summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormh0310.choi <mh0310.choi@samsung.com>2015-07-28 10:46:57 +0900
committermh0310.choi <mh0310.choi@samsung.com>2015-07-28 13:08:12 +0900
commit5e67a6f721eaedda61300baf0799199c7771ebd0 (patch)
tree6cd50b52498aab50e79b966cdccc2a137db316d9
parentd3aeffba37161d2b76b29c4ea13369bd67a47a8e (diff)
downloadcairo-5e67a6f721eaedda61300baf0799199c7771ebd0.tar.gz
cairo-5e67a6f721eaedda61300baf0799199c7771ebd0.tar.bz2
cairo-5e67a6f721eaedda61300baf0799199c7771ebd0.zip
- from 1.12.14 to 1.14.2 Change-Id: I3b62d212041b337bbb926d579f9ce74f42a45c3b
-rw-r--r--[-rwxr-xr-x]AUTHORS6
-rw-r--r--[-rwxr-xr-x]BIBLIOGRAPHY0
-rw-r--r--[-rwxr-xr-x]BUGS0
-rw-r--r--[-rwxr-xr-x]CODING_STYLE0
-rw-r--r--[-rwxr-xr-x]COPYING0
-rw-r--r--[-rwxr-xr-x]COPYING-LGPL-2.10
-rw-r--r--[-rwxr-xr-x]COPYING-MPL-1.10
-rw-r--r--[-rwxr-xr-x]HACKING27
-rw-r--r--[-rwxr-xr-x]INSTALL0
-rw-r--r--[-rwxr-xr-x]KNOWN_ISSUES13
-rw-r--r--[-rwxr-xr-x]Makefile.am29
-rw-r--r--[-rwxr-xr-x]Makefile.win320
-rw-r--r--[-rwxr-xr-x]NEWS340
-rw-r--r--[-rwxr-xr-x]PORTING_GUIDE0
-rw-r--r--[-rwxr-xr-x]README32
-rw-r--r--[-rwxr-xr-x]README.win320
-rw-r--r--[-rwxr-xr-x]RELEASING24
-rw-r--r--[-rwxr-xr-x]acinclude.m40
-rw-r--r--[-rwxr-xr-x]boilerplate/.gitignore0
-rw-r--r--[-rwxr-xr-x]boilerplate/Makefile.am6
-rw-r--r--[-rwxr-xr-x]boilerplate/Makefile.sources2
-rw-r--r--[-rwxr-xr-x]boilerplate/Makefile.win320
-rw-r--r--[-rwxr-xr-x]boilerplate/Makefile.win32.features51
-rw-r--r--[-rwxr-xr-x]boilerplate/README0
-rw-r--r--[-rwxr-xr-x]boilerplate/cairo-boilerplate-beos.cpp0
-rw-r--r--boilerplate/cairo-boilerplate-cgl.c150
-rw-r--r--[-rwxr-xr-x]boilerplate/cairo-boilerplate-cogl.c0
-rw-r--r--[-rwxr-xr-x]boilerplate/cairo-boilerplate-directfb.c0
-rw-r--r--[-rwxr-xr-x]boilerplate/cairo-boilerplate-drm.c12
-rw-r--r--[-rwxr-xr-x]boilerplate/cairo-boilerplate-egl.c26
-rw-r--r--[-rwxr-xr-x]boilerplate/cairo-boilerplate-evas-gl.c9
-rw-r--r--[-rwxr-xr-x]boilerplate/cairo-boilerplate-getopt.c0
-rw-r--r--[-rwxr-xr-x]boilerplate/cairo-boilerplate-getopt.h0
-rw-r--r--[-rwxr-xr-x]boilerplate/cairo-boilerplate-glx.c13
-rw-r--r--[-rwxr-xr-x]boilerplate/cairo-boilerplate-pdf.c2
-rw-r--r--[-rwxr-xr-x]boilerplate/cairo-boilerplate-private.h2
-rw-r--r--[-rwxr-xr-x]boilerplate/cairo-boilerplate-ps.c0
-rw-r--r--[-rwxr-xr-x]boilerplate/cairo-boilerplate-qt.cpp0
-rw-r--r--[-rwxr-xr-x]boilerplate/cairo-boilerplate-quartz.c0
-rw-r--r--[-rwxr-xr-x]boilerplate/cairo-boilerplate-scaled-font.h0
-rw-r--r--[-rwxr-xr-x]boilerplate/cairo-boilerplate-script.c0
-rw-r--r--[-rwxr-xr-x]boilerplate/cairo-boilerplate-skia.c0
-rw-r--r--[-rwxr-xr-x]boilerplate/cairo-boilerplate-svg.c0
-rw-r--r--[-rwxr-xr-x]boilerplate/cairo-boilerplate-system.c0
-rw-r--r--[-rwxr-xr-x]boilerplate/cairo-boilerplate-system.h0
-rw-r--r--[-rwxr-xr-x]boilerplate/cairo-boilerplate-test-surfaces.c0
-rw-r--r--[-rwxr-xr-x]boilerplate/cairo-boilerplate-vg.c8
-rw-r--r--[-rwxr-xr-x]boilerplate/cairo-boilerplate-wgl.c0
-rw-r--r--[-rwxr-xr-x]boilerplate/cairo-boilerplate-win32-printing.c0
-rw-r--r--[-rwxr-xr-x]boilerplate/cairo-boilerplate-win32.c0
-rw-r--r--[-rwxr-xr-x]boilerplate/cairo-boilerplate-xcb.c4
-rw-r--r--[-rwxr-xr-x]boilerplate/cairo-boilerplate-xlib.c12
-rw-r--r--[-rwxr-xr-x]boilerplate/cairo-boilerplate-xlib.h0
-rw-r--r--[-rwxr-xr-x]boilerplate/cairo-boilerplate.c188
-rw-r--r--[-rwxr-xr-x]boilerplate/cairo-boilerplate.h11
-rw-r--r--[-rwxr-xr-x]boilerplate/check-link.c0
-rw-r--r--[-rwxr-xr-x]boilerplate/make-cairo-boilerplate-constructors.sh0
-rw-r--r--[-rwxr-xr-x]build/.gitignore4
-rw-r--r--[-rwxr-xr-x]build/Makefile.am.analysis0
-rw-r--r--[-rwxr-xr-x]build/Makefile.am.changelog0
-rw-r--r--[-rwxr-xr-x]build/Makefile.am.common0
-rw-r--r--[-rwxr-xr-x]build/Makefile.am.gtk-doc0
-rw-r--r--[-rwxr-xr-x]build/Makefile.am.releasing0
-rw-r--r--[-rwxr-xr-x]build/Makefile.win32.common23
-rw-r--r--[-rwxr-xr-x]build/Makefile.win32.features5
-rw-r--r--[-rwxr-xr-x]build/Makefile.win32.features-h15
-rw-r--r--[-rwxr-xr-x]build/Makefile.win32.inform0
-rw-r--r--[-rwxr-xr-x]build/aclocal.cairo.m40
-rw-r--r--[-rwxr-xr-x]build/aclocal.compare.m40
-rw-r--r--[-rwxr-xr-x]build/aclocal.enable.m40
-rw-r--r--[-rwxr-xr-x]build/aclocal.float.m49
-rw-r--r--[-rwxr-xr-x]build/aclocal.gtk-doc.m40
-rw-r--r--[-rwxr-xr-x]build/aclocal.makefile.m40
-rw-r--r--[-rwxr-xr-x]build/aclocal.pkg.m40
-rw-r--r--[-rwxr-xr-x]build/configure.ac.analysis0
-rw-r--r--[-rwxr-xr-x]build/configure.ac.features4
-rw-r--r--[-rwxr-xr-x]build/configure.ac.noversion0
-rwxr-xr-xbuild/configure.ac.openmp74
-rw-r--r--[-rwxr-xr-x]build/configure.ac.pthread0
-rw-r--r--[-rwxr-xr-x]build/configure.ac.system0
-rwxr-xr-xbuild/configure.ac.tls108
-rw-r--r--[-rwxr-xr-x]build/configure.ac.tools0
-rw-r--r--[-rwxr-xr-x]build/configure.ac.version0
-rw-r--r--[-rwxr-xr-x]build/configure.ac.warnings24
-rw-r--r--[-rwxr-xr-x]cairo-glesv3-uninstall.pc0
-rw-r--r--[-rwxr-xr-x]cairo-version.h4
-rwxr-xr-xcairo.manifest5
-rw-r--r--[-rwxr-xr-x]configure.ac112
-rw-r--r--[-rwxr-xr-x]doc/.gitignore0
-rw-r--r--[-rwxr-xr-x]doc/Makefile.am0
-rw-r--r--[-rwxr-xr-x]doc/public/.gitignore1
-rw-r--r--[-rwxr-xr-x]doc/public/Makefile.am0
-rw-r--r--[-rwxr-xr-x]doc/public/README0
-rw-r--r--[-rwxr-xr-x]doc/public/cairo-docs.xml0
-rw-r--r--[-rwxr-xr-x]doc/public/cairo-overrides.txt0
-rw-r--r--[-rwxr-xr-x]doc/public/cairo-sections.txt42
-rw-r--r--[-rwxr-xr-x]doc/public/cairo.types0
-rw-r--r--[-rwxr-xr-x]doc/public/language-bindings.xml0
-rw-r--r--doc/tutorial/slides/.gitignore7
-rw-r--r--doc/tutorial/slides/cairo-blank.svg477
-rw-r--r--doc/tutorial/slides/cairo-code.svg913
-rw-r--r--doc/tutorial/slides/cairo-large-content.svg899
-rw-r--r--doc/tutorial/slides/cairo-separator.svg909
-rw-r--r--doc/tutorial/slides/cairo-title.svg898
-rw-r--r--doc/tutorial/slides/cairo.svg898
-rw-r--r--doc/tutorial/slides/circle-cairo-large.pngbin0 -> 3362 bytes
-rw-r--r--doc/tutorial/slides/circle-cairo.pngbin0 -> 1429 bytes
-rw-r--r--doc/tutorial/slides/circle-ooo-large.pngbin0 -> 1491 bytes
-rw-r--r--doc/tutorial/slides/circle-ooo.pngbin0 -> 383 bytes
-rw-r--r--doc/tutorial/slides/expander-fuzzy-large.pngbin0 -> 1300 bytes
-rw-r--r--doc/tutorial/slides/expander-fuzzy.pngbin0 -> 296 bytes
-rw-r--r--doc/tutorial/slides/expander-sharp-large.pngbin0 -> 929 bytes
-rw-r--r--doc/tutorial/slides/expander-sharp.pngbin0 -> 183 bytes
-rw-r--r--doc/tutorial/slides/fuzzies.svg11
-rw-r--r--doc/tutorial/slides/jaggies.svg11
-rw-r--r--doc/tutorial/slides/rendering-model.pngbin0 -> 63917 bytes
-rw-r--r--doc/tutorial/slides/tutorial.xml535
-rw-r--r--doc/tutorial/src/.gitignore8
-rw-r--r--doc/tutorial/src/README66
-rw-r--r--doc/tutorial/src/circle.c22
-rw-r--r--doc/tutorial/src/include/cairo-tutorial-gtk.h133
-rw-r--r--doc/tutorial/src/include/cairo-tutorial-pdf.h74
-rw-r--r--doc/tutorial/src/include/cairo-tutorial-png.h74
-rw-r--r--doc/tutorial/src/include/cairo-tutorial-xlib.h251
-rw-r--r--doc/tutorial/src/include/cairo-tutorial.h40
-rw-r--r--doc/tutorial/src/lca.c32
-rw-r--r--doc/tutorial/src/singular.c162
-rw-r--r--doc/tutorial/src/twin.c39
-rw-r--r--[-rwxr-xr-x]packaging/cairo.manifest0
-rw-r--r--[-rwxr-xr-x]packaging/cairo.spec42
-rw-r--r--perf/.gitignore30
-rw-r--r--perf/COPYING5
-rw-r--r--perf/Makefile.am154
-rw-r--r--perf/Makefile.sources38
-rw-r--r--perf/Makefile.win3278
-rw-r--r--perf/README239
-rw-r--r--perf/cairo-analyse-trace.c592
-rw-r--r--perf/cairo-perf-chart.c1113
-rw-r--r--perf/cairo-perf-compare-backends.c398
-rwxr-xr-xperf/cairo-perf-diff255
-rw-r--r--perf/cairo-perf-diff-files.c506
-rwxr-xr-xperf/cairo-perf-graph206
-rw-r--r--perf/cairo-perf-graph-files.c604
-rw-r--r--perf/cairo-perf-graph-widget.c604
-rw-r--r--perf/cairo-perf-graph.h63
-rw-r--r--perf/cairo-perf-micro.c594
-rw-r--r--perf/cairo-perf-print.c139
-rw-r--r--perf/cairo-perf-report.c454
-rw-r--r--perf/cairo-perf-trace.c1067
-rw-r--r--perf/cairo-perf.c98
-rw-r--r--perf/cairo-perf.h250
-rw-r--r--perf/cairo-stats.c182
-rw-r--r--perf/cairo-stats.h52
-rw-r--r--perf/dirent-win32.h102
-rwxr-xr-xperf/make-html.py88
-rw-r--r--perf/micro/Makefile.am16
-rw-r--r--perf/micro/Makefile.sources51
-rw-r--r--perf/micro/Makefile.win3212
-rw-r--r--perf/micro/a1-curve.c112
-rw-r--r--perf/micro/a1-line.c223
-rw-r--r--perf/micro/box-outline.c215
-rw-r--r--perf/micro/cairo-perf-cover.c339
-rw-r--r--perf/micro/composite-checker.c117
-rw-r--r--perf/micro/curve.c111
-rw-r--r--perf/micro/disjoint.c101
-rw-r--r--perf/micro/dragon.c277
-rw-r--r--perf/micro/fill-clip.c126
-rw-r--r--perf/micro/fill.c122
-rw-r--r--perf/micro/glyphs.c202
-rw-r--r--perf/micro/hash-table.c115
-rw-r--r--perf/micro/hatching.c202
-rw-r--r--perf/micro/intersections.c160
-rw-r--r--perf/micro/line.c222
-rw-r--r--perf/micro/long-dashed-lines.c74
-rw-r--r--perf/micro/long-lines.c148
-rw-r--r--perf/micro/many-curves.c135
-rw-r--r--perf/micro/many-fills.c187
-rw-r--r--perf/micro/many-strokes.c186
-rw-r--r--perf/micro/mask.c305
-rw-r--r--perf/micro/mosaic.c176
-rw-r--r--perf/micro/mosaic.h4387
-rw-r--r--perf/micro/paint-with-alpha.c59
-rw-r--r--perf/micro/paint.c57
-rw-r--r--perf/micro/pattern_create_radial.c106
-rw-r--r--perf/micro/pixel.c237
-rw-r--r--perf/micro/pythagoras-tree.c95
-rw-r--r--perf/micro/rectangles.c121
-rw-r--r--perf/micro/rounded-rectangles.c144
-rw-r--r--perf/micro/sierpinski.c94
-rw-r--r--perf/micro/spiral.c352
-rw-r--r--perf/micro/stroke.c100
-rw-r--r--perf/micro/subimage_copy.c80
-rw-r--r--perf/micro/tessellate.c181
-rw-r--r--perf/micro/text.c69
-rw-r--r--perf/micro/tiger.c115
-rw-r--r--perf/micro/twin.c59
-rw-r--r--perf/micro/unaligned-clip.c73
-rw-r--r--perf/micro/wave.c115
-rw-r--r--perf/micro/wide-fills.c187
-rw-r--r--perf/micro/wide-strokes.c188
-rw-r--r--perf/micro/world-map.c149
-rw-r--r--perf/micro/world-map.h196
-rw-r--r--perf/micro/zrusin-another.h668
-rw-r--r--perf/micro/zrusin.c97
-rw-r--r--[-rwxr-xr-x]src/.gitignore4
-rw-r--r--[-rwxr-xr-x]src/Makefile.am0
-rw-r--r--[-rwxr-xr-x]src/Makefile.am.analysis0
-rw-r--r--[-rwxr-xr-x]src/Makefile.sources25
-rw-r--r--[-rwxr-xr-x]src/Makefile.win320
-rw-r--r--[-rwxr-xr-x]src/Makefile.win32.features59
-rw-r--r--[-rwxr-xr-x]src/README0
-rw-r--r--[-rwxr-xr-x]src/cairo-analysis-surface-private.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-analysis-surface.c0
-rw-r--r--[-rwxr-xr-x]src/cairo-arc-private.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-arc.c4
-rw-r--r--[-rwxr-xr-x]src/cairo-array-private.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-array.c0
-rw-r--r--[-rwxr-xr-x]src/cairo-atomic-private.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-atomic.c0
-rw-r--r--[-rwxr-xr-x]src/cairo-backend-private.h1
-rw-r--r--[-rwxr-xr-x]src/cairo-base64-stream.c0
-rw-r--r--[-rwxr-xr-x]src/cairo-base85-stream.c0
-rw-r--r--[-rwxr-xr-x]src/cairo-bentley-ottmann-rectangular.c0
-rw-r--r--[-rwxr-xr-x]src/cairo-bentley-ottmann-rectilinear.c0
-rw-r--r--[-rwxr-xr-x]src/cairo-bentley-ottmann.c234
-rw-r--r--[-rwxr-xr-x]src/cairo-beos-surface.cpp0
-rw-r--r--[-rwxr-xr-x]src/cairo-beos.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-botor-scan-converter.c0
-rw-r--r--[-rwxr-xr-x]src/cairo-box-inline.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-boxes-intersect.c0
-rw-r--r--[-rwxr-xr-x]src/cairo-boxes-private.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-boxes.c0
-rw-r--r--[-rwxr-xr-x]src/cairo-cache-private.h2
-rw-r--r--[-rwxr-xr-x]src/cairo-cache.c0
-rw-r--r--[-rwxr-xr-x]src/cairo-cff-subset.c45
-rw-r--r--src/cairo-cgl-context.c224
-rw-r--r--[-rwxr-xr-x]src/cairo-clip-boxes.c11
-rw-r--r--[-rwxr-xr-x]src/cairo-clip-inline.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-clip-polygon.c0
-rw-r--r--[-rwxr-xr-x]src/cairo-clip-private.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-clip-region.c0
-rw-r--r--[-rwxr-xr-x]src/cairo-clip-surface.c20
-rw-r--r--[-rwxr-xr-x]src/cairo-clip-tor-scan-converter.c0
-rw-r--r--[-rwxr-xr-x]src/cairo-clip.c0
-rw-r--r--[-rwxr-xr-x]src/cairo-cogl-context-private.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-cogl-context.c0
-rw-r--r--[-rwxr-xr-x]src/cairo-cogl-gradient-private.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-cogl-gradient.c0
-rw-r--r--[-rwxr-xr-x]src/cairo-cogl-private.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-cogl-surface.c8
-rw-r--r--[-rwxr-xr-x]src/cairo-cogl-utils-private.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-cogl-utils.c0
-rw-r--r--[-rwxr-xr-x]src/cairo-cogl.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-color.c11
-rw-r--r--[-rwxr-xr-x]src/cairo-combsort-inline.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-compiler-private.h12
-rw-r--r--[-rwxr-xr-x]src/cairo-composite-rectangles-private.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-composite-rectangles.c11
-rw-r--r--[-rwxr-xr-x]src/cairo-compositor-private.h24
-rw-r--r--[-rwxr-xr-x]src/cairo-compositor.c0
-rw-r--r--[-rwxr-xr-x]src/cairo-contour-inline.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-contour-private.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-contour.c1
-rw-r--r--src/cairo-convex-fill-private.h112
-rw-r--r--src/cairo-convex-fill.c219
-rw-r--r--[-rwxr-xr-x]src/cairo-damage-private.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-damage.c0
-rw-r--r--[-rwxr-xr-x]src/cairo-debug.c0
-rw-r--r--[-rwxr-xr-x]src/cairo-default-context-private.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-default-context.c245
-rw-r--r--[-rwxr-xr-x]src/cairo-deflate-stream.c0
-rw-r--r--[-rwxr-xr-x]src/cairo-deprecated.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-device-private.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-device.c3
-rw-r--r--[-rwxr-xr-x]src/cairo-directfb-surface.c4
-rw-r--r--[-rwxr-xr-x]src/cairo-directfb.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-drm.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-egl-context.c25
-rw-r--r--[-rwxr-xr-x]src/cairo-error-inline.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-error-private.h8
-rw-r--r--[-rwxr-xr-x]src/cairo-error.c0
-rw-r--r--[-rwxr-xr-x]src/cairo-evas-gl-context.c12
-rw-r--r--[-rwxr-xr-x]src/cairo-fallback-compositor.c0
-rw-r--r--[-rwxr-xr-x]src/cairo-features-uninstalled.pc.in0
-rw-r--r--[-rwxr-xr-x]src/cairo-features.pc.in0
-rw-r--r--[-rwxr-xr-x]src/cairo-filters-private.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-filters.c0
-rw-r--r--[-rwxr-xr-x]src/cairo-fixed-private.h40
-rw-r--r--[-rwxr-xr-x]src/cairo-fixed-type-private.h2
-rw-r--r--[-rwxr-xr-x]src/cairo-fixed.c0
-rw-r--r--[-rwxr-xr-x]src/cairo-font-face-twin-data.c0
-rw-r--r--[-rwxr-xr-x]src/cairo-font-face-twin.c0
-rw-r--r--[-rwxr-xr-x]src/cairo-font-face.c44
-rw-r--r--[-rwxr-xr-x]src/cairo-font-options.c21
-rw-r--r--[-rwxr-xr-x]src/cairo-fontconfig-private.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-freed-pool-private.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-freed-pool.c0
-rw-r--r--[-rwxr-xr-x]src/cairo-freelist-private.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-freelist-type-private.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-freelist.c0
-rw-r--r--[-rwxr-xr-x]src/cairo-ft-font.c232
-rw-r--r--[-rwxr-xr-x]src/cairo-ft-private.h2
-rw-r--r--[-rwxr-xr-x]src/cairo-ft.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-gl-composite.c189
-rw-r--r--[-rwxr-xr-x]src/cairo-gl-device.c197
-rw-r--r--[-rwxr-xr-x]src/cairo-gl-dispatch-private.h8
-rw-r--r--[-rwxr-xr-x]src/cairo-gl-dispatch.c2
-rw-r--r--[-rwxr-xr-x]src/cairo-gl-ext-def-private.h8
-rw-r--r--[-rwxr-xr-x]src/cairo-gl-filters.c12
-rw-r--r--[-rwxr-xr-x]src/cairo-gl-glyphs.c79
-rw-r--r--[-rwxr-xr-x]src/cairo-gl-gradient-private.h35
-rw-r--r--[-rwxr-xr-x]src/cairo-gl-gradient.c2
-rw-r--r--[-rwxr-xr-x]src/cairo-gl-hairline-stroke.c13
-rw-r--r--[-rwxr-xr-x]src/cairo-gl-info.c78
-rw-r--r--[-rwxr-xr-x]src/cairo-gl-msaa-compositor.c139
-rw-r--r--[-rwxr-xr-x]src/cairo-gl-operand.c156
-rw-r--r--[-rwxr-xr-x]src/cairo-gl-private.h126
-rw-r--r--[-rwxr-xr-x]src/cairo-gl-shaders.c757
-rw-r--r--[-rwxr-xr-x]src/cairo-gl-source.c0
-rw-r--r--[-rwxr-xr-x]src/cairo-gl-spans-compositor.c3
-rw-r--r--[-rwxr-xr-x]src/cairo-gl-surface-legacy.c0
-rw-r--r--[-rwxr-xr-x]src/cairo-gl-surface.c173
-rw-r--r--[-rwxr-xr-x]src/cairo-gl-traps-compositor.c161
-rw-r--r--[-rwxr-xr-x]src/cairo-gl.h15
-rw-r--r--[-rwxr-xr-x]src/cairo-glx-context.c7
-rw-r--r--[-rwxr-xr-x]src/cairo-gstate-private.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-gstate.c53
-rw-r--r--[-rwxr-xr-x]src/cairo-hash-private.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-hash.c0
-rw-r--r--[-rwxr-xr-x]src/cairo-hull.c0
-rw-r--r--[-rwxr-xr-x]src/cairo-image-compositor.c400
-rw-r--r--[-rwxr-xr-x]src/cairo-image-filters-private.h4
-rw-r--r--[-rwxr-xr-x]src/cairo-image-filters.c16
-rw-r--r--[-rwxr-xr-x]src/cairo-image-info-private.h5
-rw-r--r--[-rwxr-xr-x]src/cairo-image-info.c157
-rw-r--r--[-rwxr-xr-x]src/cairo-image-mask-compositor.c3
-rw-r--r--[-rwxr-xr-x]src/cairo-image-source.c559
-rw-r--r--[-rwxr-xr-x]src/cairo-image-surface-inline.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-image-surface-private.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-image-surface.c23
-rw-r--r--[-rwxr-xr-x]src/cairo-line-inline.h (renamed from boilerplate/cairo-boilerplate-tg.c)67
-rw-r--r--[-rwxr-xr-x]src/cairo-line-private.h (renamed from src/cairo-tg.h)55
-rw-r--r--src/cairo-line.c306
-rw-r--r--[-rwxr-xr-x]src/cairo-list-inline.h8
-rw-r--r--[-rwxr-xr-x]src/cairo-list-private.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-lzw.c0
-rw-r--r--[-rwxr-xr-x]src/cairo-malloc-private.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-mask-compositor.c14
-rw-r--r--[-rwxr-xr-x]src/cairo-matrix.c37
-rw-r--r--[-rwxr-xr-x]src/cairo-mempool-private.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-mempool.c3
-rw-r--r--[-rwxr-xr-x]src/cairo-mesh-pattern-rasterizer.c11
-rw-r--r--[-rwxr-xr-x]src/cairo-misc.c20
-rw-r--r--[-rwxr-xr-x]src/cairo-mono-scan-converter.c0
-rw-r--r--[-rwxr-xr-x]src/cairo-mutex-impl-private.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-mutex-list-private.h5
-rw-r--r--[-rwxr-xr-x]src/cairo-mutex-private.h2
-rw-r--r--[-rwxr-xr-x]src/cairo-mutex-type-private.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-mutex.c7
-rw-r--r--[-rwxr-xr-x]src/cairo-no-compositor.c0
-rw-r--r--[-rwxr-xr-x]src/cairo-observer.c0
-rw-r--r--[-rwxr-xr-x]src/cairo-os2-private.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-os2-surface.c0
-rw-r--r--[-rwxr-xr-x]src/cairo-os2.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-output-stream-private.h5
-rw-r--r--[-rwxr-xr-x]src/cairo-output-stream.c44
-rw-r--r--[-rwxr-xr-x]src/cairo-paginated-private.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-paginated-surface-private.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-paginated-surface.c2
-rw-r--r--[-rwxr-xr-x]src/cairo-path-bounds.c2
-rw-r--r--[-rwxr-xr-x]src/cairo-path-fill.c1
-rw-r--r--[-rwxr-xr-x]src/cairo-path-fixed-private.h2
-rw-r--r--[-rwxr-xr-x]src/cairo-path-fixed.c90
-rw-r--r--[-rwxr-xr-x]src/cairo-path-in-fill.c0
-rw-r--r--[-rwxr-xr-x]src/cairo-path-private.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-path-stroke-boxes.c0
-rw-r--r--[-rwxr-xr-x]src/cairo-path-stroke-polygon.c10
-rw-r--r--[-rwxr-xr-x]src/cairo-path-stroke-traps.c59
-rw-r--r--[-rwxr-xr-x]src/cairo-path-stroke-tristrip.c0
-rw-r--r--[-rwxr-xr-x]src/cairo-path-stroke.c87
-rw-r--r--[-rwxr-xr-x]src/cairo-path.c2
-rw-r--r--[-rwxr-xr-x]src/cairo-pattern-inline.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-pattern-private.h11
-rw-r--r--[-rwxr-xr-x]src/cairo-pattern.c332
-rw-r--r--[-rwxr-xr-x]src/cairo-pdf-operators-private.h11
-rw-r--r--[-rwxr-xr-x]src/cairo-pdf-operators.c41
-rw-r--r--[-rwxr-xr-x]src/cairo-pdf-shading-private.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-pdf-shading.c0
-rw-r--r--[-rwxr-xr-x]src/cairo-pdf-surface-private.h12
-rw-r--r--[-rwxr-xr-x]src/cairo-pdf-surface.c1168
-rw-r--r--[-rwxr-xr-x]src/cairo-pdf.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-pen.c0
-rw-r--r--[-rwxr-xr-x]src/cairo-pixman-private.h (renamed from src/cairo-tg-private.h)48
-rw-r--r--[-rwxr-xr-x]src/cairo-png.c14
-rw-r--r--[-rwxr-xr-x]src/cairo-polygon-intersect.c0
-rw-r--r--[-rwxr-xr-x]src/cairo-polygon-reduce.c0
-rw-r--r--[-rwxr-xr-x]src/cairo-polygon.c0
-rw-r--r--[-rwxr-xr-x]src/cairo-private.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-ps-surface-private.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-ps-surface.c149
-rw-r--r--[-rwxr-xr-x]src/cairo-ps.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-qt-surface.cpp39
-rw-r--r--[-rwxr-xr-x]src/cairo-qt.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-quartz-filters.c2
-rw-r--r--[-rwxr-xr-x]src/cairo-quartz-font.c13
-rw-r--r--[-rwxr-xr-x]src/cairo-quartz-image-surface.c6
-rw-r--r--[-rwxr-xr-x]src/cairo-quartz-image.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-quartz-private.h3
-rw-r--r--[-rwxr-xr-x]src/cairo-quartz-surface.c16
-rw-r--r--[-rwxr-xr-x]src/cairo-quartz.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-raster-source-pattern.c2
-rw-r--r--[-rwxr-xr-x]src/cairo-recording-surface-inline.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-recording-surface-private.h12
-rw-r--r--[-rwxr-xr-x]src/cairo-recording-surface.c139
-rw-r--r--[-rwxr-xr-x]src/cairo-rectangle.c0
-rw-r--r--[-rwxr-xr-x]src/cairo-rectangular-scan-converter.c0
-rw-r--r--[-rwxr-xr-x]src/cairo-reference-count-private.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-region-private.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-region.c13
-rw-r--r--[-rwxr-xr-x]src/cairo-rtree-private.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-rtree.c0
-rw-r--r--[-rwxr-xr-x]src/cairo-scaled-font-private.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-scaled-font-subsets-private.h15
-rw-r--r--[-rwxr-xr-x]src/cairo-scaled-font-subsets.c40
-rw-r--r--[-rwxr-xr-x]src/cairo-scaled-font.c4
-rw-r--r--[-rwxr-xr-x]src/cairo-script-private.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-script-surface.c0
-rw-r--r--[-rwxr-xr-x]src/cairo-script.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-shape-mask-compositor.c27
-rw-r--r--[-rwxr-xr-x]src/cairo-skia-surface.cpp49
-rw-r--r--[-rwxr-xr-x]src/cairo-skia.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-slope-private.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-slope.c0
-rw-r--r--[-rwxr-xr-x]src/cairo-spans-compositor-private.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-spans-compositor.c30
-rw-r--r--[-rwxr-xr-x]src/cairo-spans-private.h2
-rw-r--r--[-rwxr-xr-x]src/cairo-spans.c2
-rw-r--r--[-rwxr-xr-x]src/cairo-spline.c1
-rw-r--r--[-rwxr-xr-x]src/cairo-stroke-dash-private.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-stroke-dash.c0
-rw-r--r--[-rwxr-xr-x]src/cairo-stroke-style.c0
-rw-r--r--[-rwxr-xr-x]src/cairo-surface-backend-private.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-surface-clipper-private.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-surface-clipper.c0
-rw-r--r--[-rwxr-xr-x]src/cairo-surface-fallback-private.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-surface-fallback.c0
-rw-r--r--[-rwxr-xr-x]src/cairo-surface-inline.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-surface-observer-inline.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-surface-observer-private.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-surface-observer.c17
-rw-r--r--[-rwxr-xr-x]src/cairo-surface-offset-private.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-surface-offset.c0
-rw-r--r--[-rwxr-xr-x]src/cairo-surface-private.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-surface-scale-translate-private.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-surface-scale-translate.c0
-rw-r--r--[-rwxr-xr-x]src/cairo-surface-shadow-private.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-surface-shadow.c48
-rw-r--r--[-rwxr-xr-x]src/cairo-surface-snapshot-inline.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-surface-snapshot-private.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-surface-snapshot.c0
-rw-r--r--[-rwxr-xr-x]src/cairo-surface-subsurface-inline.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-surface-subsurface-private.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-surface-subsurface.c30
-rw-r--r--[-rwxr-xr-x]src/cairo-surface-wrapper-private.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-surface-wrapper.c9
-rw-r--r--[-rwxr-xr-x]src/cairo-surface.c321
-rw-r--r--[-rwxr-xr-x]src/cairo-svg-surface-private.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-svg-surface.c21
-rw-r--r--[-rwxr-xr-x]src/cairo-svg.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-tee-surface-private.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-tee-surface.c0
-rw-r--r--[-rwxr-xr-x]src/cairo-tee.h0
-rwxr-xr-xsrc/cairo-tg-allocator-private.h134
-rwxr-xr-xsrc/cairo-tg-composite-extents-private.h121
-rwxr-xr-xsrc/cairo-tg-journal-private.h229
-rwxr-xr-xsrc/cairo-tg-journal.c520
-rwxr-xr-xsrc/cairo-tg-surface.c1372
-rwxr-xr-xsrc/cairo-thread-local-private.h161
-rw-r--r--[-rwxr-xr-x]src/cairo-time-private.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-time.c0
-rw-r--r--[-rwxr-xr-x]src/cairo-tor-scan-converter.c489
-rw-r--r--[-rwxr-xr-x]src/cairo-tor22-scan-converter.c0
-rw-r--r--[-rwxr-xr-x]src/cairo-toy-font-face.c7
-rw-r--r--[-rwxr-xr-x]src/cairo-traps-compositor.c267
-rw-r--r--[-rwxr-xr-x]src/cairo-traps-private.h8
-rw-r--r--[-rwxr-xr-x]src/cairo-traps.c90
-rw-r--r--[-rwxr-xr-x]src/cairo-tristrip-private.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-tristrip.c0
-rw-r--r--[-rwxr-xr-x]src/cairo-truetype-subset-private.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-truetype-subset.c37
-rw-r--r--[-rwxr-xr-x]src/cairo-type1-fallback.c0
-rw-r--r--[-rwxr-xr-x]src/cairo-type1-glyph-names.c0
-rw-r--r--[-rwxr-xr-x]src/cairo-type1-private.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-type1-subset.c51
-rw-r--r--[-rwxr-xr-x]src/cairo-type3-glyph-surface-private.h8
-rw-r--r--[-rwxr-xr-x]src/cairo-type3-glyph-surface.c6
-rw-r--r--[-rwxr-xr-x]src/cairo-types-private.h8
-rw-r--r--[-rwxr-xr-x]src/cairo-unicode.c0
-rw-r--r--[-rwxr-xr-x]src/cairo-uninstalled.pc.in0
-rw-r--r--[-rwxr-xr-x]src/cairo-user-font-private.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-user-font.c2
-rw-r--r--[-rwxr-xr-x]src/cairo-version.c11
-rw-r--r--[-rwxr-xr-x]src/cairo-version.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-vg-surface.c0
-rw-r--r--[-rwxr-xr-x]src/cairo-vg.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-wgl-context.c0
-rw-r--r--[-rwxr-xr-x]src/cairo-wideint-private.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-wideint-type-private.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-wideint.c8
-rw-r--r--[-rwxr-xr-x]src/cairo-win32.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-xcb-connection-core.c34
-rw-r--r--[-rwxr-xr-x]src/cairo-xcb-connection-render.c0
-rw-r--r--[-rwxr-xr-x]src/cairo-xcb-connection-shm.c6
-rw-r--r--[-rwxr-xr-x]src/cairo-xcb-connection.c29
-rw-r--r--[-rwxr-xr-x]src/cairo-xcb-private.h53
-rw-r--r--src/cairo-xcb-resources.c281
-rw-r--r--[-rwxr-xr-x]src/cairo-xcb-screen.c130
-rw-r--r--[-rwxr-xr-x]src/cairo-xcb-shm.c0
-rw-r--r--[-rwxr-xr-x]src/cairo-xcb-surface-core.c4
-rw-r--r--[-rwxr-xr-x]src/cairo-xcb-surface-render.c148
-rw-r--r--[-rwxr-xr-x]src/cairo-xcb-surface.c41
-rw-r--r--[-rwxr-xr-x]src/cairo-xcb.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-xlib-core-compositor.c4
-rw-r--r--[-rwxr-xr-x]src/cairo-xlib-display.c12
-rw-r--r--[-rwxr-xr-x]src/cairo-xlib-fallback-compositor.c0
-rw-r--r--[-rwxr-xr-x]src/cairo-xlib-private.h6
-rw-r--r--[-rwxr-xr-x]src/cairo-xlib-render-compositor.c39
-rw-r--r--[-rwxr-xr-x]src/cairo-xlib-screen.c0
-rw-r--r--[-rwxr-xr-x]src/cairo-xlib-source.c80
-rw-r--r--[-rwxr-xr-x]src/cairo-xlib-surface-private.h2
-rw-r--r--[-rwxr-xr-x]src/cairo-xlib-surface-shm.c13
-rw-r--r--[-rwxr-xr-x]src/cairo-xlib-surface.c5
-rw-r--r--[-rwxr-xr-x]src/cairo-xlib-visual.c3
-rw-r--r--[-rwxr-xr-x]src/cairo-xlib-xcb-surface.c33
-rw-r--r--[-rwxr-xr-x]src/cairo-xlib-xrender-private.h4
-rw-r--r--[-rwxr-xr-x]src/cairo-xlib-xrender.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-xlib.h0
-rw-r--r--[-rwxr-xr-x]src/cairo-xml-surface.c78
-rw-r--r--[-rwxr-xr-x]src/cairo-xml.h0
-rw-r--r--[-rwxr-xr-x]src/cairo.c54
-rw-r--r--[-rwxr-xr-x]src/cairo.h66
-rw-r--r--[-rwxr-xr-x]src/cairo.pc.in0
-rw-r--r--[-rwxr-xr-x]src/cairoint.h77
-rwxr-xr-xsrc/check-def.sh2
-rw-r--r--[-rwxr-xr-x]src/check-doc-syntax.awk2
-rwxr-xr-xsrc/check-doc-syntax.sh2
-rw-r--r--[-rwxr-xr-x]src/check-has-hidden-symbols.c0
-rw-r--r--[-rwxr-xr-x]src/check-link.c0
-rwxr-xr-xsrc/check-preprocessor-syntax.sh4
-rw-r--r--[-rwxr-xr-x]src/drm/cairo-drm-bo.c0
-rw-r--r--[-rwxr-xr-x]src/drm/cairo-drm-gallium-surface.c0
-rw-r--r--[-rwxr-xr-x]src/drm/cairo-drm-i915-glyphs.c0
-rw-r--r--[-rwxr-xr-x]src/drm/cairo-drm-i915-private.h0
-rw-r--r--[-rwxr-xr-x]src/drm/cairo-drm-i915-shader.c39
-rw-r--r--[-rwxr-xr-x]src/drm/cairo-drm-i915-spans.c0
-rw-r--r--[-rwxr-xr-x]src/drm/cairo-drm-i915-surface.c0
-rw-r--r--[-rwxr-xr-x]src/drm/cairo-drm-i965-glyphs.c0
-rw-r--r--[-rwxr-xr-x]src/drm/cairo-drm-i965-private.h0
-rw-r--r--[-rwxr-xr-x]src/drm/cairo-drm-i965-shader.c0
-rw-r--r--[-rwxr-xr-x]src/drm/cairo-drm-i965-spans.c0
-rw-r--r--[-rwxr-xr-x]src/drm/cairo-drm-i965-surface.c0
-rw-r--r--[-rwxr-xr-x]src/drm/cairo-drm-intel-brw-defines.h0
-rw-r--r--[-rwxr-xr-x]src/drm/cairo-drm-intel-brw-eu-emit.c0
-rw-r--r--[-rwxr-xr-x]src/drm/cairo-drm-intel-brw-eu-util.c0
-rw-r--r--[-rwxr-xr-x]src/drm/cairo-drm-intel-brw-eu.c0
-rw-r--r--[-rwxr-xr-x]src/drm/cairo-drm-intel-brw-eu.h0
-rw-r--r--[-rwxr-xr-x]src/drm/cairo-drm-intel-brw-structs.h0
-rw-r--r--[-rwxr-xr-x]src/drm/cairo-drm-intel-command-private.h0
-rw-r--r--[-rwxr-xr-x]src/drm/cairo-drm-intel-debug.c0
-rw-r--r--[-rwxr-xr-x]src/drm/cairo-drm-intel-ioctl-private.h0
-rw-r--r--[-rwxr-xr-x]src/drm/cairo-drm-intel-private.h0
-rw-r--r--[-rwxr-xr-x]src/drm/cairo-drm-intel-surface.c0
-rw-r--r--[-rwxr-xr-x]src/drm/cairo-drm-intel.c0
-rw-r--r--[-rwxr-xr-x]src/drm/cairo-drm-ioctl-private.h0
-rw-r--r--[-rwxr-xr-x]src/drm/cairo-drm-private.h0
-rw-r--r--[-rwxr-xr-x]src/drm/cairo-drm-radeon-private.h0
-rw-r--r--[-rwxr-xr-x]src/drm/cairo-drm-radeon-surface.c0
-rw-r--r--[-rwxr-xr-x]src/drm/cairo-drm-radeon.c0
-rw-r--r--[-rwxr-xr-x]src/drm/cairo-drm-surface.c0
-rw-r--r--[-rwxr-xr-x]src/drm/cairo-drm.c9
-rw-r--r--[-rwxr-xr-x]src/skia/cairo-skia-context.cpp65
-rw-r--r--[-rwxr-xr-x]src/skia/cairo-skia-private.h23
-rw-r--r--[-rwxr-xr-x]src/skia/cairo-skia-surface.cpp17
-rw-r--r--[-rwxr-xr-x]src/test-base-compositor-surface.c0
-rw-r--r--[-rwxr-xr-x]src/test-compositor-surface-private.h0
-rw-r--r--[-rwxr-xr-x]src/test-compositor-surface.c4
-rw-r--r--[-rwxr-xr-x]src/test-compositor-surface.h0
-rw-r--r--[-rwxr-xr-x]src/test-null-compositor-surface.c2
-rw-r--r--[-rwxr-xr-x]src/test-null-compositor-surface.h0
-rw-r--r--[-rwxr-xr-x]src/test-paginated-surface.c0
-rw-r--r--[-rwxr-xr-x]src/test-paginated-surface.h0
-rw-r--r--[-rwxr-xr-x]src/win32/cairo-win32-debug.c0
-rw-r--r--[-rwxr-xr-x]src/win32/cairo-win32-device.c0
-rw-r--r--[-rwxr-xr-x]src/win32/cairo-win32-display-surface.c14
-rw-r--r--[-rwxr-xr-x]src/win32/cairo-win32-font.c97
-rw-r--r--[-rwxr-xr-x]src/win32/cairo-win32-gdi-compositor.c3
-rw-r--r--[-rwxr-xr-x]src/win32/cairo-win32-printing-surface.c9
-rw-r--r--[-rwxr-xr-x]src/win32/cairo-win32-private.h0
-rw-r--r--[-rwxr-xr-x]src/win32/cairo-win32-surface.c21
-rw-r--r--[-rwxr-xr-x]src/win32/cairo-win32-system.c0
-rw-r--r--test/.gitignore37
-rw-r--r--test/.valgrind-suppressions577
-rw-r--r--test/6x13.pcfbin0 -> 5239 bytes
-rw-r--r--test/COPYING26
-rw-r--r--test/Makefile.am403
-rw-r--r--test/Makefile.sources446
-rw-r--r--test/Makefile.win3255
-rw-r--r--test/README319
-rw-r--r--test/a1-bug.c61
-rw-r--r--test/a1-clip.c175
-rw-r--r--test/a1-fill.c67
-rw-r--r--test/a1-image-sample.c73
-rw-r--r--test/a1-mask-sample.c83
-rw-r--r--test/a1-mask.c202
-rw-r--r--test/a1-rasterisation.c101
-rw-r--r--test/a1-sample.c59
-rw-r--r--test/a1-traps-sample.c64
-rw-r--r--test/a8-clear.c64
-rw-r--r--test/a8-mask.c201
-rw-r--r--test/aliasing.c100
-rw-r--r--test/alpha-similar.c74
-rw-r--r--test/any2ppm.c894
-rw-r--r--test/api-special-cases.c1989
-rw-r--r--test/arc-direction.c105
-rw-r--r--test/arc-infinite-loop.c61
-rw-r--r--test/arc-looping-dash.c79
-rw-r--r--test/big-empty-box.c64
-rw-r--r--test/big-empty-triangle.c75
-rw-r--r--test/big-line.c62
-rw-r--r--test/big-little-box.c69
-rw-r--r--test/big-little-triangle.c76
-rw-r--r--test/big-trap.c92
-rw-r--r--test/bilevel-image.c63
-rw-r--r--test/bitmap-font.c218
-rw-r--r--test/blur.c105
-rw-r--r--test/buffer-diff.c268
-rw-r--r--test/buffer-diff.h73
-rw-r--r--test/bug-40410.c72
-rw-r--r--test/bug-51910.c91
-rw-r--r--test/bug-84115.c61
-rw-r--r--test/bug-bo-collins.c76
-rw-r--r--test/bug-bo-rectangular.c67
-rw-r--r--test/bug-bo-ricotz.c74
-rw-r--r--test/bug-extents.c59
-rw-r--r--test/bug-seams.c120
-rw-r--r--test/bug-source-cu.c81
-rw-r--r--test/bug-spline.c95
-rw-r--r--test/cairo-test-private.h72
-rw-r--r--test/cairo-test-runner.c1108
-rw-r--r--test/cairo-test-trace.c1780
-rw-r--r--test/cairo-test.c1803
-rw-r--r--test/cairo-test.h322
-rw-r--r--test/caps-joins-alpha.c89
-rw-r--r--test/caps-joins-curve.c111
-rw-r--r--test/caps-joins.c150
-rw-r--r--test/caps-sub-paths.c65
-rw-r--r--test/caps-tails-curve.c127
-rw-r--r--test/caps.c138
-rwxr-xr-xtest/check-refs.sh63
-rw-r--r--test/checkerboard.c48
-rw-r--r--test/clear-source.c169
-rw-r--r--test/clear.c86
-rw-r--r--test/clip-all.c75
-rw-r--r--test/clip-complex-bug61592.c60
-rw-r--r--test/clip-complex-shape.c114
-rw-r--r--test/clip-contexts.c75
-rw-r--r--test/clip-device-offset.c79
-rw-r--r--test/clip-disjoint-hatching.c104
-rw-r--r--test/clip-disjoint-quad.c83
-rw-r--r--test/clip-disjoint.c90
-rw-r--r--test/clip-double-free.c87
-rw-r--r--test/clip-draw-unbounded.c184
-rw-r--r--test/clip-empty-group.c65
-rw-r--r--test/clip-empty-save.c68
-rw-r--r--test/clip-empty.c64
-rw-r--r--test/clip-fill-no-op.c67
-rw-r--r--test/clip-fill-rule-pixel-aligned.c90
-rw-r--r--test/clip-fill-rule.c87
-rw-r--r--test/clip-fill.c78
-rw-r--r--test/clip-group-shapes.c188
-rw-r--r--test/clip-image.c95
-rw-r--r--test/clip-intersect.c94
-rw-r--r--test/clip-mixed-antialias.c128
-rw-r--r--test/clip-nesting.c109
-rw-r--r--test/clip-operator.c188
-rw-r--r--test/clip-polygons.c112
-rw-r--r--test/clip-push-group.c67
-rw-r--r--test/clip-rectilinear.c90
-rw-r--r--test/clip-shape.c86
-rw-r--r--test/clip-stroke-no-op.c67
-rw-r--r--test/clip-stroke.c121
-rw-r--r--test/clip-text.c88
-rw-r--r--test/clip-twice-rectangle.c70
-rw-r--r--test/clip-twice.c74
-rw-r--r--test/clip-unbounded.c80
-rw-r--r--test/clip-zero.c72
-rw-r--r--test/clipped-group.c88
-rw-r--r--test/clipped-surface.c63
-rw-r--r--test/clipped-trapezoids-ref.pngbin0 -> 1055 bytes
-rw-r--r--test/clipped-trapezoids.c95
-rw-r--r--test/close-path-current-point.c95
-rw-r--r--test/close-path.c78
-rw-r--r--test/composite-integer-translate-over-repeat.c84
-rw-r--r--test/composite-integer-translate-over.c61
-rw-r--r--test/composite-integer-translate-source.c64
-rw-r--r--test/copy-disjoint.c87
-rw-r--r--test/copy-path.c314
-rw-r--r--test/coverage.c506
-rw-r--r--test/create-for-stream.c311
-rw-r--r--test/create-from-png-stream.c119
-rw-r--r--test/create-from-png.c320
-rw-r--r--test/culled-glyphs.c62
-rw-r--r--test/curve-to-as-line-to.c95
-rw-r--r--test/dash-caps-joins.c104
-rw-r--r--test/dash-curve.c66
-rw-r--r--test/dash-infinite-loop.c83
-rw-r--r--test/dash-no-dash.c87
-rw-r--r--test/dash-offset-negative.c100
-rw-r--r--test/dash-offset.c83
-rw-r--r--test/dash-scale.c120
-rw-r--r--test/dash-state.c64
-rw-r--r--test/dash-zero-length.c110
-rw-r--r--test/degenerate-arc.c74
-rw-r--r--test/degenerate-arcs.c57
-rw-r--r--test/degenerate-curve-to.c103
-rw-r--r--test/degenerate-dash.c90
-rw-r--r--test/degenerate-linear-gradient.c81
-rw-r--r--test/degenerate-path.c120
-rw-r--r--test/degenerate-pen.c105
-rw-r--r--test/degenerate-radial-gradient.c93
-rw-r--r--test/degenerate-rel-curve-to.c99
-rw-r--r--test/degenerate-solid-dash.c69
-rw-r--r--test/device-offset-fractional.c72
-rw-r--r--test/device-offset-positive.c82
-rw-r--r--test/device-offset-scale.c77
-rw-r--r--test/device-offset.c82
-rw-r--r--test/drunkard-tails.c135
-rw-r--r--test/egl-oversized-surface.c117
-rw-r--r--test/egl-surface-source.c135
-rw-r--r--test/error-setters.c109
-rw-r--r--test/extend-pad-border.c95
-rw-r--r--test/extend-pad-similar.c82
-rw-r--r--test/extend-pad.c81
-rw-r--r--test/extend-reflect-similar.c51
-rw-r--r--test/extend-reflect.c29
-rw-r--r--test/extend-repeat-similar.c51
-rw-r--r--test/extend-repeat.c27
-rw-r--r--test/extended-blend.c256
-rw-r--r--test/fallback-resolution.c517
-rw-r--r--test/fallback.c79
-rw-r--r--test/fill-alpha-pattern.c87
-rw-r--r--test/fill-alpha.c82
-rw-r--r--test/fill-and-stroke-alpha-add.c107
-rw-r--r--test/fill-and-stroke-alpha.c101
-rw-r--r--test/fill-and-stroke.c58
-rw-r--r--test/fill-degenerate-sort-order.c77
-rw-r--r--test/fill-disjoint.c63
-rw-r--r--test/fill-empty.c62
-rw-r--r--test/fill-image.c83
-rw-r--r--test/fill-missed-stop.c83
-rw-r--r--test/fill-rule.c127
-rw-r--r--test/filter-bilinear-extents.c102
-rw-r--r--test/filter-nearest-offset.c109
-rw-r--r--test/filter-nearest-transformed.c120
-rw-r--r--test/finer-grained-fallbacks.c180
-rw-r--r--test/font-face-get-type.c79
-rw-r--r--test/font-matrix-translation.c141
-rw-r--r--test/font-options.c110
-rw-r--r--test/ft-font-create-for-ft-face.c228
-rw-r--r--test/ft-show-glyphs-positioning.c191
-rw-r--r--test/ft-show-glyphs-table.c109
-rw-r--r--test/ft-text-antialias-none.c146
-rw-r--r--test/ft-text-vertical-layout-type1.c167
-rw-r--r--test/ft-text-vertical-layout-type3.c166
-rwxr-xr-xtest/generate_refs.sh12
-rw-r--r--test/get-and-set.c159
-rw-r--r--test/get-clip.c264
-rw-r--r--test/get-group-target.c85
-rw-r--r--test/get-path-extents.c443
-rw-r--r--test/get-xrender-format.c122
-rw-r--r--test/gl-device-release.c182
-rw-r--r--test/gl-oversized-surface.c88
-rw-r--r--test/gl-surface-source.c111
-rw-r--r--test/global.jb2bin0 -> 151 bytes
-rw-r--r--test/glyph-cache-pressure.c81
-rw-r--r--test/gradient-alpha.c56
-rw-r--r--test/gradient-constant-alpha.c61
-rw-r--r--test/gradient-zero-stops-mask.c59
-rw-r--r--test/gradient-zero-stops.c58
-rw-r--r--test/group-clip.c57
-rw-r--r--test/group-paint.c48
-rw-r--r--test/group-state.c96
-rw-r--r--test/group-unaligned.c60
-rw-r--r--test/half-coverage.c155
-rw-r--r--test/halo.c158
-rw-r--r--test/hatchings.c153
-rw-r--r--test/horizontal-clip.c77
-rw-r--r--test/huge-linear.c67
-rw-r--r--test/huge-radial.c69
-rw-r--r--test/image-bug-710072.c80
-rw-r--r--test/image-surface-source.c41
-rw-r--r--test/image1.jb2bin0 -> 143 bytes
-rw-r--r--test/image2.jb2bin0 -> 92 bytes
-rw-r--r--test/imagediff.c303
-rw-r--r--test/implicit-close.c54
-rw-r--r--test/in-fill-empty-trapezoid.c109
-rw-r--r--test/in-fill-trapezoid.c279
-rw-r--r--test/index.html42
-rw-r--r--test/infinite-join.c72
-rw-r--r--test/invalid-matrix.c374
-rw-r--r--test/inverse-text.c67
-rw-r--r--test/inverted-clip.c56
-rw-r--r--test/joins-loop.c100
-rw-r--r--test/joins-retrace.c109
-rw-r--r--test/joins-star.c99
-rw-r--r--test/joins.c109
-rw-r--r--test/jp2.jp2bin0 -> 2999 bytes
-rw-r--r--test/jpeg.jpgbin0 -> 2316 bytes
-rw-r--r--test/large-clip.c50
-rw-r--r--test/large-font.c73
-rw-r--r--test/large-source-roi.c78
-rw-r--r--test/large-source.c100
-rw-r--r--test/large-twin-antialias-mixed.c97
-rw-r--r--test/leaky-dash.c64
-rw-r--r--test/leaky-dashed-rectangle.c86
-rw-r--r--test/leaky-dashed-stroke.c166
-rw-r--r--test/leaky-polygon.c85
-rw-r--r--test/line-width-large-overlap.c149
-rw-r--r--test/line-width-overlap.c149
-rw-r--r--test/line-width-scale.c178
-rw-r--r--test/line-width-tolerance.c66
-rw-r--r--test/line-width-zero.c71
-rw-r--r--test/line-width.c77
-rw-r--r--test/linear-gradient-extend.c92
-rw-r--r--test/linear-gradient-large.c68
-rw-r--r--test/linear-gradient-one-stop.c90
-rw-r--r--test/linear-gradient-reflect.c67
-rw-r--r--test/linear-gradient-subset.c127
-rw-r--r--test/linear-gradient.c132
-rw-r--r--test/linear-step-function.c60
-rw-r--r--test/linear-uniform.c63
-rw-r--r--test/long-dashed-lines.c66
-rw-r--r--test/long-lines.c85
-rw-r--r--test/make-cairo-test-constructors.sh29
-rw-r--r--test/map-to-image.c156
-rw-r--r--test/mask-alpha.c82
-rw-r--r--test/mask-ctm.c80
-rw-r--r--test/mask-glyphs.c187
-rw-r--r--test/mask-surface-ctm.c71
-rw-r--r--test/mask-transformed-image.c96
-rw-r--r--test/mask-transformed-similar.c98
-rw-r--r--test/mask.c246
-rw-r--r--test/mesh-pattern-accuracy.c99
-rw-r--r--test/mesh-pattern-conical.c135
-rw-r--r--test/mesh-pattern-control-points.c114
-rw-r--r--test/mesh-pattern-fold.c82
-rw-r--r--test/mesh-pattern-overlap.c76
-rw-r--r--test/mesh-pattern-transformed.c107
-rw-r--r--test/mesh-pattern.c94
-rw-r--r--test/mime-data.c241
-rw-r--r--test/mime-surface-api.c151
-rw-r--r--test/miter-precision.c72
-rw-r--r--test/move-to-show-surface.c78
-rw-r--r--test/multi-page.c198
-rw-r--r--test/negative-stride-image.c71
-rw-r--r--test/new-sub-path.c74
-rw-r--r--test/nil-surface.c170
-rw-r--r--test/operator-alpha-alpha.c166
-rw-r--r--test/operator-alpha.c65
-rw-r--r--test/operator-clear.c196
-rw-r--r--test/operator-source.c250
-rw-r--r--test/operator.c65
-rw-r--r--test/outline-tolerance.c52
-rw-r--r--test/over-above-source.c72
-rw-r--r--test/over-around-source.c83
-rw-r--r--test/over-below-source.c72
-rw-r--r--test/over-between-source.c83
-rw-r--r--test/overlapping-boxes.c96
-rw-r--r--test/overlapping-dash-caps.c67
-rw-r--r--test/overlapping-glyphs.c123
-rw-r--r--test/paint-clip-fill.c106
-rw-r--r--test/paint-repeat.c61
-rw-r--r--test/paint-source-alpha.c63
-rw-r--r--test/paint-with-alpha-group-clip.c60
-rw-r--r--test/paint-with-alpha.c148
-rw-r--r--test/paint.c48
-rw-r--r--test/partial-clip-text.c120
-rw-r--r--test/partial-coverage.c680
-rw-r--r--test/pass-through.c91
-rw-r--r--test/path-append.c81
-rw-r--r--test/path-currentpoint.c89
-rw-r--r--test/path-precision.c111
-rw-r--r--test/path-stroke-twice.c54
-rw-r--r--test/pattern-get-type.c79
-rw-r--r--test/pattern-getters.c279
-rw-r--r--test/pdf-features.c148
-rw-r--r--test/pdf-isolated-group.c73
-rw-r--r--test/pdf-mime-data.c187
-rw-r--r--test/pdf-surface-source.c53
-rw-r--r--test/pdf2png.c99
-rw-r--r--test/pdiff/.gitignore3
-rw-r--r--test/pdiff/CMakeLists.txt55
-rw-r--r--test/pdiff/Makefile.am19
-rw-r--r--test/pdiff/Makefile.win3214
-rw-r--r--test/pdiff/README.txt45
-rw-r--r--test/pdiff/args.c119
-rw-r--r--test/pdiff/args.h46
-rw-r--r--test/pdiff/gpl.txt340
-rw-r--r--test/pdiff/lpyramid.c116
-rw-r--r--test/pdiff/lpyramid.h32
-rw-r--r--test/pdiff/pdiff.c420
-rw-r--r--test/pdiff/pdiff.h40
-rw-r--r--test/pdiff/perceptualdiff.c101
-rw-r--r--test/pixman-downscale.c203
-rw-r--r--test/pixman-rotate.c92
-rw-r--r--test/png-flatten.c77
-rw-r--r--test/png.c172
-rw-r--r--test/png.pngbin0 -> 2096 bytes
-rw-r--r--test/ps-eps.c354
-rw-r--r--test/ps-features.c166
-rw-r--r--test/ps-surface-source.c53
-rw-r--r--test/ps2png.c113
-rw-r--r--test/pthread-same-source.c192
-rw-r--r--test/pthread-show-text.c142
-rw-r--r--test/pthread-similar.c106
-rw-r--r--test/push-group-color.c141
-rw-r--r--test/push-group-path-offset.c77
-rw-r--r--test/push-group.c113
-rw-r--r--test/quad-color.pngbin0 -> 301 bytes
-rw-r--r--test/quartz-surface-source.c42
-rw-r--r--test/radial-gradient-extend.c92
-rw-r--r--test/radial-gradient.c256
-rw-r--r--test/radial-outer-focus.c72
-rw-r--r--test/random-clips.c232
-rw-r--r--test/random-intersections-curves-eo.c84
-rw-r--r--test/random-intersections-curves-nz.c85
-rw-r--r--test/random-intersections-eo.c78
-rw-r--r--test/random-intersections-nonzero.c79
-rw-r--r--test/raster-source.c134
-rw-r--r--test/record-extend.c288
-rw-r--r--test/record-mesh.c166
-rw-r--r--test/record.c491
-rw-r--r--test/record1414x.c498
-rw-r--r--test/record2x.c493
-rw-r--r--test/record90.c495
-rw-r--r--test/recordflip.c733
-rw-r--r--test/recording-surface-extend.c174
-rw-r--r--test/recording-surface-pattern.c162
-rw-r--r--test/rectangle-rounding-error.c64
-rw-r--r--test/rectilinear-dash-scale.c196
-rw-r--r--test/rectilinear-dash.c176
-rw-r--r--test/rectilinear-fill.c84
-rw-r--r--test/rectilinear-grid.c92
-rw-r--r--test/rectilinear-miter-limit.c72
-rw-r--r--test/rectilinear-stroke.c139
-rw-r--r--test/reference/a1-bug.base.argb32.ref.pngbin0 -> 3362 bytes
-rw-r--r--test/reference/a1-bug.base.rgb24.ref.pngbin0 -> 3362 bytes
-rw-r--r--test/reference/a1-bug.image16.ref.pngbin0 -> 3329 bytes
-rw-r--r--test/reference/a1-bug.mask.argb32.ref.pngbin0 -> 3735 bytes
-rw-r--r--test/reference/a1-bug.mask.rgb24.ref.pngbin0 -> 3735 bytes
-rw-r--r--test/reference/a1-bug.quartz.xfail.pngbin0 -> 3195 bytes
-rw-r--r--test/reference/a1-bug.ref.pngbin0 -> 3736 bytes
-rw-r--r--test/reference/a1-bug.traps.argb32.ref.pngbin0 -> 3362 bytes
-rw-r--r--test/reference/a1-bug.traps.rgb24.ref.pngbin0 -> 3362 bytes
-rw-r--r--test/reference/a1-clip-fill-equal.base.argb32.ref.pngbin0 -> 120 bytes
-rw-r--r--test/reference/a1-clip-fill-equal.base.rgb24.ref.pngbin0 -> 120 bytes
-rw-r--r--test/reference/a1-clip-fill-equal.ref.pngbin0 -> 120 bytes
-rw-r--r--test/reference/a1-clip-fill-rule.base.argb32.ref.pngbin0 -> 236 bytes
-rw-r--r--test/reference/a1-clip-fill-rule.base.rgb24.ref.pngbin0 -> 218 bytes
-rw-r--r--test/reference/a1-clip-fill-rule.ref.pngbin0 -> 236 bytes
-rw-r--r--test/reference/a1-clip-fill.base.argb32.ref.pngbin0 -> 120 bytes
-rw-r--r--test/reference/a1-clip-fill.base.rgb24.ref.pngbin0 -> 120 bytes
-rw-r--r--test/reference/a1-clip-fill.ref.pngbin0 -> 120 bytes
-rw-r--r--test/reference/a1-clip-paint.base.argb32.ref.pngbin0 -> 120 bytes
-rw-r--r--test/reference/a1-clip-paint.base.rgb24.ref.pngbin0 -> 120 bytes
-rw-r--r--test/reference/a1-clip-paint.ref.pngbin0 -> 120 bytes
-rw-r--r--test/reference/a1-clip-stroke.base.argb32.ref.pngbin0 -> 120 bytes
-rw-r--r--test/reference/a1-clip-stroke.base.rgb24.ref.pngbin0 -> 120 bytes
-rw-r--r--test/reference/a1-clip-stroke.ref.pngbin0 -> 120 bytes
-rw-r--r--test/reference/a1-fill.base.argb32.ref.pngbin0 -> 328 bytes
-rw-r--r--test/reference/a1-fill.base.rgb24.ref.pngbin0 -> 328 bytes
-rw-r--r--test/reference/a1-fill.ref.pngbin0 -> 328 bytes
-rw-r--r--test/reference/a1-image-sample.base.argb32.ref.pngbin0 -> 122 bytes
-rw-r--r--test/reference/a1-image-sample.base.rgb24.ref.pngbin0 -> 122 bytes
-rw-r--r--test/reference/a1-image-sample.gl.xfail.pngbin0 -> 120 bytes
-rw-r--r--test/reference/a1-image-sample.ref.pngbin0 -> 148 bytes
-rw-r--r--test/reference/a1-line-width.base.argb32.ref.pngbin0 -> 154 bytes
-rw-r--r--test/reference/a1-line-width.base.rgb24.ref.pngbin0 -> 154 bytes
-rw-r--r--test/reference/a1-line-width.pdf.ref.pngbin0 -> 177 bytes
-rw-r--r--test/reference/a1-line-width.ps.ref.pngbin0 -> 179 bytes
-rw-r--r--test/reference/a1-line-width.ref.pngbin0 -> 154 bytes
-rw-r--r--test/reference/a1-mask-sample.base.argb32.ref.pngbin0 -> 122 bytes
-rw-r--r--test/reference/a1-mask-sample.base.rgb24.ref.pngbin0 -> 122 bytes
-rw-r--r--test/reference/a1-mask-sample.ref.pngbin0 -> 148 bytes
-rw-r--r--test/reference/a1-mask.base.argb32.ref.pngbin0 -> 106 bytes
-rw-r--r--test/reference/a1-mask.base.rgb24.ref.pngbin0 -> 106 bytes
-rw-r--r--test/reference/a1-mask.ref.pngbin0 -> 131 bytes
-rw-r--r--test/reference/a1-rasterisation-rectangles.base.argb32.ref.pngbin0 -> 1729 bytes
-rw-r--r--test/reference/a1-rasterisation-rectangles.base.rgb24.ref.pngbin0 -> 1729 bytes
-rw-r--r--test/reference/a1-rasterisation-rectangles.quartz.xfail.pngbin0 -> 2583 bytes
-rw-r--r--test/reference/a1-rasterisation-rectangles.ref.pngbin0 -> 1729 bytes
-rw-r--r--test/reference/a1-rasterisation-triangles.base.argb32.ref.pngbin0 -> 1729 bytes
-rw-r--r--test/reference/a1-rasterisation-triangles.base.rgb24.ref.pngbin0 -> 1729 bytes
-rw-r--r--test/reference/a1-rasterisation-triangles.quartz.xfail.pngbin0 -> 2583 bytes
-rw-r--r--test/reference/a1-rasterisation-triangles.ref.pngbin0 -> 1729 bytes
-rw-r--r--test/reference/a1-rectilinear-grid.base.argb32.ref.pngbin0 -> 207 bytes
-rw-r--r--test/reference/a1-rectilinear-grid.base.rgb24.ref.pngbin0 -> 207 bytes
-rw-r--r--test/reference/a1-rectilinear-grid.ref.pngbin0 -> 207 bytes
-rw-r--r--test/reference/a1-sample.base.argb32.ref.pngbin0 -> 786 bytes
-rw-r--r--test/reference/a1-sample.base.rgb24.ref.pngbin0 -> 786 bytes
-rw-r--r--test/reference/a1-sample.ref.pngbin0 -> 786 bytes
-rw-r--r--test/reference/a1-tiger.base.argb32.ref.pngbin0 -> 20406 bytes
-rw-r--r--test/reference/a1-tiger.base.rgb24.ref.pngbin0 -> 20406 bytes
-rw-r--r--test/reference/a1-tiger.mask.argb32.ref.pngbin0 -> 20328 bytes
-rw-r--r--test/reference/a1-tiger.mask.rgb24.ref.pngbin0 -> 20328 bytes
-rw-r--r--test/reference/a1-tiger.ref.pngbin0 -> 20326 bytes
-rw-r--r--test/reference/a1-tiger.traps.argb32.ref.pngbin0 -> 20326 bytes
-rw-r--r--test/reference/a1-tiger.traps.rgb24.ref.pngbin0 -> 20326 bytes
-rw-r--r--test/reference/a1-traps-sample.base.argb32.ref.pngbin0 -> 120 bytes
-rw-r--r--test/reference/a1-traps-sample.base.rgb24.ref.pngbin0 -> 120 bytes
-rw-r--r--test/reference/a1-traps-sample.quartz.xfail.pngbin0 -> 122 bytes
-rw-r--r--test/reference/a1-traps-sample.ref.pngbin0 -> 120 bytes
-rw-r--r--test/reference/a8-clear.base.argb32.ref.pngbin0 -> 248 bytes
-rw-r--r--test/reference/a8-clear.base.rgb24.ref.pngbin0 -> 248 bytes
-rw-r--r--test/reference/a8-clear.quartz.ref.pngbin0 -> 244 bytes
-rw-r--r--test/reference/a8-clear.ref.pngbin0 -> 267 bytes
-rw-r--r--test/reference/a8-clear.traps.argb32.ref.pngbin0 -> 248 bytes
-rw-r--r--test/reference/a8-clear.traps.rgb24.ref.pngbin0 -> 248 bytes
-rw-r--r--test/reference/a8-mask.base.argb32.ref.pngbin0 -> 103 bytes
-rw-r--r--test/reference/a8-mask.base.rgb24.ref.pngbin0 -> 103 bytes
-rw-r--r--test/reference/a8-mask.ref.pngbin0 -> 128 bytes
-rw-r--r--test/reference/aliasing.base.argb32.ref.pngbin0 -> 103722 bytes
-rw-r--r--test/reference/aliasing.base.rgb24.ref.pngbin0 -> 103722 bytes
-rw-r--r--test/reference/aliasing.image16.ref.pngbin0 -> 97251 bytes
-rw-r--r--test/reference/aliasing.quartz.ref.pngbin0 -> 108801 bytes
-rw-r--r--test/reference/aliasing.ref.pngbin0 -> 103877 bytes
-rw-r--r--test/reference/aliasing.traps.argb32.ref.pngbin0 -> 103722 bytes
-rw-r--r--test/reference/aliasing.traps.rgb24.ref.pngbin0 -> 103722 bytes
-rw-r--r--test/reference/alpha-similar.base.argb32.ref.pngbin0 -> 99 bytes
-rw-r--r--test/reference/alpha-similar.base.rgb24.ref.pngbin0 -> 88 bytes
-rw-r--r--test/reference/alpha-similar.gl.argb32.xfail.pngbin0 -> 99 bytes
-rw-r--r--test/reference/alpha-similar.gl.rgb24.xfail.pngbin0 -> 93 bytes
-rw-r--r--test/reference/alpha-similar.pdf.argb32.xfail.pngbin0 -> 95 bytes
-rw-r--r--test/reference/alpha-similar.pdf.rgb24.xfail.pngbin0 -> 93 bytes
-rw-r--r--test/reference/alpha-similar.ps.argb32.xfail.pngbin0 -> 95 bytes
-rw-r--r--test/reference/alpha-similar.ps.rgb24.xfail.pngbin0 -> 93 bytes
-rw-r--r--test/reference/alpha-similar.ref.pngbin0 -> 99 bytes
-rw-r--r--test/reference/alpha-similar.svg.argb32.xfail.pngbin0 -> 99 bytes
-rw-r--r--test/reference/alpha-similar.svg.rgb24.xfail.pngbin0 -> 95 bytes
-rw-r--r--test/reference/api-special-cases.base.argb32.ref.pngbin0 -> 95 bytes
-rw-r--r--test/reference/api-special-cases.base.rgb24.ref.pngbin0 -> 95 bytes
-rw-r--r--test/reference/api-special-cases.ref.pngbin0 -> 95 bytes
-rw-r--r--test/reference/arc-direction.base.argb32.ref.pngbin0 -> 5864 bytes
-rw-r--r--test/reference/arc-direction.base.rgb24.ref.pngbin0 -> 5864 bytes
-rw-r--r--test/reference/arc-direction.ps.ref.pngbin0 -> 3295 bytes
-rw-r--r--test/reference/arc-direction.ref.pngbin0 -> 6073 bytes
-rw-r--r--test/reference/arc-direction.traps.ref.pngbin0 -> 5864 bytes
-rw-r--r--test/reference/arc-infinite-loop.base.argb32.ref.pngbin0 -> 96 bytes
-rw-r--r--test/reference/arc-infinite-loop.base.rgb24.ref.pngbin0 -> 96 bytes
-rw-r--r--test/reference/arc-infinite-loop.ref.pngbin0 -> 96 bytes
-rw-r--r--test/reference/arc-looping-dash.image16.ref.pngbin0 -> 450 bytes
-rw-r--r--test/reference/arc-looping-dash.mask.argb32.ref.pngbin0 -> 464 bytes
-rw-r--r--test/reference/arc-looping-dash.mask.rgb24.ref.pngbin0 -> 464 bytes
-rw-r--r--test/reference/arc-looping-dash.ps.ref.pngbin0 -> 377 bytes
-rw-r--r--test/reference/arc-looping-dash.quartz.ref.pngbin0 -> 470 bytes
-rw-r--r--test/reference/arc-looping-dash.ref.pngbin0 -> 464 bytes
-rw-r--r--test/reference/arc-looping-dash.traps.argb32.ref.pngbin0 -> 496 bytes
-rw-r--r--test/reference/arc-looping-dash.traps.rgb24.ref.pngbin0 -> 496 bytes
-rw-r--r--test/reference/big-empty-box.base.argb32.ref.pngbin0 -> 111 bytes
-rw-r--r--test/reference/big-empty-box.base.rgb24.ref.pngbin0 -> 108 bytes
-rw-r--r--test/reference/big-empty-box.ref.pngbin0 -> 111 bytes
-rw-r--r--test/reference/big-empty-triangle.base.argb32.ref.pngbin0 -> 111 bytes
-rw-r--r--test/reference/big-empty-triangle.base.rgb24.ref.pngbin0 -> 108 bytes
-rw-r--r--test/reference/big-empty-triangle.ref.pngbin0 -> 111 bytes
-rw-r--r--test/reference/big-line.base.argb32.ref.pngbin0 -> 933 bytes
-rw-r--r--test/reference/big-line.base.rgb24.ref.pngbin0 -> 933 bytes
-rw-r--r--test/reference/big-line.image16.ref.pngbin0 -> 988 bytes
-rw-r--r--test/reference/big-line.ps.ref.pngbin0 -> 946 bytes
-rw-r--r--test/reference/big-line.quartz.ref.pngbin0 -> 993 bytes
-rw-r--r--test/reference/big-line.ref.pngbin0 -> 999 bytes
-rw-r--r--test/reference/big-line.traps.argb32.ref.pngbin0 -> 933 bytes
-rw-r--r--test/reference/big-line.traps.rgb24.ref.pngbin0 -> 933 bytes
-rw-r--r--test/reference/big-little-box.base.argb32.ref.pngbin0 -> 169 bytes
-rw-r--r--test/reference/big-little-box.base.rgb24.ref.pngbin0 -> 160 bytes
-rw-r--r--test/reference/big-little-box.ref.pngbin0 -> 169 bytes
-rw-r--r--test/reference/big-little-triangle.argb32.ref.pngbin0 -> 399 bytes
-rw-r--r--test/reference/big-little-triangle.base.argb32.ref.pngbin0 -> 399 bytes
-rw-r--r--test/reference/big-little-triangle.base.rgb24.ref.pngbin0 -> 320 bytes
-rw-r--r--test/reference/big-little-triangle.rgb24.ref.pngbin0 -> 320 bytes
-rw-r--r--test/reference/big-little-triangle.traps.argb32.ref.pngbin0 -> 399 bytes
-rw-r--r--test/reference/big-little-triangle.traps.rgb24.ref.pngbin0 -> 320 bytes
-rw-r--r--test/reference/big-trap.base.argb32.ref.pngbin0 -> 319 bytes
-rw-r--r--test/reference/big-trap.base.rgb24.ref.pngbin0 -> 319 bytes
-rw-r--r--test/reference/big-trap.mask.argb32.ref.pngbin0 -> 319 bytes
-rw-r--r--test/reference/big-trap.mask.rgb24.ref.pngbin0 -> 319 bytes
-rw-r--r--test/reference/big-trap.traps.argb32.ref.pngbin0 -> 319 bytes
-rw-r--r--test/reference/big-trap.traps.rgb24.ref.pngbin0 -> 319 bytes
-rw-r--r--test/reference/bilevel-image.base.argb32.ref.pngbin0 -> 105 bytes
-rw-r--r--test/reference/bilevel-image.base.rgb24.ref.pngbin0 -> 105 bytes
-rw-r--r--test/reference/bilevel-image.ref.pngbin0 -> 131 bytes
-rw-r--r--test/reference/bilevel-xlib-fallback.rgb24.ref.pngbin0 -> 105 bytes
-rw-r--r--test/reference/bilevel-xlib-window.rgb24.ref.pngbin0 -> 105 bytes
-rw-r--r--test/reference/bilevel-xlib.ref.pngbin0 -> 105 bytes
-rw-r--r--test/reference/bitmap-font.base.argb32.ref.pngbin0 -> 931 bytes
-rw-r--r--test/reference/bitmap-font.base.rgb24.ref.pngbin0 -> 871 bytes
-rw-r--r--test/reference/bitmap-font.ref.pngbin0 -> 950 bytes
-rw-r--r--test/reference/blur.ref.pngbin0 -> 24543 bytes
-rw-r--r--test/reference/bug-40410.base.argb32.ref.pngbin0 -> 428 bytes
-rw-r--r--test/reference/bug-40410.base.rgb24.ref.pngbin0 -> 428 bytes
-rw-r--r--test/reference/bug-40410.ref.pngbin0 -> 429 bytes
-rw-r--r--test/reference/bug-40410.traps.argb32.ref.pngbin0 -> 428 bytes
-rw-r--r--test/reference/bug-40410.traps.rgb24.ref.pngbin0 -> 428 bytes
-rw-r--r--test/reference/bug-51910.ref.pngbin0 -> 1987 bytes
-rw-r--r--test/reference/bug-84115.ref.pngbin0 -> 62964 bytes
-rw-r--r--test/reference/bug-84115.xlib.ref.pngbin0 -> 65033 bytes
-rw-r--r--test/reference/bug-bo-collins.ref.pngbin0 -> 248 bytes
-rw-r--r--test/reference/bug-bo-rectangular.base.argb32.ref.pngbin0 -> 950 bytes
-rw-r--r--test/reference/bug-bo-rectangular.base.rgb24.ref.pngbin0 -> 950 bytes
-rw-r--r--test/reference/bug-bo-rectangular.image16.ref.pngbin0 -> 955 bytes
-rw-r--r--test/reference/bug-bo-rectangular.ps.xfail.pngbin0 -> 945 bytes
-rw-r--r--test/reference/bug-bo-rectangular.ref.pngbin0 -> 950 bytes
-rw-r--r--test/reference/bug-bo-ricotz.base.argb32.ref.pngbin0 -> 2125 bytes
-rw-r--r--test/reference/bug-bo-ricotz.base.rgb24.ref.pngbin0 -> 2125 bytes
-rw-r--r--test/reference/bug-bo-ricotz.ref.pngbin0 -> 2128 bytes
-rw-r--r--test/reference/bug-bo-ricotz.traps.ref.pngbin0 -> 2125 bytes
-rw-r--r--test/reference/bug-extents.base.argb32.ref.pngbin0 -> 9250 bytes
-rw-r--r--test/reference/bug-extents.base.rgb24.ref.pngbin0 -> 9250 bytes
-rw-r--r--test/reference/bug-extents.image16.ref.pngbin0 -> 7576 bytes
-rw-r--r--test/reference/bug-extents.ps.ref.pngbin0 -> 5844 bytes
-rw-r--r--test/reference/bug-extents.quartz.ref.pngbin0 -> 9310 bytes
-rw-r--r--test/reference/bug-extents.ref.pngbin0 -> 9211 bytes
-rw-r--r--test/reference/bug-extents.traps.argb32.ref.pngbin0 -> 9250 bytes
-rw-r--r--test/reference/bug-extents.traps.rgb24.ref.pngbin0 -> 9250 bytes
-rw-r--r--test/reference/bug-seams.base.argb32.ref.pngbin0 -> 1606 bytes
-rw-r--r--test/reference/bug-seams.base.rgb24.ref.pngbin0 -> 1606 bytes
-rw-r--r--test/reference/bug-seams.image.xfail.pngbin0 -> 1647 bytes
-rw-r--r--test/reference/bug-seams.mask.argb32.ref.pngbin0 -> 1647 bytes
-rw-r--r--test/reference/bug-seams.mask.rgb24.ref.pngbin0 -> 1647 bytes
-rw-r--r--test/reference/bug-seams.ref.pngbin0 -> 1638 bytes
-rw-r--r--test/reference/bug-seams.traps.argb32.ref.pngbin0 -> 1606 bytes
-rw-r--r--test/reference/bug-seams.traps.rgb24.ref.pngbin0 -> 1606 bytes
-rw-r--r--test/reference/bug-seams.xlib-fallback.ref.pngbin0 -> 2133 bytes
-rw-r--r--test/reference/bug-source-cu.ref.pngbin0 -> 3815 bytes
-rw-r--r--test/reference/bug-source-cu.traps.argb32.ref.pngbin0 -> 3816 bytes
-rw-r--r--test/reference/bug-source-cu.traps.rgb24.ref.pngbin0 -> 3212 bytes
-rw-r--r--test/reference/bug-spline.ref.pngbin0 -> 5405 bytes
-rw-r--r--test/reference/caps-05.ref.pngbin0 -> 1375 bytes
-rw-r--r--test/reference/caps-05.traps.ref.pngbin0 -> 1126 bytes
-rw-r--r--test/reference/caps-1.ref.pngbin0 -> 1457 bytes
-rw-r--r--test/reference/caps-1.traps.ref.pngbin0 -> 1268 bytes
-rw-r--r--test/reference/caps-2.ref.pngbin0 -> 1509 bytes
-rw-r--r--test/reference/caps-2.traps.ref.pngbin0 -> 1231 bytes
-rw-r--r--test/reference/caps-joins-05.ref.pngbin0 -> 2169 bytes
-rw-r--r--test/reference/caps-joins-05.traps.ref.pngbin0 -> 1714 bytes
-rw-r--r--test/reference/caps-joins-1.ref.pngbin0 -> 2105 bytes
-rw-r--r--test/reference/caps-joins-1.traps.ref.pngbin0 -> 1861 bytes
-rw-r--r--test/reference/caps-joins-2.ref.pngbin0 -> 2046 bytes
-rw-r--r--test/reference/caps-joins-2.traps.ref.pngbin0 -> 1631 bytes
-rw-r--r--test/reference/caps-joins-alpha.image16.ref.pngbin0 -> 2268 bytes
-rw-r--r--test/reference/caps-joins-alpha.mask.argb32.ref.pngbin0 -> 2662 bytes
-rw-r--r--test/reference/caps-joins-alpha.mask.rgb24.ref.pngbin0 -> 2662 bytes
-rw-r--r--test/reference/caps-joins-alpha.quartz.ref.pngbin0 -> 2466 bytes
-rw-r--r--test/reference/caps-joins-alpha.ref.pngbin0 -> 2420 bytes
-rw-r--r--test/reference/caps-joins-alpha.traps.argb32.ref.pngbin0 -> 2265 bytes
-rw-r--r--test/reference/caps-joins-alpha.traps.rgb24.ref.pngbin0 -> 2265 bytes
-rw-r--r--test/reference/caps-joins-curve.image16.ref.pngbin0 -> 4928 bytes
-rw-r--r--test/reference/caps-joins-curve.mask.argb32.ref.pngbin0 -> 6217 bytes
-rw-r--r--test/reference/caps-joins-curve.mask.rgb24.ref.pngbin0 -> 6217 bytes
-rw-r--r--test/reference/caps-joins-curve.ps.ref.pngbin0 -> 3715 bytes
-rw-r--r--test/reference/caps-joins-curve.quartz.ref.pngbin0 -> 5199 bytes
-rw-r--r--test/reference/caps-joins-curve.ref.pngbin0 -> 5681 bytes
-rw-r--r--test/reference/caps-joins-curve.traps.argb32.ref.pngbin0 -> 5327 bytes
-rw-r--r--test/reference/caps-joins-curve.traps.rgb24.ref.pngbin0 -> 5327 bytes
-rw-r--r--test/reference/caps-joins.base.argb32.ref.pngbin0 -> 2363 bytes
-rw-r--r--test/reference/caps-joins.base.rgb24.ref.pngbin0 -> 2363 bytes
-rw-r--r--test/reference/caps-joins.image16.ref.pngbin0 -> 2587 bytes
-rw-r--r--test/reference/caps-joins.ps.ref.pngbin0 -> 2268 bytes
-rw-r--r--test/reference/caps-joins.ref.pngbin0 -> 2560 bytes
-rw-r--r--test/reference/caps-joins.traps.argb32.ref.pngbin0 -> 2363 bytes
-rw-r--r--test/reference/caps-joins.traps.rgb24.ref.pngbin0 -> 2363 bytes
-rw-r--r--test/reference/caps-sub-paths.base.argb32.ref.pngbin0 -> 166 bytes
-rw-r--r--test/reference/caps-sub-paths.base.rgb24.ref.pngbin0 -> 166 bytes
-rw-r--r--test/reference/caps-sub-paths.image16.ref.pngbin0 -> 171 bytes
-rw-r--r--test/reference/caps-sub-paths.ps.ref.pngbin0 -> 163 bytes
-rw-r--r--test/reference/caps-sub-paths.ref.pngbin0 -> 168 bytes
-rw-r--r--test/reference/caps-sub-paths.traps.argb32.ref.pngbin0 -> 166 bytes
-rw-r--r--test/reference/caps-sub-paths.traps.rgb24.ref.pngbin0 -> 166 bytes
-rw-r--r--test/reference/caps-tails-curve.mask.argb32.ref.pngbin0 -> 53311 bytes
-rw-r--r--test/reference/caps-tails-curve.mask.rgb24.ref.pngbin0 -> 53311 bytes
-rw-r--r--test/reference/caps-tails-curve.ps.ref.pngbin0 -> 39753 bytes
-rw-r--r--test/reference/caps-tails-curve.ref.pngbin0 -> 53182 bytes
-rw-r--r--test/reference/caps-tails-curve.traps.argb32.ref.pngbin0 -> 49798 bytes
-rw-r--r--test/reference/caps-tails-curve.traps.rgb24.ref.pngbin0 -> 49798 bytes
-rw-r--r--test/reference/caps-tails-curve.xcb.ref.pngbin0 -> 50367 bytes
-rw-r--r--test/reference/caps.base.argb32.ref.pngbin0 -> 1637 bytes
-rw-r--r--test/reference/caps.base.rgb24.ref.pngbin0 -> 1637 bytes
-rw-r--r--test/reference/caps.image16.ref.pngbin0 -> 1936 bytes
-rw-r--r--test/reference/caps.ps.ref.pngbin0 -> 1478 bytes
-rw-r--r--test/reference/caps.ref.pngbin0 -> 2115 bytes
-rw-r--r--test/reference/caps.traps.argb32.ref.pngbin0 -> 1637 bytes
-rw-r--r--test/reference/caps.traps.rgb24.ref.pngbin0 -> 1637 bytes
-rw-r--r--test/reference/checkerboard.base.argb32.ref.pngbin0 -> 142 bytes
-rw-r--r--test/reference/checkerboard.base.rgb24.ref.pngbin0 -> 142 bytes
-rw-r--r--test/reference/checkerboard.ref.pngbin0 -> 142 bytes
-rw-r--r--test/reference/clear-source.base.argb32.ref.pngbin0 -> 882 bytes
-rw-r--r--test/reference/clear-source.base.rgb24.ref.pngbin0 -> 882 bytes
-rw-r--r--test/reference/clear-source.image16.ref.pngbin0 -> 909 bytes
-rw-r--r--test/reference/clear-source.pdf.xfail.pngbin0 -> 974 bytes
-rw-r--r--test/reference/clear-source.ps.xfail.pngbin0 -> 552 bytes
-rw-r--r--test/reference/clear-source.ref.pngbin0 -> 882 bytes
-rw-r--r--test/reference/clear-source.traps.argb32.ref.pngbin0 -> 882 bytes
-rw-r--r--test/reference/clear-source.traps.rgb24.ref.pngbin0 -> 882 bytes
-rw-r--r--test/reference/clear.argb32.ref.pngbin0 -> 701 bytes
-rw-r--r--test/reference/clear.base.argb32.ref.pngbin0 -> 673 bytes
-rw-r--r--test/reference/clear.base.rgb24.ref.pngbin0 -> 614 bytes
-rw-r--r--test/reference/clear.pdf.argb32.ref.pngbin0 -> 790 bytes
-rw-r--r--test/reference/clear.ps.argb32.ref.pngbin0 -> 790 bytes
-rw-r--r--test/reference/clear.quartz.argb32.ref.pngbin0 -> 691 bytes
-rw-r--r--test/reference/clear.quartz.rgb24.ref.pngbin0 -> 606 bytes
-rw-r--r--test/reference/clear.rgb24.ref.pngbin0 -> 624 bytes
-rw-r--r--test/reference/clear.svg12.argb32.xfail.pngbin0 -> 170 bytes
-rw-r--r--test/reference/clear.svg12.rgb24.xfail.pngbin0 -> 170 bytes
-rw-r--r--test/reference/clear.traps.argb32.ref.pngbin0 -> 673 bytes
-rw-r--r--test/reference/clear.traps.rgb24.ref.pngbin0 -> 614 bytes
-rw-r--r--test/reference/clip-all.base.argb32.ref.pngbin0 -> 95 bytes
-rw-r--r--test/reference/clip-all.base.rgb24.ref.pngbin0 -> 95 bytes
-rw-r--r--test/reference/clip-all.ref.pngbin0 -> 118 bytes
-rw-r--r--test/reference/clip-complex-bug61492.ref.pngbin0 -> 105 bytes
-rw-r--r--test/reference/clip-complex-shape-eo-aa.base.argb32.ref.pngbin0 -> 325 bytes
-rw-r--r--test/reference/clip-complex-shape-eo-aa.base.rgb24.ref.pngbin0 -> 325 bytes
-rw-r--r--test/reference/clip-complex-shape-eo-aa.ref.pngbin0 -> 349 bytes
-rw-r--r--test/reference/clip-complex-shape-eo-mono.base.argb32.ref.pngbin0 -> 325 bytes
-rw-r--r--test/reference/clip-complex-shape-eo-mono.base.rgb24.ref.pngbin0 -> 325 bytes
-rw-r--r--test/reference/clip-complex-shape-eo-mono.ref.pngbin0 -> 349 bytes
-rw-r--r--test/reference/clip-contexts.base.argb32.ref.pngbin0 -> 98 bytes
-rw-r--r--test/reference/clip-contexts.base.rgb24.ref.pngbin0 -> 98 bytes
-rw-r--r--test/reference/clip-contexts.ref.pngbin0 -> 98 bytes
-rw-r--r--test/reference/clip-device-offset.base.argb32.ref.pngbin0 -> 175 bytes
-rw-r--r--test/reference/clip-device-offset.base.rgb24.ref.pngbin0 -> 168 bytes
-rw-r--r--test/reference/clip-device-offset.ref.pngbin0 -> 175 bytes
-rw-r--r--test/reference/clip-disjoint-hatching.base.argb32.ref.pngbin0 -> 7948 bytes
-rw-r--r--test/reference/clip-disjoint-hatching.base.rgb24.ref.pngbin0 -> 7948 bytes
-rw-r--r--test/reference/clip-disjoint-hatching.mask.argb32.ref.pngbin0 -> 8789 bytes
-rw-r--r--test/reference/clip-disjoint-hatching.mask.rgb24.ref.pngbin0 -> 8789 bytes
-rw-r--r--test/reference/clip-disjoint-hatching.ref.pngbin0 -> 7918 bytes
-rw-r--r--test/reference/clip-disjoint-hatching.traps.argb32.ref.pngbin0 -> 7953 bytes
-rw-r--r--test/reference/clip-disjoint-hatching.traps.rgb24.ref.pngbin0 -> 7953 bytes
-rw-r--r--test/reference/clip-disjoint-quad.ref.pngbin0 -> 1642 bytes
-rw-r--r--test/reference/clip-disjoint-quad.traps.ref.pngbin0 -> 1542 bytes
-rw-r--r--test/reference/clip-disjoint.base.argb32.ref.pngbin0 -> 5411 bytes
-rw-r--r--test/reference/clip-disjoint.base.rgb24.ref.pngbin0 -> 5411 bytes
-rw-r--r--test/reference/clip-disjoint.image16.ref.pngbin0 -> 3886 bytes
-rw-r--r--test/reference/clip-disjoint.mask.argb32.ref.pngbin0 -> 5399 bytes
-rw-r--r--test/reference/clip-disjoint.mask.rgb24.ref.pngbin0 -> 5399 bytes
-rw-r--r--test/reference/clip-disjoint.ps.ref.pngbin0 -> 4037 bytes
-rw-r--r--test/reference/clip-disjoint.quartz.ref.pngbin0 -> 5476 bytes
-rw-r--r--test/reference/clip-disjoint.ref.pngbin0 -> 5348 bytes
-rw-r--r--test/reference/clip-disjoint.traps.argb32.ref.pngbin0 -> 5411 bytes
-rw-r--r--test/reference/clip-disjoint.traps.rgb24.ref.pngbin0 -> 5411 bytes
-rw-r--r--test/reference/clip-empty-group.base.argb32.ref.pngbin0 -> 103 bytes
-rw-r--r--test/reference/clip-empty-group.base.rgb24.ref.pngbin0 -> 103 bytes
-rw-r--r--test/reference/clip-empty-group.ref.pngbin0 -> 103 bytes
-rw-r--r--test/reference/clip-empty-save.base.argb32.ref.pngbin0 -> 95 bytes
-rw-r--r--test/reference/clip-empty-save.base.rgb24.ref.pngbin0 -> 95 bytes
-rw-r--r--test/reference/clip-empty-save.ref.pngbin0 -> 118 bytes
-rw-r--r--test/reference/clip-empty.base.argb32.ref.pngbin0 -> 95 bytes
-rw-r--r--test/reference/clip-empty.base.rgb24.ref.pngbin0 -> 95 bytes
-rw-r--r--test/reference/clip-empty.ref.pngbin0 -> 118 bytes
-rw-r--r--test/reference/clip-fill-eo-unbounded.argb32.ref.pngbin0 -> 4053 bytes
-rw-r--r--test/reference/clip-fill-eo-unbounded.base.argb32.ref.pngbin0 -> 3735 bytes
-rw-r--r--test/reference/clip-fill-eo-unbounded.base.rgb24.ref.pngbin0 -> 3224 bytes
-rw-r--r--test/reference/clip-fill-eo-unbounded.image16.ref.pngbin0 -> 2887 bytes
-rw-r--r--test/reference/clip-fill-eo-unbounded.mask.argb32.ref.pngbin0 -> 3769 bytes
-rw-r--r--test/reference/clip-fill-eo-unbounded.mask.rgb24.ref.pngbin0 -> 3211 bytes
-rw-r--r--test/reference/clip-fill-eo-unbounded.quartz.argb32.ref.pngbin0 -> 3382 bytes
-rw-r--r--test/reference/clip-fill-eo-unbounded.quartz.rgb24.ref.pngbin0 -> 2941 bytes
-rw-r--r--test/reference/clip-fill-eo-unbounded.rgb24.ref.pngbin0 -> 3408 bytes
-rw-r--r--test/reference/clip-fill-eo-unbounded.svg12.rgb24.xfail.pngbin0 -> 3636 bytes
-rw-r--r--test/reference/clip-fill-eo-unbounded.traps.argb32.ref.pngbin0 -> 3693 bytes
-rw-r--r--test/reference/clip-fill-eo-unbounded.traps.rgb24.ref.pngbin0 -> 3198 bytes
-rw-r--r--test/reference/clip-fill-eo-unbounded.xlib-fallback.rgb24.ref.pngbin0 -> 3208 bytes
-rw-r--r--test/reference/clip-fill-no-op.base.argb32.ref.pngbin0 -> 152 bytes
-rw-r--r--test/reference/clip-fill-no-op.base.rgb24.ref.pngbin0 -> 152 bytes
-rw-r--r--test/reference/clip-fill-no-op.image16.ref.pngbin0 -> 153 bytes
-rw-r--r--test/reference/clip-fill-no-op.ref.pngbin0 -> 152 bytes
-rw-r--r--test/reference/clip-fill-nz-unbounded.argb32.ref.pngbin0 -> 4053 bytes
-rw-r--r--test/reference/clip-fill-nz-unbounded.base.argb32.ref.pngbin0 -> 3735 bytes
-rw-r--r--test/reference/clip-fill-nz-unbounded.base.rgb24.ref.pngbin0 -> 3224 bytes
-rw-r--r--test/reference/clip-fill-nz-unbounded.image16.ref.pngbin0 -> 2887 bytes
-rw-r--r--test/reference/clip-fill-nz-unbounded.mask.argb32.ref.pngbin0 -> 3764 bytes
-rw-r--r--test/reference/clip-fill-nz-unbounded.mask.rgb24.ref.pngbin0 -> 3215 bytes
-rw-r--r--test/reference/clip-fill-nz-unbounded.quartz.argb32.ref.pngbin0 -> 3382 bytes
-rw-r--r--test/reference/clip-fill-nz-unbounded.quartz.rgb24.ref.pngbin0 -> 2941 bytes
-rw-r--r--test/reference/clip-fill-nz-unbounded.rgb24.ref.pngbin0 -> 3408 bytes
-rw-r--r--test/reference/clip-fill-nz-unbounded.svg12.rgb24.xfail.pngbin0 -> 3636 bytes
-rw-r--r--test/reference/clip-fill-nz-unbounded.traps.argb32.ref.pngbin0 -> 3693 bytes
-rw-r--r--test/reference/clip-fill-nz-unbounded.traps.rgb24.ref.pngbin0 -> 3198 bytes
-rw-r--r--test/reference/clip-fill-nz-unbounded.xlib-fallback.rgb24.ref.pngbin0 -> 3208 bytes
-rw-r--r--test/reference/clip-fill-rule-pixel-aligned.base.argb32.ref.pngbin0 -> 176 bytes
-rw-r--r--test/reference/clip-fill-rule-pixel-aligned.base.rgb24.ref.pngbin0 -> 165 bytes
-rw-r--r--test/reference/clip-fill-rule-pixel-aligned.ref.pngbin0 -> 195 bytes
-rw-r--r--test/reference/clip-fill-rule.argb32.ref.pngbin0 -> 430 bytes
-rw-r--r--test/reference/clip-fill-rule.base.argb32.ref.pngbin0 -> 437 bytes
-rw-r--r--test/reference/clip-fill-rule.base.rgb24.ref.pngbin0 -> 393 bytes
-rw-r--r--test/reference/clip-fill-rule.image16.ref.pngbin0 -> 356 bytes
-rw-r--r--test/reference/clip-fill-rule.pdf.argb32.ref.pngbin0 -> 509 bytes
-rw-r--r--test/reference/clip-fill-rule.ps.argb32.ref.pngbin0 -> 251 bytes
-rw-r--r--test/reference/clip-fill-rule.ps.rgb24.ref.pngbin0 -> 234 bytes
-rw-r--r--test/reference/clip-fill-rule.quartz.rgb24.ref.pngbin0 -> 363 bytes
-rw-r--r--test/reference/clip-fill-rule.rgb24.ref.pngbin0 -> 376 bytes
-rw-r--r--test/reference/clip-fill-rule.test-paginated.rgb24.ref.pngbin0 -> 361 bytes
-rw-r--r--test/reference/clip-fill-rule.traps.argb32.ref.pngbin0 -> 412 bytes
-rw-r--r--test/reference/clip-fill-rule.traps.rgb24.ref.pngbin0 -> 361 bytes
-rw-r--r--test/reference/clip-fill.base.argb32.ref.pngbin0 -> 1039 bytes
-rw-r--r--test/reference/clip-fill.base.rgb24.ref.pngbin0 -> 1039 bytes
-rw-r--r--test/reference/clip-fill.image16.ref.pngbin0 -> 904 bytes
-rw-r--r--test/reference/clip-fill.mask.argb32.ref.pngbin0 -> 1039 bytes
-rw-r--r--test/reference/clip-fill.mask.rgb24.ref.pngbin0 -> 1039 bytes
-rw-r--r--test/reference/clip-fill.ps.xfail.pngbin0 -> 522 bytes
-rw-r--r--test/reference/clip-fill.quartz.ref.pngbin0 -> 875 bytes
-rw-r--r--test/reference/clip-fill.ref.pngbin0 -> 1046 bytes
-rw-r--r--test/reference/clip-fill.traps.argb32.ref.pngbin0 -> 1049 bytes
-rw-r--r--test/reference/clip-fill.traps.rgb24.ref.pngbin0 -> 1049 bytes
-rw-r--r--test/reference/clip-fill.xlib-fallback.ref.pngbin0 -> 1063 bytes
-rw-r--r--test/reference/clip-group-shapes-aligned-rectangles.base.argb32.ref.pngbin0 -> 378 bytes
-rw-r--r--test/reference/clip-group-shapes-aligned-rectangles.base.rgb24.ref.pngbin0 -> 378 bytes
-rw-r--r--test/reference/clip-group-shapes-aligned-rectangles.ref.pngbin0 -> 378 bytes
-rw-r--r--test/reference/clip-group-shapes-circles.base.argb32.ref.pngbin0 -> 1511 bytes
-rw-r--r--test/reference/clip-group-shapes-circles.base.rgb24.ref.pngbin0 -> 1511 bytes
-rw-r--r--test/reference/clip-group-shapes-circles.mask.argb32.ref.pngbin0 -> 1511 bytes
-rw-r--r--test/reference/clip-group-shapes-circles.mask.rgb24.ref.pngbin0 -> 1511 bytes
-rw-r--r--test/reference/clip-group-shapes-circles.ps.ref.pngbin0 -> 678 bytes
-rw-r--r--test/reference/clip-group-shapes-circles.quartz.ref.pngbin0 -> 1518 bytes
-rw-r--r--test/reference/clip-group-shapes-circles.ref.pngbin0 -> 1504 bytes
-rw-r--r--test/reference/clip-group-shapes-circles.traps.argb32.ref.pngbin0 -> 1530 bytes
-rw-r--r--test/reference/clip-group-shapes-circles.traps.rgb24.ref.pngbin0 -> 1530 bytes
-rw-r--r--test/reference/clip-group-shapes-unaligned-rectangles.base.argb32.ref.pngbin0 -> 415 bytes
-rw-r--r--test/reference/clip-group-shapes-unaligned-rectangles.base.rgb24.ref.pngbin0 -> 415 bytes
-rw-r--r--test/reference/clip-group-shapes-unaligned-rectangles.mask.argb32.ref.pngbin0 -> 431 bytes
-rw-r--r--test/reference/clip-group-shapes-unaligned-rectangles.mask.rgb24.ref.pngbin0 -> 431 bytes
-rw-r--r--test/reference/clip-group-shapes-unaligned-rectangles.ref.pngbin0 -> 415 bytes
-rw-r--r--test/reference/clip-group-shapes-unaligned-rectangles.traps.argb32.ref.pngbin0 -> 431 bytes
-rw-r--r--test/reference/clip-group-shapes-unaligned-rectangles.traps.rgb24.ref.pngbin0 -> 431 bytes
-rw-r--r--test/reference/clip-image.base.argb32.ref.pngbin0 -> 2677 bytes
-rw-r--r--test/reference/clip-image.base.rgb24.ref.pngbin0 -> 2677 bytes
-rw-r--r--test/reference/clip-image.image16.ref.pngbin0 -> 2032 bytes
-rw-r--r--test/reference/clip-image.mask.argb32.ref.pngbin0 -> 2678 bytes
-rw-r--r--test/reference/clip-image.mask.rgb24.ref.pngbin0 -> 2678 bytes
-rw-r--r--test/reference/clip-image.ps.ref.pngbin0 -> 2498 bytes
-rw-r--r--test/reference/clip-image.ref.pngbin0 -> 2677 bytes
-rw-r--r--test/reference/clip-image.traps.argb32.ref.pngbin0 -> 2686 bytes
-rw-r--r--test/reference/clip-image.traps.rgb24.ref.pngbin0 -> 2686 bytes
-rw-r--r--test/reference/clip-intersect.base.argb32.ref.pngbin0 -> 200 bytes
-rw-r--r--test/reference/clip-intersect.base.rgb24.ref.pngbin0 -> 200 bytes
-rw-r--r--test/reference/clip-intersect.ref.pngbin0 -> 224 bytes
-rw-r--r--test/reference/clip-intersect.traps.argb32.ref.pngbin0 -> 193 bytes
-rw-r--r--test/reference/clip-intersect.traps.rgb24.ref.pngbin0 -> 193 bytes
-rw-r--r--test/reference/clip-mixed-antialias.base.argb32.ref.pngbin0 -> 1094 bytes
-rw-r--r--test/reference/clip-mixed-antialias.base.rgb24.ref.pngbin0 -> 1094 bytes
-rw-r--r--test/reference/clip-mixed-antialias.ref.pngbin0 -> 1084 bytes
-rw-r--r--test/reference/clip-mixed-antialias.traps.argb32.ref.pngbin0 -> 1094 bytes
-rw-r--r--test/reference/clip-mixed-antialias.traps.rgb24.ref.pngbin0 -> 1094 bytes
-rw-r--r--test/reference/clip-nesting.argb32.ref.pngbin0 -> 1026 bytes
-rw-r--r--test/reference/clip-nesting.base.argb32.ref.pngbin0 -> 1044 bytes
-rw-r--r--test/reference/clip-nesting.base.rgb24.ref.pngbin0 -> 937 bytes
-rw-r--r--test/reference/clip-nesting.mask.rgb24.ref.pngbin0 -> 937 bytes
-rw-r--r--test/reference/clip-nesting.pdf.argb32.ref.pngbin0 -> 850 bytes
-rw-r--r--test/reference/clip-nesting.ps.argb32.ref.pngbin0 -> 441 bytes
-rw-r--r--test/reference/clip-nesting.ps.rgb24.ref.pngbin0 -> 492 bytes
-rw-r--r--test/reference/clip-nesting.quartz.argb32.ref.pngbin0 -> 1048 bytes
-rw-r--r--test/reference/clip-nesting.quartz.rgb24.ref.pngbin0 -> 937 bytes
-rw-r--r--test/reference/clip-nesting.rgb24.ref.pngbin0 -> 917 bytes
-rw-r--r--test/reference/clip-nesting.test-paginated.rgb24.ref.pngbin0 -> 936 bytes
-rw-r--r--test/reference/clip-nesting.traps.argb32.ref.pngbin0 -> 1031 bytes
-rw-r--r--test/reference/clip-nesting.traps.rgb24.ref.pngbin0 -> 936 bytes
-rw-r--r--test/reference/clip-operator.argb32.ref.pngbin0 -> 8514 bytes
-rw-r--r--test/reference/clip-operator.base.argb32.ref.pngbin0 -> 8136 bytes
-rw-r--r--test/reference/clip-operator.base.rgb24.ref.pngbin0 -> 3244 bytes
-rw-r--r--test/reference/clip-operator.gl.argb32.ref.pngbin0 -> 8296 bytes
-rw-r--r--test/reference/clip-operator.image16.ref.pngbin0 -> 3131 bytes
-rw-r--r--test/reference/clip-operator.mask.argb32.ref.pngbin0 -> 8680 bytes
-rw-r--r--test/reference/clip-operator.mask.rgb24.ref.pngbin0 -> 3519 bytes
-rw-r--r--test/reference/clip-operator.pdf.argb32.ref.pngbin0 -> 8792 bytes
-rw-r--r--test/reference/clip-operator.pdf.rgb24.ref.pngbin0 -> 4683 bytes
-rw-r--r--test/reference/clip-operator.ps2.rgb24.ref.pngbin0 -> 3736 bytes
-rw-r--r--test/reference/clip-operator.ps3.argb32.ref.pngbin0 -> 7576 bytes
-rw-r--r--test/reference/clip-operator.ps3.ref.pngbin0 -> 8188 bytes
-rw-r--r--test/reference/clip-operator.ps3.rgb24.ref.pngbin0 -> 3736 bytes
-rw-r--r--test/reference/clip-operator.quartz.argb32.ref.pngbin0 -> 9672 bytes
-rw-r--r--test/reference/clip-operator.quartz.rgb24.ref.pngbin0 -> 4343 bytes
-rw-r--r--test/reference/clip-operator.rgb24.ref.pngbin0 -> 3417 bytes
-rw-r--r--test/reference/clip-operator.svg12.argb32.xfail.pngbin0 -> 8378 bytes
-rw-r--r--test/reference/clip-operator.svg12.rgb24.xfail.pngbin0 -> 4566 bytes
-rw-r--r--test/reference/clip-operator.test-paginated.argb32.ref.pngbin0 -> 8189 bytes
-rw-r--r--test/reference/clip-operator.traps.argb32.ref.pngbin0 -> 8114 bytes
-rw-r--r--test/reference/clip-operator.traps.rgb24.ref.pngbin0 -> 3245 bytes
-rw-r--r--test/reference/clip-operator.xlib-fallback.ref.pngbin0 -> 3228 bytes
-rw-r--r--test/reference/clip-polygons.base.argb32.ref.pngbin0 -> 1336 bytes
-rw-r--r--test/reference/clip-polygons.base.rgb24.ref.pngbin0 -> 1336 bytes
-rw-r--r--test/reference/clip-polygons.mask.argb32.ref.pngbin0 -> 1336 bytes
-rw-r--r--test/reference/clip-polygons.mask.rgb24.ref.pngbin0 -> 1336 bytes
-rw-r--r--test/reference/clip-polygons.ref.pngbin0 -> 1352 bytes
-rw-r--r--test/reference/clip-polygons.traps.ref.pngbin0 -> 1268 bytes
-rw-r--r--test/reference/clip-push-group.base.argb32.ref.pngbin0 -> 164 bytes
-rw-r--r--test/reference/clip-push-group.base.rgb24.ref.pngbin0 -> 164 bytes
-rw-r--r--test/reference/clip-push-group.image16.ref.pngbin0 -> 159 bytes
-rw-r--r--test/reference/clip-push-group.pdf.ref.pngbin0 -> 164 bytes
-rw-r--r--test/reference/clip-push-group.ps.ref.pngbin0 -> 120 bytes
-rw-r--r--test/reference/clip-push-group.quartz.ref.pngbin0 -> 166 bytes
-rw-r--r--test/reference/clip-push-group.ref.pngbin0 -> 164 bytes
-rw-r--r--test/reference/clip-push-group.svg.ref.pngbin0 -> 175 bytes
-rw-r--r--test/reference/clip-push-group.traps.argb32.ref.pngbin0 -> 155 bytes
-rw-r--r--test/reference/clip-push-group.traps.rgb24.ref.pngbin0 -> 155 bytes
-rw-r--r--test/reference/clip-rectilinear.base.argb32.ref.pngbin0 -> 439 bytes
-rw-r--r--test/reference/clip-rectilinear.base.rgb24.ref.pngbin0 -> 439 bytes
-rw-r--r--test/reference/clip-rectilinear.mask.argb32.ref.pngbin0 -> 440 bytes
-rw-r--r--test/reference/clip-rectilinear.mask.rgb24.ref.pngbin0 -> 440 bytes
-rw-r--r--test/reference/clip-rectilinear.ref.pngbin0 -> 439 bytes
-rw-r--r--test/reference/clip-rectilinear.traps.ref.pngbin0 -> 440 bytes
-rw-r--r--test/reference/clip-rotate-image-surface-paint.base.argb32.ref.pngbin0 -> 202 bytes
-rw-r--r--test/reference/clip-rotate-image-surface-paint.base.rgb24.ref.pngbin0 -> 202 bytes
-rw-r--r--test/reference/clip-rotate-image-surface-paint.ref.pngbin0 -> 202 bytes
-rw-r--r--test/reference/clip-shape.base.argb32.ref.pngbin0 -> 2916 bytes
-rw-r--r--test/reference/clip-shape.base.rgb24.ref.pngbin0 -> 2916 bytes
-rw-r--r--test/reference/clip-shape.image16.ref.pngbin0 -> 2488 bytes
-rw-r--r--test/reference/clip-shape.mask.argb32.ref.pngbin0 -> 3094 bytes
-rw-r--r--test/reference/clip-shape.mask.rgb24.ref.pngbin0 -> 3094 bytes
-rw-r--r--test/reference/clip-shape.ps.ref.pngbin0 -> 1797 bytes
-rw-r--r--test/reference/clip-shape.quartz.ref.pngbin0 -> 3229 bytes
-rw-r--r--test/reference/clip-shape.ref.pngbin0 -> 2902 bytes
-rw-r--r--test/reference/clip-shape.traps.argb32.ref.pngbin0 -> 2944 bytes
-rw-r--r--test/reference/clip-shape.traps.rgb24.ref.pngbin0 -> 2944 bytes
-rw-r--r--test/reference/clip-shape.xlib-fallback.ref.pngbin0 -> 2916 bytes
-rw-r--r--test/reference/clip-stroke-no-op.base.argb32.ref.pngbin0 -> 152 bytes
-rw-r--r--test/reference/clip-stroke-no-op.base.rgb24.ref.pngbin0 -> 152 bytes
-rw-r--r--test/reference/clip-stroke-no-op.image16.ref.pngbin0 -> 153 bytes
-rw-r--r--test/reference/clip-stroke-no-op.ref.pngbin0 -> 152 bytes
-rw-r--r--test/reference/clip-stroke-unbounded.argb32.ref.pngbin0 -> 4097 bytes
-rw-r--r--test/reference/clip-stroke-unbounded.base.argb32.ref.pngbin0 -> 3655 bytes
-rw-r--r--test/reference/clip-stroke-unbounded.base.rgb24.ref.pngbin0 -> 3135 bytes
-rw-r--r--test/reference/clip-stroke-unbounded.image16.rgb24.ref.pngbin0 -> 2778 bytes
-rw-r--r--test/reference/clip-stroke-unbounded.mask.argb32.ref.pngbin0 -> 3991 bytes
-rw-r--r--test/reference/clip-stroke-unbounded.mask.rgb24.ref.pngbin0 -> 3372 bytes
-rw-r--r--test/reference/clip-stroke-unbounded.quartz.argb32.ref.pngbin0 -> 3290 bytes
-rw-r--r--test/reference/clip-stroke-unbounded.quartz.rgb24.ref.pngbin0 -> 2840 bytes
-rw-r--r--test/reference/clip-stroke-unbounded.rgb24.ref.pngbin0 -> 3486 bytes
-rw-r--r--test/reference/clip-stroke-unbounded.svg12.rgb24.xfail.pngbin0 -> 3569 bytes
-rw-r--r--test/reference/clip-stroke-unbounded.traps.argb32.ref.pngbin0 -> 3617 bytes
-rw-r--r--test/reference/clip-stroke-unbounded.traps.rgb24.ref.pngbin0 -> 3108 bytes
-rw-r--r--test/reference/clip-stroke-unbounded.xlib-fallback.rgb24.ref.pngbin0 -> 3123 bytes
-rw-r--r--test/reference/clip-stroke.base.argb32.ref.pngbin0 -> 1444 bytes
-rw-r--r--test/reference/clip-stroke.base.rgb24.ref.pngbin0 -> 1444 bytes
-rw-r--r--test/reference/clip-stroke.image16.ref.pngbin0 -> 1305 bytes
-rw-r--r--test/reference/clip-stroke.mask.argb32.ref.pngbin0 -> 1500 bytes
-rw-r--r--test/reference/clip-stroke.mask.rgb24.ref.pngbin0 -> 1500 bytes
-rw-r--r--test/reference/clip-stroke.ps.xfail.pngbin0 -> 662 bytes
-rw-r--r--test/reference/clip-stroke.quartz.ref.pngbin0 -> 1305 bytes
-rw-r--r--test/reference/clip-stroke.ref.pngbin0 -> 1571 bytes
-rw-r--r--test/reference/clip-stroke.traps.argb32.ref.pngbin0 -> 1492 bytes
-rw-r--r--test/reference/clip-stroke.traps.rgb24.ref.pngbin0 -> 1492 bytes
-rw-r--r--test/reference/clip-stroke.xlib-fallback.ref.pngbin0 -> 1491 bytes
-rw-r--r--test/reference/clip-text.base.argb32.ref.pngbin0 -> 921 bytes
-rw-r--r--test/reference/clip-text.base.rgb24.ref.pngbin0 -> 921 bytes
-rw-r--r--test/reference/clip-text.image16.ref.pngbin0 -> 811 bytes
-rw-r--r--test/reference/clip-text.mask.argb32.ref.pngbin0 -> 918 bytes
-rw-r--r--test/reference/clip-text.mask.rgb24.ref.pngbin0 -> 918 bytes
-rw-r--r--test/reference/clip-text.ps.xfail.pngbin0 -> 434 bytes
-rw-r--r--test/reference/clip-text.quartz.ref.pngbin0 -> 854 bytes
-rw-r--r--test/reference/clip-text.ref.pngbin0 -> 912 bytes
-rw-r--r--test/reference/clip-text.svg.ref.pngbin0 -> 946 bytes
-rw-r--r--test/reference/clip-text.traps.argb32.ref.pngbin0 -> 899 bytes
-rw-r--r--test/reference/clip-text.traps.rgb24.ref.pngbin0 -> 899 bytes
-rw-r--r--test/reference/clip-twice-rectangle.base.argb32.ref.pngbin0 -> 323 bytes
-rw-r--r--test/reference/clip-twice-rectangle.base.rgb24.ref.pngbin0 -> 323 bytes
-rw-r--r--test/reference/clip-twice-rectangle.ref.pngbin0 -> 323 bytes
-rw-r--r--test/reference/clip-twice.argb32.ref.pngbin0 -> 1333 bytes
-rw-r--r--test/reference/clip-twice.base.argb32.ref.pngbin0 -> 1341 bytes
-rw-r--r--test/reference/clip-twice.base.rgb24.ref.pngbin0 -> 1194 bytes
-rw-r--r--test/reference/clip-twice.image16.ref.pngbin0 -> 1069 bytes
-rw-r--r--test/reference/clip-twice.mask.argb32.ref.pngbin0 -> 1306 bytes
-rw-r--r--test/reference/clip-twice.mask.rgb24.ref.pngbin0 -> 1215 bytes
-rw-r--r--test/reference/clip-twice.pdf.argb32.ref.pngbin0 -> 1498 bytes
-rw-r--r--test/reference/clip-twice.ps.argb32.ref.pngbin0 -> 492 bytes
-rw-r--r--test/reference/clip-twice.ps.rgb24.ref.pngbin0 -> 409 bytes
-rw-r--r--test/reference/clip-twice.quartz.argb32.ref.pngbin0 -> 1171 bytes
-rw-r--r--test/reference/clip-twice.quartz.rgb24.ref.pngbin0 -> 1095 bytes
-rw-r--r--test/reference/clip-twice.rgb24.ref.pngbin0 -> 1171 bytes
-rw-r--r--test/reference/clip-twice.test-paginated.argb32.ref.pngbin0 -> 1361 bytes
-rw-r--r--test/reference/clip-twice.test-paginated.rgb24.ref.pngbin0 -> 1199 bytes
-rw-r--r--test/reference/clip-twice.traps.argb32.ref.pngbin0 -> 1328 bytes
-rw-r--r--test/reference/clip-twice.traps.rgb24.ref.pngbin0 -> 1173 bytes
-rw-r--r--test/reference/clip-unbounded.base.argb32.ref.pngbin0 -> 100 bytes
-rw-r--r--test/reference/clip-unbounded.base.rgb24.ref.pngbin0 -> 97 bytes
-rw-r--r--test/reference/clip-unbounded.pdf.argb32.xfail.pngbin0 -> 95 bytes
-rw-r--r--test/reference/clip-unbounded.pdf.rgb24.xfail.pngbin0 -> 95 bytes
-rw-r--r--test/reference/clip-unbounded.ref.pngbin0 -> 100 bytes
-rw-r--r--test/reference/clip-unbounded.svg12.rgb24.xfail.pngbin0 -> 100 bytes
-rw-r--r--test/reference/clip-xlib-fallback.rgb24.ref.pngbin0 -> 2686 bytes
-rw-r--r--test/reference/clip-xlib-window.rgb24.ref.pngbin0 -> 2686 bytes
-rw-r--r--test/reference/clip-xlib.ref.pngbin0 -> 2686 bytes
-rw-r--r--test/reference/clipped-group.base.argb32.ref.pngbin0 -> 316 bytes
-rw-r--r--test/reference/clipped-group.base.rgb24.ref.pngbin0 -> 316 bytes
-rw-r--r--test/reference/clipped-group.image16.ref.pngbin0 -> 270 bytes
-rw-r--r--test/reference/clipped-group.mask.argb32.ref.pngbin0 -> 336 bytes
-rw-r--r--test/reference/clipped-group.mask.rgb24.ref.pngbin0 -> 336 bytes
-rw-r--r--test/reference/clipped-group.pdf.ref.pngbin0 -> 334 bytes
-rw-r--r--test/reference/clipped-group.ps2.ref.pngbin0 -> 214 bytes
-rw-r--r--test/reference/clipped-group.ps3.ref.pngbin0 -> 214 bytes
-rw-r--r--test/reference/clipped-group.quartz.ref.pngbin0 -> 308 bytes
-rw-r--r--test/reference/clipped-group.ref.pngbin0 -> 315 bytes
-rw-r--r--test/reference/clipped-group.svg.ref.pngbin0 -> 250 bytes
-rw-r--r--test/reference/clipped-group.traps.argb32.ref.pngbin0 -> 289 bytes
-rw-r--r--test/reference/clipped-group.traps.rgb24.ref.pngbin0 -> 289 bytes
-rw-r--r--test/reference/clipped-group.xlib-fallback.ref.pngbin0 -> 344 bytes
-rw-r--r--test/reference/clipped-surface.base.argb32.ref.pngbin0 -> 345 bytes
-rw-r--r--test/reference/clipped-surface.base.rgb24.ref.pngbin0 -> 345 bytes
-rw-r--r--test/reference/clipped-surface.image16.ref.pngbin0 -> 296 bytes
-rw-r--r--test/reference/clipped-surface.ref.pngbin0 -> 401 bytes
-rw-r--r--test/reference/clipped-trapezoids.ref.pngbin0 -> 963 bytes
-rw-r--r--test/reference/close-path-current-point.base.argb32.ref.pngbin0 -> 1904 bytes
-rw-r--r--test/reference/close-path-current-point.base.rgb24.ref.pngbin0 -> 1904 bytes
-rw-r--r--test/reference/close-path-current-point.image16.ref.pngbin0 -> 1804 bytes
-rw-r--r--test/reference/close-path-current-point.mask.argb32.ref.pngbin0 -> 2324 bytes
-rw-r--r--test/reference/close-path-current-point.mask.rgb24.ref.pngbin0 -> 2324 bytes
-rw-r--r--test/reference/close-path-current-point.ps.ref.pngbin0 -> 1490 bytes
-rw-r--r--test/reference/close-path-current-point.ref.pngbin0 -> 2109 bytes
-rw-r--r--test/reference/close-path-current-point.traps.argb32.ref.pngbin0 -> 1904 bytes
-rw-r--r--test/reference/close-path-current-point.traps.rgb24.ref.pngbin0 -> 1904 bytes
-rw-r--r--test/reference/close-path.base.argb32.ref.pngbin0 -> 284 bytes
-rw-r--r--test/reference/close-path.base.rgb24.ref.pngbin0 -> 284 bytes
-rw-r--r--test/reference/close-path.ps2.ref.pngbin0 -> 309 bytes
-rw-r--r--test/reference/close-path.ps3.ref.pngbin0 -> 309 bytes
-rw-r--r--test/reference/close-path.ref.pngbin0 -> 294 bytes
-rw-r--r--test/reference/close-path.traps.argb32.ref.pngbin0 -> 284 bytes
-rw-r--r--test/reference/close-path.traps.rgb24.ref.pngbin0 -> 284 bytes
-rw-r--r--test/reference/composite-integer-translate-over-repeat.base.argb32.ref.pngbin0 -> 334 bytes
-rw-r--r--test/reference/composite-integer-translate-over-repeat.base.rgb24.ref.pngbin0 -> 334 bytes
-rw-r--r--test/reference/composite-integer-translate-over-repeat.ps2.ref.pngbin0 -> 448 bytes
-rw-r--r--test/reference/composite-integer-translate-over-repeat.ps3.ref.pngbin0 -> 448 bytes
-rw-r--r--test/reference/composite-integer-translate-over-repeat.ref.pngbin0 -> 401 bytes
-rw-r--r--test/reference/composite-integer-translate-over.base.argb32.ref.pngbin0 -> 13998 bytes
-rw-r--r--test/reference/composite-integer-translate-over.base.rgb24.ref.pngbin0 -> 13998 bytes
-rw-r--r--test/reference/composite-integer-translate-over.image16.ref.pngbin0 -> 11570 bytes
-rw-r--r--test/reference/composite-integer-translate-over.ps2.ref.pngbin0 -> 15783 bytes
-rw-r--r--test/reference/composite-integer-translate-over.ps3.ref.pngbin0 -> 15783 bytes
-rw-r--r--test/reference/composite-integer-translate-over.ref.pngbin0 -> 16385 bytes
-rw-r--r--test/reference/composite-integer-translate-source.base.argb32.ref.pngbin0 -> 13998 bytes
-rw-r--r--test/reference/composite-integer-translate-source.base.rgb24.ref.pngbin0 -> 13998 bytes
-rw-r--r--test/reference/composite-integer-translate-source.image16.ref.pngbin0 -> 11570 bytes
-rw-r--r--test/reference/composite-integer-translate-source.ps2.ref.pngbin0 -> 15783 bytes
-rw-r--r--test/reference/composite-integer-translate-source.ps3.ref.pngbin0 -> 15783 bytes
-rw-r--r--test/reference/composite-integer-translate-source.ref.pngbin0 -> 16385 bytes
-rw-r--r--test/reference/composite-integer-translate-source.svg12.argb32.xfail.pngbin0 -> 16392 bytes
-rw-r--r--test/reference/composite-integer-translate-source.svg12.rgb24.xfail.pngbin0 -> 16392 bytes
-rw-r--r--test/reference/copy-disjoint.base.argb32.ref.pngbin0 -> 1098 bytes
-rw-r--r--test/reference/copy-disjoint.base.rgb24.ref.pngbin0 -> 1098 bytes
-rw-r--r--test/reference/copy-disjoint.ref.pngbin0 -> 1098 bytes
-rw-r--r--test/reference/copy-path.base.argb32.ref.pngbin0 -> 588 bytes
-rw-r--r--test/reference/copy-path.base.rgb24.ref.pngbin0 -> 588 bytes
-rw-r--r--test/reference/copy-path.image16.ref.pngbin0 -> 556 bytes
-rw-r--r--test/reference/copy-path.ps.ref.pngbin0 -> 379 bytes
-rw-r--r--test/reference/copy-path.ref.pngbin0 -> 616 bytes
-rw-r--r--test/reference/copy-path.traps.argb32.ref.pngbin0 -> 588 bytes
-rw-r--r--test/reference/copy-path.traps.rgb24.ref.pngbin0 -> 588 bytes
-rw-r--r--test/reference/coverage-abutting.ref.pngbin0 -> 777 bytes
-rw-r--r--test/reference/coverage-column-triangles.ref.pngbin0 -> 208 bytes
-rw-r--r--test/reference/coverage-column-triangles.xfail.pngbin0 -> 7632 bytes
-rw-r--r--test/reference/coverage-column-triangles.xlib.xfail.pngbin0 -> 12745 bytes
-rw-r--r--test/reference/coverage-intersecting-quads.ref.pngbin0 -> 253 bytes
-rw-r--r--test/reference/coverage-intersecting-quads.xlib.xfail.pngbin0 -> 15296 bytes
-rw-r--r--test/reference/coverage-intersecting-triangles.ref.pngbin0 -> 209 bytes
-rw-r--r--test/reference/coverage-intersecting-triangles.xfail.pngbin0 -> 14444 bytes
-rw-r--r--test/reference/coverage-intersecting-triangles.xlib.xfail.pngbin0 -> 16728 bytes
-rw-r--r--test/reference/coverage-rectangles.ref.pngbin0 -> 259 bytes
-rw-r--r--test/reference/coverage-rectangles.xlib.xfail.pngbin0 -> 15981 bytes
-rw-r--r--test/reference/coverage-rhombus.ref.pngbin0 -> 7053 bytes
-rw-r--r--test/reference/coverage-rhombus.xfail.pngbin0 -> 9898 bytes
-rw-r--r--test/reference/coverage-row-triangles.ref.pngbin0 -> 208 bytes
-rw-r--r--test/reference/coverage-row-triangles.xfail.pngbin0 -> 512 bytes
-rw-r--r--test/reference/coverage-row-triangles.xlib.xfail.pngbin0 -> 12671 bytes
-rw-r--r--test/reference/coverage-triangles.ref.pngbin0 -> 253 bytes
-rw-r--r--test/reference/coverage-triangles.xfail.pngbin0 -> 14283 bytes
-rw-r--r--test/reference/coverage-triangles.xlib.xfail.pngbin0 -> 15859 bytes
-rw-r--r--test/reference/create-from-png-stream.base.argb32.ref.pngbin0 -> 96 bytes
-rw-r--r--test/reference/create-from-png-stream.base.rgb24.ref.pngbin0 -> 96 bytes
-rw-r--r--test/reference/create-from-png-stream.ref.pngbin0 -> 100 bytes
-rw-r--r--test/reference/create-from-png.alpha.ref.pngbin0 -> 150 bytes
-rw-r--r--test/reference/create-from-png.base.argb32.ref.pngbin0 -> 96 bytes
-rw-r--r--test/reference/create-from-png.base.rgb24.ref.pngbin0 -> 96 bytes
-rw-r--r--test/reference/create-from-png.gray-alpha.ref.pngbin0 -> 142 bytes
-rw-r--r--test/reference/create-from-png.gray.ref.pngbin0 -> 124 bytes
-rw-r--r--test/reference/create-from-png.indexed-alpha.ref.pngbin0 -> 172 bytes
-rw-r--r--test/reference/create-from-png.indexed.ref.pngbin0 -> 159 bytes
-rw-r--r--test/reference/create-from-png.mask.argb32.ref.pngbin0 -> 96 bytes
-rw-r--r--test/reference/create-from-png.mask.rgb24.ref.pngbin0 -> 96 bytes
-rw-r--r--test/reference/create-from-png.ref.pngbin0 -> 96 bytes
-rw-r--r--test/reference/create-from-png.traps.argb32.ref.pngbin0 -> 96 bytes
-rw-r--r--test/reference/create-from-png.traps.rgb24.ref.pngbin0 -> 96 bytes
-rw-r--r--test/reference/culled-glyphs.base.argb32.ref.pngbin0 -> 440 bytes
-rw-r--r--test/reference/culled-glyphs.base.rgb24.ref.pngbin0 -> 440 bytes
-rw-r--r--test/reference/culled-glyphs.image16.ref.pngbin0 -> 426 bytes
-rw-r--r--test/reference/culled-glyphs.ps.ref.pngbin0 -> 372 bytes
-rw-r--r--test/reference/culled-glyphs.quartz.ref.pngbin0 -> 493 bytes
-rw-r--r--test/reference/culled-glyphs.ref.pngbin0 -> 440 bytes
-rw-r--r--test/reference/curve-to-as-line-to.base.argb32.ref.pngbin0 -> 95 bytes
-rw-r--r--test/reference/curve-to-as-line-to.base.rgb24.ref.pngbin0 -> 95 bytes
-rw-r--r--test/reference/curve-to-as-line-to.mask.argb32.ref.pngbin0 -> 109 bytes
-rw-r--r--test/reference/curve-to-as-line-to.mask.rgb24.ref.pngbin0 -> 109 bytes
-rw-r--r--test/reference/curve-to-as-line-to.ps.xfail.pngbin0 -> 112 bytes
-rw-r--r--test/reference/curve-to-as-line-to.ref.pngbin0 -> 95 bytes
-rw-r--r--test/reference/curve-to-as-line-to.traps.argb32.ref.pngbin0 -> 95 bytes
-rw-r--r--test/reference/curve-to-as-line-to.traps.rgb24.ref.pngbin0 -> 95 bytes
-rw-r--r--test/reference/dash-caps-joins.base.argb32.ref.pngbin0 -> 4483 bytes
-rw-r--r--test/reference/dash-caps-joins.base.rgb24.ref.pngbin0 -> 4483 bytes
-rw-r--r--test/reference/dash-caps-joins.image16.ref.pngbin0 -> 4491 bytes
-rw-r--r--test/reference/dash-caps-joins.mask.argb32.ref.pngbin0 -> 5157 bytes
-rw-r--r--test/reference/dash-caps-joins.mask.rgb24.ref.pngbin0 -> 5157 bytes
-rw-r--r--test/reference/dash-caps-joins.ps.ref.pngbin0 -> 3648 bytes
-rw-r--r--test/reference/dash-caps-joins.quartz.xfail.pngbin0 -> 4446 bytes
-rw-r--r--test/reference/dash-caps-joins.ref.pngbin0 -> 4713 bytes
-rw-r--r--test/reference/dash-caps-joins.traps.argb32.ref.pngbin0 -> 4483 bytes
-rw-r--r--test/reference/dash-caps-joins.traps.rgb24.ref.pngbin0 -> 4483 bytes
-rw-r--r--test/reference/dash-curve.image16.ref.pngbin0 -> 32445 bytes
-rw-r--r--test/reference/dash-curve.mask.argb32.ref.pngbin0 -> 41040 bytes
-rw-r--r--test/reference/dash-curve.mask.rgb24.ref.pngbin0 -> 41040 bytes
-rw-r--r--test/reference/dash-curve.ps2.ref.pngbin0 -> 24355 bytes
-rw-r--r--test/reference/dash-curve.ps3.ref.pngbin0 -> 24355 bytes
-rw-r--r--test/reference/dash-curve.quartz.xfail.pngbin0 -> 42238 bytes
-rw-r--r--test/reference/dash-curve.ref.pngbin0 -> 41069 bytes
-rw-r--r--test/reference/dash-curve.traps.argb32.ref.pngbin0 -> 39925 bytes
-rw-r--r--test/reference/dash-curve.traps.rgb24.ref.pngbin0 -> 39925 bytes
-rw-r--r--test/reference/dash-infinite-loop.base.argb32.ref.pngbin0 -> 642 bytes
-rw-r--r--test/reference/dash-infinite-loop.base.rgb24.ref.pngbin0 -> 642 bytes
-rw-r--r--test/reference/dash-infinite-loop.ps.ref.pngbin0 -> 601 bytes
-rw-r--r--test/reference/dash-infinite-loop.ref.pngbin0 -> 877 bytes
-rw-r--r--test/reference/dash-infinite-loop.traps.argb32.ref.pngbin0 -> 642 bytes
-rw-r--r--test/reference/dash-infinite-loop.traps.rgb24.ref.pngbin0 -> 642 bytes
-rw-r--r--test/reference/dash-no-dash.base.argb32.ref.pngbin0 -> 119 bytes
-rw-r--r--test/reference/dash-no-dash.base.rgb24.ref.pngbin0 -> 119 bytes
-rw-r--r--test/reference/dash-no-dash.ref.pngbin0 -> 152 bytes
-rw-r--r--test/reference/dash-offset-negative.base.argb32.ref.pngbin0 -> 151 bytes
-rw-r--r--test/reference/dash-offset-negative.base.rgb24.ref.pngbin0 -> 151 bytes
-rw-r--r--test/reference/dash-offset-negative.pdf.ref.pngbin0 -> 129 bytes
-rw-r--r--test/reference/dash-offset-negative.ref.pngbin0 -> 129 bytes
-rw-r--r--test/reference/dash-offset-negative.traps.argb32.ref.pngbin0 -> 151 bytes
-rw-r--r--test/reference/dash-offset-negative.traps.rgb24.ref.pngbin0 -> 151 bytes
-rw-r--r--test/reference/dash-offset.base.argb32.ref.pngbin0 -> 794 bytes
-rw-r--r--test/reference/dash-offset.base.rgb24.ref.pngbin0 -> 794 bytes
-rw-r--r--test/reference/dash-offset.ref.pngbin0 -> 794 bytes
-rw-r--r--test/reference/dash-scale.image16.ref.pngbin0 -> 7748 bytes
-rw-r--r--test/reference/dash-scale.mask.argb32.ref.pngbin0 -> 8913 bytes
-rw-r--r--test/reference/dash-scale.mask.rgb24.ref.pngbin0 -> 8913 bytes
-rw-r--r--test/reference/dash-scale.ps.ref.pngbin0 -> 5965 bytes
-rw-r--r--test/reference/dash-scale.quartz.ref.pngbin0 -> 7614 bytes
-rw-r--r--test/reference/dash-scale.ref.pngbin0 -> 7826 bytes
-rw-r--r--test/reference/dash-scale.traps.argb32.ref.pngbin0 -> 7627 bytes
-rw-r--r--test/reference/dash-scale.traps.rgb24.ref.pngbin0 -> 7627 bytes
-rw-r--r--test/reference/dash-state.base.argb32.ref.pngbin0 -> 7509 bytes
-rw-r--r--test/reference/dash-state.base.rgb24.ref.pngbin0 -> 7509 bytes
-rw-r--r--test/reference/dash-state.image16.ref.pngbin0 -> 7910 bytes
-rw-r--r--test/reference/dash-state.ps2.ref.pngbin0 -> 8740 bytes
-rw-r--r--test/reference/dash-state.ps3.ref.pngbin0 -> 8740 bytes
-rw-r--r--test/reference/dash-state.quartz.xfail.pngbin0 -> 6957 bytes
-rw-r--r--test/reference/dash-state.ref.pngbin0 -> 8027 bytes
-rw-r--r--test/reference/dash-state.traps.argb32.ref.pngbin0 -> 7509 bytes
-rw-r--r--test/reference/dash-state.traps.rgb24.ref.pngbin0 -> 7509 bytes
-rw-r--r--test/reference/dash-zero-length.base.argb32.ref.pngbin0 -> 219 bytes
-rw-r--r--test/reference/dash-zero-length.base.rgb24.ref.pngbin0 -> 199 bytes
-rw-r--r--test/reference/dash-zero-length.mask.rgb24.ref.pngbin0 -> 210 bytes
-rw-r--r--test/reference/dash-zero-length.ps2.ref.pngbin0 -> 319 bytes
-rw-r--r--test/reference/dash-zero-length.ps2.rgb24.ref.pngbin0 -> 304 bytes
-rw-r--r--test/reference/dash-zero-length.ps3.ref.pngbin0 -> 319 bytes
-rw-r--r--test/reference/dash-zero-length.ps3.rgb24.ref.pngbin0 -> 304 bytes
-rw-r--r--test/reference/dash-zero-length.ref.pngbin0 -> 230 bytes
-rw-r--r--test/reference/dash-zero-length.traps.argb32.ref.pngbin0 -> 219 bytes
-rw-r--r--test/reference/dash-zero-length.traps.rgb24.ref.pngbin0 -> 199 bytes
-rw-r--r--test/reference/degenerate-arc.base.argb32.ref.pngbin0 -> 574 bytes
-rw-r--r--test/reference/degenerate-arc.base.rgb24.ref.pngbin0 -> 574 bytes
-rw-r--r--test/reference/degenerate-arc.image16.ref.pngbin0 -> 592 bytes
-rw-r--r--test/reference/degenerate-arc.mask.argb32.ref.pngbin0 -> 653 bytes
-rw-r--r--test/reference/degenerate-arc.mask.rgb24.ref.pngbin0 -> 653 bytes
-rw-r--r--test/reference/degenerate-arc.ps2.ref.pngbin0 -> 509 bytes
-rw-r--r--test/reference/degenerate-arc.ps3.ref.pngbin0 -> 509 bytes
-rw-r--r--test/reference/degenerate-arc.quartz.ref.pngbin0 -> 552 bytes
-rw-r--r--test/reference/degenerate-arc.ref.pngbin0 -> 626 bytes
-rw-r--r--test/reference/degenerate-arc.traps.argb32.ref.pngbin0 -> 574 bytes
-rw-r--r--test/reference/degenerate-arc.traps.rgb24.ref.pngbin0 -> 574 bytes
-rw-r--r--test/reference/degenerate-arcs.base.argb32.ref.pngbin0 -> 120 bytes
-rw-r--r--test/reference/degenerate-arcs.base.rgb24.ref.pngbin0 -> 120 bytes
-rw-r--r--test/reference/degenerate-arcs.image16.ref.pngbin0 -> 120 bytes
-rw-r--r--test/reference/degenerate-arcs.ref.pngbin0 -> 120 bytes
-rw-r--r--test/reference/degenerate-curve-to.base.argb32.ref.pngbin0 -> 282 bytes
-rw-r--r--test/reference/degenerate-curve-to.base.rgb24.ref.pngbin0 -> 282 bytes
-rw-r--r--test/reference/degenerate-curve-to.image16.ref.pngbin0 -> 278 bytes
-rw-r--r--test/reference/degenerate-curve-to.mask.argb32.ref.pngbin0 -> 280 bytes
-rw-r--r--test/reference/degenerate-curve-to.mask.rgb24.ref.pngbin0 -> 280 bytes
-rw-r--r--test/reference/degenerate-curve-to.ps.xfail.pngbin0 -> 221 bytes
-rw-r--r--test/reference/degenerate-curve-to.quartz.ref.pngbin0 -> 247 bytes
-rw-r--r--test/reference/degenerate-curve-to.ref.pngbin0 -> 285 bytes
-rw-r--r--test/reference/degenerate-curve-to.traps.argb32.ref.pngbin0 -> 282 bytes
-rw-r--r--test/reference/degenerate-curve-to.traps.rgb24.ref.pngbin0 -> 282 bytes
-rw-r--r--test/reference/degenerate-dash.base.argb32.ref.pngbin0 -> 1911 bytes
-rw-r--r--test/reference/degenerate-dash.base.rgb24.ref.pngbin0 -> 1911 bytes
-rw-r--r--test/reference/degenerate-dash.mask.argb32.ref.pngbin0 -> 2086 bytes
-rw-r--r--test/reference/degenerate-dash.mask.rgb24.ref.pngbin0 -> 2086 bytes
-rw-r--r--test/reference/degenerate-dash.ps.xfail.pngbin0 -> 1837 bytes
-rw-r--r--test/reference/degenerate-dash.quartz.xfail.pngbin0 -> 1560 bytes
-rw-r--r--test/reference/degenerate-dash.ref.pngbin0 -> 1960 bytes
-rw-r--r--test/reference/degenerate-dash.traps.argb32.ref.pngbin0 -> 1911 bytes
-rw-r--r--test/reference/degenerate-dash.traps.rgb24.ref.pngbin0 -> 1911 bytes
-rw-r--r--test/reference/degenerate-linear-gradient.base.argb32.ref.pngbin0 -> 336 bytes
-rw-r--r--test/reference/degenerate-linear-gradient.base.rgb24.ref.pngbin0 -> 336 bytes
-rw-r--r--test/reference/degenerate-linear-gradient.ref.pngbin0 -> 336 bytes
-rw-r--r--test/reference/degenerate-path.base.argb32.ref.pngbin0 -> 237 bytes
-rw-r--r--test/reference/degenerate-path.base.rgb24.ref.pngbin0 -> 204 bytes
-rw-r--r--test/reference/degenerate-path.mask.argb32.ref.pngbin0 -> 250 bytes
-rw-r--r--test/reference/degenerate-path.mask.rgb24.ref.pngbin0 -> 219 bytes
-rw-r--r--test/reference/degenerate-path.ps.argb32.xfail.pngbin0 -> 234 bytes
-rw-r--r--test/reference/degenerate-path.ps.rgb24.xfail.pngbin0 -> 184 bytes
-rw-r--r--test/reference/degenerate-path.quartz.argb32.xfail.pngbin0 -> 200 bytes
-rw-r--r--test/reference/degenerate-path.quartz.rgb24.xfail.pngbin0 -> 172 bytes
-rw-r--r--test/reference/degenerate-path.ref.pngbin0 -> 251 bytes
-rw-r--r--test/reference/degenerate-path.traps.argb32.ref.pngbin0 -> 237 bytes
-rw-r--r--test/reference/degenerate-path.traps.rgb24.ref.pngbin0 -> 204 bytes
-rw-r--r--test/reference/degenerate-pen.base.argb32.ref.pngbin0 -> 1000 bytes
-rw-r--r--test/reference/degenerate-pen.base.rgb24.ref.pngbin0 -> 1000 bytes
-rw-r--r--test/reference/degenerate-pen.image16.ref.pngbin0 -> 954 bytes
-rw-r--r--test/reference/degenerate-pen.ps.ref.pngbin0 -> 753 bytes
-rw-r--r--test/reference/degenerate-pen.ref.pngbin0 -> 1019 bytes
-rw-r--r--test/reference/degenerate-pen.traps.argb32.ref.pngbin0 -> 1000 bytes
-rw-r--r--test/reference/degenerate-pen.traps.rgb24.ref.pngbin0 -> 1000 bytes
-rw-r--r--test/reference/degenerate-radial-gradient.base.argb32.ref.pngbin0 -> 428 bytes
-rw-r--r--test/reference/degenerate-radial-gradient.base.rgb24.ref.pngbin0 -> 428 bytes
-rw-r--r--test/reference/degenerate-radial-gradient.ref.pngbin0 -> 428 bytes
-rw-r--r--test/reference/degenerate-rel-curve-to.base.argb32.ref.pngbin0 -> 278 bytes
-rw-r--r--test/reference/degenerate-rel-curve-to.base.rgb24.ref.pngbin0 -> 278 bytes
-rw-r--r--test/reference/degenerate-rel-curve-to.image16.ref.pngbin0 -> 279 bytes
-rw-r--r--test/reference/degenerate-rel-curve-to.mask.argb32.ref.pngbin0 -> 277 bytes
-rw-r--r--test/reference/degenerate-rel-curve-to.mask.rgb24.ref.pngbin0 -> 277 bytes
-rw-r--r--test/reference/degenerate-rel-curve-to.ps.ref.pngbin0 -> 225 bytes
-rw-r--r--test/reference/degenerate-rel-curve-to.quartz.ref.pngbin0 -> 246 bytes
-rw-r--r--test/reference/degenerate-rel-curve-to.ref.pngbin0 -> 278 bytes
-rw-r--r--test/reference/degenerate-rel-curve-to.traps.argb32.ref.pngbin0 -> 278 bytes
-rw-r--r--test/reference/degenerate-rel-curve-to.traps.rgb24.ref.pngbin0 -> 278 bytes
-rw-r--r--test/reference/degenerate-solid-dash.ref.pngbin0 -> 407 bytes
-rw-r--r--test/reference/device-offset-fractional.base.argb32.ref.pngbin0 -> 266 bytes
-rw-r--r--test/reference/device-offset-fractional.base.rgb24.ref.pngbin0 -> 266 bytes
-rw-r--r--test/reference/device-offset-fractional.gl.xfail.pngbin0 -> 311 bytes
-rw-r--r--test/reference/device-offset-fractional.pdf.xfail.pngbin0 -> 270 bytes
-rw-r--r--test/reference/device-offset-fractional.ps2.ref.pngbin0 -> 200 bytes
-rw-r--r--test/reference/device-offset-fractional.ps3.ref.pngbin0 -> 200 bytes
-rw-r--r--test/reference/device-offset-fractional.ref.pngbin0 -> 269 bytes
-rw-r--r--test/reference/device-offset-positive.base.argb32.ref.pngbin0 -> 120 bytes
-rw-r--r--test/reference/device-offset-positive.base.rgb24.ref.pngbin0 -> 111 bytes
-rw-r--r--test/reference/device-offset-positive.ref.pngbin0 -> 139 bytes
-rw-r--r--test/reference/device-offset-scale.base.argb32.ref.pngbin0 -> 109 bytes
-rw-r--r--test/reference/device-offset-scale.base.rgb24.ref.pngbin0 -> 109 bytes
-rw-r--r--test/reference/device-offset-scale.ref.pngbin0 -> 145 bytes
-rw-r--r--test/reference/device-offset-scale.svg.xfail.pngbin0 -> 128 bytes
-rw-r--r--test/reference/device-offset.base.argb32.ref.pngbin0 -> 118 bytes
-rw-r--r--test/reference/device-offset.base.rgb24.ref.pngbin0 -> 111 bytes
-rw-r--r--test/reference/device-offset.ref.pngbin0 -> 137 bytes
-rw-r--r--test/reference/drunkard-tails.base.argb32.ref.pngbin0 -> 6176 bytes
-rw-r--r--test/reference/drunkard-tails.base.rgb24.ref.pngbin0 -> 6176 bytes
-rw-r--r--test/reference/drunkard-tails.mask.argb32.ref.pngbin0 -> 6116 bytes
-rw-r--r--test/reference/drunkard-tails.mask.rgb24.ref.pngbin0 -> 6116 bytes
-rw-r--r--test/reference/drunkard-tails.ps.ref.pngbin0 -> 3780 bytes
-rw-r--r--test/reference/drunkard-tails.ref.pngbin0 -> 6157 bytes
-rw-r--r--test/reference/drunkard-tails.traps.argb32.ref.pngbin0 -> 6176 bytes
-rw-r--r--test/reference/drunkard-tails.traps.rgb24.ref.pngbin0 -> 6176 bytes
-rw-r--r--test/reference/egl-surface-source.base.argb32.ref.pngbin0 -> 377 bytes
-rw-r--r--test/reference/egl-surface-source.base.rgb24.ref.pngbin0 -> 301 bytes
-rw-r--r--test/reference/egl-surface-source.image16.ref.pngbin0 -> 305 bytes
-rw-r--r--test/reference/egl-surface-source.ref.pngbin0 -> 377 bytes
-rw-r--r--test/reference/extend-pad-border.base.argb32.ref.pngbin0 -> 495 bytes
-rw-r--r--test/reference/extend-pad-border.base.rgb24.ref.pngbin0 -> 495 bytes
-rw-r--r--test/reference/extend-pad-border.image16.ref.pngbin0 -> 446 bytes
-rw-r--r--test/reference/extend-pad-border.pdf.ref.pngbin0 -> 495 bytes
-rw-r--r--test/reference/extend-pad-border.ps.ref.pngbin0 -> 649 bytes
-rw-r--r--test/reference/extend-pad-border.quartz.ref.pngbin0 -> 432 bytes
-rw-r--r--test/reference/extend-pad-border.ref.pngbin0 -> 495 bytes
-rw-r--r--test/reference/extend-pad-border.svg.xfail.pngbin0 -> 1063 bytes
-rw-r--r--test/reference/extend-pad-similar.base.argb32.ref.pngbin0 -> 279 bytes
-rw-r--r--test/reference/extend-pad-similar.base.rgb24.ref.pngbin0 -> 279 bytes
-rw-r--r--test/reference/extend-pad-similar.quartz.xfail.pngbin0 -> 270 bytes
-rw-r--r--test/reference/extend-pad-similar.ref.pngbin0 -> 315 bytes
-rw-r--r--test/reference/extend-pad-similar.svg.xfail.pngbin0 -> 270 bytes
-rw-r--r--test/reference/extend-pad.base.argb32.ref.pngbin0 -> 279 bytes
-rw-r--r--test/reference/extend-pad.base.rgb24.ref.pngbin0 -> 279 bytes
-rw-r--r--test/reference/extend-pad.ps.ref.pngbin0 -> 314 bytes
-rw-r--r--test/reference/extend-pad.quartz.xfail.pngbin0 -> 270 bytes
-rw-r--r--test/reference/extend-pad.ref.pngbin0 -> 315 bytes
-rw-r--r--test/reference/extend-pad.svg.xfail.pngbin0 -> 270 bytes
-rw-r--r--test/reference/extend-reflect-similar.base.argb32.ref.pngbin0 -> 133406 bytes
-rw-r--r--test/reference/extend-reflect-similar.base.rgb24.ref.pngbin0 -> 133406 bytes
-rw-r--r--test/reference/extend-reflect-similar.image16.ref.pngbin0 -> 99786 bytes
-rw-r--r--test/reference/extend-reflect-similar.ps2.ref.pngbin0 -> 146990 bytes
-rw-r--r--test/reference/extend-reflect-similar.ps3.ref.pngbin0 -> 146990 bytes
-rw-r--r--test/reference/extend-reflect-similar.ref.pngbin0 -> 153571 bytes
-rw-r--r--test/reference/extend-reflect.base.argb32.ref.pngbin0 -> 133406 bytes
-rw-r--r--test/reference/extend-reflect.base.rgb24.ref.pngbin0 -> 133406 bytes
-rw-r--r--test/reference/extend-reflect.image16.ref.pngbin0 -> 99786 bytes
-rw-r--r--test/reference/extend-reflect.ps2.ref.pngbin0 -> 146990 bytes
-rw-r--r--test/reference/extend-reflect.ps3.ref.pngbin0 -> 146990 bytes
-rw-r--r--test/reference/extend-reflect.ref.pngbin0 -> 153571 bytes
-rw-r--r--test/reference/extend-repeat-similar.base.argb32.ref.pngbin0 -> 108603 bytes
-rw-r--r--test/reference/extend-repeat-similar.base.rgb24.ref.pngbin0 -> 108603 bytes
-rw-r--r--test/reference/extend-repeat-similar.image16.ref.pngbin0 -> 83738 bytes
-rw-r--r--test/reference/extend-repeat-similar.ps2.ref.pngbin0 -> 119246 bytes
-rw-r--r--test/reference/extend-repeat-similar.ps3.ref.pngbin0 -> 119246 bytes
-rw-r--r--test/reference/extend-repeat-similar.ref.pngbin0 -> 108622 bytes
-rw-r--r--test/reference/extend-repeat.base.argb32.ref.pngbin0 -> 108603 bytes
-rw-r--r--test/reference/extend-repeat.base.rgb24.ref.pngbin0 -> 108603 bytes
-rw-r--r--test/reference/extend-repeat.image16.ref.pngbin0 -> 83738 bytes
-rw-r--r--test/reference/extend-repeat.ps2.ref.pngbin0 -> 119246 bytes
-rw-r--r--test/reference/extend-repeat.ps3.ref.pngbin0 -> 119246 bytes
-rw-r--r--test/reference/extend-repeat.ref.pngbin0 -> 108622 bytes
-rw-r--r--test/reference/extended-blend-alpha-mask.argb32.ref.pngbin0 -> 9221 bytes
-rw-r--r--test/reference/extended-blend-alpha-mask.base.argb32.ref.pngbin0 -> 9221 bytes
-rw-r--r--test/reference/extended-blend-alpha-mask.base.rgb24.ref.pngbin0 -> 4597 bytes
-rw-r--r--test/reference/extended-blend-alpha-mask.rgb24.ref.pngbin0 -> 4597 bytes
-rw-r--r--test/reference/extended-blend-alpha.argb32.ref.pngbin0 -> 9406 bytes
-rw-r--r--test/reference/extended-blend-alpha.base.argb32.ref.pngbin0 -> 9406 bytes
-rw-r--r--test/reference/extended-blend-alpha.base.rgb24.ref.pngbin0 -> 5740 bytes
-rw-r--r--test/reference/extended-blend-alpha.image16.ref.pngbin0 -> 4626 bytes
-rw-r--r--test/reference/extended-blend-alpha.quartz.argb32.ref.pngbin0 -> 9729 bytes
-rw-r--r--test/reference/extended-blend-alpha.quartz.rgb24.ref.pngbin0 -> 5598 bytes
-rw-r--r--test/reference/extended-blend-alpha.rgb24.ref.pngbin0 -> 5740 bytes
-rw-r--r--test/reference/extended-blend-alpha.svg12.argb32.xfail.pngbin0 -> 6658 bytes
-rw-r--r--test/reference/extended-blend-alpha.svg12.rgb24.xfail.pngbin0 -> 5014 bytes
-rw-r--r--test/reference/extended-blend-mask.argb32.ref.pngbin0 -> 3959 bytes
-rw-r--r--test/reference/extended-blend-mask.base.argb32.ref.pngbin0 -> 3971 bytes
-rw-r--r--test/reference/extended-blend-mask.base.rgb24.ref.pngbin0 -> 3643 bytes
-rw-r--r--test/reference/extended-blend-mask.rgb24.ref.pngbin0 -> 3634 bytes
-rw-r--r--test/reference/extended-blend-solid-alpha.argb32.ref.pngbin0 -> 9406 bytes
-rw-r--r--test/reference/extended-blend-solid-alpha.base.argb32.ref.pngbin0 -> 9406 bytes
-rw-r--r--test/reference/extended-blend-solid-alpha.base.rgb24.ref.pngbin0 -> 5740 bytes
-rw-r--r--test/reference/extended-blend-solid-alpha.image16.ref.pngbin0 -> 4626 bytes
-rw-r--r--test/reference/extended-blend-solid-alpha.rgb24.ref.pngbin0 -> 5740 bytes
-rw-r--r--test/reference/extended-blend-solid.argb32.ref.pngbin0 -> 4072 bytes
-rw-r--r--test/reference/extended-blend-solid.base.argb32.ref.pngbin0 -> 4063 bytes
-rw-r--r--test/reference/extended-blend-solid.base.rgb24.ref.pngbin0 -> 3775 bytes
-rw-r--r--test/reference/extended-blend-solid.image16.ref.pngbin0 -> 4145 bytes
-rw-r--r--test/reference/extended-blend-solid.rgb24.ref.pngbin0 -> 3784 bytes
-rw-r--r--test/reference/extended-blend.argb32.ref.pngbin0 -> 4072 bytes
-rw-r--r--test/reference/extended-blend.base.argb32.ref.pngbin0 -> 4063 bytes
-rw-r--r--test/reference/extended-blend.base.rgb24.ref.pngbin0 -> 3775 bytes
-rw-r--r--test/reference/extended-blend.image16.ref.pngbin0 -> 4145 bytes
-rw-r--r--test/reference/extended-blend.quartz.argb32.ref.pngbin0 -> 4284 bytes
-rw-r--r--test/reference/extended-blend.quartz.rgb24.ref.pngbin0 -> 3965 bytes
-rw-r--r--test/reference/extended-blend.rgb24.ref.pngbin0 -> 3784 bytes
-rw-r--r--test/reference/extended-blend.svg12.argb32.xfail.pngbin0 -> 2273 bytes
-rw-r--r--test/reference/extended-blend.svg12.rgb24.xfail.pngbin0 -> 1856 bytes
-rw-r--r--test/reference/fallback-resolution.ppi144x144.ps.ref.pngbin0 -> 5911 bytes
-rw-r--r--test/reference/fallback-resolution.ppi144x144.ref.pngbin0 -> 8746 bytes
-rw-r--r--test/reference/fallback-resolution.ppi144x72.ps.ref.pngbin0 -> 7206 bytes
-rw-r--r--test/reference/fallback-resolution.ppi144x72.ref.pngbin0 -> 8531 bytes
-rw-r--r--test/reference/fallback-resolution.ppi288x288.pdf.ref.pngbin0 -> 8681 bytes
-rw-r--r--test/reference/fallback-resolution.ppi288x288.ps.ref.pngbin0 -> 4450 bytes
-rw-r--r--test/reference/fallback-resolution.ppi288x288.svg.ref.pngbin0 -> 5771 bytes
-rw-r--r--test/reference/fallback-resolution.ppi288x72.ps.ref.pngbin0 -> 6444 bytes
-rw-r--r--test/reference/fallback-resolution.ppi288x72.ref.pngbin0 -> 7203 bytes
-rw-r--r--test/reference/fallback-resolution.ppi576x576.pdf.ref.pngbin0 -> 8732 bytes
-rw-r--r--test/reference/fallback-resolution.ppi576x576.ps.ref.pngbin0 -> 3448 bytes
-rw-r--r--test/reference/fallback-resolution.ppi576x576.svg.ref.pngbin0 -> 4317 bytes
-rw-r--r--test/reference/fallback-resolution.ppi576x72.ps.ref.pngbin0 -> 5992 bytes
-rw-r--r--test/reference/fallback-resolution.ppi576x72.ref.pngbin0 -> 6457 bytes
-rw-r--r--test/reference/fallback-resolution.ppi72x144.ps.ref.pngbin0 -> 7270 bytes
-rw-r--r--test/reference/fallback-resolution.ppi72x144.ref.pngbin0 -> 8710 bytes
-rw-r--r--test/reference/fallback-resolution.ppi72x288.ps.ref.pngbin0 -> 6616 bytes
-rw-r--r--test/reference/fallback-resolution.ppi72x288.ref.pngbin0 -> 7224 bytes
-rw-r--r--test/reference/fallback-resolution.ppi72x576.ps.ref.pngbin0 -> 6349 bytes
-rw-r--r--test/reference/fallback-resolution.ppi72x576.ref.pngbin0 -> 6604 bytes
-rw-r--r--test/reference/fallback-resolution.ppi72x72.ref.pngbin0 -> 8579 bytes
-rw-r--r--test/reference/fallback.argb32.ref.pngbin0 -> 4133 bytes
-rw-r--r--test/reference/fallback.base.argb32.ref.pngbin0 -> 4156 bytes
-rw-r--r--test/reference/fallback.base.rgb24.ref.pngbin0 -> 3332 bytes
-rw-r--r--test/reference/fallback.image16.rgb24.ref.pngbin0 -> 2642 bytes
-rw-r--r--test/reference/fallback.mask.argb32.ref.pngbin0 -> 4070 bytes
-rw-r--r--test/reference/fallback.mask.rgb24.ref.pngbin0 -> 3141 bytes
-rw-r--r--test/reference/fallback.rgb24.ref.pngbin0 -> 3283 bytes
-rw-r--r--test/reference/fallback.traps.argb32.ref.pngbin0 -> 4156 bytes
-rw-r--r--test/reference/fallback.traps.rgb24.ref.pngbin0 -> 3332 bytes
-rw-r--r--test/reference/fill-alpha-pattern.base.argb32.ref.pngbin0 -> 3379 bytes
-rw-r--r--test/reference/fill-alpha-pattern.base.rgb24.ref.pngbin0 -> 3379 bytes
-rw-r--r--test/reference/fill-alpha-pattern.image16.ref.pngbin0 -> 3380 bytes
-rw-r--r--test/reference/fill-alpha-pattern.pdf.ref.pngbin0 -> 2945 bytes
-rw-r--r--test/reference/fill-alpha-pattern.ps3.argb32.ref.pngbin0 -> 3484 bytes
-rw-r--r--test/reference/fill-alpha-pattern.quartz.ref.pngbin0 -> 7943 bytes
-rw-r--r--test/reference/fill-alpha-pattern.ref.pngbin0 -> 3500 bytes
-rw-r--r--test/reference/fill-alpha-pattern.traps.argb32.ref.pngbin0 -> 3379 bytes
-rw-r--r--test/reference/fill-alpha-pattern.traps.rgb24.ref.pngbin0 -> 3379 bytes
-rw-r--r--test/reference/fill-alpha.base.argb32.ref.pngbin0 -> 2824 bytes
-rw-r--r--test/reference/fill-alpha.base.rgb24.ref.pngbin0 -> 2824 bytes
-rw-r--r--test/reference/fill-alpha.image16.ref.pngbin0 -> 2145 bytes
-rw-r--r--test/reference/fill-alpha.ps.argb32.ref.pngbin0 -> 2248 bytes
-rw-r--r--test/reference/fill-alpha.quartz.ref.pngbin0 -> 2704 bytes
-rw-r--r--test/reference/fill-alpha.ref.pngbin0 -> 2754 bytes
-rw-r--r--test/reference/fill-alpha.traps.argb32.ref.pngbin0 -> 2824 bytes
-rw-r--r--test/reference/fill-alpha.traps.rgb24.ref.pngbin0 -> 2824 bytes
-rw-r--r--test/reference/fill-and-stroke-alpha-add.base.argb32.ref.pngbin0 -> 552 bytes
-rw-r--r--test/reference/fill-and-stroke-alpha-add.base.rgb24.ref.pngbin0 -> 552 bytes
-rw-r--r--test/reference/fill-and-stroke-alpha-add.image16.ref.pngbin0 -> 536 bytes
-rw-r--r--test/reference/fill-and-stroke-alpha-add.quartz.ref.pngbin0 -> 542 bytes
-rw-r--r--test/reference/fill-and-stroke-alpha-add.ref.pngbin0 -> 558 bytes
-rw-r--r--test/reference/fill-and-stroke-alpha-add.svg12.xfail.pngbin0 -> 631 bytes
-rw-r--r--test/reference/fill-and-stroke-alpha-add.traps.argb32.ref.pngbin0 -> 552 bytes
-rw-r--r--test/reference/fill-and-stroke-alpha-add.traps.rgb24.ref.pngbin0 -> 552 bytes
-rw-r--r--test/reference/fill-and-stroke-alpha.base.argb32.ref.pngbin0 -> 507 bytes
-rw-r--r--test/reference/fill-and-stroke-alpha.base.rgb24.ref.pngbin0 -> 507 bytes
-rw-r--r--test/reference/fill-and-stroke-alpha.image16.ref.pngbin0 -> 470 bytes
-rw-r--r--test/reference/fill-and-stroke-alpha.ref.pngbin0 -> 513 bytes
-rw-r--r--test/reference/fill-and-stroke-alpha.traps.argb32.ref.pngbin0 -> 507 bytes
-rw-r--r--test/reference/fill-and-stroke-alpha.traps.rgb24.ref.pngbin0 -> 507 bytes
-rw-r--r--test/reference/fill-and-stroke.base.argb32.ref.pngbin0 -> 321 bytes
-rw-r--r--test/reference/fill-and-stroke.base.rgb24.ref.pngbin0 -> 293 bytes
-rw-r--r--test/reference/fill-and-stroke.image16.ref.pngbin0 -> 251 bytes
-rw-r--r--test/reference/fill-and-stroke.ps.argb32.ref.pngbin0 -> 257 bytes
-rw-r--r--test/reference/fill-and-stroke.ps.rgb24.ref.pngbin0 -> 225 bytes
-rw-r--r--test/reference/fill-and-stroke.quartz.argb32.ref.pngbin0 -> 273 bytes
-rw-r--r--test/reference/fill-and-stroke.quartz.rgb24.ref.pngbin0 -> 249 bytes
-rw-r--r--test/reference/fill-and-stroke.ref.pngbin0 -> 328 bytes
-rw-r--r--test/reference/fill-and-stroke.traps.argb32.ref.pngbin0 -> 321 bytes
-rw-r--r--test/reference/fill-and-stroke.traps.rgb24.ref.pngbin0 -> 293 bytes
-rw-r--r--test/reference/fill-degenerate-sort-order.argb32.ref.pngbin0 -> 2390 bytes
-rw-r--r--test/reference/fill-degenerate-sort-order.base.argb32.ref.pngbin0 -> 2378 bytes
-rw-r--r--test/reference/fill-degenerate-sort-order.base.rgb24.ref.pngbin0 -> 2041 bytes
-rw-r--r--test/reference/fill-degenerate-sort-order.image16.ref.pngbin0 -> 1753 bytes
-rw-r--r--test/reference/fill-degenerate-sort-order.ps.argb32.xfail.pngbin0 -> 1903 bytes
-rw-r--r--test/reference/fill-degenerate-sort-order.ps.rgb24.xfail.pngbin0 -> 1638 bytes
-rw-r--r--test/reference/fill-degenerate-sort-order.quartz.argb32.ref.pngbin0 -> 2451 bytes
-rw-r--r--test/reference/fill-degenerate-sort-order.quartz.rgb24.ref.pngbin0 -> 2079 bytes
-rw-r--r--test/reference/fill-degenerate-sort-order.rgb24.ref.pngbin0 -> 2048 bytes
-rw-r--r--test/reference/fill-degenerate-sort-order.traps.argb32.ref.pngbin0 -> 2378 bytes
-rw-r--r--test/reference/fill-degenerate-sort-order.traps.rgb24.ref.pngbin0 -> 2041 bytes
-rw-r--r--test/reference/fill-disjoint.base.argb32.ref.pngbin0 -> 1098 bytes
-rw-r--r--test/reference/fill-disjoint.base.rgb24.ref.pngbin0 -> 1098 bytes
-rw-r--r--test/reference/fill-disjoint.ref.pngbin0 -> 1098 bytes
-rw-r--r--test/reference/fill-empty.base.argb32.ref.pngbin0 -> 99 bytes
-rw-r--r--test/reference/fill-empty.base.rgb24.ref.pngbin0 -> 97 bytes
-rw-r--r--test/reference/fill-empty.ref.pngbin0 -> 99 bytes
-rw-r--r--test/reference/fill-empty.svg12.rgb24.xfail.pngbin0 -> 99 bytes
-rw-r--r--test/reference/fill-image.base.argb32.ref.pngbin0 -> 1458 bytes
-rw-r--r--test/reference/fill-image.base.rgb24.ref.pngbin0 -> 1458 bytes
-rw-r--r--test/reference/fill-image.image16.ref.pngbin0 -> 1163 bytes
-rw-r--r--test/reference/fill-image.ps.ref.pngbin0 -> 1645 bytes
-rw-r--r--test/reference/fill-image.quartz.ref.pngbin0 -> 1297 bytes
-rw-r--r--test/reference/fill-image.ref.pngbin0 -> 1457 bytes
-rw-r--r--test/reference/fill-image.traps.argb32.ref.pngbin0 -> 1458 bytes
-rw-r--r--test/reference/fill-image.traps.rgb24.ref.pngbin0 -> 1458 bytes
-rw-r--r--test/reference/fill-missed-stop.base.argb32.ref.pngbin0 -> 447 bytes
-rw-r--r--test/reference/fill-missed-stop.base.rgb24.ref.pngbin0 -> 375 bytes
-rw-r--r--test/reference/fill-missed-stop.pdf.argb32.ref.pngbin0 -> 452 bytes
-rw-r--r--test/reference/fill-missed-stop.ps2.argb32.ref.pngbin0 -> 564 bytes
-rw-r--r--test/reference/fill-missed-stop.ps2.rgb24.ref.pngbin0 -> 531 bytes
-rw-r--r--test/reference/fill-missed-stop.ps3.argb32.ref.pngbin0 -> 564 bytes
-rw-r--r--test/reference/fill-missed-stop.ps3.rgb24.ref.pngbin0 -> 531 bytes
-rw-r--r--test/reference/fill-missed-stop.ref.pngbin0 -> 455 bytes
-rw-r--r--test/reference/fill-missed-stop.traps.argb32.ref.pngbin0 -> 447 bytes
-rw-r--r--test/reference/fill-missed-stop.traps.rgb24.ref.pngbin0 -> 375 bytes
-rw-r--r--test/reference/fill-rule.argb32.ref.pngbin0 -> 2076 bytes
-rw-r--r--test/reference/fill-rule.base.argb32.ref.pngbin0 -> 1979 bytes
-rw-r--r--test/reference/fill-rule.base.rgb24.ref.pngbin0 -> 1703 bytes
-rw-r--r--test/reference/fill-rule.image16.ref.pngbin0 -> 1625 bytes
-rw-r--r--test/reference/fill-rule.ps2.argb32.ref.pngbin0 -> 1878 bytes
-rw-r--r--test/reference/fill-rule.ps2.rgb24.ref.pngbin0 -> 1524 bytes
-rw-r--r--test/reference/fill-rule.ps3.argb32.ref.pngbin0 -> 1878 bytes
-rw-r--r--test/reference/fill-rule.ps3.rgb24.ref.pngbin0 -> 1524 bytes
-rw-r--r--test/reference/fill-rule.quartz.argb32.ref.pngbin0 -> 2060 bytes
-rw-r--r--test/reference/fill-rule.quartz.rgb24.ref.pngbin0 -> 1771 bytes
-rw-r--r--test/reference/fill-rule.rgb24.ref.pngbin0 -> 1763 bytes
-rw-r--r--test/reference/fill-rule.traps.argb32.ref.pngbin0 -> 1979 bytes
-rw-r--r--test/reference/fill-rule.traps.rgb24.ref.pngbin0 -> 1703 bytes
-rw-r--r--test/reference/fill-xlib-fallback.rgb24.ref.pngbin0 -> 1458 bytes
-rw-r--r--test/reference/fill-xlib-window.rgb24.ref.pngbin0 -> 1458 bytes
-rw-r--r--test/reference/fill-xlib.ref.pngbin0 -> 1458 bytes
-rw-r--r--test/reference/fill.image.argb32.ref.pngbin0 -> 1482 bytes
-rw-r--r--test/reference/fill.image.rgb24.ref.pngbin0 -> 1482 bytes
-rw-r--r--test/reference/filter-bilinear-extents.base.argb32.ref.pngbin0 -> 1210 bytes
-rw-r--r--test/reference/filter-bilinear-extents.base.rgb24.ref.pngbin0 -> 1210 bytes
-rw-r--r--test/reference/filter-bilinear-extents.image16.ref.pngbin0 -> 895 bytes
-rw-r--r--test/reference/filter-bilinear-extents.pdf.xfail.pngbin0 -> 401 bytes
-rw-r--r--test/reference/filter-bilinear-extents.ps2.ref.pngbin0 -> 556 bytes
-rw-r--r--test/reference/filter-bilinear-extents.ps3.ref.pngbin0 -> 556 bytes
-rw-r--r--test/reference/filter-bilinear-extents.quartz.xfail.pngbin0 -> 308 bytes
-rw-r--r--test/reference/filter-bilinear-extents.ref.pngbin0 -> 1210 bytes
-rw-r--r--test/reference/filter-nearest-offset.base.argb32.ref.pngbin0 -> 201 bytes
-rw-r--r--test/reference/filter-nearest-offset.base.rgb24.ref.pngbin0 -> 201 bytes
-rw-r--r--test/reference/filter-nearest-offset.gl.xfail.pngbin0 -> 260 bytes
-rw-r--r--test/reference/filter-nearest-offset.pdf.xfail.pngbin0 -> 4522 bytes
-rw-r--r--test/reference/filter-nearest-offset.ps2.ref.pngbin0 -> 255 bytes
-rw-r--r--test/reference/filter-nearest-offset.ps3.ref.pngbin0 -> 255 bytes
-rw-r--r--test/reference/filter-nearest-offset.ref.pngbin0 -> 248 bytes
-rw-r--r--test/reference/filter-nearest-offset.svg.xfail.pngbin0 -> 4419 bytes
-rw-r--r--test/reference/filter-nearest-transformed.base.argb32.ref.pngbin0 -> 514 bytes
-rw-r--r--test/reference/filter-nearest-transformed.base.rgb24.ref.pngbin0 -> 514 bytes
-rw-r--r--test/reference/filter-nearest-transformed.gl.xfail.pngbin0 -> 514 bytes
-rw-r--r--test/reference/filter-nearest-transformed.image16.ref.pngbin0 -> 418 bytes
-rw-r--r--test/reference/filter-nearest-transformed.pdf.xfail.pngbin0 -> 532 bytes
-rw-r--r--test/reference/filter-nearest-transformed.quartz.xfail.pngbin0 -> 349 bytes
-rw-r--r--test/reference/filter-nearest-transformed.ref.pngbin0 -> 570 bytes
-rw-r--r--test/reference/filter-nearest-transformed.svg.xfail.pngbin0 -> 546 bytes
-rw-r--r--test/reference/finer-grained-fallbacks.base.argb32.ref.pngbin0 -> 1110 bytes
-rw-r--r--test/reference/finer-grained-fallbacks.base.rgb24.ref.pngbin0 -> 856 bytes
-rw-r--r--test/reference/finer-grained-fallbacks.gl.argb32.ref.pngbin0 -> 1075 bytes
-rw-r--r--test/reference/finer-grained-fallbacks.image16.ref.pngbin0 -> 862 bytes
-rw-r--r--test/reference/finer-grained-fallbacks.mask.argb32.ref.pngbin0 -> 1167 bytes
-rw-r--r--test/reference/finer-grained-fallbacks.mask.rgb24.ref.pngbin0 -> 891 bytes
-rw-r--r--test/reference/finer-grained-fallbacks.ps2.argb32.ref.pngbin0 -> 1168 bytes
-rw-r--r--test/reference/finer-grained-fallbacks.ps2.ref.pngbin0 -> 1356 bytes
-rw-r--r--test/reference/finer-grained-fallbacks.ps2.rgb24.ref.pngbin0 -> 936 bytes
-rw-r--r--test/reference/finer-grained-fallbacks.ps3.argb32.ref.pngbin0 -> 1168 bytes
-rw-r--r--test/reference/finer-grained-fallbacks.ps3.ref.pngbin0 -> 1356 bytes
-rw-r--r--test/reference/finer-grained-fallbacks.ps3.rgb24.ref.pngbin0 -> 936 bytes
-rw-r--r--test/reference/finer-grained-fallbacks.quartz.argb32.ref.pngbin0 -> 988 bytes
-rw-r--r--test/reference/finer-grained-fallbacks.quartz.rgb24.ref.pngbin0 -> 763 bytes
-rw-r--r--test/reference/finer-grained-fallbacks.ref.pngbin0 -> 1151 bytes
-rw-r--r--test/reference/finer-grained-fallbacks.svg12.argb32.ref.pngbin0 -> 190 bytes
-rw-r--r--test/reference/finer-grained-fallbacks.svg12.rgb24.ref.pngbin0 -> 191 bytes
-rw-r--r--test/reference/finer-grained-fallbacks.traps.argb32.ref.pngbin0 -> 1110 bytes
-rw-r--r--test/reference/finer-grained-fallbacks.traps.rgb24.ref.pngbin0 -> 856 bytes
-rw-r--r--test/reference/finer-grained-fallbacks.xlib-fallback.ref.pngbin0 -> 919 bytes
-rw-r--r--test/reference/font-matrix-translation.base.argb32.ref.pngbin0 -> 865 bytes
-rw-r--r--test/reference/font-matrix-translation.base.rgb24.ref.pngbin0 -> 865 bytes
-rw-r--r--test/reference/font-matrix-translation.image16.ref.pngbin0 -> 852 bytes
-rw-r--r--test/reference/font-matrix-translation.ps2.argb32.ref.pngbin0 -> 748 bytes
-rw-r--r--test/reference/font-matrix-translation.ps2.rgb24.ref.pngbin0 -> 748 bytes
-rw-r--r--test/reference/font-matrix-translation.ps3.argb32.ref.pngbin0 -> 748 bytes
-rw-r--r--test/reference/font-matrix-translation.ps3.rgb24.ref.pngbin0 -> 748 bytes
-rw-r--r--test/reference/font-matrix-translation.quartz.ref.pngbin0 -> 996 bytes
-rw-r--r--test/reference/font-matrix-translation.ref.pngbin0 -> 865 bytes
-rw-r--r--test/reference/font-matrix-translation.svg.ref.pngbin0 -> 870 bytes
-rw-r--r--test/reference/font-matrix-translation.traps.ref.pngbin0 -> 865 bytes
-rw-r--r--test/reference/ft-show-glyphs-positioning.base.argb32.ref.pngbin0 -> 3243 bytes
-rw-r--r--test/reference/ft-show-glyphs-positioning.base.rgb24.ref.pngbin0 -> 3243 bytes
-rw-r--r--test/reference/ft-show-glyphs-positioning.image16.ref.pngbin0 -> 2772 bytes
-rw-r--r--test/reference/ft-show-glyphs-positioning.pdf.ref.pngbin0 -> 3117 bytes
-rw-r--r--test/reference/ft-show-glyphs-positioning.ps2.ref.pngbin0 -> 2269 bytes
-rw-r--r--test/reference/ft-show-glyphs-positioning.ps3.ref.pngbin0 -> 2269 bytes
-rw-r--r--test/reference/ft-show-glyphs-positioning.ref.pngbin0 -> 3243 bytes
-rw-r--r--test/reference/ft-show-glyphs-positioning.svg.ref.pngbin0 -> 6018 bytes
-rw-r--r--test/reference/ft-show-glyphs-positioning.traps.ref.pngbin0 -> 3243 bytes
-rw-r--r--test/reference/ft-show-glyphs-table.base.argb32.ref.pngbin0 -> 9975 bytes
-rw-r--r--test/reference/ft-show-glyphs-table.base.rgb24.ref.pngbin0 -> 9975 bytes
-rw-r--r--test/reference/ft-show-glyphs-table.image16.ref.pngbin0 -> 8052 bytes
-rw-r--r--test/reference/ft-show-glyphs-table.ps2.ref.pngbin0 -> 5687 bytes
-rw-r--r--test/reference/ft-show-glyphs-table.ps3.ref.pngbin0 -> 5687 bytes
-rw-r--r--test/reference/ft-show-glyphs-table.quartz.xfail.pngbin0 -> 827 bytes
-rw-r--r--test/reference/ft-show-glyphs-table.ref.pngbin0 -> 9975 bytes
-rw-r--r--test/reference/ft-show-glyphs-table.svg.ref.pngbin0 -> 10005 bytes
-rw-r--r--test/reference/ft-show-glyphs-table.traps.ref.pngbin0 -> 9975 bytes
-rw-r--r--test/reference/ft-text-antialias-none.base.argb32.ref.pngbin0 -> 295 bytes
-rw-r--r--test/reference/ft-text-antialias-none.base.rgb24.ref.pngbin0 -> 295 bytes
-rw-r--r--test/reference/ft-text-antialias-none.ps2.argb32.ref.pngbin0 -> 335 bytes
-rw-r--r--test/reference/ft-text-antialias-none.ps3.argb32.ref.pngbin0 -> 335 bytes
-rw-r--r--test/reference/ft-text-antialias-none.ref.pngbin0 -> 336 bytes
-rw-r--r--test/reference/ft-text-vertical-layout-type1.base.argb32.ref.pngbin0 -> 3066 bytes
-rw-r--r--test/reference/ft-text-vertical-layout-type1.base.rgb24.ref.pngbin0 -> 3066 bytes
-rw-r--r--test/reference/ft-text-vertical-layout-type1.image16.ref.pngbin0 -> 3072 bytes
-rw-r--r--test/reference/ft-text-vertical-layout-type1.pdf.ref.pngbin0 -> 3635 bytes
-rw-r--r--test/reference/ft-text-vertical-layout-type1.ps.ref.pngbin0 -> 2088 bytes
-rw-r--r--test/reference/ft-text-vertical-layout-type1.quartz.xfail.pngbin0 -> 3635 bytes
-rw-r--r--test/reference/ft-text-vertical-layout-type1.ref.pngbin0 -> 3052 bytes
-rw-r--r--test/reference/ft-text-vertical-layout-type1.svg.ref.pngbin0 -> 3607 bytes
-rw-r--r--test/reference/ft-text-vertical-layout-type1.traps.argb32.ref.pngbin0 -> 3066 bytes
-rw-r--r--test/reference/ft-text-vertical-layout-type1.traps.rgb24.ref.pngbin0 -> 3066 bytes
-rw-r--r--test/reference/ft-text-vertical-layout-type1.xfail.pngbin0 -> 2683 bytes
-rw-r--r--test/reference/ft-text-vertical-layout-type3.base.argb32.ref.pngbin0 -> 3597 bytes
-rw-r--r--test/reference/ft-text-vertical-layout-type3.base.rgb24.ref.pngbin0 -> 3597 bytes
-rw-r--r--test/reference/ft-text-vertical-layout-type3.image16.ref.pngbin0 -> 3141 bytes
-rw-r--r--test/reference/ft-text-vertical-layout-type3.mask.argb32.ref.pngbin0 -> 3610 bytes
-rw-r--r--test/reference/ft-text-vertical-layout-type3.mask.rgb24.ref.pngbin0 -> 3610 bytes
-rw-r--r--test/reference/ft-text-vertical-layout-type3.pdf.ref.pngbin0 -> 3639 bytes
-rw-r--r--test/reference/ft-text-vertical-layout-type3.ps.ref.pngbin0 -> 2134 bytes
-rw-r--r--test/reference/ft-text-vertical-layout-type3.quartz.ref.pngbin0 -> 3573 bytes
-rw-r--r--test/reference/ft-text-vertical-layout-type3.ref.pngbin0 -> 3609 bytes
-rw-r--r--test/reference/ft-text-vertical-layout-type3.svg.ref.pngbin0 -> 3626 bytes
-rw-r--r--test/reference/ft-text-vertical-layout-type3.traps.argb32.ref.pngbin0 -> 3597 bytes
-rw-r--r--test/reference/ft-text-vertical-layout-type3.traps.rgb24.ref.pngbin0 -> 3597 bytes
-rw-r--r--test/reference/get-group-target.base.argb32.ref.pngbin0 -> 113 bytes
-rw-r--r--test/reference/get-group-target.base.rgb24.ref.pngbin0 -> 113 bytes
-rw-r--r--test/reference/get-group-target.ref.pngbin0 -> 134 bytes
-rw-r--r--test/reference/gl-surface-source.base.argb32.ref.pngbin0 -> 377 bytes
-rw-r--r--test/reference/gl-surface-source.base.rgb24.ref.pngbin0 -> 301 bytes
-rw-r--r--test/reference/gl-surface-source.image16.ref.pngbin0 -> 305 bytes
-rw-r--r--test/reference/gl-surface-source.ref.pngbin0 -> 377 bytes
-rw-r--r--test/reference/glyph-cache-pressure.base.argb32.ref.pngbin0 -> 2858 bytes
-rw-r--r--test/reference/glyph-cache-pressure.base.rgb24.ref.pngbin0 -> 2858 bytes
-rw-r--r--test/reference/glyph-cache-pressure.image16.ref.pngbin0 -> 2453 bytes
-rw-r--r--test/reference/glyph-cache-pressure.ps2.ref.pngbin0 -> 1454 bytes
-rw-r--r--test/reference/glyph-cache-pressure.ps3.ref.pngbin0 -> 1454 bytes
-rw-r--r--test/reference/glyph-cache-pressure.quartz.ref.pngbin0 -> 3284 bytes
-rw-r--r--test/reference/glyph-cache-pressure.ref.pngbin0 -> 2858 bytes
-rw-r--r--test/reference/glyph-cache-pressure.traps.ref.pngbin0 -> 2858 bytes
-rw-r--r--test/reference/gradient-alpha.base.argb32.ref.pngbin0 -> 125 bytes
-rw-r--r--test/reference/gradient-alpha.base.rgb24.ref.pngbin0 -> 119 bytes
-rw-r--r--test/reference/gradient-alpha.ps2.argb32.ref.pngbin0 -> 134 bytes
-rw-r--r--test/reference/gradient-alpha.ps2.rgb24.ref.pngbin0 -> 130 bytes
-rw-r--r--test/reference/gradient-alpha.ps3.argb32.ref.pngbin0 -> 134 bytes
-rw-r--r--test/reference/gradient-alpha.ps3.rgb24.ref.pngbin0 -> 130 bytes
-rw-r--r--test/reference/gradient-alpha.ref.pngbin0 -> 125 bytes
-rw-r--r--test/reference/gradient-constant-alpha.base.argb32.ref.pngbin0 -> 111 bytes
-rw-r--r--test/reference/gradient-constant-alpha.base.rgb24.ref.pngbin0 -> 106 bytes
-rw-r--r--test/reference/gradient-constant-alpha.ps3.ref.pngbin0 -> 124 bytes
-rw-r--r--test/reference/gradient-constant-alpha.ps3.rgb24.ref.pngbin0 -> 124 bytes
-rw-r--r--test/reference/gradient-constant-alpha.quartz.argb32.ref.pngbin0 -> 214 bytes
-rw-r--r--test/reference/gradient-constant-alpha.ref.pngbin0 -> 111 bytes
-rw-r--r--test/reference/gradient-zero-stops-mask.base.argb32.ref.pngbin0 -> 86 bytes
-rw-r--r--test/reference/gradient-zero-stops-mask.base.rgb24.ref.pngbin0 -> 86 bytes
-rw-r--r--test/reference/gradient-zero-stops-mask.ref.pngbin0 -> 86 bytes
-rw-r--r--test/reference/gradient-zero-stops.base.argb32.ref.pngbin0 -> 86 bytes
-rw-r--r--test/reference/gradient-zero-stops.base.rgb24.ref.pngbin0 -> 86 bytes
-rw-r--r--test/reference/gradient-zero-stops.ref.pngbin0 -> 105 bytes
-rw-r--r--test/reference/group-clip.base.argb32.ref.pngbin0 -> 191 bytes
-rw-r--r--test/reference/group-clip.base.rgb24.ref.pngbin0 -> 191 bytes
-rw-r--r--test/reference/group-clip.image16.ref.pngbin0 -> 193 bytes
-rw-r--r--test/reference/group-clip.ref.pngbin0 -> 191 bytes
-rw-r--r--test/reference/group-paint.base.argb32.ref.pngbin0 -> 95 bytes
-rw-r--r--test/reference/group-paint.base.rgb24.ref.pngbin0 -> 95 bytes
-rw-r--r--test/reference/group-paint.ref.pngbin0 -> 118 bytes
-rw-r--r--test/reference/group-unaligned.base.argb32.ref.pngbin0 -> 468 bytes
-rw-r--r--test/reference/group-unaligned.base.rgb24.ref.pngbin0 -> 468 bytes
-rw-r--r--test/reference/group-unaligned.image16.ref.pngbin0 -> 395 bytes
-rw-r--r--test/reference/group-unaligned.ps.ref.pngbin0 -> 321 bytes
-rw-r--r--test/reference/group-unaligned.ps.rgb24.xfail.pngbin0 -> 371 bytes
-rw-r--r--test/reference/group-unaligned.quartz.ref.pngbin0 -> 363 bytes
-rw-r--r--test/reference/group-unaligned.ref.pngbin0 -> 475 bytes
-rw-r--r--test/reference/group-unaligned.svg.argb32.xfail.pngbin0 -> 520 bytes
-rw-r--r--test/reference/group-unaligned.svg.rgb24.xfail.pngbin0 -> 425 bytes
-rw-r--r--test/reference/group-unaligned.traps.argb32.ref.pngbin0 -> 468 bytes
-rw-r--r--test/reference/group-unaligned.traps.rgb24.ref.pngbin0 -> 468 bytes
-rw-r--r--test/reference/group-unaligned.xlib-fallback.ref.pngbin0 -> 474 bytes
-rw-r--r--test/reference/halo-transform.base.argb32.ref.pngbin0 -> 15122 bytes
-rw-r--r--test/reference/halo-transform.base.rgb24.ref.pngbin0 -> 15122 bytes
-rw-r--r--test/reference/halo-transform.image16.ref.pngbin0 -> 10983 bytes
-rw-r--r--test/reference/halo-transform.ps.ref.pngbin0 -> 8691 bytes
-rw-r--r--test/reference/halo-transform.quartz.ref.pngbin0 -> 14360 bytes
-rw-r--r--test/reference/halo-transform.ref.pngbin0 -> 15265 bytes
-rw-r--r--test/reference/halo-transform.traps.ref.pngbin0 -> 15122 bytes
-rw-r--r--test/reference/halo.base.argb32.ref.pngbin0 -> 8594 bytes
-rw-r--r--test/reference/halo.base.rgb24.ref.pngbin0 -> 8594 bytes
-rw-r--r--test/reference/halo.image16.ref.pngbin0 -> 6172 bytes
-rw-r--r--test/reference/halo.mask.argb32.ref.pngbin0 -> 8726 bytes
-rw-r--r--test/reference/halo.mask.rgb24.ref.pngbin0 -> 8726 bytes
-rw-r--r--test/reference/halo.ps.ref.pngbin0 -> 5220 bytes
-rw-r--r--test/reference/halo.quartz.ref.pngbin0 -> 8601 bytes
-rw-r--r--test/reference/halo.ref.pngbin0 -> 8631 bytes
-rw-r--r--test/reference/halo.traps.ref.pngbin0 -> 8594 bytes
-rw-r--r--test/reference/hatchings.base.argb32.ref.pngbin0 -> 94196 bytes
-rw-r--r--test/reference/hatchings.base.rgb24.ref.pngbin0 -> 94196 bytes
-rw-r--r--test/reference/hatchings.mask.argb32.ref.pngbin0 -> 94631 bytes
-rw-r--r--test/reference/hatchings.mask.rgb24.ref.pngbin0 -> 94631 bytes
-rw-r--r--test/reference/hatchings.ref.pngbin0 -> 90698 bytes
-rw-r--r--test/reference/hatchings.traps.argb32.ref.pngbin0 -> 89997 bytes
-rw-r--r--test/reference/hatchings.traps.rgb24.ref.pngbin0 -> 89997 bytes
-rw-r--r--test/reference/horizontal-clip.base.argb32.ref.pngbin0 -> 113 bytes
-rw-r--r--test/reference/horizontal-clip.base.rgb24.ref.pngbin0 -> 113 bytes
-rw-r--r--test/reference/horizontal-clip.ref.pngbin0 -> 113 bytes
-rw-r--r--test/reference/huge-linear.base.argb32.ref.pngbin0 -> 1600 bytes
-rw-r--r--test/reference/huge-linear.base.rgb24.ref.pngbin0 -> 1600 bytes
-rw-r--r--test/reference/huge-linear.image16.ref.pngbin0 -> 1542 bytes
-rw-r--r--test/reference/huge-linear.pdf.ref.pngbin0 -> 1586 bytes
-rw-r--r--test/reference/huge-linear.ps3.ref.pngbin0 -> 1786 bytes
-rw-r--r--test/reference/huge-linear.quartz.ref.pngbin0 -> 15230 bytes
-rw-r--r--test/reference/huge-linear.ref.pngbin0 -> 1636 bytes
-rw-r--r--test/reference/huge-radial.base.argb32.ref.pngbin0 -> 41702 bytes
-rw-r--r--test/reference/huge-radial.base.rgb24.ref.pngbin0 -> 41702 bytes
-rw-r--r--test/reference/huge-radial.image16.ref.pngbin0 -> 17893 bytes
-rw-r--r--test/reference/huge-radial.ps3.ref.pngbin0 -> 18449 bytes
-rw-r--r--test/reference/huge-radial.quartz.ref.pngbin0 -> 84690 bytes
-rw-r--r--test/reference/huge-radial.ref.pngbin0 -> 41702 bytes
-rw-r--r--test/reference/image-bug-710072-aligned.base.argb32.ref.pngbin0 -> 151 bytes
-rw-r--r--test/reference/image-bug-710072-aligned.base.rgb24.ref.pngbin0 -> 151 bytes
-rw-r--r--test/reference/image-bug-710072-aligned.ref.pngbin0 -> 151 bytes
-rw-r--r--test/reference/image-bug-710072-unaligned.base.argb32.ref.pngbin0 -> 219 bytes
-rw-r--r--test/reference/image-bug-710072-unaligned.base.rgb24.ref.pngbin0 -> 219 bytes
-rw-r--r--test/reference/image-bug-710072-unaligned.ref.pngbin0 -> 212 bytes
-rw-r--r--test/reference/image-bug-710072-unaligned.traps.argb32.ref.pngbin0 -> 219 bytes
-rw-r--r--test/reference/image-bug-710072-unaligned.traps.rgb24.ref.pngbin0 -> 219 bytes
-rw-r--r--test/reference/image-bug-710072-unaligned.xlib-fallback.rgb24.ref.pngbin0 -> 219 bytes
-rw-r--r--test/reference/image-bug-710072-unaligned.xlib-window.rgb24.ref.pngbin0 -> 219 bytes
-rw-r--r--test/reference/image-surface-source.base.argb32.ref.pngbin0 -> 377 bytes
-rw-r--r--test/reference/image-surface-source.base.rgb24.ref.pngbin0 -> 301 bytes
-rw-r--r--test/reference/image-surface-source.image16.ref.pngbin0 -> 305 bytes
-rw-r--r--test/reference/image-surface-source.ps2.ref.pngbin0 -> 376 bytes
-rw-r--r--test/reference/image-surface-source.ps3.ref.pngbin0 -> 376 bytes
-rw-r--r--test/reference/image-surface-source.ref.pngbin0 -> 377 bytes
-rw-r--r--test/reference/image-surface-source.svg12.argb32.xfail.pngbin0 -> 278 bytes
-rw-r--r--test/reference/image-surface-source.svg12.rgb24.xfail.pngbin0 -> 278 bytes
-rw-r--r--test/reference/implicit-close.base.argb32.ref.pngbin0 -> 251 bytes
-rw-r--r--test/reference/implicit-close.base.rgb24.ref.pngbin0 -> 251 bytes
-rw-r--r--test/reference/implicit-close.ps.ref.pngbin0 -> 252 bytes
-rw-r--r--test/reference/implicit-close.ref.pngbin0 -> 251 bytes
-rw-r--r--test/reference/implicit-close.traps.argb32.ref.pngbin0 -> 251 bytes
-rw-r--r--test/reference/implicit-close.traps.rgb24.ref.pngbin0 -> 251 bytes
-rw-r--r--test/reference/infinite-join.base.argb32.ref.pngbin0 -> 160 bytes
-rw-r--r--test/reference/infinite-join.base.rgb24.ref.pngbin0 -> 160 bytes
-rw-r--r--test/reference/infinite-join.ps2.ref.pngbin0 -> 218 bytes
-rw-r--r--test/reference/infinite-join.ps3.ref.pngbin0 -> 218 bytes
-rw-r--r--test/reference/infinite-join.ref.pngbin0 -> 164 bytes
-rw-r--r--test/reference/infinite-join.traps.argb32.ref.pngbin0 -> 160 bytes
-rw-r--r--test/reference/infinite-join.traps.rgb24.ref.pngbin0 -> 160 bytes
-rw-r--r--test/reference/inverse-text.base.argb32.ref.pngbin0 -> 2162 bytes
-rw-r--r--test/reference/inverse-text.base.rgb24.ref.pngbin0 -> 2162 bytes
-rw-r--r--test/reference/inverse-text.mask.argb32.ref.pngbin0 -> 2162 bytes
-rw-r--r--test/reference/inverse-text.mask.rgb24.ref.pngbin0 -> 2162 bytes
-rw-r--r--test/reference/inverse-text.ref.pngbin0 -> 2162 bytes
-rw-r--r--test/reference/inverse-text.traps.ref.pngbin0 -> 2162 bytes
-rw-r--r--test/reference/inverted-clip.argb32.ref.pngbin0 -> 1390 bytes
-rw-r--r--test/reference/inverted-clip.base.xfail.pngbin0 -> 1293 bytes
-rw-r--r--test/reference/inverted-clip.rgb24.ref.pngbin0 -> 1274 bytes
-rw-r--r--test/reference/inverted-clip.traps.xfail.pngbin0 -> 1283 bytes
-rw-r--r--test/reference/inverted-clip.xfail.pngbin0 -> 1293 bytes
-rw-r--r--test/reference/joins-loop.base.argb32.ref.pngbin0 -> 4191 bytes
-rw-r--r--test/reference/joins-loop.base.rgb24.ref.pngbin0 -> 4191 bytes
-rw-r--r--test/reference/joins-loop.ref.pngbin0 -> 4333 bytes
-rw-r--r--test/reference/joins-loop.traps.argb32.ref.pngbin0 -> 4191 bytes
-rw-r--r--test/reference/joins-loop.traps.rgb24.ref.pngbin0 -> 4191 bytes
-rw-r--r--test/reference/joins-retrace.base.argb32.ref.pngbin0 -> 4566 bytes
-rw-r--r--test/reference/joins-retrace.base.rgb24.ref.pngbin0 -> 4566 bytes
-rw-r--r--test/reference/joins-retrace.mask.argb32.ref.pngbin0 -> 4997 bytes
-rw-r--r--test/reference/joins-retrace.mask.rgb24.ref.pngbin0 -> 4997 bytes
-rw-r--r--test/reference/joins-retrace.ref.pngbin0 -> 4687 bytes
-rw-r--r--test/reference/joins-retrace.traps.argb32.ref.pngbin0 -> 4566 bytes
-rw-r--r--test/reference/joins-retrace.traps.rgb24.ref.pngbin0 -> 4566 bytes
-rw-r--r--test/reference/joins-star.base.argb32.ref.pngbin0 -> 3542 bytes
-rw-r--r--test/reference/joins-star.base.rgb24.ref.pngbin0 -> 3542 bytes
-rw-r--r--test/reference/joins-star.ref.pngbin0 -> 4015 bytes
-rw-r--r--test/reference/joins-star.traps.argb32.ref.pngbin0 -> 3542 bytes
-rw-r--r--test/reference/joins-star.traps.rgb24.ref.pngbin0 -> 3542 bytes
-rw-r--r--test/reference/joins.base.argb32.ref.pngbin0 -> 5732 bytes
-rw-r--r--test/reference/joins.base.rgb24.ref.pngbin0 -> 5732 bytes
-rw-r--r--test/reference/joins.image16.ref.pngbin0 -> 5858 bytes
-rw-r--r--test/reference/joins.mask.argb32.ref.pngbin0 -> 6970 bytes
-rw-r--r--test/reference/joins.mask.rgb24.ref.pngbin0 -> 6970 bytes
-rw-r--r--test/reference/joins.ps.ref.pngbin0 -> 4230 bytes
-rw-r--r--test/reference/joins.quartz.ref.pngbin0 -> 5833 bytes
-rw-r--r--test/reference/joins.ref.pngbin0 -> 7153 bytes
-rw-r--r--test/reference/joins.traps.argb32.ref.pngbin0 -> 5732 bytes
-rw-r--r--test/reference/joins.traps.rgb24.ref.pngbin0 -> 5732 bytes
-rw-r--r--test/reference/large-clip.base.argb32.ref.pngbin0 -> 305 bytes
-rw-r--r--test/reference/large-clip.base.rgb24.ref.pngbin0 -> 305 bytes
-rw-r--r--test/reference/large-clip.ref.pngbin0 -> 350 bytes
-rw-r--r--test/reference/large-font.base.argb32.ref.pngbin0 -> 6117 bytes
-rw-r--r--test/reference/large-font.base.rgb24.ref.pngbin0 -> 6117 bytes
-rw-r--r--test/reference/large-font.image16.ref.pngbin0 -> 5713 bytes
-rw-r--r--test/reference/large-font.ref.pngbin0 -> 6936 bytes
-rw-r--r--test/reference/large-source-roi.base.argb32.ref.pngbin0 -> 93 bytes
-rw-r--r--test/reference/large-source-roi.base.rgb24.ref.pngbin0 -> 93 bytes
-rw-r--r--test/reference/large-source-roi.ref.pngbin0 -> 112 bytes
-rw-r--r--test/reference/large-source.base.argb32.ref.pngbin0 -> 112 bytes
-rw-r--r--test/reference/large-source.base.rgb24.ref.pngbin0 -> 112 bytes
-rw-r--r--test/reference/large-source.ref.pngbin0 -> 137 bytes
-rw-r--r--test/reference/large-twin-antialias-mixed.base.argb32.ref.pngbin0 -> 16630 bytes
-rw-r--r--test/reference/large-twin-antialias-mixed.base.rgb24.ref.pngbin0 -> 16630 bytes
-rw-r--r--test/reference/large-twin-antialias-mixed.image16.ref.pngbin0 -> 14398 bytes
-rw-r--r--test/reference/large-twin-antialias-mixed.ref.pngbin0 -> 16494 bytes
-rw-r--r--test/reference/large-twin-antialias-mixed.traps.argb32.ref.pngbin0 -> 16630 bytes
-rw-r--r--test/reference/large-twin-antialias-mixed.traps.rgb24.ref.pngbin0 -> 16630 bytes
-rw-r--r--test/reference/leaky-dash.base.argb32.ref.pngbin0 -> 197 bytes
-rw-r--r--test/reference/leaky-dash.base.rgb24.ref.pngbin0 -> 197 bytes
-rw-r--r--test/reference/leaky-dash.ps2.argb32.ref.pngbin0 -> 286 bytes
-rw-r--r--test/reference/leaky-dash.ps2.rgb24.ref.pngbin0 -> 284 bytes
-rw-r--r--test/reference/leaky-dash.ps3.argb32.ref.pngbin0 -> 286 bytes
-rw-r--r--test/reference/leaky-dash.ps3.rgb24.ref.pngbin0 -> 284 bytes
-rw-r--r--test/reference/leaky-dash.quartz.ref.pngbin0 -> 195 bytes
-rw-r--r--test/reference/leaky-dash.ref.pngbin0 -> 243 bytes
-rw-r--r--test/reference/leaky-dashed-rectangle.base.argb32.ref.pngbin0 -> 345 bytes
-rw-r--r--test/reference/leaky-dashed-rectangle.base.rgb24.ref.pngbin0 -> 345 bytes
-rw-r--r--test/reference/leaky-dashed-rectangle.image16.ref.pngbin0 -> 367 bytes
-rw-r--r--test/reference/leaky-dashed-rectangle.pdf.ref.pngbin0 -> 377 bytes
-rw-r--r--test/reference/leaky-dashed-rectangle.ps.ref.pngbin0 -> 358 bytes
-rw-r--r--test/reference/leaky-dashed-rectangle.quartz.ref.pngbin0 -> 339 bytes
-rw-r--r--test/reference/leaky-dashed-rectangle.ref.pngbin0 -> 357 bytes
-rw-r--r--test/reference/leaky-dashed-rectangle.traps.argb32.ref.pngbin0 -> 345 bytes
-rw-r--r--test/reference/leaky-dashed-rectangle.traps.rgb24.ref.pngbin0 -> 345 bytes
-rw-r--r--test/reference/leaky-dashed-stroke.base.argb32.ref.pngbin0 -> 9303 bytes
-rw-r--r--test/reference/leaky-dashed-stroke.base.rgb24.ref.pngbin0 -> 9303 bytes
-rw-r--r--test/reference/leaky-dashed-stroke.image16.ref.pngbin0 -> 8089 bytes
-rw-r--r--test/reference/leaky-dashed-stroke.ps.ref.pngbin0 -> 5293 bytes
-rw-r--r--test/reference/leaky-dashed-stroke.quartz.ref.pngbin0 -> 9229 bytes
-rw-r--r--test/reference/leaky-dashed-stroke.ref.pngbin0 -> 9286 bytes
-rw-r--r--test/reference/leaky-dashed-stroke.traps.argb32.ref.pngbin0 -> 9303 bytes
-rw-r--r--test/reference/leaky-dashed-stroke.traps.rgb24.ref.pngbin0 -> 9303 bytes
-rw-r--r--test/reference/leaky-polygon.base.argb32.ref.pngbin0 -> 325 bytes
-rw-r--r--test/reference/leaky-polygon.base.rgb24.ref.pngbin0 -> 325 bytes
-rw-r--r--test/reference/leaky-polygon.image16.ref.pngbin0 -> 329 bytes
-rw-r--r--test/reference/leaky-polygon.ps.ref.pngbin0 -> 289 bytes
-rw-r--r--test/reference/leaky-polygon.ref.pngbin0 -> 337 bytes
-rw-r--r--test/reference/leaky-polygon.traps.argb32.ref.pngbin0 -> 325 bytes
-rw-r--r--test/reference/leaky-polygon.traps.rgb24.ref.pngbin0 -> 325 bytes
-rw-r--r--test/reference/line-width-large-overlap-dashed.base.argb32.ref.pngbin0 -> 338 bytes
-rw-r--r--test/reference/line-width-large-overlap-dashed.base.rgb24.ref.pngbin0 -> 338 bytes
-rw-r--r--test/reference/line-width-large-overlap-dashed.mask.argb32.ref.pngbin0 -> 343 bytes
-rw-r--r--test/reference/line-width-large-overlap-dashed.mask.rgb24.ref.pngbin0 -> 343 bytes
-rw-r--r--test/reference/line-width-large-overlap-dashed.ref.pngbin0 -> 340 bytes
-rw-r--r--test/reference/line-width-large-overlap-dashed.traps.argb32.ref.pngbin0 -> 340 bytes
-rw-r--r--test/reference/line-width-large-overlap-dashed.traps.rgb24.ref.pngbin0 -> 340 bytes
-rw-r--r--test/reference/line-width-large-overlap-flipped.base.argb32.ref.pngbin0 -> 305 bytes
-rw-r--r--test/reference/line-width-large-overlap-flipped.base.rgb24.ref.pngbin0 -> 305 bytes
-rw-r--r--test/reference/line-width-large-overlap-flipped.ref.pngbin0 -> 305 bytes
-rw-r--r--test/reference/line-width-large-overlap-flopped.base.argb32.ref.pngbin0 -> 305 bytes
-rw-r--r--test/reference/line-width-large-overlap-flopped.base.rgb24.ref.pngbin0 -> 305 bytes
-rw-r--r--test/reference/line-width-large-overlap-flopped.ref.pngbin0 -> 305 bytes
-rw-r--r--test/reference/line-width-large-overlap-offset.base.argb32.ref.pngbin0 -> 305 bytes
-rw-r--r--test/reference/line-width-large-overlap-offset.base.rgb24.ref.pngbin0 -> 305 bytes
-rw-r--r--test/reference/line-width-large-overlap-offset.ref.pngbin0 -> 305 bytes
-rw-r--r--test/reference/line-width-large-overlap-rotated.base.argb32.ref.pngbin0 -> 404 bytes
-rw-r--r--test/reference/line-width-large-overlap-rotated.base.rgb24.ref.pngbin0 -> 404 bytes
-rw-r--r--test/reference/line-width-large-overlap-rotated.ref.pngbin0 -> 415 bytes
-rw-r--r--test/reference/line-width-large-overlap-rotated.traps.ref.pngbin0 -> 404 bytes
-rw-r--r--test/reference/line-width-large-overlap.base.argb32.ref.pngbin0 -> 305 bytes
-rw-r--r--test/reference/line-width-large-overlap.base.rgb24.ref.pngbin0 -> 305 bytes
-rw-r--r--test/reference/line-width-large-overlap.ref.pngbin0 -> 305 bytes
-rw-r--r--test/reference/line-width-overlap-dashed.base.argb32.ref.pngbin0 -> 397 bytes
-rw-r--r--test/reference/line-width-overlap-dashed.base.rgb24.ref.pngbin0 -> 397 bytes
-rw-r--r--test/reference/line-width-overlap-dashed.mask.argb32.ref.pngbin0 -> 401 bytes
-rw-r--r--test/reference/line-width-overlap-dashed.mask.rgb24.ref.pngbin0 -> 401 bytes
-rw-r--r--test/reference/line-width-overlap-dashed.ref.pngbin0 -> 407 bytes
-rw-r--r--test/reference/line-width-overlap-dashed.traps.argb32.ref.pngbin0 -> 407 bytes
-rw-r--r--test/reference/line-width-overlap-dashed.traps.rgb24.ref.pngbin0 -> 407 bytes
-rw-r--r--test/reference/line-width-overlap-flipped.base.argb32.ref.pngbin0 -> 324 bytes
-rw-r--r--test/reference/line-width-overlap-flipped.base.rgb24.ref.pngbin0 -> 324 bytes
-rw-r--r--test/reference/line-width-overlap-flipped.ref.pngbin0 -> 296 bytes
-rw-r--r--test/reference/line-width-overlap-flopped.base.argb32.ref.pngbin0 -> 324 bytes
-rw-r--r--test/reference/line-width-overlap-flopped.base.rgb24.ref.pngbin0 -> 324 bytes
-rw-r--r--test/reference/line-width-overlap-flopped.ref.pngbin0 -> 296 bytes
-rw-r--r--test/reference/line-width-overlap-offset.base.argb32.ref.pngbin0 -> 365 bytes
-rw-r--r--test/reference/line-width-overlap-offset.base.rgb24.ref.pngbin0 -> 365 bytes
-rw-r--r--test/reference/line-width-overlap-offset.ref.pngbin0 -> 348 bytes
-rw-r--r--test/reference/line-width-overlap-offset.traps.ref.pngbin0 -> 365 bytes
-rw-r--r--test/reference/line-width-overlap-rotated.base.argb32.ref.pngbin0 -> 628 bytes
-rw-r--r--test/reference/line-width-overlap-rotated.base.rgb24.ref.pngbin0 -> 628 bytes
-rw-r--r--test/reference/line-width-overlap-rotated.ref.pngbin0 -> 688 bytes
-rw-r--r--test/reference/line-width-overlap-rotated.traps.argb32.ref.pngbin0 -> 628 bytes
-rw-r--r--test/reference/line-width-overlap-rotated.traps.rgb24.ref.pngbin0 -> 628 bytes
-rw-r--r--test/reference/line-width-overlap.base.argb32.ref.pngbin0 -> 324 bytes
-rw-r--r--test/reference/line-width-overlap.base.rgb24.ref.pngbin0 -> 324 bytes
-rw-r--r--test/reference/line-width-overlap.ref.pngbin0 -> 324 bytes
-rw-r--r--test/reference/line-width-scale.base.argb32.ref.pngbin0 -> 5692 bytes
-rw-r--r--test/reference/line-width-scale.base.rgb24.ref.pngbin0 -> 5692 bytes
-rw-r--r--test/reference/line-width-scale.image16.ref.pngbin0 -> 4721 bytes
-rw-r--r--test/reference/line-width-scale.ps2.ref.pngbin0 -> 3431 bytes
-rw-r--r--test/reference/line-width-scale.ps3.ref.pngbin0 -> 3431 bytes
-rw-r--r--test/reference/line-width-scale.quartz.ref.pngbin0 -> 5623 bytes
-rw-r--r--test/reference/line-width-scale.ref.pngbin0 -> 5721 bytes
-rw-r--r--test/reference/line-width-scale.traps.argb32.ref.pngbin0 -> 5692 bytes
-rw-r--r--test/reference/line-width-scale.traps.rgb24.ref.pngbin0 -> 5692 bytes
-rw-r--r--test/reference/line-width-tolerance.base.argb32.ref.pngbin0 -> 163 bytes
-rw-r--r--test/reference/line-width-tolerance.base.rgb24.ref.pngbin0 -> 163 bytes
-rw-r--r--test/reference/line-width-tolerance.ref.pngbin0 -> 168 bytes
-rw-r--r--test/reference/line-width-tolerance.traps.argb32.ref.pngbin0 -> 163 bytes
-rw-r--r--test/reference/line-width-tolerance.traps.rgb24.ref.pngbin0 -> 163 bytes
-rw-r--r--test/reference/line-width.base.argb32.ref.pngbin0 -> 180 bytes
-rw-r--r--test/reference/line-width.base.rgb24.ref.pngbin0 -> 180 bytes
-rw-r--r--test/reference/line-width.ref.pngbin0 -> 178 bytes
-rw-r--r--test/reference/line-width.traps.argb32.ref.pngbin0 -> 180 bytes
-rw-r--r--test/reference/line-width.traps.rgb24.ref.pngbin0 -> 180 bytes
-rw-r--r--test/reference/linear-gradient-extend.base.argb32.ref.pngbin0 -> 371 bytes
-rw-r--r--test/reference/linear-gradient-extend.base.rgb24.ref.pngbin0 -> 371 bytes
-rw-r--r--test/reference/linear-gradient-extend.ref.pngbin0 -> 371 bytes
-rw-r--r--test/reference/linear-gradient-large.base.argb32.ref.pngbin0 -> 4076 bytes
-rw-r--r--test/reference/linear-gradient-large.base.rgb24.ref.pngbin0 -> 4076 bytes
-rw-r--r--test/reference/linear-gradient-large.quartz.ref.pngbin0 -> 4074 bytes
-rw-r--r--test/reference/linear-gradient-large.ref.pngbin0 -> 4076 bytes
-rw-r--r--test/reference/linear-gradient-one-stop.base.argb32.ref.pngbin0 -> 225 bytes
-rw-r--r--test/reference/linear-gradient-one-stop.base.rgb24.ref.pngbin0 -> 174 bytes
-rw-r--r--test/reference/linear-gradient-one-stop.ref.pngbin0 -> 225 bytes
-rw-r--r--test/reference/linear-gradient-reflect.base.argb32.ref.pngbin0 -> 185 bytes
-rw-r--r--test/reference/linear-gradient-reflect.base.rgb24.ref.pngbin0 -> 185 bytes
-rw-r--r--test/reference/linear-gradient-reflect.image16.ref.pngbin0 -> 190 bytes
-rw-r--r--test/reference/linear-gradient-reflect.pdf.argb32.ref.pngbin0 -> 248 bytes
-rw-r--r--test/reference/linear-gradient-reflect.pdf.rgb24.ref.pngbin0 -> 248 bytes
-rw-r--r--test/reference/linear-gradient-reflect.ps3.ref.pngbin0 -> 314 bytes
-rw-r--r--test/reference/linear-gradient-reflect.quartz.ref.pngbin0 -> 780 bytes
-rw-r--r--test/reference/linear-gradient-reflect.ref.pngbin0 -> 185 bytes
-rw-r--r--test/reference/linear-gradient-subset.base.argb32.ref.pngbin0 -> 773 bytes
-rw-r--r--test/reference/linear-gradient-subset.base.rgb24.ref.pngbin0 -> 773 bytes
-rw-r--r--test/reference/linear-gradient-subset.image16.ref.pngbin0 -> 791 bytes
-rw-r--r--test/reference/linear-gradient-subset.ps3.ref.pngbin0 -> 619 bytes
-rw-r--r--test/reference/linear-gradient-subset.quartz.ref.pngbin0 -> 852 bytes
-rw-r--r--test/reference/linear-gradient-subset.ref.pngbin0 -> 813 bytes
-rw-r--r--test/reference/linear-gradient-subset.traps.argb32.ref.pngbin0 -> 773 bytes
-rw-r--r--test/reference/linear-gradient-subset.traps.rgb24.ref.pngbin0 -> 773 bytes
-rw-r--r--test/reference/linear-gradient.base.argb32.ref.pngbin0 -> 914 bytes
-rw-r--r--test/reference/linear-gradient.base.rgb24.ref.pngbin0 -> 914 bytes
-rw-r--r--test/reference/linear-gradient.image16.ref.pngbin0 -> 941 bytes
-rw-r--r--test/reference/linear-gradient.ps3.ref.pngbin0 -> 779 bytes
-rw-r--r--test/reference/linear-gradient.quartz.ref.pngbin0 -> 951 bytes
-rw-r--r--test/reference/linear-gradient.ref.pngbin0 -> 959 bytes
-rw-r--r--test/reference/linear-gradient.traps.argb32.ref.pngbin0 -> 914 bytes
-rw-r--r--test/reference/linear-gradient.traps.rgb24.ref.pngbin0 -> 914 bytes
-rw-r--r--test/reference/linear-step-function.base.argb32.ref.pngbin0 -> 118 bytes
-rw-r--r--test/reference/linear-step-function.base.rgb24.ref.pngbin0 -> 118 bytes
-rw-r--r--test/reference/linear-step-function.mask.argb32.ref.pngbin0 -> 118 bytes
-rw-r--r--test/reference/linear-step-function.mask.rgb24.ref.pngbin0 -> 118 bytes
-rw-r--r--test/reference/linear-step-function.traps.argb32.ref.pngbin0 -> 118 bytes
-rw-r--r--test/reference/linear-step-function.traps.rgb24.ref.pngbin0 -> 118 bytes
-rw-r--r--test/reference/linear-step-function.xfail.pngbin0 -> 116 bytes
-rw-r--r--test/reference/linear-uniform.base.argb32.ref.pngbin0 -> 128 bytes
-rw-r--r--test/reference/linear-uniform.base.rgb24.ref.pngbin0 -> 128 bytes
-rw-r--r--test/reference/linear-uniform.image16.ref.pngbin0 -> 131 bytes
-rw-r--r--test/reference/linear-uniform.ref.pngbin0 -> 128 bytes
-rw-r--r--test/reference/long-dashed-lines.base.argb32.ref.pngbin0 -> 2079 bytes
-rw-r--r--test/reference/long-dashed-lines.base.rgb24.ref.pngbin0 -> 2079 bytes
-rw-r--r--test/reference/long-dashed-lines.image16.ref.pngbin0 -> 1974 bytes
-rw-r--r--test/reference/long-dashed-lines.ps2.ref.pngbin0 -> 1329 bytes
-rw-r--r--test/reference/long-dashed-lines.ps3.ref.pngbin0 -> 1329 bytes
-rw-r--r--test/reference/long-dashed-lines.quartz.ref.pngbin0 -> 2068 bytes
-rw-r--r--test/reference/long-dashed-lines.ref.pngbin0 -> 2548 bytes
-rw-r--r--test/reference/long-dashed-lines.traps.argb32.ref.pngbin0 -> 2079 bytes
-rw-r--r--test/reference/long-dashed-lines.traps.rgb24.ref.pngbin0 -> 2079 bytes
-rw-r--r--test/reference/long-lines.base.argb32.ref.pngbin0 -> 201 bytes
-rw-r--r--test/reference/long-lines.base.rgb24.ref.pngbin0 -> 201 bytes
-rw-r--r--test/reference/long-lines.mask.argb32.ref.pngbin0 -> 201 bytes
-rw-r--r--test/reference/long-lines.mask.rgb24.ref.pngbin0 -> 201 bytes
-rw-r--r--test/reference/long-lines.traps.argb32.ref.pngbin0 -> 201 bytes
-rw-r--r--test/reference/long-lines.traps.rgb24.ref.pngbin0 -> 201 bytes
-rw-r--r--test/reference/map-all-to-image.base.argb32.ref.pngbin0 -> 86 bytes
-rw-r--r--test/reference/map-all-to-image.base.rgb24.ref.pngbin0 -> 86 bytes
-rw-r--r--test/reference/map-all-to-image.ref.pngbin0 -> 86 bytes
-rw-r--r--test/reference/map-all-to-xlib-fallback.rgb24.ref.pngbin0 -> 86 bytes
-rw-r--r--test/reference/map-all-to-xlib-window.rgb24.ref.pngbin0 -> 86 bytes
-rw-r--r--test/reference/map-all-to-xlib.ref.pngbin0 -> 86 bytes
-rw-r--r--test/reference/map-bit-to-image.base.argb32.ref.pngbin0 -> 103 bytes
-rw-r--r--test/reference/map-bit-to-image.base.rgb24.ref.pngbin0 -> 103 bytes
-rw-r--r--test/reference/map-bit-to-image.ref.pngbin0 -> 103 bytes
-rw-r--r--test/reference/map-bit-to-xlib-fallback.rgb24.ref.pngbin0 -> 103 bytes
-rw-r--r--test/reference/map-bit-to-xlib-window.rgb24.ref.pngbin0 -> 103 bytes
-rw-r--r--test/reference/map-bit-to-xlib.ref.pngbin0 -> 103 bytes
-rw-r--r--test/reference/map-to-image-fill.base.argb32.ref.pngbin0 -> 103 bytes
-rw-r--r--test/reference/map-to-image-fill.base.rgb24.ref.pngbin0 -> 103 bytes
-rw-r--r--test/reference/map-to-image-fill.ref.pngbin0 -> 103 bytes
-rw-r--r--test/reference/mask-alpha.argb32.ref.pngbin0 -> 629 bytes
-rw-r--r--test/reference/mask-alpha.base.argb32.ref.pngbin0 -> 627 bytes
-rw-r--r--test/reference/mask-alpha.base.rgb24.ref.pngbin0 -> 588 bytes
-rw-r--r--test/reference/mask-alpha.image16.ref.pngbin0 -> 560 bytes
-rw-r--r--test/reference/mask-alpha.ps.ref.pngbin0 -> 594 bytes
-rw-r--r--test/reference/mask-alpha.quartz.argb32.ref.pngbin0 -> 622 bytes
-rw-r--r--test/reference/mask-alpha.rgb24.ref.pngbin0 -> 595 bytes
-rw-r--r--test/reference/mask-alpha.svg.rgb24.xfail.pngbin0 -> 585 bytes
-rw-r--r--test/reference/mask-alpha.traps.argb32.ref.pngbin0 -> 627 bytes
-rw-r--r--test/reference/mask-alpha.traps.rgb24.ref.pngbin0 -> 588 bytes
-rw-r--r--test/reference/mask-ctm.base.argb32.ref.pngbin0 -> 110 bytes
-rw-r--r--test/reference/mask-ctm.base.rgb24.ref.pngbin0 -> 105 bytes
-rw-r--r--test/reference/mask-ctm.ref.pngbin0 -> 129 bytes
-rw-r--r--test/reference/mask-glyphs.gl.ref.pngbin0 -> 1188669 bytes
-rw-r--r--test/reference/mask-glyphs.image16.ref.pngbin0 -> 1053144 bytes
-rw-r--r--test/reference/mask-glyphs.pdf.ref.pngbin0 -> 1187713 bytes
-rw-r--r--test/reference/mask-glyphs.ref.pngbin0 -> 1189351 bytes
-rw-r--r--test/reference/mask-glyphs.svg.ref.pngbin0 -> 1211144 bytes
-rw-r--r--test/reference/mask-surface-ctm.base.argb32.ref.pngbin0 -> 110 bytes
-rw-r--r--test/reference/mask-surface-ctm.base.rgb24.ref.pngbin0 -> 105 bytes
-rw-r--r--test/reference/mask-surface-ctm.ref.pngbin0 -> 129 bytes
-rw-r--r--test/reference/mask-transformed-image.base.argb32.ref.pngbin0 -> 3812 bytes
-rw-r--r--test/reference/mask-transformed-image.base.rgb24.ref.pngbin0 -> 3812 bytes
-rw-r--r--test/reference/mask-transformed-image.image16.ref.pngbin0 -> 2748 bytes
-rw-r--r--test/reference/mask-transformed-image.pdf.ref.pngbin0 -> 3528 bytes
-rw-r--r--test/reference/mask-transformed-image.quartz.ref.pngbin0 -> 3909 bytes
-rw-r--r--test/reference/mask-transformed-image.ref.pngbin0 -> 3812 bytes
-rw-r--r--test/reference/mask-transformed-similar.base.argb32.ref.pngbin0 -> 3812 bytes
-rw-r--r--test/reference/mask-transformed-similar.base.rgb24.ref.pngbin0 -> 3812 bytes
-rw-r--r--test/reference/mask-transformed-similar.image16.ref.pngbin0 -> 2748 bytes
-rw-r--r--test/reference/mask-transformed-similar.pdf.ref.pngbin0 -> 4213 bytes
-rw-r--r--test/reference/mask-transformed-similar.quartz.ref.pngbin0 -> 3909 bytes
-rw-r--r--test/reference/mask-transformed-similar.recording.ref.pngbin0 -> 3528 bytes
-rw-r--r--test/reference/mask-transformed-similar.ref.pngbin0 -> 3812 bytes
-rw-r--r--test/reference/mask-transformed-similar.svg.ref.pngbin0 -> 3365 bytes
-rw-r--r--test/reference/mask-transformed-xlib-fallback.rgb24.ref.pngbin0 -> 3809 bytes
-rw-r--r--test/reference/mask-transformed-xlib-window.rgb24.ref.pngbin0 -> 3809 bytes
-rw-r--r--test/reference/mask-transformed-xlib.ref.pngbin0 -> 3809 bytes
-rw-r--r--test/reference/mask.argb32.ref.pngbin0 -> 8530 bytes
-rw-r--r--test/reference/mask.base.argb32.ref.pngbin0 -> 8439 bytes
-rw-r--r--test/reference/mask.base.rgb24.ref.pngbin0 -> 7044 bytes
-rw-r--r--test/reference/mask.image16.ref.pngbin0 -> 5533 bytes
-rw-r--r--test/reference/mask.pdf.argb32.ref.pngbin0 -> 7554 bytes
-rw-r--r--test/reference/mask.pdf.rgb24.ref.pngbin0 -> 7043 bytes
-rw-r--r--test/reference/mask.quartz.argb32.ref.pngbin0 -> 10669 bytes
-rw-r--r--test/reference/mask.quartz.rgb24.ref.pngbin0 -> 8354 bytes
-rw-r--r--test/reference/mask.rgb24.ref.pngbin0 -> 7160 bytes
-rw-r--r--test/reference/mask.svg.argb32.xfail.pngbin0 -> 8641 bytes
-rw-r--r--test/reference/mask.svg.rgb24.xfail.pngbin0 -> 7199 bytes
-rw-r--r--test/reference/mask.traps.argb32.ref.pngbin0 -> 8451 bytes
-rw-r--r--test/reference/mask.traps.rgb24.ref.pngbin0 -> 7058 bytes
-rw-r--r--test/reference/mesh-pattern-accuracy.base.argb32.ref.pngbin0 -> 8086 bytes
-rw-r--r--test/reference/mesh-pattern-accuracy.base.rgb24.ref.pngbin0 -> 8086 bytes
-rw-r--r--test/reference/mesh-pattern-accuracy.image16.ref.pngbin0 -> 7209 bytes
-rw-r--r--test/reference/mesh-pattern-accuracy.ref.pngbin0 -> 8086 bytes
-rw-r--r--test/reference/mesh-pattern-conical.base.argb32.ref.pngbin0 -> 8655 bytes
-rw-r--r--test/reference/mesh-pattern-conical.base.rgb24.ref.pngbin0 -> 8655 bytes
-rw-r--r--test/reference/mesh-pattern-conical.image16.ref.pngbin0 -> 6141 bytes
-rw-r--r--test/reference/mesh-pattern-conical.ref.pngbin0 -> 8655 bytes
-rw-r--r--test/reference/mesh-pattern-control-points.base.argb32.ref.pngbin0 -> 10665 bytes
-rw-r--r--test/reference/mesh-pattern-control-points.base.rgb24.ref.pngbin0 -> 10665 bytes
-rw-r--r--test/reference/mesh-pattern-control-points.image16.ref.pngbin0 -> 7178 bytes
-rw-r--r--test/reference/mesh-pattern-control-points.ref.pngbin0 -> 10665 bytes
-rw-r--r--test/reference/mesh-pattern-fold.base.argb32.ref.pngbin0 -> 52980 bytes
-rw-r--r--test/reference/mesh-pattern-fold.base.rgb24.ref.pngbin0 -> 52980 bytes
-rw-r--r--test/reference/mesh-pattern-fold.image16.ref.pngbin0 -> 22913 bytes
-rw-r--r--test/reference/mesh-pattern-fold.ref.pngbin0 -> 52980 bytes
-rw-r--r--test/reference/mesh-pattern-overlap.base.argb32.ref.pngbin0 -> 9129 bytes
-rw-r--r--test/reference/mesh-pattern-overlap.base.rgb24.ref.pngbin0 -> 9129 bytes
-rw-r--r--test/reference/mesh-pattern-overlap.image16.ref.pngbin0 -> 5933 bytes
-rw-r--r--test/reference/mesh-pattern-overlap.ref.pngbin0 -> 9129 bytes
-rw-r--r--test/reference/mesh-pattern-transformed.base.argb32.ref.pngbin0 -> 14463 bytes
-rw-r--r--test/reference/mesh-pattern-transformed.base.rgb24.ref.pngbin0 -> 14463 bytes
-rw-r--r--test/reference/mesh-pattern-transformed.image16.ref.pngbin0 -> 9778 bytes
-rw-r--r--test/reference/mesh-pattern-transformed.ref.pngbin0 -> 14463 bytes
-rw-r--r--test/reference/mesh-pattern.base.argb32.ref.pngbin0 -> 19566 bytes
-rw-r--r--test/reference/mesh-pattern.base.rgb24.ref.pngbin0 -> 19566 bytes
-rw-r--r--test/reference/mesh-pattern.image16.ref.pngbin0 -> 12199 bytes
-rw-r--r--test/reference/mesh-pattern.ref.pngbin0 -> 19566 bytes
-rw-r--r--test/reference/mime-data.base.argb32.ref.pngbin0 -> 243 bytes
-rw-r--r--test/reference/mime-data.base.rgb24.ref.pngbin0 -> 243 bytes
-rw-r--r--test/reference/mime-data.pdf.ref.pngbin0 -> 7563 bytes
-rw-r--r--test/reference/mime-data.ps.ref.pngbin0 -> 4705 bytes
-rw-r--r--test/reference/mime-data.ref.pngbin0 -> 243 bytes
-rw-r--r--test/reference/mime-data.script.ref.pngbin0 -> 2130 bytes
-rw-r--r--test/reference/mime-data.svg.ref.pngbin0 -> 6437 bytes
-rw-r--r--test/reference/miter-precision.base.argb32.ref.pngbin0 -> 823 bytes
-rw-r--r--test/reference/miter-precision.base.rgb24.ref.pngbin0 -> 823 bytes
-rw-r--r--test/reference/miter-precision.ps2.ref.pngbin0 -> 865 bytes
-rw-r--r--test/reference/miter-precision.ps3.ref.pngbin0 -> 865 bytes
-rw-r--r--test/reference/miter-precision.ref.pngbin0 -> 824 bytes
-rw-r--r--test/reference/miter-precision.traps.argb32.ref.pngbin0 -> 823 bytes
-rw-r--r--test/reference/miter-precision.traps.rgb24.ref.pngbin0 -> 823 bytes
-rw-r--r--test/reference/move-to-show-surface.base.argb32.ref.pngbin0 -> 96 bytes
-rw-r--r--test/reference/move-to-show-surface.base.rgb24.ref.pngbin0 -> 96 bytes
-rw-r--r--test/reference/move-to-show-surface.ref.pngbin0 -> 100 bytes
-rw-r--r--test/reference/negative-stride-image.base.argb32.ref.pngbin0 -> 81121 bytes
-rw-r--r--test/reference/negative-stride-image.base.rgb24.ref.pngbin0 -> 81121 bytes
-rw-r--r--test/reference/negative-stride-image.image16.ref.pngbin0 -> 61197 bytes
-rw-r--r--test/reference/negative-stride-image.ps.ref.pngbin0 -> 77159 bytes
-rw-r--r--test/reference/negative-stride-image.ref.pngbin0 -> 81121 bytes
-rw-r--r--test/reference/new-sub-path.base.argb32.ref.pngbin0 -> 415 bytes
-rw-r--r--test/reference/new-sub-path.base.rgb24.ref.pngbin0 -> 378 bytes
-rw-r--r--test/reference/new-sub-path.pdf.argb32.ref.pngbin0 -> 512 bytes
-rw-r--r--test/reference/new-sub-path.ps2.argb32.ref.pngbin0 -> 398 bytes
-rw-r--r--test/reference/new-sub-path.ps2.rgb24.ref.pngbin0 -> 423 bytes
-rw-r--r--test/reference/new-sub-path.ps3.argb32.ref.pngbin0 -> 398 bytes
-rw-r--r--test/reference/new-sub-path.ps3.rgb24.ref.pngbin0 -> 423 bytes
-rw-r--r--test/reference/new-sub-path.quartz.ref.pngbin0 -> 370 bytes
-rw-r--r--test/reference/new-sub-path.ref.pngbin0 -> 408 bytes
-rw-r--r--test/reference/new-sub-path.traps.argb32.ref.pngbin0 -> 415 bytes
-rw-r--r--test/reference/new-sub-path.traps.rgb24.ref.pngbin0 -> 378 bytes
-rw-r--r--test/reference/nil-surface.base.argb32.ref.pngbin0 -> 88 bytes
-rw-r--r--test/reference/nil-surface.base.rgb24.ref.pngbin0 -> 87 bytes
-rw-r--r--test/reference/nil-surface.ref.pngbin0 -> 107 bytes
-rw-r--r--test/reference/operator-alpha-alpha.base.argb32.ref.pngbin0 -> 3402 bytes
-rw-r--r--test/reference/operator-alpha-alpha.base.rgb24.ref.pngbin0 -> 3402 bytes
-rw-r--r--test/reference/operator-alpha-alpha.image16.ref.pngbin0 -> 4140 bytes
-rw-r--r--test/reference/operator-alpha-alpha.pdf.xfail.pngbin0 -> 3749 bytes
-rw-r--r--test/reference/operator-alpha-alpha.ps.xfail.pngbin0 -> 3429 bytes
-rw-r--r--test/reference/operator-alpha-alpha.ref.pngbin0 -> 3441 bytes
-rw-r--r--test/reference/operator-alpha-alpha.svg.xfail.pngbin0 -> 838 bytes
-rw-r--r--test/reference/operator-alpha-alpha.traps.argb32.ref.pngbin0 -> 3402 bytes
-rw-r--r--test/reference/operator-alpha-alpha.traps.rgb24.ref.pngbin0 -> 3402 bytes
-rw-r--r--test/reference/operator-alpha.argb32.ref.pngbin0 -> 280 bytes
-rw-r--r--test/reference/operator-alpha.base.argb32.ref.pngbin0 -> 280 bytes
-rw-r--r--test/reference/operator-alpha.base.rgb24.ref.pngbin0 -> 205 bytes
-rw-r--r--test/reference/operator-alpha.rgb24.ref.pngbin0 -> 205 bytes
-rw-r--r--test/reference/operator-alpha.svg12.argb32.xfail.pngbin0 -> 274 bytes
-rw-r--r--test/reference/operator-alpha.svg12.rgb24.xfail.pngbin0 -> 248 bytes
-rw-r--r--test/reference/operator-clear.argb32.ref.pngbin0 -> 1061 bytes
-rw-r--r--test/reference/operator-clear.base.argb32.ref.pngbin0 -> 1071 bytes
-rw-r--r--test/reference/operator-clear.base.rgb24.ref.pngbin0 -> 950 bytes
-rw-r--r--test/reference/operator-clear.mask.rgb24.ref.pngbin0 -> 947 bytes
-rw-r--r--test/reference/operator-clear.ps2.argb32.ref.pngbin0 -> 1156 bytes
-rw-r--r--test/reference/operator-clear.ps3.argb32.ref.pngbin0 -> 1156 bytes
-rw-r--r--test/reference/operator-clear.quartz.argb32.ref.pngbin0 -> 1228 bytes
-rw-r--r--test/reference/operator-clear.quartz.rgb24.ref.pngbin0 -> 1096 bytes
-rw-r--r--test/reference/operator-clear.rgb24.ref.pngbin0 -> 939 bytes
-rw-r--r--test/reference/operator-clear.svg12.argb32.xfail.pngbin0 -> 405 bytes
-rw-r--r--test/reference/operator-clear.svg12.rgb24.xfail.pngbin0 -> 535 bytes
-rw-r--r--test/reference/operator-clear.traps.argb32.ref.pngbin0 -> 1071 bytes
-rw-r--r--test/reference/operator-clear.traps.rgb24.ref.pngbin0 -> 950 bytes
-rw-r--r--test/reference/operator-source.argb32.ref.pngbin0 -> 5620 bytes
-rw-r--r--test/reference/operator-source.base.argb32.ref.pngbin0 -> 5625 bytes
-rw-r--r--test/reference/operator-source.base.rgb24.ref.pngbin0 -> 3979 bytes
-rw-r--r--test/reference/operator-source.image16.ref.pngbin0 -> 3959 bytes
-rw-r--r--test/reference/operator-source.mask.argb32.ref.pngbin0 -> 5612 bytes
-rw-r--r--test/reference/operator-source.mask.rgb24.ref.pngbin0 -> 3975 bytes
-rw-r--r--test/reference/operator-source.rgb24.ref.pngbin0 -> 4006 bytes
-rw-r--r--test/reference/operator-source.traps.argb32.ref.pngbin0 -> 5625 bytes
-rw-r--r--test/reference/operator-source.traps.rgb24.ref.pngbin0 -> 3979 bytes
-rw-r--r--test/reference/operator-source.xlib-fallback.ref.pngbin0 -> 4444 bytes
-rw-r--r--test/reference/operator.argb32.ref.pngbin0 -> 238 bytes
-rw-r--r--test/reference/operator.base.argb32.ref.pngbin0 -> 238 bytes
-rw-r--r--test/reference/operator.base.rgb24.ref.pngbin0 -> 189 bytes
-rw-r--r--test/reference/operator.rgb24.ref.pngbin0 -> 189 bytes
-rw-r--r--test/reference/operator.svg12.argb32.xfail.pngbin0 -> 238 bytes
-rw-r--r--test/reference/operator.svg12.rgb24.xfail.pngbin0 -> 242 bytes
-rw-r--r--test/reference/outline-tolerance.ref.pngbin0 -> 205 bytes
-rw-r--r--test/reference/over-above-source.argb32.ref.pngbin0 -> 533 bytes
-rw-r--r--test/reference/over-above-source.base.argb32.ref.pngbin0 -> 533 bytes
-rw-r--r--test/reference/over-above-source.base.rgb24.ref.pngbin0 -> 450 bytes
-rw-r--r--test/reference/over-above-source.ps2.argb32.ref.pngbin0 -> 558 bytes
-rw-r--r--test/reference/over-above-source.ps3.argb32.ref.pngbin0 -> 558 bytes
-rw-r--r--test/reference/over-above-source.quartz.argb32.ref.pngbin0 -> 511 bytes
-rw-r--r--test/reference/over-above-source.quartz.rgb24.ref.pngbin0 -> 437 bytes
-rw-r--r--test/reference/over-above-source.rgb24.ref.pngbin0 -> 452 bytes
-rw-r--r--test/reference/over-above-source.svg12.rgb24.xfail.pngbin0 -> 563 bytes
-rw-r--r--test/reference/over-above-source.traps.argb32.ref.pngbin0 -> 533 bytes
-rw-r--r--test/reference/over-above-source.traps.rgb24.ref.pngbin0 -> 450 bytes
-rw-r--r--test/reference/over-around-source.argb32.ref.pngbin0 -> 604 bytes
-rw-r--r--test/reference/over-around-source.base.argb32.ref.pngbin0 -> 610 bytes
-rw-r--r--test/reference/over-around-source.base.rgb24.ref.pngbin0 -> 492 bytes
-rw-r--r--test/reference/over-around-source.image16.ref.pngbin0 -> 491 bytes
-rw-r--r--test/reference/over-around-source.pdf.argb32.ref.pngbin0 -> 576 bytes
-rw-r--r--test/reference/over-around-source.ps2.argb32.ref.pngbin0 -> 508 bytes
-rw-r--r--test/reference/over-around-source.ps2.rgb24.ref.pngbin0 -> 538 bytes
-rw-r--r--test/reference/over-around-source.ps3.argb32.ref.pngbin0 -> 508 bytes
-rw-r--r--test/reference/over-around-source.ps3.rgb24.ref.pngbin0 -> 538 bytes
-rw-r--r--test/reference/over-around-source.quartz.argb32.ref.pngbin0 -> 593 bytes
-rw-r--r--test/reference/over-around-source.rgb24.ref.pngbin0 -> 489 bytes
-rw-r--r--test/reference/over-around-source.svg12.argb32.xfail.pngbin0 -> 559 bytes
-rw-r--r--test/reference/over-around-source.svg12.rgb24.xfail.pngbin0 -> 559 bytes
-rw-r--r--test/reference/over-around-source.traps.argb32.ref.pngbin0 -> 610 bytes
-rw-r--r--test/reference/over-around-source.traps.rgb24.ref.pngbin0 -> 492 bytes
-rw-r--r--test/reference/over-below-source.argb32.ref.pngbin0 -> 440 bytes
-rw-r--r--test/reference/over-below-source.base.argb32.ref.pngbin0 -> 436 bytes
-rw-r--r--test/reference/over-below-source.base.rgb24.ref.pngbin0 -> 378 bytes
-rw-r--r--test/reference/over-below-source.pdf.argb32.ref.pngbin0 -> 464 bytes
-rw-r--r--test/reference/over-below-source.ps2.argb32.ref.pngbin0 -> 368 bytes
-rw-r--r--test/reference/over-below-source.ps2.rgb24.ref.pngbin0 -> 362 bytes
-rw-r--r--test/reference/over-below-source.ps3.argb32.ref.pngbin0 -> 368 bytes
-rw-r--r--test/reference/over-below-source.ps3.rgb24.ref.pngbin0 -> 362 bytes
-rw-r--r--test/reference/over-below-source.rgb24.ref.pngbin0 -> 376 bytes
-rw-r--r--test/reference/over-below-source.svg12.argb32.xfail.pngbin0 -> 224 bytes
-rw-r--r--test/reference/over-below-source.svg12.rgb24.xfail.pngbin0 -> 224 bytes
-rw-r--r--test/reference/over-below-source.traps.argb32.ref.pngbin0 -> 436 bytes
-rw-r--r--test/reference/over-below-source.traps.rgb24.ref.pngbin0 -> 378 bytes
-rw-r--r--test/reference/over-between-source.argb32.ref.pngbin0 -> 572 bytes
-rw-r--r--test/reference/over-between-source.base.argb32.ref.pngbin0 -> 578 bytes
-rw-r--r--test/reference/over-between-source.base.rgb24.ref.pngbin0 -> 461 bytes
-rw-r--r--test/reference/over-between-source.ps2.argb32.ref.pngbin0 -> 551 bytes
-rw-r--r--test/reference/over-between-source.ps3.argb32.ref.pngbin0 -> 551 bytes
-rw-r--r--test/reference/over-between-source.quartz.argb32.ref.pngbin0 -> 551 bytes
-rw-r--r--test/reference/over-between-source.rgb24.ref.pngbin0 -> 457 bytes
-rw-r--r--test/reference/over-between-source.svg12.argb32.xfail.pngbin0 -> 224 bytes
-rw-r--r--test/reference/over-between-source.svg12.rgb24.xfail.pngbin0 -> 224 bytes
-rw-r--r--test/reference/over-between-source.traps.argb32.ref.pngbin0 -> 578 bytes
-rw-r--r--test/reference/over-between-source.traps.rgb24.ref.pngbin0 -> 461 bytes
-rw-r--r--test/reference/overlapping-boxes.base.argb32.ref.pngbin0 -> 216 bytes
-rw-r--r--test/reference/overlapping-boxes.base.rgb24.ref.pngbin0 -> 204 bytes
-rw-r--r--test/reference/overlapping-boxes.ref.pngbin0 -> 179 bytes
-rw-r--r--test/reference/overlapping-boxes.traps.argb32.ref.pngbin0 -> 216 bytes
-rw-r--r--test/reference/overlapping-boxes.traps.rgb24.ref.pngbin0 -> 204 bytes
-rw-r--r--test/reference/overlapping-dash-caps.base.argb32.ref.pngbin0 -> 3967 bytes
-rw-r--r--test/reference/overlapping-dash-caps.base.rgb24.ref.pngbin0 -> 3967 bytes
-rw-r--r--test/reference/overlapping-dash-caps.mask.argb32.ref.pngbin0 -> 3986 bytes
-rw-r--r--test/reference/overlapping-dash-caps.mask.rgb24.ref.pngbin0 -> 3986 bytes
-rw-r--r--test/reference/overlapping-dash-caps.ref.pngbin0 -> 3952 bytes
-rw-r--r--test/reference/overlapping-dash-caps.traps.argb32.ref.pngbin0 -> 3967 bytes
-rw-r--r--test/reference/overlapping-dash-caps.traps.rgb24.ref.pngbin0 -> 3967 bytes
-rw-r--r--test/reference/overlapping-glyphs.base.argb32.ref.pngbin0 -> 2715 bytes
-rw-r--r--test/reference/overlapping-glyphs.base.rgb24.ref.pngbin0 -> 1661 bytes
-rw-r--r--test/reference/overlapping-glyphs.pdf.argb32.xfail.pngbin0 -> 2199 bytes
-rw-r--r--test/reference/overlapping-glyphs.pdf.rgb24.xfail.pngbin0 -> 1692 bytes
-rw-r--r--test/reference/overlapping-glyphs.quartz.argb32.ref.pngbin0 -> 2824 bytes
-rw-r--r--test/reference/overlapping-glyphs.quartz.rgb24.ref.pngbin0 -> 1711 bytes
-rw-r--r--test/reference/overlapping-glyphs.ref.pngbin0 -> 2717 bytes
-rw-r--r--test/reference/overlapping-glyphs.svg.argb32.ref.pngbin0 -> 2338 bytes
-rw-r--r--test/reference/overlapping-glyphs.svg.rgb24.ref.pngbin0 -> 2338 bytes
-rw-r--r--test/reference/overlapping-glyphs.traps.argb32.ref.pngbin0 -> 2715 bytes
-rw-r--r--test/reference/overlapping-glyphs.traps.rgb24.ref.pngbin0 -> 1661 bytes
-rw-r--r--test/reference/paint-clip-fill-aa.base.argb32.ref.pngbin0 -> 327 bytes
-rw-r--r--test/reference/paint-clip-fill-aa.base.rgb24.ref.pngbin0 -> 327 bytes
-rw-r--r--test/reference/paint-clip-fill-aa.ref.pngbin0 -> 352 bytes
-rw-r--r--test/reference/paint-clip-fill-mono.base.argb32.ref.pngbin0 -> 327 bytes
-rw-r--r--test/reference/paint-clip-fill-mono.base.rgb24.ref.pngbin0 -> 327 bytes
-rw-r--r--test/reference/paint-clip-fill-mono.ref.pngbin0 -> 352 bytes
-rw-r--r--test/reference/paint-repeat.base.argb32.ref.pngbin0 -> 122 bytes
-rw-r--r--test/reference/paint-repeat.base.rgb24.ref.pngbin0 -> 122 bytes
-rw-r--r--test/reference/paint-repeat.ref.pngbin0 -> 145 bytes
-rw-r--r--test/reference/paint-source-alpha.base.argb32.ref.pngbin0 -> 224 bytes
-rw-r--r--test/reference/paint-source-alpha.base.rgb24.ref.pngbin0 -> 224 bytes
-rw-r--r--test/reference/paint-source-alpha.image16.ref.pngbin0 -> 253 bytes
-rw-r--r--test/reference/paint-source-alpha.ref.pngbin0 -> 256 bytes
-rw-r--r--test/reference/paint-source-alpha.svg.ref.pngbin0 -> 693 bytes
-rw-r--r--test/reference/paint-with-alpha-clip-mask.base.argb32.ref.pngbin0 -> 330 bytes
-rw-r--r--test/reference/paint-with-alpha-clip-mask.base.rgb24.ref.pngbin0 -> 330 bytes
-rw-r--r--test/reference/paint-with-alpha-clip-mask.mask.argb32.ref.pngbin0 -> 330 bytes
-rw-r--r--test/reference/paint-with-alpha-clip-mask.mask.rgb24.ref.pngbin0 -> 330 bytes
-rw-r--r--test/reference/paint-with-alpha-clip-mask.ref.pngbin0 -> 335 bytes
-rw-r--r--test/reference/paint-with-alpha-clip-mask.traps.argb32.ref.pngbin0 -> 305 bytes
-rw-r--r--test/reference/paint-with-alpha-clip-mask.traps.rgb24.ref.pngbin0 -> 305 bytes
-rw-r--r--test/reference/paint-with-alpha-clip.base.argb32.ref.pngbin0 -> 269 bytes
-rw-r--r--test/reference/paint-with-alpha-clip.base.rgb24.ref.pngbin0 -> 269 bytes
-rw-r--r--test/reference/paint-with-alpha-clip.mask.argb32.ref.pngbin0 -> 269 bytes
-rw-r--r--test/reference/paint-with-alpha-clip.mask.rgb24.ref.pngbin0 -> 269 bytes
-rw-r--r--test/reference/paint-with-alpha-clip.ref.pngbin0 -> 290 bytes
-rw-r--r--test/reference/paint-with-alpha-clip.traps.argb32.ref.pngbin0 -> 269 bytes
-rw-r--r--test/reference/paint-with-alpha-clip.traps.rgb24.ref.pngbin0 -> 269 bytes
-rw-r--r--test/reference/paint-with-alpha-group-clip.ref.pngbin0 -> 135 bytes
-rw-r--r--test/reference/paint-with-alpha-solid-clip.base.argb32.ref.pngbin0 -> 248 bytes
-rw-r--r--test/reference/paint-with-alpha-solid-clip.base.rgb24.ref.pngbin0 -> 248 bytes
-rw-r--r--test/reference/paint-with-alpha-solid-clip.mask.argb32.ref.pngbin0 -> 266 bytes
-rw-r--r--test/reference/paint-with-alpha-solid-clip.mask.rgb24.ref.pngbin0 -> 266 bytes
-rw-r--r--test/reference/paint-with-alpha-solid-clip.ref.pngbin0 -> 248 bytes
-rw-r--r--test/reference/paint-with-alpha-solid-clip.traps.argb32.ref.pngbin0 -> 266 bytes
-rw-r--r--test/reference/paint-with-alpha-solid-clip.traps.rgb24.ref.pngbin0 -> 266 bytes
-rw-r--r--test/reference/paint-with-alpha.base.argb32.ref.pngbin0 -> 224 bytes
-rw-r--r--test/reference/paint-with-alpha.base.rgb24.ref.pngbin0 -> 224 bytes
-rw-r--r--test/reference/paint-with-alpha.image16.ref.pngbin0 -> 253 bytes
-rw-r--r--test/reference/paint-with-alpha.ref.pngbin0 -> 256 bytes
-rw-r--r--test/reference/paint-with-alpha.svg.ref.pngbin0 -> 483 bytes
-rw-r--r--test/reference/paint.base.argb32.ref.pngbin0 -> 93 bytes
-rw-r--r--test/reference/paint.base.rgb24.ref.pngbin0 -> 93 bytes
-rw-r--r--test/reference/paint.ref.pngbin0 -> 116 bytes
-rw-r--r--test/reference/partial-clip-text-bottom.base.argb32.ref.pngbin0 -> 261 bytes
-rw-r--r--test/reference/partial-clip-text-bottom.base.rgb24.ref.pngbin0 -> 261 bytes
-rw-r--r--test/reference/partial-clip-text-bottom.ref.pngbin0 -> 261 bytes
-rw-r--r--test/reference/partial-clip-text-left.base.argb32.ref.pngbin0 -> 301 bytes
-rw-r--r--test/reference/partial-clip-text-left.base.rgb24.ref.pngbin0 -> 301 bytes
-rw-r--r--test/reference/partial-clip-text-left.ref.pngbin0 -> 301 bytes
-rw-r--r--test/reference/partial-clip-text-right.base.argb32.ref.pngbin0 -> 155 bytes
-rw-r--r--test/reference/partial-clip-text-right.base.rgb24.ref.pngbin0 -> 155 bytes
-rw-r--r--test/reference/partial-clip-text-right.ref.pngbin0 -> 155 bytes
-rw-r--r--test/reference/partial-clip-text-right.traps.ref.pngbin0 -> 155 bytes
-rw-r--r--test/reference/partial-clip-text-top.base.argb32.ref.pngbin0 -> 181 bytes
-rw-r--r--test/reference/partial-clip-text-top.base.rgb24.ref.pngbin0 -> 181 bytes
-rw-r--r--test/reference/partial-clip-text-top.ps.ref.pngbin0 -> 107 bytes
-rw-r--r--test/reference/partial-clip-text-top.quartz.ref.pngbin0 -> 174 bytes
-rw-r--r--test/reference/partial-clip-text-top.ref.pngbin0 -> 181 bytes
-rw-r--r--test/reference/partial-clip-text-top.svg.ref.pngbin0 -> 173 bytes
-rw-r--r--test/reference/partial-clip-text-top.traps.ref.pngbin0 -> 181 bytes
-rw-r--r--test/reference/partial-coverage-half-reference.base.argb32.ref.pngbin0 -> 189 bytes
-rw-r--r--test/reference/partial-coverage-half-reference.base.rgb24.ref.pngbin0 -> 189 bytes
-rw-r--r--test/reference/partial-coverage-half-reference.ref.pngbin0 -> 189 bytes
-rw-r--r--test/reference/partial-coverage-half-triangles.ref.pngbin0 -> 189 bytes
-rw-r--r--test/reference/partial-coverage-intersecting-quads.ref.pngbin0 -> 189 bytes
-rw-r--r--test/reference/partial-coverage-intersecting-quads.xfail.pngbin0 -> 262 bytes
-rw-r--r--test/reference/partial-coverage-intersecting-triangles.ref.pngbin0 -> 202 bytes
-rw-r--r--test/reference/partial-coverage-overlap-half-triangles-eo.ref.pngbin0 -> 189 bytes
-rw-r--r--test/reference/partial-coverage-overlap-half-triangles.ref.pngbin0 -> 189 bytes
-rw-r--r--test/reference/partial-coverage-overlap-three-quarter-triangles.ref.pngbin0 -> 186 bytes
-rw-r--r--test/reference/partial-coverage-rectangles.ref.pngbin0 -> 202 bytes
-rw-r--r--test/reference/partial-coverage-reference.base.argb32.ref.pngbin0 -> 202 bytes
-rw-r--r--test/reference/partial-coverage-reference.base.rgb24.ref.pngbin0 -> 202 bytes
-rw-r--r--test/reference/partial-coverage-reference.ref.pngbin0 -> 202 bytes
-rw-r--r--test/reference/partial-coverage-three-quarter-reference.base.argb32.ref.pngbin0 -> 186 bytes
-rw-r--r--test/reference/partial-coverage-three-quarter-reference.base.rgb24.ref.pngbin0 -> 186 bytes
-rw-r--r--test/reference/partial-coverage-three-quarter-reference.ref.pngbin0 -> 186 bytes
-rw-r--r--test/reference/partial-coverage-triangles.ref.pngbin0 -> 202 bytes
-rw-r--r--test/reference/pass-through.base.argb32.ref.pngbin0 -> 221 bytes
-rw-r--r--test/reference/pass-through.base.rgb24.ref.pngbin0 -> 158 bytes
-rw-r--r--test/reference/pass-through.ref.pngbin0 -> 221 bytes
-rw-r--r--test/reference/path-append.base.argb32.ref.pngbin0 -> 6463 bytes
-rw-r--r--test/reference/path-append.base.rgb24.ref.pngbin0 -> 6463 bytes
-rw-r--r--test/reference/path-append.image16.ref.pngbin0 -> 5252 bytes
-rw-r--r--test/reference/path-append.ps.ref.pngbin0 -> 4525 bytes
-rw-r--r--test/reference/path-append.quartz.ref.pngbin0 -> 6395 bytes
-rw-r--r--test/reference/path-append.ref.pngbin0 -> 6338 bytes
-rw-r--r--test/reference/path-append.test-fallback.ref.pngbin0 -> 6461 bytes
-rw-r--r--test/reference/path-append.traps.argb32.ref.pngbin0 -> 6463 bytes
-rw-r--r--test/reference/path-append.traps.rgb24.ref.pngbin0 -> 6463 bytes
-rw-r--r--test/reference/path-append.xlib-fallback.ref.pngbin0 -> 6320 bytes
-rw-r--r--test/reference/path-stroke-twice.base.argb32.ref.pngbin0 -> 205 bytes
-rw-r--r--test/reference/path-stroke-twice.base.rgb24.ref.pngbin0 -> 205 bytes
-rw-r--r--test/reference/path-stroke-twice.image16.ref.pngbin0 -> 210 bytes
-rw-r--r--test/reference/path-stroke-twice.ps.ref.pngbin0 -> 197 bytes
-rw-r--r--test/reference/path-stroke-twice.ref.pngbin0 -> 240 bytes
-rw-r--r--test/reference/path-stroke-twice.traps.argb32.ref.pngbin0 -> 205 bytes
-rw-r--r--test/reference/path-stroke-twice.traps.rgb24.ref.pngbin0 -> 205 bytes
-rw-r--r--test/reference/pattern-getters.base.argb32.ref.pngbin0 -> 87 bytes
-rw-r--r--test/reference/pattern-getters.base.rgb24.ref.pngbin0 -> 87 bytes
-rw-r--r--test/reference/pattern-getters.ref.pngbin0 -> 107 bytes
-rw-r--r--test/reference/pdf-isolated-group.base.argb32.ref.pngbin0 -> 217 bytes
-rw-r--r--test/reference/pdf-isolated-group.base.rgb24.ref.pngbin0 -> 217 bytes
-rw-r--r--test/reference/pdf-isolated-group.ref.pngbin0 -> 217 bytes
-rw-r--r--test/reference/pdf-surface-source.base.argb32.ref.pngbin0 -> 377 bytes
-rw-r--r--test/reference/pdf-surface-source.base.rgb24.ref.pngbin0 -> 301 bytes
-rw-r--r--test/reference/pdf-surface-source.image16.ref.pngbin0 -> 305 bytes
-rw-r--r--test/reference/pdf-surface-source.ref.pngbin0 -> 377 bytes
-rw-r--r--test/reference/pdf-surface-source.svg12.argb32.xfail.pngbin0 -> 278 bytes
-rw-r--r--test/reference/pdf-surface-source.svg12.rgb24.xfail.pngbin0 -> 278 bytes
-rw-r--r--test/reference/pixman-downscale-best-24.ref.pngbin0 -> 191 bytes
-rw-r--r--test/reference/pixman-downscale-best-95.image.rgb24.ref.pngbin0 -> 659 bytes
-rw-r--r--test/reference/pixman-downscale-best-95.image16.rgb24.ref.pngbin0 -> 648 bytes
-rw-r--r--test/reference/pixman-downscale-best-95.pdf.ref.pngbin0 -> 479 bytes
-rw-r--r--test/reference/pixman-downscale-best-95.ps2.ref.pngbin0 -> 460 bytes
-rw-r--r--test/reference/pixman-downscale-best-95.ps3.ref.pngbin0 -> 460 bytes
-rw-r--r--test/reference/pixman-downscale-best-95.recording.rgb24.ref.pngbin0 -> 659 bytes
-rw-r--r--test/reference/pixman-downscale-best-95.ref.pngbin0 -> 771 bytes
-rw-r--r--test/reference/pixman-downscale-best-95.script.ref.pngbin0 -> 772 bytes
-rw-r--r--test/reference/pixman-downscale-best-95.svg11.ref.pngbin0 -> 474 bytes
-rw-r--r--test/reference/pixman-downscale-best-95.svg12.ref.pngbin0 -> 474 bytes
-rw-r--r--test/reference/pixman-downscale-best-95.test-base.rgb24.ref.pngbin0 -> 659 bytes
-rw-r--r--test/reference/pixman-downscale-best-95.test-fallback.rgb24.ref.pngbin0 -> 659 bytes
-rw-r--r--test/reference/pixman-downscale-best-95.test-mask.rgb24.ref.pngbin0 -> 659 bytes
-rw-r--r--test/reference/pixman-downscale-best-95.test-paginated.rgb24.ref.pngbin0 -> 659 bytes
-rw-r--r--test/reference/pixman-downscale-best-95.test-spans.rgb24.ref.pngbin0 -> 659 bytes
-rw-r--r--test/reference/pixman-downscale-best-95.test-traps.rgb24.ref.pngbin0 -> 659 bytes
-rw-r--r--test/reference/pixman-downscale-best-95.xcb-fallback.rgb24.ref.pngbin0 -> 659 bytes
-rw-r--r--test/reference/pixman-downscale-best-95.xcb-render-0_0.rgb24.ref.pngbin0 -> 659 bytes
-rw-r--r--test/reference/pixman-downscale-best-95.xcb-window&.rgb24.ref.pngbin0 -> 474 bytes
-rw-r--r--test/reference/pixman-downscale-best-95.xcb-window.rgb24.ref.pngbin0 -> 474 bytes
-rw-r--r--test/reference/pixman-downscale-best-95.xcb.ref.pngbin0 -> 474 bytes
-rw-r--r--test/reference/pixman-downscale-best-95.xlib-fallback.rgb24.ref.pngbin0 -> 659 bytes
-rw-r--r--test/reference/pixman-downscale-best-95.xlib-render-0_0.rgb24.ref.pngbin0 -> 659 bytes
-rw-r--r--test/reference/pixman-downscale-best-95.xlib-window.rgb24.ref.pngbin0 -> 474 bytes
-rw-r--r--test/reference/pixman-downscale-best-95.xlib.ref.pngbin0 -> 474 bytes
-rw-r--r--test/reference/pixman-downscale-best-96.ref.pngbin0 -> 301 bytes
-rw-r--r--test/reference/pixman-downscale-bilinear-24.ref.pngbin0 -> 191 bytes
-rw-r--r--test/reference/pixman-downscale-bilinear-95.image16.rgb24.ref.pngbin0 -> 481 bytes
-rw-r--r--test/reference/pixman-downscale-bilinear-95.pdf.ref.pngbin0 -> 479 bytes
-rw-r--r--test/reference/pixman-downscale-bilinear-95.ps2.ref.pngbin0 -> 460 bytes
-rw-r--r--test/reference/pixman-downscale-bilinear-95.ps3.ref.pngbin0 -> 460 bytes
-rw-r--r--test/reference/pixman-downscale-bilinear-95.ref.pngbin0 -> 474 bytes
-rw-r--r--test/reference/pixman-downscale-bilinear-95.script.ref.pngbin0 -> 481 bytes
-rw-r--r--test/reference/pixman-downscale-bilinear-96.ref.pngbin0 -> 301 bytes
-rw-r--r--test/reference/pixman-downscale-fast-24.ref.pngbin0 -> 191 bytes
-rw-r--r--test/reference/pixman-downscale-fast-95.image16.rgb24.ref.pngbin0 -> 304 bytes
-rw-r--r--test/reference/pixman-downscale-fast-95.pdf.ref.pngbin0 -> 479 bytes
-rw-r--r--test/reference/pixman-downscale-fast-95.ps2.ref.pngbin0 -> 299 bytes
-rw-r--r--test/reference/pixman-downscale-fast-95.ps3.ref.pngbin0 -> 299 bytes
-rw-r--r--test/reference/pixman-downscale-fast-95.ref.pngbin0 -> 299 bytes
-rw-r--r--test/reference/pixman-downscale-fast-95.svg11.ref.pngbin0 -> 474 bytes
-rw-r--r--test/reference/pixman-downscale-fast-95.svg12.ref.pngbin0 -> 474 bytes
-rw-r--r--test/reference/pixman-downscale-fast-96.ref.pngbin0 -> 301 bytes
-rw-r--r--test/reference/pixman-downscale-good-24.ref.pngbin0 -> 191 bytes
-rw-r--r--test/reference/pixman-downscale-good-95.image16.rgb24.ref.pngbin0 -> 481 bytes
-rw-r--r--test/reference/pixman-downscale-good-95.pdf.ref.pngbin0 -> 479 bytes
-rw-r--r--test/reference/pixman-downscale-good-95.ps2.ref.pngbin0 -> 460 bytes
-rw-r--r--test/reference/pixman-downscale-good-95.ps3.ref.pngbin0 -> 460 bytes
-rw-r--r--test/reference/pixman-downscale-good-95.ref.pngbin0 -> 474 bytes
-rw-r--r--test/reference/pixman-downscale-good-95.script.ref.pngbin0 -> 481 bytes
-rw-r--r--test/reference/pixman-downscale-good-96.ref.pngbin0 -> 301 bytes
-rw-r--r--test/reference/pixman-downscale-nearest-24.ref.pngbin0 -> 191 bytes
-rw-r--r--test/reference/pixman-downscale-nearest-95.image16.rgb24.ref.pngbin0 -> 304 bytes
-rw-r--r--test/reference/pixman-downscale-nearest-95.pdf.ref.pngbin0 -> 479 bytes
-rw-r--r--test/reference/pixman-downscale-nearest-95.ps2.ref.pngbin0 -> 299 bytes
-rw-r--r--test/reference/pixman-downscale-nearest-95.ps3.ref.pngbin0 -> 299 bytes
-rw-r--r--test/reference/pixman-downscale-nearest-95.ref.pngbin0 -> 299 bytes
-rw-r--r--test/reference/pixman-downscale-nearest-95.svg11.ref.pngbin0 -> 474 bytes
-rw-r--r--test/reference/pixman-downscale-nearest-95.svg12.ref.pngbin0 -> 474 bytes
-rw-r--r--test/reference/pixman-downscale-nearest-96.ref.pngbin0 -> 301 bytes
-rw-r--r--test/reference/pixman-rotate.base.argb32.ref.pngbin0 -> 260 bytes
-rw-r--r--test/reference/pixman-rotate.base.rgb24.ref.pngbin0 -> 225 bytes
-rw-r--r--test/reference/pixman-rotate.ps.argb32.ref.pngbin0 -> 355 bytes
-rw-r--r--test/reference/pixman-rotate.ref.pngbin0 -> 260 bytes
-rw-r--r--test/reference/ps-eps.ref.pngbin0 -> 4584 bytes
-rw-r--r--test/reference/ps-surface-source.base.argb32.ref.pngbin0 -> 377 bytes
-rw-r--r--test/reference/ps-surface-source.base.rgb24.ref.pngbin0 -> 301 bytes
-rw-r--r--test/reference/ps-surface-source.image16.ref.pngbin0 -> 305 bytes
-rw-r--r--test/reference/ps-surface-source.ref.pngbin0 -> 377 bytes
-rw-r--r--test/reference/ps-surface-source.svg12.argb32.xfail.pngbin0 -> 278 bytes
-rw-r--r--test/reference/ps-surface-source.svg12.rgb24.xfail.pngbin0 -> 278 bytes
-rw-r--r--test/reference/pthread-same-source.image16.ref.pngbin0 -> 1048 bytes
-rw-r--r--test/reference/pthread-same-source.quartz.xfail.pngbin0 -> 961 bytes
-rw-r--r--test/reference/pthread-same-source.ref.pngbin0 -> 1076 bytes
-rw-r--r--test/reference/pthread-show-text.base.argb32.ref.pngbin0 -> 30199 bytes
-rw-r--r--test/reference/pthread-show-text.base.rgb24.ref.pngbin0 -> 30199 bytes
-rw-r--r--test/reference/pthread-show-text.image16.ref.pngbin0 -> 22167 bytes
-rw-r--r--test/reference/pthread-show-text.pdf.ref.pngbin0 -> 47015 bytes
-rw-r--r--test/reference/pthread-show-text.ps.ref.pngbin0 -> 16558 bytes
-rw-r--r--test/reference/pthread-show-text.quartz.ref.pngbin0 -> 43005 bytes
-rw-r--r--test/reference/pthread-show-text.ref.pngbin0 -> 30199 bytes
-rw-r--r--test/reference/pthread-show-text.traps.ref.pngbin0 -> 30199 bytes
-rw-r--r--test/reference/pthread-show-text.xlib-fallback.ref.pngbin0 -> 42073 bytes
-rw-r--r--test/reference/pthread-similar.base.argb32.ref.pngbin0 -> 170 bytes
-rw-r--r--test/reference/pthread-similar.base.rgb24.ref.pngbin0 -> 170 bytes
-rw-r--r--test/reference/pthread-similar.ref.pngbin0 -> 176 bytes
-rw-r--r--test/reference/push-group-color.base.argb32.ref.pngbin0 -> 2902 bytes
-rw-r--r--test/reference/push-group-color.base.rgb24.ref.pngbin0 -> 2902 bytes
-rw-r--r--test/reference/push-group-color.image16.ref.pngbin0 -> 2277 bytes
-rw-r--r--test/reference/push-group-color.ps2.ref.pngbin0 -> 2863 bytes
-rw-r--r--test/reference/push-group-color.ps3.ref.pngbin0 -> 2561 bytes
-rw-r--r--test/reference/push-group-color.quartz.ref.pngbin0 -> 3127 bytes
-rw-r--r--test/reference/push-group-color.ref.pngbin0 -> 3002 bytes
-rw-r--r--test/reference/push-group-color.traps.argb32.ref.pngbin0 -> 2902 bytes
-rw-r--r--test/reference/push-group-color.traps.rgb24.ref.pngbin0 -> 2902 bytes
-rw-r--r--test/reference/push-group-path-offset.base.argb32.ref.pngbin0 -> 186 bytes
-rw-r--r--test/reference/push-group-path-offset.base.rgb24.ref.pngbin0 -> 186 bytes
-rw-r--r--test/reference/push-group-path-offset.ref.pngbin0 -> 186 bytes
-rw-r--r--test/reference/push-group.argb32.ref.pngbin0 -> 3123 bytes
-rw-r--r--test/reference/push-group.base.argb32.ref.pngbin0 -> 3110 bytes
-rw-r--r--test/reference/push-group.base.rgb24.ref.pngbin0 -> 2947 bytes
-rw-r--r--test/reference/push-group.image16.ref.pngbin0 -> 2286 bytes
-rw-r--r--test/reference/push-group.quartz.argb32.ref.pngbin0 -> 3932 bytes
-rw-r--r--test/reference/push-group.quartz.rgb24.ref.pngbin0 -> 3659 bytes
-rw-r--r--test/reference/push-group.rgb24.ref.pngbin0 -> 2951 bytes
-rw-r--r--test/reference/push-group.traps.argb32.ref.pngbin0 -> 3110 bytes
-rw-r--r--test/reference/push-group.traps.rgb24.ref.pngbin0 -> 2947 bytes
-rw-r--r--test/reference/quartz-surface-source.ps2.ref.pngbin0 -> 376 bytes
-rw-r--r--test/reference/quartz-surface-source.ps3.ref.pngbin0 -> 376 bytes
-rw-r--r--test/reference/quartz-surface-source.ref.pngbin0 -> 377 bytes
-rw-r--r--test/reference/radial-gradient-extend.base.argb32.ref.pngbin0 -> 466 bytes
-rw-r--r--test/reference/radial-gradient-extend.base.rgb24.ref.pngbin0 -> 466 bytes
-rw-r--r--test/reference/radial-gradient-extend.mask.argb32.ref.pngbin0 -> 466 bytes
-rw-r--r--test/reference/radial-gradient-extend.mask.rgb24.ref.pngbin0 -> 466 bytes
-rw-r--r--test/reference/radial-gradient-extend.ps3.ref.pngbin0 -> 458 bytes
-rw-r--r--test/reference/radial-gradient-extend.ref.pngbin0 -> 466 bytes
-rw-r--r--test/reference/radial-gradient-extend.traps.argb32.ref.pngbin0 -> 466 bytes
-rw-r--r--test/reference/radial-gradient-extend.traps.rgb24.ref.pngbin0 -> 466 bytes
-rw-r--r--test/reference/radial-gradient-mask-source.argb32.ref.pngbin0 -> 145713 bytes
-rw-r--r--test/reference/radial-gradient-mask-source.base.argb32.ref.pngbin0 -> 145713 bytes
-rw-r--r--test/reference/radial-gradient-mask-source.base.rgb24.ref.pngbin0 -> 150945 bytes
-rw-r--r--test/reference/radial-gradient-mask-source.image16.ref.pngbin0 -> 109925 bytes
-rw-r--r--test/reference/radial-gradient-mask-source.mask.rgb24.ref.pngbin0 -> 150945 bytes
-rw-r--r--test/reference/radial-gradient-mask-source.quartz.argb32.ref.pngbin0 -> 171002 bytes
-rw-r--r--test/reference/radial-gradient-mask-source.quartz.rgb24.ref.pngbin0 -> 179120 bytes
-rw-r--r--test/reference/radial-gradient-mask-source.traps.rgb24.ref.pngbin0 -> 150945 bytes
-rw-r--r--test/reference/radial-gradient-mask.base.argb32.ref.pngbin0 -> 286065 bytes
-rw-r--r--test/reference/radial-gradient-mask.base.rgb24.ref.pngbin0 -> 286065 bytes
-rw-r--r--test/reference/radial-gradient-mask.image16.ref.pngbin0 -> 204585 bytes
-rw-r--r--test/reference/radial-gradient-mask.quartz.ref.pngbin0 -> 296910 bytes
-rw-r--r--test/reference/radial-gradient-mask.ref.pngbin0 -> 286065 bytes
-rw-r--r--test/reference/radial-gradient-one-stop.base.argb32.ref.pngbin0 -> 6306 bytes
-rw-r--r--test/reference/radial-gradient-one-stop.base.rgb24.ref.pngbin0 -> 6306 bytes
-rw-r--r--test/reference/radial-gradient-one-stop.quartz.ref.pngbin0 -> 6316 bytes
-rw-r--r--test/reference/radial-gradient-one-stop.ref.pngbin0 -> 6306 bytes
-rw-r--r--test/reference/radial-gradient-source.base.argb32.ref.pngbin0 -> 408848 bytes
-rw-r--r--test/reference/radial-gradient-source.base.rgb24.ref.pngbin0 -> 263908 bytes
-rw-r--r--test/reference/radial-gradient-source.image16.ref.pngbin0 -> 169796 bytes
-rw-r--r--test/reference/radial-gradient-source.quartz.argb32.ref.pngbin0 -> 439222 bytes
-rw-r--r--test/reference/radial-gradient-source.quartz.rgb24.ref.pngbin0 -> 279249 bytes
-rw-r--r--test/reference/radial-gradient-source.ref.pngbin0 -> 408848 bytes
-rw-r--r--test/reference/radial-gradient.base.argb32.ref.pngbin0 -> 382283 bytes
-rw-r--r--test/reference/radial-gradient.base.rgb24.ref.pngbin0 -> 382283 bytes
-rw-r--r--test/reference/radial-gradient.image16.ref.pngbin0 -> 256686 bytes
-rw-r--r--test/reference/radial-gradient.quartz.ref.pngbin0 -> 389140 bytes
-rw-r--r--test/reference/radial-gradient.ref.pngbin0 -> 382283 bytes
-rw-r--r--test/reference/radial-outer-focus.base.argb32.ref.pngbin0 -> 38310 bytes
-rw-r--r--test/reference/radial-outer-focus.base.rgb24.ref.pngbin0 -> 38310 bytes
-rw-r--r--test/reference/radial-outer-focus.mask.argb32.ref.pngbin0 -> 38310 bytes
-rw-r--r--test/reference/radial-outer-focus.mask.rgb24.ref.pngbin0 -> 38310 bytes
-rw-r--r--test/reference/radial-outer-focus.traps.argb32.ref.pngbin0 -> 38310 bytes
-rw-r--r--test/reference/radial-outer-focus.traps.rgb24.ref.pngbin0 -> 38310 bytes
-rw-r--r--test/reference/radial-outer-focus.xfail.pngbin0 -> 34234 bytes
-rw-r--r--test/reference/random-clip.base.argb32.ref.pngbin0 -> 521821 bytes
-rw-r--r--test/reference/random-clip.base.argb32.xfail.pngbin0 -> 525726 bytes
-rw-r--r--test/reference/random-clip.base.rgb24.ref.pngbin0 -> 521821 bytes
-rw-r--r--test/reference/random-clip.base.rgb24.xfail.pngbin0 -> 525726 bytes
-rw-r--r--test/reference/random-clip.mask.argb32.ref.pngbin0 -> 550190 bytes
-rw-r--r--test/reference/random-clip.mask.rgb24.ref.pngbin0 -> 550190 bytes
-rw-r--r--test/reference/random-clip.ref.pngbin0 -> 525010 bytes
-rw-r--r--test/reference/random-clip.traps.argb32.ref.pngbin0 -> 523346 bytes
-rw-r--r--test/reference/random-clip.traps.rgb24.ref.pngbin0 -> 523346 bytes
-rw-r--r--test/reference/random-intersections-curves-eo.base.argb32.ref.pngbin0 -> 244476 bytes
-rw-r--r--test/reference/random-intersections-curves-eo.base.rgb24.ref.pngbin0 -> 244476 bytes
-rw-r--r--test/reference/random-intersections-curves-eo.image16.ref.pngbin0 -> 181565 bytes
-rw-r--r--test/reference/random-intersections-curves-eo.pdf.ref.pngbin0 -> 246507 bytes
-rw-r--r--test/reference/random-intersections-curves-eo.ps.ref.pngbin0 -> 151668 bytes
-rw-r--r--test/reference/random-intersections-curves-eo.quartz.ref.pngbin0 -> 326366 bytes
-rw-r--r--test/reference/random-intersections-curves-eo.ref.pngbin0 -> 244632 bytes
-rw-r--r--test/reference/random-intersections-curves-eo.traps.argb32.ref.pngbin0 -> 244476 bytes
-rw-r--r--test/reference/random-intersections-curves-eo.traps.rgb24.ref.pngbin0 -> 244476 bytes
-rw-r--r--test/reference/random-intersections-curves-eo.xlib-fallback.ref.pngbin0 -> 244255 bytes
-rw-r--r--test/reference/random-intersections-curves-nz.base.argb32.ref.pngbin0 -> 263669 bytes
-rw-r--r--test/reference/random-intersections-curves-nz.base.rgb24.ref.pngbin0 -> 263669 bytes
-rw-r--r--test/reference/random-intersections-curves-nz.image16.ref.pngbin0 -> 204090 bytes
-rw-r--r--test/reference/random-intersections-curves-nz.pdf.ref.pngbin0 -> 266977 bytes
-rw-r--r--test/reference/random-intersections-curves-nz.ps.ref.pngbin0 -> 134746 bytes
-rw-r--r--test/reference/random-intersections-curves-nz.quartz.ref.pngbin0 -> 324940 bytes
-rw-r--r--test/reference/random-intersections-curves-nz.ref.pngbin0 -> 264413 bytes
-rw-r--r--test/reference/random-intersections-curves-nz.traps.argb32.ref.pngbin0 -> 263669 bytes
-rw-r--r--test/reference/random-intersections-curves-nz.traps.rgb24.ref.pngbin0 -> 263669 bytes
-rw-r--r--test/reference/random-intersections-curves-nz.xlib-fallback.ref.pngbin0 -> 264277 bytes
-rw-r--r--test/reference/random-intersections-eo.base.argb32.ref.pngbin0 -> 134729 bytes
-rw-r--r--test/reference/random-intersections-eo.base.rgb24.ref.pngbin0 -> 134729 bytes
-rw-r--r--test/reference/random-intersections-eo.image16.ref.pngbin0 -> 97747 bytes
-rw-r--r--test/reference/random-intersections-eo.ps.ref.pngbin0 -> 78037 bytes
-rw-r--r--test/reference/random-intersections-eo.quartz.ref.pngbin0 -> 179179 bytes
-rw-r--r--test/reference/random-intersections-eo.ref.pngbin0 -> 135555 bytes
-rw-r--r--test/reference/random-intersections-eo.traps.argb32.ref.pngbin0 -> 134729 bytes
-rw-r--r--test/reference/random-intersections-eo.traps.rgb24.ref.pngbin0 -> 134729 bytes
-rw-r--r--test/reference/random-intersections-nonzero.base.argb32.ref.pngbin0 -> 141616 bytes
-rw-r--r--test/reference/random-intersections-nonzero.base.rgb24.ref.pngbin0 -> 141616 bytes
-rw-r--r--test/reference/random-intersections-nonzero.image16.ref.pngbin0 -> 107644 bytes
-rw-r--r--test/reference/random-intersections-nonzero.ps.ref.pngbin0 -> 76450 bytes
-rw-r--r--test/reference/random-intersections-nonzero.quartz.ref.pngbin0 -> 180871 bytes
-rw-r--r--test/reference/random-intersections-nonzero.ref.pngbin0 -> 141737 bytes
-rw-r--r--test/reference/random-intersections-nonzero.traps.argb32.ref.pngbin0 -> 141616 bytes
-rw-r--r--test/reference/random-intersections-nonzero.traps.rgb24.ref.pngbin0 -> 141616 bytes
-rw-r--r--test/reference/raster-source.base.argb32.ref.pngbin0 -> 1209 bytes
-rw-r--r--test/reference/raster-source.base.rgb24.ref.pngbin0 -> 1209 bytes
-rw-r--r--test/reference/raster-source.ps.ref.pngbin0 -> 1894 bytes
-rw-r--r--test/reference/raster-source.ref.pngbin0 -> 1209 bytes
-rw-r--r--test/reference/record-extend-none-similar.base.argb32.ref.pngbin0 -> 279 bytes
-rw-r--r--test/reference/record-extend-none-similar.base.rgb24.ref.pngbin0 -> 279 bytes
-rw-r--r--test/reference/record-extend-none-similar.ref.pngbin0 -> 293 bytes
-rw-r--r--test/reference/record-extend-none-similar.traps.argb32.ref.pngbin0 -> 279 bytes
-rw-r--r--test/reference/record-extend-none-similar.traps.rgb24.ref.pngbin0 -> 279 bytes
-rw-r--r--test/reference/record-extend-none.base.argb32.ref.pngbin0 -> 293 bytes
-rw-r--r--test/reference/record-extend-none.base.rgb24.ref.pngbin0 -> 293 bytes
-rw-r--r--test/reference/record-extend-none.ref.pngbin0 -> 293 bytes
-rw-r--r--test/reference/record-extend-pad-similar.base.argb32.ref.pngbin0 -> 283 bytes
-rw-r--r--test/reference/record-extend-pad-similar.base.rgb24.ref.pngbin0 -> 283 bytes
-rw-r--r--test/reference/record-extend-pad-similar.ref.pngbin0 -> 298 bytes
-rw-r--r--test/reference/record-extend-pad-similar.traps.argb32.ref.pngbin0 -> 283 bytes
-rw-r--r--test/reference/record-extend-pad-similar.traps.rgb24.ref.pngbin0 -> 283 bytes
-rw-r--r--test/reference/record-extend-pad.base.argb32.ref.pngbin0 -> 298 bytes
-rw-r--r--test/reference/record-extend-pad.base.rgb24.ref.pngbin0 -> 298 bytes
-rw-r--r--test/reference/record-extend-pad.ref.pngbin0 -> 298 bytes
-rw-r--r--test/reference/record-extend-reflect-similar.base.argb32.ref.pngbin0 -> 283 bytes
-rw-r--r--test/reference/record-extend-reflect-similar.base.rgb24.ref.pngbin0 -> 283 bytes
-rw-r--r--test/reference/record-extend-reflect-similar.ref.pngbin0 -> 335 bytes
-rw-r--r--test/reference/record-extend-reflect-similar.traps.argb32.ref.pngbin0 -> 283 bytes
-rw-r--r--test/reference/record-extend-reflect-similar.traps.rgb24.ref.pngbin0 -> 283 bytes
-rw-r--r--test/reference/record-extend-reflect.base.argb32.ref.pngbin0 -> 335 bytes
-rw-r--r--test/reference/record-extend-reflect.base.rgb24.ref.pngbin0 -> 335 bytes
-rw-r--r--test/reference/record-extend-reflect.ref.pngbin0 -> 335 bytes
-rw-r--r--test/reference/record-extend-repeat-similar.base.argb32.ref.pngbin0 -> 283 bytes
-rw-r--r--test/reference/record-extend-repeat-similar.base.rgb24.ref.pngbin0 -> 283 bytes
-rw-r--r--test/reference/record-extend-repeat-similar.ref.pngbin0 -> 286 bytes
-rw-r--r--test/reference/record-extend-repeat-similar.traps.argb32.ref.pngbin0 -> 283 bytes
-rw-r--r--test/reference/record-extend-repeat-similar.traps.rgb24.ref.pngbin0 -> 283 bytes
-rw-r--r--test/reference/record-extend-repeat.base.argb32.ref.pngbin0 -> 286 bytes
-rw-r--r--test/reference/record-extend-repeat.base.rgb24.ref.pngbin0 -> 286 bytes
-rw-r--r--test/reference/record-extend-repeat.ref.pngbin0 -> 286 bytes
-rw-r--r--test/reference/record-fill-alpha.base.argb32.ref.pngbin0 -> 2853 bytes
-rw-r--r--test/reference/record-fill-alpha.base.rgb24.ref.pngbin0 -> 2853 bytes
-rw-r--r--test/reference/record-fill-alpha.base.xfail.pngbin0 -> 2853 bytes
-rw-r--r--test/reference/record-fill-alpha.image16.rgb24.ref.pngbin0 -> 2232 bytes
-rw-r--r--test/reference/record-fill-alpha.ref.pngbin0 -> 2754 bytes
-rw-r--r--test/reference/record-fill-alpha.traps.argb32.ref.pngbin0 -> 2824 bytes
-rw-r--r--test/reference/record-fill-alpha.traps.rgb24.ref.pngbin0 -> 2824 bytes
-rw-r--r--test/reference/record-fill-alpha.xfail.pngbin0 -> 2839 bytes
-rw-r--r--test/reference/record-mesh.base.argb32.ref.pngbin0 -> 15229 bytes
-rw-r--r--test/reference/record-mesh.base.rgb24.ref.pngbin0 -> 15229 bytes
-rw-r--r--test/reference/record-mesh.image16.rgb24.ref.pngbin0 -> 9027 bytes
-rw-r--r--test/reference/record-mesh.ref.pngbin0 -> 15229 bytes
-rw-r--r--test/reference/record-paint-alpha-clip-mask.base.argb32.ref.pngbin0 -> 337 bytes
-rw-r--r--test/reference/record-paint-alpha-clip-mask.base.rgb24.ref.pngbin0 -> 337 bytes
-rw-r--r--test/reference/record-paint-alpha-clip-mask.base.xfail.pngbin0 -> 337 bytes
-rw-r--r--test/reference/record-paint-alpha-clip-mask.image16.rgb24.ref.pngbin0 -> 352 bytes
-rw-r--r--test/reference/record-paint-alpha-clip-mask.ref.pngbin0 -> 335 bytes
-rw-r--r--test/reference/record-paint-alpha-clip-mask.traps.argb32.ref.pngbin0 -> 305 bytes
-rw-r--r--test/reference/record-paint-alpha-clip-mask.traps.rgb24.ref.pngbin0 -> 305 bytes
-rw-r--r--test/reference/record-paint-alpha-clip-mask.xfail.pngbin0 -> 333 bytes
-rw-r--r--test/reference/record-paint-alpha-clip.base.argb32.ref.pngbin0 -> 299 bytes
-rw-r--r--test/reference/record-paint-alpha-clip.base.rgb24.ref.pngbin0 -> 299 bytes
-rw-r--r--test/reference/record-paint-alpha-clip.image16.rgb24.ref.pngbin0 -> 313 bytes
-rw-r--r--test/reference/record-paint-alpha-clip.ref.pngbin0 -> 290 bytes
-rw-r--r--test/reference/record-paint-alpha-clip.traps.argb32.ref.pngbin0 -> 269 bytes
-rw-r--r--test/reference/record-paint-alpha-clip.traps.rgb24.ref.pngbin0 -> 269 bytes
-rw-r--r--test/reference/record-paint-alpha-solid-clip.base.argb32.ref.pngbin0 -> 248 bytes
-rw-r--r--test/reference/record-paint-alpha-solid-clip.base.rgb24.ref.pngbin0 -> 248 bytes
-rw-r--r--test/reference/record-paint-alpha-solid-clip.image16.rgb24.ref.pngbin0 -> 274 bytes
-rw-r--r--test/reference/record-paint-alpha-solid-clip.ref.pngbin0 -> 248 bytes
-rw-r--r--test/reference/record-paint-alpha-solid-clip.traps.argb32.ref.pngbin0 -> 266 bytes
-rw-r--r--test/reference/record-paint-alpha-solid-clip.traps.rgb24.ref.pngbin0 -> 266 bytes
-rw-r--r--test/reference/record-paint-alpha.base.argb32.ref.pngbin0 -> 224 bytes
-rw-r--r--test/reference/record-paint-alpha.base.rgb24.ref.pngbin0 -> 224 bytes
-rw-r--r--test/reference/record-paint-alpha.image16.rgb24.ref.pngbin0 -> 253 bytes
-rw-r--r--test/reference/record-paint-alpha.ref.pngbin0 -> 245 bytes
-rw-r--r--test/reference/record-paint.base.argb32.ref.pngbin0 -> 93 bytes
-rw-r--r--test/reference/record-paint.base.rgb24.ref.pngbin0 -> 93 bytes
-rw-r--r--test/reference/record-paint.ref.pngbin0 -> 116 bytes
-rw-r--r--test/reference/record-select-font-face.base.argb32.ref.pngbin0 -> 1417 bytes
-rw-r--r--test/reference/record-select-font-face.base.rgb24.ref.pngbin0 -> 1417 bytes
-rw-r--r--test/reference/record-select-font-face.image16.rgb24.ref.pngbin0 -> 1236 bytes
-rw-r--r--test/reference/record-select-font-face.ref.pngbin0 -> 2250 bytes
-rw-r--r--test/reference/record-select-font-face.xfail.pngbin0 -> 1448 bytes
-rw-r--r--test/reference/record-self-intersecting.base.argb32.ref.pngbin0 -> 168 bytes
-rw-r--r--test/reference/record-self-intersecting.base.rgb24.ref.pngbin0 -> 168 bytes
-rw-r--r--test/reference/record-self-intersecting.image16.rgb24.ref.pngbin0 -> 228 bytes
-rw-r--r--test/reference/record-self-intersecting.ref.pngbin0 -> 168 bytes
-rw-r--r--test/reference/record-text-transform.base.argb32.ref.pngbin0 -> 5281 bytes
-rw-r--r--test/reference/record-text-transform.base.rgb24.ref.pngbin0 -> 5281 bytes
-rw-r--r--test/reference/record-text-transform.image16.rgb24.ref.pngbin0 -> 2688 bytes
-rw-r--r--test/reference/record-text-transform.ref.pngbin0 -> 5579 bytes
-rw-r--r--test/reference/record1414x-fill-alpha.base.argb32.ref.pngbin0 -> 4138 bytes
-rw-r--r--test/reference/record1414x-fill-alpha.base.rgb24.ref.pngbin0 -> 4138 bytes
-rw-r--r--test/reference/record1414x-fill-alpha.base.xfail.pngbin0 -> 4138 bytes
-rw-r--r--test/reference/record1414x-fill-alpha.ref.pngbin0 -> 4124 bytes
-rw-r--r--test/reference/record1414x-fill-alpha.xfail.pngbin0 -> 4216 bytes
-rw-r--r--test/reference/record1414x-paint-alpha-clip-mask.base.argb32.ref.pngbin0 -> 514 bytes
-rw-r--r--test/reference/record1414x-paint-alpha-clip-mask.base.rgb24.ref.pngbin0 -> 514 bytes
-rw-r--r--test/reference/record1414x-paint-alpha-clip-mask.ref.pngbin0 -> 460 bytes
-rw-r--r--test/reference/record1414x-paint-alpha-clip.base.argb32.ref.pngbin0 -> 402 bytes
-rw-r--r--test/reference/record1414x-paint-alpha-clip.base.rgb24.ref.pngbin0 -> 402 bytes
-rw-r--r--test/reference/record1414x-paint-alpha-clip.ref.pngbin0 -> 378 bytes
-rw-r--r--test/reference/record1414x-paint-alpha-solid-clip.base.argb32.ref.pngbin0 -> 317 bytes
-rw-r--r--test/reference/record1414x-paint-alpha-solid-clip.base.rgb24.ref.pngbin0 -> 317 bytes
-rw-r--r--test/reference/record1414x-paint-alpha-solid-clip.ref.pngbin0 -> 317 bytes
-rw-r--r--test/reference/record1414x-paint-alpha.base.argb32.ref.pngbin0 -> 265 bytes
-rw-r--r--test/reference/record1414x-paint-alpha.base.rgb24.ref.pngbin0 -> 265 bytes
-rw-r--r--test/reference/record1414x-paint-alpha.ref.pngbin0 -> 265 bytes
-rw-r--r--test/reference/record1414x-paint.base.argb32.ref.pngbin0 -> 95 bytes
-rw-r--r--test/reference/record1414x-paint.base.rgb24.ref.pngbin0 -> 95 bytes
-rw-r--r--test/reference/record1414x-paint.ref.pngbin0 -> 95 bytes
-rw-r--r--test/reference/record1414x-select-font-face.base.argb32.ref.pngbin0 -> 2018 bytes
-rw-r--r--test/reference/record1414x-select-font-face.base.rgb24.ref.pngbin0 -> 2018 bytes
-rw-r--r--test/reference/record1414x-select-font-face.ref.pngbin0 -> 3177 bytes
-rw-r--r--test/reference/record1414x-self-intersecting.base.argb32.ref.pngbin0 -> 385 bytes
-rw-r--r--test/reference/record1414x-self-intersecting.base.rgb24.ref.pngbin0 -> 385 bytes
-rw-r--r--test/reference/record1414x-self-intersecting.ref.pngbin0 -> 385 bytes
-rw-r--r--test/reference/record1414x-text-transform.base.argb32.ref.pngbin0 -> 8368 bytes
-rw-r--r--test/reference/record1414x-text-transform.base.rgb24.ref.pngbin0 -> 8368 bytes
-rw-r--r--test/reference/record1414x-text-transform.ref.pngbin0 -> 8713 bytes
-rw-r--r--test/reference/record2x-fill-alpha.base.argb32.ref.pngbin0 -> 5724 bytes
-rw-r--r--test/reference/record2x-fill-alpha.base.rgb24.ref.pngbin0 -> 5724 bytes
-rw-r--r--test/reference/record2x-fill-alpha.base.xfail.pngbin0 -> 5724 bytes
-rw-r--r--test/reference/record2x-fill-alpha.ref.pngbin0 -> 5756 bytes
-rw-r--r--test/reference/record2x-fill-alpha.xfail.pngbin0 -> 5978 bytes
-rw-r--r--test/reference/record2x-paint-alpha-clip-mask.base.argb32.ref.pngbin0 -> 501 bytes
-rw-r--r--test/reference/record2x-paint-alpha-clip-mask.base.rgb24.ref.pngbin0 -> 501 bytes
-rw-r--r--test/reference/record2x-paint-alpha-clip-mask.ref.pngbin0 -> 483 bytes
-rw-r--r--test/reference/record2x-paint-alpha-clip.base.argb32.ref.pngbin0 -> 322 bytes
-rw-r--r--test/reference/record2x-paint-alpha-clip.base.rgb24.ref.pngbin0 -> 322 bytes
-rw-r--r--test/reference/record2x-paint-alpha-clip.ref.pngbin0 -> 322 bytes
-rw-r--r--test/reference/record2x-paint-alpha-solid-clip.base.argb32.ref.pngbin0 -> 281 bytes
-rw-r--r--test/reference/record2x-paint-alpha-solid-clip.base.rgb24.ref.pngbin0 -> 281 bytes
-rw-r--r--test/reference/record2x-paint-alpha-solid-clip.ref.pngbin0 -> 281 bytes
-rw-r--r--test/reference/record2x-paint-alpha.base.argb32.ref.pngbin0 -> 291 bytes
-rw-r--r--test/reference/record2x-paint-alpha.base.rgb24.ref.pngbin0 -> 291 bytes
-rw-r--r--test/reference/record2x-paint-alpha.ref.pngbin0 -> 291 bytes
-rw-r--r--test/reference/record2x-paint.base.argb32.ref.pngbin0 -> 98 bytes
-rw-r--r--test/reference/record2x-paint.base.rgb24.ref.pngbin0 -> 98 bytes
-rw-r--r--test/reference/record2x-paint.ref.pngbin0 -> 98 bytes
-rw-r--r--test/reference/record2x-select-font-face.base.argb32.ref.pngbin0 -> 3096 bytes
-rw-r--r--test/reference/record2x-select-font-face.base.rgb24.ref.pngbin0 -> 3096 bytes
-rw-r--r--test/reference/record2x-select-font-face.ref.pngbin0 -> 4407 bytes
-rw-r--r--test/reference/record2x-self-intersecting.base.argb32.ref.pngbin0 -> 171 bytes
-rw-r--r--test/reference/record2x-self-intersecting.base.rgb24.ref.pngbin0 -> 171 bytes
-rw-r--r--test/reference/record2x-self-intersecting.ref.pngbin0 -> 171 bytes
-rw-r--r--test/reference/record2x-text-transform.base.argb32.ref.pngbin0 -> 13174 bytes
-rw-r--r--test/reference/record2x-text-transform.base.rgb24.ref.pngbin0 -> 13174 bytes
-rw-r--r--test/reference/record2x-text-transform.ref.pngbin0 -> 13476 bytes
-rw-r--r--test/reference/record90-fill-alpha.base.argb32.ref.pngbin0 -> 2628 bytes
-rw-r--r--test/reference/record90-fill-alpha.base.rgb24.ref.pngbin0 -> 2628 bytes
-rw-r--r--test/reference/record90-fill-alpha.ref.pngbin0 -> 2656 bytes
-rw-r--r--test/reference/record90-fill-alpha.xfail.pngbin0 -> 2654 bytes
-rw-r--r--test/reference/record90-paint-alpha-clip-mask.base.argb32.ref.pngbin0 -> 343 bytes
-rw-r--r--test/reference/record90-paint-alpha-clip-mask.base.rgb24.ref.pngbin0 -> 343 bytes
-rw-r--r--test/reference/record90-paint-alpha-clip-mask.ref.pngbin0 -> 317 bytes
-rw-r--r--test/reference/record90-paint-alpha-clip-mask.xfail.pngbin0 -> 324 bytes
-rw-r--r--test/reference/record90-paint-alpha-clip.base.argb32.ref.pngbin0 -> 327 bytes
-rw-r--r--test/reference/record90-paint-alpha-clip.base.rgb24.ref.pngbin0 -> 327 bytes
-rw-r--r--test/reference/record90-paint-alpha-clip.ref.pngbin0 -> 306 bytes
-rw-r--r--test/reference/record90-paint-alpha-clip.xfail.pngbin0 -> 327 bytes
-rw-r--r--test/reference/record90-paint-alpha-solid-clip.base.argb32.ref.pngbin0 -> 279 bytes
-rw-r--r--test/reference/record90-paint-alpha-solid-clip.base.rgb24.ref.pngbin0 -> 279 bytes
-rw-r--r--test/reference/record90-paint-alpha-solid-clip.ref.pngbin0 -> 293 bytes
-rw-r--r--test/reference/record90-paint-alpha.base.argb32.ref.pngbin0 -> 105 bytes
-rw-r--r--test/reference/record90-paint-alpha.base.rgb24.ref.pngbin0 -> 105 bytes
-rw-r--r--test/reference/record90-paint-alpha.ref.pngbin0 -> 105 bytes
-rw-r--r--test/reference/record90-paint.base.argb32.ref.pngbin0 -> 93 bytes
-rw-r--r--test/reference/record90-paint.base.rgb24.ref.pngbin0 -> 93 bytes
-rw-r--r--test/reference/record90-paint.ref.pngbin0 -> 93 bytes
-rw-r--r--test/reference/record90-select-font-face.base.argb32.ref.pngbin0 -> 1480 bytes
-rw-r--r--test/reference/record90-select-font-face.base.rgb24.ref.pngbin0 -> 1480 bytes
-rw-r--r--test/reference/record90-select-font-face.ref.pngbin0 -> 2272 bytes
-rw-r--r--test/reference/record90-self-intersecting.base.argb32.ref.pngbin0 -> 208 bytes
-rw-r--r--test/reference/record90-self-intersecting.base.rgb24.ref.pngbin0 -> 208 bytes
-rw-r--r--test/reference/record90-self-intersecting.ref.pngbin0 -> 240 bytes
-rw-r--r--test/reference/record90-text-transform.base.argb32.ref.pngbin0 -> 5481 bytes
-rw-r--r--test/reference/record90-text-transform.base.rgb24.ref.pngbin0 -> 5481 bytes
-rw-r--r--test/reference/record90-text-transform.ref.pngbin0 -> 5811 bytes
-rw-r--r--test/reference/recordflip-fill-alpha.ref.pngbin0 -> 2803 bytes
-rw-r--r--test/reference/recordflip-paint-alpha-clip-mask.ref.pngbin0 -> 351 bytes
-rw-r--r--test/reference/recordflip-paint-alpha-clip.ref.pngbin0 -> 316 bytes
-rw-r--r--test/reference/recordflip-paint-alpha-solid-clip.ref.pngbin0 -> 291 bytes
-rw-r--r--test/reference/recordflip-paint-alpha.ref.pngbin0 -> 257 bytes
-rw-r--r--test/reference/recordflip-paint.ref.pngbin0 -> 93 bytes
-rw-r--r--test/reference/recordflip-select-font-face.ref.pngbin0 -> 2240 bytes
-rw-r--r--test/reference/recordflip-self-intersecting.ref.pngbin0 -> 168 bytes
-rw-r--r--test/reference/recordflip-text-transform.ref.pngbin0 -> 5609 bytes
-rw-r--r--test/reference/recordflip-whole-fill-alpha.ref.pngbin0 -> 2803 bytes
-rw-r--r--test/reference/recordflip-whole-paint-alpha-clip-mask.ref.pngbin0 -> 351 bytes
-rw-r--r--test/reference/recordflip-whole-paint-alpha-clip.ref.pngbin0 -> 316 bytes
-rw-r--r--test/reference/recordflip-whole-paint-alpha-solid-clip.ref.pngbin0 -> 291 bytes
-rw-r--r--test/reference/recordflip-whole-paint-alpha.ref.pngbin0 -> 257 bytes
-rw-r--r--test/reference/recordflip-whole-paint.ref.pngbin0 -> 93 bytes
-rw-r--r--test/reference/recordflip-whole-select-font-face.ref.pngbin0 -> 2240 bytes
-rw-r--r--test/reference/recordflip-whole-self-intersecting.ref.pngbin0 -> 168 bytes
-rw-r--r--test/reference/recordflip-whole-text-transform.ref.pngbin0 -> 5609 bytes
-rw-r--r--test/reference/recording-surface-extend-none.argb32.ref.pngbin0 -> 3670 bytes
-rw-r--r--test/reference/recording-surface-extend-none.base.argb32.ref.pngbin0 -> 3055 bytes
-rw-r--r--test/reference/recording-surface-extend-none.base.rgb24.ref.pngbin0 -> 3124 bytes
-rw-r--r--test/reference/recording-surface-extend-none.rgb24.ref.pngbin0 -> 3741 bytes
-rw-r--r--test/reference/recording-surface-extend-none.traps.argb32.ref.pngbin0 -> 3055 bytes
-rw-r--r--test/reference/recording-surface-extend-none.traps.rgb24.ref.pngbin0 -> 3124 bytes
-rw-r--r--test/reference/recording-surface-extend-pad.argb32.ref.pngbin0 -> 12932 bytes
-rw-r--r--test/reference/recording-surface-extend-pad.base.argb32.ref.pngbin0 -> 10832 bytes
-rw-r--r--test/reference/recording-surface-extend-pad.base.rgb24.ref.pngbin0 -> 12496 bytes
-rw-r--r--test/reference/recording-surface-extend-pad.rgb24.ref.pngbin0 -> 13581 bytes
-rw-r--r--test/reference/recording-surface-extend-pad.traps.argb32.ref.pngbin0 -> 10832 bytes
-rw-r--r--test/reference/recording-surface-extend-pad.traps.rgb24.ref.pngbin0 -> 12496 bytes
-rw-r--r--test/reference/recording-surface-extend-reflect.argb32.ref.pngbin0 -> 28910 bytes
-rw-r--r--test/reference/recording-surface-extend-reflect.base.argb32.ref.pngbin0 -> 23617 bytes
-rw-r--r--test/reference/recording-surface-extend-reflect.base.rgb24.ref.pngbin0 -> 24139 bytes
-rw-r--r--test/reference/recording-surface-extend-reflect.rgb24.ref.pngbin0 -> 25588 bytes
-rw-r--r--test/reference/recording-surface-extend-reflect.traps.argb32.ref.pngbin0 -> 23617 bytes
-rw-r--r--test/reference/recording-surface-extend-reflect.traps.rgb24.ref.pngbin0 -> 24139 bytes
-rw-r--r--test/reference/recording-surface-extend-repeat.argb32.ref.pngbin0 -> 29648 bytes
-rw-r--r--test/reference/recording-surface-extend-repeat.base.argb32.ref.pngbin0 -> 24112 bytes
-rw-r--r--test/reference/recording-surface-extend-repeat.base.rgb24.ref.pngbin0 -> 24029 bytes
-rw-r--r--test/reference/recording-surface-extend-repeat.rgb24.ref.pngbin0 -> 25337 bytes
-rw-r--r--test/reference/recording-surface-extend-repeat.traps.argb32.ref.pngbin0 -> 24112 bytes
-rw-r--r--test/reference/recording-surface-extend-repeat.traps.rgb24.ref.pngbin0 -> 24029 bytes
-rw-r--r--test/reference/recording-surface-over.argb32.ref.pngbin0 -> 3670 bytes
-rw-r--r--test/reference/recording-surface-over.base.argb32.ref.pngbin0 -> 3055 bytes
-rw-r--r--test/reference/recording-surface-over.base.rgb24.ref.pngbin0 -> 3124 bytes
-rw-r--r--test/reference/recording-surface-over.gl.argb32.ref.pngbin0 -> 3130 bytes
-rw-r--r--test/reference/recording-surface-over.image16.ref.pngbin0 -> 2856 bytes
-rw-r--r--test/reference/recording-surface-over.pdf.argb32.ref.pngbin0 -> 3908 bytes
-rw-r--r--test/reference/recording-surface-over.pdf.rgb24.ref.pngbin0 -> 3760 bytes
-rw-r--r--test/reference/recording-surface-over.ps.argb32.ref.pngbin0 -> 3064 bytes
-rw-r--r--test/reference/recording-surface-over.ps.rgb24.ref.pngbin0 -> 3147 bytes
-rw-r--r--test/reference/recording-surface-over.quartz.argb32.ref.pngbin0 -> 4570 bytes
-rw-r--r--test/reference/recording-surface-over.quartz.rgb24.ref.pngbin0 -> 4058 bytes
-rw-r--r--test/reference/recording-surface-over.rgb24.ref.pngbin0 -> 3741 bytes
-rw-r--r--test/reference/recording-surface-over.svg.argb32.ref.pngbin0 -> 3778 bytes
-rw-r--r--test/reference/recording-surface-over.svg.rgb24.ref.pngbin0 -> 3760 bytes
-rw-r--r--test/reference/recording-surface-over.traps.argb32.ref.pngbin0 -> 3055 bytes
-rw-r--r--test/reference/recording-surface-over.traps.rgb24.ref.pngbin0 -> 3124 bytes
-rw-r--r--test/reference/recording-surface-source.argb32.ref.pngbin0 -> 3688 bytes
-rw-r--r--test/reference/recording-surface-source.base.argb32.ref.pngbin0 -> 3049 bytes
-rw-r--r--test/reference/recording-surface-source.base.rgb24.ref.pngbin0 -> 3121 bytes
-rw-r--r--test/reference/recording-surface-source.rgb24.ref.pngbin0 -> 3738 bytes
-rw-r--r--test/reference/recording-surface-source.traps.argb32.ref.pngbin0 -> 3049 bytes
-rw-r--r--test/reference/recording-surface-source.traps.rgb24.ref.pngbin0 -> 3121 bytes
-rw-r--r--test/reference/rectangle-rounding-error.base.argb32.ref.pngbin0 -> 212 bytes
-rw-r--r--test/reference/rectangle-rounding-error.base.rgb24.ref.pngbin0 -> 212 bytes
-rw-r--r--test/reference/rectangle-rounding-error.ref.pngbin0 -> 231 bytes
-rw-r--r--test/reference/rectilinear-dash-scale-unaligned.ref.pngbin0 -> 3738 bytes
-rw-r--r--test/reference/rectilinear-dash-scale-unaligned.traps.ref.pngbin0 -> 3289 bytes
-rw-r--r--test/reference/rectilinear-dash-scale.ref.pngbin0 -> 651 bytes
-rw-r--r--test/reference/rectilinear-dash.base.argb32.ref.pngbin0 -> 291 bytes
-rw-r--r--test/reference/rectilinear-dash.base.rgb24.ref.pngbin0 -> 291 bytes
-rw-r--r--test/reference/rectilinear-dash.mask.argb32.ref.pngbin0 -> 291 bytes
-rw-r--r--test/reference/rectilinear-dash.mask.rgb24.ref.pngbin0 -> 291 bytes
-rw-r--r--test/reference/rectilinear-dash.quartz.xfail.pngbin0 -> 494 bytes
-rw-r--r--test/reference/rectilinear-dash.ref.pngbin0 -> 291 bytes
-rw-r--r--test/reference/rectilinear-dash.traps.argb32.ref.pngbin0 -> 291 bytes
-rw-r--r--test/reference/rectilinear-dash.traps.rgb24.ref.pngbin0 -> 291 bytes
-rw-r--r--test/reference/rectilinear-fill.base.argb32.ref.pngbin0 -> 151 bytes
-rw-r--r--test/reference/rectilinear-fill.base.rgb24.ref.pngbin0 -> 151 bytes
-rw-r--r--test/reference/rectilinear-fill.ref.pngbin0 -> 162 bytes
-rw-r--r--test/reference/rectilinear-grid.base.argb32.ref.pngbin0 -> 610 bytes
-rw-r--r--test/reference/rectilinear-grid.base.rgb24.ref.pngbin0 -> 610 bytes
-rw-r--r--test/reference/rectilinear-grid.image16.ref.pngbin0 -> 638 bytes
-rw-r--r--test/reference/rectilinear-grid.ref.pngbin0 -> 569 bytes
-rw-r--r--test/reference/rectilinear-grid.traps.argb32.ref.pngbin0 -> 610 bytes
-rw-r--r--test/reference/rectilinear-grid.traps.rgb24.ref.pngbin0 -> 610 bytes
-rw-r--r--test/reference/rectilinear-miter-limit.base.argb32.ref.pngbin0 -> 145 bytes
-rw-r--r--test/reference/rectilinear-miter-limit.base.rgb24.ref.pngbin0 -> 145 bytes
-rw-r--r--test/reference/rectilinear-miter-limit.ps2.ref.pngbin0 -> 221 bytes
-rw-r--r--test/reference/rectilinear-miter-limit.ps3.ref.pngbin0 -> 221 bytes
-rw-r--r--test/reference/rectilinear-miter-limit.ref.pngbin0 -> 145 bytes
-rw-r--r--test/reference/rectilinear-miter-limit.traps.argb32.ref.pngbin0 -> 145 bytes
-rw-r--r--test/reference/rectilinear-miter-limit.traps.rgb24.ref.pngbin0 -> 145 bytes
-rw-r--r--test/reference/rectilinear-stroke.base.argb32.ref.pngbin0 -> 172 bytes
-rw-r--r--test/reference/rectilinear-stroke.base.rgb24.ref.pngbin0 -> 172 bytes
-rw-r--r--test/reference/rectilinear-stroke.quartz.xfail.pngbin0 -> 209 bytes
-rw-r--r--test/reference/rectilinear-stroke.ref.pngbin0 -> 213 bytes
-rw-r--r--test/reference/reflected-stroke.base.argb32.ref.pngbin0 -> 5053 bytes
-rw-r--r--test/reference/reflected-stroke.base.rgb24.ref.pngbin0 -> 5053 bytes
-rw-r--r--test/reference/reflected-stroke.image16.ref.pngbin0 -> 4254 bytes
-rw-r--r--test/reference/reflected-stroke.mask.argb32.ref.pngbin0 -> 5119 bytes
-rw-r--r--test/reference/reflected-stroke.mask.rgb24.ref.pngbin0 -> 5119 bytes
-rw-r--r--test/reference/reflected-stroke.ps.ref.pngbin0 -> 3368 bytes
-rw-r--r--test/reference/reflected-stroke.ref.pngbin0 -> 5116 bytes
-rw-r--r--test/reference/reflected-stroke.traps.argb32.ref.pngbin0 -> 5053 bytes
-rw-r--r--test/reference/reflected-stroke.traps.rgb24.ref.pngbin0 -> 5053 bytes
-rw-r--r--test/reference/rel-path.base.argb32.ref.pngbin0 -> 189 bytes
-rw-r--r--test/reference/rel-path.base.rgb24.ref.pngbin0 -> 206 bytes
-rw-r--r--test/reference/rel-path.mask.rgb24.ref.pngbin0 -> 216 bytes
-rw-r--r--test/reference/rel-path.ps2.rgb24.ref.pngbin0 -> 243 bytes
-rw-r--r--test/reference/rel-path.ps3.rgb24.ref.pngbin0 -> 243 bytes
-rw-r--r--test/reference/rel-path.ref.pngbin0 -> 197 bytes
-rw-r--r--test/reference/rel-path.traps.argb32.ref.pngbin0 -> 189 bytes
-rw-r--r--test/reference/rel-path.traps.rgb24.ref.pngbin0 -> 206 bytes
-rw-r--r--test/reference/rgb24-ignore-alpha.base.argb32.ref.pngbin0 -> 97 bytes
-rw-r--r--test/reference/rgb24-ignore-alpha.base.rgb24.ref.pngbin0 -> 97 bytes
-rw-r--r--test/reference/rgb24-ignore-alpha.ref.pngbin0 -> 116 bytes
-rw-r--r--test/reference/rotate-clip-image-surface-paint.base.argb32.ref.pngbin0 -> 331 bytes
-rw-r--r--test/reference/rotate-clip-image-surface-paint.base.rgb24.ref.pngbin0 -> 331 bytes
-rw-r--r--test/reference/rotate-clip-image-surface-paint.ref.pngbin0 -> 332 bytes
-rw-r--r--test/reference/rotate-clip-image-surface-paint.traps.argb32.ref.pngbin0 -> 303 bytes
-rw-r--r--test/reference/rotate-clip-image-surface-paint.traps.rgb24.ref.pngbin0 -> 303 bytes
-rw-r--r--test/reference/rotate-clip-image-surface-paint.xlib-fallback.rgb24.ref.pngbin0 -> 303 bytes
-rw-r--r--test/reference/rotate-clip-image-surface-paint.xlib-window.rgb24.ref.pngbin0 -> 303 bytes
-rw-r--r--test/reference/rotate-clip.surface-paint.image.argb32.ref.pngbin0 -> 340 bytes
-rw-r--r--test/reference/rotate-clip.surface-paint.image.rgb24.ref.pngbin0 -> 340 bytes
-rw-r--r--test/reference/rotate-image-surface-paint.base.argb32.ref.pngbin0 -> 220 bytes
-rw-r--r--test/reference/rotate-image-surface-paint.base.rgb24.ref.pngbin0 -> 220 bytes
-rw-r--r--test/reference/rotate-image-surface-paint.pdf.xfail.pngbin0 -> 442 bytes
-rw-r--r--test/reference/rotate-image-surface-paint.ps.ref.pngbin0 -> 236 bytes
-rw-r--r--test/reference/rotate-image-surface-paint.quartz.ref.pngbin0 -> 223 bytes
-rw-r--r--test/reference/rotate-image-surface-paint.ref.pngbin0 -> 220 bytes
-rw-r--r--test/reference/rotate-image-surface-paint.svg.ref.pngbin0 -> 209 bytes
-rw-r--r--test/reference/rotate-image-surface-paint.svg.xfail.pngbin0 -> 387 bytes
-rw-r--r--test/reference/rotate-stroke-box.ref.pngbin0 -> 150 bytes
-rw-r--r--test/reference/rotated-clip.base.argb32.ref.pngbin0 -> 3912 bytes
-rw-r--r--test/reference/rotated-clip.base.rgb24.ref.pngbin0 -> 3912 bytes
-rw-r--r--test/reference/rotated-clip.image16.ref.pngbin0 -> 3336 bytes
-rw-r--r--test/reference/rotated-clip.mask.argb32.ref.pngbin0 -> 3697 bytes
-rw-r--r--test/reference/rotated-clip.mask.rgb24.ref.pngbin0 -> 3697 bytes
-rw-r--r--test/reference/rotated-clip.ps.ref.pngbin0 -> 3378 bytes
-rw-r--r--test/reference/rotated-clip.quartz.ref.pngbin0 -> 3923 bytes
-rw-r--r--test/reference/rotated-clip.ref.pngbin0 -> 3834 bytes
-rw-r--r--test/reference/rotated-clip.traps.argb32.ref.pngbin0 -> 3922 bytes
-rw-r--r--test/reference/rotated-clip.traps.rgb24.ref.pngbin0 -> 3922 bytes
-rw-r--r--test/reference/rounded-rectangle-fill.base.argb32.ref.pngbin0 -> 890 bytes
-rw-r--r--test/reference/rounded-rectangle-fill.base.rgb24.ref.pngbin0 -> 890 bytes
-rw-r--r--test/reference/rounded-rectangle-fill.image16.ref.pngbin0 -> 730 bytes
-rw-r--r--test/reference/rounded-rectangle-fill.ps.ref.pngbin0 -> 551 bytes
-rw-r--r--test/reference/rounded-rectangle-fill.quartz.ref.pngbin0 -> 684 bytes
-rw-r--r--test/reference/rounded-rectangle-fill.ref.pngbin0 -> 872 bytes
-rw-r--r--test/reference/rounded-rectangle-fill.traps.argb32.ref.pngbin0 -> 890 bytes
-rw-r--r--test/reference/rounded-rectangle-fill.traps.rgb24.ref.pngbin0 -> 890 bytes
-rw-r--r--test/reference/rounded-rectangle-stroke.base.argb32.ref.pngbin0 -> 856 bytes
-rw-r--r--test/reference/rounded-rectangle-stroke.base.rgb24.ref.pngbin0 -> 856 bytes
-rw-r--r--test/reference/rounded-rectangle-stroke.image16.ref.pngbin0 -> 732 bytes
-rw-r--r--test/reference/rounded-rectangle-stroke.mask.argb32.ref.pngbin0 -> 951 bytes
-rw-r--r--test/reference/rounded-rectangle-stroke.mask.rgb24.ref.pngbin0 -> 951 bytes
-rw-r--r--test/reference/rounded-rectangle-stroke.ps.ref.pngbin0 -> 568 bytes
-rw-r--r--test/reference/rounded-rectangle-stroke.ref.pngbin0 -> 872 bytes
-rw-r--r--test/reference/rounded-rectangle-stroke.traps.argb32.ref.pngbin0 -> 856 bytes
-rw-r--r--test/reference/rounded-rectangle-stroke.traps.rgb24.ref.pngbin0 -> 856 bytes
-rw-r--r--test/reference/sample-diagonal.ref.pngbin0 -> 272 bytes
-rw-r--r--test/reference/sample-horizontal.ref.pngbin0 -> 209 bytes
-rw-r--r--test/reference/sample-vertical.ref.pngbin0 -> 209 bytes
-rw-r--r--test/reference/scale-down-source-surface-paint.base.argb32.ref.pngbin0 -> 96 bytes
-rw-r--r--test/reference/scale-down-source-surface-paint.base.rgb24.ref.pngbin0 -> 96 bytes
-rw-r--r--test/reference/scale-down-source-surface-paint.ref.pngbin0 -> 133 bytes
-rw-r--r--test/reference/scale-offset-image.base.argb32.ref.pngbin0 -> 9048 bytes
-rw-r--r--test/reference/scale-offset-image.base.rgb24.ref.pngbin0 -> 9048 bytes
-rw-r--r--test/reference/scale-offset-image.gl.ref.pngbin0 -> 9197 bytes
-rw-r--r--test/reference/scale-offset-image.image16.ref.pngbin0 -> 7793 bytes
-rw-r--r--test/reference/scale-offset-image.pdf.argb32.ref.pngbin0 -> 7643 bytes
-rw-r--r--test/reference/scale-offset-image.pdf.rgb24.ref.pngbin0 -> 7643 bytes
-rw-r--r--test/reference/scale-offset-image.ps.ref.pngbin0 -> 7697 bytes
-rw-r--r--test/reference/scale-offset-image.quartz.ref.pngbin0 -> 8977 bytes
-rw-r--r--test/reference/scale-offset-image.ref.pngbin0 -> 9748 bytes
-rw-r--r--test/reference/scale-offset-image.script.xfail.pngbin0 -> 9963 bytes
-rw-r--r--test/reference/scale-offset-image.traps.argb32.ref.pngbin0 -> 9048 bytes
-rw-r--r--test/reference/scale-offset-image.traps.rgb24.ref.pngbin0 -> 9048 bytes
-rw-r--r--test/reference/scale-offset-image.xfail.pngbin0 -> 9961 bytes
-rw-r--r--test/reference/scale-offset-image.xlib-fallback.xfail.pngbin0 -> 8686 bytes
-rw-r--r--test/reference/scale-offset-similar.base.argb32.ref.pngbin0 -> 9048 bytes
-rw-r--r--test/reference/scale-offset-similar.base.rgb24.ref.pngbin0 -> 9048 bytes
-rw-r--r--test/reference/scale-offset-similar.gl.ref.pngbin0 -> 9197 bytes
-rw-r--r--test/reference/scale-offset-similar.image16.ref.pngbin0 -> 7793 bytes
-rw-r--r--test/reference/scale-offset-similar.pdf.argb32.ref.pngbin0 -> 8419 bytes
-rw-r--r--test/reference/scale-offset-similar.pdf.rgb24.ref.pngbin0 -> 8419 bytes
-rw-r--r--test/reference/scale-offset-similar.ps.ref.pngbin0 -> 6850 bytes
-rw-r--r--test/reference/scale-offset-similar.quartz.ref.pngbin0 -> 8977 bytes
-rw-r--r--test/reference/scale-offset-similar.recording.xfail.pngbin0 -> 10752 bytes
-rw-r--r--test/reference/scale-offset-similar.ref.pngbin0 -> 9779 bytes
-rw-r--r--test/reference/scale-offset-similar.script.xfail.pngbin0 -> 9963 bytes
-rw-r--r--test/reference/scale-offset-similar.traps.argb32.ref.pngbin0 -> 9048 bytes
-rw-r--r--test/reference/scale-offset-similar.traps.rgb24.ref.pngbin0 -> 9048 bytes
-rw-r--r--test/reference/scale-offset-similar.xfail.pngbin0 -> 9961 bytes
-rw-r--r--test/reference/scale-offset-similar.xlib-fallback.xfail.pngbin0 -> 8686 bytes
-rw-r--r--test/reference/scale-offset-similar.xlib.xfail.pngbin0 -> 8698 bytes
-rw-r--r--test/reference/scale-offset-xlib-fallback.rgb24.ref.pngbin0 -> 9120 bytes
-rw-r--r--test/reference/scale-offset-xlib-window.rgb24.ref.pngbin0 -> 9120 bytes
-rw-r--r--test/reference/scale-offset-xlib.ref.pngbin0 -> 9120 bytes
-rw-r--r--test/reference/scale-offset.image.argb32.ref.pngbin0 -> 9847 bytes
-rw-r--r--test/reference/scale-offset.image.rgb24.ref.pngbin0 -> 9847 bytes
-rw-r--r--test/reference/scale-source-surface-paint.base.argb32.ref.pngbin0 -> 128 bytes
-rw-r--r--test/reference/scale-source-surface-paint.base.rgb24.ref.pngbin0 -> 117 bytes
-rw-r--r--test/reference/scale-source-surface-paint.pdf.argb32.xfail.pngbin0 -> 157 bytes
-rw-r--r--test/reference/scale-source-surface-paint.pdf.rgb24.xfail.pngbin0 -> 152 bytes
-rw-r--r--test/reference/scale-source-surface-paint.ref.pngbin0 -> 147 bytes
-rw-r--r--test/reference/scale-source-surface-paint.svg.argb32.xfail.pngbin0 -> 229 bytes
-rw-r--r--test/reference/scale-source-surface-paint.svg.rgb24.xfail.pngbin0 -> 222 bytes
-rw-r--r--test/reference/select-font-face.base.argb32.ref.pngbin0 -> 2250 bytes
-rw-r--r--test/reference/select-font-face.base.rgb24.ref.pngbin0 -> 2250 bytes
-rw-r--r--test/reference/select-font-face.image16.ref.pngbin0 -> 1962 bytes
-rw-r--r--test/reference/select-font-face.ps2.ref.pngbin0 -> 959 bytes
-rw-r--r--test/reference/select-font-face.ps3.ref.pngbin0 -> 959 bytes
-rw-r--r--test/reference/select-font-face.quartz.ref.pngbin0 -> 2645 bytes
-rw-r--r--test/reference/select-font-face.ref.pngbin0 -> 2250 bytes
-rw-r--r--test/reference/select-font-face.traps.ref.pngbin0 -> 2250 bytes
-rw-r--r--test/reference/self-copy-overlap.base.argb32.ref.pngbin0 -> 1140 bytes
-rw-r--r--test/reference/self-copy-overlap.base.rgb24.ref.pngbin0 -> 213 bytes
-rw-r--r--test/reference/self-copy-overlap.mask.argb32.ref.pngbin0 -> 1140 bytes
-rw-r--r--test/reference/self-copy-overlap.mask.rgb24.ref.pngbin0 -> 213 bytes
-rw-r--r--test/reference/self-copy-overlap.traps.argb32.ref.pngbin0 -> 1140 bytes
-rw-r--r--test/reference/self-copy-overlap.traps.rgb24.ref.pngbin0 -> 213 bytes
-rw-r--r--test/reference/self-copy.base.argb32.ref.pngbin0 -> 257 bytes
-rw-r--r--test/reference/self-copy.base.rgb24.ref.pngbin0 -> 257 bytes
-rw-r--r--test/reference/self-copy.ps2.ref.pngbin0 -> 335 bytes
-rw-r--r--test/reference/self-copy.ps3.ref.pngbin0 -> 335 bytes
-rw-r--r--test/reference/self-copy.ref.pngbin0 -> 257 bytes
-rw-r--r--test/reference/self-copy.traps.argb32.ref.pngbin0 -> 257 bytes
-rw-r--r--test/reference/self-copy.traps.rgb24.ref.pngbin0 -> 257 bytes
-rw-r--r--test/reference/self-intersecting.base.argb32.ref.pngbin0 -> 208 bytes
-rw-r--r--test/reference/self-intersecting.base.rgb24.ref.pngbin0 -> 208 bytes
-rw-r--r--test/reference/self-intersecting.ps.ref.pngbin0 -> 186 bytes
-rw-r--r--test/reference/self-intersecting.quartz.xfail.pngbin0 -> 233 bytes
-rw-r--r--test/reference/self-intersecting.ref.pngbin0 -> 168 bytes
-rw-r--r--test/reference/self-intersecting.traps.argb32.ref.pngbin0 -> 208 bytes
-rw-r--r--test/reference/self-intersecting.traps.rgb24.ref.pngbin0 -> 208 bytes
-rw-r--r--test/reference/set-source.base.argb32.ref.pngbin0 -> 101 bytes
-rw-r--r--test/reference/set-source.base.rgb24.ref.pngbin0 -> 101 bytes
-rw-r--r--test/reference/set-source.ref.pngbin0 -> 120 bytes
-rw-r--r--test/reference/shape-general-convex.base.argb32.ref.pngbin0 -> 2532 bytes
-rw-r--r--test/reference/shape-general-convex.base.rgb24.ref.pngbin0 -> 2532 bytes
-rw-r--r--test/reference/shape-general-convex.ps.ref.pngbin0 -> 1632 bytes
-rw-r--r--test/reference/shape-general-convex.ref.pngbin0 -> 2539 bytes
-rw-r--r--test/reference/shape-general-convex.traps.argb32.ref.pngbin0 -> 2532 bytes
-rw-r--r--test/reference/shape-general-convex.traps.rgb24.ref.pngbin0 -> 2532 bytes
-rw-r--r--test/reference/shape-sierpinski.base.argb32.ref.pngbin0 -> 54485 bytes
-rw-r--r--test/reference/shape-sierpinski.base.rgb24.ref.pngbin0 -> 54485 bytes
-rw-r--r--test/reference/shape-sierpinski.pdf.argb32.ref.pngbin0 -> 39520 bytes
-rw-r--r--test/reference/shape-sierpinski.pdf.rgb24.ref.pngbin0 -> 39520 bytes
-rw-r--r--test/reference/shape-sierpinski.ps.ref.pngbin0 -> 39965 bytes
-rw-r--r--test/reference/shape-sierpinski.ps3.argb32.ref.pngbin0 -> 39965 bytes
-rw-r--r--test/reference/shape-sierpinski.ps3.rgb24.ref.pngbin0 -> 39965 bytes
-rw-r--r--test/reference/shape-sierpinski.ref.pngbin0 -> 54850 bytes
-rw-r--r--test/reference/shape-sierpinski.traps.argb32.ref.pngbin0 -> 54485 bytes
-rw-r--r--test/reference/shape-sierpinski.traps.rgb24.ref.pngbin0 -> 54485 bytes
-rw-r--r--test/reference/show-glyphs-advance.base.argb32.ref.pngbin0 -> 1394 bytes
-rw-r--r--test/reference/show-glyphs-advance.base.rgb24.ref.pngbin0 -> 1394 bytes
-rw-r--r--test/reference/show-glyphs-advance.image16.ref.pngbin0 -> 1270 bytes
-rw-r--r--test/reference/show-glyphs-advance.ps.ref.pngbin0 -> 901 bytes
-rw-r--r--test/reference/show-glyphs-advance.quartz.ref.pngbin0 -> 1464 bytes
-rw-r--r--test/reference/show-glyphs-advance.ref.pngbin0 -> 1394 bytes
-rw-r--r--test/reference/show-glyphs-advance.svg.ref.pngbin0 -> 1435 bytes
-rw-r--r--test/reference/show-glyphs-advance.traps.ref.pngbin0 -> 1394 bytes
-rw-r--r--test/reference/show-glyphs-many.base.argb32.ref.pngbin0 -> 96 bytes
-rw-r--r--test/reference/show-glyphs-many.base.rgb24.ref.pngbin0 -> 96 bytes
-rw-r--r--test/reference/show-glyphs-many.ref.pngbin0 -> 118 bytes
-rw-r--r--test/reference/show-text-current-point.base.argb32.ref.pngbin0 -> 2151 bytes
-rw-r--r--test/reference/show-text-current-point.base.rgb24.ref.pngbin0 -> 2151 bytes
-rw-r--r--test/reference/show-text-current-point.image16.ref.pngbin0 -> 1932 bytes
-rw-r--r--test/reference/show-text-current-point.ps2.ref.pngbin0 -> 1356 bytes
-rw-r--r--test/reference/show-text-current-point.ps3.ref.pngbin0 -> 1356 bytes
-rw-r--r--test/reference/show-text-current-point.quartz.ref.pngbin0 -> 2773 bytes
-rw-r--r--test/reference/show-text-current-point.ref.pngbin0 -> 2151 bytes
-rw-r--r--test/reference/show-text-current-point.traps.ref.pngbin0 -> 2151 bytes
-rw-r--r--test/reference/simple-edge.ref.pngbin0 -> 1922 bytes
-rw-r--r--test/reference/simple-edge.xfail.pngbin0 -> 2124 bytes
-rw-r--r--test/reference/skew-extreme.base.argb32.ref.pngbin0 -> 935 bytes
-rw-r--r--test/reference/skew-extreme.base.rgb24.ref.pngbin0 -> 935 bytes
-rw-r--r--test/reference/skew-extreme.ps2.ref.pngbin0 -> 1048 bytes
-rw-r--r--test/reference/skew-extreme.ps3.ref.pngbin0 -> 1048 bytes
-rw-r--r--test/reference/skew-extreme.ref.pngbin0 -> 944 bytes
-rw-r--r--test/reference/skew-extreme.traps.argb32.ref.pngbin0 -> 935 bytes
-rw-r--r--test/reference/skew-extreme.traps.rgb24.ref.pngbin0 -> 935 bytes
-rw-r--r--test/reference/smask-fill.base.argb32.ref.pngbin0 -> 1170 bytes
-rw-r--r--test/reference/smask-fill.base.rgb24.ref.pngbin0 -> 1170 bytes
-rw-r--r--test/reference/smask-fill.image16.ref.pngbin0 -> 925 bytes
-rw-r--r--test/reference/smask-fill.pdf.ref.pngbin0 -> 1105 bytes
-rw-r--r--test/reference/smask-fill.quartz.ref.pngbin0 -> 2076 bytes
-rw-r--r--test/reference/smask-fill.ref.pngbin0 -> 1185 bytes
-rw-r--r--test/reference/smask-fill.svg.ref.pngbin0 -> 1150 bytes
-rw-r--r--test/reference/smask-fill.traps.argb32.ref.pngbin0 -> 1170 bytes
-rw-r--r--test/reference/smask-fill.traps.rgb24.ref.pngbin0 -> 1170 bytes
-rw-r--r--test/reference/smask-image-mask.base.argb32.ref.pngbin0 -> 619 bytes
-rw-r--r--test/reference/smask-image-mask.base.rgb24.ref.pngbin0 -> 619 bytes
-rw-r--r--test/reference/smask-image-mask.pdf.ref.pngbin0 -> 615 bytes
-rw-r--r--test/reference/smask-image-mask.ref.pngbin0 -> 619 bytes
-rw-r--r--test/reference/smask-mask.base.argb32.ref.pngbin0 -> 2353 bytes
-rw-r--r--test/reference/smask-mask.base.rgb24.ref.pngbin0 -> 2353 bytes
-rw-r--r--test/reference/smask-mask.image16.ref.pngbin0 -> 1358 bytes
-rw-r--r--test/reference/smask-mask.pdf.ref.pngbin0 -> 2308 bytes
-rw-r--r--test/reference/smask-mask.quartz.ref.pngbin0 -> 3191 bytes
-rw-r--r--test/reference/smask-mask.ref.pngbin0 -> 2353 bytes
-rw-r--r--test/reference/smask-mask.svg.ref.pngbin0 -> 2376 bytes
-rw-r--r--test/reference/smask-paint.base.argb32.ref.pngbin0 -> 2469 bytes
-rw-r--r--test/reference/smask-paint.base.rgb24.ref.pngbin0 -> 2469 bytes
-rw-r--r--test/reference/smask-paint.image16.ref.pngbin0 -> 1469 bytes
-rw-r--r--test/reference/smask-paint.pdf.ref.pngbin0 -> 2431 bytes
-rw-r--r--test/reference/smask-paint.quartz.ref.pngbin0 -> 3311 bytes
-rw-r--r--test/reference/smask-paint.ref.pngbin0 -> 2469 bytes
-rw-r--r--test/reference/smask-paint.svg.ref.pngbin0 -> 2453 bytes
-rw-r--r--test/reference/smask-stroke.base.argb32.ref.pngbin0 -> 1703 bytes
-rw-r--r--test/reference/smask-stroke.base.rgb24.ref.pngbin0 -> 1703 bytes
-rw-r--r--test/reference/smask-stroke.image16.ref.pngbin0 -> 1330 bytes
-rw-r--r--test/reference/smask-stroke.pdf.xfail.pngbin0 -> 392 bytes
-rw-r--r--test/reference/smask-stroke.quartz.ref.pngbin0 -> 1697 bytes
-rw-r--r--test/reference/smask-stroke.ref.pngbin0 -> 1701 bytes
-rw-r--r--test/reference/smask-stroke.traps.argb32.ref.pngbin0 -> 1703 bytes
-rw-r--r--test/reference/smask-stroke.traps.rgb24.ref.pngbin0 -> 1703 bytes
-rw-r--r--test/reference/smask-text.base.argb32.ref.pngbin0 -> 1660 bytes
-rw-r--r--test/reference/smask-text.base.rgb24.ref.pngbin0 -> 1660 bytes
-rw-r--r--test/reference/smask-text.image16.ref.pngbin0 -> 1206 bytes
-rw-r--r--test/reference/smask-text.mask.argb32.ref.pngbin0 -> 1660 bytes
-rw-r--r--test/reference/smask-text.mask.rgb24.ref.pngbin0 -> 1660 bytes
-rw-r--r--test/reference/smask-text.pdf.ref.pngbin0 -> 1874 bytes
-rw-r--r--test/reference/smask-text.ps2.ref.pngbin0 -> 2023 bytes
-rw-r--r--test/reference/smask-text.ps3.ref.pngbin0 -> 2023 bytes
-rw-r--r--test/reference/smask-text.quartz.ref.pngbin0 -> 1904 bytes
-rw-r--r--test/reference/smask-text.ref.pngbin0 -> 1661 bytes
-rw-r--r--test/reference/smask-text.script.ref.pngbin0 -> 1663 bytes
-rw-r--r--test/reference/smask-text.svg.ref.pngbin0 -> 1794 bytes
-rw-r--r--test/reference/smask-text.traps.ref.pngbin0 -> 1661 bytes
-rw-r--r--test/reference/smask-text.xlib-fallback.ref.pngbin0 -> 1874 bytes
-rw-r--r--test/reference/smask.base.argb32.ref.pngbin0 -> 3393 bytes
-rw-r--r--test/reference/smask.base.rgb24.ref.pngbin0 -> 3393 bytes
-rw-r--r--test/reference/smask.image16.ref.pngbin0 -> 2213 bytes
-rw-r--r--test/reference/smask.mask.argb32.ref.pngbin0 -> 3413 bytes
-rw-r--r--test/reference/smask.mask.rgb24.ref.pngbin0 -> 3413 bytes
-rw-r--r--test/reference/smask.pdf.xfail.pngbin0 -> 2848 bytes
-rw-r--r--test/reference/smask.ps.ref.pngbin0 -> 3430 bytes
-rw-r--r--test/reference/smask.quartz.ref.pngbin0 -> 4031 bytes
-rw-r--r--test/reference/smask.ref.pngbin0 -> 3422 bytes
-rw-r--r--test/reference/smask.script.ref.pngbin0 -> 3396 bytes
-rw-r--r--test/reference/smask.svg.ref.pngbin0 -> 3457 bytes
-rw-r--r--test/reference/smask.traps.ref.pngbin0 -> 3393 bytes
-rw-r--r--test/reference/smask.xlib-fallback.ref.pngbin0 -> 3423 bytes
-rw-r--r--test/reference/solid-pattern-cache-stress.base.argb32.ref.pngbin0 -> 87 bytes
-rw-r--r--test/reference/solid-pattern-cache-stress.base.rgb24.ref.pngbin0 -> 87 bytes
-rw-r--r--test/reference/solid-pattern-cache-stress.ref.pngbin0 -> 107 bytes
-rw-r--r--test/reference/source-clip-scale.base.argb32.ref.pngbin0 -> 136 bytes
-rw-r--r--test/reference/source-clip-scale.base.rgb24.ref.pngbin0 -> 136 bytes
-rw-r--r--test/reference/source-clip-scale.gl.ref.pngbin0 -> 164 bytes
-rw-r--r--test/reference/source-clip-scale.pdf.ref.pngbin0 -> 113 bytes
-rw-r--r--test/reference/source-clip-scale.ps2.argb32.ref.pngbin0 -> 183 bytes
-rw-r--r--test/reference/source-clip-scale.ps2.rgb24.ref.pngbin0 -> 183 bytes
-rw-r--r--test/reference/source-clip-scale.ps3.argb32.ref.pngbin0 -> 183 bytes
-rw-r--r--test/reference/source-clip-scale.ps3.rgb24.ref.pngbin0 -> 183 bytes
-rw-r--r--test/reference/source-clip-scale.quartz.ref.pngbin0 -> 126 bytes
-rw-r--r--test/reference/source-clip-scale.recording.ref.pngbin0 -> 116 bytes
-rw-r--r--test/reference/source-clip-scale.ref.pngbin0 -> 161 bytes
-rw-r--r--test/reference/source-clip-scale.svg.ref.pngbin0 -> 116 bytes
-rw-r--r--test/reference/source-clip.base.argb32.ref.pngbin0 -> 111 bytes
-rw-r--r--test/reference/source-clip.base.rgb24.ref.pngbin0 -> 111 bytes
-rw-r--r--test/reference/source-clip.ref.pngbin0 -> 133 bytes
-rw-r--r--test/reference/source-surface-scale-paint.base.argb32.ref.pngbin0 -> 120 bytes
-rw-r--r--test/reference/source-surface-scale-paint.base.rgb24.ref.pngbin0 -> 114 bytes
-rw-r--r--test/reference/source-surface-scale-paint.ref.pngbin0 -> 139 bytes
-rw-r--r--test/reference/spline-decomposition.base.argb32.ref.pngbin0 -> 19089 bytes
-rw-r--r--test/reference/spline-decomposition.base.rgb24.ref.pngbin0 -> 19089 bytes
-rw-r--r--test/reference/spline-decomposition.image16.ref.pngbin0 -> 14064 bytes
-rw-r--r--test/reference/spline-decomposition.pdf.ref.pngbin0 -> 19540 bytes
-rw-r--r--test/reference/spline-decomposition.ps.ref.pngbin0 -> 8939 bytes
-rw-r--r--test/reference/spline-decomposition.quartz.xfail.pngbin0 -> 19560 bytes
-rw-r--r--test/reference/spline-decomposition.ref.pngbin0 -> 19578 bytes
-rw-r--r--test/reference/spline-decomposition.svg.ref.pngbin0 -> 19540 bytes
-rw-r--r--test/reference/spline-decomposition.traps.argb32.ref.pngbin0 -> 19089 bytes
-rw-r--r--test/reference/spline-decomposition.traps.rgb24.ref.pngbin0 -> 19089 bytes
-rw-r--r--test/reference/stride-12-image.base.argb32.ref.pngbin0 -> 81121 bytes
-rw-r--r--test/reference/stride-12-image.base.rgb24.ref.pngbin0 -> 81121 bytes
-rw-r--r--test/reference/stride-12-image.image16.ref.pngbin0 -> 61197 bytes
-rw-r--r--test/reference/stride-12-image.ps.ref.pngbin0 -> 77159 bytes
-rw-r--r--test/reference/stride-12-image.ref.pngbin0 -> 81121 bytes
-rw-r--r--test/reference/stride-12-xlib-fallback.rgb24.ref.pngbin0 -> 81121 bytes
-rw-r--r--test/reference/stride-12-xlib-window.rgb24.ref.pngbin0 -> 81121 bytes
-rw-r--r--test/reference/stride-12-xlib.ref.pngbin0 -> 81121 bytes
-rw-r--r--test/reference/stroke-clipped.ref.pngbin0 -> 5845 bytes
-rw-r--r--test/reference/stroke-ctm-caps.base.argb32.ref.pngbin0 -> 835 bytes
-rw-r--r--test/reference/stroke-ctm-caps.base.rgb24.ref.pngbin0 -> 835 bytes
-rw-r--r--test/reference/stroke-ctm-caps.image16.ref.pngbin0 -> 908 bytes
-rw-r--r--test/reference/stroke-ctm-caps.mask.argb32.ref.pngbin0 -> 942 bytes
-rw-r--r--test/reference/stroke-ctm-caps.mask.rgb24.ref.pngbin0 -> 942 bytes
-rw-r--r--test/reference/stroke-ctm-caps.ps2.ref.pngbin0 -> 1079 bytes
-rw-r--r--test/reference/stroke-ctm-caps.ps3.ref.pngbin0 -> 1079 bytes
-rw-r--r--test/reference/stroke-ctm-caps.quartz.ref.pngbin0 -> 899 bytes
-rw-r--r--test/reference/stroke-ctm-caps.ref.pngbin0 -> 896 bytes
-rw-r--r--test/reference/stroke-ctm-caps.traps.argb32.ref.pngbin0 -> 835 bytes
-rw-r--r--test/reference/stroke-ctm-caps.traps.rgb24.ref.pngbin0 -> 835 bytes
-rw-r--r--test/reference/stroke-image.base.argb32.ref.pngbin0 -> 1467 bytes
-rw-r--r--test/reference/stroke-image.base.rgb24.ref.pngbin0 -> 1467 bytes
-rw-r--r--test/reference/stroke-image.image16.ref.pngbin0 -> 1167 bytes
-rw-r--r--test/reference/stroke-image.pdf.ref.pngbin0 -> 1006 bytes
-rw-r--r--test/reference/stroke-image.ps.ref.pngbin0 -> 1535 bytes
-rw-r--r--test/reference/stroke-image.quartz.ref.pngbin0 -> 1350 bytes
-rw-r--r--test/reference/stroke-image.ref.pngbin0 -> 1455 bytes
-rw-r--r--test/reference/stroke-image.traps.argb32.ref.pngbin0 -> 1467 bytes
-rw-r--r--test/reference/stroke-image.traps.rgb24.ref.pngbin0 -> 1467 bytes
-rw-r--r--test/reference/stroke-open-box.base.argb32.ref.pngbin0 -> 148 bytes
-rw-r--r--test/reference/stroke-open-box.base.rgb24.ref.pngbin0 -> 148 bytes
-rw-r--r--test/reference/stroke-open-box.ref.pngbin0 -> 148 bytes
-rw-r--r--test/reference/stroke-pattern.base.argb32.ref.pngbin0 -> 1487 bytes
-rw-r--r--test/reference/stroke-pattern.base.rgb24.ref.pngbin0 -> 1487 bytes
-rw-r--r--test/reference/stroke-pattern.ref.pngbin0 -> 1514 bytes
-rw-r--r--test/reference/stroke-pattern.traps.ref.pngbin0 -> 1487 bytes
-rw-r--r--test/reference/stroke-xlib-fallback.rgb24.ref.pngbin0 -> 1467 bytes
-rw-r--r--test/reference/stroke-xlib-window.rgb24.ref.pngbin0 -> 1467 bytes
-rw-r--r--test/reference/stroke-xlib.ref.pngbin0 -> 1467 bytes
-rw-r--r--test/reference/stroke.image.argb32.ref.pngbin0 -> 1479 bytes
-rw-r--r--test/reference/stroke.image.rgb24.ref.pngbin0 -> 1479 bytes
-rw-r--r--test/reference/subsurface-image-repeat.base.argb32.ref.pngbin0 -> 915 bytes
-rw-r--r--test/reference/subsurface-image-repeat.base.rgb24.ref.pngbin0 -> 915 bytes
-rw-r--r--test/reference/subsurface-image-repeat.image16.ref.pngbin0 -> 776 bytes
-rw-r--r--test/reference/subsurface-image-repeat.ref.pngbin0 -> 915 bytes
-rw-r--r--test/reference/subsurface-modify-child.base.argb32.ref.pngbin0 -> 197 bytes
-rw-r--r--test/reference/subsurface-modify-child.base.rgb24.ref.pngbin0 -> 197 bytes
-rw-r--r--test/reference/subsurface-modify-child.ref.pngbin0 -> 197 bytes
-rw-r--r--test/reference/subsurface-modify-parent.base.argb32.ref.pngbin0 -> 197 bytes
-rw-r--r--test/reference/subsurface-modify-parent.base.rgb24.ref.pngbin0 -> 197 bytes
-rw-r--r--test/reference/subsurface-modify-parent.ref.pngbin0 -> 197 bytes
-rw-r--r--test/reference/subsurface-outside-target.base.argb32.ref.pngbin0 -> 2063 bytes
-rw-r--r--test/reference/subsurface-outside-target.base.rgb24.ref.pngbin0 -> 1648 bytes
-rw-r--r--test/reference/subsurface-outside-target.ref.pngbin0 -> 2063 bytes
-rw-r--r--test/reference/subsurface-pad.base.argb32.ref.pngbin0 -> 181 bytes
-rw-r--r--test/reference/subsurface-pad.base.rgb24.ref.pngbin0 -> 181 bytes
-rw-r--r--test/reference/subsurface-pad.quartz.xfail.pngbin0 -> 197 bytes
-rw-r--r--test/reference/subsurface-pad.ref.pngbin0 -> 181 bytes
-rw-r--r--test/reference/subsurface-reflect.base.argb32.ref.pngbin0 -> 210 bytes
-rw-r--r--test/reference/subsurface-reflect.base.rgb24.ref.pngbin0 -> 210 bytes
-rw-r--r--test/reference/subsurface-reflect.ref.pngbin0 -> 210 bytes
-rw-r--r--test/reference/subsurface-repeat.base.argb32.ref.pngbin0 -> 197 bytes
-rw-r--r--test/reference/subsurface-repeat.base.rgb24.ref.pngbin0 -> 197 bytes
-rw-r--r--test/reference/subsurface-repeat.ref.pngbin0 -> 197 bytes
-rw-r--r--test/reference/subsurface-scale.base.argb32.ref.pngbin0 -> 5919 bytes
-rw-r--r--test/reference/subsurface-scale.base.rgb24.ref.pngbin0 -> 5919 bytes
-rw-r--r--test/reference/subsurface-scale.ref.pngbin0 -> 5921 bytes
-rw-r--r--test/reference/subsurface-scale.traps.argb32.ref.pngbin0 -> 5919 bytes
-rw-r--r--test/reference/subsurface-scale.traps.rgb24.ref.pngbin0 -> 5919 bytes
-rw-r--r--test/reference/subsurface-similar-repeat.base.argb32.ref.pngbin0 -> 197 bytes
-rw-r--r--test/reference/subsurface-similar-repeat.base.rgb24.ref.pngbin0 -> 197 bytes
-rw-r--r--test/reference/subsurface-similar-repeat.ref.pngbin0 -> 197 bytes
-rw-r--r--test/reference/subsurface.base.argb32.ref.pngbin0 -> 1801 bytes
-rw-r--r--test/reference/subsurface.base.rgb24.ref.pngbin0 -> 1801 bytes
-rw-r--r--test/reference/subsurface.image16.ref.pngbin0 -> 1643 bytes
-rw-r--r--test/reference/subsurface.ps.ref.pngbin0 -> 1651 bytes
-rw-r--r--test/reference/subsurface.ref.pngbin0 -> 1811 bytes
-rw-r--r--test/reference/subsurface.traps.argb32.ref.pngbin0 -> 1801 bytes
-rw-r--r--test/reference/subsurface.traps.rgb24.ref.pngbin0 -> 1801 bytes
-rw-r--r--test/reference/surface-pattern-big-scale-down.base.argb32.ref.pngbin0 -> 191 bytes
-rw-r--r--test/reference/surface-pattern-big-scale-down.base.rgb24.ref.pngbin0 -> 191 bytes
-rw-r--r--test/reference/surface-pattern-big-scale-down.ps.ref.pngbin0 -> 235 bytes
-rw-r--r--test/reference/surface-pattern-big-scale-down.quartz.ref.pngbin0 -> 258 bytes
-rw-r--r--test/reference/surface-pattern-big-scale-down.ref.pngbin0 -> 191 bytes
-rw-r--r--test/reference/surface-pattern-operator.argb32.ref.pngbin0 -> 5087 bytes
-rw-r--r--test/reference/surface-pattern-operator.base.argb32.ref.pngbin0 -> 5107 bytes
-rw-r--r--test/reference/surface-pattern-operator.base.rgb24.ref.pngbin0 -> 1913 bytes
-rw-r--r--test/reference/surface-pattern-operator.image16.ref.pngbin0 -> 1977 bytes
-rw-r--r--test/reference/surface-pattern-operator.pdf.argb32.xfail.pngbin0 -> 5485 bytes
-rw-r--r--test/reference/surface-pattern-operator.pdf.rgb24.xfail.pngbin0 -> 2095 bytes
-rw-r--r--test/reference/surface-pattern-operator.quartz.argb32.ref.pngbin0 -> 5721 bytes
-rw-r--r--test/reference/surface-pattern-operator.quartz.rgb24.ref.pngbin0 -> 2429 bytes
-rw-r--r--test/reference/surface-pattern-operator.rgb24.ref.pngbin0 -> 1919 bytes
-rw-r--r--test/reference/surface-pattern-operator.traps.argb32.ref.pngbin0 -> 5107 bytes
-rw-r--r--test/reference/surface-pattern-operator.traps.rgb24.ref.pngbin0 -> 1913 bytes
-rw-r--r--test/reference/surface-pattern-scale-down-extend-none.base.argb32.ref.pngbin0 -> 329 bytes
-rw-r--r--test/reference/surface-pattern-scale-down-extend-none.base.rgb24.ref.pngbin0 -> 329 bytes
-rw-r--r--test/reference/surface-pattern-scale-down-extend-none.quartz.ref.pngbin0 -> 391 bytes
-rw-r--r--test/reference/surface-pattern-scale-down-extend-none.ref.pngbin0 -> 329 bytes
-rw-r--r--test/reference/surface-pattern-scale-down-extend-pad.base.argb32.ref.pngbin0 -> 320 bytes
-rw-r--r--test/reference/surface-pattern-scale-down-extend-pad.base.rgb24.ref.pngbin0 -> 320 bytes
-rw-r--r--test/reference/surface-pattern-scale-down-extend-pad.quartz.xfail.pngbin0 -> 397 bytes
-rw-r--r--test/reference/surface-pattern-scale-down-extend-pad.ref.pngbin0 -> 320 bytes
-rw-r--r--test/reference/surface-pattern-scale-down-extend-reflect.base.argb32.ref.pngbin0 -> 328 bytes
-rw-r--r--test/reference/surface-pattern-scale-down-extend-reflect.base.rgb24.ref.pngbin0 -> 328 bytes
-rw-r--r--test/reference/surface-pattern-scale-down-extend-reflect.quartz.ref.pngbin0 -> 475 bytes
-rw-r--r--test/reference/surface-pattern-scale-down-extend-reflect.ref.pngbin0 -> 328 bytes
-rw-r--r--test/reference/surface-pattern-scale-down-extend-repeat.base.argb32.ref.pngbin0 -> 330 bytes
-rw-r--r--test/reference/surface-pattern-scale-down-extend-repeat.base.rgb24.ref.pngbin0 -> 330 bytes
-rw-r--r--test/reference/surface-pattern-scale-down-extend-repeat.quartz.ref.pngbin0 -> 397 bytes
-rw-r--r--test/reference/surface-pattern-scale-down-extend-repeat.ref.pngbin0 -> 330 bytes
-rw-r--r--test/reference/surface-pattern-scale-down.base.argb32.ref.pngbin0 -> 1326 bytes
-rw-r--r--test/reference/surface-pattern-scale-down.base.rgb24.ref.pngbin0 -> 1326 bytes
-rw-r--r--test/reference/surface-pattern-scale-down.image16.ref.pngbin0 -> 1313 bytes
-rw-r--r--test/reference/surface-pattern-scale-down.pdf.ref.pngbin0 -> 2189 bytes
-rw-r--r--test/reference/surface-pattern-scale-down.ps2.ref.pngbin0 -> 1324 bytes
-rw-r--r--test/reference/surface-pattern-scale-down.ps3.ref.pngbin0 -> 1324 bytes
-rw-r--r--test/reference/surface-pattern-scale-down.quartz.ref.pngbin0 -> 2276 bytes
-rw-r--r--test/reference/surface-pattern-scale-down.ref.pngbin0 -> 1326 bytes
-rw-r--r--test/reference/surface-pattern-scale-up.base.argb32.ref.pngbin0 -> 4020 bytes
-rw-r--r--test/reference/surface-pattern-scale-up.base.rgb24.ref.pngbin0 -> 4020 bytes
-rw-r--r--test/reference/surface-pattern-scale-up.image16.ref.pngbin0 -> 3864 bytes
-rw-r--r--test/reference/surface-pattern-scale-up.pdf.ref.pngbin0 -> 3482 bytes
-rw-r--r--test/reference/surface-pattern-scale-up.ps2.ref.pngbin0 -> 913 bytes
-rw-r--r--test/reference/surface-pattern-scale-up.ps3.ref.pngbin0 -> 913 bytes
-rw-r--r--test/reference/surface-pattern-scale-up.quartz.xfail.pngbin0 -> 3294 bytes
-rw-r--r--test/reference/surface-pattern-scale-up.ref.pngbin0 -> 4020 bytes
-rw-r--r--test/reference/surface-pattern.base.argb32.ref.pngbin0 -> 11088 bytes
-rw-r--r--test/reference/surface-pattern.base.rgb24.ref.pngbin0 -> 11088 bytes
-rw-r--r--test/reference/surface-pattern.image16.ref.pngbin0 -> 11870 bytes
-rw-r--r--test/reference/surface-pattern.pdf.xfail.pngbin0 -> 10532 bytes
-rw-r--r--test/reference/surface-pattern.ps.xfail.pngbin0 -> 2188 bytes
-rw-r--r--test/reference/surface-pattern.quartz.xfail.pngbin0 -> 9216 bytes
-rw-r--r--test/reference/surface-pattern.ref.pngbin0 -> 11088 bytes
-rw-r--r--test/reference/surface-pattern.svg.xfail.pngbin0 -> 16069 bytes
-rw-r--r--test/reference/svg-surface-source.base.argb32.ref.pngbin0 -> 377 bytes
-rw-r--r--test/reference/svg-surface-source.base.rgb24.ref.pngbin0 -> 301 bytes
-rw-r--r--test/reference/svg-surface-source.image16.ref.pngbin0 -> 305 bytes
-rw-r--r--test/reference/svg-surface-source.ref.pngbin0 -> 377 bytes
-rw-r--r--test/reference/svg-surface-source.svg12.argb32.xfail.pngbin0 -> 278 bytes
-rw-r--r--test/reference/svg-surface-source.svg12.rgb24.xfail.pngbin0 -> 278 bytes
-rw-r--r--test/reference/text-antialias-gray.base.argb32.ref.pngbin0 -> 966 bytes
-rw-r--r--test/reference/text-antialias-gray.base.rgb24.ref.pngbin0 -> 966 bytes
-rw-r--r--test/reference/text-antialias-gray.image16.ref.pngbin0 -> 895 bytes
-rw-r--r--test/reference/text-antialias-gray.quartz.ref.pngbin0 -> 956 bytes
-rw-r--r--test/reference/text-antialias-gray.ref.pngbin0 -> 966 bytes
-rw-r--r--test/reference/text-antialias-gray.traps.ref.pngbin0 -> 966 bytes
-rw-r--r--test/reference/text-antialias-none.base.argb32.ref.pngbin0 -> 265 bytes
-rw-r--r--test/reference/text-antialias-none.base.rgb24.ref.pngbin0 -> 265 bytes
-rw-r--r--test/reference/text-antialias-none.quartz.ref.pngbin0 -> 270 bytes
-rw-r--r--test/reference/text-antialias-none.ref.pngbin0 -> 298 bytes
-rw-r--r--test/reference/text-antialias-subpixel-bgr.base.argb32.ref.pngbin0 -> 917 bytes
-rw-r--r--test/reference/text-antialias-subpixel-bgr.base.rgb24.ref.pngbin0 -> 917 bytes
-rw-r--r--test/reference/text-antialias-subpixel-bgr.image16.ref.pngbin0 -> 863 bytes
-rw-r--r--test/reference/text-antialias-subpixel-bgr.mask.argb32.ref.pngbin0 -> 917 bytes
-rw-r--r--test/reference/text-antialias-subpixel-bgr.mask.rgb24.ref.pngbin0 -> 917 bytes
-rw-r--r--test/reference/text-antialias-subpixel-bgr.ref.pngbin0 -> 1124 bytes
-rw-r--r--test/reference/text-antialias-subpixel-bgr.traps.ref.pngbin0 -> 1005 bytes
-rw-r--r--test/reference/text-antialias-subpixel-rgb.base.argb32.ref.pngbin0 -> 917 bytes
-rw-r--r--test/reference/text-antialias-subpixel-rgb.base.rgb24.ref.pngbin0 -> 917 bytes
-rw-r--r--test/reference/text-antialias-subpixel-rgb.image16.ref.pngbin0 -> 863 bytes
-rw-r--r--test/reference/text-antialias-subpixel-rgb.mask.argb32.ref.pngbin0 -> 917 bytes
-rw-r--r--test/reference/text-antialias-subpixel-rgb.mask.rgb24.ref.pngbin0 -> 917 bytes
-rw-r--r--test/reference/text-antialias-subpixel-rgb.ref.pngbin0 -> 1109 bytes
-rw-r--r--test/reference/text-antialias-subpixel-rgb.traps.ref.pngbin0 -> 1013 bytes
-rw-r--r--test/reference/text-antialias-subpixel-vbgr.base.argb32.ref.pngbin0 -> 932 bytes
-rw-r--r--test/reference/text-antialias-subpixel-vbgr.base.rgb24.ref.pngbin0 -> 932 bytes
-rw-r--r--test/reference/text-antialias-subpixel-vbgr.image16.ref.pngbin0 -> 864 bytes
-rw-r--r--test/reference/text-antialias-subpixel-vbgr.mask.argb32.ref.pngbin0 -> 932 bytes
-rw-r--r--test/reference/text-antialias-subpixel-vbgr.mask.rgb24.ref.pngbin0 -> 932 bytes
-rw-r--r--test/reference/text-antialias-subpixel-vbgr.ref.pngbin0 -> 1205 bytes
-rw-r--r--test/reference/text-antialias-subpixel-vbgr.traps.ref.pngbin0 -> 985 bytes
-rw-r--r--test/reference/text-antialias-subpixel-vrgb.base.argb32.ref.pngbin0 -> 932 bytes
-rw-r--r--test/reference/text-antialias-subpixel-vrgb.base.rgb24.ref.pngbin0 -> 932 bytes
-rw-r--r--test/reference/text-antialias-subpixel-vrgb.image16.ref.pngbin0 -> 862 bytes
-rw-r--r--test/reference/text-antialias-subpixel-vrgb.mask.argb32.ref.pngbin0 -> 932 bytes
-rw-r--r--test/reference/text-antialias-subpixel-vrgb.mask.rgb24.ref.pngbin0 -> 932 bytes
-rw-r--r--test/reference/text-antialias-subpixel-vrgb.ref.pngbin0 -> 1180 bytes
-rw-r--r--test/reference/text-antialias-subpixel-vrgb.traps.ref.pngbin0 -> 1009 bytes
-rw-r--r--test/reference/text-antialias-subpixel.base.argb32.ref.pngbin0 -> 917 bytes
-rw-r--r--test/reference/text-antialias-subpixel.base.argb32.xfail.pngbin0 -> 925 bytes
-rw-r--r--test/reference/text-antialias-subpixel.base.rgb24.ref.pngbin0 -> 917 bytes
-rw-r--r--test/reference/text-antialias-subpixel.base.rgb24.xfail.pngbin0 -> 925 bytes
-rw-r--r--test/reference/text-antialias-subpixel.image16.ref.pngbin0 -> 866 bytes
-rw-r--r--test/reference/text-antialias-subpixel.mask.argb32.ref.pngbin0 -> 917 bytes
-rw-r--r--test/reference/text-antialias-subpixel.mask.rgb24.ref.pngbin0 -> 917 bytes
-rw-r--r--test/reference/text-antialias-subpixel.quartz.ref.pngbin0 -> 949 bytes
-rw-r--r--test/reference/text-antialias-subpixel.ref.pngbin0 -> 1109 bytes
-rw-r--r--test/reference/text-antialias-subpixel.traps.ref.pngbin0 -> 1013 bytes
-rw-r--r--test/reference/text-glyph-range.base.argb32.ref.pngbin0 -> 1979 bytes
-rw-r--r--test/reference/text-glyph-range.base.rgb24.ref.pngbin0 -> 1979 bytes
-rw-r--r--test/reference/text-glyph-range.image16.ref.pngbin0 -> 1731 bytes
-rw-r--r--test/reference/text-glyph-range.ps.ref.pngbin0 -> 1253 bytes
-rw-r--r--test/reference/text-glyph-range.quartz.ref.pngbin0 -> 2191 bytes
-rw-r--r--test/reference/text-glyph-range.ref.pngbin0 -> 1928 bytes
-rw-r--r--test/reference/text-glyph-range.traps.ref.pngbin0 -> 1979 bytes
-rw-r--r--test/reference/text-pattern.base.argb32.ref.pngbin0 -> 3497 bytes
-rw-r--r--test/reference/text-pattern.base.rgb24.ref.pngbin0 -> 2707 bytes
-rw-r--r--test/reference/text-pattern.pdf.argb32.ref.pngbin0 -> 1515 bytes
-rw-r--r--test/reference/text-pattern.pdf.rgb24.ref.pngbin0 -> 1339 bytes
-rw-r--r--test/reference/text-pattern.ps2.argb32.ref.pngbin0 -> 1646 bytes
-rw-r--r--test/reference/text-pattern.ps2.rgb24.ref.pngbin0 -> 1646 bytes
-rw-r--r--test/reference/text-pattern.ps3.argb32.ref.pngbin0 -> 881 bytes
-rw-r--r--test/reference/text-pattern.ps3.rgb24.ref.pngbin0 -> 862 bytes
-rw-r--r--test/reference/text-pattern.quartz.argb32.ref.pngbin0 -> 2148 bytes
-rw-r--r--test/reference/text-pattern.quartz.rgb24.ref.pngbin0 -> 1867 bytes
-rw-r--r--test/reference/text-pattern.ref.pngbin0 -> 3455 bytes
-rw-r--r--test/reference/text-pattern.svg.argb32.ref.pngbin0 -> 1745 bytes
-rw-r--r--test/reference/text-pattern.svg.rgb24.ref.pngbin0 -> 1453 bytes
-rw-r--r--test/reference/text-pattern.traps.argb32.ref.pngbin0 -> 3497 bytes
-rw-r--r--test/reference/text-pattern.traps.rgb24.ref.pngbin0 -> 2707 bytes
-rw-r--r--test/reference/text-rotate.base.argb32.ref.pngbin0 -> 16597 bytes
-rw-r--r--test/reference/text-rotate.base.rgb24.ref.pngbin0 -> 16597 bytes
-rw-r--r--test/reference/text-rotate.image16.ref.pngbin0 -> 12599 bytes
-rw-r--r--test/reference/text-rotate.mask.argb32.ref.pngbin0 -> 16655 bytes
-rw-r--r--test/reference/text-rotate.mask.rgb24.ref.pngbin0 -> 16655 bytes
-rw-r--r--test/reference/text-rotate.pdf.ref.pngbin0 -> 16744 bytes
-rw-r--r--test/reference/text-rotate.ps.ref.pngbin0 -> 8765 bytes
-rw-r--r--test/reference/text-rotate.quartz.ref.pngbin0 -> 16655 bytes
-rw-r--r--test/reference/text-rotate.ref.pngbin0 -> 16356 bytes
-rw-r--r--test/reference/text-rotate.svg.ref.pngbin0 -> 17118 bytes
-rw-r--r--test/reference/text-rotate.traps.ref.pngbin0 -> 16597 bytes
-rw-r--r--test/reference/text-rotate.xlib-fallback.ref.pngbin0 -> 16592 bytes
-rw-r--r--test/reference/text-transform.base.argb32.ref.pngbin0 -> 5579 bytes
-rw-r--r--test/reference/text-transform.base.rgb24.ref.pngbin0 -> 5579 bytes
-rw-r--r--test/reference/text-transform.image16.ref.pngbin0 -> 4469 bytes
-rw-r--r--test/reference/text-transform.pdf.argb32.ref.pngbin0 -> 5507 bytes
-rw-r--r--test/reference/text-transform.pdf.rgb24.ref.pngbin0 -> 5507 bytes
-rw-r--r--test/reference/text-transform.ps2.ref.pngbin0 -> 3943 bytes
-rw-r--r--test/reference/text-transform.ps3.ref.pngbin0 -> 3943 bytes
-rw-r--r--test/reference/text-transform.ref.pngbin0 -> 6200 bytes
-rw-r--r--test/reference/text-transform.svg.ref.pngbin0 -> 5682 bytes
-rw-r--r--test/reference/tiger.base.argb32.ref.pngbin0 -> 94370 bytes
-rw-r--r--test/reference/tiger.base.rgb24.ref.pngbin0 -> 94370 bytes
-rw-r--r--test/reference/tiger.ref.pngbin0 -> 94477 bytes
-rw-r--r--test/reference/tiger.traps.argb32.ref.pngbin0 -> 94370 bytes
-rw-r--r--test/reference/tiger.traps.rgb24.ref.pngbin0 -> 94370 bytes
-rw-r--r--test/reference/tighten-bounds.argb32.ref.pngbin0 -> 8997 bytes
-rw-r--r--test/reference/tighten-bounds.base.argb32.ref.pngbin0 -> 8512 bytes
-rw-r--r--test/reference/tighten-bounds.base.rgb24.ref.pngbin0 -> 7873 bytes
-rw-r--r--test/reference/tighten-bounds.rgb24.ref.pngbin0 -> 8450 bytes
-rw-r--r--test/reference/tighten-bounds.traps.argb32.ref.pngbin0 -> 8486 bytes
-rw-r--r--test/reference/tighten-bounds.traps.rgb24.ref.pngbin0 -> 7856 bytes
-rw-r--r--test/reference/transforms.base.argb32.ref.pngbin0 -> 299 bytes
-rw-r--r--test/reference/transforms.base.rgb24.ref.pngbin0 -> 299 bytes
-rw-r--r--test/reference/transforms.image16.ref.pngbin0 -> 326 bytes
-rw-r--r--test/reference/transforms.ps2.ref.pngbin0 -> 418 bytes
-rw-r--r--test/reference/transforms.ps3.ref.pngbin0 -> 418 bytes
-rw-r--r--test/reference/transforms.ref.pngbin0 -> 348 bytes
-rw-r--r--test/reference/transforms.traps.argb32.ref.pngbin0 -> 299 bytes
-rw-r--r--test/reference/transforms.traps.rgb24.ref.pngbin0 -> 299 bytes
-rw-r--r--test/reference/translate-show-surface.base.argb32.ref.pngbin0 -> 96 bytes
-rw-r--r--test/reference/translate-show-surface.base.rgb24.ref.pngbin0 -> 96 bytes
-rw-r--r--test/reference/translate-show-surface.ref.pngbin0 -> 100 bytes
-rw-r--r--test/reference/trap-clip.argb32.ref.pngbin0 -> 5822 bytes
-rw-r--r--test/reference/trap-clip.base.argb32.ref.pngbin0 -> 5651 bytes
-rw-r--r--test/reference/trap-clip.base.rgb24.ref.pngbin0 -> 5351 bytes
-rw-r--r--test/reference/trap-clip.image16.ref.pngbin0 -> 4344 bytes
-rw-r--r--test/reference/trap-clip.mask.argb32.ref.pngbin0 -> 6162 bytes
-rw-r--r--test/reference/trap-clip.mask.rgb24.ref.pngbin0 -> 5606 bytes
-rw-r--r--test/reference/trap-clip.ps2.argb32.ref.pngbin0 -> 4839 bytes
-rw-r--r--test/reference/trap-clip.ps2.rgb24.ref.pngbin0 -> 4729 bytes
-rw-r--r--test/reference/trap-clip.ps3.argb32.ref.pngbin0 -> 4751 bytes
-rw-r--r--test/reference/trap-clip.ps3.rgb24.ref.pngbin0 -> 4553 bytes
-rw-r--r--test/reference/trap-clip.quartz.argb32.ref.pngbin0 -> 6115 bytes
-rw-r--r--test/reference/trap-clip.quartz.rgb24.ref.pngbin0 -> 5801 bytes
-rw-r--r--test/reference/trap-clip.rgb24.ref.pngbin0 -> 5422 bytes
-rw-r--r--test/reference/trap-clip.test-paginated.argb32.ref.pngbin0 -> 5898 bytes
-rw-r--r--test/reference/trap-clip.traps.argb32.ref.pngbin0 -> 5755 bytes
-rw-r--r--test/reference/trap-clip.traps.rgb24.ref.pngbin0 -> 5379 bytes
-rw-r--r--test/reference/twin-antialias-gray.base.argb32.ref.pngbin0 -> 4320 bytes
-rw-r--r--test/reference/twin-antialias-gray.base.rgb24.ref.pngbin0 -> 4320 bytes
-rw-r--r--test/reference/twin-antialias-gray.image16.ref.pngbin0 -> 3005 bytes
-rw-r--r--test/reference/twin-antialias-gray.mask.argb32.ref.pngbin0 -> 3990 bytes
-rw-r--r--test/reference/twin-antialias-gray.mask.rgb24.ref.pngbin0 -> 3990 bytes
-rw-r--r--test/reference/twin-antialias-gray.ref.pngbin0 -> 3536 bytes
-rw-r--r--test/reference/twin-antialias-gray.traps.argb32.ref.pngbin0 -> 4320 bytes
-rw-r--r--test/reference/twin-antialias-gray.traps.rgb24.ref.pngbin0 -> 4320 bytes
-rw-r--r--test/reference/twin-antialias-mixed.base.argb32.ref.pngbin0 -> 2340 bytes
-rw-r--r--test/reference/twin-antialias-mixed.base.rgb24.ref.pngbin0 -> 2340 bytes
-rw-r--r--test/reference/twin-antialias-mixed.image16.ref.pngbin0 -> 2049 bytes
-rw-r--r--test/reference/twin-antialias-mixed.ref.pngbin0 -> 2392 bytes
-rw-r--r--test/reference/twin-antialias-mixed.traps.argb32.ref.pngbin0 -> 2340 bytes
-rw-r--r--test/reference/twin-antialias-mixed.traps.rgb24.ref.pngbin0 -> 2340 bytes
-rw-r--r--test/reference/twin-antialias-none.base.argb32.ref.pngbin0 -> 738 bytes
-rw-r--r--test/reference/twin-antialias-none.base.rgb24.ref.pngbin0 -> 738 bytes
-rw-r--r--test/reference/twin-antialias-none.ref.pngbin0 -> 688 bytes
-rw-r--r--test/reference/twin-antialias-none.traps.argb32.ref.pngbin0 -> 738 bytes
-rw-r--r--test/reference/twin-antialias-none.traps.rgb24.ref.pngbin0 -> 738 bytes
-rw-r--r--test/reference/twin-antialias-subpixel.base.argb32.ref.pngbin0 -> 4320 bytes
-rw-r--r--test/reference/twin-antialias-subpixel.base.rgb24.ref.pngbin0 -> 4320 bytes
-rw-r--r--test/reference/twin-antialias-subpixel.image16.ref.pngbin0 -> 3005 bytes
-rw-r--r--test/reference/twin-antialias-subpixel.mask.argb32.ref.pngbin0 -> 3990 bytes
-rw-r--r--test/reference/twin-antialias-subpixel.mask.rgb24.ref.pngbin0 -> 3990 bytes
-rw-r--r--test/reference/twin-antialias-subpixel.ref.pngbin0 -> 3536 bytes
-rw-r--r--test/reference/twin-antialias-subpixel.traps.argb32.ref.pngbin0 -> 4320 bytes
-rw-r--r--test/reference/twin-antialias-subpixel.traps.rgb24.ref.pngbin0 -> 4320 bytes
-rw-r--r--test/reference/twin.base.argb32.ref.pngbin0 -> 4320 bytes
-rw-r--r--test/reference/twin.base.rgb24.ref.pngbin0 -> 4320 bytes
-rw-r--r--test/reference/twin.image16.ref.pngbin0 -> 3005 bytes
-rw-r--r--test/reference/twin.mask.argb32.ref.pngbin0 -> 3990 bytes
-rw-r--r--test/reference/twin.mask.rgb24.ref.pngbin0 -> 3990 bytes
-rw-r--r--test/reference/twin.ps.ref.pngbin0 -> 2136 bytes
-rw-r--r--test/reference/twin.ref.pngbin0 -> 3536 bytes
-rw-r--r--test/reference/twin.svg.ref.pngbin0 -> 3040 bytes
-rw-r--r--test/reference/twin.traps.argb32.ref.pngbin0 -> 4320 bytes
-rw-r--r--test/reference/twin.traps.rgb24.ref.pngbin0 -> 4320 bytes
-rw-r--r--test/reference/unaligned-box.base.argb32.ref.pngbin0 -> 526 bytes
-rw-r--r--test/reference/unaligned-box.base.rgb24.ref.pngbin0 -> 526 bytes
-rw-r--r--test/reference/unaligned-box.ref.pngbin0 -> 496 bytes
-rw-r--r--test/reference/unaligned-box.traps.argb32.ref.pngbin0 -> 526 bytes
-rw-r--r--test/reference/unaligned-box.traps.rgb24.ref.pngbin0 -> 526 bytes
-rw-r--r--test/reference/unantialiased-shapes.base.argb32.ref.pngbin0 -> 3977 bytes
-rw-r--r--test/reference/unantialiased-shapes.base.rgb24.ref.pngbin0 -> 3977 bytes
-rw-r--r--test/reference/unantialiased-shapes.quartz.ref.pngbin0 -> 3868 bytes
-rw-r--r--test/reference/unantialiased-shapes.ref.pngbin0 -> 3926 bytes
-rw-r--r--test/reference/unantialiased-shapes.traps.argb32.ref.pngbin0 -> 3932 bytes
-rw-r--r--test/reference/unantialiased-shapes.traps.rgb24.ref.pngbin0 -> 3932 bytes
-rw-r--r--test/reference/unbounded-operator.argb32.ref.pngbin0 -> 2744 bytes
-rw-r--r--test/reference/unbounded-operator.base.argb32.ref.pngbin0 -> 2764 bytes
-rw-r--r--test/reference/unbounded-operator.base.rgb24.ref.pngbin0 -> 1302 bytes
-rw-r--r--test/reference/unbounded-operator.gl.argb32.xfail.pngbin0 -> 2805 bytes
-rw-r--r--test/reference/unbounded-operator.gl.rgb24.xfail.pngbin0 -> 1355 bytes
-rw-r--r--test/reference/unbounded-operator.image16.ref.pngbin0 -> 1276 bytes
-rw-r--r--test/reference/unbounded-operator.mask.argb32.ref.pngbin0 -> 2666 bytes
-rw-r--r--test/reference/unbounded-operator.mask.rgb24.ref.pngbin0 -> 1300 bytes
-rw-r--r--test/reference/unbounded-operator.pdf.argb32.ref.pngbin0 -> 2713 bytes
-rw-r--r--test/reference/unbounded-operator.ps2.argb32.ref.pngbin0 -> 2713 bytes
-rw-r--r--test/reference/unbounded-operator.ps3.argb32.ref.pngbin0 -> 2713 bytes
-rw-r--r--test/reference/unbounded-operator.quartz.argb32.ref.pngbin0 -> 3509 bytes
-rw-r--r--test/reference/unbounded-operator.quartz.rgb24.ref.pngbin0 -> 1657 bytes
-rw-r--r--test/reference/unbounded-operator.rgb24.ref.pngbin0 -> 1303 bytes
-rw-r--r--test/reference/unbounded-operator.svg12.argb32.ref.pngbin0 -> 2767 bytes
-rw-r--r--test/reference/unbounded-operator.svg12.rgb24.xfail.pngbin0 -> 1731 bytes
-rw-r--r--test/reference/unbounded-operator.traps.argb32.ref.pngbin0 -> 2764 bytes
-rw-r--r--test/reference/unbounded-operator.traps.rgb24.ref.pngbin0 -> 1302 bytes
-rw-r--r--test/reference/unclosed-strokes.base.argb32.ref.pngbin0 -> 1452 bytes
-rw-r--r--test/reference/unclosed-strokes.base.rgb24.ref.pngbin0 -> 1452 bytes
-rw-r--r--test/reference/unclosed-strokes.ref.pngbin0 -> 1588 bytes
-rw-r--r--test/reference/unclosed-strokes.traps.argb32.ref.pngbin0 -> 1452 bytes
-rw-r--r--test/reference/unclosed-strokes.traps.rgb24.ref.pngbin0 -> 1452 bytes
-rw-r--r--test/reference/user-font-mask.base.argb32.ref.pngbin0 -> 5476 bytes
-rw-r--r--test/reference/user-font-mask.base.rgb24.ref.pngbin0 -> 5476 bytes
-rw-r--r--test/reference/user-font-mask.image16.ref.pngbin0 -> 4948 bytes
-rw-r--r--test/reference/user-font-mask.pdf.ref.pngbin0 -> 1927 bytes
-rw-r--r--test/reference/user-font-mask.ps2.ref.pngbin0 -> 1927 bytes
-rw-r--r--test/reference/user-font-mask.ps3.ref.pngbin0 -> 1927 bytes
-rw-r--r--test/reference/user-font-mask.ref.pngbin0 -> 5476 bytes
-rw-r--r--test/reference/user-font-mask.svg.ref.pngbin0 -> 2030 bytes
-rw-r--r--test/reference/user-font-proxy.base.argb32.ref.pngbin0 -> 16854 bytes
-rw-r--r--test/reference/user-font-proxy.base.rgb24.ref.pngbin0 -> 16854 bytes
-rw-r--r--test/reference/user-font-proxy.image16.ref.pngbin0 -> 14460 bytes
-rw-r--r--test/reference/user-font-proxy.pdf.argb32.ref.pngbin0 -> 16937 bytes
-rw-r--r--test/reference/user-font-proxy.pdf.ref.pngbin0 -> 18111 bytes
-rw-r--r--test/reference/user-font-proxy.pdf.rgb24.ref.pngbin0 -> 16937 bytes
-rw-r--r--test/reference/user-font-proxy.ps.ref.pngbin0 -> 7837 bytes
-rw-r--r--test/reference/user-font-proxy.quartz.ref.pngbin0 -> 19795 bytes
-rw-r--r--test/reference/user-font-proxy.ref.pngbin0 -> 16981 bytes
-rw-r--r--test/reference/user-font-proxy.svg.ref.pngbin0 -> 16814 bytes
-rw-r--r--test/reference/user-font-proxy.traps.ref.pngbin0 -> 16854 bytes
-rw-r--r--test/reference/user-font-rescale.base.argb32.ref.pngbin0 -> 14883 bytes
-rw-r--r--test/reference/user-font-rescale.base.rgb24.ref.pngbin0 -> 14883 bytes
-rw-r--r--test/reference/user-font-rescale.image16.ref.pngbin0 -> 12590 bytes
-rw-r--r--test/reference/user-font-rescale.ps.ref.pngbin0 -> 6781 bytes
-rw-r--r--test/reference/user-font-rescale.quartz.ref.pngbin0 -> 15982 bytes
-rw-r--r--test/reference/user-font-rescale.ref.pngbin0 -> 14883 bytes
-rw-r--r--test/reference/user-font-rescale.svg.ref.pngbin0 -> 14873 bytes
-rw-r--r--test/reference/user-font-rescale.traps.ref.pngbin0 -> 14883 bytes
-rw-r--r--test/reference/user-font.base.argb32.ref.pngbin0 -> 5785 bytes
-rw-r--r--test/reference/user-font.base.rgb24.ref.pngbin0 -> 5785 bytes
-rw-r--r--test/reference/user-font.image16.ref.pngbin0 -> 5814 bytes
-rw-r--r--test/reference/user-font.mask.argb32.ref.pngbin0 -> 6478 bytes
-rw-r--r--test/reference/user-font.mask.rgb24.ref.pngbin0 -> 6478 bytes
-rw-r--r--test/reference/user-font.pdf.ref.pngbin0 -> 6241 bytes
-rw-r--r--test/reference/user-font.ps.ref.pngbin0 -> 4605 bytes
-rw-r--r--test/reference/user-font.quartz.ref.pngbin0 -> 5960 bytes
-rw-r--r--test/reference/user-font.ref.pngbin0 -> 5875 bytes
-rw-r--r--test/reference/user-font.svg.ref.pngbin0 -> 6379 bytes
-rw-r--r--test/reference/user-font.traps.argb32.ref.pngbin0 -> 5785 bytes
-rw-r--r--test/reference/user-font.traps.rgb24.ref.pngbin0 -> 5785 bytes
-rw-r--r--test/reference/white-in-noop.base.argb32.ref.pngbin0 -> 95 bytes
-rw-r--r--test/reference/white-in-noop.base.rgb24.ref.pngbin0 -> 95 bytes
-rw-r--r--test/reference/white-in-noop.ref.pngbin0 -> 95 bytes
-rw-r--r--test/reference/world-map-fill.base.argb32.ref.pngbin0 -> 57451 bytes
-rw-r--r--test/reference/world-map-fill.base.rgb24.ref.pngbin0 -> 57451 bytes
-rw-r--r--test/reference/world-map-fill.image16.ref.pngbin0 -> 36582 bytes
-rw-r--r--test/reference/world-map-fill.ref.pngbin0 -> 57407 bytes
-rw-r--r--test/reference/world-map-fill.traps.argb32.ref.pngbin0 -> 57451 bytes
-rw-r--r--test/reference/world-map-fill.traps.rgb24.ref.pngbin0 -> 57451 bytes
-rw-r--r--test/reference/world-map-stroke.base.argb32.ref.pngbin0 -> 65217 bytes
-rw-r--r--test/reference/world-map-stroke.base.rgb24.ref.pngbin0 -> 65217 bytes
-rw-r--r--test/reference/world-map-stroke.image16.ref.pngbin0 -> 41885 bytes
-rw-r--r--test/reference/world-map-stroke.mask.argb32.ref.pngbin0 -> 65149 bytes
-rw-r--r--test/reference/world-map-stroke.mask.rgb24.ref.pngbin0 -> 65149 bytes
-rw-r--r--test/reference/world-map-stroke.ref.pngbin0 -> 65152 bytes
-rw-r--r--test/reference/world-map-stroke.traps.argb32.ref.pngbin0 -> 65217 bytes
-rw-r--r--test/reference/world-map-stroke.traps.rgb24.ref.pngbin0 -> 65217 bytes
-rw-r--r--test/reference/world-map.base.argb32.ref.pngbin0 -> 70536 bytes
-rw-r--r--test/reference/world-map.base.rgb24.ref.pngbin0 -> 70536 bytes
-rw-r--r--test/reference/world-map.image16.ref.pngbin0 -> 48377 bytes
-rw-r--r--test/reference/world-map.mask.argb32.ref.pngbin0 -> 70474 bytes
-rw-r--r--test/reference/world-map.mask.rgb24.ref.pngbin0 -> 70474 bytes
-rw-r--r--test/reference/world-map.ref.pngbin0 -> 70463 bytes
-rw-r--r--test/reference/world-map.traps.argb32.ref.pngbin0 -> 70536 bytes
-rw-r--r--test/reference/world-map.traps.rgb24.ref.pngbin0 -> 70536 bytes
-rw-r--r--test/reference/xcb-huge-image-shm.base.argb32.ref.pngbin0 -> 97 bytes
-rw-r--r--test/reference/xcb-huge-image-shm.base.rgb24.ref.pngbin0 -> 97 bytes
-rw-r--r--test/reference/xcb-huge-image-shm.ref.pngbin0 -> 97 bytes
-rw-r--r--test/reference/xcb-huge-subimage.ref.pngbin0 -> 97 bytes
-rw-r--r--test/reference/xcb-snapshot-assert.base.argb32.ref.pngbin0 -> 97 bytes
-rw-r--r--test/reference/xcb-snapshot-assert.base.rgb24.ref.pngbin0 -> 97 bytes
-rw-r--r--test/reference/xcb-snapshot-assert.ref.pngbin0 -> 97 bytes
-rw-r--r--test/reference/xcb-stress-cache.base.argb32.ref.pngbin0 -> 97 bytes
-rw-r--r--test/reference/xcb-stress-cache.base.rgb24.ref.pngbin0 -> 97 bytes
-rw-r--r--test/reference/xcb-stress-cache.ref.pngbin0 -> 97 bytes
-rw-r--r--test/reference/xcb-surface-source.base.argb32.ref.pngbin0 -> 377 bytes
-rw-r--r--test/reference/xcb-surface-source.base.rgb24.ref.pngbin0 -> 301 bytes
-rw-r--r--test/reference/xcb-surface-source.image16.ref.pngbin0 -> 305 bytes
-rw-r--r--test/reference/xcb-surface-source.ps.argb32.ref.pngbin0 -> 491 bytes
-rw-r--r--test/reference/xcb-surface-source.ps.rgb24.ref.pngbin0 -> 482 bytes
-rw-r--r--test/reference/xcb-surface-source.ref.pngbin0 -> 377 bytes
-rw-r--r--test/reference/xcomposite-projection.base.argb32.ref.pngbin0 -> 1112 bytes
-rw-r--r--test/reference/xcomposite-projection.base.rgb24.ref.pngbin0 -> 1112 bytes
-rw-r--r--test/reference/xcomposite-projection.image16.ref.pngbin0 -> 1000 bytes
-rw-r--r--test/reference/xcomposite-projection.mask.argb32.ref.pngbin0 -> 1109 bytes
-rw-r--r--test/reference/xcomposite-projection.mask.rgb24.ref.pngbin0 -> 1109 bytes
-rw-r--r--test/reference/xcomposite-projection.quartz.ref.pngbin0 -> 926 bytes
-rw-r--r--test/reference/xcomposite-projection.ref.pngbin0 -> 1108 bytes
-rw-r--r--test/reference/xcomposite-projection.traps.argb32.ref.pngbin0 -> 1112 bytes
-rw-r--r--test/reference/xcomposite-projection.traps.rgb24.ref.pngbin0 -> 1112 bytes
-rw-r--r--test/reference/xlib-expose-event.base.argb32.ref.pngbin0 -> 40717 bytes
-rw-r--r--test/reference/xlib-expose-event.base.rgb24.ref.pngbin0 -> 40717 bytes
-rw-r--r--test/reference/xlib-expose-event.image16.ref.pngbin0 -> 30332 bytes
-rw-r--r--test/reference/xlib-expose-event.ps.ref.pngbin0 -> 39035 bytes
-rw-r--r--test/reference/xlib-expose-event.ref.pngbin0 -> 40736 bytes
-rw-r--r--test/reference/xlib-surface-source.base.argb32.ref.pngbin0 -> 377 bytes
-rw-r--r--test/reference/xlib-surface-source.base.rgb24.ref.pngbin0 -> 301 bytes
-rw-r--r--test/reference/xlib-surface-source.image16.ref.pngbin0 -> 305 bytes
-rw-r--r--test/reference/xlib-surface-source.ps.argb32.ref.pngbin0 -> 491 bytes
-rw-r--r--test/reference/xlib-surface-source.ps.rgb24.ref.pngbin0 -> 482 bytes
-rw-r--r--test/reference/xlib-surface-source.ref.pngbin0 -> 377 bytes
-rw-r--r--test/reference/xlib-surface-source.svg12.argb32.xfail.pngbin0 -> 278 bytes
-rw-r--r--test/reference/xlib-surface-source.svg12.rgb24.xfail.pngbin0 -> 278 bytes
-rw-r--r--test/reference/zero-alpha.base.argb32.ref.pngbin0 -> 91 bytes
-rw-r--r--test/reference/zero-alpha.base.rgb24.ref.pngbin0 -> 91 bytes
-rw-r--r--test/reference/zero-alpha.ref.pngbin0 -> 115 bytes
-rw-r--r--test/reference/zero-mask.base.argb32.ref.pngbin0 -> 402 bytes
-rw-r--r--test/reference/zero-mask.base.rgb24.ref.pngbin0 -> 382 bytes
-rw-r--r--test/reference/zero-mask.ref.pngbin0 -> 402 bytes
-rw-r--r--test/reflected-stroke.c91
-rw-r--r--test/rel-path.c129
-rw-r--r--test/rgb24-ignore-alpha.c60
-rw-r--r--test/romedalen.jpgbin0 -> 11400 bytes
-rw-r--r--test/romedalen.pngbin0 -> 80944 bytes
-rw-r--r--test/rotate-image-surface-paint.c172
-rw-r--r--test/rotate-stroke-box.c49
-rw-r--r--test/rotated-clip.c110
-rw-r--r--test/rounded-rectangle-fill.c65
-rw-r--r--test/rounded-rectangle-stroke.c64
-rwxr-xr-xtest/run-cairo-test-suite.sh18
-rw-r--r--test/sample.c117
-rw-r--r--test/scale-down-source-surface-paint.c65
-rw-r--r--test/scale-offset-image.c143
-rw-r--r--test/scale-offset-similar.c143
-rw-r--r--test/scale-source-surface-paint.c60
-rw-r--r--test/scaled-font-zero-matrix.c63
-rw-r--r--test/scarab.jpgbin0 -> 9650 bytes
-rw-r--r--test/select-font-face.c65
-rw-r--r--test/select-font-no-show-text.c59
-rw-r--r--test/self-copy-overlap.c54
-rw-r--r--test/self-copy.c84
-rw-r--r--test/self-intersecting.c87
-rw-r--r--test/set-source.c81
-rw-r--r--test/shape-general-convex.c88
-rw-r--r--test/shape-sierpinski.c85
-rw-r--r--test/show-glyphs-advance.c107
-rw-r--r--test/show-glyphs-many.c176
-rw-r--r--test/show-text-current-point.c59
-rw-r--r--test/simple.c347
-rw-r--r--test/skew-extreme.c118
-rw-r--r--test/smask-fill.c73
-rw-r--r--test/smask-image-mask.c85
-rw-r--r--test/smask-mask.c96
-rw-r--r--test/smask-paint.c81
-rw-r--r--test/smask-stroke.c73
-rw-r--r--test/smask-text.c83
-rw-r--r--test/smask.c123
-rw-r--r--test/solid-pattern-cache-stress.c212
-rw-r--r--test/source-clip-scale.c82
-rw-r--r--test/source-clip.c77
-rw-r--r--test/source-surface-scale-paint.c59
-rw-r--r--test/spline-decomposition.c471
-rw-r--r--test/stride-12-image.c71
-rw-r--r--test/stroke-clipped.c54
-rw-r--r--test/stroke-ctm-caps.c78
-rw-r--r--test/stroke-image.c73
-rw-r--r--test/stroke-open-box.c51
-rw-r--r--test/stroke-pattern.c68
-rw-r--r--test/subsurface-image-repeat.c70
-rw-r--r--test/subsurface-modify-child.c98
-rw-r--r--test/subsurface-modify-parent.c78
-rw-r--r--test/subsurface-outside-target.c177
-rw-r--r--test/subsurface-pad.c76
-rw-r--r--test/subsurface-reflect.c76
-rw-r--r--test/subsurface-repeat.c76
-rw-r--r--test/subsurface-scale.c93
-rw-r--r--test/subsurface-similar-repeat.c86
-rw-r--r--test/subsurface.c85
-rw-r--r--test/surface-finish-twice.c79
-rw-r--r--test/surface-pattern-big-scale-down.c125
-rw-r--r--test/surface-pattern-operator.c119
-rw-r--r--test/surface-pattern-scale-down-extend.c120
-rw-r--r--test/surface-pattern-scale-down.c88
-rw-r--r--test/surface-pattern-scale-up.c93
-rw-r--r--test/surface-pattern.c90
-rw-r--r--test/surface-source.c170
-rw-r--r--test/svg-clip.c152
-rw-r--r--test/svg-surface-source.c54
-rw-r--r--test/svg-surface.c136
-rw-r--r--test/svg2png.c62
-rwxr-xr-xtest/testsvg51
-rw-r--r--test/testtable.js428
-rw-r--r--test/text-antialias-subpixel.c123
-rw-r--r--test/text-antialias.c106
-rw-r--r--test/text-cache-crash.c93
-rw-r--r--test/text-glyph-range.c125
-rw-r--r--test/text-pattern.c73
-rw-r--r--test/text-rotate.c189
-rw-r--r--test/text-transform.c104
-rw-r--r--test/text-zero-len.c203
-rw-r--r--test/tiger.c85
-rw-r--r--test/tiger.inc2316
-rw-r--r--test/tighten-bounds.c172
-rw-r--r--test/toy-font-face.c149
-rw-r--r--test/transforms.c112
-rw-r--r--test/translate-show-surface.c79
-rw-r--r--test/trap-clip.c213
-rw-r--r--test/twin-antialias-gray.c71
-rw-r--r--test/twin-antialias-mixed.c97
-rw-r--r--test/twin-antialias-none.c71
-rw-r--r--test/twin-antialias-subpixel.c71
-rw-r--r--test/twin.c61
-rw-r--r--test/unaligned-box.c73
-rw-r--r--test/unantialiased-shapes.c98
-rw-r--r--test/unbounded-operator.c185
-rw-r--r--test/unclosed-strokes.c83
-rwxr-xr-xtest/update-refs.sh84
-rw-r--r--test/user-data.c110
-rw-r--r--test/user-font-mask.c253
-rw-r--r--test/user-font-proxy.c222
-rw-r--r--test/user-font-rescale.c368
-rw-r--r--test/user-font.c267
-rw-r--r--test/white-in-noop.c52
-rw-r--r--test/world-map.c151
-rw-r--r--test/world-map.h196
-rw-r--r--test/xcb-huge-image-shm.c67
-rw-r--r--test/xcb-huge-subimage.c81
-rw-r--r--test/xcb-snapshot-assert.c75
-rw-r--r--test/xcb-stress-cache.c118
-rw-r--r--test/xcb-surface-source.c149
-rw-r--r--test/xcomposite-projection.c109
-rw-r--r--test/xlib-expose-event.c196
-rw-r--r--test/xlib-surface-source.c100
-rw-r--r--test/xlib-surface.c353
-rw-r--r--test/zero-alpha.c95
-rw-r--r--test/zero-mask.c198
-rw-r--r--[-rwxr-xr-x]util/.gitignore0
-rw-r--r--[-rwxr-xr-x]util/COPYING0
-rw-r--r--[-rwxr-xr-x]util/Makefile.am3
-rw-r--r--[-rwxr-xr-x]util/README0
-rw-r--r--util/backtrace-symbols.c377
-rw-r--r--util/cairo-fdr/Makefile.am15
-rw-r--r--util/cairo-fdr/fdr.c331
-rw-r--r--[-rwxr-xr-x]util/cairo-gobject/Makefile.am0
-rw-r--r--[-rwxr-xr-x]util/cairo-gobject/cairo-gobject-enums.c0
-rw-r--r--[-rwxr-xr-x]util/cairo-gobject/cairo-gobject-structs.c4
-rw-r--r--[-rwxr-xr-x]util/cairo-gobject/cairo-gobject.h4
-rw-r--r--[-rwxr-xr-x]util/cairo-missing/Makefile.am0
-rw-r--r--[-rwxr-xr-x]util/cairo-missing/Makefile.sources0
-rw-r--r--[-rwxr-xr-x]util/cairo-missing/Makefile.win320
-rw-r--r--[-rwxr-xr-x]util/cairo-missing/cairo-missing.h2
-rw-r--r--[-rwxr-xr-x]util/cairo-missing/getline.c0
-rw-r--r--[-rwxr-xr-x]util/cairo-missing/strndup.c0
-rw-r--r--[-rwxr-xr-x]util/cairo-script/.gitignore0
-rw-r--r--[-rwxr-xr-x]util/cairo-script/COPYING0
-rw-r--r--[-rwxr-xr-x]util/cairo-script/Makefile.am0
-rw-r--r--[-rwxr-xr-x]util/cairo-script/Makefile.sources0
-rw-r--r--[-rwxr-xr-x]util/cairo-script/Makefile.win320
-rw-r--r--[-rwxr-xr-x]util/cairo-script/cairo-script-file.c9
-rw-r--r--[-rwxr-xr-x]util/cairo-script/cairo-script-hash.c0
-rw-r--r--[-rwxr-xr-x]util/cairo-script/cairo-script-interpreter.c2
-rw-r--r--[-rwxr-xr-x]util/cairo-script/cairo-script-interpreter.h0
-rw-r--r--[-rwxr-xr-x]util/cairo-script/cairo-script-objects.c0
-rw-r--r--[-rwxr-xr-x]util/cairo-script/cairo-script-operators.c76
-rw-r--r--[-rwxr-xr-x]util/cairo-script/cairo-script-private.h0
-rw-r--r--[-rwxr-xr-x]util/cairo-script/cairo-script-scanner.c0
-rw-r--r--[-rwxr-xr-x]util/cairo-script/cairo-script-stack.c0
-rw-r--r--[-rwxr-xr-x]util/cairo-script/csi-bind.c0
-rw-r--r--[-rwxr-xr-x]util/cairo-script/csi-exec.c0
-rw-r--r--[-rwxr-xr-x]util/cairo-script/csi-replay.c0
-rw-r--r--[-rwxr-xr-x]util/cairo-script/csi-trace.c10
-rw-r--r--[-rwxr-xr-x]util/cairo-script/examples/Makefile.am0
-rw-r--r--[-rwxr-xr-x]util/cairo-script/examples/dragon.cs0
-rw-r--r--[-rwxr-xr-x]util/cairo-script/examples/hilbert.cs0
-rw-r--r--[-rwxr-xr-x]util/cairo-script/examples/infinichess.cs0
-rw-r--r--[-rwxr-xr-x]util/cairo-script/examples/interference.cs0
-rw-r--r--[-rwxr-xr-x]util/cairo-script/examples/pythagoras-tree.cs0
-rw-r--r--[-rwxr-xr-x]util/cairo-script/examples/sierpinski.cs0
-rw-r--r--[-rwxr-xr-x]util/cairo-script/examples/wedgeAnnulus_crop_ybRings.cs0
-rw-r--r--[-rwxr-xr-x]util/cairo-script/examples/world-map.cs0
-rw-r--r--[-rwxr-xr-x]util/cairo-script/examples/zrusin.cs0
-rw-r--r--util/cairo-sphinx/.gitignore1
-rw-r--r--util/cairo-sphinx/Makefile.am43
-rw-r--r--util/cairo-sphinx/fdr.c261
-rw-r--r--util/cairo-sphinx/sphinx.c1545
-rw-r--r--util/cairo-trace/.gitignore1
-rw-r--r--util/cairo-trace/COPYING5
-rw-r--r--util/cairo-trace/COPYING-GPL-3674
-rw-r--r--util/cairo-trace/Makefile.am40
-rw-r--r--util/cairo-trace/cairo-trace.in136
-rw-r--r--util/cairo-trace/lookup-symbol.c331
-rw-r--r--util/cairo-trace/lookup-symbol.h24
-rw-r--r--util/cairo-trace/trace.c5581
-rw-r--r--[-rwxr-xr-x]util/cairo.modules0
-rw-r--r--[-rwxr-xr-x]util/font-view.c0
-rw-r--r--[-rwxr-xr-x]util/malloc-stats.c9
-rw-r--r--[-rwxr-xr-x]util/show-contour.c0
-rw-r--r--[-rwxr-xr-x]util/show-edges.c0
-rw-r--r--[-rwxr-xr-x]util/show-events.c0
-rw-r--r--[-rwxr-xr-x]util/show-polygon.c0
-rw-r--r--[-rwxr-xr-x]util/show-traps.c0
-rw-r--r--[-rwxr-xr-x]util/trace-to-xml.c0
-rw-r--r--[-rwxr-xr-x]util/xml-to-trace.c0
4164 files changed, 108966 insertions, 6532 deletions
diff --git a/AUTHORS b/AUTHORS
index a977e73c9..d85696fa8 100755..100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -24,6 +24,7 @@ John Ellson <ellson@research.att.com> First font/glyph extents functions
Michael Emmel <mike.emmel@gmail.com> DirectFB backend
Miklós Erdélyi <erdelyim@gmail.com> Fix typo leading to a crash
Behdad Esfahbod <behdad@behdad.org> Huge piles of bug fixes, improvements, and general maintenance
+Gilles Espinasse <g.esp@free.fr> Font related fixes
Larry Ewing <lewing@novell.com> Test case for group-clip
Brian Ewins <Brian.Ewins@gmail.com> ATSUI maintenance (first success at making it really work)
Bertram Felgenhauer <int-e@gmx.de> Fixes for subtle arithmetic errors
@@ -32,6 +33,7 @@ Bdale Garbee <bdale@gag.com> Provided essential support for cairo achitecture se
Jens Granseuer <jensgr@gmx.net> Fixes to generate proper compiler flags
Laxmi Harikumar <laxmi.harikumar@digital.com> Build fix
J. Ali Harlow <ali@avrc.city.ac.uk> win32 backend updates
+Bryce Harrington <bryce@osg.samsung.com> Test cases, bug/typo fixes
Mathias Hasselmann <mathias.hasselmann@gmx.de> Significant reduction of calls to malloc
Richard Henderson <rth@twiddle.net> "slim" macros for better shared libraries
James Henstridge <james@daa.com.au> Build fixes related to freetype
@@ -49,6 +51,7 @@ Martin Kretzschmar <martink@gnome.org> Arithmetic fix for 64-bit architectures
Mathieu Lacage <Mathieu.Lacage@sophia.inria.fr> several bug/typo fixes
Dominic Lachowicz <domlachowicz@gmail.com> PDF conformance fix, fix image surface to zero out contents
Alexander Larsson <alexl@redhat.com> Profiling and performance fixes.
+Sylvestre Ledru <sylvestre@mozilla.com> Static analysis fixes.
Tor Lillqvist <tml@novell.com> win32 build fixes, build scripts
Jinghua Luo <sunmoon1997@gmail.com> Add bitmap glyph transformation, many freetype and glitz fixes
Luke-Jr <luke-jr@utopios.org> Build fix for cross-compiling
@@ -62,6 +65,7 @@ Christopher (Monty) Montgomery <xiphmont@gmail.com> Performnace fix (subimage_co
Tim Mooney <enchanter@users.sourceforge.net> Fix test suite to compile with Solaris compiler
Jeff Muizelaar <jeff@infidigm.net> Patient, painful, pixman code merge. Many fixes for intricacies of dashing.
Yevgen Muntyan <muntyan@tamu.edu> win32 build fix
+Ravi Nanjundappa <nravi.n@samsung.com> Static analysis fixes, test cases, skia backend update/fixes
Declan Naughton <piratepenguin@gmail.com> Fix documentation typos
Peter Nilsson <c99pnn@cs.umu.se> Glitz backend
Henning Noren <henning.noren.402@student.lu.se> Fix memory leak
@@ -88,7 +92,7 @@ Jamey Sharp <jamey@minilop.net> Surface/font backend virtualization, XCB backend
Jason Dorje Short <jdorje@users.sf.net> Build fixes and bug fixes
Jeff Smith <whydoubt@yahoo.com> Fixes for intricacies of stroking code
Travis Spencer <tspencer@cs.pdx.edu> XCB backend fix
-Bill Spitzak <spitzak@d2.com> Build fix to find Xrender.h without xrender.pc
+Bill Spitzak <spitzak@d2.com> Build fix to find Xrender.h without xrender.pc, downscaling support
Zhe Su <james.su@gmail.com> Add support for fontconfig's embeddedbitmap option
Owen Taylor <otaylor@redhat.com> Font rewrite, documentation, win32 backend
Pierre Tardy <tardyp@gmail.com> EGL support and testing, OpenVG backend
diff --git a/BIBLIOGRAPHY b/BIBLIOGRAPHY
index 90a6cef20..90a6cef20 100755..100644
--- a/BIBLIOGRAPHY
+++ b/BIBLIOGRAPHY
diff --git a/BUGS b/BUGS
index ef044046d..ef044046d 100755..100644
--- a/BUGS
+++ b/BUGS
diff --git a/CODING_STYLE b/CODING_STYLE
index 95ceac04d..95ceac04d 100755..100644
--- a/CODING_STYLE
+++ b/CODING_STYLE
diff --git a/COPYING b/COPYING
index f54969f1c..f54969f1c 100755..100644
--- a/COPYING
+++ b/COPYING
diff --git a/COPYING-LGPL-2.1 b/COPYING-LGPL-2.1
index f1ed6182c..f1ed6182c 100755..100644
--- a/COPYING-LGPL-2.1
+++ b/COPYING-LGPL-2.1
diff --git a/COPYING-MPL-1.1 b/COPYING-MPL-1.1
index 7714141d1..7714141d1 100755..100644
--- a/COPYING-MPL-1.1
+++ b/COPYING-MPL-1.1
diff --git a/HACKING b/HACKING
index 92aa6541d..aba2c545b 100755..100644
--- a/HACKING
+++ b/HACKING
@@ -73,9 +73,9 @@ We use /git/ for version control. See:
http://cairographics.org/download/
-TODO:
-Add links to some git tutorials or better, write a few paragraphs
-about how to use git to efficiently hack on cairo.
+For more information on using git, see:
+
+ http://freedesktop.org/wiki/Infrastructure/git/
Build System
@@ -103,10 +103,9 @@ No manual ChangeLog writing is necessary.
Copyrights and Licensing
------------------------
-The cairo library is dual-licensed under LGPL and MPL. See file named
-COPYING for details. The test suites are more liberal. For example,
-GPL code is allowed in the test suites, though it's always better to
-keep things simple.
+The cairo library is dual-licensed under LGPL and MPL. See the file
+named COPYING for details. The test suites are more liberal, and are
+allowed to include GPL code.
When writing new code, update the file headers to add your (or your
employers) copyright line and contributor line. If adding new files
@@ -136,10 +135,11 @@ See test/README for more information.
Performance Test Suite
----------------------
-There is a small performance-testing suite for cairo.
-
-The performance test suite is located under the perf/ directory.
-See perf/README for more information.
+There is a performance test suite located under the perf/ directory.
+A collection of traces of real-world behavior are also available in the
+cairo-traces repository, which can be used in isolation or hooked in
+with the main performance test suite. See perf/README for more
+information.
Boilerplate
@@ -173,9 +173,8 @@ Some of those should gradually be moved to doc/.
Utilities
---------
-There are a few useful utilities we have developed that are either
-useful when writing code using cairo, or writing cairo, or useful in
-general. These tools can be found under the util/ directory.
+We have developed several utilities useful for writing cairo or code
+that uses cairo. These tools can be found under the util/ directory.
See util/README for more information.
diff --git a/INSTALL b/INSTALL
index 9db68dee2..9db68dee2 100755..100644
--- a/INSTALL
+++ b/INSTALL
diff --git a/KNOWN_ISSUES b/KNOWN_ISSUES
index 5fda68389..c367f918e 100755..100644
--- a/KNOWN_ISSUES
+++ b/KNOWN_ISSUES
@@ -1,10 +1,3 @@
-There are a few known bugs in 1.10 that have been fixed in master, but
-appear to be non-trivial to backport without fear of causing other
-regressions. The impact of these bugs is considered to be less than of a
-risk than rewriting the code.
-
-Zero Path Extents
------------------
-A closed degenerate path is reported as having extents (0, 0) x (0, 0),
-whereas the expected value is (x, y) x (0, 0). This regression has existed
-since at least 1.2.
+Known Issues
+------------
+None
diff --git a/Makefile.am b/Makefile.am
index 0fa9c74f4..03fa35236 100755..100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -16,28 +16,25 @@ EXTRA_DIST += \
ACLOCAL_AMFLAGS = -I build ${ACLOCAL_FLAGS}
-#DIST_SUBDIRS = src doc util boilerplate test
-#SUBDIRS = src doc util
-DIST_SUBDIRS = src util boilerplate
-SUBDIRS = src util
+DIST_SUBDIRS = src doc util boilerplate test perf
+SUBDIRS = src doc util
# libpng is required for our test programs
if CAIRO_HAS_PNG_FUNCTIONS
-#SUBDIRS += boilerplate test
-SUBDIRS += boilerplate
+SUBDIRS += boilerplate test perf
endif
configure: cairo-version.h
-#doc:
-# cd doc && $(MAKE) $(AM_MAKEFLAGS) $@
-#test retest recheck: all
-# cd test && $(MAKE) $(AM_MAKEFLAGS) $@
-#perf: all
-# cd perf && $(MAKE) $(AM_MAKEFLAGS) $@
-#check-valgrind: all
-# cd test && $(MAKE) $(AM_MAKEFLAGS) check-valgrind
-# cd perf && $(MAKE) $(AM_MAKEFLAGS) check-valgrind
-#.PHONY: doc test retest recheck perf check-valgrind
+doc:
+ cd doc && $(MAKE) $(AM_MAKEFLAGS) $@
+test retest recheck: all
+ cd test && $(MAKE) $(AM_MAKEFLAGS) $@
+perf: all
+ cd perf && $(MAKE) $(AM_MAKEFLAGS) $@
+check-valgrind: all
+ cd test && $(MAKE) $(AM_MAKEFLAGS) check-valgrind
+ cd perf && $(MAKE) $(AM_MAKEFLAGS) check-valgrind
+.PHONY: doc test retest recheck perf check-valgrind
EXTRA_DIST += \
diff --git a/Makefile.win32 b/Makefile.win32
index fbad7f3e4..fbad7f3e4 100755..100644
--- a/Makefile.win32
+++ b/Makefile.win32
diff --git a/NEWS b/NEWS
index 368d293c2..93b650ef5 100755..100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,339 @@
+Release 1.14.2 (2014-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
+fonts.
+
+The running theme of the bug fixes is platform-specific issues, both
+build and run-time. Platforms with fixes include Sparc, AIX, Windows
+(mingw), and Windows (MSVC8). Memory leaks, valgrind issues, and PDF
+issues round out our list.
+
+It's come to light that changes in cairo 1.14 resulted in breakage on
+MacOS X 10.4. We've not yet determined whether to fix up the support,
+or excise the 10.4-specific code and support only OS X 10.5 or newer.
+Meantime, we'll only advertise cairo as working on OS X 10.5.
+
+Features
+--------
+ * Improve xcb's handling of per-screen subpixel ordering. If no
+ Xft.rgba property is specified, default to the screen's subpixel
+ order.
+
+API Changes
+-----------
+None
+
+Dependency Changes
+------------------
+None
+
+Performance Optimizations
+-------------------------
+ * Improve performance of cpu_to_be32 and be32_to_cpu, making truetype
+ subsetting of large fonts run about 15% faster.
+
+Bug Fixes
+---------
+ * Fix unaligned access on sparc with the compact font format (CFF).
+ Unlike truetype, all data in CFF is not aligned.
+ (Debian bug #712836)
+ * Fix unaligned access on sparc with tor-scan-converter's memory pool.
+ * Fix crash when loading a PDF with a transformed image.
+ (fdo bug #85151)
+ * Fix regression on mingw for bigendian test due to removal of file
+ extension for executables.
+ (fdo bug #85120)
+ * Fix handling of backslash in PDF interpreter
+ (fdo bug #85662)
+ * Fix crash in xlib and xcb renderers when swapping a 0-sized glyph
+ * Fix bug with RTL text in PDF operators
+ (fdo bug #86461)
+ * Fix compilation 'cairo-path-stroke-traps.c' with MSVC8
+ (fdo bug #84908)
+ * Fix crash in _fill_xrgb32_lerp_opaque_spans when a span length is
+ negative.
+ * Fix valgrind error by releasing pattern created by
+ cairo_pattern_create_rgb().
+ * Fix valgrind errors when running cairo-test-suite.
+ * Fix memory leak in recording surface replays
+ (fdo bug #87898)
+ * Fix destruction of fonts in api-special-cases test.
+ (fdo bug #87567)
+ * Fix duplicated surface push on similar-image, preventing trivial GTK3
+ program traces from being replayable, with an error message about
+ invalid values for the size of the input.
+ (fdo bug #73580)
+ * Fix crash when win32 surface's image size does not cover the entire
+ surface.
+ (fdo bug #53121)
+ * Fix crash due to obsolete CGFontGetGlyphPath call
+ (fdo bug #84324)
+ * Fix several build issues on AIX
+ (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
+not for lack of activity. This release includes contributions of a wide
+assortment of bug fixes, build system improvements, warnings cleanups,
+codebase refactoring, test suite repairs, and static analysis work.
+
+This release is lighter on features (compared with 1.12.10) but includes
+a highly demanded rehaul of our image downscaling functionality, which
+solves a serious problem experienced by Inkscape users when shrinking
+embedded bitmaps in SVG files. The new scaling algorithms are used by
+the image backend and by other backends as needed for fallbacks.
+
+
+Features
+--------
+
+ Filtering improvements for the image backend, in particular
+ down-scaling of images produces filtered images that depend on all the
+ pixels of the source. When using the image backend you get the
+ following settings:
+
+ CAIRO_FILTER_GOOD: uses a box filter for scales less than .75 in
+ either direction. For scales larger than this, the same filter as
+ CAIRO_FILTER_BILINEAR is used.
+
+ CAIRO_FILTER_BEST: uses a Catmull-Rom filter always. When upscaling
+ more than 2x this will produce anti-aliased square pixels, similar
+ to OS/X.
+
+ CAIRO_FILTER_GAUSSIAN: uses PIXMAN_FILTER_BEST, which in current
+ pixman is the same as BILINEAR. (This is subject to change in the
+ future).
+
+ xlib and xcb also use the image fallback for GOOD/BEST filters, but
+ note that other backends do not implement these filtering fixes yet,
+ however other actions may cause them to use an image fallback which
+ will cause these filters to be used.
+
+ Improve handling of device transformation and scaling, allowing Cairo
+ to now support scaling at a device level, permitting easier, more
+ transparent HiDPI support.
+
+ Support JBIG2 mime data in PDF. This allows embedding of more
+ compressed JPEG formats within PDF, rather than including the full
+ uncompressed image. Also, reduce the number of transparency groups
+ used by PDF to keep the file size small and viewing/printing of the
+ PDF fast.
+
+ Expand the embedding section to include stencil mask support.
+
+ Reorder font declarations to be in natural order.
+
+ Update the Skia backend to build against current Skia (as of June
+ 2014).
+
+ Drop Link-Time Optimization (LTO) support from build system. This
+ seems to have caused much trouble for unclear benefit, and most
+ distros are reverting or disabling it anyway.
+
+ Optimize VBO size on GL to 1M and to 16k for EGL. This improves
+ (theoretical) performance for desktop GLX use cases while avoiding
+ hitting VBO memory size limitations on embedded devices.
+
+API Changes
+-----------
+
+ cairo_surface_set_device_scale, cairo_surface_get_device_scale:
+
+ Sets a scale that is multiplied to the device coordinates
+ determined by the CTM when drawing to @surface. One common use for
+ this is to render to very high resolution display devices at a scale
+ factor, so that code that assumes 1 pixel will be a certain size
+ will still work.
+
+ cairo_egl_device_get_display, cairo_egl_device_get_context:
+
+ Support get/set of EGLContext and EGLDisplay for egl-based cairo
+ devices, similar to GLX.
+
+Dependency Changes
+------------------
+
+ Cairo now requires glib 2.14 for its gobject helper functions,
+ and pixman 0.30 for downscaling.
+
+
+Bug fixes
+---------
+
+ Don't embed CMYK Jpeg images in svg.
+
+ Fix tests to place output in proper location.
+
+ Fix determination of alpha for all surfaces when recording.
+
+ Extend oversize check to cairo_gl_surface_create_for_texture, so an
+ error surface is returned if the texture is too large to render to.
+
+ Fix embedding of mime data in PDF and PS files.
+
+ Remove useless error handling in *_reply() functions in XCB.
+
+ Fix a double-free exposed by multithreaded apps creating and
+ destroying the same font concurrently.
+ https://bugs.freedesktop.org/show_bug.cgi?id=69470
+
+ Fix corrupt stacks produced by bugs in operand emission for trace.
+
+ Fix out of bounds array access in format cache for xlib
+
+ Don't rename glyphs used by seac operator. This can cause certain
+ combined characters to use their decorations (e.g. umlauts on ö) to be
+ lost during printing of PDFs using evince.
+ https://bugs.freedesktop.org/show_bug.cgi?id=70364
+
+ Fix crash on calling cairo_create with a finished surface
+
+ Fix SSIZE_T definition problem when making with MSYS on Windows7
+
+ Fix one off issue in gl context cleanup
+
+ Fix usage of CAIRO_STACK_ARRAY_LENGTH
+
+ Fix rectangle stroke with non rectilinear pen
+
+ Fix imagemask with pattern source failure on some printers. This bug
+ could cause files converted using pdftops to fail for example on Ricoh
+ printers, or opening in Adobe Distiller on Windows.
+ https://bugs.freedesktop.org/show_bug.cgi?id=69485
+
+ Fix whitespace in font names
+
+ Fix page size in generated PDFs. When printing using pdftocairo on
+ larger page sizes, such as 11x17, the image would be cropped to letter
+ size.
+ https://bugs.freedesktop.org/show_bug.cgi?id=73452
+
+ Fix path-currentpoint test by preserving current-point in
+ copy_path()/append_path() sequence
+
+ Fix generation of HTML in code docs for
+ cairo-format-stride-for-width. Raw HTML code was being passed
+ to the browser, instead of displaying normally.
+ https://bugs.freedesktop.org/show_bug.cgi?id=63257
+
+ Fix spelling of "tessellator" throughout code. We're using the
+ American rather than British spelling of this word.
+ https://bugs.freedesktop.org/show_bug.cgi?id=50411
+
+ Fix crash in pixman_image_composite32
+
+ Fix crash when trying to modify a (const) all-clipped cairo_clip_t
+ https://bugs.freedesktop.org/show_bug.cgi?id=75819
+
+ Add check_composite method to all compositors, to fix crashes in the
+ test suite.
+
+ Fix crash in Firefox when scrolling on certain pages.
+
+ Fix memory leaks found by static analysis.
+
+ Fix build of any2ppm if fork is not available.
+
+ Fix broken build for Qt backend, due to missing libstdc++.
+
+ Fix typo in two cairo_uint128 functions. Fixes potential build issues
+ on systems without a uint128 type.
+
+ Fix build when --enable-pdf=no
+
+ Fix cache_frozen assertions for Win32 print.
+
+ Correctly check for xcb image surface for inplace upload
+
+ Fix webkit-based web browser crashes due to empty boxes by skipping
+ over them when tesselating.
+
+ Make pixman, libpng, and zlib paths commandline configurable for win32
+ builds.
+
+ Fix image scale on Win32 when GDI scale is not identity.
+
+ Fix float endian configure test when using clang -O4
+
+ Fix compilation with Android bionic libc
+
+ Don't try to build util/sphinx on Windows
+
+ Fix loss of precision when emitting joins. This was caused by
+ discrepancies in line gradients when passing trapezoids around.
+
+ Fix loss of precision and associated rendering issues in
+ cairo-tor-scan-converter from projection onto sample grid.
+
+ Fix pixman oversampling of neighbouring edges within a cell by
+ eliminating self-intersections for the pixman traps compositor.
+
+ Fix multi-line string splitting in PDFs
+
+ Various cleanups and fixes to warnings, documentation, tests, and
+ build system. Improve error handling and return value checks.
+ Cleanup XFAIL tests and reference images. Cover recently added
+ functionality.
+
+
+Release 1.12.16 (2013-08-21 Chris Wilson <chris@chris-wilson.co.uk>)
+===================================================================
+Thanks to everybody who reported a bug and helped us develop a fix,
+we have amassed quite a few bug fixes. There are still more outstanding
+bugs that seek attention and a little bit of TLC, but this release has
+been delayed long enough...
+
+Bug fixes
+---------
+
+ Set the correct orientation for simple boxes with a negative scale
+ factor.
+
+ Fix the creation of the shading dictionary in PDF.
+
+ Fix a crash in PDF when incorporating an image with CAIRO_EXTEND_PAD.
+ https://bugs.freedesktop.org/show_bug.cgi?id=61451
+
+ Avoid upscaling bitmap fonts if possible.
+
+ Fix an assertion failure within the mempool allocator for shared memory.
+
+ Fix allocation size for CFF subsets.
+
+ Export cairo_matrix_t for GObject bindings.
+
+ Fix a double free in the Quartz backend.
+ https://bugs.freedesktop.org/show_bug.cgi?id=62885
+
+ Fix origin of GDI StretchBlits for the Windows backend
+ https://bugs.freedesktop.org/show_bug.cgi?id=61876
+
+ Fix error propagation for requests to create a similar surface with
+ negative size.
+ https://bugs.freedesktop.org/show_bug.cgi?id=63196
+
+ Fix complex clipping of trapezoids with regions
+ https://bugzilla.gnome.org/show_bug.cgi?id=697357
+
+ Stop leaking the image data when loading PNGs
+
+ Fix unbounded operations with a clip mask through the span compositor
+ https://bugs.freedesktop.org/show_bug.cgi?id=61592
+
+ Add missing checks before rendering to a finished surface - so we return
+ an error rather than hit an assert.
+ https://bugs.freedesktop.org/show_bug.cgi?id=68014
+
+ Prevent an assertion failure when creating similar GL surfaces larger
+ than supported by hardware.
+
+ Prevent a double free of a similar image under Windows.
+ https://bugs.freedesktop.org/show_bug.cgi?id=63787
+
+
Release 1.12.14 (2013-02-10 Chris Wilson <chris@chris-wilson.co.uk>)
===================================================================
In the last week we had a few more bugs reported and promptly resolved.
@@ -350,8 +686,8 @@ cases (such as stroking around a rectangle) and by reducing the number
of edges generated by the general stroker.
As part of the focus on performance, Cairo 1.12 introduces some
-antialias hints (NONE,FAST, GOOD, BEST) that are interpolated by the
-raserisers to fine tune their performance versus quality. Cairo 1.12
+antialias hints (NONE, FAST, GOOD, BEST) that are interpolated by the
+rasterisers to fine tune their performance versus quality. Cairo 1.12
also introduces a new observation architecture,
cairo_surface_observer_t, which can be used to analyse the amount of
time consumed by drawing commands and help identify inefficiencies in
diff --git a/PORTING_GUIDE b/PORTING_GUIDE
index 7488173c4..7488173c4 100755..100644
--- a/PORTING_GUIDE
+++ b/PORTING_GUIDE
diff --git a/README b/README
index 67ce4f58d..0be9947d5 100755..100644
--- a/README
+++ b/README
@@ -67,29 +67,31 @@ backends. Further, the supported backends can be divided into the
"platform" backends which depend on some underlying platform-specific
system, (such as the X Window System or some other window system).
-As an example, for a standard Linux build, (with image, png, pdf,
-PostScript, svg, and xlib surface backends, and the freetype font
-backend), the following sample commands will install necessary
-dependencies:
+As an example, for a standard Linux build similar to what's shipped by
+your distro, (with image, png, pdf, PostScript, svg, and xlib surface
+backends, and the freetype font backend), the following sample commands
+will install necessary dependencies:
Debian (and similar):
- apt-get install libpng12-dev libz-dev libxrender-dev libfontconfig1-dev
+ apt-get build-dep cairo
Fedora (and similar):
yum install libpng-devel zlib-devel libXrender-devel fontconfig-devel
-(Those commands intentionally don't install pixman from a distribution
-package since if you're manually compiling cairo, then you likely want
-to grab pixman from the same place at the same time and compile it as
-well.)
+Technically you probably don't need pixman from the distribution since
+if you're manually compiling Cairo you probably want an updated pixman
+as well. However, if you follow the default settings and install pixman
+to /usr/local, your Cairo build should properly use it in preference to
+the system pixman.
+
Supported, "standard" surface backends
------------------------------------
image backend (required)
------------------------
- pixman >= 0.20.2 http://cairographics.org/releases
+ pixman >= 0.30.0 http://cairographics.org/releases
png support (can be left out if desired, but many
----------- applications expect it to be present)
@@ -119,7 +121,7 @@ Supported, "platform" surface backends
quartz backend
--------------
- MacOS X >= 10.4 with Xcode >= 2.4
+ MacOS X >= 10.5 with Xcode >= 3.0
win32 backend
-------------
@@ -179,10 +181,18 @@ 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
=========
See the INSTALL document for build instructions.
+
History
=======
Cairo was originally developed by Carl Worth <cworth@cworth.org> and
diff --git a/README.win32 b/README.win32
index ff962b72a..ff962b72a 100755..100644
--- a/README.win32
+++ b/README.win32
diff --git a/RELEASING b/RELEASING
index a1edceba9..641ac1fc4 100755..100644
--- a/RELEASING
+++ b/RELEASING
@@ -2,7 +2,9 @@ Here are the steps to follow to create a new cairo release:
1) Ensure that there are no local, uncommitted/unpushed
modifications. You're probably in a good state if both "git diff
- HEAD" and "git log master..origin/master" give no output.
+ HEAD" and "git log master..origin/master" give no output. Also make
+ sure you have libglib2.0-doc installed (else you'll get excessive
+ gtk-doc cross reference warnings in the next step).
2) Verify that the code passes "make distcheck"
@@ -111,7 +113,7 @@ Here are the steps to follow to create a new cairo release:
8) Push the newly created tag out to the central tree with a command
something like:
- git push cairo X.Y.Z
+ git push origin master X.Y.Z
9) 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
@@ -119,12 +121,13 @@ Here are the steps to follow to create a new cairo release:
odd micro version).
10) Send a message to cairo-announce@cairographics.org and CC
- gnome-announce-list@gnome.org and ftp-release@lists.freedesktop.org
- (pr@lwn.net as well for major releases) to announce the new release
- using the text provided from "make release-publish", adding the excerpt
- from NEWS, your signature, followed by the standard "What is cairo" and
- "Where to get more information about cairo" blurbs from README, and
- finally the shortlog of all changes since last release, generated by:
+ cairo@cairographics.org, gnome-announce-list@gnome.org and
+ ftp-release@lists.freedesktop.org (pr@lwn.net as well for major
+ releases) to announce the new release using the text provided from
+ "make release-publish", adding the excerpt from NEWS, your
+ signature, followed by the standard "What is cairo" and "Where to
+ get more information about cairo" blurbs from README, and finally
+ the shortlog of all changes since last release, generated by:
git shortlog X.Y.Z...
@@ -133,8 +136,3 @@ Here are the steps to follow to create a new cairo release:
11) Edit the cairo wiki to add the announcement to the NEWS page and
the front page. (just the parts before your signature).
-12) For minor releases (no X.Y change), notify desktop-devel-list@gnome.org
- or update the ExternalDependencies page for the current cycle if you
- know where it is. Currently it's:
-
- http://live.gnome.org/TwoPointNineteen/ExternalDependencies
diff --git a/acinclude.m4 b/acinclude.m4
index dcf54f935..dcf54f935 100755..100644
--- a/acinclude.m4
+++ b/acinclude.m4
diff --git a/boilerplate/.gitignore b/boilerplate/.gitignore
index a81663b80..a81663b80 100755..100644
--- a/boilerplate/.gitignore
+++ b/boilerplate/.gitignore
diff --git a/boilerplate/Makefile.am b/boilerplate/Makefile.am
index 29ad015ac..240736c79 100755..100644
--- a/boilerplate/Makefile.am
+++ b/boilerplate/Makefile.am
@@ -21,7 +21,7 @@ cxx_boilerplate_lib =
endif
EXTRA_LTLIBRARIES += libcairoboilerplate.la $(cxx_boilerplate_lib)
-
+#lib_LTLIBRARIES = libcairoboilerplate.la $(cxx_boilerplate_lib)
libcairoboilerplate_la_SOURCES = \
$(enabled_cairo_boilerplate_headers) \
@@ -58,6 +58,10 @@ if CAIRO_HAS_WIN32_SURFACE
libcairoboilerplate_la_LIBADD += -lwinspool
endif
+if CAIRO_HAS_CGL_FUNCTIONS
+libcairoboilerplate_la_LDFLAGS = -framework OpenGL
+endif
+
cairo-boilerplate-constructors.c: Makefile $(enabled_cairo_boilerplate_sources) $(enabled_cairo_boilerplate_cxx_sources) make-cairo-boilerplate-constructors.sh
(cd $(srcdir) && sh ./make-cairo-boilerplate-constructors.sh $(enabled_cairo_boilerplate_sources) $(enabled_cairo_boilerplate_cxx_sources)) > $@
diff --git a/boilerplate/Makefile.sources b/boilerplate/Makefile.sources
index e0fdb4e99..73dbd77e6 100755..100644
--- a/boilerplate/Makefile.sources
+++ b/boilerplate/Makefile.sources
@@ -24,6 +24,7 @@ cairo_boilerplate_directfb_sources = cairo-boilerplate-directfb.c
cairo_boilerplate_drm_sources = cairo-boilerplate-drm.c
cairo_boilerplate_glx_sources = cairo-boilerplate-glx.c
cairo_boilerplate_wgl_sources = cairo-boilerplate-wgl.c
+cairo_boilerplate_cgl_sources = cairo-boilerplate-cgl.c
cairo_boilerplate_egl_sources = cairo-boilerplate-egl.c
cairo_boilerplate_evasgl_sources = cairo-boilerplate-evas-gl.c
cairo_boilerplate_pdf_sources = cairo-boilerplate-pdf.c
@@ -40,4 +41,3 @@ cairo_boilerplate_xlib_headers = cairo-boilerplate-xlib.h
cairo_boilerplate_xlib_sources = cairo-boilerplate-xlib.c
cairo_boilerplate_vg_sources = cairo-boilerplate-vg.c
cairo_boilerplate_cogl_sources = cairo-boilerplate-cogl.c
-cairo_boilerplate_tg_sources = cairo-boilerplate-tg.c
diff --git a/boilerplate/Makefile.win32 b/boilerplate/Makefile.win32
index 29df5cf79..29df5cf79 100755..100644
--- a/boilerplate/Makefile.win32
+++ b/boilerplate/Makefile.win32
diff --git a/boilerplate/Makefile.win32.features b/boilerplate/Makefile.win32.features
index 8efe8562c..6087bff50 100755..100644
--- a/boilerplate/Makefile.win32.features
+++ b/boilerplate/Makefile.win32.features
@@ -19,24 +19,6 @@ enabled_cairo_boilerplate_cxx_sources = $(cairo_boilerplate_cxx_sources)
enabled_cairo_boilerplate_sources = $(cairo_boilerplate_sources)
-all_cairo_boilerplate_private += $(cairo_boilerplate_tls_private) $(cairo_boilerplate_tls_headers)
-all_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_tls_cxx_sources)
-all_cairo_boilerplate_sources += $(cairo_boilerplate_tls_sources)
-ifeq ($(CAIRO_HAS_TLS),1)
-enabled_cairo_boilerplate_private += $(cairo_boilerplate_tls_private) $(cairo_boilerplate_tls_headers)
-enabled_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_tls_cxx_sources)
-enabled_cairo_boilerplate_sources += $(cairo_boilerplate_tls_sources)
-endif
-
-all_cairo_boilerplate_private += $(cairo_boilerplate_pthread_setspecific_private) $(cairo_boilerplate_pthread_setspecific_headers)
-all_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_pthread_setspecific_cxx_sources)
-all_cairo_boilerplate_sources += $(cairo_boilerplate_pthread_setspecific_sources)
-ifeq ($(CAIRO_HAS_PTHREAD_SETSPECIFIC),1)
-enabled_cairo_boilerplate_private += $(cairo_boilerplate_pthread_setspecific_private) $(cairo_boilerplate_pthread_setspecific_headers)
-enabled_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_pthread_setspecific_cxx_sources)
-enabled_cairo_boilerplate_sources += $(cairo_boilerplate_pthread_setspecific_sources)
-endif
-
supported_cairo_boilerplate_headers += $(cairo_boilerplate_xlib_headers)
all_cairo_boilerplate_headers += $(cairo_boilerplate_xlib_headers)
all_cairo_boilerplate_private += $(cairo_boilerplate_xlib_private)
@@ -313,18 +295,6 @@ enabled_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_directfb_cxx_source
enabled_cairo_boilerplate_sources += $(cairo_boilerplate_directfb_sources)
endif
-unsupported_cairo_boilerplate_headers += $(cairo_boilerplate_tg_headers)
-all_cairo_boilerplate_headers += $(cairo_boilerplate_tg_headers)
-all_cairo_boilerplate_private += $(cairo_boilerplate_tg_private)
-all_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_tg_cxx_sources)
-all_cairo_boilerplate_sources += $(cairo_boilerplate_tg_sources)
-ifeq ($(CAIRO_HAS_TG_SURFACE),1)
-enabled_cairo_boilerplate_headers += $(cairo_boilerplate_tg_headers)
-enabled_cairo_boilerplate_private += $(cairo_boilerplate_tg_private)
-enabled_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_tg_cxx_sources)
-enabled_cairo_boilerplate_sources += $(cairo_boilerplate_tg_sources)
-endif
-
unsupported_cairo_boilerplate_headers += $(cairo_boilerplate_vg_headers)
all_cairo_boilerplate_headers += $(cairo_boilerplate_vg_headers)
all_cairo_boilerplate_private += $(cairo_boilerplate_vg_private)
@@ -361,6 +331,18 @@ enabled_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_glx_cxx_sources)
enabled_cairo_boilerplate_sources += $(cairo_boilerplate_glx_sources)
endif
+supported_cairo_boilerplate_headers += $(cairo_boilerplate_cgl_headers)
+all_cairo_boilerplate_headers += $(cairo_boilerplate_cgl_headers)
+all_cairo_boilerplate_private += $(cairo_boilerplate_cgl_private)
+all_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_cgl_cxx_sources)
+all_cairo_boilerplate_sources += $(cairo_boilerplate_cgl_sources)
+ifeq ($(CAIRO_HAS_CGL_FUNCTIONS),1)
+enabled_cairo_boilerplate_headers += $(cairo_boilerplate_cgl_headers)
+enabled_cairo_boilerplate_private += $(cairo_boilerplate_cgl_private)
+enabled_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_cgl_cxx_sources)
+enabled_cairo_boilerplate_sources += $(cairo_boilerplate_cgl_sources)
+endif
+
supported_cairo_boilerplate_headers += $(cairo_boilerplate_wgl_headers)
all_cairo_boilerplate_headers += $(cairo_boilerplate_wgl_headers)
all_cairo_boilerplate_private += $(cairo_boilerplate_wgl_private)
@@ -528,15 +510,6 @@ enabled_cairo_boilerplate_private += $(cairo_boilerplate_user_private)
enabled_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_user_cxx_sources)
enabled_cairo_boilerplate_sources += $(cairo_boilerplate_user_sources)
-all_cairo_boilerplate_private += $(cairo_boilerplate_openmp_private) $(cairo_boilerplate_openmp_headers)
-all_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_openmp_cxx_sources)
-all_cairo_boilerplate_sources += $(cairo_boilerplate_openmp_sources)
-ifeq ($(CAIRO_HAS_OPENMP),1)
-enabled_cairo_boilerplate_private += $(cairo_boilerplate_openmp_private) $(cairo_boilerplate_openmp_headers)
-enabled_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_openmp_cxx_sources)
-enabled_cairo_boilerplate_sources += $(cairo_boilerplate_openmp_sources)
-endif
-
all_cairo_boilerplate_private += $(cairo_boilerplate_pthread_private) $(cairo_boilerplate_pthread_headers)
all_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_pthread_cxx_sources)
all_cairo_boilerplate_sources += $(cairo_boilerplate_pthread_sources)
diff --git a/boilerplate/README b/boilerplate/README
index 2a27c415c..2a27c415c 100755..100644
--- a/boilerplate/README
+++ b/boilerplate/README
diff --git a/boilerplate/cairo-boilerplate-beos.cpp b/boilerplate/cairo-boilerplate-beos.cpp
index 8a1b1afb5..8a1b1afb5 100755..100644
--- a/boilerplate/cairo-boilerplate-beos.cpp
+++ b/boilerplate/cairo-boilerplate-beos.cpp
diff --git a/boilerplate/cairo-boilerplate-cgl.c b/boilerplate/cairo-boilerplate-cgl.c
new file mode 100644
index 000000000..b4d1abe7d
--- /dev/null
+++ b/boilerplate/cairo-boilerplate-cgl.c
@@ -0,0 +1,150 @@
+/* Cairo - a vector graphics library with display and print output
+ *
+ * Copyright © 2009 Chris Wilson
+ * Copyright © 2015 Samsung Research America Inc - Silicon Valley
+ *
+ * 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 Chris Wilson.
+ */
+
+#include "cairo-boilerplate-private.h"
+
+#include <cairo-gl.h>
+
+#include <OpenGL/OpenGL.h>
+#include <OpenGL/gl.h>
+
+static const cairo_user_data_key_t gl_closure_key;
+
+typedef struct _cgl_target_closure {
+ CGLContextObj context;
+ cairo_device_t *device;
+ cairo_surface_t *surface;
+} cgl_target_closure_t;
+
+static void
+_cairo_boilerplate_cgl_cleanup (void *closure)
+{
+ cgl_target_closure_t *gltc = closure;
+
+ cairo_device_finish (gltc->device);
+ cairo_device_destroy (gltc->device);
+
+ CGLSetCurrentContext (NULL);
+ CGLDestroyContext (gltc->context);
+
+ free (gltc);
+}
+
+static cairo_surface_t *
+_cairo_boilerplate_cgl_create_surface (const char *name,
+ cairo_content_t content,
+ double width,
+ double height,
+ double max_width,
+ double max_height,
+ cairo_boilerplate_mode_t mode,
+ void **closure)
+{
+ cgl_target_closure_t *gltc;
+ cairo_surface_t *surface;
+ CGLPixelFormatObj pixelformat;
+ CGLContextObj context;
+ GLint npix;
+ CGLError error;
+
+ CGLPixelFormatAttribute attribs[] = {
+ kCGLPFAAlphaSize, 8,
+ kCGLPFAColorSize, 24,
+ kCGLPFAOpenGLProfile, kCGLOGLPVersion_3_2_Core,
+ kCGLPFAAccelerated,
+ 0
+ };
+
+ error = CGLChoosePixelFormat (attribs, &pixelformat, &npix);
+ if (error != kCGLNoError || ! pixelformat)
+ return NULL;
+
+ error = CGLCreateContext (pixelformat, NULL, &context);
+ if (error != kCGLNoError) {
+ CGLReleasePixelFormat (pixelformat);
+ return NULL;
+ }
+
+ CGLReleasePixelFormat (pixelformat);
+
+ gltc = xcalloc (1, sizeof (cgl_target_closure_t));
+ *closure = gltc;
+ gltc->context = context;
+
+ gltc->device = cairo_cgl_device_create (gltc->context);
+
+ if (width < 1)
+ width = 1;
+ if (height < 1)
+ height = 1;
+
+ gltc->surface = surface = cairo_gl_surface_create (gltc->device,
+ content,
+ ceil (width),
+ ceil (height));
+ if (cairo_surface_status (surface))
+ _cairo_boilerplate_cgl_cleanup (gltc);
+
+ return surface;
+}
+
+static void
+_cairo_boilerplate_cgl_synchronize (void *closure)
+{
+ cgl_target_closure_t *gltc = closure;
+
+ if (cairo_device_acquire (gltc->device))
+ return;
+
+ glFinish ();
+
+ cairo_device_release (gltc->device);
+}
+
+static const cairo_boilerplate_target_t targets[] = {
+ {
+ "cgl", "gl", NULL, NULL,
+ CAIRO_SURFACE_TYPE_GL, CAIRO_CONTENT_COLOR_ALPHA, 1,
+ "cairo_cgl_device_create",
+ _cairo_boilerplate_cgl_create_surface,
+ cairo_surface_create_similar,
+ NULL, NULL,
+ _cairo_boilerplate_get_image_surface,
+ cairo_surface_write_to_png,
+ _cairo_boilerplate_cgl_cleanup,
+ _cairo_boilerplate_cgl_synchronize,
+ NULL,
+ TRUE, FALSE, FALSE
+ }
+};
+CAIRO_BOILERPLATE (egl, targets)
diff --git a/boilerplate/cairo-boilerplate-cogl.c b/boilerplate/cairo-boilerplate-cogl.c
index e39ad333d..e39ad333d 100755..100644
--- a/boilerplate/cairo-boilerplate-cogl.c
+++ b/boilerplate/cairo-boilerplate-cogl.c
diff --git a/boilerplate/cairo-boilerplate-directfb.c b/boilerplate/cairo-boilerplate-directfb.c
index a479011d9..a479011d9 100755..100644
--- a/boilerplate/cairo-boilerplate-directfb.c
+++ b/boilerplate/cairo-boilerplate-directfb.c
diff --git a/boilerplate/cairo-boilerplate-drm.c b/boilerplate/cairo-boilerplate-drm.c
index 214ce50cd..79d9229f6 100755..100644
--- a/boilerplate/cairo-boilerplate-drm.c
+++ b/boilerplate/cairo-boilerplate-drm.c
@@ -52,10 +52,16 @@ _cairo_boilerplate_drm_create_surface (const char *name,
return NULL; /* skip tests if no supported h/w found */
switch (content) {
- case CAIRO_CONTENT_ALPHA: format = CAIRO_FORMAT_A8; break;
- case CAIRO_CONTENT_COLOR: format = CAIRO_FORMAT_RGB24; break;
+ case CAIRO_CONTENT_ALPHA:
+ format = CAIRO_FORMAT_A8;
+ break;
+ case CAIRO_CONTENT_COLOR:
+ format = CAIRO_FORMAT_RGB24;
+ break;
+ case CAIRO_CONTENT_COLOR_ALPHA:
default:
- case CAIRO_CONTENT_COLOR_ALPHA: format = CAIRO_FORMAT_ARGB32; break;
+ format = CAIRO_FORMAT_ARGB32;
+ break;
}
return *closure = cairo_drm_surface_create (device, format, width, height);
diff --git a/boilerplate/cairo-boilerplate-egl.c b/boilerplate/cairo-boilerplate-egl.c
index dd62ea8a0..c5b126065 100755..100644
--- a/boilerplate/cairo-boilerplate-egl.c
+++ b/boilerplate/cairo-boilerplate-egl.c
@@ -41,6 +41,14 @@ extern void glFinish (void);
#include <GL/gl.h>
#elif CAIRO_HAS_GLESV2_SURFACE
#include <GLES2/gl2.h>
+#elif CAIRO_HAS_GLESV3_SURFACE
+#include <GLES3/gl3.h>
+#endif
+
+// For Wayland-egl
+#ifdef HAVE_WAYLAND
+#include <wayland-egl.h>
+#include <wayland-client.h>
#endif
static const cairo_user_data_key_t gl_closure_key;
@@ -91,15 +99,16 @@ _cairo_boilerplate_egl_create_surface (const char *name,
EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
#if CAIRO_HAS_GL_SURFACE
EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
-#elif CAIRO_HAS_GLESV2_SURFACE
+#elif CAIRO_HAS_GLESV2_SURFACE || CAIRO_HAS_GLESV3_SURFACE
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
#endif
- EGL_SAMPLES, 4,
EGL_NONE
};
const EGLint ctx_attribs[] = {
#if CAIRO_HAS_GLESV2_SURFACE
EGL_CONTEXT_CLIENT_VERSION, 2,
+#elif CAIRO_HAS_GLESV3_SURFACE
+ EGL_CONTEXT_CLIENT_VERSION, 3,
#endif
EGL_NONE
};
@@ -107,7 +116,15 @@ _cairo_boilerplate_egl_create_surface (const char *name,
gltc = xcalloc (1, sizeof (egl_target_closure_t));
*closure = gltc;
+#ifdef HAVE_WAYLAND
+ static struct wl_display *display;
+ display = wl_display_connect (NULL);
+ struct wl_registry *registry = wl_display_get_registry (display);
+ wl_display_dispatch (display);
+ gltc->dpy = eglGetDisplay (display);
+#else
gltc->dpy = eglGetDisplay (EGL_DEFAULT_DISPLAY);
+#endif
if (! eglInitialize (gltc->dpy, &major, &minor)) {
free (gltc);
@@ -122,7 +139,7 @@ _cairo_boilerplate_egl_create_surface (const char *name,
#if CAIRO_HAS_GL_SURFACE
eglBindAPI (EGL_OPENGL_API);
-#elif CAIRO_HAS_GLESV2_SURFACE
+#elif CAIRO_HAS_GLESV2_SURFACE || CAIRO_HAS_GLESV3_SURFACE
eglBindAPI (EGL_OPENGL_ES_API);
#endif
@@ -135,7 +152,8 @@ _cairo_boilerplate_egl_create_surface (const char *name,
}
gltc->device = cairo_egl_device_create (gltc->dpy, gltc->ctx);
- cairo_gl_device_set_thread_aware (gltc->device, FALSE);
+ if (mode == CAIRO_BOILERPLATE_MODE_PERF)
+ cairo_gl_device_set_thread_aware(gltc->device, FALSE);
if (width < 1)
width = 1;
diff --git a/boilerplate/cairo-boilerplate-evas-gl.c b/boilerplate/cairo-boilerplate-evas-gl.c
index 151e6af29..0b98de80a 100755..100644
--- a/boilerplate/cairo-boilerplate-evas-gl.c
+++ b/boilerplate/cairo-boilerplate-evas-gl.c
@@ -32,7 +32,6 @@
*/
#include "cairo-boilerplate-private.h"
-
#include <cairo-gl.h>
#include <cairo-evas-gl.h>
#include <Ecore_Evas.h>
@@ -90,7 +89,13 @@ _cairo_boilerplate_evas_gl_create_surface (const char *name,
ecore_init ();
ecore_evas_init ();
+
+#ifdef HAVE_WAYLAND //Wayland (Tizen 3.0)
+ ee = ecore_evas_wayland_egl_new (NULL, 0, 0, 0, ceil (width), ceil (height), EINA_TRUE);
+#else
ee = ecore_evas_gl_x11_new (NULL, 0, 0, 0, ceil (width), ceil (height));;
+#endif
+
canvas = ecore_evas_get (ee);
gltc = xcalloc (1, sizeof (evas_gl_target_closure_t));
@@ -99,7 +104,7 @@ _cairo_boilerplate_evas_gl_create_surface (const char *name,
gltc->evas_gl = evas_gl_new (canvas);
gltc->evas_ctx = evas_gl_context_create (gltc->evas_gl, NULL);
gltc->evas_api = evas_gl_api_get (gltc->evas_gl);
-
+
gltc->device = cairo_evas_gl_device_create (gltc->evas_gl, gltc->evas_ctx);
gltc->surface = surface =
diff --git a/boilerplate/cairo-boilerplate-getopt.c b/boilerplate/cairo-boilerplate-getopt.c
index 53b150c29..53b150c29 100755..100644
--- a/boilerplate/cairo-boilerplate-getopt.c
+++ b/boilerplate/cairo-boilerplate-getopt.c
diff --git a/boilerplate/cairo-boilerplate-getopt.h b/boilerplate/cairo-boilerplate-getopt.h
index 74bce14c7..74bce14c7 100755..100644
--- a/boilerplate/cairo-boilerplate-getopt.h
+++ b/boilerplate/cairo-boilerplate-getopt.h
diff --git a/boilerplate/cairo-boilerplate-glx.c b/boilerplate/cairo-boilerplate-glx.c
index 52cd99f9b..3d582151e 100755..100644
--- a/boilerplate/cairo-boilerplate-glx.c
+++ b/boilerplate/cairo-boilerplate-glx.c
@@ -82,13 +82,13 @@ _cairo_boilerplate_gl_create_surface (const char *name,
GLX_BLUE_SIZE, 1,
GLX_ALPHA_SIZE, 1,
GLX_DOUBLEBUFFER,
- None };
+ GLX_NONE };
int rgb_attribs[] = { GLX_RGBA,
GLX_RED_SIZE, 1,
GLX_GREEN_SIZE, 1,
GLX_BLUE_SIZE, 1,
GLX_DOUBLEBUFFER,
- None };
+ GLX_NONE };
XVisualInfo *visinfo;
GLXContext ctx;
gl_target_closure_t *gltc;
@@ -135,6 +135,9 @@ _cairo_boilerplate_gl_create_surface (const char *name,
gltc->ctx = ctx;
gltc->device = cairo_glx_device_create (dpy, ctx);
+ if (mode == CAIRO_BOILERPLATE_MODE_PERF)
+ cairo_gl_device_set_thread_aware(gltc->device, FALSE);
+
gltc->surface = surface = cairo_gl_surface_create (gltc->device,
content, width, height);
if (cairo_surface_status (surface))
@@ -233,7 +236,7 @@ _cairo_boilerplate_gl_create_window (const char *name,
GLX_BLUE_SIZE, 1,
GLX_ALPHA_SIZE, 1,
GLX_DOUBLEBUFFER,
- None };
+ GLX_NONE };
gltc = calloc (1, sizeof (gl_target_closure_t));
*closure = gltc;
@@ -265,7 +268,7 @@ _cairo_boilerplate_gl_create_window_msaa (const char *name,
GLX_SAMPLES, 4,
GLX_SAMPLE_BUFFERS, 1,
GLX_DOUBLEBUFFER,
- None };
+ GLX_NONE };
gltc = calloc (1, sizeof (gl_target_closure_t));
*closure = gltc;
@@ -296,7 +299,7 @@ _cairo_boilerplate_gl_create_window_db (const char *name,
GLX_BLUE_SIZE, 1,
GLX_ALPHA_SIZE, 1,
GLX_DOUBLEBUFFER,
- None };
+ GLX_NONE };
gltc = calloc (1, sizeof (gl_target_closure_t));
*closure = gltc;
diff --git a/boilerplate/cairo-boilerplate-pdf.c b/boilerplate/cairo-boilerplate-pdf.c
index d76d13951..177cdf174 100755..100644
--- a/boilerplate/cairo-boilerplate-pdf.c
+++ b/boilerplate/cairo-boilerplate-pdf.c
@@ -54,8 +54,6 @@ typedef struct _pdf_target_closure
cairo_surface_t *target;
} pdf_target_closure_t;
-#define ARRAY_LENGTH(__array) ((int) (sizeof (__array) / sizeof (__array[0])))
-
static cairo_surface_t *
_cairo_boilerplate_pdf_create_surface (const char *name,
cairo_content_t content,
diff --git a/boilerplate/cairo-boilerplate-private.h b/boilerplate/cairo-boilerplate-private.h
index a7a2dd0eb..d16a645b2 100755..100644
--- a/boilerplate/cairo-boilerplate-private.h
+++ b/boilerplate/cairo-boilerplate-private.h
@@ -41,7 +41,7 @@ _cairo_boilerplate_register_backend (const cairo_boilerplate_target_t *targets,
void _register_##name__ (void); \
void _register_##name__ (void) { \
_cairo_boilerplate_register_backend (targets__, \
- sizeof (targets__) / sizeof (targets__[0])); \
+ ARRAY_LENGTH(targets__)); \
}
#define CAIRO_NO_BOILERPLATE(name__) \
diff --git a/boilerplate/cairo-boilerplate-ps.c b/boilerplate/cairo-boilerplate-ps.c
index ae61239f3..ae61239f3 100755..100644
--- a/boilerplate/cairo-boilerplate-ps.c
+++ b/boilerplate/cairo-boilerplate-ps.c
diff --git a/boilerplate/cairo-boilerplate-qt.cpp b/boilerplate/cairo-boilerplate-qt.cpp
index 31c081483..31c081483 100755..100644
--- a/boilerplate/cairo-boilerplate-qt.cpp
+++ b/boilerplate/cairo-boilerplate-qt.cpp
diff --git a/boilerplate/cairo-boilerplate-quartz.c b/boilerplate/cairo-boilerplate-quartz.c
index d4ca35383..d4ca35383 100755..100644
--- a/boilerplate/cairo-boilerplate-quartz.c
+++ b/boilerplate/cairo-boilerplate-quartz.c
diff --git a/boilerplate/cairo-boilerplate-scaled-font.h b/boilerplate/cairo-boilerplate-scaled-font.h
index a7ba2fede..a7ba2fede 100755..100644
--- a/boilerplate/cairo-boilerplate-scaled-font.h
+++ b/boilerplate/cairo-boilerplate-scaled-font.h
diff --git a/boilerplate/cairo-boilerplate-script.c b/boilerplate/cairo-boilerplate-script.c
index da8ae3bbd..da8ae3bbd 100755..100644
--- a/boilerplate/cairo-boilerplate-script.c
+++ b/boilerplate/cairo-boilerplate-script.c
diff --git a/boilerplate/cairo-boilerplate-skia.c b/boilerplate/cairo-boilerplate-skia.c
index c06e7f054..c06e7f054 100755..100644
--- a/boilerplate/cairo-boilerplate-skia.c
+++ b/boilerplate/cairo-boilerplate-skia.c
diff --git a/boilerplate/cairo-boilerplate-svg.c b/boilerplate/cairo-boilerplate-svg.c
index 797106ea6..797106ea6 100755..100644
--- a/boilerplate/cairo-boilerplate-svg.c
+++ b/boilerplate/cairo-boilerplate-svg.c
diff --git a/boilerplate/cairo-boilerplate-system.c b/boilerplate/cairo-boilerplate-system.c
index ec23341a4..ec23341a4 100755..100644
--- a/boilerplate/cairo-boilerplate-system.c
+++ b/boilerplate/cairo-boilerplate-system.c
diff --git a/boilerplate/cairo-boilerplate-system.h b/boilerplate/cairo-boilerplate-system.h
index 28165671b..28165671b 100755..100644
--- a/boilerplate/cairo-boilerplate-system.h
+++ b/boilerplate/cairo-boilerplate-system.h
diff --git a/boilerplate/cairo-boilerplate-test-surfaces.c b/boilerplate/cairo-boilerplate-test-surfaces.c
index 293b77fff..293b77fff 100755..100644
--- a/boilerplate/cairo-boilerplate-test-surfaces.c
+++ b/boilerplate/cairo-boilerplate-test-surfaces.c
diff --git a/boilerplate/cairo-boilerplate-vg.c b/boilerplate/cairo-boilerplate-vg.c
index ee32b3c62..692765745 100755..100644
--- a/boilerplate/cairo-boilerplate-vg.c
+++ b/boilerplate/cairo-boilerplate-vg.c
@@ -87,7 +87,7 @@ _cairo_boilerplate_vg_create_surface_glx (const char *name,
GLX_BLUE_SIZE, 1,
GLX_ALPHA_SIZE, 1,
GLX_DOUBLEBUFFER,
- None
+ GLX_NONE
};
int rgb_attribs[] = {
GLX_RGBA,
@@ -95,7 +95,7 @@ _cairo_boilerplate_vg_create_surface_glx (const char *name,
GLX_GREEN_SIZE, 1,
GLX_BLUE_SIZE, 1,
GLX_DOUBLEBUFFER,
- None
+ GLX_NONE
};
XVisualInfo *vi;
Display *dpy;
@@ -215,7 +215,7 @@ _cairo_boilerplate_vg_create_surface_egl (const char *name,
EGL_ALPHA_SIZE, 8,
EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
EGL_RENDERABLE_TYPE, EGL_OPENVG_BIT,
- None
+ EGL_NONE
};
int rgb_attribs[] = {
EGL_RED_SIZE, 8,
@@ -225,7 +225,7 @@ _cairo_boilerplate_vg_create_surface_egl (const char *name,
EGL_VG_ALPHA_FORMAT, EGL_VG_ALPHA_FORMAT_PRE_BIT,
EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
EGL_RENDERABLE_TYPE, EGL_OPENVG_BIT,
- None
+ EGL_NONE
};
int dummy_attribs[] = {
EGL_WIDTH, 8, EGL_HEIGHT, 8,
diff --git a/boilerplate/cairo-boilerplate-wgl.c b/boilerplate/cairo-boilerplate-wgl.c
index 908817788..908817788 100755..100644
--- a/boilerplate/cairo-boilerplate-wgl.c
+++ b/boilerplate/cairo-boilerplate-wgl.c
diff --git a/boilerplate/cairo-boilerplate-win32-printing.c b/boilerplate/cairo-boilerplate-win32-printing.c
index 625d52c53..625d52c53 100755..100644
--- a/boilerplate/cairo-boilerplate-win32-printing.c
+++ b/boilerplate/cairo-boilerplate-win32-printing.c
diff --git a/boilerplate/cairo-boilerplate-win32.c b/boilerplate/cairo-boilerplate-win32.c
index 7469cc749..7469cc749 100755..100644
--- a/boilerplate/cairo-boilerplate-win32.c
+++ b/boilerplate/cairo-boilerplate-win32.c
diff --git a/boilerplate/cairo-boilerplate-xcb.c b/boilerplate/cairo-boilerplate-xcb.c
index ffefecb93..cc9b422e9 100755..100644
--- a/boilerplate/cairo-boilerplate-xcb.c
+++ b/boilerplate/cairo-boilerplate-xcb.c
@@ -828,7 +828,7 @@ static const cairo_boilerplate_target_t targets[] = {
FALSE, FALSE, FALSE
},
{
- "xcb-render-0.0", "xlib-fallback", NULL, NULL,
+ "xcb-render-0_0", "xlib-fallback", NULL, NULL,
CAIRO_SURFACE_TYPE_XCB, CAIRO_CONTENT_COLOR_ALPHA, 1,
"cairo_xcb_surface_create_with_xrender_format",
_cairo_boilerplate_xcb_create_render_0_0,
@@ -843,7 +843,7 @@ static const cairo_boilerplate_target_t targets[] = {
FALSE, FALSE, FALSE
},
{
- "xcb-render-0.0", "xlib-fallback", NULL, NULL,
+ "xcb-render-0_0", "xlib-fallback", NULL, NULL,
CAIRO_SURFACE_TYPE_XCB, CAIRO_CONTENT_COLOR, 1,
"cairo_xcb_surface_create_with_xrender_format",
_cairo_boilerplate_xcb_create_render_0_0,
diff --git a/boilerplate/cairo-boilerplate-xlib.c b/boilerplate/cairo-boilerplate-xlib.c
index aed075f67..f3d559806 100755..100644
--- a/boilerplate/cairo-boilerplate-xlib.c
+++ b/boilerplate/cairo-boilerplate-xlib.c
@@ -248,10 +248,16 @@ _cairo_boilerplate_xlib_create_similar (cairo_surface_t *other,
similar->dpy = cairo_xlib_surface_get_display (other);
switch (content) {
+ case CAIRO_CONTENT_COLOR:
+ format = PictStandardRGB24;
+ break;
+ case CAIRO_CONTENT_ALPHA:
+ format = PictStandardA8;
+ break;
+ case CAIRO_CONTENT_COLOR_ALPHA:
default:
- case CAIRO_CONTENT_COLOR_ALPHA: format = PictStandardARGB32; break;
- case CAIRO_CONTENT_COLOR: format = PictStandardRGB24; break;
- case CAIRO_CONTENT_ALPHA: format = PictStandardA8; break;
+ format = PictStandardARGB32;
+ break;
}
xrender_format = XRenderFindStandardFormat (similar->dpy, format);
diff --git a/boilerplate/cairo-boilerplate-xlib.h b/boilerplate/cairo-boilerplate-xlib.h
index 9a6391812..9a6391812 100755..100644
--- a/boilerplate/cairo-boilerplate-xlib.h
+++ b/boilerplate/cairo-boilerplate-xlib.h
diff --git a/boilerplate/cairo-boilerplate.c b/boilerplate/cairo-boilerplate.c
index 41db8b887..7fdbf798b 100755..100644
--- a/boilerplate/cairo-boilerplate.c
+++ b/boilerplate/cairo-boilerplate.c
@@ -112,13 +112,19 @@ cairo_boilerplate_format_from_content (cairo_content_t content)
cairo_format_t format;
switch (content) {
- case CAIRO_CONTENT_COLOR: format = CAIRO_FORMAT_RGB24; break;
- case CAIRO_CONTENT_COLOR_ALPHA: format = CAIRO_FORMAT_ARGB32; break;
- case CAIRO_CONTENT_ALPHA: format = CAIRO_FORMAT_A8; break;
- default:
- assert (0); /* not reached */
- format = CAIRO_FORMAT_INVALID;
- break;
+ case CAIRO_CONTENT_COLOR:
+ format = CAIRO_FORMAT_RGB24;
+ break;
+ case CAIRO_CONTENT_COLOR_ALPHA:
+ format = CAIRO_FORMAT_ARGB32;
+ break;
+ case CAIRO_CONTENT_ALPHA:
+ format = CAIRO_FORMAT_A8;
+ break;
+ default:
+ assert (0); /* not reached */
+ format = CAIRO_FORMAT_INVALID;
+ break;
}
return format;
@@ -163,10 +169,16 @@ _cairo_boilerplate_image_create_similar (cairo_surface_t *other,
void *ptr;
switch (content) {
- case CAIRO_CONTENT_ALPHA: format = CAIRO_FORMAT_A8; break;
- case CAIRO_CONTENT_COLOR: format = CAIRO_FORMAT_RGB24; break;
+ case CAIRO_CONTENT_ALPHA:
+ format = CAIRO_FORMAT_A8;
+ break;
+ case CAIRO_CONTENT_COLOR:
+ format = CAIRO_FORMAT_RGB24;
+ break;
+ case CAIRO_CONTENT_COLOR_ALPHA:
default:
- case CAIRO_CONTENT_COLOR_ALPHA: format = CAIRO_FORMAT_ARGB32; break;
+ format = CAIRO_FORMAT_ARGB32;
+ break;
}
stride = cairo_format_stride_for_width(format, width);
@@ -206,10 +218,16 @@ _cairo_boilerplate_image16_create_similar (cairo_surface_t *other,
void *ptr;
switch (content) {
- case CAIRO_CONTENT_ALPHA: format = CAIRO_FORMAT_A8; break;
- case CAIRO_CONTENT_COLOR: format = CAIRO_FORMAT_RGB16_565; break;
+ case CAIRO_CONTENT_ALPHA:
+ format = CAIRO_FORMAT_A8;
+ break;
+ case CAIRO_CONTENT_COLOR:
+ format = CAIRO_FORMAT_RGB16_565;
+ break;
+ case CAIRO_CONTENT_COLOR_ALPHA:
default:
- case CAIRO_CONTENT_COLOR_ALPHA: format = CAIRO_FORMAT_ARGB32; break;
+ format = CAIRO_FORMAT_ARGB32;
+ break;
}
stride = cairo_format_stride_for_width(format, width);
@@ -504,6 +522,28 @@ _cairo_boilerplate_register_backend (const cairo_boilerplate_target_t *targets,
}
static cairo_bool_t
+_cairo_boilerplate_target_format_matches_name (const cairo_boilerplate_target_t *target,
+ const char *tcontent_name,
+ const char *tcontent_end)
+{
+ char const *content_name;
+ const char *content_end = tcontent_end;
+ size_t content_len;
+
+ content_name = _cairo_boilerplate_content_visible_name (target->content);
+ if (tcontent_end)
+ content_len = content_end - tcontent_name;
+ else
+ content_len = strlen(tcontent_name);
+ if (strlen(content_name) != content_len)
+ return FALSE;
+ if (0 == strncmp (content_name, tcontent_name, content_len))
+ return TRUE;
+
+ return FALSE;
+}
+
+static cairo_bool_t
_cairo_boilerplate_target_matches_name (const cairo_boilerplate_target_t *target,
const char *tname,
const char *end)
@@ -514,6 +554,8 @@ _cairo_boilerplate_target_matches_name (const cairo_boilerplate_target_t *target
size_t name_len;
size_t content_len;
+ if (content_start >= end)
+ content_start = NULL;
if (content_start != NULL)
end = content_start++;
@@ -577,13 +619,38 @@ cairo_boilerplate_get_targets (int *pnum_targets,
list != NULL;
list = list->next)
{
- const cairo_boilerplate_target_t *target = list->target;
- if (_cairo_boilerplate_target_matches_name (target, tname, end)) {
- /* realloc isn't exactly the best thing here, but meh. */
- targets_to_test = xrealloc (targets_to_test, sizeof(cairo_boilerplate_target_t *) * (num_targets+1));
- targets_to_test[num_targets++] = target;
- found = 1;
- }
+ const cairo_boilerplate_target_t *target = list->target;
+ const char *tcontent_name;
+ const char *tcontent_end;
+ if (_cairo_boilerplate_target_matches_name (target, tname, end)) {
+ if ((tcontent_name = getenv ("CAIRO_TEST_TARGET_FORMAT")) != NULL && *tcontent_name) {
+ while(tcontent_name) {
+ tcontent_end = strpbrk (tcontent_name, " \t\r\n;:,");
+ if (tcontent_end == tcontent_name) {
+ tcontent_name = tcontent_end + 1;
+ continue;
+ }
+ if(_cairo_boilerplate_target_format_matches_name (target,
+ tcontent_name, tcontent_end)) {
+ /* realloc isn't exactly the best thing here, but meh. */
+ targets_to_test = xrealloc (targets_to_test,
+ sizeof(cairo_boilerplate_target_t *) * (num_targets+1));
+ targets_to_test[num_targets++] = target;
+ found = 1;
+ }
+
+ if (tcontent_end)
+ tcontent_end++;
+ tcontent_name = tcontent_end;
+ }
+ } else {
+ /* realloc isn't exactly the best thing here, but meh. */
+ targets_to_test = xrealloc (targets_to_test,
+ sizeof(cairo_boilerplate_target_t *) * (num_targets+1));
+ targets_to_test[num_targets++] = target;
+ found = 1;
+ }
+ }
}
if (!found) {
@@ -616,20 +683,62 @@ cairo_boilerplate_get_targets (int *pnum_targets,
tname = end;
}
} else {
- /* check all compiled in targets */
- num_targets = 0;
- for (list = cairo_boilerplate_targets; list != NULL; list = list->next)
- num_targets++;
+ int found = 0;
+ int not_found_targets = 0;
+ num_targets = 0;
+ targets_to_test = xmalloc (sizeof(cairo_boilerplate_target_t*) * num_targets);
+ for (list = cairo_boilerplate_targets; list != NULL; list = list->next)
+ {
+ const cairo_boilerplate_target_t *target = list->target;
+ const char *tcontent_name;
+ const char *tcontent_end;
+ if ((tcontent_name = getenv ("CAIRO_TEST_TARGET_FORMAT")) != NULL && *tcontent_name) {
+ while(tcontent_name) {
+ tcontent_end = strpbrk (tcontent_name, " \t\r\n;:,");
+ if (tcontent_end == tcontent_name) {
+ tcontent_name = tcontent_end + 1;
+ continue;
+ }
+ if (_cairo_boilerplate_target_format_matches_name (target,
+ tcontent_name, tcontent_end)) {
+ /* realloc isn't exactly the best thing here, but meh. */
+ targets_to_test = xrealloc (targets_to_test,
+ sizeof(cairo_boilerplate_target_t *) * (num_targets+1));
+ targets_to_test[num_targets++] = target;
+ found =1;
+ }
+ else
+ {
+ not_found_targets++;
+ }
+
+ if (tcontent_end)
+ tcontent_end++;
+
+ tcontent_name = tcontent_end;
+ }
+ }
+ else
+ {
+ num_targets++;
+ }
+ }
+ if (!found)
+ {
+ /* check all compiled in targets */
+ num_targets = num_targets + not_found_targets;
+ targets_to_test = xrealloc (targets_to_test,
+ sizeof(cairo_boilerplate_target_t*) * num_targets);
+ num_targets = 0;
+ for (list = cairo_boilerplate_targets;
+ list != NULL;
+ list = list->next)
+ {
+ const cairo_boilerplate_target_t *target = list->target;
+ targets_to_test[num_targets++] = target;
+ }
+ }
- targets_to_test = xmalloc (sizeof(cairo_boilerplate_target_t*) * num_targets);
- num_targets = 0;
- for (list = cairo_boilerplate_targets;
- list != NULL;
- list = list->next)
- {
- const cairo_boilerplate_target_t *target = list->target;
- targets_to_test[num_targets++] = target;
- }
}
/* exclude targets as specified by the user */
@@ -679,10 +788,13 @@ cairo_boilerplate_get_image_target (cairo_content_t content)
_cairo_boilerplate_register_all ();
switch (content) {
+ case CAIRO_CONTENT_COLOR:
+ return &builtin_targets[1];
+ case CAIRO_CONTENT_COLOR_ALPHA:
+ return &builtin_targets[0];
+ case CAIRO_CONTENT_ALPHA:
default:
- case CAIRO_CONTENT_ALPHA: return NULL;
- case CAIRO_CONTENT_COLOR: return &builtin_targets[1];
- case CAIRO_CONTENT_COLOR_ALPHA: return &builtin_targets[0];
+ return NULL;
}
}
@@ -830,14 +942,14 @@ cairo_boilerplate_open_any2ppm (const char *filename,
}
*close_cb = fclose;
- return fdopen (sk, "r");
+ return fdopen (sk, "rb");
POPEN:
#endif
*close_cb = pclose;
sprintf (command, "%s %s %d", any2ppm, filename, page);
- return popen (command, "r");
+ return popen (command, "rb");
}
static cairo_bool_t
diff --git a/boilerplate/cairo-boilerplate.h b/boilerplate/cairo-boilerplate.h
index 461b98b69..515bb03bc 100755..100644
--- a/boilerplate/cairo-boilerplate.h
+++ b/boilerplate/cairo-boilerplate.h
@@ -94,6 +94,10 @@
#define M_PI 3.14159265358979323846
#endif
+#ifndef ARRAY_LENGTH
+#define ARRAY_LENGTH(__array) ((int) (sizeof (__array) / sizeof (__array[0])))
+#endif
+
CAIRO_BEGIN_DECLS
/* A fake format we use for the flattened ARGB output of the PS and
@@ -113,7 +117,12 @@ cairo_boilerplate_format_from_content (cairo_content_t content);
typedef enum {
CAIRO_BOILERPLATE_MODE_TEST,
- CAIRO_BOILERPLATE_MODE_PERF
+ CAIRO_BOILERPLATE_MODE_PERF,
+
+ /* This will allow running performance test with threads. The
+ * GL backend is very slow on some drivers when run with thread
+ * awareness turned on. */
+ CAIRO_BOILERPLATE_MODE_PERF_THREADS,
} cairo_boilerplate_mode_t;
typedef cairo_surface_t *
diff --git a/boilerplate/check-link.c b/boilerplate/check-link.c
index f16444878..f16444878 100755..100644
--- a/boilerplate/check-link.c
+++ b/boilerplate/check-link.c
diff --git a/boilerplate/make-cairo-boilerplate-constructors.sh b/boilerplate/make-cairo-boilerplate-constructors.sh
index 09716ca9e..09716ca9e 100755..100644
--- a/boilerplate/make-cairo-boilerplate-constructors.sh
+++ b/boilerplate/make-cairo-boilerplate-constructors.sh
diff --git a/build/.gitignore b/build/.gitignore
index 53f31d770..2f0183557 100755..100644
--- a/build/.gitignore
+++ b/build/.gitignore
@@ -1,3 +1,4 @@
+ar-lib
compile
config.guess
config.sub
@@ -10,3 +11,6 @@ mkinstalldirs
#Makefile.win32.features-h
libtool.m4
lt*.m4
+gtk-doc.m4
+test-driver
+
diff --git a/build/Makefile.am.analysis b/build/Makefile.am.analysis
index a44077ab4..a44077ab4 100755..100644
--- a/build/Makefile.am.analysis
+++ b/build/Makefile.am.analysis
diff --git a/build/Makefile.am.changelog b/build/Makefile.am.changelog
index 07e603695..07e603695 100755..100644
--- a/build/Makefile.am.changelog
+++ b/build/Makefile.am.changelog
diff --git a/build/Makefile.am.common b/build/Makefile.am.common
index b955af58f..b955af58f 100755..100644
--- a/build/Makefile.am.common
+++ b/build/Makefile.am.common
diff --git a/build/Makefile.am.gtk-doc b/build/Makefile.am.gtk-doc
index c3d642b09..c3d642b09 100755..100644
--- a/build/Makefile.am.gtk-doc
+++ b/build/Makefile.am.gtk-doc
diff --git a/build/Makefile.am.releasing b/build/Makefile.am.releasing
index b17faabce..b17faabce 100755..100644
--- a/build/Makefile.am.releasing
+++ b/build/Makefile.am.releasing
diff --git a/build/Makefile.win32.common b/build/Makefile.win32.common
index 01a38cd32..7d7e9735f 100755..100644
--- a/build/Makefile.win32.common
+++ b/build/Makefile.win32.common
@@ -23,18 +23,29 @@ CFG_CFLAGS := -MD -O2
CFG_LDFLAGS :=
endif
-PIXMAN_CFLAGS := -I$(top_srcdir)/../pixman/pixman
-PIXMAN_LIBS := $(top_builddir)/../pixman/pixman/$(CFG)/pixman-1.lib
+ifeq ($(PIXMAN_PATH),)
+PIXMAN_PATH := $(top_builddir)/../pixman
+endif
+PIXMAN_CFLAGS := -I$(PIXMAN_PATH)/pixman/
+PIXMAN_LIBS := $(PIXMAN_PATH)/pixman/$(CFG)/pixman-1.lib
CAIRO_LIBS = gdi32.lib msimg32.lib user32.lib
+
ifeq ($(CAIRO_HAS_PNG_FUNCTIONS),1)
-LIBPNG_CFLAGS += -I$(top_srcdir)/../libpng/
-CAIRO_LIBS += $(top_builddir)/../libpng/libpng.lib
+ifeq ($(LIBPNG_PATH),)
+LIBPNG_PATH := $(top_builddir)/../libpng
+endif
+LIBPNG_CFLAGS += -I$(LIBPNG_PATH)/
+CAIRO_LIBS += $(LIBPNG_PATH)/libpng.lib
endif
+
ifeq ($(CAIRO_HAS_PS_SURFACE)$(CAIRO_HAS_PDF_SURFACE),00)
else
-ZLIB_CFLAGS += -I$(top_srcdir)/../zlib/
-CAIRO_LIBS += $(top_builddir)/../zlib/zdll.lib
+ifeq ($(ZLIB_PATH),)
+ZLIB_PATH := $(top_builddir)/../zlib
+endif
+ZLIB_CFLAGS += -I$(ZLIB_PATH)/
+CAIRO_LIBS += $(ZLIB_PATH)/zdll.lib
endif
DEFAULT_CFLAGS = -nologo $(CFG_CFLAGS)
diff --git a/build/Makefile.win32.features b/build/Makefile.win32.features
index cf7721ad2..5a5848da6 100755..100644
--- a/build/Makefile.win32.features
+++ b/build/Makefile.win32.features
@@ -1,7 +1,5 @@
# Generated by configure. Modify to customize.
-CAIRO_HAS_TLS=0
-CAIRO_HAS_PTHREAD_SETSPECIFIC=0
CAIRO_HAS_XLIB_SURFACE=0
CAIRO_HAS_XLIB_XRENDER_SURFACE=0
CAIRO_HAS_XCB_SURFACE=0
@@ -25,10 +23,10 @@ CAIRO_HAS_GLESV2_SURFACE=0
CAIRO_HAS_GLESV3_SURFACE=0
CAIRO_HAS_COGL_SURFACE=0
CAIRO_HAS_DIRECTFB_SURFACE=0
-CAIRO_HAS_TG_SURFACE=0
CAIRO_HAS_VG_SURFACE=0
CAIRO_HAS_EGL_FUNCTIONS=0
CAIRO_HAS_GLX_FUNCTIONS=0
+CAIRO_HAS_CGL_FUNCTIONS=0
CAIRO_HAS_WGL_FUNCTIONS=0
CAIRO_HAS_SCRIPT_SURFACE=1
CAIRO_HAS_FT_FONT=0
@@ -39,7 +37,6 @@ CAIRO_HAS_SVG_SURFACE=1
CAIRO_HAS_TEST_SURFACES=0
CAIRO_HAS_TEE_SURFACE=0
CAIRO_HAS_XML_SURFACE=0
-CAIRO_HAS_OPENMP=0
CAIRO_HAS_PTHREAD=0
CAIRO_HAS_GOBJECT_FUNCTIONS=0
CAIRO_HAS_TRACE=0
diff --git a/build/Makefile.win32.features-h b/build/Makefile.win32.features-h
index f5164d71b..6c0e91f8f 100755..100644
--- a/build/Makefile.win32.features-h
+++ b/build/Makefile.win32.features-h
@@ -5,12 +5,6 @@ $(top_srcdir)/src/cairo-features.h: $(top_srcdir)/build/Makefile.win32.features
@echo "/* Generated by Makefile.win32.features-h. Do not edit. */" > $(top_srcdir)/src/cairo-features.h
@echo "#ifndef CAIRO_FEATURES_H" >> $(top_srcdir)/src/cairo-features.h
@echo "#define CAIRO_FEATURES_H 1" >> $(top_srcdir)/src/cairo-features.h
-ifeq ($(CAIRO_HAS_TLS),1)
- @echo "#define CAIRO_HAS_TLS 1" >> $(top_srcdir)/src/cairo-features.h
-endif
-ifeq ($(CAIRO_HAS_PTHREAD_SETSPECIFIC),1)
- @echo "#define CAIRO_HAS_PTHREAD_SETSPECIFIC 1" >> $(top_srcdir)/src/cairo-features.h
-endif
ifeq ($(CAIRO_HAS_XLIB_SURFACE),1)
@echo "#define CAIRO_HAS_XLIB_SURFACE 1" >> $(top_srcdir)/src/cairo-features.h
endif
@@ -80,9 +74,6 @@ endif
ifeq ($(CAIRO_HAS_DIRECTFB_SURFACE),1)
@echo "#define CAIRO_HAS_DIRECTFB_SURFACE 1" >> $(top_srcdir)/src/cairo-features.h
endif
-ifeq ($(CAIRO_HAS_TG_SURFACE),1)
- @echo "#define CAIRO_HAS_TG_SURFACE 1" >> $(top_srcdir)/src/cairo-features.h
-endif
ifeq ($(CAIRO_HAS_VG_SURFACE),1)
@echo "#define CAIRO_HAS_VG_SURFACE 1" >> $(top_srcdir)/src/cairo-features.h
endif
@@ -92,6 +83,9 @@ endif
ifeq ($(CAIRO_HAS_GLX_FUNCTIONS),1)
@echo "#define CAIRO_HAS_GLX_FUNCTIONS 1" >> $(top_srcdir)/src/cairo-features.h
endif
+ifeq ($(CAIRO_HAS_CGL_FUNCTIONS),1)
+ @echo "#define CAIRO_HAS_CGL_FUNCTIONS 1" >> $(top_srcdir)/src/cairo-features.h
+endif
ifeq ($(CAIRO_HAS_WGL_FUNCTIONS),1)
@echo "#define CAIRO_HAS_WGL_FUNCTIONS 1" >> $(top_srcdir)/src/cairo-features.h
endif
@@ -127,9 +121,6 @@ ifeq ($(CAIRO_HAS_XML_SURFACE),1)
@echo "#define CAIRO_HAS_XML_SURFACE 1" >> $(top_srcdir)/src/cairo-features.h
endif
@echo "#define CAIRO_HAS_USER_FONT 1" >> $(top_srcdir)/src/cairo-features.h
-ifeq ($(CAIRO_HAS_OPENMP),1)
- @echo "#define CAIRO_HAS_OPENMP 1" >> $(top_srcdir)/src/cairo-features.h
-endif
ifeq ($(CAIRO_HAS_PTHREAD),1)
@echo "#define CAIRO_HAS_PTHREAD 1" >> $(top_srcdir)/src/cairo-features.h
endif
diff --git a/build/Makefile.win32.inform b/build/Makefile.win32.inform
index ba1116505..ba1116505 100755..100644
--- a/build/Makefile.win32.inform
+++ b/build/Makefile.win32.inform
diff --git a/build/aclocal.cairo.m4 b/build/aclocal.cairo.m4
index 2f4873b04..2f4873b04 100755..100644
--- a/build/aclocal.cairo.m4
+++ b/build/aclocal.cairo.m4
diff --git a/build/aclocal.compare.m4 b/build/aclocal.compare.m4
index bd6c51b28..bd6c51b28 100755..100644
--- a/build/aclocal.compare.m4
+++ b/build/aclocal.compare.m4
diff --git a/build/aclocal.enable.m4 b/build/aclocal.enable.m4
index f3522b983..f3522b983 100755..100644
--- a/build/aclocal.enable.m4
+++ b/build/aclocal.enable.m4
diff --git a/build/aclocal.float.m4 b/build/aclocal.float.m4
index 18ec31618..8f85f0862 100755..100644
--- a/build/aclocal.float.m4
+++ b/build/aclocal.float.m4
@@ -24,16 +24,17 @@ AC_DEFUN([AX_C_FLOAT_WORDS_BIGENDIAN],
# is found, the user is instructed to specify the ordering.
ax_cv_c_float_words_bigendian=unknown
-AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
+AC_LINK_IFELSE([AC_LANG_SOURCE([[
-double d = 90904234967036810337470478905505011476211692735615632014797120844053488865816695273723469097858056257517020191247487429516932130503560650002327564517570778480236724525140520121371739201496540132640109977779420565776568942592.0;
+double d __attribute__((used)) = 90904234967036810337470478905505011476211692735615632014797120844053488865816695273723469097858056257517020191247487429516932130503560650002327564517570778480236724525140520121371739201496540132640109977779420565776568942592.0;
+int main() { return 0; }
]])], [
-if strings - conftest.$ac_objext | grep noonsees >/dev/null ; then
+if strings - conftest$ac_exeext | grep noonsees >/dev/null ; then
ax_cv_c_float_words_bigendian=yes
fi
-if strings - conftest.$ac_objext | grep seesnoon >/dev/null ; then
+if strings - conftest$ac_exeext | grep seesnoon >/dev/null ; then
if test "$ax_cv_c_float_words_bigendian" = unknown; then
ax_cv_c_float_words_bigendian=no
else
diff --git a/build/aclocal.gtk-doc.m4 b/build/aclocal.gtk-doc.m4
index bfdfa1da6..bfdfa1da6 100755..100644
--- a/build/aclocal.gtk-doc.m4
+++ b/build/aclocal.gtk-doc.m4
diff --git a/build/aclocal.makefile.m4 b/build/aclocal.makefile.m4
index 70777810d..70777810d 100755..100644
--- a/build/aclocal.makefile.m4
+++ b/build/aclocal.makefile.m4
diff --git a/build/aclocal.pkg.m4 b/build/aclocal.pkg.m4
index cf90a9678..cf90a9678 100755..100644
--- a/build/aclocal.pkg.m4
+++ b/build/aclocal.pkg.m4
diff --git a/build/configure.ac.analysis b/build/configure.ac.analysis
index 11c52e70d..11c52e70d 100755..100644
--- a/build/configure.ac.analysis
+++ b/build/configure.ac.analysis
diff --git a/build/configure.ac.features b/build/configure.ac.features
index 0457bf31c..adb840fd8 100755..100644
--- a/build/configure.ac.features
+++ b/build/configure.ac.features
@@ -367,7 +367,6 @@ AC_DEFUN([CAIRO_REPORT],
echo " Recording: yes (always builtin)"
echo " Observer: yes (always builtin)"
echo " Mime: yes (always builtin)"
- echo " TG: $use_tg"
echo " Tee: $use_tee"
echo " XML: $use_xml"
echo " Skia: $use_skia"
@@ -384,6 +383,7 @@ AC_DEFUN([CAIRO_REPORT],
echo " PDF: $use_pdf"
echo " SVG: $use_svg"
echo " OpenGL: $use_gl"
+ echo " EvasGL: $use_evasgl"
echo " OpenGL ES 2.0: $use_glesv2"
echo " OpenGL ES 3.0: $use_glesv3"
echo " BeOS: $use_beos"
@@ -403,6 +403,7 @@ AC_DEFUN([CAIRO_REPORT],
echo " PNG functions: $use_png"
echo " GLX functions: $use_glx"
echo " WGL functions: $use_wgl"
+ echo " CGL functions: $use_cgl"
echo " EGL functions: $use_egl"
echo " X11-xcb functions: $use_xlib_xcb"
echo " XCB-shm functions: $use_xcb_shm"
@@ -413,7 +414,6 @@ AC_DEFUN([CAIRO_REPORT],
echo ""
echo "And the following internal features:"
echo " pthread: $use_pthread"
- echo " openmp: $use_openmp"
echo " gtk-doc: $enable_gtk_doc"
echo " gcov support: $use_gcov"
echo " symbol-lookup: $use_symbol_lookup"
diff --git a/build/configure.ac.noversion b/build/configure.ac.noversion
index 18c4bd5f7..18c4bd5f7 100755..100644
--- a/build/configure.ac.noversion
+++ b/build/configure.ac.noversion
diff --git a/build/configure.ac.openmp b/build/configure.ac.openmp
deleted file mode 100755
index e5bff7f23..000000000
--- a/build/configure.ac.openmp
+++ /dev/null
@@ -1,74 +0,0 @@
-m4_define([libcairo_openmp_program],[dnl
- #include <stdio.h>
-
- extern unsigned int lcg_seed;
- #pragma omp threadprivate(lcg_seed)
- unsigned int lcg_seed;
-
- unsigned function(unsigned a, unsigned b)
- {
- lcg_seed ^= b;
- return ((a + b) ^ a ) + lcg_seed;
- }
-
- int main(int argc, char **argv)
- {
- int i;
- int n1 = 0, n2 = argc;
- unsigned checksum = 0;
- int verbose = argv != NULL;
- unsigned (*test_function)(unsigned, unsigned);
- test_function = function;
- #pragma omp parallel for reduction(+:checksum) default(none) \
- shared(n1, n2, test_function, verbose)
- for (i = n1; i < n2; i++)
- {
- unsigned crc = test_function (i, 0);
- if (verbose)
- printf ("%d: %08X\n", i, crc);
- checksum += crc;
- }
- printf("%u\n", checksum);
- return 0;
- }
-}])
-
-AC_DEFUN([CAIRO_CHECK_OPENMP],[dnl
- CAIRO_CC_TRY_LINK_WITH_ENV_SILENT(
- [CFLAGS="$CFLAGS $2";
- LIBS="$LIBS $3"],
- [$4],
- [$1_CFLAGS="$2";
- $1_LIBS="$3";
- $5],
- [$1_CFLAGS="";
- $1_LIBS="";
- $6])
-])
-
-AC_DEFUN([CAIRO_CONFIGURE_OPENMP],[dnl
- if test "x$OPENMP_CFLAGS" = "x"; then
- OPENMP_CFLAGS="-fopenmp"
- fi
- if test "x$OPENMP_LIBS" = "x"; then
- OPENMP_LIBS="-lgomp"
- fi
-
- CAIRO_CHECK_OPENMP(
- [openmp], [$OPENMP_CFLAGS], [$OPENMP_LIBS],
- [libcairo_openmp_program],
- [have_openmp=yes],
- [have_openmp=no])
- OPENMP_CFLAGS=
- OPENMP_LIBS=
-
- dnl Tell autoconf about the results.
- if test "x$have_openmp" = "xyes"; then
- AC_DEFINE([CAIRO_HAS_OPENMP], 1,
- [Define to 1 if we have openmp support])
- fi
-
- dnl Set the output variables for CAIRO_ENABLE.
- use_openmp="$have_openmp"
- openmp_REQUIRES=""
-])
diff --git a/build/configure.ac.pthread b/build/configure.ac.pthread
index 29c930da9..29c930da9 100755..100644
--- a/build/configure.ac.pthread
+++ b/build/configure.ac.pthread
diff --git a/build/configure.ac.system b/build/configure.ac.system
index b9d71c8d7..b9d71c8d7 100755..100644
--- a/build/configure.ac.system
+++ b/build/configure.ac.system
diff --git a/build/configure.ac.tls b/build/configure.ac.tls
deleted file mode 100755
index 881c919c4..000000000
--- a/build/configure.ac.tls
+++ /dev/null
@@ -1,108 +0,0 @@
-m4_define([libcairo_pthread_setspecific_program],[dnl
- #include <stdlib.h>
- #include <pthread.h>
- #include <stdio.h>
-
- static pthread_once_t once_control = PTHREAD_ONCE_INIT;
- static pthread_key_t key;
-
- static void
- make_key (void)
- {
- pthread_key_create (&key, NULL);
- }
-
- int
- main (int argc, char **argv)
- {
- void *value = NULL;
-
- if (pthread_once (&once_control, make_key) != 0)
- {
- value = NULL;
- }
- else
- {
- value = pthread_getspecific (key);
- if (!value)
- {
- value = malloc (100);
- pthread_setspecific (key, value);
- }
- }
-
- printf ("%d, %p\n", argc, argv);
- return 0;
- }
-}])
-
-AC_DEFUN([CAIRO_CONFIGURE_TLS], [dnl
- have_tls=no
- AC_CACHE_VAL(ac_cv_tls, [
- ac_cv_tls=none
- keywords="__thread __declspec(thread)"
- for kw in $keywords ; do
- AC_TRY_COMPILE([
- #if defined(__MINGW32__) && !(__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5))
- #error This MinGW version has broken __thread support
- #endif
- #ifdef __OpenBSD__
- #error OpenBSD has broken __thread support
- #endif
-
- int $kw test;], [], [ac_cv_tls=$kw; break])
- done
- ])
-
- if test "$ac_cv_tls" != "none"; then
- have_tls=yes
- AC_DEFINE([CAIRO_HAS_TLS], 1, [Define to 1 if we have tls support])
- AC_DEFINE_UNQUOTED([TLS], $ac_cv_tls, [The compiler supported TLS storage class])
- fi
-
- dnl Set the output variables for CAIRO_ENABLE.
- use_tls="$have_tls"
- tls_REQUIRES=""
-])
-
-AC_DEFUN([CAIRO_CHECK_PTHREAD_SETSPECIFIC],[dnl
- CAIRO_CC_TRY_LINK_WITH_ENV_SILENT(
- [CFLAGS="$CFLAGS $2";
- LIBS="$LIBS $3"],
- [$4],
- [$1_CFLAGS="$2";
- $1_LIBS="$3";
- $5],
- [$1_CFLAGS="";
- $1_LIBS="";
- $6])
-])
-
-AC_DEFUN([CAIRO_CONFIGURE_PTHREAD_SETSPECIFIC],[dnl
- if test "x$PTHREAD_SETSPECIFIC_CFLAGS" = "x"; then
- PTHREAD_SETSPECIFIC_CFLAGS="-D_REENTRANT"
- fi
-
- if test "x$PTHREAD_SETSPECIFIC_LIBS" = "x"; then
- PTHREAD_SETSPECIFIC_LIBS="-lpthread"
- fi
-
- CAIRO_CHECK_PTHREAD_SETSPECIFIC(
- [pthread_setspecific], [$PTHREAD_SETSPECIFIC_CFLAGS], [$PTHREAD_SETSPECIFIC_LIBS],
- [libcairo_pthread_setspecific_program],
- [have_pthread_setspecific=yes],
- [have_pthread_setspecific=no])
-
- PTHREAD_SETSPECIFIC_CFLAGS=
- PTHREAD_SETSPECIFIC_LIBS=
-
- dnl Tell autoconf about the results.
- if test "x$have_pthread_setspecific" = "xyes"; then
- AC_DEFINE([CAIRO_HAS_PTHREAD_SETSPECIFIC], 1,
- [Define to 1 if we have pthread_setspecific support])
- fi
-
- dnl Set the output variables for CAIRO_ENABLE.
- use_pthread_setspecific="$have_pthread_setspecific"
- pthread_setspecific_REQUIRES=""
-])
diff --git a/build/configure.ac.tools b/build/configure.ac.tools
index a24dbcecb..a24dbcecb 100755..100644
--- a/build/configure.ac.tools
+++ b/build/configure.ac.tools
diff --git a/build/configure.ac.version b/build/configure.ac.version
index a91cee39e..a91cee39e 100755..100644
--- a/build/configure.ac.version
+++ b/build/configure.ac.version
diff --git a/build/configure.ac.warnings b/build/configure.ac.warnings
index f984eb29c..74e6634b2 100755..100644
--- a/build/configure.ac.warnings
+++ b/build/configure.ac.warnings
@@ -11,16 +11,17 @@ dnl MAYBE_WARN in an ignorable way (like adding whitespace)
# -Wlogical-op causes too much noise from strcmp("literal", str)
MAYBE_WARN="-Wall -Wextra \
--Wold-style-definition -Wdeclaration-after-statement \
-Wmissing-declarations -Werror-implicit-function-declaration \
--Wnested-externs -Wpointer-arith -Wwrite-strings \
--Wsign-compare -Wstrict-prototypes -Wmissing-prototypes \
--Wpacked -Wswitch-enum -Wmissing-format-attribute \
--Wbad-function-cast -Wvolatile-register-var \
+-Wpointer-arith -Wwrite-strings -Wsign-compare -Wpacked
+-Wswitch-enum -Wmissing-format-attribute -Wvolatile-register-var \
-Wstrict-aliasing=2 -Winit-self -Wunsafe-loop-optimizations \
-Wno-missing-field-initializers -Wno-unused-parameter \
-Wno-attributes -Wno-long-long -Winline"
+MAYBE_C_SPECIFIC_WARN="-Wold-style-definition \
+-Wdeclaration-after-statement -Wstrict-prototypes \
+-Wmissing-prototypes -Wbad-function-cast -Wnested-externs"
+
# New -Wno options should be added here
# gcc-4.4 and later accept every -Wno- option but may complain later that this
# option is unknow each time another warning happen.
@@ -35,17 +36,6 @@ MAYBE_WARN="$MAYBE_WARN -erroff=E_ENUM_TYPE_MISMATCH_ARG \
dnl We also abuse the warning-flag facility to enable other compiler
dnl options. Namely, the following:
-
-dnl -flto working really needs a test link, not just a compile
-
-safe_MAYBE_WARN="$MAYBE_WARN"
-MAYBE_WARN="$MAYBE_WARN -flto"
-AC_TRY_LINK([],[
- int main(int argc, char **argv) { return 0; }
-],[],[
- MAYBE_WARN="$safe_MAYBE_WARN"
-])
-
MAYBE_WARN="$MAYBE_WARN -fno-strict-aliasing -fno-common"
dnl Also to turn various gcc/glibc-specific preprocessor checks
@@ -77,7 +67,7 @@ AC_CACHE_CHECK([for supported warning flags], cairo_cv_warn_cflags, [
CAIRO_CC_TRY_FLAG([-W$W -Wno-$W],, [WARN_CFLAGS="$WARN_CFLAGS -Wno-$W"])
done
cairo_cv_warn_cflags=$WARN_CFLAGS
- cairo_cv_warn_maybe=$MAYBE_WARN
+ cairo_cv_warn_maybe="$MAYBE_WARN $MAYBE_C_SPECIFIC_WARN"
AC_MSG_CHECKING([which warning flags were supported])
])
diff --git a/cairo-glesv3-uninstall.pc b/cairo-glesv3-uninstall.pc
index 67e252ed5..67e252ed5 100755..100644
--- a/cairo-glesv3-uninstall.pc
+++ b/cairo-glesv3-uninstall.pc
diff --git a/cairo-version.h b/cairo-version.h
index 9cda3831d..516999ee6 100755..100644
--- a/cairo-version.h
+++ b/cairo-version.h
@@ -2,7 +2,7 @@
#define CAIRO_VERSION_H
#define CAIRO_VERSION_MAJOR 1
-#define CAIRO_VERSION_MINOR 12
-#define CAIRO_VERSION_MICRO 14
+#define CAIRO_VERSION_MINOR 14
+#define CAIRO_VERSION_MICRO 2
#endif
diff --git a/cairo.manifest b/cairo.manifest
new file mode 100755
index 000000000..017d22d3a
--- /dev/null
+++ b/cairo.manifest
@@ -0,0 +1,5 @@
+<manifest>
+ <request>
+ <domain name="_"/>
+ </request>
+</manifest>
diff --git a/configure.ac b/configure.ac
index 5be2f9b30..bd33aada8 100755..100644
--- a/configure.ac
+++ b/configure.ac
@@ -11,8 +11,11 @@ AC_USE_SYSTEM_EXTENSIONS
AC_CONFIG_SRCDIR(src/cairo.h)
AC_CONFIG_HEADERS(config.h)
+AC_CHECK_HEADERS([unistd.h sys/ioctl.h])
+
AM_INIT_AUTOMAKE([1.11 foreign -Wall no-define no-dist-gzip dist-xz])
AM_SILENT_RULES([yes])
+m4_ifdef([AM_PROG_AR], [AM_PROG_AR]) dnl Workaround for Automake 1.12
# Initialize libtool
LT_PREREQ([2.2])
@@ -34,9 +37,7 @@ m4_include(build/configure.ac.warnings) dnl checks for compiler warning
m4_include(build/configure.ac.system) dnl checks for system functions, headers, libs
m4_include(build/configure.ac.analysis) dnl checks for analysis tools (lcov, etc)
m4_include(build/configure.ac.noversion) dnl disable builtin libtool versioning
-m4_include(build/configure.ac.openmp) dnl checks for openmp
m4_include(build/configure.ac.pthread) dnl checks for pthreads
-m4_include(build/configure.ac.tls) dnl checks for thread-local storage
AC_CACHE_SAVE
dnl ===========================================================================
@@ -49,6 +50,16 @@ AC_CHECK_LIB(z, compress,
[have_libz="no (requires zlib http://www.gzip.org/zlib/)"])],
[have_libz="no (requires zlib http://www.gzip.org/zlib/)"])
+AC_CHECK_LIB(wayland-client, wl_display_connect,
+ [AC_CHECK_HEADER(wayland-client.h, [
+ have_wayland=yes
+ AC_DEFINE(HAVE_WAYLAND, 1, [Define to 1 if you have wayland available])
+ wayland_LIBS="-lwayland-client -lwayland-egl"
+ ],
+ [have_wayland="no (requires wayland-egl)"])],
+ [have_wayland="no (requires wayland-egl)"])
+LIBS="$wayland_LIBS $LIBS"
+
save_LIBS="$LIBS"
AC_CHECK_LIB(lzo2, lzo2a_decompress,
[AC_CHECK_HEADER(lzo/lzo2a.h, [
@@ -75,22 +86,6 @@ fi
AM_CONDITIONAL(CAIRO_HAS_DLSYM, test "x$have_dlsym" = "xyes")
dnl ===========================================================================
-dnl Check support for TLS
-have_tls=no
-CAIRO_ENABLE(tls, tls, no, [CAIRO_CONFIGURE_TLS])
-AM_CONDITIONAL(HAVE_TLS, test "x$use_tls" = "xyes")
-AC_SUBST(tls_CFLAGS)
-AC_SUBST(tls_LIBS)
-
-dnl ===========================================================================
-dnl Check support for pthread_setspecific
-have_pthread_setspecific=no
-CAIRO_ENABLE(pthread_setspecific, pthread_setspecific, no, [CAIRO_CONFIGURE_PTHREAD_SETSPECIFIC])
-AM_CONDITIONAL(HAVE_PTHREAD_SETSPECIFIC, test "x$use_pthread_setspecific" = "xyes")
-AC_SUBST(pthread_setspecific_CFLAGS)
-AC_SUBST(pthread_setspecific_LIBS)
-
-dnl ===========================================================================
CAIRO_ENABLE_SURFACE_BACKEND(xlib, Xlib, auto, [
xlib_REQUIRES="x11 xext"
@@ -163,7 +158,7 @@ CAIRO_ENABLE_SURFACE_BACKEND(xlib_xrender, Xlib Xrender, auto, [
old_LIBS=$LIBS
CFLAGS="$CFLAGS $xlib_CFLAGS $xlib_NONPKGCONFIG_CFLAGS $xlib_xrender_CFLAGS $xlib_xrender_NONPKGCONFIG_CFLAGS"
LIBS="$LIBS $xlib_LIBS $xlib_NONPKGCONFIG_LIBS $xlib_xrender_LIBS $xlib_xrender_NONPKGCONFIG_LIBS"
- AC_CHECK_FUNCS([XRenderCreateLinearGradient XRenderCreateRadialGradient XRenderCreateConicalGradient])
+ AC_CHECK_FUNCS([XRenderCreateSolidFill XRenderCreateLinearGradient XRenderCreateRadialGradient XRenderCreateConicalGradient])
CFLAGS=$old_CFLAGS
LIBS=$old_LIBS
@@ -206,6 +201,7 @@ CAIRO_ENABLE_SURFACE_BACKEND(qt, Qt, no, [
[qt_REQUIRES=""
use_qt="no (requires Qt4 development libraries)"
])
+ qt_NONPKGCONFIG_LIBS="-lstdc++"
])
dnl ===========================================================================
@@ -265,16 +261,16 @@ CAIRO_ENABLE_SURFACE_BACKEND(skia, Skia, no, [
[directory to find compiled skia sources])],
[skia_DIR="$withval"],
[skia_DIR="`pwd`/../skia"])
- AC_ARG_WITH([skia-bulid],
- [AS_HELP_STRING([--with-skia-build=(Release|Debug)]
+ 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="$withval"],
- [skia_BUILD="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" = x"Release"; then
+ if test "x$skia_BUILD_TYPE" = "xRelease"; then
skia_NONPKGCONFIG_CFLAGS="-DSK_RELEASE -DSK_CAN_USE_FLOAT $skia_NONPKGCONFIG_CFLAGS"
fi
- skia_NONPKGCONFIG_LIBS="--start-group $skia_DIR/out/$skia_BUILD/obj.target/gyp/libeffects.a $skia_DIR/out/$skia_BUILD/obj.target/gyp/libimages.a $skia_DIR/out/$skia_BUILD/obj.target/gyp/libutils.a $skia_DIR/out/$skia_BUILD/obj.target/gyp/libopts.a $skia_DIR/out/$skia_BUILD/obj.target/gyp/libcore.a -end-group"
+ skia_NONPKGCONFIG_LIBS="-L$skia_DIR/out/$skia_BUILD_TYPE/lib.target/ -lskia -lstdc++"
AC_SUBST(skia_DIR)
])
@@ -362,20 +358,21 @@ CAIRO_ENABLE_SURFACE_BACKEND(gl, OpenGL, no, [
gl_REQUIRES="gl"
PKG_CHECK_MODULES(gl, $gl_REQUIRES,, [
dnl Fallback to searching for headers
- AC_CHECK_HEADER(GL/gl.h,, [use_gl="no (gl.pc nor OpenGL headers not found)"])
+ AC_CHECK_HEADER([GL/gl.h, OpenGL/gl.h], [use_gl="no (gl.pc nor OpenGL headers not found)"])
if test "x$use_gl" = "xyes"; then
gl_NONPKGCONFIG_CFLAGS=
- gl_NONPKGCONFIG_LIBS="-lGL"
+ gl_NONPKGCONFIG_LIBS=
fi])
if test "x$have_dl" = "xyes" -a "x$have_dlsym" = "xyes"; then
- gl_LIBS="$gl_LIBS -ldl"
+ gl_LIBS="-ldl"
fi
need_glx_functions=yes
need_wgl_functions=yes
need_egl_functions=yes
need_evasgl_functions=yes
+ need_cgl_functions=yes
])
dnl ===========================================================================
@@ -410,6 +407,10 @@ CAIRO_ENABLE_SURFACE_BACKEND(glesv2, OpenGLESv2, no, [
glesv2_LIBS="$glesv2_LIBS -ldl"
fi
+ if test "x$use_glesv2" = "xyes" -a "x$use_gl" = "xyes"; then
+ AC_MSG_ERROR([use either --enable-gl=yes or --enable-glesv2=yes. Not both at the same time.])
+ fi
+
need_egl_functions=yes
])
@@ -447,15 +448,6 @@ CAIRO_ENABLE_SURFACE_BACKEND(directfb, directfb, no, [
dnl ===========================================================================
-CAIRO_ENABLE_SURFACE_BACKEND(tg, TG, no, [
- if test "x$use_tls" != "xyes" -a \
- "x$use_pthread_setspecific" != "xyes"; then
- use_tg="no (requires tls or pthread_setspecific)"
- tg_REQUIRES="tls or pthread setspecific"
- fi])
-
-dnl ===========================================================================
-
CAIRO_ENABLE_SURFACE_BACKEND(vg, OpenVG, no, [
dnl There is no pkgconfig for OpenVG; lets do a header check
AC_CHECK_HEADER(VG/openvg.h,, [use_vg="no (OpenVG headers not found)"])
@@ -507,11 +499,27 @@ CAIRO_ENABLE_FUNCTIONS(glx, GLX, auto, [
glx_NONPKGCONFIG_CFLAGS=
glx_NONPKGCONFIG_LIBS="-lGL"
CFLAGS="$save_CFLAGS"
+ need_cgl_functions="no"
else
use_glx="no (not required by any backend)"
fi
])
+CAIRO_ENABLE_FUNCTIONS(cgl, CGL, auto, [
+ if test "x$need_cgl_functions" = "xyes"; then
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS $gl_CFLAGS $gl_NONPKGCONFIG_CFLAGS"
+ AC_CHECK_HEADER(OpenGL/gl.h,, [use_gl="no (CGL headers not found)"])
+ cgl_LIBS="-Xlinker -framework -Xlinker OpenGL"
+ cgl_NONPKGCONFIG_CFLAGS=
+ cgl_NONPKGCONFIG_LIBS=
+ CFLAGS="$save_CFLAGS"
+ need_glx_functions="no"
+ else
+ use_cgl="no (not required by any backend)"
+ fi
+])
+
CAIRO_ENABLE_FUNCTIONS(wgl, WGL, auto, [
if test "x$need_wgl_functions" = "xyes"; then
AC_CHECK_HEADER(windows.h,, [use_wgl="no (WGL headers not found)"])
@@ -688,7 +696,7 @@ CAIRO_ENABLE_SURFACE_BACKEND(svg, SVG, yes, [
fi
])
-LIBRSVG_VERSION_REQUIRED=2.15.0
+LIBRSVG_VERSION_REQUIRED=2.35.0
test_svg=no
any2ppm_svg=no
if test "x$use_svg" = "xyes"; then
@@ -717,7 +725,7 @@ CAIRO_ENABLE(test_surfaces, test surfaces, no)
dnl ===========================================================================
CAIRO_ENABLE_SURFACE_BACKEND(image, image, always, [
- pixman_REQUIRES="pixman-1 >= 0.22.0"
+ pixman_REQUIRES="pixman-1 >= 0.30.0"
PKG_CHECK_MODULES(pixman, $pixman_REQUIRES, ,
[use_image="no (requires $pixman_REQUIRES http://cairographics.org/releases/)"])
image_REQUIRES=$pixman_REQUIRES
@@ -746,14 +754,6 @@ dnl ===========================================================================
CAIRO_ENABLE_FONT_BACKEND(user, user, always)
dnl ===========================================================================
-dnl Check support for openmp
-have_openmp=no
-CAIRO_ENABLE(openmp, openmp, no, [CAIRO_CONFIGURE_OPENMP])
-AM_CONDITIONAL(HAVE_OPENMP, test "x$use_openmp" = "xyes")
-AC_SUBST(openmp_CFLAGS)
-AC_SUBST(openmp_LIBS)
-
-dnl ===========================================================================
dnl
dnl This needs to be last on our list of features so that the pthread libs and flags
dnl gets prefixed in front of everything else in CAIRO_{CFLAGS,LIBS}.
@@ -773,7 +773,7 @@ dnl ===========================================================================
dnl Build gobject integration library
CAIRO_ENABLE_FUNCTIONS(gobject, gobject, auto, [
- gobject_REQUIRES="gobject-2.0 glib-2.0"
+ 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/)"])
gobject_NONPKGCONFIG_EXTRA_LIBS="-L\${libdir} -lcairo-gobject"
@@ -868,7 +868,7 @@ CAIRO_ENABLE(symbol_lookup, symbol-lookup, auto, [
PKG_CHECK_MODULES(glib, glib-2.0, have_glib=yes, have_glib=no)
AC_SUBST(glib_CFLAGS)
AC_SUBST(glib_LIBS)
-AM_CONDITIONAL(BUILD_SPHINX, test "x$have_glib" = "xyes")
+AM_CONDITIONAL(BUILD_SPHINX, test "x$have_glib" = "xyes" -a "x$have_windows" = "xno")
save_LIBS="$LIBS"
AC_CHECK_LIB(rt, shm_open, shm_LIBS="-lrt")
@@ -918,12 +918,24 @@ AC_CONFIG_FILES([
Makefile
boilerplate/Makefile
src/Makefile
+test/Makefile
+test/pdiff/Makefile
+perf/Makefile
+perf/micro/Makefile
util/Makefile
+util/cairo-fdr/Makefile
util/cairo-gobject/Makefile
util/cairo-missing/Makefile
util/cairo-script/Makefile
util/cairo-script/examples/Makefile
-])
+util/cairo-sphinx/Makefile
+util/cairo-trace/Makefile
+util/cairo-trace/cairo-trace
+doc/Makefile
+doc/public/Makefile
+])
+AC_CONFIG_COMMANDS([cairo-trace],
+ [chmod a+x util/cairo-trace/cairo-trace])
AC_OUTPUT
CAIRO_REPORT
diff --git a/doc/.gitignore b/doc/.gitignore
index 23c1897f1..23c1897f1 100755..100644
--- a/doc/.gitignore
+++ b/doc/.gitignore
diff --git a/doc/Makefile.am b/doc/Makefile.am
index 864a9f1df..864a9f1df 100755..100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
diff --git a/doc/public/.gitignore b/doc/public/.gitignore
index 493a24172..d08fd80e0 100755..100644
--- a/doc/public/.gitignore
+++ b/doc/public/.gitignore
@@ -14,6 +14,7 @@ cairo.args
cairo.signals
html
xml
+tmpl
version.xml
*~
*.bak
diff --git a/doc/public/Makefile.am b/doc/public/Makefile.am
index 11f9e7b72..11f9e7b72 100755..100644
--- a/doc/public/Makefile.am
+++ b/doc/public/Makefile.am
diff --git a/doc/public/README b/doc/public/README
index f3d157b1a..f3d157b1a 100755..100644
--- a/doc/public/README
+++ b/doc/public/README
diff --git a/doc/public/cairo-docs.xml b/doc/public/cairo-docs.xml
index baf844c18..baf844c18 100755..100644
--- a/doc/public/cairo-docs.xml
+++ b/doc/public/cairo-docs.xml
diff --git a/doc/public/cairo-overrides.txt b/doc/public/cairo-overrides.txt
index e69de29bb..e69de29bb 100755..100644
--- a/doc/public/cairo-overrides.txt
+++ b/doc/public/cairo-overrides.txt
diff --git a/doc/public/cairo-sections.txt b/doc/public/cairo-sections.txt
index c67da371c..4beaa0ae2 100755..100644
--- a/doc/public/cairo-sections.txt
+++ b/doc/public/cairo-sections.txt
@@ -114,6 +114,16 @@ cairo_recording_surface_get_extents
</SECTION>
<SECTION>
+<FILE>cairo-skia</FILE>
+cairo_skia_context_t
+cairo_skia_surface_t
+format_to_sk_config
+<SUBSECTION Private>
+cairo_skia_context
+cairo_skia_surface
+</SECTION>
+
+<SECTION>
<FILE>cairo-win32</FILE>
CAIRO_HAS_WIN32_SURFACE
cairo_win32_surface_create
@@ -143,9 +153,6 @@ CAIRO_HAS_QUARTZ_SURFACE
cairo_quartz_surface_create
cairo_quartz_surface_create_for_cg_context
cairo_quartz_surface_get_cg_context
-<SUBSECTION Private>
-cairo_quartz_image_surface_create
-cairo_quartz_image_surface_get_image
</SECTION>
<SECTION>
@@ -216,11 +223,21 @@ cairo_device_set_user_data
cairo_device_get_user_data
cairo_device_acquire
cairo_device_release
+cairo_device_observer_elapsed
+cairo_device_observer_fill_elapsed
+cairo_device_observer_glyphs_elapsed
+cairo_device_observer_mask_elapsed
+cairo_device_observer_paint_elapsed
+cairo_device_observer_print
+cairo_device_observer_stroke_elapsed
</SECTION>
<SECTION>
<FILE>cairo-surface</FILE>
CAIRO_HAS_MIME_SURFACE
+CAIRO_MIME_TYPE_JBIG2
+CAIRO_MIME_TYPE_JBIG2_GLOBAL
+CAIRO_MIME_TYPE_JBIG2_GLOBAL_ID
CAIRO_MIME_TYPE_JP2
CAIRO_MIME_TYPE_JPEG
CAIRO_MIME_TYPE_PNG
@@ -243,6 +260,8 @@ cairo_surface_mark_dirty
cairo_surface_mark_dirty_rectangle
cairo_surface_set_device_offset
cairo_surface_get_device_offset
+cairo_surface_get_device_scale
+cairo_surface_set_device_scale
cairo_surface_set_fallback_resolution
cairo_surface_get_fallback_resolution
cairo_surface_type_t
@@ -261,6 +280,23 @@ cairo_surface_unmap_image
</SECTION>
<SECTION>
+<FILE>cairo-surface-observer</FILE>
+CAIRO_HAS_OBSERVER_SURFACE
+cairo_surface_create_observer
+cairo_surface_observer_add_fill_callback
+cairo_surface_observer_add_finish_callback
+cairo_surface_observer_add_flush_callback
+cairo_surface_observer_add_glyphs_callback
+cairo_surface_observer_add_mask_callback
+cairo_surface_observer_add_paint_callback
+cairo_surface_observer_add_stroke_callback
+cairo_surface_observer_callback_t
+cairo_surface_observer_elapsed
+cairo_surface_observer_mode_t
+cairo_surface_observer_print
+</SECTION>
+
+<SECTION>
<FILE>cairo-version</FILE>
CAIRO_VERSION
CAIRO_VERSION_MAJOR
diff --git a/doc/public/cairo.types b/doc/public/cairo.types
index e69de29bb..e69de29bb 100755..100644
--- a/doc/public/cairo.types
+++ b/doc/public/cairo.types
diff --git a/doc/public/language-bindings.xml b/doc/public/language-bindings.xml
index ce437ef53..ce437ef53 100755..100644
--- a/doc/public/language-bindings.xml
+++ b/doc/public/language-bindings.xml
diff --git a/doc/tutorial/slides/.gitignore b/doc/tutorial/slides/.gitignore
new file mode 100644
index 000000000..72a67a02c
--- /dev/null
+++ b/doc/tutorial/slides/.gitignore
@@ -0,0 +1,7 @@
+tutorial-???.html
+tutorial-???.png
+tutorial-???.svg
+tutorial-index.xml
+tutorial.pdf
+index.html
+*~
diff --git a/doc/tutorial/slides/cairo-blank.svg b/doc/tutorial/slides/cairo-blank.svg
new file mode 100644
index 000000000..ac91186fb
--- /dev/null
+++ b/doc/tutorial/slides/cairo-blank.svg
@@ -0,0 +1,477 @@
+<?xml version="1.0" ?>
+<svg width="1024" height="768"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:ss="http://www.svgslides.org/svgslides0.1"
+ fill="black">
+
+
+ <defs id="cairo-artwork_defs">
+ <g id="hacker_emblem">
+ <!-- Note: This is similar though not identical to Keith Packard's SVG version
+ of the hacker emblem (http://www.catb.org/hacker-emblem/glider.svg) -->
+ <g id="hacker_emblem_grid" fill="white" stroke="none">
+ <!-- Outside: Top, Right, Bottom, Left -->
+ <rect x="-2.95" y="-3.05" width="6" height="0.1" />
+ <rect x="2.95" y="-2.95" width="0.1" height="6" />
+ <rect x="-3.05" y="2.95" width="6" height="0.1" />
+ <rect x="-3.05" y="-3.05" width="0.1" height="6" />
+ <!-- Vertical: Left, Right -->
+ <rect x="-1.05" y="-2.95" width="0.1" height="5.9" />
+ <rect x="0.95" y="-2.95" width="0.1" height="5.9" />
+ <!-- Horizontal: TopLeft, TopMiddle, TopRight -->
+ <rect x="-2.95" y="-1.05" width="1.9" height="0.1" />
+ <rect x="-0.95" y="-1.05" width="1.9" height="0.1" />
+ <rect x="1.05" y="-1.05" width="1.9" height="0.1" />
+ <!-- Horizontal: BottomLeft, BottomMiddle, BottomRight -->
+ <rect x="-2.95" y="0.95" width="1.9" height="0.1" />
+ <rect x="-0.95" y="0.95" width="1.9" height="0.1" />
+ <rect x="1.05" y="0.95" width="1.9" height="0.1" />
+ </g>
+ <g id="hacker_emblem_dots" fill="white">
+ <circle cx="0" cy="-2" r="0.7" />
+ <circle cx="2" cy="0" r="0.7" />
+ <circle cx="-2" cy="2" r="0.7" />
+ <circle cx="0" cy="2" r="0.7" />
+ <circle cx="2" cy="2" r="0.7" />
+ </g>
+ </g>
+ <g id="scarab" fill="#3B80AE">
+ <g transform="translate(-150, -170)">
+ <path id="scarab_head" d="M205.599,94.567c0-11.668-24.914-21.129-55.628-21.129
+ c-30.723,0-55.624,9.46-55.624,21.129c0,10.203,24.901,7.346,55.624,7.346C180.685,101.913,205.599,104.233,205.599,94.567z"/>
+ <path id="scarab_torso" d="M136.423,161.506c0,0,12.751,12.577,13.547,13.362
+ c2.262-2.232,13.545-13.362,13.545-13.362c7.135-7.036,87.111-6.399,91.066-6.363c-0.469-6.298-1.254-12.472-2.325-18.519
+ c-15.183-19.279-42.811-32.225-74.485-32.225h-55.518c-31.745,0-59.439,13.011-74.598,32.37c-1.054,6-1.829,12.128-2.296,18.374
+ C49.321,155.106,129.288,154.47,136.423,161.506z"/>
+ <path id="scarab_spine" d="M149.97,301.187c2.005-24.729,8.386-103.483,8.405-103.721
+ c-0.09-0.219-6.478-15.578-8.405-20.214c-1.936,4.655-8.316,19.995-8.408,20.214C141.582,197.704,147.965,276.458,149.97,301.187z"/>
+ <path id="scarab_wing_left" d="M140.403,197.149l8.862-21.31l-13.686-13.499
+ c-5.65-5.573-67.074-6.235-90.259-6.019l-0.006-0.622c-0.154,2.144-0.271,4.302-0.35,6.475
+ c-0.076,2.207,10.392,4.706,10.392,6.717c0,2.319-10.457,5.084-10.359,7.631c2.993,73.349,48.53,131.631,104.372,132.048
+ l-9.02-111.29L140.403,197.149z"/>
+ <path id="scarab_wing_right" d="M244.585,168.891c0-2.011,10.467-4.506,10.391-6.715
+ c-0.079-2.174-0.195-4.332-0.351-6.479l-0.004,0.624c-23.186-0.216-84.608,0.445-90.26,6.017l-13.688,13.502l8.915,21.438
+ l-9.017,111.29c55.854-0.417,101.378-58.698,104.373-132.049C255.04,173.976,244.585,171.209,244.585,168.891z"/>
+ <path id="scarab_leg_front_left" d="M44.506,141.12c-4.135-0.856-4.895-1.54-7.935-2.92
+ c-9.59-3.364-10.376-5.481-16.08-11.86c-7.426-8.306-12.661-20.142-17.1-29.463c-3.576-7.525-3.984-16.409-2.86-24.273
+ c0.991-6.935,7.144-12.869,12.074-18.92c5.844-7.191,10.356-14.822,17.924-21.354c7.736-6.682,23.203-9.809,26.168-19.648
+ C57.86,8.819,54.334,1.766,61.482,0c-0.366,4.703,3.639,8.477,2.397,13.575c-1.129,4.627-4.368,5.811-9.611,9.099
+ c-7.564,4.746-18.366,8.779-24.748,13.965c-7.175,5.827-4.369,13.771-10.569,20.057c-2.001,2.03-7.901,4.706-9.137,6.83
+ c-1.861,3.199-0.297,9.572-0.116,13.12c0.425,8.284,5.588,14.244,9.555,22.045c4.152,8.141,6.429,15.409,13.411,22.519
+ c4.183,4.262,11.429,4.802,16.21,10.647l-3.555,4.186L44.506,141.12z"/>
+ <path id="scarab_leg_middle_left" d="M43.94,191.922l-0.809-7.346
+ c-9.506-4.579-10.339-9.772-20.738-12.466c-23.728-6.151-21.361,11.25-15.532,26.373c5.676,14.726,8.237,30.23,14.345,44.795
+ c2.805,6.688,6.919,13.213,14.298,15.127c0.372-8.435-0.917-10.651-6.113-16.919c-4.395-5.293-3.326-12.548-6.072-18.504
+ c-3.581-7.804-4.196-15.646-7.279-23.502c-1.363-3.479-8.33-13.966-6.452-17.861c3.183-6.603,9.178-0.083,12.179,2.077
+ c4.218,3.036,6.467,2.223,11.681,2.898C34.041,186.673,37.005,188.756,43.94,191.922z"/>
+ <path id="scarab_leg_back_left" d="M65.839,257.063l-2.771-4.837
+ c-6.68,8.928-6.993,16.228-10.056,23.347c-5.277,12.263-0.157,28.851,9.854,37.676c6.052,5.375,15.907,9.618,23.122,13.136
+ c10.035,4.892,20.113,11.286,31.336,13.396c2.482,0.466,8.798,1.295,6.693-3.522c-0.975-2.237-8.091-4.591-10.146-5.734
+ c-8.312-4.623-16.377-10.524-24.142-16.176c-9.498-6.862-20.843-11.186-28.311-20.684c-3.054-3.885-3.544-4.922-2.816-9.39
+ c0.693-4.263,1.344-9.174,2.241-13.439C61.855,266.029,63.274,261.378,65.839,257.063z"/>
+ <path id="scarab_leg_front_right" d="M255.487,141.12c4.134-0.856,4.896-1.54,7.936-2.92
+ c9.583-3.364,10.369-5.481,16.071-11.86c7.428-8.306,12.661-20.142,17.115-29.463c3.574-7.525,3.983-16.409,2.86-24.273
+ c-0.992-6.935-7.157-12.869-12.087-18.92c-5.843-7.191-10.356-14.822-17.919-21.354c-7.735-6.682-23.202-9.809-26.167-19.648
+ C242.135,8.819,245.66,1.766,238.511,0c0.366,4.703-3.637,8.477-2.396,13.575c1.131,4.627,4.368,5.811,9.611,9.099
+ c7.563,4.746,18.367,8.779,24.747,13.965c7.17,5.827,4.362,13.771,10.563,20.057c2.001,2.03,7.901,4.706,9.139,6.83
+ c1.859,3.199,0.295,9.572,0.113,13.12c-0.424,8.284-5.588,14.244-9.553,22.045c-4.152,8.141-6.431,15.409-13.404,22.519
+ c-4.184,4.262-11.429,4.802-16.211,10.647l3.556,4.186L255.487,141.12z"/>
+ <path id="scarab_leg_middle_right" d="M256.053,191.922l0.81-7.346
+ c9.507-4.579,10.34-9.772,20.73-12.466c23.741-6.151,21.374,11.25,15.534,26.373c-5.676,14.726-8.238,30.23-14.347,44.795
+ c-2.804,6.688-6.911,13.213-14.291,15.127c-0.371-8.435,0.918-10.651,6.113-16.919c4.39-5.293,3.319-12.548,6.066-18.504
+ c3.58-7.804,4.197-15.646,7.278-23.502c1.363-3.479,8.33-13.966,6.453-17.861c-3.184-6.603-9.179-0.083-12.181,2.077
+ c-4.217,3.036-6.458,2.223-11.672,2.898C265.951,186.673,262.986,188.756,256.053,191.922z"/>
+ <path id="scarab_leg_back_right" d="M234.155,257.063l2.771-4.837
+ c6.679,8.928,6.991,16.228,10.057,23.347c5.274,12.263,0.154,28.851-9.854,37.676c-6.055,5.375-15.903,9.618-23.117,13.136
+ c-10.034,4.892-20.127,11.286-31.351,13.396c-2.481,0.466-8.789,1.295-6.691-3.522c0.976-2.237,8.092-4.591,10.146-5.734
+ c8.312-4.623,16.392-10.524,24.155-16.176c9.498-6.862,20.838-11.186,28.305-20.684c3.055-3.885,3.543-4.922,2.818-9.39
+ c-0.696-4.263-1.346-9.174-2.244-13.439C238.137,266.029,236.718,261.378,234.155,257.063z"/>
+ </g>
+ </g>
+ <radialGradient id="gradient_radial_dung"
+ cx="0" cy="0" r="60"
+ fx="0" fy="0" gradientUnits="userSpaceOnUse"
+ >
+ <stop offset="0" stop-color="#9a9a9a" />
+ <stop offset="0.70" stop-color="#bababa" />
+ <stop offset="0.95" stop-color="#FFFFFF" />
+ </radialGradient>
+ <g id="dung">
+ <circle cx="0" cy="0" r="60" fill="url(#gradient_radial_dung)" />
+ <g transform="translate(-61, -61)">
+ <!-- rough equivalent: <circle cx="0" cy="0" r="60" stroke="#8a8a8a" stroke-width="2" /> -->
+ <path fill="#8a8a8a" d="M0,61c0,33.636,27.364,61,61,61s61-27.364,61-61S94.636,0,61,0S0,27.364,0,61z
+ M2,61C2,28.467,28.467,2,61,2c32.532,0,59,26.467,59,59c0,32.533-26.468,59-59,59C28.467,120,2,93.533,2,61z"/>
+ </g>
+ <use xlink:href="#hacker_emblem" x="0" y="0" transform="scale(9)" />
+ </g>
+
+ <!-- scarab dimensions: 300x340 -->
+ <!-- dung dimensions: 120x120 (radius: 60) -->
+ <!-- scarab and dung dimensions: 300x400 -->
+
+ <g id="cairo_logo">
+ <!-- dimensions: 300x400, centered -->
+ <!-- The logo (scarab and dung), with the center-point of the bounding box at (0,0) -->
+ <use xlink:href="#dung" x="0" y="0" transform="translate(0, -140)" />
+ <use xlink:href="#scarab" x="0" y="0" transform="translate(0, 30)" />
+ </g>
+ <g id="cairo_logo_dung-centered">
+ <!-- The logo (scarab and dung), with the dung at (0,0), the scarab below -->
+ <use xlink:href="#dung" x="0" y="0" />
+ <use xlink:href="#scarab" x="0" y="0" transform="translate(0,170)" />
+ </g>
+ <g id="cairo_logo_scarab-centered">
+ <!-- The logo (scarab and dung), with the scarab's rotational center at (0,0), the dung above -->
+ <!-- The scarab's rotational center in this case is not the center of its bounding box,
+ but is calculated to be the intersection-point of the torso, spine and wings -->
+ <use xlink:href="#dung" x="0" y="0" transform="translate(0, -175.85)" />
+ <use xlink:href="#scarab" x="0" y="0" transform="translate(0, -5.85)" />
+ </g>
+ <g id="cairo_logo_top-centered">
+ <!-- The logo (scarab and dung), with the top-center point of the bounding box at (0,0) -->
+ <use xlink:href="#dung" x="0" y="0" transform="translate(0, 60)" />
+ <use xlink:href="#scarab" x="0" y="0" transform="translate(0, 230)" /><!-- (0,170+60) -->
+ </g>
+ <g id="cairo_logo_bottom-centered">
+ <!-- The logo (scarab and dung), with the bottom-center point of the bounding box at (0,0) -->
+ <use xlink:href="#dung" x="0" y="0" transform="translate(0, -340)" />
+ <use xlink:href="#scarab" x="0" y="0" transform="translate(0, -170)" />
+ </g>
+ <g id="cairo_logo_right-centered">
+ <!-- The logo (scarab and dung), with the right-center point of the bounding box at (0,0) -->
+ <use xlink:href="#dung" x="0" y="0" transform="translate(-150, -140)" />
+ <use xlink:href="#scarab" x="0" y="0" transform="translate(-150, 30)" />
+ </g>
+ <g id="cairo_logo_left-centered">
+ <!-- The logo (scarab and dung), with the left-center point of the bounding box at (0,0) -->
+ <use xlink:href="#dung" x="0" y="0" transform="translate(150, -140)" />
+ <use xlink:href="#scarab" x="0" y="0" transform="translate(150, 30)" />
+ </g>
+ <g id="cairo_logo_topleft-centered">
+ <!-- The logo (scarab and dung), with the top-left point of the bounding box at (0,0) -->
+ <use xlink:href="#dung" x="0" y="0" transform="translate(150, 60)" />
+ <use xlink:href="#scarab" x="0" y="0" transform="translate(150, 230)" /><!-- (150, 170+60) -->
+ </g>
+ <g id="cairo_logo_topright-centered">
+ <!-- The logo (scarab and dung), with the top-right point of the bounding box at (0,0) -->
+ <use xlink:href="#dung" x="0" y="0" transform="translate(-150, 60)" />
+ <use xlink:href="#scarab" x="0" y="0" transform="translate(-150, 230)" /><!-- (-150,170+60) -->
+ </g>
+ <g id="cairo_logo_bottomleft-centered">
+ <!-- The logo (scarab and dung), with the bottom-left point of the bounding box at (0,0) -->
+ <use xlink:href="#dung" x="0" y="0" transform="translate(150, -340)" />
+ <use xlink:href="#scarab" x="0" y="0" transform="translate(150, -170)" />
+ </g>
+ <g id="cairo_logo_bottomright-centered">
+ <!-- The logo (scarab and dung), with the bottom-right point of the bounding box at (0,0) -->
+ <use xlink:href="#dung" x="0" y="0" transform="translate(-150, -340)" />
+ <use xlink:href="#scarab" x="0" y="0" transform="translate(-150, -170)" />
+ </g>
+
+ <g id="cairo_text" transform="translate(0,-97)">
+ <g transform="scale(0.1484,0.1484)"> <g transform="translate(-1139,-208.5)">
+ <!-- 63 (c), advance 444, 0 horiBearing 38,522 -->
+ <path transform="translate(65,0)" d="
+ M 412, 433
+ C 385, 422 336, 413 298, 413
+ C 142, 413 38, 525 38, 680
+ C 38, 826 144, 947 298, 947
+ C 332, 947 377, 944 416, 926
+ L 409, 842
+ C 380, 861 340, 871 308, 871
+ C 187, 871 138, 771 138, 680
+ C 138, 583 197, 489 302, 489
+ C 332, 489 368, 496 404, 511
+ L 412, 433 " />
+ <!-- 61 (a), advance 556, 0 horiBearing 46,522 -->
+ <path transform="translate(486.75,0)" d="
+ M 109, 541
+ C 147, 509 204, 489 257, 489
+ C 351, 489 383, 534 383, 622
+ C 346, 620 320, 620 283, 620
+ C 186, 620 46, 660 46, 788
+ C 46, 899 123, 947 233, 947
+ C 319, 947 369, 900 391, 869
+ L 393, 869
+ L 393, 935
+ L 481, 935
+ C 479, 920 477, 893 477, 835
+ L 477, 624
+ C 477, 485 418, 413 272, 413
+ C 207, 413 151, 433 104, 461
+ L 109, 541
+ M 383, 737
+ C 383, 813 334, 871 241, 871
+ C 198, 871 146, 842 146, 788
+ C 146, 698 272, 690 323, 690
+ C 343, 690 363, 692 383, 692
+ L 383, 737 " />
+ <!-- 69 (i), advance 278, 0 horiBearing 86,730 -->
+ <path transform="translate(1000,0)" d="
+ M 92, 935
+ L 186, 935
+ L 186, 425
+ L 92, 425
+ L 92, 935
+ M 88, 261
+ A 51, 51 0 1 1 190,261
+ A 51, 51 0 1 1 88,261" />
+ <!-- 72 (r), advance 389, 0 horiBearing 80,522 -->
+ <path transform="translate(1234.25,0)" d="
+ M 80, 935
+ L 174, 935
+ L 174, 703
+ C 174, 575 229, 495 313, 495
+ C 329, 495 348, 497 365, 504
+ L 365, 420
+ C 345, 416 331, 413 303, 413
+ C 249, 413 195, 451 170, 504
+ L 168, 504
+ L 168, 425
+ L 80, 425
+ L 80, 935 " />
+ <!-- 6f (o), advance 611, 0 horiBearing 46,522 -->
+ <path transform="translate(1610,0)" d="
+ M 46, 680
+ C 46, 826 152, 947 306, 947
+ C 459, 947 565, 826 565, 680
+ C 565, 525 461, 413 306, 413
+ C 150, 413 46, 525 46, 680
+ M 146, 680
+ C 146, 583 205, 489 306, 489
+ C 406, 489 465, 583 465, 680
+ C 465, 771 416, 871 306, 871
+ C 195, 871 146, 771 146, 680 " />
+ <!-- bounds: 38, 205 <-> 2232, 947 -->
+ </g> </g>
+ </g>
+
+ <!-- scaled by 0.72, shifted around to hit pixel boundaries -->
+ <g id="cairo_text_small_spaced" transform="translate(0,-71)">
+ <g transform="scale(0.085,0.085)"> <g transform="translate(-1139,-208.5)">
+ <!-- 63 (c), advance 444, 0 horiBearing 38,522 -->
+ <path transform="translate(-151,0)" d="
+ M 412, 433
+ C 385, 422 336, 413 298, 413
+ C 142, 413 38, 525 38, 680
+ C 38, 826 144, 947 298, 947
+ C 332, 947 377, 944 416, 926
+ L 409, 842
+ C 380, 861 340, 871 308, 871
+ C 187, 871 138, 771 138, 680
+ C 138, 583 197, 489 302, 489
+ C 332, 489 368, 496 404, 511
+ L 412, 433 " />
+ <!-- 61 (a), advance 556, 0 horiBearing 46,522 -->
+ <path transform="translate(379.5,0)" d="
+ M 109, 541
+ C 147, 509 204, 489 257, 489
+ C 351, 489 383, 534 383, 622
+ C 346, 620 320, 620 283, 620
+ C 186, 620 46, 660 46, 788
+ C 46, 899 123, 947 233, 947
+ C 319, 947 369, 900 391, 869
+ L 393, 869
+ L 393, 935
+ L 481, 935
+ C 479, 920 477, 893 477, 835
+ L 477, 624
+ C 477, 485 418, 413 272, 413
+ C 207, 413 151, 433 104, 461
+ L 109, 541
+ M 383, 737
+ C 383, 813 334, 871 241, 871
+ C 198, 871 146, 842 146, 788
+ C 146, 698 272, 690 323, 690
+ C 343, 690 363, 692 383, 692
+ L 383, 737 " />
+ <!-- 69 (i), advance 278, 0 horiBearing 86,730 -->
+ <path transform="translate(1000,0)" d="
+ M 92, 935
+ L 186, 935
+ L 186, 425
+ L 92, 425
+ L 92, 935
+ M 88, 261
+ A 51, 51 0 1 1 190,261
+ A 51, 51 0 1 1 88,261" />
+ <!-- 72 (r), advance 389, 0 horiBearing 80,522 -->
+ <path transform="translate(1341.5,0)" d="
+ M 80, 935
+ L 174, 935
+ L 174, 703
+ C 174, 575 229, 495 313, 495
+ C 329, 495 348, 497 365, 504
+ L 365, 420
+ C 345, 416 331, 413 303, 413
+ C 249, 413 195, 451 170, 504
+ L 168, 504
+ L 168, 425
+ L 80, 425
+ L 80, 935 " />
+ <!-- 6f (o), advance 611, 0 horiBearing 46,522 -->
+ <path transform="translate(1826,0)" d="
+ M 46, 680
+ C 46, 826 152, 947 306, 947
+ C 459, 947 565, 826 565, 680
+ C 565, 525 461, 413 306, 413
+ C 150, 413 46, 525 46, 680
+ M 146, 680
+ C 146, 583 205, 489 306, 489
+ C 406, 489 465, 583 465, 680
+ C 465, 771 416, 871 306, 871
+ C 195, 871 146, 771 146, 680 " />
+ <!-- bounds: 38, 205 <-> 2232, 947 -->
+ </g> </g>
+ </g>
+
+
+ <!-- scaled by 0.72, shifted around to hit pixel boundaries -->
+ <g id="cairo_text_small" transform="translate(0,-71)">
+ <g transform="scale(0.085,0.085)"> <g transform="translate(-1139,-208.5)">
+ <!-- 63 (c), advance 444, 0 horiBearing 38,522 -->
+ <path transform="translate(-151,0)" d="
+ M 412, 433
+ C 385, 422 336, 413 298, 413
+ C 142, 413 38, 525 38, 680
+ C 38, 826 144, 947 298, 947
+ C 332, 947 377, 944 416, 926
+ L 409, 842
+ C 380, 861 340, 871 308, 871
+ C 187, 871 138, 771 138, 680
+ C 138, 583 197, 489 302, 489
+ C 332, 489 368, 496 404, 511
+ L 412, 433 " />
+ <!-- 61 (a), advance 556, 0 horiBearing 46,522 -->
+ <path transform="translate(261.75,0)" d="
+ M 109, 541
+ C 147, 509 204, 489 257, 489
+ C 351, 489 383, 534 383, 622
+ C 346, 620 320, 620 283, 620
+ C 186, 620 46, 660 46, 788
+ C 46, 899 123, 947 233, 947
+ C 319, 947 369, 900 391, 869
+ L 393, 869
+ L 393, 935
+ L 481, 935
+ C 479, 920 477, 893 477, 835
+ L 477, 624
+ C 477, 485 418, 413 272, 413
+ C 207, 413 151, 433 104, 461
+ L 109, 541
+ M 383, 737
+ C 383, 813 334, 871 241, 871
+ C 198, 871 146, 842 146, 788
+ C 146, 698 272, 690 323, 690
+ C 343, 690 363, 692 383, 692
+ L 383, 737 " />
+ <!-- 69 (i), advance 278, 0 horiBearing 86,730 -->
+ <path transform="translate(764.75)" d="
+ M 92, 935
+ L 186, 935
+ L 186, 425
+ L 92, 425
+ L 92, 935
+ M 88, 261
+ A 51, 51 0 1 1 190,261
+ A 51, 51 0 1 1 88,261" />
+ <!-- 72 (r), advance 389, 0 horiBearing 80,522 -->
+ <path transform="translate(988.5,0)" d="
+ M 80, 935
+ L 174, 935
+ L 174, 703
+ C 174, 575 229, 495 313, 495
+ C 329, 495 348, 497 365, 504
+ L 365, 420
+ C 345, 416 331, 413 303, 413
+ C 249, 413 195, 451 170, 504
+ L 168, 504
+ L 168, 425
+ L 80, 425
+ L 80, 935 " />
+ <!-- 6f (o), advance 611, 0 horiBearing 46,522 -->
+ <path transform="translate(1355.5,0)" d="
+ M 46, 680
+ C 46, 826 152, 947 306, 947
+ C 459, 947 565, 826 565, 680
+ C 565, 525 461, 413 306, 413
+ C 150, 413 46, 525 46, 680
+ M 146, 680
+ C 146, 583 205, 489 306, 489
+ C 406, 489 465, 583 465, 680
+ C 465, 771 416, 871 306, 871
+ C 195, 871 146, 771 146, 680 " />
+ <!-- bounds: 38, 205 <-> 2232, 947 -->
+ </g> </g>
+ </g>
+
+ <g id="cairo_logo_text_small">
+ <!-- The logo on the left, the text 'cairo' on the right -->
+ <use xlink:href="#cairo_logo_bottomleft-centered" transform="translate(0, 78), scale(0.1944)" />
+ <use xlink:href="#cairo_text_small" transform="translate(175,82)"/>
+ </g>
+
+ <g id="cairo_logo_with_text">
+ <!-- The logo (scarab and dung), with the text 'cairo' below, the dot of the 'i' positioned between the hind legs of the scarab -->
+ <!-- dimensions: 300x490, centered -->
+ <use xlink:href="#cairo_logo_top-centered" transform="translate(0, -245)" />
+ <use xlink:href="#cairo_text" transform="translate(0, 245)" />
+ </g>
+
+ <g id="cairo_banner">
+ <!-- The logo on the left, the text 'cairo' in the center, and a mirror image of the logo on the right -->
+ <!-- The logos are scaled such that the scarab body nearly matches the height of the text characters (excepting the 'i')
+ and the dung should nearly aligns with the dot of the 'i'. The bottoms of the logos are aligned with the bottom of the text. -->
+ <!-- dimensions: 370x88, centered -->
+ <use xlink:href="#cairo_logo_bottomleft-centered" transform="translate(-180, 40), scale(0.1944)" />
+ <use xlink:href="#cairo_text_small" transform="translate(0, 42)" fill="black" />
+ <use xlink:href="#cairo_logo_bottomleft-centered" transform="translate(180, 40), scale(0.1944), scale(-1, 1)" />
+ </g>
+
+ <g id="freedesktop_org_logo" style="fill:#FFFFFF;stroke:#3B80AE;stroke-width:2.4588;">
+ <g>
+ <path style="stroke:#BABABA;" d="M85.277,40.796c2.058,7.884-2.667,15.942-10.551,17.999L27.143,71.21c-7.884,2.057-15.943-2.667-18-10.552
+ l-7.448-28.55c-2.057-7.884,2.667-15.942,10.551-17.999L59.83,1.695c7.884-2.057,15.942,2.667,17.999,10.551
+ l7.449,28.55z"/>>
+ <path style="fill:#3B80AE;stroke:none;" d="M80.444,39.778c1.749,7.854-1.816,13.621-9.504,15.447l-42.236,11.02c-7.569,2.396-14.089-1.181
+ -15.838-8.836L6.53,33.127c-1.749-8.145,0.709-12.889,9.503-15.447L58.27,6.661
+ c8.144-1.826,14.089,1.363,15.838,8.835l6.336,24.282z"/>>
+ </g>g>
+ <path style="opacity:0.5;fill:none;stroke:#FFFFFF;" d="M45.542,51.793L24.104,31.102l38.1-4.393L45.542,51.793z"/>>
+ <path d="M72.325,28.769c0.405,1.55-0.525,3.136-2.075,3.541l-12.331,3.217c-1.551,0.404-3.137-0.525-3.542-2.076l-2.295-8.801
+ c-0.405-1.551,0.524-3.137,2.076-3.542l12.33-3.217c1.551-0.405,3.137,0.525,3.542,2.076l2.295,8.801z"/>>
+ <path d="M36.51,33.625c0.496,1.9-0.645,3.844-2.545,4.34l-15.112,3.943c-1.901,0.496-3.845-0.644-4.34-2.544l-2.814-10.786
+ c-0.496-1.901,0.644-3.844,2.544-4.34l15.113-3.942c1.901-0.496,3.845,0.643,4.34,2.544l2.814,10.786z"/>>
+ <path d="M52.493,53.208c0.278,1.065-0.36,2.154-1.425,2.432L42.6,57.848c-1.064,0.277-2.153-0.36-2.431-1.426l-1.577-6.043
+ c-0.277-1.064,0.36-2.153,1.425-2.432l8.468-2.209c1.064-0.277,2.154,0.361,2.431,1.426l1.577,6.043z"/>>
+ </g>g>
+ </defs>
+
+ <!-- Blue bar at top of slide -->
+ <rect x="0" y="0" width="1024" height="170" fill="#162284" />
+
+ <g font-family="Frutiger">
+ <!-- Slide title -->
+ <g id="slide_title" transform="translate(512, 133)">
+ <text text-anchor="middle"
+ fill="white"
+ font-weight="bold"
+ x="0"
+ y="4" font-size="55"
+ ss:variable="title">Slide Title</text>
+ </g>
+
+ <!-- Slide content -->
+ <g ss:region="default">
+ <rect x="112" y="200" width="800" height="480" fill="none" stroke="blue"/>
+ <text font-size="35" fill="black"
+ x="112" y="232">Slide content</text>
+ </g>
+
+ <!-- Footer -->
+ <text ss:variable="URL" x="1016" y="753" text-anchor="end" font-size="20">http://cairographics.org</text>
+ </g>
+
+</svg>
diff --git a/doc/tutorial/slides/cairo-code.svg b/doc/tutorial/slides/cairo-code.svg
new file mode 100644
index 000000000..09e26bf3a
--- /dev/null
+++ b/doc/tutorial/slides/cairo-code.svg
@@ -0,0 +1,913 @@
+<?xml version="1.0" ?>
+<svg width="1024" height="768"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:ss="http://www.svgslides.org/svgslides0.1"
+ fill="black">
+
+
+
+ <defs id="cairo-artwork_defs">
+ <g id="hacker_emblem">
+ <!-- Note: This is similar though not identical to Keith Packard's SVG version
+ of the hacker emblem (http://www.catb.org/hacker-emblem/glider.svg) -->
+ <g id="hacker_emblem_grid" fill="white" stroke="none">
+ <!-- Outside: Top, Right, Bottom, Left -->
+ <rect x="-2.95" y="-3.05" width="6" height="0.1" />
+ <rect x="2.95" y="-2.95" width="0.1" height="6" />
+ <rect x="-3.05" y="2.95" width="6" height="0.1" />
+ <rect x="-3.05" y="-3.05" width="0.1" height="6" />
+ <!-- Vertical: Left, Right -->
+ <rect x="-1.05" y="-2.95" width="0.1" height="5.9" />
+ <rect x="0.95" y="-2.95" width="0.1" height="5.9" />
+ <!-- Horizontal: TopLeft, TopMiddle, TopRight -->
+ <rect x="-2.95" y="-1.05" width="1.9" height="0.1" />
+ <rect x="-0.95" y="-1.05" width="1.9" height="0.1" />
+ <rect x="1.05" y="-1.05" width="1.9" height="0.1" />
+ <!-- Horizontal: BottomLeft, BottomMiddle, BottomRight -->
+ <rect x="-2.95" y="0.95" width="1.9" height="0.1" />
+ <rect x="-0.95" y="0.95" width="1.9" height="0.1" />
+ <rect x="1.05" y="0.95" width="1.9" height="0.1" />
+ </g>
+ <g id="hacker_emblem_dots" fill="white">
+ <circle cx="0" cy="-2" r="0.7" />
+ <circle cx="2" cy="0" r="0.7" />
+ <circle cx="-2" cy="2" r="0.7" />
+ <circle cx="0" cy="2" r="0.7" />
+ <circle cx="2" cy="2" r="0.7" />
+ </g>
+ </g>
+ <g id="scarab" fill="#f19a14">
+ <g transform="translate(-150, -170)">
+ <path id="scarab_head" d="M205.599,94.567c0-11.668-24.914-21.129-55.628-21.129
+ c-30.723,0-55.624,9.46-55.624,21.129c0,10.203,24.901,7.346,55.624,7.346C180.685,101.913,205.599,104.233,205.599,94.567z"/>
+ <path id="scarab_torso" d="M136.423,161.506c0,0,12.751,12.577,13.547,13.362
+ c2.262-2.232,13.545-13.362,13.545-13.362c7.135-7.036,87.111-6.399,91.066-6.363c-0.469-6.298-1.254-12.472-2.325-18.519
+ c-15.183-19.279-42.811-32.225-74.485-32.225h-55.518c-31.745,0-59.439,13.011-74.598,32.37c-1.054,6-1.829,12.128-2.296,18.374
+ C49.321,155.106,129.288,154.47,136.423,161.506z"/>
+ <path id="scarab_spine" d="M149.97,301.187c2.005-24.729,8.386-103.483,8.405-103.721
+ c-0.09-0.219-6.478-15.578-8.405-20.214c-1.936,4.655-8.316,19.995-8.408,20.214C141.582,197.704,147.965,276.458,149.97,301.187z"/>
+ <path id="scarab_wing_left" d="M140.403,197.149l8.862-21.31l-13.686-13.499
+ c-5.65-5.573-67.074-6.235-90.259-6.019l-0.006-0.622c-0.154,2.144-0.271,4.302-0.35,6.475
+ c-0.076,2.207,10.392,4.706,10.392,6.717c0,2.319-10.457,5.084-10.359,7.631c2.993,73.349,48.53,131.631,104.372,132.048
+ l-9.02-111.29L140.403,197.149z"/>
+ <path id="scarab_wing_right" d="M244.585,168.891c0-2.011,10.467-4.506,10.391-6.715
+ c-0.079-2.174-0.195-4.332-0.351-6.479l-0.004,0.624c-23.186-0.216-84.608,0.445-90.26,6.017l-13.688,13.502l8.915,21.438
+ l-9.017,111.29c55.854-0.417,101.378-58.698,104.373-132.049C255.04,173.976,244.585,171.209,244.585,168.891z"/>
+ <path id="scarab_leg_front_left" d="M44.506,141.12c-4.135-0.856-4.895-1.54-7.935-2.92
+ c-9.59-3.364-10.376-5.481-16.08-11.86c-7.426-8.306-12.661-20.142-17.1-29.463c-3.576-7.525-3.984-16.409-2.86-24.273
+ c0.991-6.935,7.144-12.869,12.074-18.92c5.844-7.191,10.356-14.822,17.924-21.354c7.736-6.682,23.203-9.809,26.168-19.648
+ C57.86,8.819,54.334,1.766,61.482,0c-0.366,4.703,3.639,8.477,2.397,13.575c-1.129,4.627-4.368,5.811-9.611,9.099
+ c-7.564,4.746-18.366,8.779-24.748,13.965c-7.175,5.827-4.369,13.771-10.569,20.057c-2.001,2.03-7.901,4.706-9.137,6.83
+ c-1.861,3.199-0.297,9.572-0.116,13.12c0.425,8.284,5.588,14.244,9.555,22.045c4.152,8.141,6.429,15.409,13.411,22.519
+ c4.183,4.262,11.429,4.802,16.21,10.647l-3.555,4.186L44.506,141.12z"/>
+ <path id="scarab_leg_middle_left" d="M43.94,191.922l-0.809-7.346
+ c-9.506-4.579-10.339-9.772-20.738-12.466c-23.728-6.151-21.361,11.25-15.532,26.373c5.676,14.726,8.237,30.23,14.345,44.795
+ c2.805,6.688,6.919,13.213,14.298,15.127c0.372-8.435-0.917-10.651-6.113-16.919c-4.395-5.293-3.326-12.548-6.072-18.504
+ c-3.581-7.804-4.196-15.646-7.279-23.502c-1.363-3.479-8.33-13.966-6.452-17.861c3.183-6.603,9.178-0.083,12.179,2.077
+ c4.218,3.036,6.467,2.223,11.681,2.898C34.041,186.673,37.005,188.756,43.94,191.922z"/>
+ <path id="scarab_leg_back_left" d="M65.839,257.063l-2.771-4.837
+ c-6.68,8.928-6.993,16.228-10.056,23.347c-5.277,12.263-0.157,28.851,9.854,37.676c6.052,5.375,15.907,9.618,23.122,13.136
+ c10.035,4.892,20.113,11.286,31.336,13.396c2.482,0.466,8.798,1.295,6.693-3.522c-0.975-2.237-8.091-4.591-10.146-5.734
+ c-8.312-4.623-16.377-10.524-24.142-16.176c-9.498-6.862-20.843-11.186-28.311-20.684c-3.054-3.885-3.544-4.922-2.816-9.39
+ c0.693-4.263,1.344-9.174,2.241-13.439C61.855,266.029,63.274,261.378,65.839,257.063z"/>
+ <path id="scarab_leg_front_right" d="M255.487,141.12c4.134-0.856,4.896-1.54,7.936-2.92
+ c9.583-3.364,10.369-5.481,16.071-11.86c7.428-8.306,12.661-20.142,17.115-29.463c3.574-7.525,3.983-16.409,2.86-24.273
+ c-0.992-6.935-7.157-12.869-12.087-18.92c-5.843-7.191-10.356-14.822-17.919-21.354c-7.735-6.682-23.202-9.809-26.167-19.648
+ C242.135,8.819,245.66,1.766,238.511,0c0.366,4.703-3.637,8.477-2.396,13.575c1.131,4.627,4.368,5.811,9.611,9.099
+ c7.563,4.746,18.367,8.779,24.747,13.965c7.17,5.827,4.362,13.771,10.563,20.057c2.001,2.03,7.901,4.706,9.139,6.83
+ c1.859,3.199,0.295,9.572,0.113,13.12c-0.424,8.284-5.588,14.244-9.553,22.045c-4.152,8.141-6.431,15.409-13.404,22.519
+ c-4.184,4.262-11.429,4.802-16.211,10.647l3.556,4.186L255.487,141.12z"/>
+ <path id="scarab_leg_middle_right" d="M256.053,191.922l0.81-7.346
+ c9.507-4.579,10.34-9.772,20.73-12.466c23.741-6.151,21.374,11.25,15.534,26.373c-5.676,14.726-8.238,30.23-14.347,44.795
+ c-2.804,6.688-6.911,13.213-14.291,15.127c-0.371-8.435,0.918-10.651,6.113-16.919c4.39-5.293,3.319-12.548,6.066-18.504
+ c3.58-7.804,4.197-15.646,7.278-23.502c1.363-3.479,8.33-13.966,6.453-17.861c-3.184-6.603-9.179-0.083-12.181,2.077
+ c-4.217,3.036-6.458,2.223-11.672,2.898C265.951,186.673,262.986,188.756,256.053,191.922z"/>
+ <path id="scarab_leg_back_right" d="M234.155,257.063l2.771-4.837
+ c6.679,8.928,6.991,16.228,10.057,23.347c5.274,12.263,0.154,28.851-9.854,37.676c-6.055,5.375-15.903,9.618-23.117,13.136
+ c-10.034,4.892-20.127,11.286-31.351,13.396c-2.481,0.466-8.789,1.295-6.691-3.522c0.976-2.237,8.092-4.591,10.146-5.734
+ c8.312-4.623,16.392-10.524,24.155-16.176c9.498-6.862,20.838-11.186,28.305-20.684c3.055-3.885,3.543-4.922,2.818-9.39
+ c-0.696-4.263-1.346-9.174-2.244-13.439C238.137,266.029,236.718,261.378,234.155,257.063z"/>
+ </g>
+ </g>
+ <radialGradient id="gradient_radial_dung"
+ cx="0" cy="0" r="60"
+ fx="0" fy="0" gradientUnits="userSpaceOnUse"
+ >
+ <stop offset="0" stop-color="#9a9a9a" />
+ <stop offset="0.70" stop-color="#bababa" />
+ <stop offset="0.95" stop-color="#FFFFFF" />
+ </radialGradient>
+ <g id="dung">
+ <circle cx="0" cy="0" r="60" fill="url(#gradient_radial_dung)" />
+ <g transform="translate(-61, -61)">
+ <!-- rough equivalent: <circle cx="0" cy="0" r="60" stroke="#8a8a8a" stroke-width="2" /> -->
+ <path fill="#8a8a8a" d="M0,61c0,33.636,27.364,61,61,61s61-27.364,61-61S94.636,0,61,0S0,27.364,0,61z
+ M2,61C2,28.467,28.467,2,61,2c32.532,0,59,26.467,59,59c0,32.533-26.468,59-59,59C28.467,120,2,93.533,2,61z"/>
+ </g>
+ <use xlink:href="#hacker_emblem" x="0" y="0" transform="scale(9)" />
+ </g>
+ <g id="dung_2_color">
+ <!-- This would be simple a circle like so:
+ <circle cx="0" cy="0" r="48" stroke-width="2" fill="none" stroke="white"/>
+ but there appears to currently be a bug in the cairo
+ PDF backend that results in an ugly spike in that
+ case. So we use 8 splines instead.
+ -->
+ <path stroke-width="4" stroke="white" fill="none" d="
+M 48, 0
+C 48, 12.730391512298112,
+ 42.94287166245995, 24.939379331448613
+ 33.941125496954285, 33.941125496954278
+C 24.939379331448624, 42.942871662459943
+ 12.730391512298114, 48
+ 0, 48
+C -12.730391512298109, 48,
+ -24.939379331448613, 42.94287166245995
+ -33.941125496954278, 33.941125496954285
+C -42.942871662459943, 24.939379331448624,
+ -48, 12.730391512298118,
+ -48, 0,
+C -48, -12.730391512298105,
+ -42.94287166245995, -24.939379331448613,
+ -33.941125496954285, -33.941125496954278
+C -24.939379331448624, -42.942871662459943,
+ -12.730391512298119, -48,
+ 0, -48
+C 12.730391512298104, -48,
+ 24.939379331448606, -42.942871662459943,
+ 33.941125496954271, -33.941125496954285
+C 42.942871662459936, -24.939379331448624,
+ 48, -12.730391512298123,
+ 48, 0" />
+ <g transform="scale(9)" fill="white" stroke="none" stroke-width="0.22222">
+ <!-- Hacker emblem grid -->
+ <!--
+ <path stroke="white" fill="none"
+ d="M -3,-3 L 3,-3 L 3,3 L-3,3 Z
+ M -1,-3 L -1, 3
+ M 1,-3 L 1, 3
+ M -3,-1 L 3,-1
+ M -3, 1 L 3, 1"/>
+ -->
+
+ <!-- Hacker emblem dots -->
+ <circle cx="0" cy="-2" r="0.7" />
+ <circle cx="2" cy="0" r="0.7" />
+ <circle cx="-2" cy="2" r="0.7" />
+ <circle cx="0" cy="2" r="0.7" />
+ <circle cx="2" cy="2" r="0.7" />
+ </g>
+ </g>
+
+ <!-- scarab dimensions: 300x340 -->
+ <!-- dung dimensions: 120x120 (radius: 60) -->
+ <!-- scarab and dung dimensions: 300x400 -->
+
+ <g id="cairo_logo">
+ <!-- dimensions: 300x400, centered -->
+ <!-- The logo (scarab and dung), with the center-point of the bounding box at (0,0) -->
+ <use xlink:href="#dung_2_color" x="0" y="0" transform="translate(0, -140)" />
+ <use xlink:href="#scarab" x="0" y="0" transform="translate(0, 30)" />
+ </g>
+ <g id="cairo_logo_dung-centered">
+ <!-- The logo (scarab and dung), with the dung at (0,0), the scarab below -->
+ <use xlink:href="#dung_2_color" x="0" y="0" />
+ <use xlink:href="#scarab" x="0" y="0" transform="translate(0,170)" />
+ </g>
+ <g id="cairo_logo_scarab-centered">
+ <!-- The logo (scarab and dung), with the scarab's rotational center at (0,0), the dung above -->
+ <!-- The scarab's rotational center in this case is not the center of its bounding box,
+ but is calculated to be the intersection-point of the torso, spine and wings -->
+ <use xlink:href="#dung_2_color" x="0" y="0" transform="translate(0, -175.85)" />
+ <use xlink:href="#scarab" x="0" y="0" transform="translate(0, -5.85)" />
+ </g>
+ <g id="cairo_logo_top-centered">
+ <!-- The logo (scarab and dung), with the top-center point of the bounding box at (0,0) -->
+ <use xlink:href="#dung_2_color" x="0" y="0" transform="translate(0, 60)" />
+ <use xlink:href="#scarab" x="0" y="0" transform="translate(0, 230)" /><!-- (0,170+60) -->
+ </g>
+ <g id="cairo_logo_bottom-centered">
+ <!-- The logo (scarab and dung), with the bottom-center point of the bounding box at (0,0) -->
+ <use xlink:href="#dung_2_color" x="0" y="0" transform="translate(0, -340)" />
+ <use xlink:href="#scarab" x="0" y="0" transform="translate(0, -170)" />
+ </g>
+ <g id="cairo_logo_right-centered">
+ <!-- The logo (scarab and dung), with the right-center point of the bounding box at (0,0) -->
+ <use xlink:href="#dung_2_color" x="0" y="0" transform="translate(-150, -140)" />
+ <use xlink:href="#scarab" x="0" y="0" transform="translate(-150, 30)" />
+ </g>
+ <g id="cairo_logo_left-centered">
+ <!-- The logo (scarab and dung), with the left-center point of the bounding box at (0,0) -->
+ <use xlink:href="#dung_2_color" x="0" y="0" transform="translate(150, -140)" />
+ <use xlink:href="#scarab" x="0" y="0" transform="translate(150, 30)" />
+ </g>
+ <g id="cairo_logo_topleft-centered">
+ <!-- The logo (scarab and dung), with the top-left point of the bounding box at (0,0) -->
+ <use xlink:href="#dung_2_color" x="0" y="0" transform="translate(150, 60)" />
+ <use xlink:href="#scarab" x="0" y="0" transform="translate(150, 230)" /><!-- (150, 170+60) -->
+ </g>
+ <g id="cairo_logo_topright-centered">
+ <!-- The logo (scarab and dung), with the top-right point of the bounding box at (0,0) -->
+ <use xlink:href="#dung_2_color" x="0" y="0" transform="translate(-150, 60)" />
+ <use xlink:href="#scarab" x="0" y="0" transform="translate(-150, 230)" /><!-- (-150,170+60) -->
+ </g>
+ <g id="cairo_logo_bottomleft-centered">
+ <!-- The logo (scarab and dung), with the bottom-left point of the bounding box at (0,0) -->
+ <use xlink:href="#dung_2_color" x="0" y="0" transform="translate(150, -340)" />
+ <use xlink:href="#scarab" x="0" y="0" transform="translate(150, -170)" />
+ </g>
+ <g id="cairo_logo_bottomright-centered">
+ <!-- The logo (scarab and dung), with the bottom-right point of the bounding box at (0,0) -->
+ <use xlink:href="#dung_2_color" x="0" y="0" transform="translate(-150, -340)" />
+ <use xlink:href="#scarab" x="0" y="0" transform="translate(-150, -170)" />
+ </g>
+
+ <g id="cairo_text" transform="translate(0,-97)">
+ <g transform="scale(0.1484,0.1484)"> <g transform="translate(-1139,-208.5)">
+ <!-- 63 (c), advance 444, 0 horiBearing 38,522 -->
+ <path transform="translate(65,0)" d="
+ M 412, 433
+ C 385, 422 336, 413 298, 413
+ C 142, 413 38, 525 38, 680
+ C 38, 826 144, 947 298, 947
+ C 332, 947 377, 944 416, 926
+ L 409, 842
+ C 380, 861 340, 871 308, 871
+ C 187, 871 138, 771 138, 680
+ C 138, 583 197, 489 302, 489
+ C 332, 489 368, 496 404, 511
+ L 412, 433 " />
+ <!-- 61 (a), advance 556, 0 horiBearing 46,522 -->
+ <path transform="translate(486.75,0)" d="
+ M 109, 541
+ C 147, 509 204, 489 257, 489
+ C 351, 489 383, 534 383, 622
+ C 346, 620 320, 620 283, 620
+ C 186, 620 46, 660 46, 788
+ C 46, 899 123, 947 233, 947
+ C 319, 947 369, 900 391, 869
+ L 393, 869
+ L 393, 935
+ L 481, 935
+ C 479, 920 477, 893 477, 835
+ L 477, 624
+ C 477, 485 418, 413 272, 413
+ C 207, 413 151, 433 104, 461
+ L 109, 541
+ M 383, 737
+ C 383, 813 334, 871 241, 871
+ C 198, 871 146, 842 146, 788
+ C 146, 698 272, 690 323, 690
+ C 343, 690 363, 692 383, 692
+ L 383, 737 " />
+ <!-- 69 (i), advance 278, 0 horiBearing 86,730 -->
+ <path transform="translate(1000,0)" d="
+ M 92, 935
+ L 186, 935
+ L 186, 425
+ L 92, 425
+ L 92, 935
+ M 88, 261
+ A 51, 51 0 1 1 190,261
+ A 51, 51 0 1 1 88,261" />
+ <!-- 72 (r), advance 389, 0 horiBearing 80,522 -->
+ <path transform="translate(1234.25,0)" d="
+ M 80, 935
+ L 174, 935
+ L 174, 703
+ C 174, 575 229, 495 313, 495
+ C 329, 495 348, 497 365, 504
+ L 365, 420
+ C 345, 416 331, 413 303, 413
+ C 249, 413 195, 451 170, 504
+ L 168, 504
+ L 168, 425
+ L 80, 425
+ L 80, 935 " />
+ <!-- 6f (o), advance 611, 0 horiBearing 46,522 -->
+ <path transform="translate(1610,0)" d="
+ M 46, 680
+ C 46, 826 152, 947 306, 947
+ C 459, 947 565, 826 565, 680
+ C 565, 525 461, 413 306, 413
+ C 150, 413 46, 525 46, 680
+ M 146, 680
+ C 146, 583 205, 489 306, 489
+ C 406, 489 465, 583 465, 680
+ C 465, 771 416, 871 306, 871
+ C 195, 871 146, 771 146, 680 " />
+ <!-- bounds: 38, 205 <-> 2232, 947 -->
+ </g> </g>
+ </g>
+
+ <!-- scaled by 0.72, shifted around to hit pixel boundaries -->
+ <g id="cairo_text_small_spaced" transform="translate(0,-71)">
+ <g transform="scale(0.085,0.085)"> <g transform="translate(-1139,-208.5)">
+ <!-- 63 (c), advance 444, 0 horiBearing 38,522 -->
+ <path transform="translate(-151,0)" d="
+ M 412, 433
+ C 385, 422 336, 413 298, 413
+ C 142, 413 38, 525 38, 680
+ C 38, 826 144, 947 298, 947
+ C 332, 947 377, 944 416, 926
+ L 409, 842
+ C 380, 861 340, 871 308, 871
+ C 187, 871 138, 771 138, 680
+ C 138, 583 197, 489 302, 489
+ C 332, 489 368, 496 404, 511
+ L 412, 433 " />
+ <!-- 61 (a), advance 556, 0 horiBearing 46,522 -->
+ <path transform="translate(379.5,0)" d="
+ M 109, 541
+ C 147, 509 204, 489 257, 489
+ C 351, 489 383, 534 383, 622
+ C 346, 620 320, 620 283, 620
+ C 186, 620 46, 660 46, 788
+ C 46, 899 123, 947 233, 947
+ C 319, 947 369, 900 391, 869
+ L 393, 869
+ L 393, 935
+ L 481, 935
+ C 479, 920 477, 893 477, 835
+ L 477, 624
+ C 477, 485 418, 413 272, 413
+ C 207, 413 151, 433 104, 461
+ L 109, 541
+ M 383, 737
+ C 383, 813 334, 871 241, 871
+ C 198, 871 146, 842 146, 788
+ C 146, 698 272, 690 323, 690
+ C 343, 690 363, 692 383, 692
+ L 383, 737 " />
+ <!-- 69 (i), advance 278, 0 horiBearing 86,730 -->
+ <path transform="translate(1000,0)" d="
+ M 92, 935
+ L 186, 935
+ L 186, 425
+ L 92, 425
+ L 92, 935
+ M 88, 261
+ A 51, 51 0 1 1 190,261
+ A 51, 51 0 1 1 88,261" />
+ <!-- 72 (r), advance 389, 0 horiBearing 80,522 -->
+ <path transform="translate(1341.5,0)" d="
+ M 80, 935
+ L 174, 935
+ L 174, 703
+ C 174, 575 229, 495 313, 495
+ C 329, 495 348, 497 365, 504
+ L 365, 420
+ C 345, 416 331, 413 303, 413
+ C 249, 413 195, 451 170, 504
+ L 168, 504
+ L 168, 425
+ L 80, 425
+ L 80, 935 " />
+ <!-- 6f (o), advance 611, 0 horiBearing 46,522 -->
+ <path transform="translate(1826,0)" d="
+ M 46, 680
+ C 46, 826 152, 947 306, 947
+ C 459, 947 565, 826 565, 680
+ C 565, 525 461, 413 306, 413
+ C 150, 413 46, 525 46, 680
+ M 146, 680
+ C 146, 583 205, 489 306, 489
+ C 406, 489 465, 583 465, 680
+ C 465, 771 416, 871 306, 871
+ C 195, 871 146, 771 146, 680 " />
+ <!-- bounds: 38, 205 <-> 2232, 947 -->
+ </g> </g>
+ </g>
+
+
+ <!-- scaled by 0.72, shifted around to hit pixel boundaries -->
+ <g id="cairo_text_small" transform="translate(0,-71)">
+ <g transform="scale(0.085,0.085)"> <g transform="translate(-1139,-208.5)">
+ <!-- 63 (c), advance 444, 0 horiBearing 38,522 -->
+ <path transform="translate(-151,0)" d="
+ M 412, 433
+ C 385, 422 336, 413 298, 413
+ C 142, 413 38, 525 38, 680
+ C 38, 826 144, 947 298, 947
+ C 332, 947 377, 944 416, 926
+ L 409, 842
+ C 380, 861 340, 871 308, 871
+ C 187, 871 138, 771 138, 680
+ C 138, 583 197, 489 302, 489
+ C 332, 489 368, 496 404, 511
+ L 412, 433 " />
+ <!-- 61 (a), advance 556, 0 horiBearing 46,522 -->
+ <path transform="translate(261.75,0)" d="
+ M 109, 541
+ C 147, 509 204, 489 257, 489
+ C 351, 489 383, 534 383, 622
+ C 346, 620 320, 620 283, 620
+ C 186, 620 46, 660 46, 788
+ C 46, 899 123, 947 233, 947
+ C 319, 947 369, 900 391, 869
+ L 393, 869
+ L 393, 935
+ L 481, 935
+ C 479, 920 477, 893 477, 835
+ L 477, 624
+ C 477, 485 418, 413 272, 413
+ C 207, 413 151, 433 104, 461
+ L 109, 541
+ M 383, 737
+ C 383, 813 334, 871 241, 871
+ C 198, 871 146, 842 146, 788
+ C 146, 698 272, 690 323, 690
+ C 343, 690 363, 692 383, 692
+ L 383, 737 " />
+ <!-- 69 (i), advance 278, 0 horiBearing 86,730 -->
+ <path transform="translate(764.75)" d="
+ M 92, 935
+ L 186, 935
+ L 186, 425
+ L 92, 425
+ L 92, 935
+ M 88, 261
+ A 51, 51 0 1 1 190,261
+ A 51, 51 0 1 1 88,261" />
+ <!-- 72 (r), advance 389, 0 horiBearing 80,522 -->
+ <path transform="translate(988.5,0)" d="
+ M 80, 935
+ L 174, 935
+ L 174, 703
+ C 174, 575 229, 495 313, 495
+ C 329, 495 348, 497 365, 504
+ L 365, 420
+ C 345, 416 331, 413 303, 413
+ C 249, 413 195, 451 170, 504
+ L 168, 504
+ L 168, 425
+ L 80, 425
+ L 80, 935 " />
+ <!-- 6f (o), advance 611, 0 horiBearing 46,522 -->
+ <path transform="translate(1355.5,0)" d="
+ M 46, 680
+ C 46, 826 152, 947 306, 947
+ C 459, 947 565, 826 565, 680
+ C 565, 525 461, 413 306, 413
+ C 150, 413 46, 525 46, 680
+ M 146, 680
+ C 146, 583 205, 489 306, 489
+ C 406, 489 465, 583 465, 680
+ C 465, 771 416, 871 306, 871
+ C 195, 871 146, 771 146, 680 " />
+ <!-- bounds: 38, 205 <-> 2232, 947 -->
+ </g> </g>
+ </g>
+
+ <g id="cairo_logo_text_small">
+ <!-- The logo on the left, the text 'cairo' on the right -->
+ <use xlink:href="#cairo_logo_bottomleft-centered" transform="translate(0, 78), scale(0.1944)" />
+ <use xlink:href="#cairo_text_small" fill="white" transform="translate(175,82)"/>
+ </g>
+
+ <g id="cairo_logo_with_text">
+ <!-- The logo (scarab and dung), with the text 'cairo' below, the dot of the 'i' positioned between the hind legs of the scarab -->
+ <!-- dimensions: 300x490, centered -->
+ <use xlink:href="#cairo_logo_top-centered" transform="translate(0, -245)" />
+ <use xlink:href="#cairo_text" transform="translate(0, 245)" />
+ </g>
+
+ <g id="cairo_banner">
+ <!-- The logo on the left, the text 'cairo' in the center, and a mirror image of the logo on the right -->
+ <!-- The logos are scaled such that the scarab body nearly matches the height of the text characters (excepting the 'i')
+ and the dung should nearly aligns with the dot of the 'i'. The bottoms of the logos are aligned with the bottom of the text. -->
+ <!-- dimensions: 370x88, centered -->
+ <use xlink:href="#cairo_logo_bottomleft-centered" transform="translate(-180, 40), scale(0.1944)" />
+ <use xlink:href="#cairo_text_small" transform="translate(0, 42)" fill="black" />
+ <use xlink:href="#cairo_logo_bottomleft-centered" transform="translate(180, 40), scale(0.1944), scale(-1, 1)" />
+ </g>
+
+ <g id="freedesktop_org_logo" style="fill:#FFFFFF;stroke:#3B80AE;stroke-width:2.4588;">
+ <g>
+ <path style="stroke:#BABABA;" d="M85.277,40.796c2.058,7.884-2.667,15.942-10.551,17.999L27.143,71.21c-7.884,2.057-15.943-2.667-18-10.552
+ l-7.448-28.55c-2.057-7.884,2.667-15.942,10.551-17.999L59.83,1.695c7.884-2.057,15.942,2.667,17.999,10.551
+ l7.449,28.55z"/>>
+ <path style="fill:#3B80AE;stroke:none;" d="M80.444,39.778c1.749,7.854-1.816,13.621-9.504,15.447l-42.236,11.02c-7.569,2.396-14.089-1.181
+ -15.838-8.836L6.53,33.127c-1.749-8.145,0.709-12.889,9.503-15.447L58.27,6.661
+ c8.144-1.826,14.089,1.363,15.838,8.835l6.336,24.282z"/>>
+ </g>g>
+ <path style="opacity:0.5;fill:none;stroke:#FFFFFF;" d="M45.542,51.793L24.104,31.102l38.1-4.393L45.542,51.793z"/>>
+ <path d="M72.325,28.769c0.405,1.55-0.525,3.136-2.075,3.541l-12.331,3.217c-1.551,0.404-3.137-0.525-3.542-2.076l-2.295-8.801
+ c-0.405-1.551,0.524-3.137,2.076-3.542l12.33-3.217c1.551-0.405,3.137,0.525,3.542,2.076l2.295,8.801z"/>>
+ <path d="M36.51,33.625c0.496,1.9-0.645,3.844-2.545,4.34l-15.112,3.943c-1.901,0.496-3.845-0.644-4.34-2.544l-2.814-10.786
+ c-0.496-1.901,0.644-3.844,2.544-4.34l15.113-3.942c1.901-0.496,3.845,0.643,4.34,2.544l2.814,10.786z"/>>
+ <path d="M52.493,53.208c0.278,1.065-0.36,2.154-1.425,2.432L42.6,57.848c-1.064,0.277-2.153-0.36-2.431-1.426l-1.577-6.043
+ c-0.277-1.064,0.36-2.153,1.425-2.432l8.468-2.209c1.064-0.277,2.154,0.361,2.431,1.426l1.577,6.043z"/>>
+ </g>g>
+ <g id="bullet">
+ <use x="0" y="0" xlink:href="#cairo_logo" transform="translate(-6,-2) scale(0.1, 0.1)"/>>
+ </g>
+ <g id="redhat_logo_horizontal">
+ <!-- 380x125 Red Hat log (horizontal layout) -->
+ <g fill="black" stroke="none"
+ transform="translate(0,124),scale(1,-1),translate(-214,-258)"
+ fill-rule="evenodd"
+ >
+ <!-- r -->
+ <path fill="black" d="
+ M 367.0625 315.3203
+ C 367.0625 320.8765 366.9463 324.9644 366.7227 328.6597
+ L 375.811 328.6597
+ L 376.2002 320.7764
+ L 376.4971 320.7764
+ C 378.5391 326.6221 383.3809 329.5996 387.8594 329.5996
+ C 388.8843 329.5996 389.4824 329.5601 390.3218 329.373
+ L 390.3218 319.4863
+ C 389.3398 319.6763 388.4224 319.7842 387.1592 319.7842
+ C 382.1597 319.7842 378.688 316.6006 377.751 311.8447
+ C 377.5732 310.918 377.4805 309.8086 377.4805 308.6777
+ L 377.4805 287.1504
+ L 366.9766 287.1504
+ L 367.0625 315.3203
+ " />
+
+ <!-- e -->
+ <path fill="black" d="
+ M 402.9927 305.0791
+ C 403.2715 297.5586 409.0918 294.2695 415.814 294.2695
+ C 420.6406 294.2695 424.0942 295.0234 427.2681 296.1924
+ L 428.8232 288.9678
+ C 425.269 287.4629 420.3413 286.3359 414.3149 286.3359
+ C 400.8384 286.3359 392.9409 294.6592 392.9409 307.3809
+ C 392.9409 318.8369 399.8911 329.6772 413.2437 329.6772
+ C 426.7397 329.6772 431.1338 318.5771 431.1338 309.4893
+ C 431.1338 307.5381 430.9624 305.9707 430.7593 305.0059
+ L 402.9927 305.0791
+
+ M 421.2485 312.3926
+ C 421.2954 316.2388 419.6206 322.5088 412.5903 322.5088
+ C 406.1299 322.5088 403.4438 316.645 402.9722 312.3926
+ L 421.2485 312.3926
+ " />
+
+ <!-- d -->
+ <path fill="black" d="
+ M 476.355 344.667
+ L 465.8638 347.5083
+ L 465.8638 324.1914
+ L 465.6904 324.1914
+ C 463.8335 327.2563 459.7407 329.5996 454.0571 329.5996
+ C 444.0762 329.5996 435.3828 321.3374 435.4478 307.4307
+ C 435.4478 294.6719 443.2983 286.2168 453.2119 286.2168
+ C 459.2017 286.2168 464.2114 289.0723 466.6909 293.7217
+ L 466.8779 293.7217
+ L 467.3491 287.1504
+ L 476.6997 287.1504
+ C 476.5083 289.9717 476.355 294.543 476.355 298.792
+ L 476.355 344.667
+
+ M 465.8638 305.1504
+ C 465.8638 304.0479 465.7856 303.0234 465.5454 302.0869
+ C 464.4873 297.5439 460.7734 294.6172 456.4819 294.6172
+ C 449.8721 294.6172 446.0903 300.1885 446.0903 307.8164
+ C 446.0903 315.5166 449.8384 321.4761 456.6016 321.4761
+ C 461.3208 321.4761 464.6992 318.1484 465.6274 314.1064
+ C 465.8071 313.2559 465.8638 312.208 465.8638 311.3711
+ L 465.8638 305.1504
+ " />
+
+ <!-- h -->
+ <path fill="black" d="
+ M 503.7964 329.0176
+ C 500.6836 329.0176 497.8926 328.1187 495.5493 326.6714
+ C 493.1162 325.2461 491.1353 323.0464 489.959 320.7666
+ L 489.7915 320.7666
+ L 489.7915 341.0195
+ L 485.7427 342.1226
+ L 485.7427 287.1504
+ L 489.7915 287.1504
+ L 489.7915 312.1787
+ C 489.7915 313.8408 489.9204 314.9946 490.3462 316.2109
+ C 492.0928 321.3013 496.8896 325.4805 502.689 325.4805
+ C 511.0664 325.4805 513.9673 318.7603 513.9673 311.3906
+ L 513.9673 287.1504
+ L 518.0137 287.1504
+ L 518.0137 311.8359
+ C 518.0137 327.0791 507.6753 329.0176 503.7964 329.0176
+ " />
+
+ <!-- a -->
+ <path fill="black" d="
+ M 554.3413 296.873
+ C 554.3413 293.6357 554.4692 290.2832 554.9375 287.1504
+ L 551.2085 287.1504
+ L 550.6128 293.0156
+ L 550.4209 293.0156
+ C 548.438 289.8594 543.8765 286.2168 537.3726 286.2168
+ C 529.1392 286.2168 525.3057 292.0117 525.3057 297.4688
+ C 525.3057 306.9121 533.6421 312.6064 550.292 312.4321
+ L 550.292 313.5234
+ C 550.292 317.5718 549.5044 325.6475 539.8242 325.5859
+ C 536.2446 325.5859 532.5132 324.6255 529.5513 322.5366
+ L 528.2632 325.4805
+ C 532.0015 328.0137 536.5659 329.0176 540.2705 329.0176
+ C 552.0801 329.0176 554.3413 320.1509 554.3413 312.8379
+ L 554.3413 296.873
+
+ M 550.292 309.0234
+ C 541.3813 309.2813 529.6128 307.9336 529.6128 298.1055
+ C 529.6128 292.2246 533.4946 289.5811 537.7578 289.5811
+ C 544.5796 289.5811 548.4561 293.8018 549.8677 297.7871
+ C 550.1646 298.6621 550.292 299.5371 550.292 300.2402
+ L 550.292 309.0234
+ " />
+
+ <!-- t -->
+ <path fill="black" d="
+ M 570.459 337.0996
+ L 570.459 328.0801
+ L 582.1235 328.0801
+ L 582.1235 324.7959
+ L 570.459 324.7959
+ L 570.459 298.1943
+ C 570.459 292.9912 572.0757 289.7285 576.4692 289.7285
+ C 578.5815 289.7285 580.0757 290.0078 581.1206 290.3711
+ L 581.6099 287.2354
+ C 580.2871 286.6836 578.4302 286.2539 575.9619 286.2539
+ C 572.9741 286.2539 570.4995 287.1934 568.8994 289.1543
+ C 567.0469 291.3057 566.4116 294.7412 566.4116 298.916
+ L 566.4116 324.7959
+ L 559.5059 324.7959
+ L 559.5059 328.0801
+ L 566.4116 328.0801
+ L 566.4116 335.606
+ L 570.459 337.0996
+ " />
+
+ <!-- ® for 'redhat' -->
+ <path fill="black" d="
+ M 335.5 288.9707
+ L 336.0352 288.9707
+ L 336.8408 287.6445
+ L 337.3608 287.6445
+ L 336.4888 288.9937
+ C 336.9404 289.0498 337.2832 289.2881 337.2832 289.834
+ C 337.2832 290.4385 336.9258 290.7051 336.2017 290.7051
+ L 335.0366 290.7051
+ L 335.0366 287.6445
+ L 335.5 287.6445
+ L 335.5 288.9707
+
+ M 335.5 289.3643
+ L 335.5 290.3101
+ L 336.1318 290.3101
+ C 336.4531 290.3101 336.7979 290.2402 336.7979 289.8647
+ C 336.7979 289.3916 336.4492 289.3643 336.0566 289.3643
+ L 335.5 289.3643
+ " />
+
+ <path fill="black" d="
+ M 339.0439 289.1719
+ C 339.0439 287.5176 337.7041 286.1763 336.0493 286.1763
+ C 334.395 286.1763 333.0527 287.5176 333.0527 289.1719
+ C 333.0527 290.8271 334.395 292.1675 336.0493 292.1675
+ C 337.7041 292.1675 339.0439 290.8271 339.0439 289.1719
+
+ M 336.0493 291.6367
+ C 334.6865 291.6367 333.5835 290.5332 333.5835 289.1719
+ C 333.5835 287.8096 334.6865 286.7061 336.0493 286.7061
+ C 337.4082 286.7061 338.5117 287.8096 338.5117 289.1719
+ C 338.5117 290.5332 337.4082 291.6367 336.0493 291.6367
+ " />
+
+ <!-- Black background behind The Shadowman -->
+ <path fill="black" d="
+ M 326.4531 286.208
+ C 324.1177 286.7451 321.6396 287.0801 319.1338 287.0801
+ C 314.8496 287.0801 310.9502 286.3389 308.0732 285.1426
+ C 307.7559 284.9844 307.5303 284.6533 307.5303 284.2764
+ C 307.5303 284.1406 307.5654 283.999 307.6172 283.8838
+ C 307.957 282.8975 307.3984 281.8281 304.6157 281.2158
+ C 300.4883 280.3096 297.8833 276.0527 296.3916 274.6367
+ C 294.6411 272.9756 289.6973 271.9531 290.4404 272.9434
+ C 291.0225 273.7188 293.2485 276.1348 294.6016 278.748
+ C 295.8125 281.083 296.8906 281.7461 298.375 283.9736
+ C 298.811 284.627 300.4995 286.9219 300.9912 288.7373
+ C 301.543 290.5107 301.356 292.7344 301.5679 293.6494
+ C 301.8721 294.9697 303.1182 297.8369 303.2129 299.4531
+ C 303.2666 300.3691 299.3916 298.1494 297.5532 298.1494
+ C 295.7144 298.1494 293.9233 299.248 292.2808 299.3281
+ C 290.248 299.4248 288.9414 297.7607 287.1025 298.0508
+ C 286.0518 298.2178 285.167 299.1426 283.3311 299.2129
+ C 280.7178 299.3086 277.5244 297.7607 271.5264 297.9531
+ C 265.6255 298.1436 260.1753 305.4082 259.4312 306.5635
+ C 258.5605 307.9199 257.4961 307.9199 256.335 306.8555
+ C 255.1738 305.792 253.7432 306.627 253.3359 307.3389
+ C 252.5615 308.6943 250.4927 312.6543 247.2881 313.4824
+ C 242.8564 314.6309 240.6118 311.0283 240.9033 308.1621
+ C 241.1987 305.252 243.0801 304.4375 243.9512 302.8906
+ C 244.8213 301.3428 245.2671 300.3428 246.9053 299.6572
+ C 248.0674 299.1758 248.5 298.458 248.1533 297.5049
+ C 247.8506 296.6738 246.6416 296.4834 245.8477 296.4463
+ C 244.1592 296.3662 242.9756 296.8242 242.1123 297.376
+ C 241.1084 298.0137 240.292 298.9033 239.416 300.4131
+ C 238.4023 302.0781 236.8052 302.8037 234.9453 302.8037
+ C 234.0586 302.8037 233.2295 302.5693 232.4922 302.1895
+ C 229.5771 300.6748 226.1064 299.7744 222.3706 299.7744
+ L 218.1572 299.7734
+ C 216.1064 305.8555 214.9951 312.3682 214.9951 319.1416
+ C 214.9951 352.6064 242.1226 379.7334 275.5859 379.7334
+ C 309.0498 379.7334 336.1758 352.6064 336.1758 319.1416
+ C 336.1758 307 332.6035 295.6895 326.4531 286.208
+ " />
+
+ <!-- The Shadowman's face -->
+ <path fill="white" d="
+ M 326.4531 286.209
+ C 324.1177 286.7461 321.6396 287.084 319.1338 287.084
+ C 314.8496 287.084 310.9502 286.3418 308.0732 285.1436
+ C 307.7559 284.9873 307.5303 284.6553 307.5303 284.2783
+ C 307.5303 284.1416 307.5654 284.001 307.6172 283.8838
+ C 307.957 282.8994 307.3984 281.8311 304.6157 281.2178
+ C 300.4883 280.3115 297.8833 276.0537 296.3916 274.6416
+ C 294.6411 272.9766 289.6973 271.9551 290.4404 272.9463
+ C 291.0225 273.7197 293.2485 276.1367 294.6016 278.749
+ C 295.8125 281.083 296.8906 281.75 298.375 283.9756
+ C 298.811 284.627 300.4995 286.9238 300.9912 288.7402
+ C 301.543 290.5117 301.356 292.7354 301.5679 293.6514
+ C 301.8721 294.9727 303.1182 297.8379 303.2129 299.457
+ C 303.2666 300.3721 299.3916 298.1504 297.5532 298.1504
+ C 295.7144 298.1504 293.9233 299.251 292.2808 299.3301
+ C 290.248 299.4258 288.9414 297.7627 287.1025 298.0518
+ C 286.0518 298.2207 285.167 299.1465 283.3311 299.2148
+ C 280.7178 299.3096 277.5244 297.7627 271.5264 297.9561
+ C 265.6255 298.1475 260.1753 305.4121 259.4312 306.5674
+ C 258.5605 307.9219 257.4961 307.9219 256.335 306.8574
+ C 255.1738 305.7939 253.7432 306.6299 253.3359 307.3438
+ C 252.5615 308.6963 250.4927 312.6553 247.2881 313.4854
+ C 242.8564 314.6338 240.6118 311.0313 240.9033 308.1641
+ C 241.1987 305.2539 243.0801 304.4395 243.9512 302.8926
+ C 244.8213 301.3438 245.2671 300.3457 246.9053 299.6621
+ C 248.0674 299.1768 248.5 298.4609 248.1533 297.5068
+ C 247.8506 296.6768 246.6416 296.4873 245.8477 296.4492
+ C 244.1592 296.3672 242.9756 296.8262 242.1123 297.376
+ C 241.1084 298.0176 240.292 298.9043 239.416 300.416
+ C 238.4023 302.0801 236.8052 302.8086 234.9453 302.8086
+ C 234.0586 302.8086 233.2295 302.5723 232.4922 302.1934
+ C 229.5771 300.6748 226.1064 299.7773 222.3706 299.7773
+ L 218.1572 299.7744
+ C 226.2363 275.8105 248.8965 258.5527 275.5859 258.5527
+ C 296.9063 258.5527 315.6538 269.5635 326.4531 286.209
+ " />
+
+ <!-- nose shadow -->
+ <path fill="black" d="
+ M 288.9307 291.7637
+ C 289.2422 291.46 289.7793 290.4375 289.1226 289.1396
+ C 288.7544 288.4521 288.3579 287.9678 287.6489 287.4023
+ C 286.7969 286.7188 285.1309 285.9307 282.8457 287.3799
+ C 281.6172 288.1592 281.543 288.4209 279.8467 288.2012
+ C 278.6348 288.043 278.1533 289.2656 278.5884 290.2832
+ C 279.0244 291.2969 280.8145 292.1191 283.04 290.8135
+ C 284.041 290.2256 285.6025 288.9844 286.9688 290.084
+ C 287.5356 290.5381 287.875 290.8408 288.6611 291.75
+ C 288.6963 291.7881 288.7461 291.8105 288.8018 291.8105
+ C 288.8516 291.8105 288.8965 291.793 288.9307 291.7637
+ " />
+
+ <!-- The Shadowman's red hat -->
+ <path fill="#cc0000" d="
+ M 309.7769 335.2627
+ C 309.1787 333.251 308.3271 330.6763 304.5391 328.7314
+ C 303.9878 328.4497 303.7764 328.9126 304.0313 329.3477
+ C 305.4629 331.7832 305.7168 332.3921 306.1328 333.3525
+ C 306.7148 334.7568 307.02 336.7549 305.8618 340.9219
+ C 303.5835 349.1221 298.8296 360.083 295.375 363.6392
+ C 292.04 367.0698 285.998 368.0361 280.5371 366.6348
+ C 278.5264 366.1191 274.5918 364.0732 267.2939 365.7168
+ C 254.665 368.5605 252.7939 362.2368 252.0693 359.4824
+ C 251.3438 356.7271 249.6045 348.897 249.6045 348.897
+ C 249.0244 345.7085 248.2646 340.1631 267.874 336.4287
+ C 277.0088 334.6885 277.4736 332.3276 277.8779 330.6289
+ C 278.603 327.585 279.7627 325.8438 281.0674 324.9746
+ C 282.373 324.1035 281.0674 323.3828 279.6187 323.2349
+ C 275.7285 322.8311 261.3491 326.9541 252.8428 331.7881
+ C 245.8828 336.0415 245.7656 339.8721 247.3584 343.1211
+ C 236.8452 344.2573 228.9561 342.1348 227.5254 337.1582
+ C 225.0693 328.6157 246.3047 314.0264 270.4839 306.7061
+ C 295.8579 299.0225 321.9556 304.3857 324.8564 320.335
+ C 326.1738 327.5811 320.0713 332.9419 309.7769 335.2627
+ " />
+
+ <!-- shadow on hat -->
+ <path fill="black" d="
+ M 270.8711 350.8813
+ C 263.8721 350.375 263.145 349.6191 261.834 348.2227
+ C 259.9854 346.2539 257.5508 350.7773 257.5508 350.7773
+ C 256.0898 351.085 254.3179 353.4404 255.2744 355.6411
+ C 256.2158 357.8174 257.9551 357.1641 258.5 356.4868
+ C 259.1626 355.6621 260.5771 354.3125 262.4141 354.3613
+ C 264.251 354.4097 266.3706 354.7959 269.3262 354.7959
+ C 272.3213 354.7959 274.335 353.6777 274.4487 352.7168
+ C 274.5459 351.8965 274.2061 351.1226 270.8711 350.8813
+ " />
+
+ <!-- another shadow on hat -->
+ <path fill="black" d="
+ M 278.2236 362.4463
+ C 278.2129 362.4453 278.2021 362.4438 278.1919 362.4438
+ C 278.084 362.4438 277.9961 362.5273 277.9961 362.6274
+ C 277.9961 362.7007 278.041 362.7646 278.106 362.7939
+ C 279.4629 363.5107 281.4873 364.0811 283.8042 364.3169
+ C 284.499 364.3887 285.1787 364.4248 285.832 364.4307
+ C 285.9478 364.4307 286.0615 364.4297 286.1787 364.4277
+ C 290.062 364.3398 293.1719 362.7974 293.1255 360.9814
+ C 293.0791 359.165 289.8955 357.7637 286.0112 357.8506
+ C 284.7529 357.8794 283.5732 358.0615 282.5576 358.3545
+ C 282.4385 358.3857 282.3506 358.4883 282.3506 358.6094
+ C 282.3506 358.731 282.4385 358.834 282.5605 358.8638
+ C 284.9839 359.4248 286.6191 360.3408 286.5039 361.207
+ C 286.3511 362.3545 283.1816 362.979 279.4248 362.6011
+ C 279.0137 362.5596 278.6118 362.5068 278.2236 362.4463
+ " />
+
+ <!-- ® for The Shadowman -->
+ <path fill="black" d="
+ M 588.3018 288.9707
+ L 588.8369 288.9707
+ L 589.6426 287.6445
+ L 590.1626 287.6445
+ L 589.2905 288.9937
+ C 589.7422 289.0498 590.085 289.2881 590.085 289.834
+ C 590.085 290.4385 589.7275 290.7051 589.0034 290.7051
+ L 587.8384 290.7051
+ L 587.8384 287.6445
+ L 588.3018 287.6445
+ L 588.3018 288.9707
+
+ M 588.3018 289.3643
+ L 588.3018 290.3101
+ L 588.9336 290.3101
+ C 589.2549 290.3101 589.5996 290.2402 589.5996 289.8647
+ C 589.5996 289.3916 589.251 289.3643 588.8584 289.3643
+ L 588.3018 289.3643
+ " />
+
+ <path fill="black" d="
+ M 591.8457 289.1719
+ C 591.8457 287.5176 590.5059 286.1763 588.8511 286.1763
+ C 587.1968 286.1763 585.8545 287.5176 585.8545 289.1719
+ C 585.8545 290.8271 587.1968 292.1675 588.8511 292.1675
+ C 590.5059 292.1675 591.8457 290.8271 591.8457 289.1719
+
+ M 588.8511 291.6367
+ C 587.4883 291.6367 586.3853 290.5332 586.3853 289.1719
+ C 586.3853 287.8096 587.4883 286.7061 588.8511 286.7061
+ C 590.21 286.7061 591.3135 287.8096 591.3135 289.1719
+ C 591.3135 290.5332 590.21 291.6367 588.8511 291.6367
+ " />
+
+ </g>
+ </g>
+
+ </defs>
+
+ <g id="watermark" transform="translate(200, 185), rotate(-50), scale(2.5)">
+ <use xlink:href="#scarab" x="0" y="170" fill-opacity="0.2"/>
+ </g>
+
+
+ <!-- Blue bar at top of slide -->
+ <rect x="0" y="0" width="1024" height="170" fill="#162284" />
+
+ <!-- Scarab and "cairo" at upper-left -->
+ <g transform="translate(10,0)">
+ <use stroke="none" xlink:href="#cairo_logo_text_small"/>
+ </g>
+
+ <!-- Presentation title at upper-right -->
+ <text ss:variable="presentation-subtitle" text-anchor="end"
+ fill="white" x="1016" y="28" font-size="20">Presentation Sub-title</text>
+
+ <!-- Red Hat logo at lower-left -->
+ <use xlink:href="#redhat_logo_horizontal" transform="translate(8,768),scale(.5,.5),translate(0, -125)" />
+
+ <g font-family="Frutiger">
+ <!-- Slide title -->
+ <g id="slide_title" transform="translate(512, 133)">
+ <text text-anchor="middle"
+ fill="white"
+ font-weight="bold"
+ x="0"
+ y="4" font-size="55"
+ ss:variable="title">Slide Title</text>
+ </g>
+
+ <!-- Slide content -->
+ <g ss:region="default" font-family="Mono">
+ <rect x="112" y="170" width="800" height="480" fill="none" stroke="blue"/>
+ <text font-size="20" fill="black"
+ x="112" y="190">Slide content</text>
+ </g>
+
+ <!-- Footer -->
+ <text ss:variable="URL" x="1016" y="753" text-anchor="end" font-size="20">http://cairographics.org</text>
+ </g>
+
+</svg>
diff --git a/doc/tutorial/slides/cairo-large-content.svg b/doc/tutorial/slides/cairo-large-content.svg
new file mode 100644
index 000000000..5acf4c937
--- /dev/null
+++ b/doc/tutorial/slides/cairo-large-content.svg
@@ -0,0 +1,899 @@
+<?xml version="1.0" ?>
+<svg width="1024" height="768"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:ss="http://www.svgslides.org/svgslides0.1"
+ fill="black">
+
+
+
+ <defs id="cairo-artwork_defs">
+ <g id="hacker_emblem">
+ <!-- Note: This is similar though not identical to Keith Packard's SVG version
+ of the hacker emblem (http://www.catb.org/hacker-emblem/glider.svg) -->
+ <g id="hacker_emblem_grid" fill="white" stroke="none">
+ <!-- Outside: Top, Right, Bottom, Left -->
+ <rect x="-2.95" y="-3.05" width="6" height="0.1" />
+ <rect x="2.95" y="-2.95" width="0.1" height="6" />
+ <rect x="-3.05" y="2.95" width="6" height="0.1" />
+ <rect x="-3.05" y="-3.05" width="0.1" height="6" />
+ <!-- Vertical: Left, Right -->
+ <rect x="-1.05" y="-2.95" width="0.1" height="5.9" />
+ <rect x="0.95" y="-2.95" width="0.1" height="5.9" />
+ <!-- Horizontal: TopLeft, TopMiddle, TopRight -->
+ <rect x="-2.95" y="-1.05" width="1.9" height="0.1" />
+ <rect x="-0.95" y="-1.05" width="1.9" height="0.1" />
+ <rect x="1.05" y="-1.05" width="1.9" height="0.1" />
+ <!-- Horizontal: BottomLeft, BottomMiddle, BottomRight -->
+ <rect x="-2.95" y="0.95" width="1.9" height="0.1" />
+ <rect x="-0.95" y="0.95" width="1.9" height="0.1" />
+ <rect x="1.05" y="0.95" width="1.9" height="0.1" />
+ </g>
+ <g id="hacker_emblem_dots" fill="white">
+ <circle cx="0" cy="-2" r="0.7" />
+ <circle cx="2" cy="0" r="0.7" />
+ <circle cx="-2" cy="2" r="0.7" />
+ <circle cx="0" cy="2" r="0.7" />
+ <circle cx="2" cy="2" r="0.7" />
+ </g>
+ </g>
+ <g id="scarab" fill="#f19a14">
+ <g transform="translate(-150, -170)">
+ <path id="scarab_head" d="M205.599,94.567c0-11.668-24.914-21.129-55.628-21.129
+ c-30.723,0-55.624,9.46-55.624,21.129c0,10.203,24.901,7.346,55.624,7.346C180.685,101.913,205.599,104.233,205.599,94.567z"/>
+ <path id="scarab_torso" d="M136.423,161.506c0,0,12.751,12.577,13.547,13.362
+ c2.262-2.232,13.545-13.362,13.545-13.362c7.135-7.036,87.111-6.399,91.066-6.363c-0.469-6.298-1.254-12.472-2.325-18.519
+ c-15.183-19.279-42.811-32.225-74.485-32.225h-55.518c-31.745,0-59.439,13.011-74.598,32.37c-1.054,6-1.829,12.128-2.296,18.374
+ C49.321,155.106,129.288,154.47,136.423,161.506z"/>
+ <path id="scarab_spine" d="M149.97,301.187c2.005-24.729,8.386-103.483,8.405-103.721
+ c-0.09-0.219-6.478-15.578-8.405-20.214c-1.936,4.655-8.316,19.995-8.408,20.214C141.582,197.704,147.965,276.458,149.97,301.187z"/>
+ <path id="scarab_wing_left" d="M140.403,197.149l8.862-21.31l-13.686-13.499
+ c-5.65-5.573-67.074-6.235-90.259-6.019l-0.006-0.622c-0.154,2.144-0.271,4.302-0.35,6.475
+ c-0.076,2.207,10.392,4.706,10.392,6.717c0,2.319-10.457,5.084-10.359,7.631c2.993,73.349,48.53,131.631,104.372,132.048
+ l-9.02-111.29L140.403,197.149z"/>
+ <path id="scarab_wing_right" d="M244.585,168.891c0-2.011,10.467-4.506,10.391-6.715
+ c-0.079-2.174-0.195-4.332-0.351-6.479l-0.004,0.624c-23.186-0.216-84.608,0.445-90.26,6.017l-13.688,13.502l8.915,21.438
+ l-9.017,111.29c55.854-0.417,101.378-58.698,104.373-132.049C255.04,173.976,244.585,171.209,244.585,168.891z"/>
+ <path id="scarab_leg_front_left" d="M44.506,141.12c-4.135-0.856-4.895-1.54-7.935-2.92
+ c-9.59-3.364-10.376-5.481-16.08-11.86c-7.426-8.306-12.661-20.142-17.1-29.463c-3.576-7.525-3.984-16.409-2.86-24.273
+ c0.991-6.935,7.144-12.869,12.074-18.92c5.844-7.191,10.356-14.822,17.924-21.354c7.736-6.682,23.203-9.809,26.168-19.648
+ C57.86,8.819,54.334,1.766,61.482,0c-0.366,4.703,3.639,8.477,2.397,13.575c-1.129,4.627-4.368,5.811-9.611,9.099
+ c-7.564,4.746-18.366,8.779-24.748,13.965c-7.175,5.827-4.369,13.771-10.569,20.057c-2.001,2.03-7.901,4.706-9.137,6.83
+ c-1.861,3.199-0.297,9.572-0.116,13.12c0.425,8.284,5.588,14.244,9.555,22.045c4.152,8.141,6.429,15.409,13.411,22.519
+ c4.183,4.262,11.429,4.802,16.21,10.647l-3.555,4.186L44.506,141.12z"/>
+ <path id="scarab_leg_middle_left" d="M43.94,191.922l-0.809-7.346
+ c-9.506-4.579-10.339-9.772-20.738-12.466c-23.728-6.151-21.361,11.25-15.532,26.373c5.676,14.726,8.237,30.23,14.345,44.795
+ c2.805,6.688,6.919,13.213,14.298,15.127c0.372-8.435-0.917-10.651-6.113-16.919c-4.395-5.293-3.326-12.548-6.072-18.504
+ c-3.581-7.804-4.196-15.646-7.279-23.502c-1.363-3.479-8.33-13.966-6.452-17.861c3.183-6.603,9.178-0.083,12.179,2.077
+ c4.218,3.036,6.467,2.223,11.681,2.898C34.041,186.673,37.005,188.756,43.94,191.922z"/>
+ <path id="scarab_leg_back_left" d="M65.839,257.063l-2.771-4.837
+ c-6.68,8.928-6.993,16.228-10.056,23.347c-5.277,12.263-0.157,28.851,9.854,37.676c6.052,5.375,15.907,9.618,23.122,13.136
+ c10.035,4.892,20.113,11.286,31.336,13.396c2.482,0.466,8.798,1.295,6.693-3.522c-0.975-2.237-8.091-4.591-10.146-5.734
+ c-8.312-4.623-16.377-10.524-24.142-16.176c-9.498-6.862-20.843-11.186-28.311-20.684c-3.054-3.885-3.544-4.922-2.816-9.39
+ c0.693-4.263,1.344-9.174,2.241-13.439C61.855,266.029,63.274,261.378,65.839,257.063z"/>
+ <path id="scarab_leg_front_right" d="M255.487,141.12c4.134-0.856,4.896-1.54,7.936-2.92
+ c9.583-3.364,10.369-5.481,16.071-11.86c7.428-8.306,12.661-20.142,17.115-29.463c3.574-7.525,3.983-16.409,2.86-24.273
+ c-0.992-6.935-7.157-12.869-12.087-18.92c-5.843-7.191-10.356-14.822-17.919-21.354c-7.735-6.682-23.202-9.809-26.167-19.648
+ C242.135,8.819,245.66,1.766,238.511,0c0.366,4.703-3.637,8.477-2.396,13.575c1.131,4.627,4.368,5.811,9.611,9.099
+ c7.563,4.746,18.367,8.779,24.747,13.965c7.17,5.827,4.362,13.771,10.563,20.057c2.001,2.03,7.901,4.706,9.139,6.83
+ c1.859,3.199,0.295,9.572,0.113,13.12c-0.424,8.284-5.588,14.244-9.553,22.045c-4.152,8.141-6.431,15.409-13.404,22.519
+ c-4.184,4.262-11.429,4.802-16.211,10.647l3.556,4.186L255.487,141.12z"/>
+ <path id="scarab_leg_middle_right" d="M256.053,191.922l0.81-7.346
+ c9.507-4.579,10.34-9.772,20.73-12.466c23.741-6.151,21.374,11.25,15.534,26.373c-5.676,14.726-8.238,30.23-14.347,44.795
+ c-2.804,6.688-6.911,13.213-14.291,15.127c-0.371-8.435,0.918-10.651,6.113-16.919c4.39-5.293,3.319-12.548,6.066-18.504
+ c3.58-7.804,4.197-15.646,7.278-23.502c1.363-3.479,8.33-13.966,6.453-17.861c-3.184-6.603-9.179-0.083-12.181,2.077
+ c-4.217,3.036-6.458,2.223-11.672,2.898C265.951,186.673,262.986,188.756,256.053,191.922z"/>
+ <path id="scarab_leg_back_right" d="M234.155,257.063l2.771-4.837
+ c6.679,8.928,6.991,16.228,10.057,23.347c5.274,12.263,0.154,28.851-9.854,37.676c-6.055,5.375-15.903,9.618-23.117,13.136
+ c-10.034,4.892-20.127,11.286-31.351,13.396c-2.481,0.466-8.789,1.295-6.691-3.522c0.976-2.237,8.092-4.591,10.146-5.734
+ c8.312-4.623,16.392-10.524,24.155-16.176c9.498-6.862,20.838-11.186,28.305-20.684c3.055-3.885,3.543-4.922,2.818-9.39
+ c-0.696-4.263-1.346-9.174-2.244-13.439C238.137,266.029,236.718,261.378,234.155,257.063z"/>
+ </g>
+ </g>
+ <radialGradient id="gradient_radial_dung"
+ cx="0" cy="0" r="60"
+ fx="0" fy="0" gradientUnits="userSpaceOnUse"
+ >
+ <stop offset="0" stop-color="#9a9a9a" />
+ <stop offset="0.70" stop-color="#bababa" />
+ <stop offset="0.95" stop-color="#FFFFFF" />
+ </radialGradient>
+ <g id="dung">
+ <circle cx="0" cy="0" r="60" fill="url(#gradient_radial_dung)" />
+ <g transform="translate(-61, -61)">
+ <!-- rough equivalent: <circle cx="0" cy="0" r="60" stroke="#8a8a8a" stroke-width="2" /> -->
+ <path fill="#8a8a8a" d="M0,61c0,33.636,27.364,61,61,61s61-27.364,61-61S94.636,0,61,0S0,27.364,0,61z
+ M2,61C2,28.467,28.467,2,61,2c32.532,0,59,26.467,59,59c0,32.533-26.468,59-59,59C28.467,120,2,93.533,2,61z"/>
+ </g>
+ <use xlink:href="#hacker_emblem" x="0" y="0" transform="scale(9)" />
+ </g>
+ <g id="dung_2_color">
+ <!-- This would be simple a circle like so:
+ <circle cx="0" cy="0" r="48" stroke-width="2" fill="none" stroke="white"/>
+ but there appears to currently be a bug in the cairo
+ PDF backend that results in an ugly spike in that
+ case. So we use 8 splines instead.
+ -->
+ <path stroke-width="4" stroke="white" fill="none" d="
+M 48, 0
+C 48, 12.730391512298112,
+ 42.94287166245995, 24.939379331448613
+ 33.941125496954285, 33.941125496954278
+C 24.939379331448624, 42.942871662459943
+ 12.730391512298114, 48
+ 0, 48
+C -12.730391512298109, 48,
+ -24.939379331448613, 42.94287166245995
+ -33.941125496954278, 33.941125496954285
+C -42.942871662459943, 24.939379331448624,
+ -48, 12.730391512298118,
+ -48, 0,
+C -48, -12.730391512298105,
+ -42.94287166245995, -24.939379331448613,
+ -33.941125496954285, -33.941125496954278
+C -24.939379331448624, -42.942871662459943,
+ -12.730391512298119, -48,
+ 0, -48
+C 12.730391512298104, -48,
+ 24.939379331448606, -42.942871662459943,
+ 33.941125496954271, -33.941125496954285
+C 42.942871662459936, -24.939379331448624,
+ 48, -12.730391512298123,
+ 48, 0" />
+ <g transform="scale(9)" fill="white" stroke="none" stroke-width="0.22222">
+ <!-- Hacker emblem grid -->
+ <!--
+ <path stroke="white" fill="none"
+ d="M -3,-3 L 3,-3 L 3,3 L-3,3 Z
+ M -1,-3 L -1, 3
+ M 1,-3 L 1, 3
+ M -3,-1 L 3,-1
+ M -3, 1 L 3, 1"/>
+ -->
+
+ <!-- Hacker emblem dots -->
+ <circle cx="0" cy="-2" r="0.7" />
+ <circle cx="2" cy="0" r="0.7" />
+ <circle cx="-2" cy="2" r="0.7" />
+ <circle cx="0" cy="2" r="0.7" />
+ <circle cx="2" cy="2" r="0.7" />
+ </g>
+ </g>
+
+ <!-- scarab dimensions: 300x340 -->
+ <!-- dung dimensions: 120x120 (radius: 60) -->
+ <!-- scarab and dung dimensions: 300x400 -->
+
+ <g id="cairo_logo">
+ <!-- dimensions: 300x400, centered -->
+ <!-- The logo (scarab and dung), with the center-point of the bounding box at (0,0) -->
+ <use xlink:href="#dung_2_color" x="0" y="0" transform="translate(0, -140)" />
+ <use xlink:href="#scarab" x="0" y="0" transform="translate(0, 30)" />
+ </g>
+ <g id="cairo_logo_dung-centered">
+ <!-- The logo (scarab and dung), with the dung at (0,0), the scarab below -->
+ <use xlink:href="#dung_2_color" x="0" y="0" />
+ <use xlink:href="#scarab" x="0" y="0" transform="translate(0,170)" />
+ </g>
+ <g id="cairo_logo_scarab-centered">
+ <!-- The logo (scarab and dung), with the scarab's rotational center at (0,0), the dung above -->
+ <!-- The scarab's rotational center in this case is not the center of its bounding box,
+ but is calculated to be the intersection-point of the torso, spine and wings -->
+ <use xlink:href="#dung_2_color" x="0" y="0" transform="translate(0, -175.85)" />
+ <use xlink:href="#scarab" x="0" y="0" transform="translate(0, -5.85)" />
+ </g>
+ <g id="cairo_logo_top-centered">
+ <!-- The logo (scarab and dung), with the top-center point of the bounding box at (0,0) -->
+ <use xlink:href="#dung_2_color" x="0" y="0" transform="translate(0, 60)" />
+ <use xlink:href="#scarab" x="0" y="0" transform="translate(0, 230)" /><!-- (0,170+60) -->
+ </g>
+ <g id="cairo_logo_bottom-centered">
+ <!-- The logo (scarab and dung), with the bottom-center point of the bounding box at (0,0) -->
+ <use xlink:href="#dung_2_color" x="0" y="0" transform="translate(0, -340)" />
+ <use xlink:href="#scarab" x="0" y="0" transform="translate(0, -170)" />
+ </g>
+ <g id="cairo_logo_right-centered">
+ <!-- The logo (scarab and dung), with the right-center point of the bounding box at (0,0) -->
+ <use xlink:href="#dung_2_color" x="0" y="0" transform="translate(-150, -140)" />
+ <use xlink:href="#scarab" x="0" y="0" transform="translate(-150, 30)" />
+ </g>
+ <g id="cairo_logo_left-centered">
+ <!-- The logo (scarab and dung), with the left-center point of the bounding box at (0,0) -->
+ <use xlink:href="#dung_2_color" x="0" y="0" transform="translate(150, -140)" />
+ <use xlink:href="#scarab" x="0" y="0" transform="translate(150, 30)" />
+ </g>
+ <g id="cairo_logo_topleft-centered">
+ <!-- The logo (scarab and dung), with the top-left point of the bounding box at (0,0) -->
+ <use xlink:href="#dung_2_color" x="0" y="0" transform="translate(150, 60)" />
+ <use xlink:href="#scarab" x="0" y="0" transform="translate(150, 230)" /><!-- (150, 170+60) -->
+ </g>
+ <g id="cairo_logo_topright-centered">
+ <!-- The logo (scarab and dung), with the top-right point of the bounding box at (0,0) -->
+ <use xlink:href="#dung_2_color" x="0" y="0" transform="translate(-150, 60)" />
+ <use xlink:href="#scarab" x="0" y="0" transform="translate(-150, 230)" /><!-- (-150,170+60) -->
+ </g>
+ <g id="cairo_logo_bottomleft-centered">
+ <!-- The logo (scarab and dung), with the bottom-left point of the bounding box at (0,0) -->
+ <use xlink:href="#dung_2_color" x="0" y="0" transform="translate(150, -340)" />
+ <use xlink:href="#scarab" x="0" y="0" transform="translate(150, -170)" />
+ </g>
+ <g id="cairo_logo_bottomright-centered">
+ <!-- The logo (scarab and dung), with the bottom-right point of the bounding box at (0,0) -->
+ <use xlink:href="#dung_2_color" x="0" y="0" transform="translate(-150, -340)" />
+ <use xlink:href="#scarab" x="0" y="0" transform="translate(-150, -170)" />
+ </g>
+
+ <g id="cairo_text" transform="translate(0,-97)">
+ <g transform="scale(0.1484,0.1484)"> <g transform="translate(-1139,-208.5)">
+ <!-- 63 (c), advance 444, 0 horiBearing 38,522 -->
+ <path transform="translate(65,0)" d="
+ M 412, 433
+ C 385, 422 336, 413 298, 413
+ C 142, 413 38, 525 38, 680
+ C 38, 826 144, 947 298, 947
+ C 332, 947 377, 944 416, 926
+ L 409, 842
+ C 380, 861 340, 871 308, 871
+ C 187, 871 138, 771 138, 680
+ C 138, 583 197, 489 302, 489
+ C 332, 489 368, 496 404, 511
+ L 412, 433 " />
+ <!-- 61 (a), advance 556, 0 horiBearing 46,522 -->
+ <path transform="translate(486.75,0)" d="
+ M 109, 541
+ C 147, 509 204, 489 257, 489
+ C 351, 489 383, 534 383, 622
+ C 346, 620 320, 620 283, 620
+ C 186, 620 46, 660 46, 788
+ C 46, 899 123, 947 233, 947
+ C 319, 947 369, 900 391, 869
+ L 393, 869
+ L 393, 935
+ L 481, 935
+ C 479, 920 477, 893 477, 835
+ L 477, 624
+ C 477, 485 418, 413 272, 413
+ C 207, 413 151, 433 104, 461
+ L 109, 541
+ M 383, 737
+ C 383, 813 334, 871 241, 871
+ C 198, 871 146, 842 146, 788
+ C 146, 698 272, 690 323, 690
+ C 343, 690 363, 692 383, 692
+ L 383, 737 " />
+ <!-- 69 (i), advance 278, 0 horiBearing 86,730 -->
+ <path transform="translate(1000,0)" d="
+ M 92, 935
+ L 186, 935
+ L 186, 425
+ L 92, 425
+ L 92, 935
+ M 88, 261
+ A 51, 51 0 1 1 190,261
+ A 51, 51 0 1 1 88,261" />
+ <!-- 72 (r), advance 389, 0 horiBearing 80,522 -->
+ <path transform="translate(1234.25,0)" d="
+ M 80, 935
+ L 174, 935
+ L 174, 703
+ C 174, 575 229, 495 313, 495
+ C 329, 495 348, 497 365, 504
+ L 365, 420
+ C 345, 416 331, 413 303, 413
+ C 249, 413 195, 451 170, 504
+ L 168, 504
+ L 168, 425
+ L 80, 425
+ L 80, 935 " />
+ <!-- 6f (o), advance 611, 0 horiBearing 46,522 -->
+ <path transform="translate(1610,0)" d="
+ M 46, 680
+ C 46, 826 152, 947 306, 947
+ C 459, 947 565, 826 565, 680
+ C 565, 525 461, 413 306, 413
+ C 150, 413 46, 525 46, 680
+ M 146, 680
+ C 146, 583 205, 489 306, 489
+ C 406, 489 465, 583 465, 680
+ C 465, 771 416, 871 306, 871
+ C 195, 871 146, 771 146, 680 " />
+ <!-- bounds: 38, 205 <-> 2232, 947 -->
+ </g> </g>
+ </g>
+
+ <!-- scaled by 0.72, shifted around to hit pixel boundaries -->
+ <g id="cairo_text_small_spaced" transform="translate(0,-71)">
+ <g transform="scale(0.085,0.085)"> <g transform="translate(-1139,-208.5)">
+ <!-- 63 (c), advance 444, 0 horiBearing 38,522 -->
+ <path transform="translate(-151,0)" d="
+ M 412, 433
+ C 385, 422 336, 413 298, 413
+ C 142, 413 38, 525 38, 680
+ C 38, 826 144, 947 298, 947
+ C 332, 947 377, 944 416, 926
+ L 409, 842
+ C 380, 861 340, 871 308, 871
+ C 187, 871 138, 771 138, 680
+ C 138, 583 197, 489 302, 489
+ C 332, 489 368, 496 404, 511
+ L 412, 433 " />
+ <!-- 61 (a), advance 556, 0 horiBearing 46,522 -->
+ <path transform="translate(379.5,0)" d="
+ M 109, 541
+ C 147, 509 204, 489 257, 489
+ C 351, 489 383, 534 383, 622
+ C 346, 620 320, 620 283, 620
+ C 186, 620 46, 660 46, 788
+ C 46, 899 123, 947 233, 947
+ C 319, 947 369, 900 391, 869
+ L 393, 869
+ L 393, 935
+ L 481, 935
+ C 479, 920 477, 893 477, 835
+ L 477, 624
+ C 477, 485 418, 413 272, 413
+ C 207, 413 151, 433 104, 461
+ L 109, 541
+ M 383, 737
+ C 383, 813 334, 871 241, 871
+ C 198, 871 146, 842 146, 788
+ C 146, 698 272, 690 323, 690
+ C 343, 690 363, 692 383, 692
+ L 383, 737 " />
+ <!-- 69 (i), advance 278, 0 horiBearing 86,730 -->
+ <path transform="translate(1000,0)" d="
+ M 92, 935
+ L 186, 935
+ L 186, 425
+ L 92, 425
+ L 92, 935
+ M 88, 261
+ A 51, 51 0 1 1 190,261
+ A 51, 51 0 1 1 88,261" />
+ <!-- 72 (r), advance 389, 0 horiBearing 80,522 -->
+ <path transform="translate(1341.5,0)" d="
+ M 80, 935
+ L 174, 935
+ L 174, 703
+ C 174, 575 229, 495 313, 495
+ C 329, 495 348, 497 365, 504
+ L 365, 420
+ C 345, 416 331, 413 303, 413
+ C 249, 413 195, 451 170, 504
+ L 168, 504
+ L 168, 425
+ L 80, 425
+ L 80, 935 " />
+ <!-- 6f (o), advance 611, 0 horiBearing 46,522 -->
+ <path transform="translate(1826,0)" d="
+ M 46, 680
+ C 46, 826 152, 947 306, 947
+ C 459, 947 565, 826 565, 680
+ C 565, 525 461, 413 306, 413
+ C 150, 413 46, 525 46, 680
+ M 146, 680
+ C 146, 583 205, 489 306, 489
+ C 406, 489 465, 583 465, 680
+ C 465, 771 416, 871 306, 871
+ C 195, 871 146, 771 146, 680 " />
+ <!-- bounds: 38, 205 <-> 2232, 947 -->
+ </g> </g>
+ </g>
+
+
+ <!-- scaled by 0.72, shifted around to hit pixel boundaries -->
+ <g id="cairo_text_small" transform="translate(0,-71)">
+ <g transform="scale(0.085,0.085)"> <g transform="translate(-1139,-208.5)">
+ <!-- 63 (c), advance 444, 0 horiBearing 38,522 -->
+ <path transform="translate(-151,0)" d="
+ M 412, 433
+ C 385, 422 336, 413 298, 413
+ C 142, 413 38, 525 38, 680
+ C 38, 826 144, 947 298, 947
+ C 332, 947 377, 944 416, 926
+ L 409, 842
+ C 380, 861 340, 871 308, 871
+ C 187, 871 138, 771 138, 680
+ C 138, 583 197, 489 302, 489
+ C 332, 489 368, 496 404, 511
+ L 412, 433 " />
+ <!-- 61 (a), advance 556, 0 horiBearing 46,522 -->
+ <path transform="translate(261.75,0)" d="
+ M 109, 541
+ C 147, 509 204, 489 257, 489
+ C 351, 489 383, 534 383, 622
+ C 346, 620 320, 620 283, 620
+ C 186, 620 46, 660 46, 788
+ C 46, 899 123, 947 233, 947
+ C 319, 947 369, 900 391, 869
+ L 393, 869
+ L 393, 935
+ L 481, 935
+ C 479, 920 477, 893 477, 835
+ L 477, 624
+ C 477, 485 418, 413 272, 413
+ C 207, 413 151, 433 104, 461
+ L 109, 541
+ M 383, 737
+ C 383, 813 334, 871 241, 871
+ C 198, 871 146, 842 146, 788
+ C 146, 698 272, 690 323, 690
+ C 343, 690 363, 692 383, 692
+ L 383, 737 " />
+ <!-- 69 (i), advance 278, 0 horiBearing 86,730 -->
+ <path transform="translate(764.75)" d="
+ M 92, 935
+ L 186, 935
+ L 186, 425
+ L 92, 425
+ L 92, 935
+ M 88, 261
+ A 51, 51 0 1 1 190,261
+ A 51, 51 0 1 1 88,261" />
+ <!-- 72 (r), advance 389, 0 horiBearing 80,522 -->
+ <path transform="translate(988.5,0)" d="
+ M 80, 935
+ L 174, 935
+ L 174, 703
+ C 174, 575 229, 495 313, 495
+ C 329, 495 348, 497 365, 504
+ L 365, 420
+ C 345, 416 331, 413 303, 413
+ C 249, 413 195, 451 170, 504
+ L 168, 504
+ L 168, 425
+ L 80, 425
+ L 80, 935 " />
+ <!-- 6f (o), advance 611, 0 horiBearing 46,522 -->
+ <path transform="translate(1355.5,0)" d="
+ M 46, 680
+ C 46, 826 152, 947 306, 947
+ C 459, 947 565, 826 565, 680
+ C 565, 525 461, 413 306, 413
+ C 150, 413 46, 525 46, 680
+ M 146, 680
+ C 146, 583 205, 489 306, 489
+ C 406, 489 465, 583 465, 680
+ C 465, 771 416, 871 306, 871
+ C 195, 871 146, 771 146, 680 " />
+ <!-- bounds: 38, 205 <-> 2232, 947 -->
+ </g> </g>
+ </g>
+
+ <g id="cairo_logo_text_small">
+ <!-- The logo on the left, the text 'cairo' on the right -->
+ <use xlink:href="#cairo_logo_bottomleft-centered" transform="translate(0, 78), scale(0.1944)" />
+ <use xlink:href="#cairo_text_small" fill="white" transform="translate(175,82)"/>
+ </g>
+
+ <g id="cairo_logo_with_text">
+ <!-- The logo (scarab and dung), with the text 'cairo' below, the dot of the 'i' positioned between the hind legs of the scarab -->
+ <!-- dimensions: 300x490, centered -->
+ <use xlink:href="#cairo_logo_top-centered" transform="translate(0, -245)" />
+ <use xlink:href="#cairo_text" transform="translate(0, 245)" />
+ </g>
+
+ <g id="cairo_banner">
+ <!-- The logo on the left, the text 'cairo' in the center, and a mirror image of the logo on the right -->
+ <!-- The logos are scaled such that the scarab body nearly matches the height of the text characters (excepting the 'i')
+ and the dung should nearly aligns with the dot of the 'i'. The bottoms of the logos are aligned with the bottom of the text. -->
+ <!-- dimensions: 370x88, centered -->
+ <use xlink:href="#cairo_logo_bottomleft-centered" transform="translate(-180, 40), scale(0.1944)" />
+ <use xlink:href="#cairo_text_small" transform="translate(0, 42)" fill="black" />
+ <use xlink:href="#cairo_logo_bottomleft-centered" transform="translate(180, 40), scale(0.1944), scale(-1, 1)" />
+ </g>
+
+ <g id="freedesktop_org_logo" style="fill:#FFFFFF;stroke:#3B80AE;stroke-width:2.4588;">
+ <g>
+ <path style="stroke:#BABABA;" d="M85.277,40.796c2.058,7.884-2.667,15.942-10.551,17.999L27.143,71.21c-7.884,2.057-15.943-2.667-18-10.552
+ l-7.448-28.55c-2.057-7.884,2.667-15.942,10.551-17.999L59.83,1.695c7.884-2.057,15.942,2.667,17.999,10.551
+ l7.449,28.55z"/>>
+ <path style="fill:#3B80AE;stroke:none;" d="M80.444,39.778c1.749,7.854-1.816,13.621-9.504,15.447l-42.236,11.02c-7.569,2.396-14.089-1.181
+ -15.838-8.836L6.53,33.127c-1.749-8.145,0.709-12.889,9.503-15.447L58.27,6.661
+ c8.144-1.826,14.089,1.363,15.838,8.835l6.336,24.282z"/>>
+ </g>g>
+ <path style="opacity:0.5;fill:none;stroke:#FFFFFF;" d="M45.542,51.793L24.104,31.102l38.1-4.393L45.542,51.793z"/>>
+ <path d="M72.325,28.769c0.405,1.55-0.525,3.136-2.075,3.541l-12.331,3.217c-1.551,0.404-3.137-0.525-3.542-2.076l-2.295-8.801
+ c-0.405-1.551,0.524-3.137,2.076-3.542l12.33-3.217c1.551-0.405,3.137,0.525,3.542,2.076l2.295,8.801z"/>>
+ <path d="M36.51,33.625c0.496,1.9-0.645,3.844-2.545,4.34l-15.112,3.943c-1.901,0.496-3.845-0.644-4.34-2.544l-2.814-10.786
+ c-0.496-1.901,0.644-3.844,2.544-4.34l15.113-3.942c1.901-0.496,3.845,0.643,4.34,2.544l2.814,10.786z"/>>
+ <path d="M52.493,53.208c0.278,1.065-0.36,2.154-1.425,2.432L42.6,57.848c-1.064,0.277-2.153-0.36-2.431-1.426l-1.577-6.043
+ c-0.277-1.064,0.36-2.153,1.425-2.432l8.468-2.209c1.064-0.277,2.154,0.361,2.431,1.426l1.577,6.043z"/>>
+ </g>g>
+ <g id="bullet">
+ <use x="0" y="0" xlink:href="#cairo_logo" transform="translate(-6,-2) scale(0.1, 0.1)"/>>
+ </g>
+ <g id="redhat_logo_horizontal">
+ <!-- 380x125 Red Hat log (horizontal layout) -->
+ <g fill="black" stroke="none"
+ transform="translate(0,124),scale(1,-1),translate(-214,-258)"
+ fill-rule="evenodd"
+ >
+ <!-- r -->
+ <path fill="black" d="
+ M 367.0625 315.3203
+ C 367.0625 320.8765 366.9463 324.9644 366.7227 328.6597
+ L 375.811 328.6597
+ L 376.2002 320.7764
+ L 376.4971 320.7764
+ C 378.5391 326.6221 383.3809 329.5996 387.8594 329.5996
+ C 388.8843 329.5996 389.4824 329.5601 390.3218 329.373
+ L 390.3218 319.4863
+ C 389.3398 319.6763 388.4224 319.7842 387.1592 319.7842
+ C 382.1597 319.7842 378.688 316.6006 377.751 311.8447
+ C 377.5732 310.918 377.4805 309.8086 377.4805 308.6777
+ L 377.4805 287.1504
+ L 366.9766 287.1504
+ L 367.0625 315.3203
+ " />
+
+ <!-- e -->
+ <path fill="black" d="
+ M 402.9927 305.0791
+ C 403.2715 297.5586 409.0918 294.2695 415.814 294.2695
+ C 420.6406 294.2695 424.0942 295.0234 427.2681 296.1924
+ L 428.8232 288.9678
+ C 425.269 287.4629 420.3413 286.3359 414.3149 286.3359
+ C 400.8384 286.3359 392.9409 294.6592 392.9409 307.3809
+ C 392.9409 318.8369 399.8911 329.6772 413.2437 329.6772
+ C 426.7397 329.6772 431.1338 318.5771 431.1338 309.4893
+ C 431.1338 307.5381 430.9624 305.9707 430.7593 305.0059
+ L 402.9927 305.0791
+
+ M 421.2485 312.3926
+ C 421.2954 316.2388 419.6206 322.5088 412.5903 322.5088
+ C 406.1299 322.5088 403.4438 316.645 402.9722 312.3926
+ L 421.2485 312.3926
+ " />
+
+ <!-- d -->
+ <path fill="black" d="
+ M 476.355 344.667
+ L 465.8638 347.5083
+ L 465.8638 324.1914
+ L 465.6904 324.1914
+ C 463.8335 327.2563 459.7407 329.5996 454.0571 329.5996
+ C 444.0762 329.5996 435.3828 321.3374 435.4478 307.4307
+ C 435.4478 294.6719 443.2983 286.2168 453.2119 286.2168
+ C 459.2017 286.2168 464.2114 289.0723 466.6909 293.7217
+ L 466.8779 293.7217
+ L 467.3491 287.1504
+ L 476.6997 287.1504
+ C 476.5083 289.9717 476.355 294.543 476.355 298.792
+ L 476.355 344.667
+
+ M 465.8638 305.1504
+ C 465.8638 304.0479 465.7856 303.0234 465.5454 302.0869
+ C 464.4873 297.5439 460.7734 294.6172 456.4819 294.6172
+ C 449.8721 294.6172 446.0903 300.1885 446.0903 307.8164
+ C 446.0903 315.5166 449.8384 321.4761 456.6016 321.4761
+ C 461.3208 321.4761 464.6992 318.1484 465.6274 314.1064
+ C 465.8071 313.2559 465.8638 312.208 465.8638 311.3711
+ L 465.8638 305.1504
+ " />
+
+ <!-- h -->
+ <path fill="black" d="
+ M 503.7964 329.0176
+ C 500.6836 329.0176 497.8926 328.1187 495.5493 326.6714
+ C 493.1162 325.2461 491.1353 323.0464 489.959 320.7666
+ L 489.7915 320.7666
+ L 489.7915 341.0195
+ L 485.7427 342.1226
+ L 485.7427 287.1504
+ L 489.7915 287.1504
+ L 489.7915 312.1787
+ C 489.7915 313.8408 489.9204 314.9946 490.3462 316.2109
+ C 492.0928 321.3013 496.8896 325.4805 502.689 325.4805
+ C 511.0664 325.4805 513.9673 318.7603 513.9673 311.3906
+ L 513.9673 287.1504
+ L 518.0137 287.1504
+ L 518.0137 311.8359
+ C 518.0137 327.0791 507.6753 329.0176 503.7964 329.0176
+ " />
+
+ <!-- a -->
+ <path fill="black" d="
+ M 554.3413 296.873
+ C 554.3413 293.6357 554.4692 290.2832 554.9375 287.1504
+ L 551.2085 287.1504
+ L 550.6128 293.0156
+ L 550.4209 293.0156
+ C 548.438 289.8594 543.8765 286.2168 537.3726 286.2168
+ C 529.1392 286.2168 525.3057 292.0117 525.3057 297.4688
+ C 525.3057 306.9121 533.6421 312.6064 550.292 312.4321
+ L 550.292 313.5234
+ C 550.292 317.5718 549.5044 325.6475 539.8242 325.5859
+ C 536.2446 325.5859 532.5132 324.6255 529.5513 322.5366
+ L 528.2632 325.4805
+ C 532.0015 328.0137 536.5659 329.0176 540.2705 329.0176
+ C 552.0801 329.0176 554.3413 320.1509 554.3413 312.8379
+ L 554.3413 296.873
+
+ M 550.292 309.0234
+ C 541.3813 309.2813 529.6128 307.9336 529.6128 298.1055
+ C 529.6128 292.2246 533.4946 289.5811 537.7578 289.5811
+ C 544.5796 289.5811 548.4561 293.8018 549.8677 297.7871
+ C 550.1646 298.6621 550.292 299.5371 550.292 300.2402
+ L 550.292 309.0234
+ " />
+
+ <!-- t -->
+ <path fill="black" d="
+ M 570.459 337.0996
+ L 570.459 328.0801
+ L 582.1235 328.0801
+ L 582.1235 324.7959
+ L 570.459 324.7959
+ L 570.459 298.1943
+ C 570.459 292.9912 572.0757 289.7285 576.4692 289.7285
+ C 578.5815 289.7285 580.0757 290.0078 581.1206 290.3711
+ L 581.6099 287.2354
+ C 580.2871 286.6836 578.4302 286.2539 575.9619 286.2539
+ C 572.9741 286.2539 570.4995 287.1934 568.8994 289.1543
+ C 567.0469 291.3057 566.4116 294.7412 566.4116 298.916
+ L 566.4116 324.7959
+ L 559.5059 324.7959
+ L 559.5059 328.0801
+ L 566.4116 328.0801
+ L 566.4116 335.606
+ L 570.459 337.0996
+ " />
+
+ <!-- ® for 'redhat' -->
+ <path fill="black" d="
+ M 335.5 288.9707
+ L 336.0352 288.9707
+ L 336.8408 287.6445
+ L 337.3608 287.6445
+ L 336.4888 288.9937
+ C 336.9404 289.0498 337.2832 289.2881 337.2832 289.834
+ C 337.2832 290.4385 336.9258 290.7051 336.2017 290.7051
+ L 335.0366 290.7051
+ L 335.0366 287.6445
+ L 335.5 287.6445
+ L 335.5 288.9707
+
+ M 335.5 289.3643
+ L 335.5 290.3101
+ L 336.1318 290.3101
+ C 336.4531 290.3101 336.7979 290.2402 336.7979 289.8647
+ C 336.7979 289.3916 336.4492 289.3643 336.0566 289.3643
+ L 335.5 289.3643
+ " />
+
+ <path fill="black" d="
+ M 339.0439 289.1719
+ C 339.0439 287.5176 337.7041 286.1763 336.0493 286.1763
+ C 334.395 286.1763 333.0527 287.5176 333.0527 289.1719
+ C 333.0527 290.8271 334.395 292.1675 336.0493 292.1675
+ C 337.7041 292.1675 339.0439 290.8271 339.0439 289.1719
+
+ M 336.0493 291.6367
+ C 334.6865 291.6367 333.5835 290.5332 333.5835 289.1719
+ C 333.5835 287.8096 334.6865 286.7061 336.0493 286.7061
+ C 337.4082 286.7061 338.5117 287.8096 338.5117 289.1719
+ C 338.5117 290.5332 337.4082 291.6367 336.0493 291.6367
+ " />
+
+ <!-- Black background behind The Shadowman -->
+ <path fill="black" d="
+ M 326.4531 286.208
+ C 324.1177 286.7451 321.6396 287.0801 319.1338 287.0801
+ C 314.8496 287.0801 310.9502 286.3389 308.0732 285.1426
+ C 307.7559 284.9844 307.5303 284.6533 307.5303 284.2764
+ C 307.5303 284.1406 307.5654 283.999 307.6172 283.8838
+ C 307.957 282.8975 307.3984 281.8281 304.6157 281.2158
+ C 300.4883 280.3096 297.8833 276.0527 296.3916 274.6367
+ C 294.6411 272.9756 289.6973 271.9531 290.4404 272.9434
+ C 291.0225 273.7188 293.2485 276.1348 294.6016 278.748
+ C 295.8125 281.083 296.8906 281.7461 298.375 283.9736
+ C 298.811 284.627 300.4995 286.9219 300.9912 288.7373
+ C 301.543 290.5107 301.356 292.7344 301.5679 293.6494
+ C 301.8721 294.9697 303.1182 297.8369 303.2129 299.4531
+ C 303.2666 300.3691 299.3916 298.1494 297.5532 298.1494
+ C 295.7144 298.1494 293.9233 299.248 292.2808 299.3281
+ C 290.248 299.4248 288.9414 297.7607 287.1025 298.0508
+ C 286.0518 298.2178 285.167 299.1426 283.3311 299.2129
+ C 280.7178 299.3086 277.5244 297.7607 271.5264 297.9531
+ C 265.6255 298.1436 260.1753 305.4082 259.4312 306.5635
+ C 258.5605 307.9199 257.4961 307.9199 256.335 306.8555
+ C 255.1738 305.792 253.7432 306.627 253.3359 307.3389
+ C 252.5615 308.6943 250.4927 312.6543 247.2881 313.4824
+ C 242.8564 314.6309 240.6118 311.0283 240.9033 308.1621
+ C 241.1987 305.252 243.0801 304.4375 243.9512 302.8906
+ C 244.8213 301.3428 245.2671 300.3428 246.9053 299.6572
+ C 248.0674 299.1758 248.5 298.458 248.1533 297.5049
+ C 247.8506 296.6738 246.6416 296.4834 245.8477 296.4463
+ C 244.1592 296.3662 242.9756 296.8242 242.1123 297.376
+ C 241.1084 298.0137 240.292 298.9033 239.416 300.4131
+ C 238.4023 302.0781 236.8052 302.8037 234.9453 302.8037
+ C 234.0586 302.8037 233.2295 302.5693 232.4922 302.1895
+ C 229.5771 300.6748 226.1064 299.7744 222.3706 299.7744
+ L 218.1572 299.7734
+ C 216.1064 305.8555 214.9951 312.3682 214.9951 319.1416
+ C 214.9951 352.6064 242.1226 379.7334 275.5859 379.7334
+ C 309.0498 379.7334 336.1758 352.6064 336.1758 319.1416
+ C 336.1758 307 332.6035 295.6895 326.4531 286.208
+ " />
+
+ <!-- The Shadowman's face -->
+ <path fill="white" d="
+ M 326.4531 286.209
+ C 324.1177 286.7461 321.6396 287.084 319.1338 287.084
+ C 314.8496 287.084 310.9502 286.3418 308.0732 285.1436
+ C 307.7559 284.9873 307.5303 284.6553 307.5303 284.2783
+ C 307.5303 284.1416 307.5654 284.001 307.6172 283.8838
+ C 307.957 282.8994 307.3984 281.8311 304.6157 281.2178
+ C 300.4883 280.3115 297.8833 276.0537 296.3916 274.6416
+ C 294.6411 272.9766 289.6973 271.9551 290.4404 272.9463
+ C 291.0225 273.7197 293.2485 276.1367 294.6016 278.749
+ C 295.8125 281.083 296.8906 281.75 298.375 283.9756
+ C 298.811 284.627 300.4995 286.9238 300.9912 288.7402
+ C 301.543 290.5117 301.356 292.7354 301.5679 293.6514
+ C 301.8721 294.9727 303.1182 297.8379 303.2129 299.457
+ C 303.2666 300.3721 299.3916 298.1504 297.5532 298.1504
+ C 295.7144 298.1504 293.9233 299.251 292.2808 299.3301
+ C 290.248 299.4258 288.9414 297.7627 287.1025 298.0518
+ C 286.0518 298.2207 285.167 299.1465 283.3311 299.2148
+ C 280.7178 299.3096 277.5244 297.7627 271.5264 297.9561
+ C 265.6255 298.1475 260.1753 305.4121 259.4312 306.5674
+ C 258.5605 307.9219 257.4961 307.9219 256.335 306.8574
+ C 255.1738 305.7939 253.7432 306.6299 253.3359 307.3438
+ C 252.5615 308.6963 250.4927 312.6553 247.2881 313.4854
+ C 242.8564 314.6338 240.6118 311.0313 240.9033 308.1641
+ C 241.1987 305.2539 243.0801 304.4395 243.9512 302.8926
+ C 244.8213 301.3438 245.2671 300.3457 246.9053 299.6621
+ C 248.0674 299.1768 248.5 298.4609 248.1533 297.5068
+ C 247.8506 296.6768 246.6416 296.4873 245.8477 296.4492
+ C 244.1592 296.3672 242.9756 296.8262 242.1123 297.376
+ C 241.1084 298.0176 240.292 298.9043 239.416 300.416
+ C 238.4023 302.0801 236.8052 302.8086 234.9453 302.8086
+ C 234.0586 302.8086 233.2295 302.5723 232.4922 302.1934
+ C 229.5771 300.6748 226.1064 299.7773 222.3706 299.7773
+ L 218.1572 299.7744
+ C 226.2363 275.8105 248.8965 258.5527 275.5859 258.5527
+ C 296.9063 258.5527 315.6538 269.5635 326.4531 286.209
+ " />
+
+ <!-- nose shadow -->
+ <path fill="black" d="
+ M 288.9307 291.7637
+ C 289.2422 291.46 289.7793 290.4375 289.1226 289.1396
+ C 288.7544 288.4521 288.3579 287.9678 287.6489 287.4023
+ C 286.7969 286.7188 285.1309 285.9307 282.8457 287.3799
+ C 281.6172 288.1592 281.543 288.4209 279.8467 288.2012
+ C 278.6348 288.043 278.1533 289.2656 278.5884 290.2832
+ C 279.0244 291.2969 280.8145 292.1191 283.04 290.8135
+ C 284.041 290.2256 285.6025 288.9844 286.9688 290.084
+ C 287.5356 290.5381 287.875 290.8408 288.6611 291.75
+ C 288.6963 291.7881 288.7461 291.8105 288.8018 291.8105
+ C 288.8516 291.8105 288.8965 291.793 288.9307 291.7637
+ " />
+
+ <!-- The Shadowman's red hat -->
+ <path fill="#cc0000" d="
+ M 309.7769 335.2627
+ C 309.1787 333.251 308.3271 330.6763 304.5391 328.7314
+ C 303.9878 328.4497 303.7764 328.9126 304.0313 329.3477
+ C 305.4629 331.7832 305.7168 332.3921 306.1328 333.3525
+ C 306.7148 334.7568 307.02 336.7549 305.8618 340.9219
+ C 303.5835 349.1221 298.8296 360.083 295.375 363.6392
+ C 292.04 367.0698 285.998 368.0361 280.5371 366.6348
+ C 278.5264 366.1191 274.5918 364.0732 267.2939 365.7168
+ C 254.665 368.5605 252.7939 362.2368 252.0693 359.4824
+ C 251.3438 356.7271 249.6045 348.897 249.6045 348.897
+ C 249.0244 345.7085 248.2646 340.1631 267.874 336.4287
+ C 277.0088 334.6885 277.4736 332.3276 277.8779 330.6289
+ C 278.603 327.585 279.7627 325.8438 281.0674 324.9746
+ C 282.373 324.1035 281.0674 323.3828 279.6187 323.2349
+ C 275.7285 322.8311 261.3491 326.9541 252.8428 331.7881
+ C 245.8828 336.0415 245.7656 339.8721 247.3584 343.1211
+ C 236.8452 344.2573 228.9561 342.1348 227.5254 337.1582
+ C 225.0693 328.6157 246.3047 314.0264 270.4839 306.7061
+ C 295.8579 299.0225 321.9556 304.3857 324.8564 320.335
+ C 326.1738 327.5811 320.0713 332.9419 309.7769 335.2627
+ " />
+
+ <!-- shadow on hat -->
+ <path fill="black" d="
+ M 270.8711 350.8813
+ C 263.8721 350.375 263.145 349.6191 261.834 348.2227
+ C 259.9854 346.2539 257.5508 350.7773 257.5508 350.7773
+ C 256.0898 351.085 254.3179 353.4404 255.2744 355.6411
+ C 256.2158 357.8174 257.9551 357.1641 258.5 356.4868
+ C 259.1626 355.6621 260.5771 354.3125 262.4141 354.3613
+ C 264.251 354.4097 266.3706 354.7959 269.3262 354.7959
+ C 272.3213 354.7959 274.335 353.6777 274.4487 352.7168
+ C 274.5459 351.8965 274.2061 351.1226 270.8711 350.8813
+ " />
+
+ <!-- another shadow on hat -->
+ <path fill="black" d="
+ M 278.2236 362.4463
+ C 278.2129 362.4453 278.2021 362.4438 278.1919 362.4438
+ C 278.084 362.4438 277.9961 362.5273 277.9961 362.6274
+ C 277.9961 362.7007 278.041 362.7646 278.106 362.7939
+ C 279.4629 363.5107 281.4873 364.0811 283.8042 364.3169
+ C 284.499 364.3887 285.1787 364.4248 285.832 364.4307
+ C 285.9478 364.4307 286.0615 364.4297 286.1787 364.4277
+ C 290.062 364.3398 293.1719 362.7974 293.1255 360.9814
+ C 293.0791 359.165 289.8955 357.7637 286.0112 357.8506
+ C 284.7529 357.8794 283.5732 358.0615 282.5576 358.3545
+ C 282.4385 358.3857 282.3506 358.4883 282.3506 358.6094
+ C 282.3506 358.731 282.4385 358.834 282.5605 358.8638
+ C 284.9839 359.4248 286.6191 360.3408 286.5039 361.207
+ C 286.3511 362.3545 283.1816 362.979 279.4248 362.6011
+ C 279.0137 362.5596 278.6118 362.5068 278.2236 362.4463
+ " />
+
+ <!-- ® for The Shadowman -->
+ <path fill="black" d="
+ M 588.3018 288.9707
+ L 588.8369 288.9707
+ L 589.6426 287.6445
+ L 590.1626 287.6445
+ L 589.2905 288.9937
+ C 589.7422 289.0498 590.085 289.2881 590.085 289.834
+ C 590.085 290.4385 589.7275 290.7051 589.0034 290.7051
+ L 587.8384 290.7051
+ L 587.8384 287.6445
+ L 588.3018 287.6445
+ L 588.3018 288.9707
+
+ M 588.3018 289.3643
+ L 588.3018 290.3101
+ L 588.9336 290.3101
+ C 589.2549 290.3101 589.5996 290.2402 589.5996 289.8647
+ C 589.5996 289.3916 589.251 289.3643 588.8584 289.3643
+ L 588.3018 289.3643
+ " />
+
+ <path fill="black" d="
+ M 591.8457 289.1719
+ C 591.8457 287.5176 590.5059 286.1763 588.8511 286.1763
+ C 587.1968 286.1763 585.8545 287.5176 585.8545 289.1719
+ C 585.8545 290.8271 587.1968 292.1675 588.8511 292.1675
+ C 590.5059 292.1675 591.8457 290.8271 591.8457 289.1719
+
+ M 588.8511 291.6367
+ C 587.4883 291.6367 586.3853 290.5332 586.3853 289.1719
+ C 586.3853 287.8096 587.4883 286.7061 588.8511 286.7061
+ C 590.21 286.7061 591.3135 287.8096 591.3135 289.1719
+ C 591.3135 290.5332 590.21 291.6367 588.8511 291.6367
+ " />
+
+ </g>
+ </g>
+
+ </defs>
+
+ <g id="watermark" transform="translate(200, 185), rotate(-50), scale(2.5)">
+ <use xlink:href="#scarab" x="0" y="170" fill-opacity="0.2"/>
+ </g>
+
+ <!-- Blue bar at top of slide -->
+ <rect x="0" y="0" width="1024" height="80" fill="#162284" />
+
+ <g font-family="Frutiger">
+ <!-- Slide title -->
+ <!-- Slide title -->
+ <g id="slide_title" transform="translate(512, 60)">
+ <text text-anchor="middle"
+ fill="white"
+ font-weight="bold"
+ x="0"
+ y="4" font-size="55"
+ ss:variable="title">Slide Title</text>
+ </g>
+
+ <!-- Slide content -->
+ <g ss:region="default">
+ <rect x="112" y="120" width="800" height="580" fill="none" stroke="blue"/>
+ <text font-size="40" fill="black"
+ x="112" y="152">Slide content</text>
+ </g>
+
+ </g>
+
+</svg>
diff --git a/doc/tutorial/slides/cairo-separator.svg b/doc/tutorial/slides/cairo-separator.svg
new file mode 100644
index 000000000..8d2c8406d
--- /dev/null
+++ b/doc/tutorial/slides/cairo-separator.svg
@@ -0,0 +1,909 @@
+<?xml version="1.0" ?>
+<svg width="1024" height="768"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:ss="http://www.svgslides.org/svgslides0.1"
+ fill="black">
+
+
+
+ <defs id="cairo-artwork_defs">
+ <g id="hacker_emblem">
+ <!-- Note: This is similar though not identical to Keith Packard's SVG version
+ of the hacker emblem (http://www.catb.org/hacker-emblem/glider.svg) -->
+ <g id="hacker_emblem_grid" fill="white" stroke="none">
+ <!-- Outside: Top, Right, Bottom, Left -->
+ <rect x="-2.95" y="-3.05" width="6" height="0.1" />
+ <rect x="2.95" y="-2.95" width="0.1" height="6" />
+ <rect x="-3.05" y="2.95" width="6" height="0.1" />
+ <rect x="-3.05" y="-3.05" width="0.1" height="6" />
+ <!-- Vertical: Left, Right -->
+ <rect x="-1.05" y="-2.95" width="0.1" height="5.9" />
+ <rect x="0.95" y="-2.95" width="0.1" height="5.9" />
+ <!-- Horizontal: TopLeft, TopMiddle, TopRight -->
+ <rect x="-2.95" y="-1.05" width="1.9" height="0.1" />
+ <rect x="-0.95" y="-1.05" width="1.9" height="0.1" />
+ <rect x="1.05" y="-1.05" width="1.9" height="0.1" />
+ <!-- Horizontal: BottomLeft, BottomMiddle, BottomRight -->
+ <rect x="-2.95" y="0.95" width="1.9" height="0.1" />
+ <rect x="-0.95" y="0.95" width="1.9" height="0.1" />
+ <rect x="1.05" y="0.95" width="1.9" height="0.1" />
+ </g>
+ <g id="hacker_emblem_dots" fill="white">
+ <circle cx="0" cy="-2" r="0.7" />
+ <circle cx="2" cy="0" r="0.7" />
+ <circle cx="-2" cy="2" r="0.7" />
+ <circle cx="0" cy="2" r="0.7" />
+ <circle cx="2" cy="2" r="0.7" />
+ </g>
+ </g>
+ <g id="scarab" fill="#f19a14">
+ <g transform="translate(-150, -170)">
+ <path id="scarab_head" d="M205.599,94.567c0-11.668-24.914-21.129-55.628-21.129
+ c-30.723,0-55.624,9.46-55.624,21.129c0,10.203,24.901,7.346,55.624,7.346C180.685,101.913,205.599,104.233,205.599,94.567z"/>
+ <path id="scarab_torso" d="M136.423,161.506c0,0,12.751,12.577,13.547,13.362
+ c2.262-2.232,13.545-13.362,13.545-13.362c7.135-7.036,87.111-6.399,91.066-6.363c-0.469-6.298-1.254-12.472-2.325-18.519
+ c-15.183-19.279-42.811-32.225-74.485-32.225h-55.518c-31.745,0-59.439,13.011-74.598,32.37c-1.054,6-1.829,12.128-2.296,18.374
+ C49.321,155.106,129.288,154.47,136.423,161.506z"/>
+ <path id="scarab_spine" d="M149.97,301.187c2.005-24.729,8.386-103.483,8.405-103.721
+ c-0.09-0.219-6.478-15.578-8.405-20.214c-1.936,4.655-8.316,19.995-8.408,20.214C141.582,197.704,147.965,276.458,149.97,301.187z"/>
+ <path id="scarab_wing_left" d="M140.403,197.149l8.862-21.31l-13.686-13.499
+ c-5.65-5.573-67.074-6.235-90.259-6.019l-0.006-0.622c-0.154,2.144-0.271,4.302-0.35,6.475
+ c-0.076,2.207,10.392,4.706,10.392,6.717c0,2.319-10.457,5.084-10.359,7.631c2.993,73.349,48.53,131.631,104.372,132.048
+ l-9.02-111.29L140.403,197.149z"/>
+ <path id="scarab_wing_right" d="M244.585,168.891c0-2.011,10.467-4.506,10.391-6.715
+ c-0.079-2.174-0.195-4.332-0.351-6.479l-0.004,0.624c-23.186-0.216-84.608,0.445-90.26,6.017l-13.688,13.502l8.915,21.438
+ l-9.017,111.29c55.854-0.417,101.378-58.698,104.373-132.049C255.04,173.976,244.585,171.209,244.585,168.891z"/>
+ <path id="scarab_leg_front_left" d="M44.506,141.12c-4.135-0.856-4.895-1.54-7.935-2.92
+ c-9.59-3.364-10.376-5.481-16.08-11.86c-7.426-8.306-12.661-20.142-17.1-29.463c-3.576-7.525-3.984-16.409-2.86-24.273
+ c0.991-6.935,7.144-12.869,12.074-18.92c5.844-7.191,10.356-14.822,17.924-21.354c7.736-6.682,23.203-9.809,26.168-19.648
+ C57.86,8.819,54.334,1.766,61.482,0c-0.366,4.703,3.639,8.477,2.397,13.575c-1.129,4.627-4.368,5.811-9.611,9.099
+ c-7.564,4.746-18.366,8.779-24.748,13.965c-7.175,5.827-4.369,13.771-10.569,20.057c-2.001,2.03-7.901,4.706-9.137,6.83
+ c-1.861,3.199-0.297,9.572-0.116,13.12c0.425,8.284,5.588,14.244,9.555,22.045c4.152,8.141,6.429,15.409,13.411,22.519
+ c4.183,4.262,11.429,4.802,16.21,10.647l-3.555,4.186L44.506,141.12z"/>
+ <path id="scarab_leg_middle_left" d="M43.94,191.922l-0.809-7.346
+ c-9.506-4.579-10.339-9.772-20.738-12.466c-23.728-6.151-21.361,11.25-15.532,26.373c5.676,14.726,8.237,30.23,14.345,44.795
+ c2.805,6.688,6.919,13.213,14.298,15.127c0.372-8.435-0.917-10.651-6.113-16.919c-4.395-5.293-3.326-12.548-6.072-18.504
+ c-3.581-7.804-4.196-15.646-7.279-23.502c-1.363-3.479-8.33-13.966-6.452-17.861c3.183-6.603,9.178-0.083,12.179,2.077
+ c4.218,3.036,6.467,2.223,11.681,2.898C34.041,186.673,37.005,188.756,43.94,191.922z"/>
+ <path id="scarab_leg_back_left" d="M65.839,257.063l-2.771-4.837
+ c-6.68,8.928-6.993,16.228-10.056,23.347c-5.277,12.263-0.157,28.851,9.854,37.676c6.052,5.375,15.907,9.618,23.122,13.136
+ c10.035,4.892,20.113,11.286,31.336,13.396c2.482,0.466,8.798,1.295,6.693-3.522c-0.975-2.237-8.091-4.591-10.146-5.734
+ c-8.312-4.623-16.377-10.524-24.142-16.176c-9.498-6.862-20.843-11.186-28.311-20.684c-3.054-3.885-3.544-4.922-2.816-9.39
+ c0.693-4.263,1.344-9.174,2.241-13.439C61.855,266.029,63.274,261.378,65.839,257.063z"/>
+ <path id="scarab_leg_front_right" d="M255.487,141.12c4.134-0.856,4.896-1.54,7.936-2.92
+ c9.583-3.364,10.369-5.481,16.071-11.86c7.428-8.306,12.661-20.142,17.115-29.463c3.574-7.525,3.983-16.409,2.86-24.273
+ c-0.992-6.935-7.157-12.869-12.087-18.92c-5.843-7.191-10.356-14.822-17.919-21.354c-7.735-6.682-23.202-9.809-26.167-19.648
+ C242.135,8.819,245.66,1.766,238.511,0c0.366,4.703-3.637,8.477-2.396,13.575c1.131,4.627,4.368,5.811,9.611,9.099
+ c7.563,4.746,18.367,8.779,24.747,13.965c7.17,5.827,4.362,13.771,10.563,20.057c2.001,2.03,7.901,4.706,9.139,6.83
+ c1.859,3.199,0.295,9.572,0.113,13.12c-0.424,8.284-5.588,14.244-9.553,22.045c-4.152,8.141-6.431,15.409-13.404,22.519
+ c-4.184,4.262-11.429,4.802-16.211,10.647l3.556,4.186L255.487,141.12z"/>
+ <path id="scarab_leg_middle_right" d="M256.053,191.922l0.81-7.346
+ c9.507-4.579,10.34-9.772,20.73-12.466c23.741-6.151,21.374,11.25,15.534,26.373c-5.676,14.726-8.238,30.23-14.347,44.795
+ c-2.804,6.688-6.911,13.213-14.291,15.127c-0.371-8.435,0.918-10.651,6.113-16.919c4.39-5.293,3.319-12.548,6.066-18.504
+ c3.58-7.804,4.197-15.646,7.278-23.502c1.363-3.479,8.33-13.966,6.453-17.861c-3.184-6.603-9.179-0.083-12.181,2.077
+ c-4.217,3.036-6.458,2.223-11.672,2.898C265.951,186.673,262.986,188.756,256.053,191.922z"/>
+ <path id="scarab_leg_back_right" d="M234.155,257.063l2.771-4.837
+ c6.679,8.928,6.991,16.228,10.057,23.347c5.274,12.263,0.154,28.851-9.854,37.676c-6.055,5.375-15.903,9.618-23.117,13.136
+ c-10.034,4.892-20.127,11.286-31.351,13.396c-2.481,0.466-8.789,1.295-6.691-3.522c0.976-2.237,8.092-4.591,10.146-5.734
+ c8.312-4.623,16.392-10.524,24.155-16.176c9.498-6.862,20.838-11.186,28.305-20.684c3.055-3.885,3.543-4.922,2.818-9.39
+ c-0.696-4.263-1.346-9.174-2.244-13.439C238.137,266.029,236.718,261.378,234.155,257.063z"/>
+ </g>
+ </g>
+ <radialGradient id="gradient_radial_dung"
+ cx="0" cy="0" r="60"
+ fx="0" fy="0" gradientUnits="userSpaceOnUse"
+ >
+ <stop offset="0" stop-color="#9a9a9a" />
+ <stop offset="0.70" stop-color="#bababa" />
+ <stop offset="0.95" stop-color="#FFFFFF" />
+ </radialGradient>
+ <g id="dung">
+ <circle cx="0" cy="0" r="60" fill="url(#gradient_radial_dung)" />
+ <g transform="translate(-61, -61)">
+ <!-- rough equivalent: <circle cx="0" cy="0" r="60" stroke="#8a8a8a" stroke-width="2" /> -->
+ <path fill="#8a8a8a" d="M0,61c0,33.636,27.364,61,61,61s61-27.364,61-61S94.636,0,61,0S0,27.364,0,61z
+ M2,61C2,28.467,28.467,2,61,2c32.532,0,59,26.467,59,59c0,32.533-26.468,59-59,59C28.467,120,2,93.533,2,61z"/>
+ </g>
+ <use xlink:href="#hacker_emblem" x="0" y="0" transform="scale(9)" />
+ </g>
+ <g id="dung_2_color">
+ <!-- This would be simple a circle like so:
+ <circle cx="0" cy="0" r="48" stroke-width="2" fill="none" stroke="white"/>
+ but there appears to currently be a bug in the cairo
+ PDF backend that results in an ugly spike in that
+ case. So we use 8 splines instead.
+ -->
+ <path stroke-width="4" stroke="white" fill="none" d="
+M 48, 0
+C 48, 12.730391512298112,
+ 42.94287166245995, 24.939379331448613
+ 33.941125496954285, 33.941125496954278
+C 24.939379331448624, 42.942871662459943
+ 12.730391512298114, 48
+ 0, 48
+C -12.730391512298109, 48,
+ -24.939379331448613, 42.94287166245995
+ -33.941125496954278, 33.941125496954285
+C -42.942871662459943, 24.939379331448624,
+ -48, 12.730391512298118,
+ -48, 0,
+C -48, -12.730391512298105,
+ -42.94287166245995, -24.939379331448613,
+ -33.941125496954285, -33.941125496954278
+C -24.939379331448624, -42.942871662459943,
+ -12.730391512298119, -48,
+ 0, -48
+C 12.730391512298104, -48,
+ 24.939379331448606, -42.942871662459943,
+ 33.941125496954271, -33.941125496954285
+C 42.942871662459936, -24.939379331448624,
+ 48, -12.730391512298123,
+ 48, 0" />
+ <g transform="scale(9)" fill="white" stroke="none" stroke-width="0.22222">
+ <!-- Hacker emblem grid -->
+ <!--
+ <path stroke="white" fill="none"
+ d="M -3,-3 L 3,-3 L 3,3 L-3,3 Z
+ M -1,-3 L -1, 3
+ M 1,-3 L 1, 3
+ M -3,-1 L 3,-1
+ M -3, 1 L 3, 1"/>
+ -->
+
+ <!-- Hacker emblem dots -->
+ <circle cx="0" cy="-2" r="0.7" />
+ <circle cx="2" cy="0" r="0.7" />
+ <circle cx="-2" cy="2" r="0.7" />
+ <circle cx="0" cy="2" r="0.7" />
+ <circle cx="2" cy="2" r="0.7" />
+ </g>
+ </g>
+
+ <!-- scarab dimensions: 300x340 -->
+ <!-- dung dimensions: 120x120 (radius: 60) -->
+ <!-- scarab and dung dimensions: 300x400 -->
+
+ <g id="cairo_logo">
+ <!-- dimensions: 300x400, centered -->
+ <!-- The logo (scarab and dung), with the center-point of the bounding box at (0,0) -->
+ <use xlink:href="#dung_2_color" x="0" y="0" transform="translate(0, -140)" />
+ <use xlink:href="#scarab" x="0" y="0" transform="translate(0, 30)" />
+ </g>
+ <g id="cairo_logo_dung-centered">
+ <!-- The logo (scarab and dung), with the dung at (0,0), the scarab below -->
+ <use xlink:href="#dung_2_color" x="0" y="0" />
+ <use xlink:href="#scarab" x="0" y="0" transform="translate(0,170)" />
+ </g>
+ <g id="cairo_logo_scarab-centered">
+ <!-- The logo (scarab and dung), with the scarab's rotational center at (0,0), the dung above -->
+ <!-- The scarab's rotational center in this case is not the center of its bounding box,
+ but is calculated to be the intersection-point of the torso, spine and wings -->
+ <use xlink:href="#dung_2_color" x="0" y="0" transform="translate(0, -175.85)" />
+ <use xlink:href="#scarab" x="0" y="0" transform="translate(0, -5.85)" />
+ </g>
+ <g id="cairo_logo_top-centered">
+ <!-- The logo (scarab and dung), with the top-center point of the bounding box at (0,0) -->
+ <use xlink:href="#dung_2_color" x="0" y="0" transform="translate(0, 60)" />
+ <use xlink:href="#scarab" x="0" y="0" transform="translate(0, 230)" /><!-- (0,170+60) -->
+ </g>
+ <g id="cairo_logo_bottom-centered">
+ <!-- The logo (scarab and dung), with the bottom-center point of the bounding box at (0,0) -->
+ <use xlink:href="#dung_2_color" x="0" y="0" transform="translate(0, -340)" />
+ <use xlink:href="#scarab" x="0" y="0" transform="translate(0, -170)" />
+ </g>
+ <g id="cairo_logo_right-centered">
+ <!-- The logo (scarab and dung), with the right-center point of the bounding box at (0,0) -->
+ <use xlink:href="#dung_2_color" x="0" y="0" transform="translate(-150, -140)" />
+ <use xlink:href="#scarab" x="0" y="0" transform="translate(-150, 30)" />
+ </g>
+ <g id="cairo_logo_left-centered">
+ <!-- The logo (scarab and dung), with the left-center point of the bounding box at (0,0) -->
+ <use xlink:href="#dung_2_color" x="0" y="0" transform="translate(150, -140)" />
+ <use xlink:href="#scarab" x="0" y="0" transform="translate(150, 30)" />
+ </g>
+ <g id="cairo_logo_topleft-centered">
+ <!-- The logo (scarab and dung), with the top-left point of the bounding box at (0,0) -->
+ <use xlink:href="#dung_2_color" x="0" y="0" transform="translate(150, 60)" />
+ <use xlink:href="#scarab" x="0" y="0" transform="translate(150, 230)" /><!-- (150, 170+60) -->
+ </g>
+ <g id="cairo_logo_topright-centered">
+ <!-- The logo (scarab and dung), with the top-right point of the bounding box at (0,0) -->
+ <use xlink:href="#dung_2_color" x="0" y="0" transform="translate(-150, 60)" />
+ <use xlink:href="#scarab" x="0" y="0" transform="translate(-150, 230)" /><!-- (-150,170+60) -->
+ </g>
+ <g id="cairo_logo_bottomleft-centered">
+ <!-- The logo (scarab and dung), with the bottom-left point of the bounding box at (0,0) -->
+ <use xlink:href="#dung_2_color" x="0" y="0" transform="translate(150, -340)" />
+ <use xlink:href="#scarab" x="0" y="0" transform="translate(150, -170)" />
+ </g>
+ <g id="cairo_logo_bottomright-centered">
+ <!-- The logo (scarab and dung), with the bottom-right point of the bounding box at (0,0) -->
+ <use xlink:href="#dung_2_color" x="0" y="0" transform="translate(-150, -340)" />
+ <use xlink:href="#scarab" x="0" y="0" transform="translate(-150, -170)" />
+ </g>
+
+ <g id="cairo_text" transform="translate(0,-97)">
+ <g transform="scale(0.1484,0.1484)"> <g transform="translate(-1139,-208.5)">
+ <!-- 63 (c), advance 444, 0 horiBearing 38,522 -->
+ <path transform="translate(65,0)" d="
+ M 412, 433
+ C 385, 422 336, 413 298, 413
+ C 142, 413 38, 525 38, 680
+ C 38, 826 144, 947 298, 947
+ C 332, 947 377, 944 416, 926
+ L 409, 842
+ C 380, 861 340, 871 308, 871
+ C 187, 871 138, 771 138, 680
+ C 138, 583 197, 489 302, 489
+ C 332, 489 368, 496 404, 511
+ L 412, 433 " />
+ <!-- 61 (a), advance 556, 0 horiBearing 46,522 -->
+ <path transform="translate(486.75,0)" d="
+ M 109, 541
+ C 147, 509 204, 489 257, 489
+ C 351, 489 383, 534 383, 622
+ C 346, 620 320, 620 283, 620
+ C 186, 620 46, 660 46, 788
+ C 46, 899 123, 947 233, 947
+ C 319, 947 369, 900 391, 869
+ L 393, 869
+ L 393, 935
+ L 481, 935
+ C 479, 920 477, 893 477, 835
+ L 477, 624
+ C 477, 485 418, 413 272, 413
+ C 207, 413 151, 433 104, 461
+ L 109, 541
+ M 383, 737
+ C 383, 813 334, 871 241, 871
+ C 198, 871 146, 842 146, 788
+ C 146, 698 272, 690 323, 690
+ C 343, 690 363, 692 383, 692
+ L 383, 737 " />
+ <!-- 69 (i), advance 278, 0 horiBearing 86,730 -->
+ <path transform="translate(1000,0)" d="
+ M 92, 935
+ L 186, 935
+ L 186, 425
+ L 92, 425
+ L 92, 935
+ M 88, 261
+ A 51, 51 0 1 1 190,261
+ A 51, 51 0 1 1 88,261" />
+ <!-- 72 (r), advance 389, 0 horiBearing 80,522 -->
+ <path transform="translate(1234.25,0)" d="
+ M 80, 935
+ L 174, 935
+ L 174, 703
+ C 174, 575 229, 495 313, 495
+ C 329, 495 348, 497 365, 504
+ L 365, 420
+ C 345, 416 331, 413 303, 413
+ C 249, 413 195, 451 170, 504
+ L 168, 504
+ L 168, 425
+ L 80, 425
+ L 80, 935 " />
+ <!-- 6f (o), advance 611, 0 horiBearing 46,522 -->
+ <path transform="translate(1610,0)" d="
+ M 46, 680
+ C 46, 826 152, 947 306, 947
+ C 459, 947 565, 826 565, 680
+ C 565, 525 461, 413 306, 413
+ C 150, 413 46, 525 46, 680
+ M 146, 680
+ C 146, 583 205, 489 306, 489
+ C 406, 489 465, 583 465, 680
+ C 465, 771 416, 871 306, 871
+ C 195, 871 146, 771 146, 680 " />
+ <!-- bounds: 38, 205 <-> 2232, 947 -->
+ </g> </g>
+ </g>
+
+ <!-- scaled by 0.72, shifted around to hit pixel boundaries -->
+ <g id="cairo_text_small_spaced" transform="translate(0,-71)">
+ <g transform="scale(0.085,0.085)"> <g transform="translate(-1139,-208.5)">
+ <!-- 63 (c), advance 444, 0 horiBearing 38,522 -->
+ <path transform="translate(-151,0)" d="
+ M 412, 433
+ C 385, 422 336, 413 298, 413
+ C 142, 413 38, 525 38, 680
+ C 38, 826 144, 947 298, 947
+ C 332, 947 377, 944 416, 926
+ L 409, 842
+ C 380, 861 340, 871 308, 871
+ C 187, 871 138, 771 138, 680
+ C 138, 583 197, 489 302, 489
+ C 332, 489 368, 496 404, 511
+ L 412, 433 " />
+ <!-- 61 (a), advance 556, 0 horiBearing 46,522 -->
+ <path transform="translate(379.5,0)" d="
+ M 109, 541
+ C 147, 509 204, 489 257, 489
+ C 351, 489 383, 534 383, 622
+ C 346, 620 320, 620 283, 620
+ C 186, 620 46, 660 46, 788
+ C 46, 899 123, 947 233, 947
+ C 319, 947 369, 900 391, 869
+ L 393, 869
+ L 393, 935
+ L 481, 935
+ C 479, 920 477, 893 477, 835
+ L 477, 624
+ C 477, 485 418, 413 272, 413
+ C 207, 413 151, 433 104, 461
+ L 109, 541
+ M 383, 737
+ C 383, 813 334, 871 241, 871
+ C 198, 871 146, 842 146, 788
+ C 146, 698 272, 690 323, 690
+ C 343, 690 363, 692 383, 692
+ L 383, 737 " />
+ <!-- 69 (i), advance 278, 0 horiBearing 86,730 -->
+ <path transform="translate(1000,0)" d="
+ M 92, 935
+ L 186, 935
+ L 186, 425
+ L 92, 425
+ L 92, 935
+ M 88, 261
+ A 51, 51 0 1 1 190,261
+ A 51, 51 0 1 1 88,261" />
+ <!-- 72 (r), advance 389, 0 horiBearing 80,522 -->
+ <path transform="translate(1341.5,0)" d="
+ M 80, 935
+ L 174, 935
+ L 174, 703
+ C 174, 575 229, 495 313, 495
+ C 329, 495 348, 497 365, 504
+ L 365, 420
+ C 345, 416 331, 413 303, 413
+ C 249, 413 195, 451 170, 504
+ L 168, 504
+ L 168, 425
+ L 80, 425
+ L 80, 935 " />
+ <!-- 6f (o), advance 611, 0 horiBearing 46,522 -->
+ <path transform="translate(1826,0)" d="
+ M 46, 680
+ C 46, 826 152, 947 306, 947
+ C 459, 947 565, 826 565, 680
+ C 565, 525 461, 413 306, 413
+ C 150, 413 46, 525 46, 680
+ M 146, 680
+ C 146, 583 205, 489 306, 489
+ C 406, 489 465, 583 465, 680
+ C 465, 771 416, 871 306, 871
+ C 195, 871 146, 771 146, 680 " />
+ <!-- bounds: 38, 205 <-> 2232, 947 -->
+ </g> </g>
+ </g>
+
+
+ <!-- scaled by 0.72, shifted around to hit pixel boundaries -->
+ <g id="cairo_text_small" transform="translate(0,-71)">
+ <g transform="scale(0.085,0.085)"> <g transform="translate(-1139,-208.5)">
+ <!-- 63 (c), advance 444, 0 horiBearing 38,522 -->
+ <path transform="translate(-151,0)" d="
+ M 412, 433
+ C 385, 422 336, 413 298, 413
+ C 142, 413 38, 525 38, 680
+ C 38, 826 144, 947 298, 947
+ C 332, 947 377, 944 416, 926
+ L 409, 842
+ C 380, 861 340, 871 308, 871
+ C 187, 871 138, 771 138, 680
+ C 138, 583 197, 489 302, 489
+ C 332, 489 368, 496 404, 511
+ L 412, 433 " />
+ <!-- 61 (a), advance 556, 0 horiBearing 46,522 -->
+ <path transform="translate(261.75,0)" d="
+ M 109, 541
+ C 147, 509 204, 489 257, 489
+ C 351, 489 383, 534 383, 622
+ C 346, 620 320, 620 283, 620
+ C 186, 620 46, 660 46, 788
+ C 46, 899 123, 947 233, 947
+ C 319, 947 369, 900 391, 869
+ L 393, 869
+ L 393, 935
+ L 481, 935
+ C 479, 920 477, 893 477, 835
+ L 477, 624
+ C 477, 485 418, 413 272, 413
+ C 207, 413 151, 433 104, 461
+ L 109, 541
+ M 383, 737
+ C 383, 813 334, 871 241, 871
+ C 198, 871 146, 842 146, 788
+ C 146, 698 272, 690 323, 690
+ C 343, 690 363, 692 383, 692
+ L 383, 737 " />
+ <!-- 69 (i), advance 278, 0 horiBearing 86,730 -->
+ <path transform="translate(764.75)" d="
+ M 92, 935
+ L 186, 935
+ L 186, 425
+ L 92, 425
+ L 92, 935
+ M 88, 261
+ A 51, 51 0 1 1 190,261
+ A 51, 51 0 1 1 88,261" />
+ <!-- 72 (r), advance 389, 0 horiBearing 80,522 -->
+ <path transform="translate(988.5,0)" d="
+ M 80, 935
+ L 174, 935
+ L 174, 703
+ C 174, 575 229, 495 313, 495
+ C 329, 495 348, 497 365, 504
+ L 365, 420
+ C 345, 416 331, 413 303, 413
+ C 249, 413 195, 451 170, 504
+ L 168, 504
+ L 168, 425
+ L 80, 425
+ L 80, 935 " />
+ <!-- 6f (o), advance 611, 0 horiBearing 46,522 -->
+ <path transform="translate(1355.5,0)" d="
+ M 46, 680
+ C 46, 826 152, 947 306, 947
+ C 459, 947 565, 826 565, 680
+ C 565, 525 461, 413 306, 413
+ C 150, 413 46, 525 46, 680
+ M 146, 680
+ C 146, 583 205, 489 306, 489
+ C 406, 489 465, 583 465, 680
+ C 465, 771 416, 871 306, 871
+ C 195, 871 146, 771 146, 680 " />
+ <!-- bounds: 38, 205 <-> 2232, 947 -->
+ </g> </g>
+ </g>
+
+ <g id="cairo_logo_text_small">
+ <!-- The logo on the left, the text 'cairo' on the right -->
+ <use xlink:href="#cairo_logo_bottomleft-centered" transform="translate(0, 78), scale(0.1944)" />
+ <use xlink:href="#cairo_text_small" fill="white" transform="translate(175,82)"/>
+ </g>
+
+ <g id="cairo_logo_with_text">
+ <!-- The logo (scarab and dung), with the text 'cairo' below, the dot of the 'i' positioned between the hind legs of the scarab -->
+ <!-- dimensions: 300x490, centered -->
+ <use xlink:href="#cairo_logo_top-centered" transform="translate(0, -245)" />
+ <use xlink:href="#cairo_text" transform="translate(0, 245)" />
+ </g>
+
+ <g id="cairo_banner">
+ <!-- The logo on the left, the text 'cairo' in the center, and a mirror image of the logo on the right -->
+ <!-- The logos are scaled such that the scarab body nearly matches the height of the text characters (excepting the 'i')
+ and the dung should nearly aligns with the dot of the 'i'. The bottoms of the logos are aligned with the bottom of the text. -->
+ <!-- dimensions: 370x88, centered -->
+ <use xlink:href="#cairo_logo_bottomleft-centered" transform="translate(-180, 40), scale(0.1944)" />
+ <use xlink:href="#cairo_text_small" transform="translate(0, 42)" fill="black" />
+ <use xlink:href="#cairo_logo_bottomleft-centered" transform="translate(180, 40), scale(0.1944), scale(-1, 1)" />
+ </g>
+
+ <g id="freedesktop_org_logo" style="fill:#FFFFFF;stroke:#3B80AE;stroke-width:2.4588;">
+ <g>
+ <path style="stroke:#BABABA;" d="M85.277,40.796c2.058,7.884-2.667,15.942-10.551,17.999L27.143,71.21c-7.884,2.057-15.943-2.667-18-10.552
+ l-7.448-28.55c-2.057-7.884,2.667-15.942,10.551-17.999L59.83,1.695c7.884-2.057,15.942,2.667,17.999,10.551
+ l7.449,28.55z"/>>
+ <path style="fill:#3B80AE;stroke:none;" d="M80.444,39.778c1.749,7.854-1.816,13.621-9.504,15.447l-42.236,11.02c-7.569,2.396-14.089-1.181
+ -15.838-8.836L6.53,33.127c-1.749-8.145,0.709-12.889,9.503-15.447L58.27,6.661
+ c8.144-1.826,14.089,1.363,15.838,8.835l6.336,24.282z"/>>
+ </g>g>
+ <path style="opacity:0.5;fill:none;stroke:#FFFFFF;" d="M45.542,51.793L24.104,31.102l38.1-4.393L45.542,51.793z"/>>
+ <path d="M72.325,28.769c0.405,1.55-0.525,3.136-2.075,3.541l-12.331,3.217c-1.551,0.404-3.137-0.525-3.542-2.076l-2.295-8.801
+ c-0.405-1.551,0.524-3.137,2.076-3.542l12.33-3.217c1.551-0.405,3.137,0.525,3.542,2.076l2.295,8.801z"/>>
+ <path d="M36.51,33.625c0.496,1.9-0.645,3.844-2.545,4.34l-15.112,3.943c-1.901,0.496-3.845-0.644-4.34-2.544l-2.814-10.786
+ c-0.496-1.901,0.644-3.844,2.544-4.34l15.113-3.942c1.901-0.496,3.845,0.643,4.34,2.544l2.814,10.786z"/>>
+ <path d="M52.493,53.208c0.278,1.065-0.36,2.154-1.425,2.432L42.6,57.848c-1.064,0.277-2.153-0.36-2.431-1.426l-1.577-6.043
+ c-0.277-1.064,0.36-2.153,1.425-2.432l8.468-2.209c1.064-0.277,2.154,0.361,2.431,1.426l1.577,6.043z"/>>
+ </g>g>
+ <g id="bullet">
+ <use x="0" y="0" xlink:href="#cairo_logo" transform="translate(-6,-2) scale(0.1, 0.1)"/>>
+ </g>
+ <g id="redhat_logo_horizontal">
+ <!-- 380x125 Red Hat log (horizontal layout) -->
+ <g fill="black" stroke="none"
+ transform="translate(0,124),scale(1,-1),translate(-214,-258)"
+ fill-rule="evenodd"
+ >
+ <!-- r -->
+ <path fill="black" d="
+ M 367.0625 315.3203
+ C 367.0625 320.8765 366.9463 324.9644 366.7227 328.6597
+ L 375.811 328.6597
+ L 376.2002 320.7764
+ L 376.4971 320.7764
+ C 378.5391 326.6221 383.3809 329.5996 387.8594 329.5996
+ C 388.8843 329.5996 389.4824 329.5601 390.3218 329.373
+ L 390.3218 319.4863
+ C 389.3398 319.6763 388.4224 319.7842 387.1592 319.7842
+ C 382.1597 319.7842 378.688 316.6006 377.751 311.8447
+ C 377.5732 310.918 377.4805 309.8086 377.4805 308.6777
+ L 377.4805 287.1504
+ L 366.9766 287.1504
+ L 367.0625 315.3203
+ " />
+
+ <!-- e -->
+ <path fill="black" d="
+ M 402.9927 305.0791
+ C 403.2715 297.5586 409.0918 294.2695 415.814 294.2695
+ C 420.6406 294.2695 424.0942 295.0234 427.2681 296.1924
+ L 428.8232 288.9678
+ C 425.269 287.4629 420.3413 286.3359 414.3149 286.3359
+ C 400.8384 286.3359 392.9409 294.6592 392.9409 307.3809
+ C 392.9409 318.8369 399.8911 329.6772 413.2437 329.6772
+ C 426.7397 329.6772 431.1338 318.5771 431.1338 309.4893
+ C 431.1338 307.5381 430.9624 305.9707 430.7593 305.0059
+ L 402.9927 305.0791
+
+ M 421.2485 312.3926
+ C 421.2954 316.2388 419.6206 322.5088 412.5903 322.5088
+ C 406.1299 322.5088 403.4438 316.645 402.9722 312.3926
+ L 421.2485 312.3926
+ " />
+
+ <!-- d -->
+ <path fill="black" d="
+ M 476.355 344.667
+ L 465.8638 347.5083
+ L 465.8638 324.1914
+ L 465.6904 324.1914
+ C 463.8335 327.2563 459.7407 329.5996 454.0571 329.5996
+ C 444.0762 329.5996 435.3828 321.3374 435.4478 307.4307
+ C 435.4478 294.6719 443.2983 286.2168 453.2119 286.2168
+ C 459.2017 286.2168 464.2114 289.0723 466.6909 293.7217
+ L 466.8779 293.7217
+ L 467.3491 287.1504
+ L 476.6997 287.1504
+ C 476.5083 289.9717 476.355 294.543 476.355 298.792
+ L 476.355 344.667
+
+ M 465.8638 305.1504
+ C 465.8638 304.0479 465.7856 303.0234 465.5454 302.0869
+ C 464.4873 297.5439 460.7734 294.6172 456.4819 294.6172
+ C 449.8721 294.6172 446.0903 300.1885 446.0903 307.8164
+ C 446.0903 315.5166 449.8384 321.4761 456.6016 321.4761
+ C 461.3208 321.4761 464.6992 318.1484 465.6274 314.1064
+ C 465.8071 313.2559 465.8638 312.208 465.8638 311.3711
+ L 465.8638 305.1504
+ " />
+
+ <!-- h -->
+ <path fill="black" d="
+ M 503.7964 329.0176
+ C 500.6836 329.0176 497.8926 328.1187 495.5493 326.6714
+ C 493.1162 325.2461 491.1353 323.0464 489.959 320.7666
+ L 489.7915 320.7666
+ L 489.7915 341.0195
+ L 485.7427 342.1226
+ L 485.7427 287.1504
+ L 489.7915 287.1504
+ L 489.7915 312.1787
+ C 489.7915 313.8408 489.9204 314.9946 490.3462 316.2109
+ C 492.0928 321.3013 496.8896 325.4805 502.689 325.4805
+ C 511.0664 325.4805 513.9673 318.7603 513.9673 311.3906
+ L 513.9673 287.1504
+ L 518.0137 287.1504
+ L 518.0137 311.8359
+ C 518.0137 327.0791 507.6753 329.0176 503.7964 329.0176
+ " />
+
+ <!-- a -->
+ <path fill="black" d="
+ M 554.3413 296.873
+ C 554.3413 293.6357 554.4692 290.2832 554.9375 287.1504
+ L 551.2085 287.1504
+ L 550.6128 293.0156
+ L 550.4209 293.0156
+ C 548.438 289.8594 543.8765 286.2168 537.3726 286.2168
+ C 529.1392 286.2168 525.3057 292.0117 525.3057 297.4688
+ C 525.3057 306.9121 533.6421 312.6064 550.292 312.4321
+ L 550.292 313.5234
+ C 550.292 317.5718 549.5044 325.6475 539.8242 325.5859
+ C 536.2446 325.5859 532.5132 324.6255 529.5513 322.5366
+ L 528.2632 325.4805
+ C 532.0015 328.0137 536.5659 329.0176 540.2705 329.0176
+ C 552.0801 329.0176 554.3413 320.1509 554.3413 312.8379
+ L 554.3413 296.873
+
+ M 550.292 309.0234
+ C 541.3813 309.2813 529.6128 307.9336 529.6128 298.1055
+ C 529.6128 292.2246 533.4946 289.5811 537.7578 289.5811
+ C 544.5796 289.5811 548.4561 293.8018 549.8677 297.7871
+ C 550.1646 298.6621 550.292 299.5371 550.292 300.2402
+ L 550.292 309.0234
+ " />
+
+ <!-- t -->
+ <path fill="black" d="
+ M 570.459 337.0996
+ L 570.459 328.0801
+ L 582.1235 328.0801
+ L 582.1235 324.7959
+ L 570.459 324.7959
+ L 570.459 298.1943
+ C 570.459 292.9912 572.0757 289.7285 576.4692 289.7285
+ C 578.5815 289.7285 580.0757 290.0078 581.1206 290.3711
+ L 581.6099 287.2354
+ C 580.2871 286.6836 578.4302 286.2539 575.9619 286.2539
+ C 572.9741 286.2539 570.4995 287.1934 568.8994 289.1543
+ C 567.0469 291.3057 566.4116 294.7412 566.4116 298.916
+ L 566.4116 324.7959
+ L 559.5059 324.7959
+ L 559.5059 328.0801
+ L 566.4116 328.0801
+ L 566.4116 335.606
+ L 570.459 337.0996
+ " />
+
+ <!-- ® for 'redhat' -->
+ <path fill="black" d="
+ M 335.5 288.9707
+ L 336.0352 288.9707
+ L 336.8408 287.6445
+ L 337.3608 287.6445
+ L 336.4888 288.9937
+ C 336.9404 289.0498 337.2832 289.2881 337.2832 289.834
+ C 337.2832 290.4385 336.9258 290.7051 336.2017 290.7051
+ L 335.0366 290.7051
+ L 335.0366 287.6445
+ L 335.5 287.6445
+ L 335.5 288.9707
+
+ M 335.5 289.3643
+ L 335.5 290.3101
+ L 336.1318 290.3101
+ C 336.4531 290.3101 336.7979 290.2402 336.7979 289.8647
+ C 336.7979 289.3916 336.4492 289.3643 336.0566 289.3643
+ L 335.5 289.3643
+ " />
+
+ <path fill="black" d="
+ M 339.0439 289.1719
+ C 339.0439 287.5176 337.7041 286.1763 336.0493 286.1763
+ C 334.395 286.1763 333.0527 287.5176 333.0527 289.1719
+ C 333.0527 290.8271 334.395 292.1675 336.0493 292.1675
+ C 337.7041 292.1675 339.0439 290.8271 339.0439 289.1719
+
+ M 336.0493 291.6367
+ C 334.6865 291.6367 333.5835 290.5332 333.5835 289.1719
+ C 333.5835 287.8096 334.6865 286.7061 336.0493 286.7061
+ C 337.4082 286.7061 338.5117 287.8096 338.5117 289.1719
+ C 338.5117 290.5332 337.4082 291.6367 336.0493 291.6367
+ " />
+
+ <!-- Black background behind The Shadowman -->
+ <path fill="black" d="
+ M 326.4531 286.208
+ C 324.1177 286.7451 321.6396 287.0801 319.1338 287.0801
+ C 314.8496 287.0801 310.9502 286.3389 308.0732 285.1426
+ C 307.7559 284.9844 307.5303 284.6533 307.5303 284.2764
+ C 307.5303 284.1406 307.5654 283.999 307.6172 283.8838
+ C 307.957 282.8975 307.3984 281.8281 304.6157 281.2158
+ C 300.4883 280.3096 297.8833 276.0527 296.3916 274.6367
+ C 294.6411 272.9756 289.6973 271.9531 290.4404 272.9434
+ C 291.0225 273.7188 293.2485 276.1348 294.6016 278.748
+ C 295.8125 281.083 296.8906 281.7461 298.375 283.9736
+ C 298.811 284.627 300.4995 286.9219 300.9912 288.7373
+ C 301.543 290.5107 301.356 292.7344 301.5679 293.6494
+ C 301.8721 294.9697 303.1182 297.8369 303.2129 299.4531
+ C 303.2666 300.3691 299.3916 298.1494 297.5532 298.1494
+ C 295.7144 298.1494 293.9233 299.248 292.2808 299.3281
+ C 290.248 299.4248 288.9414 297.7607 287.1025 298.0508
+ C 286.0518 298.2178 285.167 299.1426 283.3311 299.2129
+ C 280.7178 299.3086 277.5244 297.7607 271.5264 297.9531
+ C 265.6255 298.1436 260.1753 305.4082 259.4312 306.5635
+ C 258.5605 307.9199 257.4961 307.9199 256.335 306.8555
+ C 255.1738 305.792 253.7432 306.627 253.3359 307.3389
+ C 252.5615 308.6943 250.4927 312.6543 247.2881 313.4824
+ C 242.8564 314.6309 240.6118 311.0283 240.9033 308.1621
+ C 241.1987 305.252 243.0801 304.4375 243.9512 302.8906
+ C 244.8213 301.3428 245.2671 300.3428 246.9053 299.6572
+ C 248.0674 299.1758 248.5 298.458 248.1533 297.5049
+ C 247.8506 296.6738 246.6416 296.4834 245.8477 296.4463
+ C 244.1592 296.3662 242.9756 296.8242 242.1123 297.376
+ C 241.1084 298.0137 240.292 298.9033 239.416 300.4131
+ C 238.4023 302.0781 236.8052 302.8037 234.9453 302.8037
+ C 234.0586 302.8037 233.2295 302.5693 232.4922 302.1895
+ C 229.5771 300.6748 226.1064 299.7744 222.3706 299.7744
+ L 218.1572 299.7734
+ C 216.1064 305.8555 214.9951 312.3682 214.9951 319.1416
+ C 214.9951 352.6064 242.1226 379.7334 275.5859 379.7334
+ C 309.0498 379.7334 336.1758 352.6064 336.1758 319.1416
+ C 336.1758 307 332.6035 295.6895 326.4531 286.208
+ " />
+
+ <!-- The Shadowman's face -->
+ <path fill="white" d="
+ M 326.4531 286.209
+ C 324.1177 286.7461 321.6396 287.084 319.1338 287.084
+ C 314.8496 287.084 310.9502 286.3418 308.0732 285.1436
+ C 307.7559 284.9873 307.5303 284.6553 307.5303 284.2783
+ C 307.5303 284.1416 307.5654 284.001 307.6172 283.8838
+ C 307.957 282.8994 307.3984 281.8311 304.6157 281.2178
+ C 300.4883 280.3115 297.8833 276.0537 296.3916 274.6416
+ C 294.6411 272.9766 289.6973 271.9551 290.4404 272.9463
+ C 291.0225 273.7197 293.2485 276.1367 294.6016 278.749
+ C 295.8125 281.083 296.8906 281.75 298.375 283.9756
+ C 298.811 284.627 300.4995 286.9238 300.9912 288.7402
+ C 301.543 290.5117 301.356 292.7354 301.5679 293.6514
+ C 301.8721 294.9727 303.1182 297.8379 303.2129 299.457
+ C 303.2666 300.3721 299.3916 298.1504 297.5532 298.1504
+ C 295.7144 298.1504 293.9233 299.251 292.2808 299.3301
+ C 290.248 299.4258 288.9414 297.7627 287.1025 298.0518
+ C 286.0518 298.2207 285.167 299.1465 283.3311 299.2148
+ C 280.7178 299.3096 277.5244 297.7627 271.5264 297.9561
+ C 265.6255 298.1475 260.1753 305.4121 259.4312 306.5674
+ C 258.5605 307.9219 257.4961 307.9219 256.335 306.8574
+ C 255.1738 305.7939 253.7432 306.6299 253.3359 307.3438
+ C 252.5615 308.6963 250.4927 312.6553 247.2881 313.4854
+ C 242.8564 314.6338 240.6118 311.0313 240.9033 308.1641
+ C 241.1987 305.2539 243.0801 304.4395 243.9512 302.8926
+ C 244.8213 301.3438 245.2671 300.3457 246.9053 299.6621
+ C 248.0674 299.1768 248.5 298.4609 248.1533 297.5068
+ C 247.8506 296.6768 246.6416 296.4873 245.8477 296.4492
+ C 244.1592 296.3672 242.9756 296.8262 242.1123 297.376
+ C 241.1084 298.0176 240.292 298.9043 239.416 300.416
+ C 238.4023 302.0801 236.8052 302.8086 234.9453 302.8086
+ C 234.0586 302.8086 233.2295 302.5723 232.4922 302.1934
+ C 229.5771 300.6748 226.1064 299.7773 222.3706 299.7773
+ L 218.1572 299.7744
+ C 226.2363 275.8105 248.8965 258.5527 275.5859 258.5527
+ C 296.9063 258.5527 315.6538 269.5635 326.4531 286.209
+ " />
+
+ <!-- nose shadow -->
+ <path fill="black" d="
+ M 288.9307 291.7637
+ C 289.2422 291.46 289.7793 290.4375 289.1226 289.1396
+ C 288.7544 288.4521 288.3579 287.9678 287.6489 287.4023
+ C 286.7969 286.7188 285.1309 285.9307 282.8457 287.3799
+ C 281.6172 288.1592 281.543 288.4209 279.8467 288.2012
+ C 278.6348 288.043 278.1533 289.2656 278.5884 290.2832
+ C 279.0244 291.2969 280.8145 292.1191 283.04 290.8135
+ C 284.041 290.2256 285.6025 288.9844 286.9688 290.084
+ C 287.5356 290.5381 287.875 290.8408 288.6611 291.75
+ C 288.6963 291.7881 288.7461 291.8105 288.8018 291.8105
+ C 288.8516 291.8105 288.8965 291.793 288.9307 291.7637
+ " />
+
+ <!-- The Shadowman's red hat -->
+ <path fill="#cc0000" d="
+ M 309.7769 335.2627
+ C 309.1787 333.251 308.3271 330.6763 304.5391 328.7314
+ C 303.9878 328.4497 303.7764 328.9126 304.0313 329.3477
+ C 305.4629 331.7832 305.7168 332.3921 306.1328 333.3525
+ C 306.7148 334.7568 307.02 336.7549 305.8618 340.9219
+ C 303.5835 349.1221 298.8296 360.083 295.375 363.6392
+ C 292.04 367.0698 285.998 368.0361 280.5371 366.6348
+ C 278.5264 366.1191 274.5918 364.0732 267.2939 365.7168
+ C 254.665 368.5605 252.7939 362.2368 252.0693 359.4824
+ C 251.3438 356.7271 249.6045 348.897 249.6045 348.897
+ C 249.0244 345.7085 248.2646 340.1631 267.874 336.4287
+ C 277.0088 334.6885 277.4736 332.3276 277.8779 330.6289
+ C 278.603 327.585 279.7627 325.8438 281.0674 324.9746
+ C 282.373 324.1035 281.0674 323.3828 279.6187 323.2349
+ C 275.7285 322.8311 261.3491 326.9541 252.8428 331.7881
+ C 245.8828 336.0415 245.7656 339.8721 247.3584 343.1211
+ C 236.8452 344.2573 228.9561 342.1348 227.5254 337.1582
+ C 225.0693 328.6157 246.3047 314.0264 270.4839 306.7061
+ C 295.8579 299.0225 321.9556 304.3857 324.8564 320.335
+ C 326.1738 327.5811 320.0713 332.9419 309.7769 335.2627
+ " />
+
+ <!-- shadow on hat -->
+ <path fill="black" d="
+ M 270.8711 350.8813
+ C 263.8721 350.375 263.145 349.6191 261.834 348.2227
+ C 259.9854 346.2539 257.5508 350.7773 257.5508 350.7773
+ C 256.0898 351.085 254.3179 353.4404 255.2744 355.6411
+ C 256.2158 357.8174 257.9551 357.1641 258.5 356.4868
+ C 259.1626 355.6621 260.5771 354.3125 262.4141 354.3613
+ C 264.251 354.4097 266.3706 354.7959 269.3262 354.7959
+ C 272.3213 354.7959 274.335 353.6777 274.4487 352.7168
+ C 274.5459 351.8965 274.2061 351.1226 270.8711 350.8813
+ " />
+
+ <!-- another shadow on hat -->
+ <path fill="black" d="
+ M 278.2236 362.4463
+ C 278.2129 362.4453 278.2021 362.4438 278.1919 362.4438
+ C 278.084 362.4438 277.9961 362.5273 277.9961 362.6274
+ C 277.9961 362.7007 278.041 362.7646 278.106 362.7939
+ C 279.4629 363.5107 281.4873 364.0811 283.8042 364.3169
+ C 284.499 364.3887 285.1787 364.4248 285.832 364.4307
+ C 285.9478 364.4307 286.0615 364.4297 286.1787 364.4277
+ C 290.062 364.3398 293.1719 362.7974 293.1255 360.9814
+ C 293.0791 359.165 289.8955 357.7637 286.0112 357.8506
+ C 284.7529 357.8794 283.5732 358.0615 282.5576 358.3545
+ C 282.4385 358.3857 282.3506 358.4883 282.3506 358.6094
+ C 282.3506 358.731 282.4385 358.834 282.5605 358.8638
+ C 284.9839 359.4248 286.6191 360.3408 286.5039 361.207
+ C 286.3511 362.3545 283.1816 362.979 279.4248 362.6011
+ C 279.0137 362.5596 278.6118 362.5068 278.2236 362.4463
+ " />
+
+ <!-- ® for The Shadowman -->
+ <path fill="black" d="
+ M 588.3018 288.9707
+ L 588.8369 288.9707
+ L 589.6426 287.6445
+ L 590.1626 287.6445
+ L 589.2905 288.9937
+ C 589.7422 289.0498 590.085 289.2881 590.085 289.834
+ C 590.085 290.4385 589.7275 290.7051 589.0034 290.7051
+ L 587.8384 290.7051
+ L 587.8384 287.6445
+ L 588.3018 287.6445
+ L 588.3018 288.9707
+
+ M 588.3018 289.3643
+ L 588.3018 290.3101
+ L 588.9336 290.3101
+ C 589.2549 290.3101 589.5996 290.2402 589.5996 289.8647
+ C 589.5996 289.3916 589.251 289.3643 588.8584 289.3643
+ L 588.3018 289.3643
+ " />
+
+ <path fill="black" d="
+ M 591.8457 289.1719
+ C 591.8457 287.5176 590.5059 286.1763 588.8511 286.1763
+ C 587.1968 286.1763 585.8545 287.5176 585.8545 289.1719
+ C 585.8545 290.8271 587.1968 292.1675 588.8511 292.1675
+ C 590.5059 292.1675 591.8457 290.8271 591.8457 289.1719
+
+ M 588.8511 291.6367
+ C 587.4883 291.6367 586.3853 290.5332 586.3853 289.1719
+ C 586.3853 287.8096 587.4883 286.7061 588.8511 286.7061
+ C 590.21 286.7061 591.3135 287.8096 591.3135 289.1719
+ C 591.3135 290.5332 590.21 291.6367 588.8511 291.6367
+ " />
+
+ </g>
+ </g>
+
+ </defs>
+
+ <g id="watermark" transform="translate(200, 185), rotate(-50), scale(2.5)">
+ <use xlink:href="#scarab" x="0" y="170" fill-opacity="0.2"/>
+ </g>
+
+ <!-- Blue bar at top of slide -->
+ <rect x="0" y="0" width="1024" height="170" fill="#162284" />
+
+ <!-- Scarab and "cairo" at upper-left -->
+ <g transform="translate(10,0)">
+ <use stroke="none" xlink:href="#cairo_logo_text_small"/>
+ </g>
+
+ <!-- Presentation title at upper-right -->
+ <text ss:variable="presentation-subtitle" text-anchor="end"
+ fill="white" x="1016" y="28" font-size="20">Presentation Sub-title</text>
+
+ <!-- Red Hat logo at lower-left -->
+ <use xlink:href="#redhat_logo_horizontal" transform="translate(8,768),scale(.5,.5),translate(0, -125)" />
+
+ <g font-family="Frutiger">
+ <text text-anchor="middle"
+ fill="black"
+ x="512"
+ y="300" font-size="80"
+ font-weight="bold"
+ ss:variable="title">Slide Title</text>
+
+ <!-- Slide content -->
+ <g ss:region="default">
+ <rect x="512" y="400" width="2" height="280" fill="none" stroke="blue"/>
+ <text font-size="50" fill="black" text-anchor="middle"
+ x="512" y="450">Slide content</text>
+ </g>
+
+ <!-- Footer -->
+ <text ss:variable="URL" x="1016" y="753" text-anchor="end" font-size="20">http://cairographics.org</text>
+ </g>
+
+</svg>
diff --git a/doc/tutorial/slides/cairo-title.svg b/doc/tutorial/slides/cairo-title.svg
new file mode 100644
index 000000000..31b14f83b
--- /dev/null
+++ b/doc/tutorial/slides/cairo-title.svg
@@ -0,0 +1,898 @@
+<?xml version="1.0" ?>
+<svg width="1024" height="768"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:ss="http://www.svgslides.org/svgslides0.1"
+ fill="black">
+
+
+ <defs id="cairo-artwork_defs">
+ <g id="hacker_emblem">
+ <!-- Note: This is similar though not identical to Keith Packard's SVG version
+ of the hacker emblem (http://www.catb.org/hacker-emblem/glider.svg) -->
+ <g id="hacker_emblem_grid" fill="white" stroke="none">
+ <!-- Outside: Top, Right, Bottom, Left -->
+ <rect x="-2.95" y="-3.05" width="6" height="0.1" />
+ <rect x="2.95" y="-2.95" width="0.1" height="6" />
+ <rect x="-3.05" y="2.95" width="6" height="0.1" />
+ <rect x="-3.05" y="-3.05" width="0.1" height="6" />
+ <!-- Vertical: Left, Right -->
+ <rect x="-1.05" y="-2.95" width="0.1" height="5.9" />
+ <rect x="0.95" y="-2.95" width="0.1" height="5.9" />
+ <!-- Horizontal: TopLeft, TopMiddle, TopRight -->
+ <rect x="-2.95" y="-1.05" width="1.9" height="0.1" />
+ <rect x="-0.95" y="-1.05" width="1.9" height="0.1" />
+ <rect x="1.05" y="-1.05" width="1.9" height="0.1" />
+ <!-- Horizontal: BottomLeft, BottomMiddle, BottomRight -->
+ <rect x="-2.95" y="0.95" width="1.9" height="0.1" />
+ <rect x="-0.95" y="0.95" width="1.9" height="0.1" />
+ <rect x="1.05" y="0.95" width="1.9" height="0.1" />
+ </g>
+ <g id="hacker_emblem_dots" fill="white">
+ <circle cx="0" cy="-2" r="0.7" />
+ <circle cx="2" cy="0" r="0.7" />
+ <circle cx="-2" cy="2" r="0.7" />
+ <circle cx="0" cy="2" r="0.7" />
+ <circle cx="2" cy="2" r="0.7" />
+ </g>
+ </g>
+ <g id="scarab" fill="#f19a14">
+ <g transform="translate(-150, -170)">
+ <path id="scarab_head" d="M205.599,94.567c0-11.668-24.914-21.129-55.628-21.129
+ c-30.723,0-55.624,9.46-55.624,21.129c0,10.203,24.901,7.346,55.624,7.346C180.685,101.913,205.599,104.233,205.599,94.567z"/>
+ <path id="scarab_torso" d="M136.423,161.506c0,0,12.751,12.577,13.547,13.362
+ c2.262-2.232,13.545-13.362,13.545-13.362c7.135-7.036,87.111-6.399,91.066-6.363c-0.469-6.298-1.254-12.472-2.325-18.519
+ c-15.183-19.279-42.811-32.225-74.485-32.225h-55.518c-31.745,0-59.439,13.011-74.598,32.37c-1.054,6-1.829,12.128-2.296,18.374
+ C49.321,155.106,129.288,154.47,136.423,161.506z"/>
+ <path id="scarab_spine" d="M149.97,301.187c2.005-24.729,8.386-103.483,8.405-103.721
+ c-0.09-0.219-6.478-15.578-8.405-20.214c-1.936,4.655-8.316,19.995-8.408,20.214C141.582,197.704,147.965,276.458,149.97,301.187z"/>
+ <path id="scarab_wing_left" d="M140.403,197.149l8.862-21.31l-13.686-13.499
+ c-5.65-5.573-67.074-6.235-90.259-6.019l-0.006-0.622c-0.154,2.144-0.271,4.302-0.35,6.475
+ c-0.076,2.207,10.392,4.706,10.392,6.717c0,2.319-10.457,5.084-10.359,7.631c2.993,73.349,48.53,131.631,104.372,132.048
+ l-9.02-111.29L140.403,197.149z"/>
+ <path id="scarab_wing_right" d="M244.585,168.891c0-2.011,10.467-4.506,10.391-6.715
+ c-0.079-2.174-0.195-4.332-0.351-6.479l-0.004,0.624c-23.186-0.216-84.608,0.445-90.26,6.017l-13.688,13.502l8.915,21.438
+ l-9.017,111.29c55.854-0.417,101.378-58.698,104.373-132.049C255.04,173.976,244.585,171.209,244.585,168.891z"/>
+ <path id="scarab_leg_front_left" d="M44.506,141.12c-4.135-0.856-4.895-1.54-7.935-2.92
+ c-9.59-3.364-10.376-5.481-16.08-11.86c-7.426-8.306-12.661-20.142-17.1-29.463c-3.576-7.525-3.984-16.409-2.86-24.273
+ c0.991-6.935,7.144-12.869,12.074-18.92c5.844-7.191,10.356-14.822,17.924-21.354c7.736-6.682,23.203-9.809,26.168-19.648
+ C57.86,8.819,54.334,1.766,61.482,0c-0.366,4.703,3.639,8.477,2.397,13.575c-1.129,4.627-4.368,5.811-9.611,9.099
+ c-7.564,4.746-18.366,8.779-24.748,13.965c-7.175,5.827-4.369,13.771-10.569,20.057c-2.001,2.03-7.901,4.706-9.137,6.83
+ c-1.861,3.199-0.297,9.572-0.116,13.12c0.425,8.284,5.588,14.244,9.555,22.045c4.152,8.141,6.429,15.409,13.411,22.519
+ c4.183,4.262,11.429,4.802,16.21,10.647l-3.555,4.186L44.506,141.12z"/>
+ <path id="scarab_leg_middle_left" d="M43.94,191.922l-0.809-7.346
+ c-9.506-4.579-10.339-9.772-20.738-12.466c-23.728-6.151-21.361,11.25-15.532,26.373c5.676,14.726,8.237,30.23,14.345,44.795
+ c2.805,6.688,6.919,13.213,14.298,15.127c0.372-8.435-0.917-10.651-6.113-16.919c-4.395-5.293-3.326-12.548-6.072-18.504
+ c-3.581-7.804-4.196-15.646-7.279-23.502c-1.363-3.479-8.33-13.966-6.452-17.861c3.183-6.603,9.178-0.083,12.179,2.077
+ c4.218,3.036,6.467,2.223,11.681,2.898C34.041,186.673,37.005,188.756,43.94,191.922z"/>
+ <path id="scarab_leg_back_left" d="M65.839,257.063l-2.771-4.837
+ c-6.68,8.928-6.993,16.228-10.056,23.347c-5.277,12.263-0.157,28.851,9.854,37.676c6.052,5.375,15.907,9.618,23.122,13.136
+ c10.035,4.892,20.113,11.286,31.336,13.396c2.482,0.466,8.798,1.295,6.693-3.522c-0.975-2.237-8.091-4.591-10.146-5.734
+ c-8.312-4.623-16.377-10.524-24.142-16.176c-9.498-6.862-20.843-11.186-28.311-20.684c-3.054-3.885-3.544-4.922-2.816-9.39
+ c0.693-4.263,1.344-9.174,2.241-13.439C61.855,266.029,63.274,261.378,65.839,257.063z"/>
+ <path id="scarab_leg_front_right" d="M255.487,141.12c4.134-0.856,4.896-1.54,7.936-2.92
+ c9.583-3.364,10.369-5.481,16.071-11.86c7.428-8.306,12.661-20.142,17.115-29.463c3.574-7.525,3.983-16.409,2.86-24.273
+ c-0.992-6.935-7.157-12.869-12.087-18.92c-5.843-7.191-10.356-14.822-17.919-21.354c-7.735-6.682-23.202-9.809-26.167-19.648
+ C242.135,8.819,245.66,1.766,238.511,0c0.366,4.703-3.637,8.477-2.396,13.575c1.131,4.627,4.368,5.811,9.611,9.099
+ c7.563,4.746,18.367,8.779,24.747,13.965c7.17,5.827,4.362,13.771,10.563,20.057c2.001,2.03,7.901,4.706,9.139,6.83
+ c1.859,3.199,0.295,9.572,0.113,13.12c-0.424,8.284-5.588,14.244-9.553,22.045c-4.152,8.141-6.431,15.409-13.404,22.519
+ c-4.184,4.262-11.429,4.802-16.211,10.647l3.556,4.186L255.487,141.12z"/>
+ <path id="scarab_leg_middle_right" d="M256.053,191.922l0.81-7.346
+ c9.507-4.579,10.34-9.772,20.73-12.466c23.741-6.151,21.374,11.25,15.534,26.373c-5.676,14.726-8.238,30.23-14.347,44.795
+ c-2.804,6.688-6.911,13.213-14.291,15.127c-0.371-8.435,0.918-10.651,6.113-16.919c4.39-5.293,3.319-12.548,6.066-18.504
+ c3.58-7.804,4.197-15.646,7.278-23.502c1.363-3.479,8.33-13.966,6.453-17.861c-3.184-6.603-9.179-0.083-12.181,2.077
+ c-4.217,3.036-6.458,2.223-11.672,2.898C265.951,186.673,262.986,188.756,256.053,191.922z"/>
+ <path id="scarab_leg_back_right" d="M234.155,257.063l2.771-4.837
+ c6.679,8.928,6.991,16.228,10.057,23.347c5.274,12.263,0.154,28.851-9.854,37.676c-6.055,5.375-15.903,9.618-23.117,13.136
+ c-10.034,4.892-20.127,11.286-31.351,13.396c-2.481,0.466-8.789,1.295-6.691-3.522c0.976-2.237,8.092-4.591,10.146-5.734
+ c8.312-4.623,16.392-10.524,24.155-16.176c9.498-6.862,20.838-11.186,28.305-20.684c3.055-3.885,3.543-4.922,2.818-9.39
+ c-0.696-4.263-1.346-9.174-2.244-13.439C238.137,266.029,236.718,261.378,234.155,257.063z"/>
+ </g>
+ </g>
+ <radialGradient id="gradient_radial_dung"
+ cx="0" cy="0" r="60"
+ fx="0" fy="0" gradientUnits="userSpaceOnUse"
+ >
+ <stop offset="0" stop-color="#9a9a9a" />
+ <stop offset="0.70" stop-color="#bababa" />
+ <stop offset="0.95" stop-color="#FFFFFF" />
+ </radialGradient>
+ <g id="dung">
+ <circle cx="0" cy="0" r="60" fill="url(#gradient_radial_dung)" />
+ <g transform="translate(-61, -61)">
+ <!-- rough equivalent: <circle cx="0" cy="0" r="60" stroke="#8a8a8a" stroke-width="2" /> -->
+ <path fill="#8a8a8a" d="M0,61c0,33.636,27.364,61,61,61s61-27.364,61-61S94.636,0,61,0S0,27.364,0,61z
+ M2,61C2,28.467,28.467,2,61,2c32.532,0,59,26.467,59,59c0,32.533-26.468,59-59,59C28.467,120,2,93.533,2,61z"/>
+ </g>
+ <use xlink:href="#hacker_emblem" x="0" y="0" transform="scale(9)" />
+ </g>
+ <g id="dung_2_color">
+ <!-- This would be simple a circle like so:
+ <circle cx="0" cy="0" r="48" stroke-width="2" fill="none" stroke="white"/>
+ but there appears to currently be a bug in the cairo
+ PDF backend that results in an ugly spike in that
+ case. So we use 8 splines instead.
+ -->
+ <path stroke-width="4" stroke="white" fill="none" d="
+M 48, 0
+C 48, 12.730391512298112,
+ 42.94287166245995, 24.939379331448613
+ 33.941125496954285, 33.941125496954278
+C 24.939379331448624, 42.942871662459943
+ 12.730391512298114, 48
+ 0, 48
+C -12.730391512298109, 48,
+ -24.939379331448613, 42.94287166245995
+ -33.941125496954278, 33.941125496954285
+C -42.942871662459943, 24.939379331448624,
+ -48, 12.730391512298118,
+ -48, 0,
+C -48, -12.730391512298105,
+ -42.94287166245995, -24.939379331448613,
+ -33.941125496954285, -33.941125496954278
+C -24.939379331448624, -42.942871662459943,
+ -12.730391512298119, -48,
+ 0, -48
+C 12.730391512298104, -48,
+ 24.939379331448606, -42.942871662459943,
+ 33.941125496954271, -33.941125496954285
+C 42.942871662459936, -24.939379331448624,
+ 48, -12.730391512298123,
+ 48, 0" />
+ <g transform="scale(9)" fill="white" stroke="none"
+stroke-width="0.2">
+ <!-- Hacker emblem grid -->
+ <path stroke="white" fill="none"
+ d="M -3,-3 L 3,-3 L 3,3 L-3,3 Z
+ M -1,-3 L -1, 3
+ M 1,-3 L 1, 3
+ M -3,-1 L 3,-1
+ M -3, 1 L 3, 1"/>
+
+ <!-- Hacker emblem dots -->
+ <circle cx="0" cy="-2" r="0.7" />
+ <circle cx="2" cy="0" r="0.7" />
+ <circle cx="-2" cy="2" r="0.7" />
+ <circle cx="0" cy="2" r="0.7" />
+ <circle cx="2" cy="2" r="0.7" />
+ </g>
+ </g>
+
+ <!-- scarab dimensions: 300x340 -->
+ <!-- dung dimensions: 120x120 (radius: 60) -->
+ <!-- scarab and dung dimensions: 300x400 -->
+
+ <g id="cairo_logo">
+ <!-- dimensions: 300x400, centered -->
+ <!-- The logo (scarab and dung), with the center-point of the bounding box at (0,0) -->
+ <use xlink:href="#dung_2_color" x="0" y="0" transform="translate(0, -140)" />
+ <use xlink:href="#scarab" x="0" y="0" transform="translate(0, 30)" />
+ </g>
+ <g id="cairo_logo_dung-centered">
+ <!-- The logo (scarab and dung), with the dung at (0,0), the scarab below -->
+ <use xlink:href="#dung_2_color" x="0" y="0" />
+ <use xlink:href="#scarab" x="0" y="0" transform="translate(0,170)" />
+ </g>
+ <g id="cairo_logo_scarab-centered">
+ <!-- The logo (scarab and dung), with the scarab's rotational center at (0,0), the dung above -->
+ <!-- The scarab's rotational center in this case is not the center of its bounding box,
+ but is calculated to be the intersection-point of the torso, spine and wings -->
+ <use xlink:href="#dung_2_color" x="0" y="0" transform="translate(0, -175.85)" />
+ <use xlink:href="#scarab" x="0" y="0" transform="translate(0, -5.85)" />
+ </g>
+ <g id="cairo_logo_top-centered">
+ <!-- The logo (scarab and dung), with the top-center point of the bounding box at (0,0) -->
+ <use xlink:href="#dung_2_color" x="0" y="0" transform="translate(0, 60)" />
+ <use xlink:href="#scarab" x="0" y="0" transform="translate(0, 230)" /><!-- (0,170+60) -->
+ </g>
+ <g id="cairo_logo_bottom-centered">
+ <!-- The logo (scarab and dung), with the bottom-center point of the bounding box at (0,0) -->
+ <use xlink:href="#dung_2_color" x="0" y="0" transform="translate(0, -340)" />
+ <use xlink:href="#scarab" x="0" y="0" transform="translate(0, -170)" />
+ </g>
+ <g id="cairo_logo_right-centered">
+ <!-- The logo (scarab and dung), with the right-center point of the bounding box at (0,0) -->
+ <use xlink:href="#dung_2_color" x="0" y="0" transform="translate(-150, -140)" />
+ <use xlink:href="#scarab" x="0" y="0" transform="translate(-150, 30)" />
+ </g>
+ <g id="cairo_logo_left-centered">
+ <!-- The logo (scarab and dung), with the left-center point of the bounding box at (0,0) -->
+ <use xlink:href="#dung_2_color" x="0" y="0" transform="translate(150, -140)" />
+ <use xlink:href="#scarab" x="0" y="0" transform="translate(150, 30)" />
+ </g>
+ <g id="cairo_logo_topleft-centered">
+ <!-- The logo (scarab and dung), with the top-left point of the bounding box at (0,0) -->
+ <use xlink:href="#dung_2_color" x="0" y="0" transform="translate(150, 60)" />
+ <use xlink:href="#scarab" x="0" y="0" transform="translate(150, 230)" /><!-- (150, 170+60) -->
+ </g>
+ <g id="cairo_logo_topright-centered">
+ <!-- The logo (scarab and dung), with the top-right point of the bounding box at (0,0) -->
+ <use xlink:href="#dung_2_color" x="0" y="0" transform="translate(-150, 60)" />
+ <use xlink:href="#scarab" x="0" y="0" transform="translate(-150, 230)" /><!-- (-150,170+60) -->
+ </g>
+ <g id="cairo_logo_bottomleft-centered">
+ <!-- The logo (scarab and dung), with the bottom-left point of the bounding box at (0,0) -->
+ <use xlink:href="#dung_2_color" x="0" y="0" transform="translate(150, -340)" />
+ <use xlink:href="#scarab" x="0" y="0" transform="translate(150, -170)" />
+ </g>
+ <g id="cairo_logo_bottomright-centered">
+ <!-- The logo (scarab and dung), with the bottom-right point of the bounding box at (0,0) -->
+ <use xlink:href="#dung_2_color" x="0" y="0" transform="translate(-150, -340)" />
+ <use xlink:href="#scarab" x="0" y="0" transform="translate(-150, -170)" />
+ </g>
+
+ <g id="cairo_text" transform="translate(0,-97)">
+ <g transform="scale(0.1484,0.1484)"> <g transform="translate(-1139,-208.5)">
+ <!-- 63 (c), advance 444, 0 horiBearing 38,522 -->
+ <path transform="translate(65,0)" d="
+ M 412, 433
+ C 385, 422 336, 413 298, 413
+ C 142, 413 38, 525 38, 680
+ C 38, 826 144, 947 298, 947
+ C 332, 947 377, 944 416, 926
+ L 409, 842
+ C 380, 861 340, 871 308, 871
+ C 187, 871 138, 771 138, 680
+ C 138, 583 197, 489 302, 489
+ C 332, 489 368, 496 404, 511
+ L 412, 433 " />
+ <!-- 61 (a), advance 556, 0 horiBearing 46,522 -->
+ <path transform="translate(486.75,0)" d="
+ M 109, 541
+ C 147, 509 204, 489 257, 489
+ C 351, 489 383, 534 383, 622
+ C 346, 620 320, 620 283, 620
+ C 186, 620 46, 660 46, 788
+ C 46, 899 123, 947 233, 947
+ C 319, 947 369, 900 391, 869
+ L 393, 869
+ L 393, 935
+ L 481, 935
+ C 479, 920 477, 893 477, 835
+ L 477, 624
+ C 477, 485 418, 413 272, 413
+ C 207, 413 151, 433 104, 461
+ L 109, 541
+ M 383, 737
+ C 383, 813 334, 871 241, 871
+ C 198, 871 146, 842 146, 788
+ C 146, 698 272, 690 323, 690
+ C 343, 690 363, 692 383, 692
+ L 383, 737 " />
+ <!-- 69 (i), advance 278, 0 horiBearing 86,730 -->
+ <path transform="translate(1000,0)" d="
+ M 92, 935
+ L 186, 935
+ L 186, 425
+ L 92, 425
+ L 92, 935
+ M 88, 261
+ A 51, 51 0 1 1 190,261
+ A 51, 51 0 1 1 88,261" />
+ <!-- 72 (r), advance 389, 0 horiBearing 80,522 -->
+ <path transform="translate(1234.25,0)" d="
+ M 80, 935
+ L 174, 935
+ L 174, 703
+ C 174, 575 229, 495 313, 495
+ C 329, 495 348, 497 365, 504
+ L 365, 420
+ C 345, 416 331, 413 303, 413
+ C 249, 413 195, 451 170, 504
+ L 168, 504
+ L 168, 425
+ L 80, 425
+ L 80, 935 " />
+ <!-- 6f (o), advance 611, 0 horiBearing 46,522 -->
+ <path transform="translate(1610,0)" d="
+ M 46, 680
+ C 46, 826 152, 947 306, 947
+ C 459, 947 565, 826 565, 680
+ C 565, 525 461, 413 306, 413
+ C 150, 413 46, 525 46, 680
+ M 146, 680
+ C 146, 583 205, 489 306, 489
+ C 406, 489 465, 583 465, 680
+ C 465, 771 416, 871 306, 871
+ C 195, 871 146, 771 146, 680 " />
+ <!-- bounds: 38, 205 <-> 2232, 947 -->
+ </g> </g>
+ </g>
+
+ <!-- scaled by 0.72, shifted around to hit pixel boundaries -->
+ <g id="cairo_text_small_spaced" transform="translate(0,-71)">
+ <g transform="scale(0.085,0.085)"> <g transform="translate(-1139,-208.5)">
+ <!-- 63 (c), advance 444, 0 horiBearing 38,522 -->
+ <path transform="translate(-151,0)" d="
+ M 412, 433
+ C 385, 422 336, 413 298, 413
+ C 142, 413 38, 525 38, 680
+ C 38, 826 144, 947 298, 947
+ C 332, 947 377, 944 416, 926
+ L 409, 842
+ C 380, 861 340, 871 308, 871
+ C 187, 871 138, 771 138, 680
+ C 138, 583 197, 489 302, 489
+ C 332, 489 368, 496 404, 511
+ L 412, 433 " />
+ <!-- 61 (a), advance 556, 0 horiBearing 46,522 -->
+ <path transform="translate(379.5,0)" d="
+ M 109, 541
+ C 147, 509 204, 489 257, 489
+ C 351, 489 383, 534 383, 622
+ C 346, 620 320, 620 283, 620
+ C 186, 620 46, 660 46, 788
+ C 46, 899 123, 947 233, 947
+ C 319, 947 369, 900 391, 869
+ L 393, 869
+ L 393, 935
+ L 481, 935
+ C 479, 920 477, 893 477, 835
+ L 477, 624
+ C 477, 485 418, 413 272, 413
+ C 207, 413 151, 433 104, 461
+ L 109, 541
+ M 383, 737
+ C 383, 813 334, 871 241, 871
+ C 198, 871 146, 842 146, 788
+ C 146, 698 272, 690 323, 690
+ C 343, 690 363, 692 383, 692
+ L 383, 737 " />
+ <!-- 69 (i), advance 278, 0 horiBearing 86,730 -->
+ <path transform="translate(1000,0)" d="
+ M 92, 935
+ L 186, 935
+ L 186, 425
+ L 92, 425
+ L 92, 935
+ M 88, 261
+ A 51, 51 0 1 1 190,261
+ A 51, 51 0 1 1 88,261" />
+ <!-- 72 (r), advance 389, 0 horiBearing 80,522 -->
+ <path transform="translate(1341.5,0)" d="
+ M 80, 935
+ L 174, 935
+ L 174, 703
+ C 174, 575 229, 495 313, 495
+ C 329, 495 348, 497 365, 504
+ L 365, 420
+ C 345, 416 331, 413 303, 413
+ C 249, 413 195, 451 170, 504
+ L 168, 504
+ L 168, 425
+ L 80, 425
+ L 80, 935 " />
+ <!-- 6f (o), advance 611, 0 horiBearing 46,522 -->
+ <path transform="translate(1826,0)" d="
+ M 46, 680
+ C 46, 826 152, 947 306, 947
+ C 459, 947 565, 826 565, 680
+ C 565, 525 461, 413 306, 413
+ C 150, 413 46, 525 46, 680
+ M 146, 680
+ C 146, 583 205, 489 306, 489
+ C 406, 489 465, 583 465, 680
+ C 465, 771 416, 871 306, 871
+ C 195, 871 146, 771 146, 680 " />
+ <!-- bounds: 38, 205 <-> 2232, 947 -->
+ </g> </g>
+ </g>
+
+
+ <!-- scaled by 0.72, shifted around to hit pixel boundaries -->
+ <g id="cairo_text_small" transform="translate(0,-71)">
+ <g transform="scale(0.085,0.085)"> <g transform="translate(-1139,-208.5)">
+ <!-- 63 (c), advance 444, 0 horiBearing 38,522 -->
+ <path transform="translate(-151,0)" d="
+ M 412, 433
+ C 385, 422 336, 413 298, 413
+ C 142, 413 38, 525 38, 680
+ C 38, 826 144, 947 298, 947
+ C 332, 947 377, 944 416, 926
+ L 409, 842
+ C 380, 861 340, 871 308, 871
+ C 187, 871 138, 771 138, 680
+ C 138, 583 197, 489 302, 489
+ C 332, 489 368, 496 404, 511
+ L 412, 433 " />
+ <!-- 61 (a), advance 556, 0 horiBearing 46,522 -->
+ <path transform="translate(261.75,0)" d="
+ M 109, 541
+ C 147, 509 204, 489 257, 489
+ C 351, 489 383, 534 383, 622
+ C 346, 620 320, 620 283, 620
+ C 186, 620 46, 660 46, 788
+ C 46, 899 123, 947 233, 947
+ C 319, 947 369, 900 391, 869
+ L 393, 869
+ L 393, 935
+ L 481, 935
+ C 479, 920 477, 893 477, 835
+ L 477, 624
+ C 477, 485 418, 413 272, 413
+ C 207, 413 151, 433 104, 461
+ L 109, 541
+ M 383, 737
+ C 383, 813 334, 871 241, 871
+ C 198, 871 146, 842 146, 788
+ C 146, 698 272, 690 323, 690
+ C 343, 690 363, 692 383, 692
+ L 383, 737 " />
+ <!-- 69 (i), advance 278, 0 horiBearing 86,730 -->
+ <path transform="translate(764.75)" d="
+ M 92, 935
+ L 186, 935
+ L 186, 425
+ L 92, 425
+ L 92, 935
+ M 88, 261
+ A 51, 51 0 1 1 190,261
+ A 51, 51 0 1 1 88,261" />
+ <!-- 72 (r), advance 389, 0 horiBearing 80,522 -->
+ <path transform="translate(988.5,0)" d="
+ M 80, 935
+ L 174, 935
+ L 174, 703
+ C 174, 575 229, 495 313, 495
+ C 329, 495 348, 497 365, 504
+ L 365, 420
+ C 345, 416 331, 413 303, 413
+ C 249, 413 195, 451 170, 504
+ L 168, 504
+ L 168, 425
+ L 80, 425
+ L 80, 935 " />
+ <!-- 6f (o), advance 611, 0 horiBearing 46,522 -->
+ <path transform="translate(1355.5,0)" d="
+ M 46, 680
+ C 46, 826 152, 947 306, 947
+ C 459, 947 565, 826 565, 680
+ C 565, 525 461, 413 306, 413
+ C 150, 413 46, 525 46, 680
+ M 146, 680
+ C 146, 583 205, 489 306, 489
+ C 406, 489 465, 583 465, 680
+ C 465, 771 416, 871 306, 871
+ C 195, 871 146, 771 146, 680 " />
+ <!-- bounds: 38, 205 <-> 2232, 947 -->
+ </g> </g>
+ </g>
+
+ <g id="cairo_logo_text_small">
+ <!-- The logo on the left, the text 'cairo' on the right -->
+ <use xlink:href="#cairo_logo_bottomleft-centered" transform="translate(0, 78), scale(0.1944)" />
+ <use xlink:href="#cairo_text_small" fill="white" transform="translate(175,82)"/>
+ </g>
+
+ <g id="cairo_logo_with_text">
+ <!-- The logo (scarab and dung), with the text 'cairo' below, the dot of the 'i' positioned between the hind legs of the scarab -->
+ <!-- dimensions: 300x490, centered -->
+ <use xlink:href="#cairo_logo_top-centered" transform="translate(0, -245)" />
+ <use xlink:href="#cairo_text" transform="translate(0, 245)" />
+ </g>
+
+ <g id="cairo_banner">
+ <!-- The logo on the left, the text 'cairo' in the center, and a mirror image of the logo on the right -->
+ <!-- The logos are scaled such that the scarab body nearly matches the height of the text characters (excepting the 'i')
+ and the dung should nearly aligns with the dot of the 'i'. The bottoms of the logos are aligned with the bottom of the text. -->
+ <!-- dimensions: 370x88, centered -->
+ <use xlink:href="#cairo_logo_bottomleft-centered" transform="translate(-180, 40), scale(0.1944)" />
+ <use xlink:href="#cairo_text_small" transform="translate(0, 42)" fill="black" />
+ <use xlink:href="#cairo_logo_bottomleft-centered" transform="translate(180, 40), scale(0.1944), scale(-1, 1)" />
+ </g>
+
+ <g id="freedesktop_org_logo" style="fill:#FFFFFF;stroke:#3B80AE;stroke-width:2.4588;">
+ <g>
+ <path style="stroke:#BABABA;" d="M85.277,40.796c2.058,7.884-2.667,15.942-10.551,17.999L27.143,71.21c-7.884,2.057-15.943-2.667-18-10.552
+ l-7.448-28.55c-2.057-7.884,2.667-15.942,10.551-17.999L59.83,1.695c7.884-2.057,15.942,2.667,17.999,10.551
+ l7.449,28.55z"/>>
+ <path style="fill:#3B80AE;stroke:none;" d="M80.444,39.778c1.749,7.854-1.816,13.621-9.504,15.447l-42.236,11.02c-7.569,2.396-14.089-1.181
+ -15.838-8.836L6.53,33.127c-1.749-8.145,0.709-12.889,9.503-15.447L58.27,6.661
+ c8.144-1.826,14.089,1.363,15.838,8.835l6.336,24.282z"/>>
+ </g>g>
+ <path style="opacity:0.5;fill:none;stroke:#FFFFFF;" d="M45.542,51.793L24.104,31.102l38.1-4.393L45.542,51.793z"/>>
+ <path d="M72.325,28.769c0.405,1.55-0.525,3.136-2.075,3.541l-12.331,3.217c-1.551,0.404-3.137-0.525-3.542-2.076l-2.295-8.801
+ c-0.405-1.551,0.524-3.137,2.076-3.542l12.33-3.217c1.551-0.405,3.137,0.525,3.542,2.076l2.295,8.801z"/>>
+ <path d="M36.51,33.625c0.496,1.9-0.645,3.844-2.545,4.34l-15.112,3.943c-1.901,0.496-3.845-0.644-4.34-2.544l-2.814-10.786
+ c-0.496-1.901,0.644-3.844,2.544-4.34l15.113-3.942c1.901-0.496,3.845,0.643,4.34,2.544l2.814,10.786z"/>>
+ <path d="M52.493,53.208c0.278,1.065-0.36,2.154-1.425,2.432L42.6,57.848c-1.064,0.277-2.153-0.36-2.431-1.426l-1.577-6.043
+ c-0.277-1.064,0.36-2.153,1.425-2.432l8.468-2.209c1.064-0.277,2.154,0.361,2.431,1.426l1.577,6.043z"/>>
+ </g>g>
+ <g id="bullet">
+ <use x="0" y="0" xlink:href="#cairo_logo" transform="translate(-6,-2) scale(0.1, 0.1)"/>>
+ </g>
+ <g id="redhat_logo_horizontal">
+ <!-- 380x125 Red Hat log (horizontal layout) -->
+ <g fill="black" stroke="none"
+ transform="translate(0,124),scale(1,-1),translate(-214,-258)"
+ fill-rule="evenodd"
+ >
+ <!-- r -->
+ <path fill="black" d="
+ M 367.0625 315.3203
+ C 367.0625 320.8765 366.9463 324.9644 366.7227 328.6597
+ L 375.811 328.6597
+ L 376.2002 320.7764
+ L 376.4971 320.7764
+ C 378.5391 326.6221 383.3809 329.5996 387.8594 329.5996
+ C 388.8843 329.5996 389.4824 329.5601 390.3218 329.373
+ L 390.3218 319.4863
+ C 389.3398 319.6763 388.4224 319.7842 387.1592 319.7842
+ C 382.1597 319.7842 378.688 316.6006 377.751 311.8447
+ C 377.5732 310.918 377.4805 309.8086 377.4805 308.6777
+ L 377.4805 287.1504
+ L 366.9766 287.1504
+ L 367.0625 315.3203
+ " />
+
+ <!-- e -->
+ <path fill="black" d="
+ M 402.9927 305.0791
+ C 403.2715 297.5586 409.0918 294.2695 415.814 294.2695
+ C 420.6406 294.2695 424.0942 295.0234 427.2681 296.1924
+ L 428.8232 288.9678
+ C 425.269 287.4629 420.3413 286.3359 414.3149 286.3359
+ C 400.8384 286.3359 392.9409 294.6592 392.9409 307.3809
+ C 392.9409 318.8369 399.8911 329.6772 413.2437 329.6772
+ C 426.7397 329.6772 431.1338 318.5771 431.1338 309.4893
+ C 431.1338 307.5381 430.9624 305.9707 430.7593 305.0059
+ L 402.9927 305.0791
+
+ M 421.2485 312.3926
+ C 421.2954 316.2388 419.6206 322.5088 412.5903 322.5088
+ C 406.1299 322.5088 403.4438 316.645 402.9722 312.3926
+ L 421.2485 312.3926
+ " />
+
+ <!-- d -->
+ <path fill="black" d="
+ M 476.355 344.667
+ L 465.8638 347.5083
+ L 465.8638 324.1914
+ L 465.6904 324.1914
+ C 463.8335 327.2563 459.7407 329.5996 454.0571 329.5996
+ C 444.0762 329.5996 435.3828 321.3374 435.4478 307.4307
+ C 435.4478 294.6719 443.2983 286.2168 453.2119 286.2168
+ C 459.2017 286.2168 464.2114 289.0723 466.6909 293.7217
+ L 466.8779 293.7217
+ L 467.3491 287.1504
+ L 476.6997 287.1504
+ C 476.5083 289.9717 476.355 294.543 476.355 298.792
+ L 476.355 344.667
+
+ M 465.8638 305.1504
+ C 465.8638 304.0479 465.7856 303.0234 465.5454 302.0869
+ C 464.4873 297.5439 460.7734 294.6172 456.4819 294.6172
+ C 449.8721 294.6172 446.0903 300.1885 446.0903 307.8164
+ C 446.0903 315.5166 449.8384 321.4761 456.6016 321.4761
+ C 461.3208 321.4761 464.6992 318.1484 465.6274 314.1064
+ C 465.8071 313.2559 465.8638 312.208 465.8638 311.3711
+ L 465.8638 305.1504
+ " />
+
+ <!-- h -->
+ <path fill="black" d="
+ M 503.7964 329.0176
+ C 500.6836 329.0176 497.8926 328.1187 495.5493 326.6714
+ C 493.1162 325.2461 491.1353 323.0464 489.959 320.7666
+ L 489.7915 320.7666
+ L 489.7915 341.0195
+ L 485.7427 342.1226
+ L 485.7427 287.1504
+ L 489.7915 287.1504
+ L 489.7915 312.1787
+ C 489.7915 313.8408 489.9204 314.9946 490.3462 316.2109
+ C 492.0928 321.3013 496.8896 325.4805 502.689 325.4805
+ C 511.0664 325.4805 513.9673 318.7603 513.9673 311.3906
+ L 513.9673 287.1504
+ L 518.0137 287.1504
+ L 518.0137 311.8359
+ C 518.0137 327.0791 507.6753 329.0176 503.7964 329.0176
+ " />
+
+ <!-- a -->
+ <path fill="black" d="
+ M 554.3413 296.873
+ C 554.3413 293.6357 554.4692 290.2832 554.9375 287.1504
+ L 551.2085 287.1504
+ L 550.6128 293.0156
+ L 550.4209 293.0156
+ C 548.438 289.8594 543.8765 286.2168 537.3726 286.2168
+ C 529.1392 286.2168 525.3057 292.0117 525.3057 297.4688
+ C 525.3057 306.9121 533.6421 312.6064 550.292 312.4321
+ L 550.292 313.5234
+ C 550.292 317.5718 549.5044 325.6475 539.8242 325.5859
+ C 536.2446 325.5859 532.5132 324.6255 529.5513 322.5366
+ L 528.2632 325.4805
+ C 532.0015 328.0137 536.5659 329.0176 540.2705 329.0176
+ C 552.0801 329.0176 554.3413 320.1509 554.3413 312.8379
+ L 554.3413 296.873
+
+ M 550.292 309.0234
+ C 541.3813 309.2813 529.6128 307.9336 529.6128 298.1055
+ C 529.6128 292.2246 533.4946 289.5811 537.7578 289.5811
+ C 544.5796 289.5811 548.4561 293.8018 549.8677 297.7871
+ C 550.1646 298.6621 550.292 299.5371 550.292 300.2402
+ L 550.292 309.0234
+ " />
+
+ <!-- t -->
+ <path fill="black" d="
+ M 570.459 337.0996
+ L 570.459 328.0801
+ L 582.1235 328.0801
+ L 582.1235 324.7959
+ L 570.459 324.7959
+ L 570.459 298.1943
+ C 570.459 292.9912 572.0757 289.7285 576.4692 289.7285
+ C 578.5815 289.7285 580.0757 290.0078 581.1206 290.3711
+ L 581.6099 287.2354
+ C 580.2871 286.6836 578.4302 286.2539 575.9619 286.2539
+ C 572.9741 286.2539 570.4995 287.1934 568.8994 289.1543
+ C 567.0469 291.3057 566.4116 294.7412 566.4116 298.916
+ L 566.4116 324.7959
+ L 559.5059 324.7959
+ L 559.5059 328.0801
+ L 566.4116 328.0801
+ L 566.4116 335.606
+ L 570.459 337.0996
+ " />
+
+ <!-- ® for 'redhat' -->
+ <path fill="black" d="
+ M 335.5 288.9707
+ L 336.0352 288.9707
+ L 336.8408 287.6445
+ L 337.3608 287.6445
+ L 336.4888 288.9937
+ C 336.9404 289.0498 337.2832 289.2881 337.2832 289.834
+ C 337.2832 290.4385 336.9258 290.7051 336.2017 290.7051
+ L 335.0366 290.7051
+ L 335.0366 287.6445
+ L 335.5 287.6445
+ L 335.5 288.9707
+
+ M 335.5 289.3643
+ L 335.5 290.3101
+ L 336.1318 290.3101
+ C 336.4531 290.3101 336.7979 290.2402 336.7979 289.8647
+ C 336.7979 289.3916 336.4492 289.3643 336.0566 289.3643
+ L 335.5 289.3643
+ " />
+
+ <path fill="black" d="
+ M 339.0439 289.1719
+ C 339.0439 287.5176 337.7041 286.1763 336.0493 286.1763
+ C 334.395 286.1763 333.0527 287.5176 333.0527 289.1719
+ C 333.0527 290.8271 334.395 292.1675 336.0493 292.1675
+ C 337.7041 292.1675 339.0439 290.8271 339.0439 289.1719
+
+ M 336.0493 291.6367
+ C 334.6865 291.6367 333.5835 290.5332 333.5835 289.1719
+ C 333.5835 287.8096 334.6865 286.7061 336.0493 286.7061
+ C 337.4082 286.7061 338.5117 287.8096 338.5117 289.1719
+ C 338.5117 290.5332 337.4082 291.6367 336.0493 291.6367
+ " />
+
+ <!-- Black background behind The Shadowman -->
+ <path fill="black" d="
+ M 326.4531 286.208
+ C 324.1177 286.7451 321.6396 287.0801 319.1338 287.0801
+ C 314.8496 287.0801 310.9502 286.3389 308.0732 285.1426
+ C 307.7559 284.9844 307.5303 284.6533 307.5303 284.2764
+ C 307.5303 284.1406 307.5654 283.999 307.6172 283.8838
+ C 307.957 282.8975 307.3984 281.8281 304.6157 281.2158
+ C 300.4883 280.3096 297.8833 276.0527 296.3916 274.6367
+ C 294.6411 272.9756 289.6973 271.9531 290.4404 272.9434
+ C 291.0225 273.7188 293.2485 276.1348 294.6016 278.748
+ C 295.8125 281.083 296.8906 281.7461 298.375 283.9736
+ C 298.811 284.627 300.4995 286.9219 300.9912 288.7373
+ C 301.543 290.5107 301.356 292.7344 301.5679 293.6494
+ C 301.8721 294.9697 303.1182 297.8369 303.2129 299.4531
+ C 303.2666 300.3691 299.3916 298.1494 297.5532 298.1494
+ C 295.7144 298.1494 293.9233 299.248 292.2808 299.3281
+ C 290.248 299.4248 288.9414 297.7607 287.1025 298.0508
+ C 286.0518 298.2178 285.167 299.1426 283.3311 299.2129
+ C 280.7178 299.3086 277.5244 297.7607 271.5264 297.9531
+ C 265.6255 298.1436 260.1753 305.4082 259.4312 306.5635
+ C 258.5605 307.9199 257.4961 307.9199 256.335 306.8555
+ C 255.1738 305.792 253.7432 306.627 253.3359 307.3389
+ C 252.5615 308.6943 250.4927 312.6543 247.2881 313.4824
+ C 242.8564 314.6309 240.6118 311.0283 240.9033 308.1621
+ C 241.1987 305.252 243.0801 304.4375 243.9512 302.8906
+ C 244.8213 301.3428 245.2671 300.3428 246.9053 299.6572
+ C 248.0674 299.1758 248.5 298.458 248.1533 297.5049
+ C 247.8506 296.6738 246.6416 296.4834 245.8477 296.4463
+ C 244.1592 296.3662 242.9756 296.8242 242.1123 297.376
+ C 241.1084 298.0137 240.292 298.9033 239.416 300.4131
+ C 238.4023 302.0781 236.8052 302.8037 234.9453 302.8037
+ C 234.0586 302.8037 233.2295 302.5693 232.4922 302.1895
+ C 229.5771 300.6748 226.1064 299.7744 222.3706 299.7744
+ L 218.1572 299.7734
+ C 216.1064 305.8555 214.9951 312.3682 214.9951 319.1416
+ C 214.9951 352.6064 242.1226 379.7334 275.5859 379.7334
+ C 309.0498 379.7334 336.1758 352.6064 336.1758 319.1416
+ C 336.1758 307 332.6035 295.6895 326.4531 286.208
+ " />
+
+ <!-- The Shadowman's face -->
+ <path fill="white" d="
+ M 326.4531 286.209
+ C 324.1177 286.7461 321.6396 287.084 319.1338 287.084
+ C 314.8496 287.084 310.9502 286.3418 308.0732 285.1436
+ C 307.7559 284.9873 307.5303 284.6553 307.5303 284.2783
+ C 307.5303 284.1416 307.5654 284.001 307.6172 283.8838
+ C 307.957 282.8994 307.3984 281.8311 304.6157 281.2178
+ C 300.4883 280.3115 297.8833 276.0537 296.3916 274.6416
+ C 294.6411 272.9766 289.6973 271.9551 290.4404 272.9463
+ C 291.0225 273.7197 293.2485 276.1367 294.6016 278.749
+ C 295.8125 281.083 296.8906 281.75 298.375 283.9756
+ C 298.811 284.627 300.4995 286.9238 300.9912 288.7402
+ C 301.543 290.5117 301.356 292.7354 301.5679 293.6514
+ C 301.8721 294.9727 303.1182 297.8379 303.2129 299.457
+ C 303.2666 300.3721 299.3916 298.1504 297.5532 298.1504
+ C 295.7144 298.1504 293.9233 299.251 292.2808 299.3301
+ C 290.248 299.4258 288.9414 297.7627 287.1025 298.0518
+ C 286.0518 298.2207 285.167 299.1465 283.3311 299.2148
+ C 280.7178 299.3096 277.5244 297.7627 271.5264 297.9561
+ C 265.6255 298.1475 260.1753 305.4121 259.4312 306.5674
+ C 258.5605 307.9219 257.4961 307.9219 256.335 306.8574
+ C 255.1738 305.7939 253.7432 306.6299 253.3359 307.3438
+ C 252.5615 308.6963 250.4927 312.6553 247.2881 313.4854
+ C 242.8564 314.6338 240.6118 311.0313 240.9033 308.1641
+ C 241.1987 305.2539 243.0801 304.4395 243.9512 302.8926
+ C 244.8213 301.3438 245.2671 300.3457 246.9053 299.6621
+ C 248.0674 299.1768 248.5 298.4609 248.1533 297.5068
+ C 247.8506 296.6768 246.6416 296.4873 245.8477 296.4492
+ C 244.1592 296.3672 242.9756 296.8262 242.1123 297.376
+ C 241.1084 298.0176 240.292 298.9043 239.416 300.416
+ C 238.4023 302.0801 236.8052 302.8086 234.9453 302.8086
+ C 234.0586 302.8086 233.2295 302.5723 232.4922 302.1934
+ C 229.5771 300.6748 226.1064 299.7773 222.3706 299.7773
+ L 218.1572 299.7744
+ C 226.2363 275.8105 248.8965 258.5527 275.5859 258.5527
+ C 296.9063 258.5527 315.6538 269.5635 326.4531 286.209
+ " />
+
+ <!-- nose shadow -->
+ <path fill="black" d="
+ M 288.9307 291.7637
+ C 289.2422 291.46 289.7793 290.4375 289.1226 289.1396
+ C 288.7544 288.4521 288.3579 287.9678 287.6489 287.4023
+ C 286.7969 286.7188 285.1309 285.9307 282.8457 287.3799
+ C 281.6172 288.1592 281.543 288.4209 279.8467 288.2012
+ C 278.6348 288.043 278.1533 289.2656 278.5884 290.2832
+ C 279.0244 291.2969 280.8145 292.1191 283.04 290.8135
+ C 284.041 290.2256 285.6025 288.9844 286.9688 290.084
+ C 287.5356 290.5381 287.875 290.8408 288.6611 291.75
+ C 288.6963 291.7881 288.7461 291.8105 288.8018 291.8105
+ C 288.8516 291.8105 288.8965 291.793 288.9307 291.7637
+ " />
+
+ <!-- The Shadowman's red hat -->
+ <path fill="#cc0000" d="
+ M 309.7769 335.2627
+ C 309.1787 333.251 308.3271 330.6763 304.5391 328.7314
+ C 303.9878 328.4497 303.7764 328.9126 304.0313 329.3477
+ C 305.4629 331.7832 305.7168 332.3921 306.1328 333.3525
+ C 306.7148 334.7568 307.02 336.7549 305.8618 340.9219
+ C 303.5835 349.1221 298.8296 360.083 295.375 363.6392
+ C 292.04 367.0698 285.998 368.0361 280.5371 366.6348
+ C 278.5264 366.1191 274.5918 364.0732 267.2939 365.7168
+ C 254.665 368.5605 252.7939 362.2368 252.0693 359.4824
+ C 251.3438 356.7271 249.6045 348.897 249.6045 348.897
+ C 249.0244 345.7085 248.2646 340.1631 267.874 336.4287
+ C 277.0088 334.6885 277.4736 332.3276 277.8779 330.6289
+ C 278.603 327.585 279.7627 325.8438 281.0674 324.9746
+ C 282.373 324.1035 281.0674 323.3828 279.6187 323.2349
+ C 275.7285 322.8311 261.3491 326.9541 252.8428 331.7881
+ C 245.8828 336.0415 245.7656 339.8721 247.3584 343.1211
+ C 236.8452 344.2573 228.9561 342.1348 227.5254 337.1582
+ C 225.0693 328.6157 246.3047 314.0264 270.4839 306.7061
+ C 295.8579 299.0225 321.9556 304.3857 324.8564 320.335
+ C 326.1738 327.5811 320.0713 332.9419 309.7769 335.2627
+ " />
+
+ <!-- shadow on hat -->
+ <path fill="black" d="
+ M 270.8711 350.8813
+ C 263.8721 350.375 263.145 349.6191 261.834 348.2227
+ C 259.9854 346.2539 257.5508 350.7773 257.5508 350.7773
+ C 256.0898 351.085 254.3179 353.4404 255.2744 355.6411
+ C 256.2158 357.8174 257.9551 357.1641 258.5 356.4868
+ C 259.1626 355.6621 260.5771 354.3125 262.4141 354.3613
+ C 264.251 354.4097 266.3706 354.7959 269.3262 354.7959
+ C 272.3213 354.7959 274.335 353.6777 274.4487 352.7168
+ C 274.5459 351.8965 274.2061 351.1226 270.8711 350.8813
+ " />
+
+ <!-- another shadow on hat -->
+ <path fill="black" d="
+ M 278.2236 362.4463
+ C 278.2129 362.4453 278.2021 362.4438 278.1919 362.4438
+ C 278.084 362.4438 277.9961 362.5273 277.9961 362.6274
+ C 277.9961 362.7007 278.041 362.7646 278.106 362.7939
+ C 279.4629 363.5107 281.4873 364.0811 283.8042 364.3169
+ C 284.499 364.3887 285.1787 364.4248 285.832 364.4307
+ C 285.9478 364.4307 286.0615 364.4297 286.1787 364.4277
+ C 290.062 364.3398 293.1719 362.7974 293.1255 360.9814
+ C 293.0791 359.165 289.8955 357.7637 286.0112 357.8506
+ C 284.7529 357.8794 283.5732 358.0615 282.5576 358.3545
+ C 282.4385 358.3857 282.3506 358.4883 282.3506 358.6094
+ C 282.3506 358.731 282.4385 358.834 282.5605 358.8638
+ C 284.9839 359.4248 286.6191 360.3408 286.5039 361.207
+ C 286.3511 362.3545 283.1816 362.979 279.4248 362.6011
+ C 279.0137 362.5596 278.6118 362.5068 278.2236 362.4463
+ " />
+
+ <!-- ® for The Shadowman -->
+ <path fill="black" d="
+ M 588.3018 288.9707
+ L 588.8369 288.9707
+ L 589.6426 287.6445
+ L 590.1626 287.6445
+ L 589.2905 288.9937
+ C 589.7422 289.0498 590.085 289.2881 590.085 289.834
+ C 590.085 290.4385 589.7275 290.7051 589.0034 290.7051
+ L 587.8384 290.7051
+ L 587.8384 287.6445
+ L 588.3018 287.6445
+ L 588.3018 288.9707
+
+ M 588.3018 289.3643
+ L 588.3018 290.3101
+ L 588.9336 290.3101
+ C 589.2549 290.3101 589.5996 290.2402 589.5996 289.8647
+ C 589.5996 289.3916 589.251 289.3643 588.8584 289.3643
+ L 588.3018 289.3643
+ " />
+
+ <path fill="black" d="
+ M 591.8457 289.1719
+ C 591.8457 287.5176 590.5059 286.1763 588.8511 286.1763
+ C 587.1968 286.1763 585.8545 287.5176 585.8545 289.1719
+ C 585.8545 290.8271 587.1968 292.1675 588.8511 292.1675
+ C 590.5059 292.1675 591.8457 290.8271 591.8457 289.1719
+
+ M 588.8511 291.6367
+ C 587.4883 291.6367 586.3853 290.5332 586.3853 289.1719
+ C 586.3853 287.8096 587.4883 286.7061 588.8511 286.7061
+ C 590.21 286.7061 591.3135 287.8096 591.3135 289.1719
+ C 591.3135 290.5332 590.21 291.6367 588.8511 291.6367
+ " />
+
+ </g>
+ </g>
+
+ </defs>
+
+<g fill="black">
+
+ <g font-family="Frutiger">
+
+ <rect x="0" y="0" width="341" height="768" fill="#162284"/>
+
+ <use xlink:href="#cairo_logo_with_text" fill="white" transform="translate(170, 420)" />
+
+ <use xlink:href="#redhat_logo_horizontal"
+ transform="translate(826,768),scale(.5,.5),translate(0,-125)"/>
+
+ <g id="slide_title" transform="translate(683, 80)">
+ <text text-anchor="middle"
+ fill="black"
+ font-weight="bold"
+ x="0"
+ y="10" font-size="50"
+ ss:variable="presentation">Presentation Title</text>
+ </g>
+
+ <g ss:region="default" text-anchor="middle">
+ <rect x="683" y="270" width="2" height="350" fill="none" stroke="blue"/>
+ <text font-size="40" fill="black"
+ x="683" y="310">Slide content</text>
+ </g>
+ </g>
+
+</g>
+
+</svg>
diff --git a/doc/tutorial/slides/cairo.svg b/doc/tutorial/slides/cairo.svg
new file mode 100644
index 000000000..3d96abc53
--- /dev/null
+++ b/doc/tutorial/slides/cairo.svg
@@ -0,0 +1,898 @@
+<?xml version="1.0" ?>
+<svg width="1024" height="768"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:ss="http://www.svgslides.org/svgslides0.1"
+ fill="black">
+
+
+ <defs id="cairo-artwork_defs">
+ <g id="hacker_emblem">
+ <!-- Note: This is similar though not identical to Keith Packard's SVG version
+ of the hacker emblem (http://www.catb.org/hacker-emblem/glider.svg) -->
+ <g id="hacker_emblem_grid" fill="white" stroke="none">
+ <!-- Outside: Top, Right, Bottom, Left -->
+ <rect x="-2.95" y="-3.05" width="6" height="0.1" />
+ <rect x="2.95" y="-2.95" width="0.1" height="6" />
+ <rect x="-3.05" y="2.95" width="6" height="0.1" />
+ <rect x="-3.05" y="-3.05" width="0.1" height="6" />
+ <!-- Vertical: Left, Right -->
+ <rect x="-1.05" y="-2.95" width="0.1" height="5.9" />
+ <rect x="0.95" y="-2.95" width="0.1" height="5.9" />
+ <!-- Horizontal: TopLeft, TopMiddle, TopRight -->
+ <rect x="-2.95" y="-1.05" width="1.9" height="0.1" />
+ <rect x="-0.95" y="-1.05" width="1.9" height="0.1" />
+ <rect x="1.05" y="-1.05" width="1.9" height="0.1" />
+ <!-- Horizontal: BottomLeft, BottomMiddle, BottomRight -->
+ <rect x="-2.95" y="0.95" width="1.9" height="0.1" />
+ <rect x="-0.95" y="0.95" width="1.9" height="0.1" />
+ <rect x="1.05" y="0.95" width="1.9" height="0.1" />
+ </g>
+ <g id="hacker_emblem_dots" fill="white">
+ <circle cx="0" cy="-2" r="0.7" />
+ <circle cx="2" cy="0" r="0.7" />
+ <circle cx="-2" cy="2" r="0.7" />
+ <circle cx="0" cy="2" r="0.7" />
+ <circle cx="2" cy="2" r="0.7" />
+ </g>
+ </g>
+ <g id="scarab" fill="#f19a14" stroke="none">
+ <g transform="translate(-150, -170)">
+ <path id="scarab_head" d="M205.599,94.567c0-11.668-24.914-21.129-55.628-21.129
+ c-30.723,0-55.624,9.46-55.624,21.129c0,10.203,24.901,7.346,55.624,7.346C180.685,101.913,205.599,104.233,205.599,94.567z"/>
+ <path id="scarab_torso" d="M136.423,161.506c0,0,12.751,12.577,13.547,13.362
+ c2.262-2.232,13.545-13.362,13.545-13.362c7.135-7.036,87.111-6.399,91.066-6.363c-0.469-6.298-1.254-12.472-2.325-18.519
+ c-15.183-19.279-42.811-32.225-74.485-32.225h-55.518c-31.745,0-59.439,13.011-74.598,32.37c-1.054,6-1.829,12.128-2.296,18.374
+ C49.321,155.106,129.288,154.47,136.423,161.506z"/>
+ <path id="scarab_spine" d="M149.97,301.187c2.005-24.729,8.386-103.483,8.405-103.721
+ c-0.09-0.219-6.478-15.578-8.405-20.214c-1.936,4.655-8.316,19.995-8.408,20.214C141.582,197.704,147.965,276.458,149.97,301.187z"/>
+ <path id="scarab_wing_left" d="M140.403,197.149l8.862-21.31l-13.686-13.499
+ c-5.65-5.573-67.074-6.235-90.259-6.019l-0.006-0.622c-0.154,2.144-0.271,4.302-0.35,6.475
+ c-0.076,2.207,10.392,4.706,10.392,6.717c0,2.319-10.457,5.084-10.359,7.631c2.993,73.349,48.53,131.631,104.372,132.048
+ l-9.02-111.29L140.403,197.149z"/>
+ <path id="scarab_wing_right" d="M244.585,168.891c0-2.011,10.467-4.506,10.391-6.715
+ c-0.079-2.174-0.195-4.332-0.351-6.479l-0.004,0.624c-23.186-0.216-84.608,0.445-90.26,6.017l-13.688,13.502l8.915,21.438
+ l-9.017,111.29c55.854-0.417,101.378-58.698,104.373-132.049C255.04,173.976,244.585,171.209,244.585,168.891z"/>
+ <path id="scarab_leg_front_left" d="M44.506,141.12c-4.135-0.856-4.895-1.54-7.935-2.92
+ c-9.59-3.364-10.376-5.481-16.08-11.86c-7.426-8.306-12.661-20.142-17.1-29.463c-3.576-7.525-3.984-16.409-2.86-24.273
+ c0.991-6.935,7.144-12.869,12.074-18.92c5.844-7.191,10.356-14.822,17.924-21.354c7.736-6.682,23.203-9.809,26.168-19.648
+ C57.86,8.819,54.334,1.766,61.482,0c-0.366,4.703,3.639,8.477,2.397,13.575c-1.129,4.627-4.368,5.811-9.611,9.099
+ c-7.564,4.746-18.366,8.779-24.748,13.965c-7.175,5.827-4.369,13.771-10.569,20.057c-2.001,2.03-7.901,4.706-9.137,6.83
+ c-1.861,3.199-0.297,9.572-0.116,13.12c0.425,8.284,5.588,14.244,9.555,22.045c4.152,8.141,6.429,15.409,13.411,22.519
+ c4.183,4.262,11.429,4.802,16.21,10.647l-3.555,4.186L44.506,141.12z"/>
+ <path id="scarab_leg_middle_left" d="M43.94,191.922l-0.809-7.346
+ c-9.506-4.579-10.339-9.772-20.738-12.466c-23.728-6.151-21.361,11.25-15.532,26.373c5.676,14.726,8.237,30.23,14.345,44.795
+ c2.805,6.688,6.919,13.213,14.298,15.127c0.372-8.435-0.917-10.651-6.113-16.919c-4.395-5.293-3.326-12.548-6.072-18.504
+ c-3.581-7.804-4.196-15.646-7.279-23.502c-1.363-3.479-8.33-13.966-6.452-17.861c3.183-6.603,9.178-0.083,12.179,2.077
+ c4.218,3.036,6.467,2.223,11.681,2.898C34.041,186.673,37.005,188.756,43.94,191.922z"/>
+ <path id="scarab_leg_back_left" d="M65.839,257.063l-2.771-4.837
+ c-6.68,8.928-6.993,16.228-10.056,23.347c-5.277,12.263-0.157,28.851,9.854,37.676c6.052,5.375,15.907,9.618,23.122,13.136
+ c10.035,4.892,20.113,11.286,31.336,13.396c2.482,0.466,8.798,1.295,6.693-3.522c-0.975-2.237-8.091-4.591-10.146-5.734
+ c-8.312-4.623-16.377-10.524-24.142-16.176c-9.498-6.862-20.843-11.186-28.311-20.684c-3.054-3.885-3.544-4.922-2.816-9.39
+ c0.693-4.263,1.344-9.174,2.241-13.439C61.855,266.029,63.274,261.378,65.839,257.063z"/>
+ <path id="scarab_leg_front_right" d="M255.487,141.12c4.134-0.856,4.896-1.54,7.936-2.92
+ c9.583-3.364,10.369-5.481,16.071-11.86c7.428-8.306,12.661-20.142,17.115-29.463c3.574-7.525,3.983-16.409,2.86-24.273
+ c-0.992-6.935-7.157-12.869-12.087-18.92c-5.843-7.191-10.356-14.822-17.919-21.354c-7.735-6.682-23.202-9.809-26.167-19.648
+ C242.135,8.819,245.66,1.766,238.511,0c0.366,4.703-3.637,8.477-2.396,13.575c1.131,4.627,4.368,5.811,9.611,9.099
+ c7.563,4.746,18.367,8.779,24.747,13.965c7.17,5.827,4.362,13.771,10.563,20.057c2.001,2.03,7.901,4.706,9.139,6.83
+ c1.859,3.199,0.295,9.572,0.113,13.12c-0.424,8.284-5.588,14.244-9.553,22.045c-4.152,8.141-6.431,15.409-13.404,22.519
+ c-4.184,4.262-11.429,4.802-16.211,10.647l3.556,4.186L255.487,141.12z"/>
+ <path id="scarab_leg_middle_right" d="M256.053,191.922l0.81-7.346
+ c9.507-4.579,10.34-9.772,20.73-12.466c23.741-6.151,21.374,11.25,15.534,26.373c-5.676,14.726-8.238,30.23-14.347,44.795
+ c-2.804,6.688-6.911,13.213-14.291,15.127c-0.371-8.435,0.918-10.651,6.113-16.919c4.39-5.293,3.319-12.548,6.066-18.504
+ c3.58-7.804,4.197-15.646,7.278-23.502c1.363-3.479,8.33-13.966,6.453-17.861c-3.184-6.603-9.179-0.083-12.181,2.077
+ c-4.217,3.036-6.458,2.223-11.672,2.898C265.951,186.673,262.986,188.756,256.053,191.922z"/>
+ <path id="scarab_leg_back_right" d="M234.155,257.063l2.771-4.837
+ c6.679,8.928,6.991,16.228,10.057,23.347c5.274,12.263,0.154,28.851-9.854,37.676c-6.055,5.375-15.903,9.618-23.117,13.136
+ c-10.034,4.892-20.127,11.286-31.351,13.396c-2.481,0.466-8.789,1.295-6.691-3.522c0.976-2.237,8.092-4.591,10.146-5.734
+ c8.312-4.623,16.392-10.524,24.155-16.176c9.498-6.862,20.838-11.186,28.305-20.684c3.055-3.885,3.543-4.922,2.818-9.39
+ c-0.696-4.263-1.346-9.174-2.244-13.439C238.137,266.029,236.718,261.378,234.155,257.063z"/>
+ </g>
+ </g>
+ <radialGradient id="gradient_radial_dung"
+ cx="0" cy="0" r="60"
+ fx="0" fy="0" gradientUnits="userSpaceOnUse"
+ >
+ <stop offset="0" stop-color="#9a9a9a" />
+ <stop offset="0.70" stop-color="#bababa" />
+ <stop offset="0.95" stop-color="#FFFFFF" />
+ </radialGradient>
+ <g id="dung">
+ <circle cx="0" cy="0" r="60" fill="url(#gradient_radial_dung)" />
+ <g transform="translate(-61, -61)">
+ <!-- rough equivalent: <circle cx="0" cy="0" r="60" stroke="#8a8a8a" stroke-width="2" /> -->
+ <path fill="#8a8a8a" d="M0,61c0,33.636,27.364,61,61,61s61-27.364,61-61S94.636,0,61,0S0,27.364,0,61z
+ M2,61C2,28.467,28.467,2,61,2c32.532,0,59,26.467,59,59c0,32.533-26.468,59-59,59C28.467,120,2,93.533,2,61z"/>
+ </g>
+ <use xlink:href="#hacker_emblem" x="0" y="0" transform="scale(9)" />
+ </g>
+ <g id="dung_2_color">
+ <path stroke="none" d="
+M -46, 0
+A 46, 46,
+ 0,
+ 0, 1,
+ 46, 0
+A 46, 46,
+ 0,
+ 0, 1,
+ -46, 0
+M -50, 0
+A 50, 50,
+ 0,
+ 0, 0,
+ 50, 0
+A 50, 50,
+ 0,
+ 0, 0,
+ -50, 0
+Z" />
+ <g transform="scale(9)">
+ <!-- Hacker emblem grid -->
+ <path fill="none" stroke-width="0.2"
+ d="M -3,-3 L 3,-3 L 3,3 L-3,3 Z
+ M -1,-3 L -1, 3
+ M 1,-3 L 1, 3
+ M -3,-1 L 3,-1
+ M -3, 1 L 3, 1"/>
+ <g stroke="none">
+ <!-- Hacker emblem dots -->
+ <circle cx="0" cy="-2" r="0.7" />
+ <circle cx="2" cy="0" r="0.7" />
+ <circle cx="-2" cy="2" r="0.7" />
+ <circle cx="0" cy="2" r="0.7" />
+ <circle cx="2" cy="2" r="0.7" />
+ </g>
+ </g>
+ </g>
+
+ <!-- scarab dimensions: 300x340 -->
+ <!-- dung dimensions: 120x120 (radius: 60) -->
+ <!-- scarab and dung dimensions: 300x400 -->
+
+ <g id="cairo_logo">
+ <!-- dimensions: 300x400, centered -->
+ <!-- The logo (scarab and dung), with the center-point of the bounding box at (0,0) -->
+ <use xlink:href="#dung_2_color" x="0" y="0" transform="translate(0, -140)" />
+ <use xlink:href="#scarab" x="0" y="0" transform="translate(0, 30)" />
+ </g>
+ <g id="cairo_logo_dung-centered">
+ <!-- The logo (scarab and dung), with the dung at (0,0), the scarab below -->
+ <use xlink:href="#dung_2_color" x="0" y="0" />
+ <use xlink:href="#scarab" x="0" y="0" transform="translate(0,170)" />
+ </g>
+ <g id="cairo_logo_scarab-centered">
+ <!-- The logo (scarab and dung), with the scarab's rotational center at (0,0), the dung above -->
+ <!-- The scarab's rotational center in this case is not the center of its bounding box,
+ but is calculated to be the intersection-point of the torso, spine and wings -->
+ <use xlink:href="#dung_2_color" x="0" y="0" transform="translate(0, -175.85)" />
+ <use xlink:href="#scarab" x="0" y="0" transform="translate(0, -5.85)" />
+ </g>
+ <g id="cairo_logo_top-centered">
+ <!-- The logo (scarab and dung), with the top-center point of the bounding box at (0,0) -->
+ <use xlink:href="#dung_2_color" x="0" y="0" transform="translate(0, 60)" />
+ <use xlink:href="#scarab" x="0" y="0" transform="translate(0, 230)" /><!-- (0,170+60) -->
+ </g>
+ <g id="cairo_logo_bottom-centered">
+ <!-- The logo (scarab and dung), with the bottom-center point of the bounding box at (0,0) -->
+ <use xlink:href="#dung_2_color" x="0" y="0" transform="translate(0, -340)" />
+ <use xlink:href="#scarab" x="0" y="0" transform="translate(0, -170)" />
+ </g>
+ <g id="cairo_logo_right-centered">
+ <!-- The logo (scarab and dung), with the right-center point of the bounding box at (0,0) -->
+ <use xlink:href="#dung_2_color" x="0" y="0" transform="translate(-150, -140)" />
+ <use xlink:href="#scarab" x="0" y="0" transform="translate(-150, 30)" />
+ </g>
+ <g id="cairo_logo_left-centered">
+ <!-- The logo (scarab and dung), with the left-center point of the bounding box at (0,0) -->
+ <use xlink:href="#dung_2_color" x="0" y="0" transform="translate(150, -140)" />
+ <use xlink:href="#scarab" x="0" y="0" transform="translate(150, 30)" />
+ </g>
+ <g id="cairo_logo_topleft-centered">
+ <!-- The logo (scarab and dung), with the top-left point of the bounding box at (0,0) -->
+ <use xlink:href="#dung_2_color" x="0" y="0" transform="translate(150, 60)" />
+ <use xlink:href="#scarab" x="0" y="0" transform="translate(150, 230)" /><!-- (150, 170+60) -->
+ </g>
+ <g id="cairo_logo_topright-centered">
+ <!-- The logo (scarab and dung), with the top-right point of the bounding box at (0,0) -->
+ <use xlink:href="#dung_2_color" x="0" y="0" transform="translate(-150, 60)" />
+ <use xlink:href="#scarab" x="0" y="0" transform="translate(-150, 230)" /><!-- (-150,170+60) -->
+ </g>
+ <g id="cairo_logo_bottomleft-centered">
+ <!-- The logo (scarab and dung), with the bottom-left point of the bounding box at (0,0) -->
+ <use xlink:href="#dung_2_color" x="0" y="0" transform="translate(150, -340)" />
+ <use xlink:href="#scarab" x="0" y="0" transform="translate(150, -170)" />
+ </g>
+ <g id="cairo_logo_bottomright-centered">
+ <!-- The logo (scarab and dung), with the bottom-right point of the bounding box at (0,0) -->
+ <use xlink:href="#dung_2_color" x="0" y="0" transform="translate(-150, -340)" />
+ <use xlink:href="#scarab" x="0" y="0" transform="translate(-150, -170)" />
+ </g>
+
+ <g id="cairo_text" transform="translate(0,-97)">
+ <g transform="scale(0.1484,0.1484)"> <g transform="translate(-1139,-208.5)">
+ <!-- 63 (c), advance 444, 0 horiBearing 38,522 -->
+ <path transform="translate(65,0)" d="
+ M 412, 433
+ C 385, 422 336, 413 298, 413
+ C 142, 413 38, 525 38, 680
+ C 38, 826 144, 947 298, 947
+ C 332, 947 377, 944 416, 926
+ L 409, 842
+ C 380, 861 340, 871 308, 871
+ C 187, 871 138, 771 138, 680
+ C 138, 583 197, 489 302, 489
+ C 332, 489 368, 496 404, 511
+ L 412, 433 " />
+ <!-- 61 (a), advance 556, 0 horiBearing 46,522 -->
+ <path transform="translate(486.75,0)" d="
+ M 109, 541
+ C 147, 509 204, 489 257, 489
+ C 351, 489 383, 534 383, 622
+ C 346, 620 320, 620 283, 620
+ C 186, 620 46, 660 46, 788
+ C 46, 899 123, 947 233, 947
+ C 319, 947 369, 900 391, 869
+ L 393, 869
+ L 393, 935
+ L 481, 935
+ C 479, 920 477, 893 477, 835
+ L 477, 624
+ C 477, 485 418, 413 272, 413
+ C 207, 413 151, 433 104, 461
+ L 109, 541
+ M 383, 737
+ C 383, 813 334, 871 241, 871
+ C 198, 871 146, 842 146, 788
+ C 146, 698 272, 690 323, 690
+ C 343, 690 363, 692 383, 692
+ L 383, 737 " />
+ <!-- 69 (i), advance 278, 0 horiBearing 86,730 -->
+ <path transform="translate(1000,0)" d="
+ M 92, 935
+ L 186, 935
+ L 186, 425
+ L 92, 425
+ L 92, 935
+ M 88, 261
+ A 51, 51 0 1 1 190,261
+ A 51, 51 0 1 1 88,261" />
+ <!-- 72 (r), advance 389, 0 horiBearing 80,522 -->
+ <path transform="translate(1234.25,0)" d="
+ M 80, 935
+ L 174, 935
+ L 174, 703
+ C 174, 575 229, 495 313, 495
+ C 329, 495 348, 497 365, 504
+ L 365, 420
+ C 345, 416 331, 413 303, 413
+ C 249, 413 195, 451 170, 504
+ L 168, 504
+ L 168, 425
+ L 80, 425
+ L 80, 935 " />
+ <!-- 6f (o), advance 611, 0 horiBearing 46,522 -->
+ <path transform="translate(1610,0)" d="
+ M 46, 680
+ C 46, 826 152, 947 306, 947
+ C 459, 947 565, 826 565, 680
+ C 565, 525 461, 413 306, 413
+ C 150, 413 46, 525 46, 680
+ M 146, 680
+ C 146, 583 205, 489 306, 489
+ C 406, 489 465, 583 465, 680
+ C 465, 771 416, 871 306, 871
+ C 195, 871 146, 771 146, 680 " />
+ <!-- bounds: 38, 205 <-> 2232, 947 -->
+ </g> </g>
+ </g>
+
+ <!-- scaled by 0.72, shifted around to hit pixel boundaries -->
+ <g id="cairo_text_small_spaced" transform="translate(0,-71)">
+ <g transform="scale(0.085,0.085)"> <g transform="translate(-1139,-208.5)">
+ <!-- 63 (c), advance 444, 0 horiBearing 38,522 -->
+ <path transform="translate(-151,0)" d="
+ M 412, 433
+ C 385, 422 336, 413 298, 413
+ C 142, 413 38, 525 38, 680
+ C 38, 826 144, 947 298, 947
+ C 332, 947 377, 944 416, 926
+ L 409, 842
+ C 380, 861 340, 871 308, 871
+ C 187, 871 138, 771 138, 680
+ C 138, 583 197, 489 302, 489
+ C 332, 489 368, 496 404, 511
+ L 412, 433 " />
+ <!-- 61 (a), advance 556, 0 horiBearing 46,522 -->
+ <path transform="translate(379.5,0)" d="
+ M 109, 541
+ C 147, 509 204, 489 257, 489
+ C 351, 489 383, 534 383, 622
+ C 346, 620 320, 620 283, 620
+ C 186, 620 46, 660 46, 788
+ C 46, 899 123, 947 233, 947
+ C 319, 947 369, 900 391, 869
+ L 393, 869
+ L 393, 935
+ L 481, 935
+ C 479, 920 477, 893 477, 835
+ L 477, 624
+ C 477, 485 418, 413 272, 413
+ C 207, 413 151, 433 104, 461
+ L 109, 541
+ M 383, 737
+ C 383, 813 334, 871 241, 871
+ C 198, 871 146, 842 146, 788
+ C 146, 698 272, 690 323, 690
+ C 343, 690 363, 692 383, 692
+ L 383, 737 " />
+ <!-- 69 (i), advance 278, 0 horiBearing 86,730 -->
+ <path transform="translate(1000,0)" d="
+ M 92, 935
+ L 186, 935
+ L 186, 425
+ L 92, 425
+ L 92, 935
+ M 88, 261
+ A 51, 51 0 1 1 190,261
+ A 51, 51 0 1 1 88,261" />
+ <!-- 72 (r), advance 389, 0 horiBearing 80,522 -->
+ <path transform="translate(1341.5,0)" d="
+ M 80, 935
+ L 174, 935
+ L 174, 703
+ C 174, 575 229, 495 313, 495
+ C 329, 495 348, 497 365, 504
+ L 365, 420
+ C 345, 416 331, 413 303, 413
+ C 249, 413 195, 451 170, 504
+ L 168, 504
+ L 168, 425
+ L 80, 425
+ L 80, 935 " />
+ <!-- 6f (o), advance 611, 0 horiBearing 46,522 -->
+ <path transform="translate(1826,0)" d="
+ M 46, 680
+ C 46, 826 152, 947 306, 947
+ C 459, 947 565, 826 565, 680
+ C 565, 525 461, 413 306, 413
+ C 150, 413 46, 525 46, 680
+ M 146, 680
+ C 146, 583 205, 489 306, 489
+ C 406, 489 465, 583 465, 680
+ C 465, 771 416, 871 306, 871
+ C 195, 871 146, 771 146, 680 " />
+ <!-- bounds: 38, 205 <-> 2232, 947 -->
+ </g> </g>
+ </g>
+
+
+ <!-- scaled by 0.72, shifted around to hit pixel boundaries -->
+ <g id="cairo_text_small" transform="translate(0,-71)">
+ <g transform="scale(0.085,0.085)"> <g transform="translate(-1139,-208.5)">
+ <!-- 63 (c), advance 444, 0 horiBearing 38,522 -->
+ <path transform="translate(-151,0)" d="
+ M 412, 433
+ C 385, 422 336, 413 298, 413
+ C 142, 413 38, 525 38, 680
+ C 38, 826 144, 947 298, 947
+ C 332, 947 377, 944 416, 926
+ L 409, 842
+ C 380, 861 340, 871 308, 871
+ C 187, 871 138, 771 138, 680
+ C 138, 583 197, 489 302, 489
+ C 332, 489 368, 496 404, 511
+ L 412, 433 " />
+ <!-- 61 (a), advance 556, 0 horiBearing 46,522 -->
+ <path transform="translate(261.75,0)" d="
+ M 109, 541
+ C 147, 509 204, 489 257, 489
+ C 351, 489 383, 534 383, 622
+ C 346, 620 320, 620 283, 620
+ C 186, 620 46, 660 46, 788
+ C 46, 899 123, 947 233, 947
+ C 319, 947 369, 900 391, 869
+ L 393, 869
+ L 393, 935
+ L 481, 935
+ C 479, 920 477, 893 477, 835
+ L 477, 624
+ C 477, 485 418, 413 272, 413
+ C 207, 413 151, 433 104, 461
+ L 109, 541
+ M 383, 737
+ C 383, 813 334, 871 241, 871
+ C 198, 871 146, 842 146, 788
+ C 146, 698 272, 690 323, 690
+ C 343, 690 363, 692 383, 692
+ L 383, 737 " />
+ <!-- 69 (i), advance 278, 0 horiBearing 86,730 -->
+ <path transform="translate(764.75)" d="
+ M 92, 935
+ L 186, 935
+ L 186, 425
+ L 92, 425
+ L 92, 935
+ M 88, 261
+ A 51, 51 0 1 1 190,261
+ A 51, 51 0 1 1 88,261" />
+ <!-- 72 (r), advance 389, 0 horiBearing 80,522 -->
+ <path transform="translate(988.5,0)" d="
+ M 80, 935
+ L 174, 935
+ L 174, 703
+ C 174, 575 229, 495 313, 495
+ C 329, 495 348, 497 365, 504
+ L 365, 420
+ C 345, 416 331, 413 303, 413
+ C 249, 413 195, 451 170, 504
+ L 168, 504
+ L 168, 425
+ L 80, 425
+ L 80, 935 " />
+ <!-- 6f (o), advance 611, 0 horiBearing 46,522 -->
+ <path transform="translate(1355.5,0)" d="
+ M 46, 680
+ C 46, 826 152, 947 306, 947
+ C 459, 947 565, 826 565, 680
+ C 565, 525 461, 413 306, 413
+ C 150, 413 46, 525 46, 680
+ M 146, 680
+ C 146, 583 205, 489 306, 489
+ C 406, 489 465, 583 465, 680
+ C 465, 771 416, 871 306, 871
+ C 195, 871 146, 771 146, 680 " />
+ <!-- bounds: 38, 205 <-> 2232, 947 -->
+ </g> </g>
+ </g>
+
+ <g id="cairo_logo_text_small">
+ <!-- The logo on the left, the text 'cairo' on the right -->
+ <use xlink:href="#cairo_logo_bottomleft-centered" transform="translate(0, 78), scale(0.1944)" />
+ <use xlink:href="#cairo_text_small" fill="white" transform="translate(175,82)"/>
+ </g>
+
+ <g id="cairo_logo_with_text">
+ <!-- The logo (scarab and dung), with the text 'cairo' below, the dot of the 'i' positioned between the hind legs of the scarab -->
+ <!-- dimensions: 300x490, centered -->
+ <use xlink:href="#cairo_logo_top-centered" transform="translate(0, -245)" />
+ <use xlink:href="#cairo_text" transform="translate(0, 245)" />
+ </g>
+
+ <g id="cairo_banner">
+ <!-- The logo on the left, the text 'cairo' in the center, and a mirror image of the logo on the right -->
+ <!-- The logos are scaled such that the scarab body nearly matches the height of the text characters (excepting the 'i')
+ and the dung should nearly aligns with the dot of the 'i'. The bottoms of the logos are aligned with the bottom of the text. -->
+ <!-- dimensions: 370x88, centered -->
+ <use xlink:href="#cairo_logo_bottomleft-centered" transform="translate(-180, 40), scale(0.1944)" />
+ <use xlink:href="#cairo_text_small" transform="translate(0, 42)" fill="black" />
+ <use xlink:href="#cairo_logo_bottomleft-centered" transform="translate(180, 40), scale(0.1944), scale(-1, 1)" />
+ </g>
+
+ <g id="freedesktop_org_logo" style="fill:#FFFFFF;stroke:#3B80AE;stroke-width:2.4588;">
+ <g>
+ <path style="stroke:#BABABA;" d="M85.277,40.796c2.058,7.884-2.667,15.942-10.551,17.999L27.143,71.21c-7.884,2.057-15.943-2.667-18-10.552
+ l-7.448-28.55c-2.057-7.884,2.667-15.942,10.551-17.999L59.83,1.695c7.884-2.057,15.942,2.667,17.999,10.551
+ l7.449,28.55z"/>>
+ <path style="fill:#3B80AE;stroke:none;" d="M80.444,39.778c1.749,7.854-1.816,13.621-9.504,15.447l-42.236,11.02c-7.569,2.396-14.089-1.181
+ -15.838-8.836L6.53,33.127c-1.749-8.145,0.709-12.889,9.503-15.447L58.27,6.661
+ c8.144-1.826,14.089,1.363,15.838,8.835l6.336,24.282z"/>>
+ </g>g>
+ <path style="opacity:0.5;fill:none;stroke:#FFFFFF;" d="M45.542,51.793L24.104,31.102l38.1-4.393L45.542,51.793z"/>>
+ <path d="M72.325,28.769c0.405,1.55-0.525,3.136-2.075,3.541l-12.331,3.217c-1.551,0.404-3.137-0.525-3.542-2.076l-2.295-8.801
+ c-0.405-1.551,0.524-3.137,2.076-3.542l12.33-3.217c1.551-0.405,3.137,0.525,3.542,2.076l2.295,8.801z"/>>
+ <path d="M36.51,33.625c0.496,1.9-0.645,3.844-2.545,4.34l-15.112,3.943c-1.901,0.496-3.845-0.644-4.34-2.544l-2.814-10.786
+ c-0.496-1.901,0.644-3.844,2.544-4.34l15.113-3.942c1.901-0.496,3.845,0.643,4.34,2.544l2.814,10.786z"/>>
+ <path d="M52.493,53.208c0.278,1.065-0.36,2.154-1.425,2.432L42.6,57.848c-1.064,0.277-2.153-0.36-2.431-1.426l-1.577-6.043
+ c-0.277-1.064,0.36-2.153,1.425-2.432l8.468-2.209c1.064-0.277,2.154,0.361,2.431,1.426l1.577,6.043z"/>>
+ </g>g>
+ <g id="bullet">
+ <use x="0" y="0" xlink:href="#cairo_logo" transform="translate(-6,-2) scale(0.1, 0.1)"/>>
+ </g>
+ <g id="redhat_logo_horizontal">
+ <!-- 380x125 Red Hat log (horizontal layout) -->
+ <g fill="black" stroke="none"
+ transform="translate(0,124),scale(1,-1),translate(-214,-258)"
+ fill-rule="evenodd"
+ >
+ <!-- r -->
+ <path fill="black" d="
+ M 367.0625 315.3203
+ C 367.0625 320.8765 366.9463 324.9644 366.7227 328.6597
+ L 375.811 328.6597
+ L 376.2002 320.7764
+ L 376.4971 320.7764
+ C 378.5391 326.6221 383.3809 329.5996 387.8594 329.5996
+ C 388.8843 329.5996 389.4824 329.5601 390.3218 329.373
+ L 390.3218 319.4863
+ C 389.3398 319.6763 388.4224 319.7842 387.1592 319.7842
+ C 382.1597 319.7842 378.688 316.6006 377.751 311.8447
+ C 377.5732 310.918 377.4805 309.8086 377.4805 308.6777
+ L 377.4805 287.1504
+ L 366.9766 287.1504
+ L 367.0625 315.3203
+ " />
+
+ <!-- e -->
+ <path fill="black" d="
+ M 402.9927 305.0791
+ C 403.2715 297.5586 409.0918 294.2695 415.814 294.2695
+ C 420.6406 294.2695 424.0942 295.0234 427.2681 296.1924
+ L 428.8232 288.9678
+ C 425.269 287.4629 420.3413 286.3359 414.3149 286.3359
+ C 400.8384 286.3359 392.9409 294.6592 392.9409 307.3809
+ C 392.9409 318.8369 399.8911 329.6772 413.2437 329.6772
+ C 426.7397 329.6772 431.1338 318.5771 431.1338 309.4893
+ C 431.1338 307.5381 430.9624 305.9707 430.7593 305.0059
+ L 402.9927 305.0791
+
+ M 421.2485 312.3926
+ C 421.2954 316.2388 419.6206 322.5088 412.5903 322.5088
+ C 406.1299 322.5088 403.4438 316.645 402.9722 312.3926
+ L 421.2485 312.3926
+ " />
+
+ <!-- d -->
+ <path fill="black" d="
+ M 476.355 344.667
+ L 465.8638 347.5083
+ L 465.8638 324.1914
+ L 465.6904 324.1914
+ C 463.8335 327.2563 459.7407 329.5996 454.0571 329.5996
+ C 444.0762 329.5996 435.3828 321.3374 435.4478 307.4307
+ C 435.4478 294.6719 443.2983 286.2168 453.2119 286.2168
+ C 459.2017 286.2168 464.2114 289.0723 466.6909 293.7217
+ L 466.8779 293.7217
+ L 467.3491 287.1504
+ L 476.6997 287.1504
+ C 476.5083 289.9717 476.355 294.543 476.355 298.792
+ L 476.355 344.667
+
+ M 465.8638 305.1504
+ C 465.8638 304.0479 465.7856 303.0234 465.5454 302.0869
+ C 464.4873 297.5439 460.7734 294.6172 456.4819 294.6172
+ C 449.8721 294.6172 446.0903 300.1885 446.0903 307.8164
+ C 446.0903 315.5166 449.8384 321.4761 456.6016 321.4761
+ C 461.3208 321.4761 464.6992 318.1484 465.6274 314.1064
+ C 465.8071 313.2559 465.8638 312.208 465.8638 311.3711
+ L 465.8638 305.1504
+ " />
+
+ <!-- h -->
+ <path fill="black" d="
+ M 503.7964 329.0176
+ C 500.6836 329.0176 497.8926 328.1187 495.5493 326.6714
+ C 493.1162 325.2461 491.1353 323.0464 489.959 320.7666
+ L 489.7915 320.7666
+ L 489.7915 341.0195
+ L 485.7427 342.1226
+ L 485.7427 287.1504
+ L 489.7915 287.1504
+ L 489.7915 312.1787
+ C 489.7915 313.8408 489.9204 314.9946 490.3462 316.2109
+ C 492.0928 321.3013 496.8896 325.4805 502.689 325.4805
+ C 511.0664 325.4805 513.9673 318.7603 513.9673 311.3906
+ L 513.9673 287.1504
+ L 518.0137 287.1504
+ L 518.0137 311.8359
+ C 518.0137 327.0791 507.6753 329.0176 503.7964 329.0176
+ " />
+
+ <!-- a -->
+ <path fill="black" d="
+ M 554.3413 296.873
+ C 554.3413 293.6357 554.4692 290.2832 554.9375 287.1504
+ L 551.2085 287.1504
+ L 550.6128 293.0156
+ L 550.4209 293.0156
+ C 548.438 289.8594 543.8765 286.2168 537.3726 286.2168
+ C 529.1392 286.2168 525.3057 292.0117 525.3057 297.4688
+ C 525.3057 306.9121 533.6421 312.6064 550.292 312.4321
+ L 550.292 313.5234
+ C 550.292 317.5718 549.5044 325.6475 539.8242 325.5859
+ C 536.2446 325.5859 532.5132 324.6255 529.5513 322.5366
+ L 528.2632 325.4805
+ C 532.0015 328.0137 536.5659 329.0176 540.2705 329.0176
+ C 552.0801 329.0176 554.3413 320.1509 554.3413 312.8379
+ L 554.3413 296.873
+
+ M 550.292 309.0234
+ C 541.3813 309.2813 529.6128 307.9336 529.6128 298.1055
+ C 529.6128 292.2246 533.4946 289.5811 537.7578 289.5811
+ C 544.5796 289.5811 548.4561 293.8018 549.8677 297.7871
+ C 550.1646 298.6621 550.292 299.5371 550.292 300.2402
+ L 550.292 309.0234
+ " />
+
+ <!-- t -->
+ <path fill="black" d="
+ M 570.459 337.0996
+ L 570.459 328.0801
+ L 582.1235 328.0801
+ L 582.1235 324.7959
+ L 570.459 324.7959
+ L 570.459 298.1943
+ C 570.459 292.9912 572.0757 289.7285 576.4692 289.7285
+ C 578.5815 289.7285 580.0757 290.0078 581.1206 290.3711
+ L 581.6099 287.2354
+ C 580.2871 286.6836 578.4302 286.2539 575.9619 286.2539
+ C 572.9741 286.2539 570.4995 287.1934 568.8994 289.1543
+ C 567.0469 291.3057 566.4116 294.7412 566.4116 298.916
+ L 566.4116 324.7959
+ L 559.5059 324.7959
+ L 559.5059 328.0801
+ L 566.4116 328.0801
+ L 566.4116 335.606
+ L 570.459 337.0996
+ " />
+
+ <!-- ® for 'redhat' -->
+ <path fill="black" d="
+ M 335.5 288.9707
+ L 336.0352 288.9707
+ L 336.8408 287.6445
+ L 337.3608 287.6445
+ L 336.4888 288.9937
+ C 336.9404 289.0498 337.2832 289.2881 337.2832 289.834
+ C 337.2832 290.4385 336.9258 290.7051 336.2017 290.7051
+ L 335.0366 290.7051
+ L 335.0366 287.6445
+ L 335.5 287.6445
+ L 335.5 288.9707
+
+ M 335.5 289.3643
+ L 335.5 290.3101
+ L 336.1318 290.3101
+ C 336.4531 290.3101 336.7979 290.2402 336.7979 289.8647
+ C 336.7979 289.3916 336.4492 289.3643 336.0566 289.3643
+ L 335.5 289.3643
+ " />
+
+ <path fill="black" d="
+ M 339.0439 289.1719
+ C 339.0439 287.5176 337.7041 286.1763 336.0493 286.1763
+ C 334.395 286.1763 333.0527 287.5176 333.0527 289.1719
+ C 333.0527 290.8271 334.395 292.1675 336.0493 292.1675
+ C 337.7041 292.1675 339.0439 290.8271 339.0439 289.1719
+
+ M 336.0493 291.6367
+ C 334.6865 291.6367 333.5835 290.5332 333.5835 289.1719
+ C 333.5835 287.8096 334.6865 286.7061 336.0493 286.7061
+ C 337.4082 286.7061 338.5117 287.8096 338.5117 289.1719
+ C 338.5117 290.5332 337.4082 291.6367 336.0493 291.6367
+ " />
+
+ <!-- Black background behind The Shadowman -->
+ <path fill="black" d="
+ M 326.4531 286.208
+ C 324.1177 286.7451 321.6396 287.0801 319.1338 287.0801
+ C 314.8496 287.0801 310.9502 286.3389 308.0732 285.1426
+ C 307.7559 284.9844 307.5303 284.6533 307.5303 284.2764
+ C 307.5303 284.1406 307.5654 283.999 307.6172 283.8838
+ C 307.957 282.8975 307.3984 281.8281 304.6157 281.2158
+ C 300.4883 280.3096 297.8833 276.0527 296.3916 274.6367
+ C 294.6411 272.9756 289.6973 271.9531 290.4404 272.9434
+ C 291.0225 273.7188 293.2485 276.1348 294.6016 278.748
+ C 295.8125 281.083 296.8906 281.7461 298.375 283.9736
+ C 298.811 284.627 300.4995 286.9219 300.9912 288.7373
+ C 301.543 290.5107 301.356 292.7344 301.5679 293.6494
+ C 301.8721 294.9697 303.1182 297.8369 303.2129 299.4531
+ C 303.2666 300.3691 299.3916 298.1494 297.5532 298.1494
+ C 295.7144 298.1494 293.9233 299.248 292.2808 299.3281
+ C 290.248 299.4248 288.9414 297.7607 287.1025 298.0508
+ C 286.0518 298.2178 285.167 299.1426 283.3311 299.2129
+ C 280.7178 299.3086 277.5244 297.7607 271.5264 297.9531
+ C 265.6255 298.1436 260.1753 305.4082 259.4312 306.5635
+ C 258.5605 307.9199 257.4961 307.9199 256.335 306.8555
+ C 255.1738 305.792 253.7432 306.627 253.3359 307.3389
+ C 252.5615 308.6943 250.4927 312.6543 247.2881 313.4824
+ C 242.8564 314.6309 240.6118 311.0283 240.9033 308.1621
+ C 241.1987 305.252 243.0801 304.4375 243.9512 302.8906
+ C 244.8213 301.3428 245.2671 300.3428 246.9053 299.6572
+ C 248.0674 299.1758 248.5 298.458 248.1533 297.5049
+ C 247.8506 296.6738 246.6416 296.4834 245.8477 296.4463
+ C 244.1592 296.3662 242.9756 296.8242 242.1123 297.376
+ C 241.1084 298.0137 240.292 298.9033 239.416 300.4131
+ C 238.4023 302.0781 236.8052 302.8037 234.9453 302.8037
+ C 234.0586 302.8037 233.2295 302.5693 232.4922 302.1895
+ C 229.5771 300.6748 226.1064 299.7744 222.3706 299.7744
+ L 218.1572 299.7734
+ C 216.1064 305.8555 214.9951 312.3682 214.9951 319.1416
+ C 214.9951 352.6064 242.1226 379.7334 275.5859 379.7334
+ C 309.0498 379.7334 336.1758 352.6064 336.1758 319.1416
+ C 336.1758 307 332.6035 295.6895 326.4531 286.208
+ " />
+
+ <!-- The Shadowman's face -->
+ <path fill="white" d="
+ M 326.4531 286.209
+ C 324.1177 286.7461 321.6396 287.084 319.1338 287.084
+ C 314.8496 287.084 310.9502 286.3418 308.0732 285.1436
+ C 307.7559 284.9873 307.5303 284.6553 307.5303 284.2783
+ C 307.5303 284.1416 307.5654 284.001 307.6172 283.8838
+ C 307.957 282.8994 307.3984 281.8311 304.6157 281.2178
+ C 300.4883 280.3115 297.8833 276.0537 296.3916 274.6416
+ C 294.6411 272.9766 289.6973 271.9551 290.4404 272.9463
+ C 291.0225 273.7197 293.2485 276.1367 294.6016 278.749
+ C 295.8125 281.083 296.8906 281.75 298.375 283.9756
+ C 298.811 284.627 300.4995 286.9238 300.9912 288.7402
+ C 301.543 290.5117 301.356 292.7354 301.5679 293.6514
+ C 301.8721 294.9727 303.1182 297.8379 303.2129 299.457
+ C 303.2666 300.3721 299.3916 298.1504 297.5532 298.1504
+ C 295.7144 298.1504 293.9233 299.251 292.2808 299.3301
+ C 290.248 299.4258 288.9414 297.7627 287.1025 298.0518
+ C 286.0518 298.2207 285.167 299.1465 283.3311 299.2148
+ C 280.7178 299.3096 277.5244 297.7627 271.5264 297.9561
+ C 265.6255 298.1475 260.1753 305.4121 259.4312 306.5674
+ C 258.5605 307.9219 257.4961 307.9219 256.335 306.8574
+ C 255.1738 305.7939 253.7432 306.6299 253.3359 307.3438
+ C 252.5615 308.6963 250.4927 312.6553 247.2881 313.4854
+ C 242.8564 314.6338 240.6118 311.0313 240.9033 308.1641
+ C 241.1987 305.2539 243.0801 304.4395 243.9512 302.8926
+ C 244.8213 301.3438 245.2671 300.3457 246.9053 299.6621
+ C 248.0674 299.1768 248.5 298.4609 248.1533 297.5068
+ C 247.8506 296.6768 246.6416 296.4873 245.8477 296.4492
+ C 244.1592 296.3672 242.9756 296.8262 242.1123 297.376
+ C 241.1084 298.0176 240.292 298.9043 239.416 300.416
+ C 238.4023 302.0801 236.8052 302.8086 234.9453 302.8086
+ C 234.0586 302.8086 233.2295 302.5723 232.4922 302.1934
+ C 229.5771 300.6748 226.1064 299.7773 222.3706 299.7773
+ L 218.1572 299.7744
+ C 226.2363 275.8105 248.8965 258.5527 275.5859 258.5527
+ C 296.9063 258.5527 315.6538 269.5635 326.4531 286.209
+ " />
+
+ <!-- nose shadow -->
+ <path fill="black" d="
+ M 288.9307 291.7637
+ C 289.2422 291.46 289.7793 290.4375 289.1226 289.1396
+ C 288.7544 288.4521 288.3579 287.9678 287.6489 287.4023
+ C 286.7969 286.7188 285.1309 285.9307 282.8457 287.3799
+ C 281.6172 288.1592 281.543 288.4209 279.8467 288.2012
+ C 278.6348 288.043 278.1533 289.2656 278.5884 290.2832
+ C 279.0244 291.2969 280.8145 292.1191 283.04 290.8135
+ C 284.041 290.2256 285.6025 288.9844 286.9688 290.084
+ C 287.5356 290.5381 287.875 290.8408 288.6611 291.75
+ C 288.6963 291.7881 288.7461 291.8105 288.8018 291.8105
+ C 288.8516 291.8105 288.8965 291.793 288.9307 291.7637
+ " />
+
+ <!-- The Shadowman's red hat -->
+ <path fill="#cc0000" d="
+ M 309.7769 335.2627
+ C 309.1787 333.251 308.3271 330.6763 304.5391 328.7314
+ C 303.9878 328.4497 303.7764 328.9126 304.0313 329.3477
+ C 305.4629 331.7832 305.7168 332.3921 306.1328 333.3525
+ C 306.7148 334.7568 307.02 336.7549 305.8618 340.9219
+ C 303.5835 349.1221 298.8296 360.083 295.375 363.6392
+ C 292.04 367.0698 285.998 368.0361 280.5371 366.6348
+ C 278.5264 366.1191 274.5918 364.0732 267.2939 365.7168
+ C 254.665 368.5605 252.7939 362.2368 252.0693 359.4824
+ C 251.3438 356.7271 249.6045 348.897 249.6045 348.897
+ C 249.0244 345.7085 248.2646 340.1631 267.874 336.4287
+ C 277.0088 334.6885 277.4736 332.3276 277.8779 330.6289
+ C 278.603 327.585 279.7627 325.8438 281.0674 324.9746
+ C 282.373 324.1035 281.0674 323.3828 279.6187 323.2349
+ C 275.7285 322.8311 261.3491 326.9541 252.8428 331.7881
+ C 245.8828 336.0415 245.7656 339.8721 247.3584 343.1211
+ C 236.8452 344.2573 228.9561 342.1348 227.5254 337.1582
+ C 225.0693 328.6157 246.3047 314.0264 270.4839 306.7061
+ C 295.8579 299.0225 321.9556 304.3857 324.8564 320.335
+ C 326.1738 327.5811 320.0713 332.9419 309.7769 335.2627
+ " />
+
+ <!-- shadow on hat -->
+ <path fill="black" d="
+ M 270.8711 350.8813
+ C 263.8721 350.375 263.145 349.6191 261.834 348.2227
+ C 259.9854 346.2539 257.5508 350.7773 257.5508 350.7773
+ C 256.0898 351.085 254.3179 353.4404 255.2744 355.6411
+ C 256.2158 357.8174 257.9551 357.1641 258.5 356.4868
+ C 259.1626 355.6621 260.5771 354.3125 262.4141 354.3613
+ C 264.251 354.4097 266.3706 354.7959 269.3262 354.7959
+ C 272.3213 354.7959 274.335 353.6777 274.4487 352.7168
+ C 274.5459 351.8965 274.2061 351.1226 270.8711 350.8813
+ " />
+
+ <!-- another shadow on hat -->
+ <path fill="black" d="
+ M 278.2236 362.4463
+ C 278.2129 362.4453 278.2021 362.4438 278.1919 362.4438
+ C 278.084 362.4438 277.9961 362.5273 277.9961 362.6274
+ C 277.9961 362.7007 278.041 362.7646 278.106 362.7939
+ C 279.4629 363.5107 281.4873 364.0811 283.8042 364.3169
+ C 284.499 364.3887 285.1787 364.4248 285.832 364.4307
+ C 285.9478 364.4307 286.0615 364.4297 286.1787 364.4277
+ C 290.062 364.3398 293.1719 362.7974 293.1255 360.9814
+ C 293.0791 359.165 289.8955 357.7637 286.0112 357.8506
+ C 284.7529 357.8794 283.5732 358.0615 282.5576 358.3545
+ C 282.4385 358.3857 282.3506 358.4883 282.3506 358.6094
+ C 282.3506 358.731 282.4385 358.834 282.5605 358.8638
+ C 284.9839 359.4248 286.6191 360.3408 286.5039 361.207
+ C 286.3511 362.3545 283.1816 362.979 279.4248 362.6011
+ C 279.0137 362.5596 278.6118 362.5068 278.2236 362.4463
+ " />
+
+ <!-- ® for The Shadowman -->
+ <path fill="black" d="
+ M 588.3018 288.9707
+ L 588.8369 288.9707
+ L 589.6426 287.6445
+ L 590.1626 287.6445
+ L 589.2905 288.9937
+ C 589.7422 289.0498 590.085 289.2881 590.085 289.834
+ C 590.085 290.4385 589.7275 290.7051 589.0034 290.7051
+ L 587.8384 290.7051
+ L 587.8384 287.6445
+ L 588.3018 287.6445
+ L 588.3018 288.9707
+
+ M 588.3018 289.3643
+ L 588.3018 290.3101
+ L 588.9336 290.3101
+ C 589.2549 290.3101 589.5996 290.2402 589.5996 289.8647
+ C 589.5996 289.3916 589.251 289.3643 588.8584 289.3643
+ L 588.3018 289.3643
+ " />
+
+ <path fill="black" d="
+ M 591.8457 289.1719
+ C 591.8457 287.5176 590.5059 286.1763 588.8511 286.1763
+ C 587.1968 286.1763 585.8545 287.5176 585.8545 289.1719
+ C 585.8545 290.8271 587.1968 292.1675 588.8511 292.1675
+ C 590.5059 292.1675 591.8457 290.8271 591.8457 289.1719
+
+ M 588.8511 291.6367
+ C 587.4883 291.6367 586.3853 290.5332 586.3853 289.1719
+ C 586.3853 287.8096 587.4883 286.7061 588.8511 286.7061
+ C 590.21 286.7061 591.3135 287.8096 591.3135 289.1719
+ C 591.3135 290.5332 590.21 291.6367 588.8511 291.6367
+ " />
+
+ </g>
+ </g>
+
+ </defs>
+
+ <g id="watermark" transform="translate(200, 185), rotate(-50), scale(2.5)">
+ <use xlink:href="#scarab" x="0" y="170" fill-opacity="0.2"/>
+ </g>
+
+ <!-- Blue bar at top of slide -->
+ <rect x="0" y="0" width="1024" height="170" fill="#162284" />
+
+ <!-- Scarab and "cairo" at upper-left -->
+ <g transform="translate(10,0)">
+ <use stroke="none" fill="white" xlink:href="#cairo_logo_text_small"/>
+ </g>
+
+ <!-- Presentation title at upper-right -->
+ <text ss:variable="presentation-subtitle" text-anchor="end"
+ fill="white" x="1016" y="28" font-size="20">Presentation Sub-title</text>
+
+ <!-- Red Hat logo at lower-left -->
+ <use xlink:href="#redhat_logo_horizontal" transform="translate(8,768),scale(.5,.5),translate(0, -125)" />
+
+ <g font-family="Frutiger">
+ <!-- Slide title -->
+ <g id="slide_title" transform="translate(512, 133)">
+ <text text-anchor="middle"
+ fill="white"
+ font-weight="bold"
+ x="0"
+ y="4" font-size="55"
+ ss:variable="title">Really long slide title so you can see</text>
+ </g>
+
+ <!-- Slide content -->
+ <g ss:region="default">
+ <rect x="112" y="200" width="800" height="480" fill="none" stroke="blue"/>
+ <text font-size="40" fill="black"
+ x="112" y="232">Slide content</text>
+ </g>
+
+ <!-- Footer -->
+ <text ss:variable="URL" x="1016" y="753" text-anchor="end" font-size="20">http://cairographics.org</text>
+ </g>
+
+</svg>
diff --git a/doc/tutorial/slides/circle-cairo-large.png b/doc/tutorial/slides/circle-cairo-large.png
new file mode 100644
index 000000000..a08e1193a
--- /dev/null
+++ b/doc/tutorial/slides/circle-cairo-large.png
Binary files differ
diff --git a/doc/tutorial/slides/circle-cairo.png b/doc/tutorial/slides/circle-cairo.png
new file mode 100644
index 000000000..f5d8cd438
--- /dev/null
+++ b/doc/tutorial/slides/circle-cairo.png
Binary files differ
diff --git a/doc/tutorial/slides/circle-ooo-large.png b/doc/tutorial/slides/circle-ooo-large.png
new file mode 100644
index 000000000..dfa40997f
--- /dev/null
+++ b/doc/tutorial/slides/circle-ooo-large.png
Binary files differ
diff --git a/doc/tutorial/slides/circle-ooo.png b/doc/tutorial/slides/circle-ooo.png
new file mode 100644
index 000000000..eb90666e6
--- /dev/null
+++ b/doc/tutorial/slides/circle-ooo.png
Binary files differ
diff --git a/doc/tutorial/slides/expander-fuzzy-large.png b/doc/tutorial/slides/expander-fuzzy-large.png
new file mode 100644
index 000000000..3a485da6a
--- /dev/null
+++ b/doc/tutorial/slides/expander-fuzzy-large.png
Binary files differ
diff --git a/doc/tutorial/slides/expander-fuzzy.png b/doc/tutorial/slides/expander-fuzzy.png
new file mode 100644
index 000000000..b01fd636e
--- /dev/null
+++ b/doc/tutorial/slides/expander-fuzzy.png
Binary files differ
diff --git a/doc/tutorial/slides/expander-sharp-large.png b/doc/tutorial/slides/expander-sharp-large.png
new file mode 100644
index 000000000..f97fa06a4
--- /dev/null
+++ b/doc/tutorial/slides/expander-sharp-large.png
Binary files differ
diff --git a/doc/tutorial/slides/expander-sharp.png b/doc/tutorial/slides/expander-sharp.png
new file mode 100644
index 000000000..40759aef7
--- /dev/null
+++ b/doc/tutorial/slides/expander-sharp.png
Binary files differ
diff --git a/doc/tutorial/slides/fuzzies.svg b/doc/tutorial/slides/fuzzies.svg
new file mode 100644
index 000000000..df12b8a71
--- /dev/null
+++ b/doc/tutorial/slides/fuzzies.svg
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ width="800" height="500">
+
+ <image xlink:href="expander-fuzzy.png" x="175" y="25" width="50" height="50"/>
+ <image xlink:href="expander-sharp.png" x="575" y="25" width="50" height="50"/>
+
+ <image xlink:href="expander-fuzzy-large.png" x="0" y="100" width="400" height="400"/>
+ <image xlink:href="expander-sharp-large.png" x="400" y="100" width="400" height="400"/>
+</svg>
diff --git a/doc/tutorial/slides/jaggies.svg b/doc/tutorial/slides/jaggies.svg
new file mode 100644
index 000000000..e99d07ba5
--- /dev/null
+++ b/doc/tutorial/slides/jaggies.svg
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ width="800" height="500">
+
+ <image xlink:href="circle-ooo.png" x="175" y="25" width="50" height="50"/>
+ <image xlink:href="circle-cairo.png" x="575" y="25" width="50" height="50"/>
+
+ <image xlink:href="circle-ooo-large.png" x="0" y="100" width="400" height="400"/>
+ <image xlink:href="circle-cairo-large.png" x="400" y="100" width="400" height="400"/>
+</svg>
diff --git a/doc/tutorial/slides/rendering-model.png b/doc/tutorial/slides/rendering-model.png
new file mode 100644
index 000000000..900898417
--- /dev/null
+++ b/doc/tutorial/slides/rendering-model.png
Binary files differ
diff --git a/doc/tutorial/slides/tutorial.xml b/doc/tutorial/slides/tutorial.xml
new file mode 100644
index 000000000..3224bea22
--- /dev/null
+++ b/doc/tutorial/slides/tutorial.xml
@@ -0,0 +1,535 @@
+<?xml version="1.0" ?>
+<svgslides
+ xmlns="http://www.svgslides.org/svgslides0.1"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ >
+
+ <slides theme="cairo"
+ presentation="Drawing with cairo"
+ presentation-subtitle="drawing with cairo"
+ URL="http://cairographics.org"
+ bullet="bullet">
+
+ <slide title="Tutorial preparation" variant="blank" bullet="">
+ <lc></lc>
+ <lc align="center">http://cairographics.org/tutorial</lc>
+ <lc></lc>
+ <li>wget http://cairographics.org/cairo-tutorial.tar.gz</li>
+ <li>tar xzf cairo-tutorial.tar.gz</li>
+ <li>cd cairo-tutorial</li>
+ <li>make</li>
+ <li>cat README</li>
+ <lc></lc>
+ <lc align="center">IRC: irc.freenode.net #cairo</lc>
+ </slide>
+
+ <slide variant="title">
+ <lc>Carl Worth</lc>
+ <lc>Red Hat, Inc.</lc>
+ <lc></lc>
+ <lc>linux.conf.au</lc>
+ <lc>2006-01-26</lc>
+ <lc>http://cairographics.org</lc>
+ </slide>
+
+ <slide title="Ugly graphics" variant="separator">
+ <lc align="left">Jaggies</lc>
+ <lc align="center">Fuzzies</lc>
+ <lc align="right">Fireworks</lc>
+ </slide>
+
+ <slide title="Jaggies">
+ <img src="jaggies.svg"/>
+ </slide>
+
+ <slide title="Fuzzies">
+ <img src="fuzzies.svg"/>
+ </slide>
+
+ <slide title="Fireworks">
+ </slide>
+
+ <slide title="What you can do about it">
+ <li>Let application authors know there are options</li>
+ <li>Learn to use cairo—patch the applications</li>
+ <li>Write your own cairo-using applications</li>
+ </slide>
+
+ <slide title="Getting started" variant="separator">
+ <lc align="center">Various shell cairo programs</lc>
+ </slide>
+
+ <slide title="Minimal cairo-xlib program" variant="code">
+ <lc>#include &lt;cairo.h&gt;</lc>
+ <lc>#include &lt;cairo-xlib.h&gt;</lc>
+ <lc>int main (void) {</lc>
+ <lc> Display *dpy = XOpenDisplay (0);</lc>
+ <lc> Window w = XCreateSimpleWindow (dpy,RootWindow (dpy, 0),</lc>
+ <lc> 0, 0, WIDTH, HEIGHT, 0, 0, WhitePixel (dpy, 0));</lc>
+ <lc> cairo_surface_t *surface = cairo_xlib_surface_create (dpy, w,</lc>
+ <lc> DefaultVisual (dpy, DefaultScreen (dpy)),</lc>
+ <lc> WIDTH, HEIGHT);</lc>
+ <lc> XEvent ev;</lc>
+ <lc> XSelectInput (dpy, w, ExposureMask);</lc>
+ <lc> XMapWindow (dpy, w);</lc>
+ <lc> while (XNextEvent (dpy, &amp;ev) == 0)</lc>
+ <lc> if (ev.type == Expose &amp;&amp; !ev.xexpose.count) {</lc>
+ <lc> cairo_t *cr = cairo_create (surface);</lc>
+ <lc> draw (cr);</lc>
+ <lc> cairo_destroy (cr);</lc>
+ <lc> }</lc>
+ <lc>}</lc>
+ </slide>
+
+ <slide title="Minimal cairo-gtk program" variant="code">
+ <lc>#include &lt;gtk/gtk.h&gt;</lc>
+ <lc>static gboolean</lc>
+ <lc>handle_expose (GtkWidget *widget, GdkEventExpose *event, gpointer data) {</lc>
+ <lc> cairo_t *cr = gdk_cairo_create (widget->window);</lc>
+ <lc> draw (cr);</lc>
+ <lc> cairo_destroy (cr);</lc>
+ <lc> return FALSE;</lc>
+ <lc>}</lc>
+ <lc>int main (int argc, char **argv) {</lc>
+ <lc> GtkWidget *window, *drawing_area;</lc>
+ <lc> gtk_init (&amp;argc, &amp;argv);</lc>
+ <lc> window = gtk_window_new (GTK_WINDOW_TOPLEVEL);</lc>
+ <lc> gtk_window_set_default_size (GTK_WINDOW (window), WIDTH, HEIGHT);</lc>
+ <lc> drawing_area = gtk_drawing_area_new ();</lc>
+ <lc> gtk_container_add (GTK_CONTAINER (window), drawing_area);</lc>
+ <lc> g_signal_connect (drawing_area, "expose-event",</lc>
+ <lc> G_CALLBACK (handle_expose), NULL);</lc>
+ <lc> gtk_widget_show_all (window); gtk_main ();</lc>
+ <lc>}</lc>
+ </slide>
+
+ <slide title="Minimal cairo-png program" variant="code">
+ <lc>#include &lt;cairo.h&gt;</lc>
+ <lc></lc>
+ <lc>int main (void)</lc>
+ <lc>{</lc>
+ <lc> cairo_surface_t *surface;</lc>
+ <lc> cairo_t *cr;</lc>
+ <lc></lc>
+ <lc> surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,</lc>
+ <lc> WIDTH, HEIGHT);</lc>
+ <lc> cr = cairo_create (surface);</lc>
+ <lc> draw (cr);</lc>
+ <lc> cairo_surface_write_to_png (surface, "foo.png");</lc>
+ <lc></lc>
+ <lc> cairo_surface_destroy (surface);</lc>
+ <lc> cairo_destroy (cr);</lc>
+ <lc></lc>
+ <lc> return 0;</lc>
+ <lc>}</lc>
+ </slide>
+
+ <slide title="Minimal cairo-pdf program" variant="code">
+ <lc>#include &lt;cairo.h&gt;</lc>
+ <lc>#include &lt;cairo-pdf.h&gt;</lc>
+ <lc>int main (void)</lc>
+ <lc>{</lc>
+ <lc> cairo_surface_t *surface;</lc>
+ <lc> cairo_t *cr;</lc>
+ <lc></lc>
+ <lc> surface = cairo_pdf_surface_create ("foo.pdf", WIDTH, HEIGHT);</lc>
+ <lc> </lc>
+ <lc> cr = cairo_create (surface);</lc>
+ <lc> draw (cr);</lc>
+ <lc> cairo_show_page (cr);</lc>
+ <lc></lc>
+ <lc> cairo_surface_destroy (surface);</lc>
+ <lc> cairo_destroy (cr);</lc>
+ <lc></lc>
+ <lc> return 0;</lc>
+ <lc>}</lc>
+ </slide>
+
+ <slide title="Minimal pycairo-gtk shell" variant="code">
+ <lc>#!/usr/bin/env python</lc>
+ <lc>import gtk</lc>
+ <lc>import cairo</lc>
+ <lc></lc>
+ <lc>def expose (widget, event):</lc>
+ <lc> cr = widget.window.cairo_create ()</lc>
+ <lc> draw (cr)</lc>
+ <lc> </lc>
+ <lc>win = gtk.Window ()</lc>
+ <lc>win.connect ('destroy', gtk.main_quit)</lc>
+ <lc>win.set_default_size(WIDTH, HEIGHT)</lc>
+ <lc>drawingarea = gtk.DrawingArea ()</lc>
+ <lc>win.add (drawingarea)</lc>
+ <lc>drawingarea.connect ('expose_event', expose)</lc>
+ <lc>win.show_all ()</lc>
+ <lc>gtk.main ()</lc>
+ </slide>
+
+ <slide title="Minimal pycairo-png shell" variant="code">
+ <lc>#!/usr/bin/env python</lc>
+ <lc>import cairo</lc>
+ <lc></lc>
+ <lc>surface = cairo.ImageSurface (cairo.FORMAT_ARGB32, WIDTH, HEIGHT)</lc>
+ <lc>cr = cairo.Context (surface)</lc>
+ <lc></lc>
+ <lc>draw (cr)</lc>
+ <lc></lc>
+ <lc>surface.write_to_png ('foo.png')</lc>
+ </slide>
+
+ <slide title="Minimal nickle program" variant="code">
+ <lc>autoimport Cairo;</lc>
+ <lc></lc>
+ <lc>cairo_t cr = new (WIDTH, HEIGHT);</lc>
+ <lc>draw (cr);</lc>
+ </slide>
+
+ <slide title="Available bindings:" variant="large-content">
+ <li>C++ (cairomm)</li>
+ <li>Haskell (hscairo)</li>
+ <li>Java (CairoJava, cairo-java)</li>
+ <li>Common Lisp (cl-cairo)</li>
+ <li>Nickle (cairo-5c)</li>
+ <li>Objective Caml (cairo-ocaml)</li>
+ <li>perl (cairo-perl)</li>
+ <li>python (pycairo)</li>
+ <li>ruby (rcairo)</li>
+ <li>squeak (cairo-squeak)</li>
+ </slide>
+
+ <slide title="Following along" >
+ <lc></lc>
+ <lc align="center">http://cairographics.org/tutorial</lc>
+ <lc align="center">http://cairographics.org/cairo-tutorial.tar.gz</lc>
+ <li>tar xzf cairo-tutorial.tar.gz</li>
+ <li>cd cairo-tutorial</li>
+ <li>make</li>
+ <li>cat README</li>
+ <lc align="center">IRC: irc.freenode.net #cairo</lc>
+ </slide>
+
+ <slide title="Cairo's rendering model">
+ <g>
+ <image x="0" y="0" xlink:href="rendering-model.png" width="800" height="500" />
+ </g>
+ </slide>
+
+ <slide title="Let's start drawing" variant="separator">
+ <lc align="center">Here comes the fun part</lc>
+ </slide>
+
+ <slide title="API Overview" variant="large-content">
+ <ul>
+ <li>Paths</li>
+ <ul>
+ <li>construction</li>
+ <li>filling, stroking</li>
+ </ul>
+ <li>Images</li>
+ <ul>
+ <li>loading from disk</li>
+ <li>using as source</li>
+ <li>transforming/filtering</li>
+ </ul>
+ <li>Text</li>
+ <ul>
+ <li>“Toy” API</li>
+ <li>“Full” API</li>
+ </ul>
+ </ul>
+ </slide>
+
+ <slide title="Drawing functions" variant="large-content">
+ <ul>
+ <li>Paths</li>
+ <ul>
+ <li>cairo_stroke</li>
+ <li>cairo_fill</li>
+ </ul>
+ <li>Images</li>
+ <ul>
+ <li>cairo_paint</li>
+ <li>cairo_mask</li>
+ <li>cairo_paint_with_alpha</li>
+ </ul>
+ <li>Text</li>
+ <ul>
+ <li>cairo_show_text (“toy”)</li>
+ <li>cairo_show_glyphs (“full”)</li>
+ </ul>
+ </ul>
+ </slide>
+
+ <slide title="Basic path building">
+ <ul>
+ <li>Paths consist of lines and splines:</li>
+ <ul>
+ <li>cairo_move_to</li>
+ <lc> start new sub path, set current point</lc>
+ <li>cairo_line_to</li>
+ <lc> add line segment to path</lc>
+ <li>cairo_curve_to</li>
+ <lc> add Bézier spline to path</lc>
+ <li>cairo_close_path</li>
+ <lc> add line segment to last move_to point</lc>
+ </ul>
+ </ul>
+ </slide>
+
+ <slide title="Stroking paths">
+ <ul>
+ <li>cairo_stroke</li>
+ <ul>
+ <li>Paints the path itself as stroked by a pen</li>
+ <li>Controlled by various stroke parameters:</li>
+ <ul>
+ <li>cairo_set_line_width</li>
+ <li>cairo_set_line_cap</li>
+ <li>cairo_set_line_join</li>
+ <li>cairo_set_miter_limit</li>
+ <li>cairo_set_dash</li>
+ </ul>
+ </ul>
+ </ul>
+ </slide>
+
+ <slide title="cairo_stroke example">
+ </slide>
+
+ <slide title="cairo_set_line_width">
+ </slide>
+
+ <slide title="cairo_set_line_cap example">
+ <ul>
+ <li>CAIRO_LINE_CAP_BUTT</li>
+ <li>CAIRO_LINE_CAP_ROUND</li>
+ <li>CAIRO_LINE_CAP_SQUARE</li>
+ </ul>
+ </slide>
+
+ <slide title="cairo_set_line_join example">
+ <ul>
+ <li>CAIRO_LINE_JOIN_BEVEL</li>
+ <li>CAIRO_LINE_JOIN_ROUND</li>
+ <li>CAIRO_LINE_JOIN_MITER</li>
+ </ul>
+ </slide>
+
+ <slide title="cairo_close_path example">
+ <li>Adds a line segment (if necessary) to the</li>
+ <lc>start of the path</lc>
+ <li>Draws a join from that line to the first</li>
+ <lc>element of the path</lc>
+ </slide>
+
+ <slide title="cairo_set_dash example">
+ </slide>
+
+ <slide title="cairo_fill">
+ <ul>
+ <li>Paints the “inside” of the path</li>
+ <li>Two different ways to determine inside-ness</li>
+ <ul>
+ <li>cairo_set_fill_rule:</li>
+ <lc> CAIRO_FILL_RULE_WINDING</lc>
+ <lc> CAIRO_FILL_RULE_EVEN_ODD</lc>
+ </ul>
+ </ul>
+ </slide>
+
+ <slide title="cairo_fill example">
+ </slide>
+
+ <slide title="cairo_set_fill_rule">
+ <li>To test a point for inside-ness, imagine a ray</li>
+ <lc>from the point and extending to infinity</lc>
+ <lc>(any direction) and examine path crossings</lc>
+ <li>EVEN_ODD counts crossings and fills when odd</li>
+ <li>WINDING counts up/down for left/right crossings</li>
+ <lc>and fills when the final number is not zero</lc>
+ </slide>
+
+ <slide title="Fill rule example">
+ </slide>
+
+ <slide title="Something besides black?">
+ <li>All drawing occurs with the source pattern</li>
+ <li>Uniform-color sources can be set</li>
+ <lc>with or without alpha:</lc>
+ <ul>
+ <li>cairo_set_source_rgb</li>
+ <li>cairo_set_source_rgba</li>
+ </ul>
+ </slide>
+
+ <slide title="cairo_set_source example">
+ </slide>
+
+ <slide title="Fill and stroke the same path">
+ <li>cairo_stroke and cairo_fill consume the path</li>
+ <li>Variants are available to preserve the path:</li>
+ <ul>
+ <li>cairo_stroke_preserve</li>
+ <li>cairo_fill_preserve</li>
+ </ul>
+ <li>This is a variation from PostScript and PDF</li>
+ <ul>
+ <li>The cairo approach differs in different ways</li>
+ <li>We think this way is better (of course)</li>
+ </ul>
+ </slide>
+
+ <slide title="Fill and stroke example">
+ </slide>
+
+ <slide title="More path building">
+ <ul>
+ <li>cairo_rectangle</li>
+ <li>cairo_arc</li>
+ <li>cairo_text_path</li>
+ <li>cairo_glyph_path</li>
+ <li>Relative-coordinate variants:</li>
+ <ul>
+ <li>cairo_rel_move_to</li>
+ <li>cairo_rel_line_to</li>
+ <li>cairo_rel_curve_to</li>
+ </ul>
+ </ul>
+ </slide>
+
+ <slide title="cairo_arc example">
+ </slide>
+
+ <slide title="Outline text">
+ </slide>
+
+ <slide title="Affine Transformations">
+ <ul>
+ <li>Single matrix combines rotation, translation,</li>
+ <lc>scale and shear</lc>
+ <li>Non-projective transformations</li>
+ <ul>
+ <li>Pen doesn't change shape along the stroke</li>
+ </ul>
+ <li>Transformations are cumulative</li>
+ <ul>
+ <li>translate, scale != scale, translate</li>
+ </ul>
+ </ul>
+ </slide>
+
+ <slide title="Affine Transform Example">
+ </slide>
+
+ <slide title="Save/Restore Graphics States">
+ <ul>
+ <li>cairo_save and cairo_restore</li>
+ <li>Very useful for bracketing function bodies</li>
+ <li>Eliminates graphics state side effects</li>
+ <lc></lc>
+ <li>NOTE: Path is not part of graphics state</li>
+ <ul>
+ <li>Path is not affected by cairo_save/restore</li>
+ <li>Useful for path-generating functions</li>
+ </ul>
+ </ul>
+ </slide>
+
+ <slide title="Clipping">
+ <li>cairo_clip</li>
+ <li>Intersects path with current clip to further</li>
+ <lc>restrict drawing</lc>
+ <li>Pixel-aligned clipping is much faster</li>
+ <li>cairo_clip_preserve is available as well</li>
+ </slide>
+
+ <slide title="Other source patterns">
+ <ul>
+ <li>Surface patterns</li>
+ <ul>
+ <li>Image from disk</li>
+ <li>Results of cairo drawing</li>
+ </ul>
+ <li>Gradient patterns</li>
+ <ul>
+ <li>linear gradients</li>
+ <li>radial gradients</li>
+ </ul>
+ </ul>
+ </slide>
+
+ <slide title="Loading an image file">
+ </slide>
+
+ <slide title="Painting an image">
+ </slide>
+
+ <slide title="Pattern transformation">
+ </slide>
+
+ <slide title="Pattern filtering">
+ </slide>
+
+ <slide title="Linear gradient example">
+ </slide>
+
+ <slide title="Radial gradient example">
+ </slide>
+
+ <slide title="Text">
+ <ul>
+ <li>“Toy” API:</li>
+ <ul>
+ <li>Useful for demos like we are writing today</li>
+ <li>No real layout—not useful for the majority</li>
+ <lc>of writing systems in the world</lc>
+ </ul>
+ <li>“Full” API:</li>
+ <ul>
+ <li>User must do OS-dependent font selection</li>
+ <li>User must access font glyph IDs directly</li>
+ <li>User must do all text layout</li>
+ </ul>
+ </ul>
+ </slide>
+
+ <slide title="“Toy” text API"/>
+ <ul>
+ <li>Simple font selection</li>
+ <ul>
+ <li>family, weight, slant</li>
+ <li>OS independent</li>
+ <li>No font listing support</li>
+ </ul>
+ <li>UTF-8 text drawing and extents functions</li>
+ <li>Still supports full font transformations</li>
+ </ul>
+
+ <slide title="“Toy” text example">
+ </slide>
+
+ <slide title="“Real” text example">
+ <li>Just use pango</li>
+ </slide>
+
+ <slide title="Error handling in C">
+ <li>C has no exceptions</li>
+ <li>Checking each return is tedious</li>
+ <li>C programmers rarely bother</li>
+ <li>Lots of broken programs result</li>
+ </slide>
+
+ <slide title="Cairo error handling">
+ <li>Cairo stores status value when error occurs</li>
+ <li>API “shuts down” when an error occurs</li>
+ <li>All cairo functions are benign</li>
+ <lc>(and well defined) after any error.</lc>
+ <li>cairo_status can be called when convenient</li>
+ <li>Error status values propagate across objects</li>
+ </slide>
+
+ <slide title="Cairo error example">
+ </slide>
+
+ </slides>
+</svgslides>
diff --git a/doc/tutorial/src/.gitignore b/doc/tutorial/src/.gitignore
new file mode 100644
index 000000000..68af59e73
--- /dev/null
+++ b/doc/tutorial/src/.gitignore
@@ -0,0 +1,8 @@
+*-gtk
+*-pdf
+*-png
+*-xlib
+*.pdf
+*.png
+*.o
+*~
diff --git a/doc/tutorial/src/README b/doc/tutorial/src/README
new file mode 100644
index 000000000..a2738da4e
--- /dev/null
+++ b/doc/tutorial/src/README
@@ -0,0 +1,66 @@
+Welcome to the cairo tutorial:
+
++--------------------------------+
+| How to Recognize Ugly Graphics |
+|(and what you can do about them)|
++--------------------------------+
+
+This directory is your personal playground for following along with
+the examples. In order for you to make use of these files you will
+need to have cairo and its header files installed. You can find
+instructions for doing this at:
+
+ http://cairographics.org/tutorial
+
+Notice that there are a few .c files in this directory.
+
+You should start out by just typing "make" which will turn each .c
+file into several different programs. Go ahead and run each of the
+programs and see what they do. Some of them will open up new X windows
+while others will simply write their output to files (such .png or
+.pdf).
+
+After you play with those a bit, go ahead and take a look at the
+contents of the .c files. You'll see that each file contains a draw()
+function that does all of the drawing.
+
+You might be surprised to notice that there is no main() function in
+any of the files. Instead, main is hidden away by means of
+cairo-tutorial.h. This rather non-conventional style is used to allow
+you to focus on the actual drawing code involved in using cairo, while
+not having to worry about the setup semantics. We don't recommend that
+you follow this style for real projects.
+
+As you follow along during the tutorial and get some ideas for things
+to draw, you'll want to start making your own .c files. You can copy
+an existing file or make your own by following this simple minimal
+template:
+
+ #include "cairo-tutorial.h"
+
+ static void
+ draw (cairo_t *cr, int width, int height)
+ {
+ /* Put your drawing code here. */
+ }
+
+Any new file you create will automatically get picked up by the
+Makefile so that "make" will compile your file into several different
+programs, just like the existing examples.
+
+If you'd like to control the initial size of the output, you may
+define WIDTH and HEIGHT before including cairo-tutorial.h like so:
+
+ #define WIDTH 100
+ #define HEIGHT 100
+
+ #include "cairo-tutorial.h"
+
+If you would like to change the set of cairo-backend target programs
+that are compiled, you may edit the "all" target in the Makefile.
+
+Have fun!
+
+-Carl Worth
+
+cworth@redhat.com
diff --git a/doc/tutorial/src/circle.c b/doc/tutorial/src/circle.c
new file mode 100644
index 000000000..6bd02e8ba
--- /dev/null
+++ b/doc/tutorial/src/circle.c
@@ -0,0 +1,22 @@
+#include "cairo-tutorial.h"
+
+static void
+draw (cairo_t *cr, int width, int height)
+{
+ int radius;
+
+ if (width < height)
+ radius = width/2 - 4;
+ else
+ radius = height/2 - 4;
+
+ cairo_move_to (cr, width/2 + radius, height/2);
+ cairo_arc (cr, width/2, height/2, radius,
+ 0.0, 2 * M_PI);
+
+ cairo_set_source_rgb (cr, 0.6, 0.8, 1.0);
+ cairo_fill_preserve (cr);
+
+ cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
+ cairo_stroke (cr);
+}
diff --git a/doc/tutorial/src/include/cairo-tutorial-gtk.h b/doc/tutorial/src/include/cairo-tutorial-gtk.h
new file mode 100644
index 000000000..60516a356
--- /dev/null
+++ b/doc/tutorial/src/include/cairo-tutorial-gtk.h
@@ -0,0 +1,133 @@
+/* cairo-tutorial-gtk.h - a tutorial framework for cairo with gtk+
+ *
+ * Copyright © 2005, Carl Worth
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
+ */
+
+#include <gtk/gtk.h>
+#include <gdk/gdkkeysyms.h>
+
+#include <cairo.h>
+
+#ifndef WIDTH
+#define WIDTH 400
+#endif
+
+#ifndef HEIGHT
+#define HEIGHT 400
+#endif
+
+static void
+draw (cairo_t *cr, int width, int height);
+
+#if ! GTK_CHECK_VERSION(2,7,0)
+/* copied from gtk+/gdk/gdkcairo.c and gtk+/gdk/x11/gdkdrawable-x11.c
+ * gdk_cairo_create() which is available in 2.7.0 and later.
+ */
+static cairo_t *
+gdk_cairo_create (GdkDrawable *drawable)
+{
+ int width, height;
+ cairo_t *cr = NULL;
+ cairo_surface_t *surface = NULL;
+ GdkVisual *visual = gdk_drawable_get_visual (drawable);
+
+ gdk_drawable_get_size (drawable, &width, &height);
+ if (visual)
+ surface = cairo_xlib_surface_create (GDK_DRAWABLE_XDISPLAY (drawable),
+ GDK_DRAWABLE_XID (drawable),
+ GDK_VISUAL_XVISUAL (visual),
+ width, height);
+ else if (gdk_drawable_get_depth (drawable) == 1)
+ surface = cairo_xlib_surface_create_for_bitmap
+ (GDK_PIXMAP_XDISPLAY (drawable),
+ GDK_PIXMAP_XID (drawable),
+ GDK_SCREEN_XSCREEN (gdk_drawable_get_screen (drawable)),
+ width, height);
+ else {
+ g_warning ("Using Cairo rendering requires the drawable argument to\n"
+ "have a specified colormap. All windows have a colormap,\n"
+ "however, pixmaps only have colormap by default if they\n"
+ "were created with a non-NULL window argument. Otherwise\n"
+ "a colormap must be set on them with "
+ "gdk_drawable_set_colormap");
+ return NULL;
+ }
+ if (surface) {
+ cr = cairo_create (surface);
+ cairo_surface_destroy (surface);
+ }
+ return cr;
+}
+#endif
+
+static gboolean
+handle_expose (GtkWidget *widget,
+ GdkEventExpose *event,
+ gpointer data)
+{
+ cairo_t *cr;
+
+ cr = gdk_cairo_create (widget->window);
+
+ draw (cr, widget->allocation.width, widget->allocation.height);
+
+ cairo_destroy (cr);
+
+ return FALSE;
+}
+
+static gboolean
+handle_key_press (GtkWidget *widget,
+ GdkEventKey *event,
+ gpointer data)
+{
+ if ((event->keyval == GDK_Q ||
+ event->keyval == GDK_q) && (event->state & GDK_CONTROL_MASK))
+ gtk_main_quit ();
+
+ return FALSE;
+}
+
+int
+main (int argc, char **argv)
+{
+ GtkWidget *window, *drawing_area;
+
+ gtk_init (&argc, &argv);
+
+ window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+
+ gtk_window_set_default_size (GTK_WINDOW (window), WIDTH, HEIGHT);
+ gtk_window_set_title (GTK_WINDOW (window), "cairo demo");
+
+ g_signal_connect (window, "destroy",
+ G_CALLBACK (gtk_main_quit), NULL);
+
+ drawing_area = gtk_drawing_area_new ();
+ gtk_container_add (GTK_CONTAINER (window), drawing_area);
+
+ g_signal_connect (drawing_area, "expose-event",
+ G_CALLBACK (handle_expose), NULL);
+
+ g_signal_connect (window, "key-press-event",
+ G_CALLBACK (handle_key_press), NULL);
+
+ gtk_widget_show_all (window);
+
+ gtk_main ();
+
+ return 0;
+}
diff --git a/doc/tutorial/src/include/cairo-tutorial-pdf.h b/doc/tutorial/src/include/cairo-tutorial-pdf.h
new file mode 100644
index 000000000..00d0f188e
--- /dev/null
+++ b/doc/tutorial/src/include/cairo-tutorial-pdf.h
@@ -0,0 +1,74 @@
+/* cairo-tutorial-png.h - a tutorial framework for cairo to write a PNG image
+ *
+ * Copyright © 2005, Carl Worth
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
+ */
+
+#include <cairo.h>
+#include <cairo-pdf.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+
+#ifndef WIDTH
+#define WIDTH 400
+#endif
+
+#ifndef HEIGHT
+#define HEIGHT 400
+#endif
+
+static void
+draw (cairo_t *cr, int width, int height);
+
+int
+main (int argc, char **argv)
+{
+ cairo_surface_t *surface;
+ cairo_t *cr;
+ char *filename, *dash;
+
+ filename = strdup (argv[0]);
+ assert (filename != NULL);
+
+ dash = strrchr (filename, '-');
+
+ if (strcmp (dash, "-pdf") == 0) {
+ *dash = '.';
+ } else {
+ char *new_filename;
+ new_filename = malloc (strlen (filename) + 5);
+ sprintf (new_filename, "%s.pdf", filename);
+ free (filename);
+ filename = new_filename;
+ }
+
+ surface = cairo_pdf_surface_create (filename, WIDTH, HEIGHT);
+
+ cr = cairo_create (surface);
+
+ draw (cr, WIDTH, HEIGHT);
+
+ cairo_show_page (cr);
+
+ cairo_surface_destroy (surface);
+ cairo_destroy (cr);
+
+ free (filename);
+
+ return 0;
+}
diff --git a/doc/tutorial/src/include/cairo-tutorial-png.h b/doc/tutorial/src/include/cairo-tutorial-png.h
new file mode 100644
index 000000000..428baf294
--- /dev/null
+++ b/doc/tutorial/src/include/cairo-tutorial-png.h
@@ -0,0 +1,74 @@
+/* cairo-tutorial-png.h - a tutorial framework for cairo to write a PNG image
+ *
+ * Copyright © 2005, Carl Worth
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
+ */
+
+#include <cairo.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+
+#ifndef WIDTH
+#define WIDTH 400
+#endif
+
+#ifndef HEIGHT
+#define HEIGHT 400
+#endif
+
+static void
+draw (cairo_t *cr, int width, int height);
+
+int
+main (int argc, char **argv)
+{
+ cairo_surface_t *surface;
+ cairo_t *cr;
+ char *filename, *dash;
+
+ surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
+ WIDTH, HEIGHT);
+
+ cr = cairo_create (surface);
+
+ draw (cr, WIDTH, HEIGHT);
+
+ filename = strdup (argv[0]);
+ assert (filename != NULL);
+
+ dash = strrchr (filename, '-');
+
+ if (strcmp (dash, "-png") == 0) {
+ *dash = '.';
+ } else {
+ char *new_filename;
+ new_filename = malloc (strlen (filename) + 5);
+ sprintf (new_filename, "%s.png", filename);
+ free (filename);
+ filename = new_filename;
+ }
+
+ cairo_surface_write_to_png (surface, filename);
+
+ free (filename);
+
+ cairo_surface_destroy (surface);
+ cairo_destroy (cr);
+
+ return 0;
+}
diff --git a/doc/tutorial/src/include/cairo-tutorial-xlib.h b/doc/tutorial/src/include/cairo-tutorial-xlib.h
new file mode 100644
index 000000000..5e78d0354
--- /dev/null
+++ b/doc/tutorial/src/include/cairo-tutorial-xlib.h
@@ -0,0 +1,251 @@
+/* cairo-tutorial-xlib.h - a tutorial framework for cairo with xlib
+ *
+ * Copyright © 2005, Keith Packard
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <strings.h>
+#include <X11/Xos.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xatom.h>
+#include <cairo.h>
+#include <cairo-xlib.h>
+
+#ifndef WIDTH
+#define WIDTH 400
+#endif
+
+#ifndef HEIGHT
+#define HEIGHT 400
+#endif
+
+#ifndef DEFAULT_VISUAL
+#define DEFAULT_VISUAL 0
+#endif
+
+static void
+Usage (char *program)
+{
+ fprintf (stderr, "Usage: %s\n", program);
+ fprintf (stderr, "\t-display <display-name>\n");
+ fprintf (stderr, "\t-geometry <geometry>\n");
+ exit (1);
+}
+
+char *dpy_name;
+VisualID vid = DEFAULT_VISUAL;
+Colormap colormap;
+Visual *visual;
+int depth;
+unsigned int width = WIDTH, height = HEIGHT;
+Window win;
+Pixmap pix;
+GC gc;
+
+static void
+draw (cairo_t *cr, int width, int height);
+
+static void
+draw_to_pixmap (Display *dpy, Pixmap pix)
+{
+ cairo_surface_t *surface;
+ cairo_t *cr;
+
+ surface = cairo_xlib_surface_create (dpy, pix, visual,
+ width, height);
+ cr = cairo_create (surface);
+
+ draw (cr, width, height);
+
+ cairo_destroy (cr);
+ cairo_surface_destroy (surface);
+}
+
+static void
+handle_configure (Display *dpy, XConfigureEvent *cev)
+{
+ width = cev->width;
+ height = cev->height;
+
+ XFreePixmap(dpy, pix);
+ pix = XCreatePixmap(dpy, win, width, height, depth);
+ XFillRectangle(dpy, pix, gc, 0, 0, width, height);
+ draw_to_pixmap (dpy, pix);
+}
+
+static void
+handle_expose (Display *dpy, XExposeEvent *eev)
+{
+ XCopyArea (dpy, pix, win, gc,
+ eev->x, eev->y,
+ eev->width, eev->height,
+ eev->x, eev->y);
+}
+
+int
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ Display *dpy;
+ Window root = 0;
+ char **init_argv = argv;
+ XSetWindowAttributes attr;
+ int scr;
+ int x = 0, y = 0;
+ int geometryMask;
+ int border_width = 1;
+ XSizeHints sizeHints;
+ XWMHints wmHints;
+ XClassHint classHints;
+ XEvent ev;
+ XEvent eev;
+ int HasExpose = 0;
+ int sync = 0;
+ XTextProperty wm_name, icon_name;
+ Atom wm_delete_window;
+ unsigned long gc_mask;
+ XGCValues gcv;
+ char quit_string[10];
+ unsigned long window_mask;
+ int has_colormap = 0;
+
+ wm_name.value = (unsigned char *) argv[0];
+ wm_name.encoding = XA_STRING;
+ wm_name.format = 8;
+ wm_name.nitems = strlen (argv[0]) + 1;
+ icon_name = wm_name;
+ gc_mask = 0;
+ while (*++argv) {
+ if (!strcmp (*argv, "-display"))
+ dpy_name = *++argv;
+ else if (!strcmp (*argv, "-visual"))
+ vid = strtol(*++argv, NULL, 0);
+ else if (!strcmp (*argv, "-geometry"))
+ geometryMask = XParseGeometry (*++argv, &x, &y, &width, &height);
+ else if (!strcmp (*argv, "-sync"))
+ sync = 1;
+ else if (!strcmp (*argv, "-bw"))
+ border_width = strtol(*++argv, NULL, 0);
+ else if (!strcmp (*argv, "-root"))
+ root = strtol (*++argv, NULL, 0);
+ else
+ Usage (*init_argv);
+ }
+ sizeHints.flags = 0;
+ wmHints.flags = InputHint;
+ wmHints.input = True;
+ classHints.res_name = init_argv[0];
+ classHints.res_class = init_argv[0];
+ dpy = XOpenDisplay (dpy_name);
+ if (!dpy) {
+ fprintf (stderr, "Error: failed to open display: %s\n",
+ XDisplayName (dpy_name));
+ exit (1);
+ }
+ if (sync)
+ XSynchronize (dpy, sync);
+ scr = DefaultScreen (dpy);
+ if (!root)
+ root = RootWindow (dpy, scr);
+ window_mask = CWBackPixel|CWBorderPixel|CWEventMask;
+ if (!has_colormap)
+ colormap = DefaultColormap (dpy, scr);
+ else
+ {
+ window_mask |= CWColormap;
+ attr.colormap = colormap;
+ }
+ visual = DefaultVisual (dpy, scr);
+ depth = DefaultDepth (dpy, scr);
+ if (vid)
+ {
+ XVisualInfo vi, *vi_ret;
+ int n;
+
+ vi.visualid = vid;
+ vi.screen = scr;
+ vi_ret = XGetVisualInfo (dpy, VisualIDMask|VisualScreenMask,
+ &vi, &n);
+ if (vi_ret)
+ {
+ visual = vi_ret->visual;
+ if (!has_colormap)
+ {
+ colormap = XCreateColormap (dpy, root, visual, AllocNone);
+ window_mask |= CWColormap;
+ attr.colormap = colormap;
+ }
+ depth = vi_ret->depth;
+ }
+ }
+ attr.background_pixel = WhitePixel (dpy, scr);
+ attr.border_pixel = 0;
+ attr.event_mask = ExposureMask|KeyPressMask|KeyReleaseMask|StructureNotifyMask;
+ wm_delete_window = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
+ win = XCreateWindow (dpy, root, x, y, width, height, border_width,
+ depth, InputOutput,
+ visual,
+ window_mask,
+ &attr);
+ pix = XCreatePixmap (dpy, win, width, height, depth);
+ gcv.foreground = WhitePixel (dpy, scr);
+ gc = XCreateGC (dpy, pix, GCForeground, &gcv);
+ XFillRectangle(dpy, pix, gc, 0, 0, width, height);
+ draw_to_pixmap (dpy, pix);
+ XSetWMProperties (dpy, win,
+ &wm_name, &icon_name,
+ init_argv, argc,
+ &sizeHints, &wmHints, 0);
+ XSetWMProtocols (dpy, win, &wm_delete_window, 1);
+ XMapWindow (dpy, win);
+ for (;;) {
+ XNextEvent (dpy, &ev);
+ if (HasExpose && ev.type != Expose) {
+ HasExpose = 0;
+ handle_expose (dpy, &eev.xexpose);
+ }
+ switch (ev.type) {
+ case ConfigureNotify:
+ handle_configure (dpy, &ev.xconfigure);
+ break;
+ case Expose:
+ if (QLength(dpy)) {
+ eev = ev;
+ HasExpose = 1;
+ } else if (ev.xexpose.count == 0) {
+ handle_expose (dpy, &ev.xexpose);
+ }
+ break;
+ case KeyPress:
+ if (XLookupString ((XKeyEvent *) &ev, quit_string, sizeof (quit_string), 0, 0) == 1) {
+ switch (quit_string[0]) {
+ case 'q':
+ exit (0);
+ case 'c':
+ XClearArea (dpy, ev.xkey.window, 0, 0, 0, 0, True);
+ break;
+ }
+ }
+ break;
+ case ClientMessage:
+ exit (0);
+ }
+ }
+}
diff --git a/doc/tutorial/src/include/cairo-tutorial.h b/doc/tutorial/src/include/cairo-tutorial.h
new file mode 100644
index 000000000..ec738e915
--- /dev/null
+++ b/doc/tutorial/src/include/cairo-tutorial.h
@@ -0,0 +1,40 @@
+/* cairo-tutorial-gtk.h - a tutorial framework for cairo
+ *
+ * Copyright © 2005, Carl Worth
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
+ */
+
+#include <cairo.h>
+#include <math.h>
+
+/* The application program may override these before including
+ * cairo-tutorial.h in order to get a window of a different size. */
+#ifndef WIDTH
+#define WIDTH 400
+#endif
+
+#ifndef HEIGHT
+#define HEIGHT 400
+#endif
+
+#ifdef CAIRO_TUTORIAL_GTK
+#include "cairo-tutorial-gtk.h"
+#elif CAIRO_TUTORIAL_XLIB
+#include "cairo-tutorial-xlib.h"
+#elif CAIRO_TUTORIAL_PDF
+#include "cairo-tutorial-pdf.h"
+#elif CAIRO_TUTORIAL_PNG
+#include "cairo-tutorial-png.h"
+#endif
diff --git a/doc/tutorial/src/lca.c b/doc/tutorial/src/lca.c
new file mode 100644
index 000000000..0b131afaf
--- /dev/null
+++ b/doc/tutorial/src/lca.c
@@ -0,0 +1,32 @@
+#define WIDTH 750
+#define HEIGHT 360
+
+#include "cairo-tutorial.h"
+
+static void
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_save (cr);
+
+ cairo_translate (cr, 60, 60);
+ cairo_scale (cr, 3, 3);
+
+ cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
+ cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND);
+ cairo_set_line_width (cr, 20);
+
+ /* L */
+ cairo_move_to (cr, 0, 0);
+ cairo_line_to (cr, 0, 80);
+ cairo_line_to (cr, 50, 80);
+
+ /* C */
+ cairo_move_to (cr, 110 + 40 * cos (M_PI / 3), 40 + 40 * sin(M_PI / 3));
+ cairo_arc (cr, 110, 40, 40, M_PI / 3, -M_PI / 3);
+
+ /* A */
+ cairo_move_to (cr, 160, 80);
+ cairo_curve_to (cr, 160, -30, 210, -30, 210, 80);
+
+ cairo_stroke (cr);
+}
diff --git a/doc/tutorial/src/singular.c b/doc/tutorial/src/singular.c
new file mode 100644
index 000000000..958b2b047
--- /dev/null
+++ b/doc/tutorial/src/singular.c
@@ -0,0 +1,162 @@
+/**
+ * Uses Singular values of transformation matrix to find the length of the
+ * major and minor axes of the scaled pen.
+ *
+ * Put this file in cairo/doc/tutorial/src and type "make"
+ */
+
+#define WIDTH 300
+#define HEIGHT 300
+
+#include "cairo-tutorial.h"
+
+#include <math.h>
+
+/*
+ * Finds the singular values of the non-translation part of matrix.
+ *
+ * Let M be the cairo transformation matrix in question:
+ *
+ * ⌈xx xy⌉
+ * M = |yx yy|
+ * ⌊x0 y0⌋
+ *
+ * The non-translation part is:
+ *
+ * A = ⌈xx xy⌉
+ * ⌊yx yy⌋
+ *
+ * The non-zero singular values of A are the square roots of the non-zero
+ * eigenvalues of A⁺ A, where A⁺ is A-transpose.
+ *
+ * A⁺ A = ⌈xx yx⌉⌈xx xy⌉ = ⌈xx²+yx² xx*xy+yx*yy⌉
+ * ⌊xy yy⌋⌊yx yy⌋ ⌊xx*xy+yx*yy xy²+yy²⌋
+ *
+ * Name those:
+ *
+ * B = A⁺ A = ⌈a k⌉
+ * ⌊k b⌋
+ *
+ * The eigenvalues of B satisfy:
+ *
+ * λ² - (a+b).λ + a.b - k² = 0
+ *
+ * The eigenvalues are:
+ * __________________
+ * (a+b) ± √(a+b)² - 4(a.b-k²)
+ * λ = ---------------------------
+ * 2
+ * that simplifies to:
+ * _______________
+ * λ = (a+b)/2 ± √((a-b)/2)² + k²
+ *
+ * And the Singular values are the root of λs.
+ *
+ */
+static void
+get_singular_values (const cairo_matrix_t *matrix,
+ double *major,
+ double *minor)
+{
+ double xx = matrix->xx, xy = matrix->xy;
+ double yx = matrix->yx, yy = matrix->yy;
+
+ double a = xx*xx+yx*yx;
+ double b = xy*xy+yy*yy;
+ double k = xx*xy+yx*yy;
+
+ double f = (a+b) * .5;
+ double g = (a-b) * .5;
+ double delta = sqrt (g*g + k*k);
+
+ if (major)
+ *major = sqrt (f + delta);
+ if (minor)
+ *minor = sqrt (f - delta);
+}
+
+/*
+ * Finds the length of the major and minor axes of the pen for a cairo_t,
+ * identified by the current transformation matrix and line width.
+ *
+ * Returned values are in device units.
+ */
+static void
+get_pen_axes (cairo_t *cr,
+ double *major,
+ double *minor)
+{
+ double width;
+ cairo_matrix_t matrix;
+
+ width = cairo_get_line_width (cr);
+ cairo_get_matrix (cr, &matrix);
+
+ get_singular_values (&matrix, major, minor);
+
+ if (major)
+ *major *= width;
+ if (minor)
+ *minor *= width;
+}
+
+static void
+draw (cairo_t *cr, int width, int height)
+{
+ double major_width, minor_width;
+
+ /* clear background */
+ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */
+ cairo_paint (cr);
+
+#define W width
+#define H height
+#define B ((width+height)/16)
+
+ /* the spline we want to stroke */
+ cairo_move_to (cr, W-B, B);
+ cairo_curve_to (cr, -W, B,
+ 2*W, H-B,
+ B, H-B);
+
+ /* the effect is show better with round caps */
+ cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
+
+ /* set the skewed pen */
+ cairo_rotate (cr, +.7);
+ cairo_scale (cr, .5, 2.);
+ cairo_rotate (cr, -.7);
+ cairo_set_line_width (cr, B);
+
+ get_pen_axes (cr, &major_width, &minor_width);
+
+ /* stroke with "major" pen in translucent red */
+ cairo_save (cr);
+ cairo_identity_matrix (cr);
+ cairo_set_line_width (cr, major_width);
+ cairo_set_source_rgba (cr, 1.0, 0.0, 0.0, .9);
+ cairo_stroke_preserve (cr);
+ cairo_restore (cr);
+
+ /* stroke with skewed pen in translucent black */
+ cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, .9);
+ cairo_stroke_preserve (cr);
+
+ /* stroke with "minor" pen in translucent yellow */
+ cairo_save (cr);
+ cairo_identity_matrix (cr);
+ cairo_set_line_width (cr, minor_width);
+ cairo_set_source_rgba (cr, 1.0, 1.0, 0.0, .9);
+ cairo_stroke_preserve (cr);
+ cairo_restore (cr);
+
+ /* stroke with hairline in black */
+ cairo_save (cr);
+ cairo_identity_matrix (cr);
+ cairo_set_line_width (cr, 1);
+ cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
+ cairo_stroke_preserve (cr);
+ cairo_restore (cr);
+
+ cairo_new_path (cr);
+}
diff --git a/doc/tutorial/src/twin.c b/doc/tutorial/src/twin.c
new file mode 100644
index 000000000..14347bac2
--- /dev/null
+++ b/doc/tutorial/src/twin.c
@@ -0,0 +1,39 @@
+/**
+ * Put this file in cairo/doc/tutorial/src and type "make"
+ */
+
+#define WIDTH 1350
+#define HEIGHT 900
+
+#include "cairo-tutorial.h"
+
+
+static void
+draw (cairo_t *cr, int width, int height)
+{
+ int i, j, h;
+ unsigned char s[2] = {0, 0};
+
+ /* clear background */
+ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */
+ cairo_paint (cr);
+
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ cairo_select_font_face (cr,
+ "@cairo:",
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_NORMAL);
+
+ h = 2;
+ for (i = 8; i < 48; i >= 24 ? i+=3 : i++) {
+ cairo_set_font_size (cr, i);
+ for (j = 33; j < 128; j++) {
+ if (j == 33 || (j == 80 && i > 24)) {
+ h += i + 2;
+ cairo_move_to (cr, 10, h);
+ }
+ s[0] = j;
+ cairo_show_text (cr, (const char *) s);
+ }
+ }
+}
diff --git a/packaging/cairo.manifest b/packaging/cairo.manifest
index 017d22d3a..017d22d3a 100755..100644
--- a/packaging/cairo.manifest
+++ b/packaging/cairo.manifest
diff --git a/packaging/cairo.spec b/packaging/cairo.spec
index 0ffc725ac..850546ee8 100755..100644
--- a/packaging/cairo.spec
+++ b/packaging/cairo.spec
@@ -7,7 +7,7 @@
Name: cairo
#Version: 1.12.16
-Version: 1.12.14
+Version: 1.14.2
Release: 0
License: LGPL-2.1+ or MPL-1.1
Summary: Vector Graphics Library with Cross-Device Output Support
@@ -95,19 +95,19 @@ in-memory image buffers, and PostScript. Cairo is designed to produce
identical output on all output media while taking advantage of display
hardware acceleration when available.
-#%package tools
-#License: GPL-3.0+
-#Summary: Vector Graphics Library with Cross-Device Output Support -- Utilities
-#Group: Development/Libraries
+%package -n tools
+License: GPL-3.0+
+Summary: Vector Graphics Library with Cross-Device Output Support -- Utilities
+Group: Development/Libraries
# We need an explicit requires since nothing links to the cairo library
#Requires: libcairo = %{version}
-#%description tools
-#Cairo is a vector graphics library with cross-device output support.
-#Currently supported output targets include the X Window System,
-#in-memory image buffers, and PostScript. Cairo is designed to produce
-#identical output on all output media while taking advantage of display
-#hardware acceleration when available.
+%description -n tools
+Cairo is a vector graphics library with cross-device output support.
+Currently supported output targets include the X Window System,
+in-memory image buffers, and PostScript. Cairo is designed to produce
+identical output on all output media while taking advantage of display
+hardware acceleration when available.
This package contains various cairo utilities.
@@ -203,16 +203,16 @@ make %{?_smp_mflags} V=1
%license util/cairo-script/COPYING
%{_libdir}/libcairo-script-interpreter.so.*
-#%files tools
-#%manifest %{name}.manifest
-#%defattr(-, root, root)
-#%license util/cairo-trace/COPYING util/cairo-trace/COPYING-GPL-3
-#%{_bindir}/cairo-sphinx
-#%{_bindir}/cairo-trace
-#%dir %{_libdir}/cairo
-#%{_libdir}/cairo/cairo-fdr.so
-#%{_libdir}/cairo/cairo-sphinx.so
-#%{_libdir}/cairo/libcairo-trace.so
+%files -n tools
+%manifest %{name}.manifest
+%defattr(-, root, root)
+%license util/cairo-trace/COPYING util/cairo-trace/COPYING-GPL-3
+%{_bindir}/cairo-sphinx
+%{_bindir}/cairo-trace
+%dir %{_libdir}/cairo
+%{_libdir}/cairo/cairo-fdr.so*
+%{_libdir}/cairo/cairo-sphinx.so*
+%{_libdir}/cairo/libcairo-trace.so*
%files devel
%manifest %{name}.manifest
diff --git a/perf/.gitignore b/perf/.gitignore
new file mode 100644
index 000000000..02af7a93c
--- /dev/null
+++ b/perf/.gitignore
@@ -0,0 +1,30 @@
+TAGS
+tags
+cairo-analyse-trace
+cairo-perf
+cairo-perf-micro
+cairo-perf-print
+cairo-perf-trace
+cairo-perf-chart
+cairo-perf-compare-backends
+cairo-perf-diff-files
+cairo-perf-graph-files
+cairo-traces
+valgrind-log
+callgrind.out.*
+index.html
+*.png
+*.perf
+*.o
+*.gcda
+*.gcno
+*.exe
+*.manifest
+*.obj
+*.ilk
+*.suo
+*.lib
+*.pdb
+*~
+.*.sw?
+*.data
diff --git a/perf/COPYING b/perf/COPYING
new file mode 100644
index 000000000..17754cf7b
--- /dev/null
+++ b/perf/COPYING
@@ -0,0 +1,5 @@
+Cairo is free software.
+
+These tests are mainly available under a liberal MIT license to simplify
+any use of the code for reference purposes. Please check the opening comment
+of each file for copyright and licensing information.
diff --git a/perf/Makefile.am b/perf/Makefile.am
new file mode 100644
index 000000000..40b35bc38
--- /dev/null
+++ b/perf/Makefile.am
@@ -0,0 +1,154 @@
+include $(top_srcdir)/build/Makefile.am.common
+
+include $(top_srcdir)/perf/Makefile.sources
+
+AM_CPPFLAGS = \
+ -I$(srcdir) \
+ -I$(top_srcdir)/boilerplate \
+ -I$(top_srcdir)/src \
+ -I$(top_srcdir)/util/cairo-missing \
+ -I$(top_srcdir)/util/cairo-script \
+ -I$(top_builddir)/src \
+ $(CAIRO_CFLAGS)
+
+AM_LDFLAGS = $(CAIRO_LDFLAGS)
+
+SUBDIRS = micro
+
+noinst_PROGRAMS = \
+ cairo-analyse-trace \
+ cairo-perf-trace \
+ cairo-perf-micro \
+ $(NULL)
+
+EXTRA_PROGRAMS += \
+ cairo-analyse-trace \
+ cairo-perf-micro \
+ cairo-perf-trace \
+ cairo-perf-diff-files \
+ cairo-perf-print \
+ cairo-perf-chart \
+ cairo-perf-compare-backends \
+ cairo-perf-graph-files \
+ $(NULL)
+EXTRA_DIST += cairo-perf-diff COPYING
+EXTRA_LTLIBRARIES += libcairoperf.la
+
+LDADD = libcairoperf.la \
+ $(top_builddir)/boilerplate/libcairoboilerplate.la \
+ $(top_builddir)/src/libcairo.la
+
+cairo_perf_micro_SOURCES = $(cairo_perf_micro_sources)
+cairo_perf_micro_LDADD = \
+ $(top_builddir)/perf/micro/libcairo-perf-micro.la \
+ $(LDADD)
+cairo_perf_micro_DEPENDENCIES = \
+ $(top_builddir)/perf/micro/libcairo-perf-micro.la \
+ $(LDADD)
+
+libcairoperf_la_SOURCES = \
+ $(libcairoperf_sources) \
+ $(libcairoperf_external_sources) \
+ $(libcairoperf_headers) \
+ $(NULL)
+
+cairo_analyse_trace_SOURCES = \
+ $(cairo_analyse_trace_sources) \
+ $(cairo_analyse_trace_external_sources)
+cairo_analyse_trace_LDADD = \
+ $(top_builddir)/util/cairo-script/libcairo-script-interpreter.la \
+ $(top_builddir)/util/cairo-missing/libcairo-missing.la \
+ $(LDADD)
+cairo_analyse_trace_DEPENDENCIES = \
+ $(top_builddir)/util/cairo-script/libcairo-script-interpreter.la \
+ $(top_builddir)/util/cairo-missing/libcairo-missing.la \
+ $(LDADD)
+
+cairo_perf_trace_SOURCES = \
+ $(cairo_perf_trace_sources) \
+ $(cairo_perf_trace_external_sources)
+cairo_perf_trace_LDADD = \
+ $(top_builddir)/util/cairo-script/libcairo-script-interpreter.la \
+ $(top_builddir)/util/cairo-missing/libcairo-missing.la \
+ $(LDADD)
+cairo_perf_trace_DEPENDENCIES = \
+ $(top_builddir)/util/cairo-script/libcairo-script-interpreter.la \
+ $(top_builddir)/util/cairo-missing/libcairo-missing.la \
+ $(LDADD)
+
+cairo_perf_diff_files_SOURCES = $(cairo_perf_diff_files_sources)
+cairo_perf_print_SOURCES = $(cairo_perf_print_sources)
+cairo_perf_chart_SOURCES = $(cairo_perf_chart_sources)
+cairo_perf_compare_backends_SOURCES = $(cairo_perf_compare_backends_sources)
+
+cairo_perf_graph_files_SOURCES = \
+ $(cairo_perf_graph_files_sources) \
+ $(cairo_perf_graph_files_headers)
+cairo_perf_graph_files_CFLAGS = @gtk_CFLAGS@
+cairo_perf_graph_files_LDADD = @gtk_LIBS@ $(LDADD)
+
+# Install rules to rebuild the libraries and add explicit dependencies
+$(top_builddir)/perf/micro/libcairo-perf-micro.la:
+ cd $(top_builddir)/perf/micro && $(MAKE) $(AM_MAKEFLAGS) libcairo-perf-micro.la
+
+$(top_builddir)/boilerplate/libcairoboilerplate.la: $(top_builddir)/src/libcairo.la
+ cd $(top_builddir)/boilerplate && $(MAKE) $(AM_MAKEFLAGS) libcairoboilerplate.la
+
+$(top_builddir)/src/libcairo.la:
+ cd $(top_builddir)/src && $(MAKE) $(AM_MAKEFLAGS) libcairo.la
+
+$(top_builddir)/util/cairo-script/libcairo-script-interpreter.la: $(top_builddir)/src/libcairo.la
+ cd $(top_builddir)/util/cairo-script && $(MAKE) $(AM_MAKEFLAGS) libcairo-script-interpreter.la
+
+
+# Do a funny transition of CAIRO_TEST_TARGET through TARGETS such that
+# one can limit tested targets both through CAIRO_TEST_TARGET env var
+# and TARGETS make var on the command line. Same for the rest.
+TARGETS = $(CAIRO_TEST_TARGET)
+TARGETS_EXCLUDE = $(CAIRO_TEST_TARGET_EXCLUDE)
+FORMAT = $(CAIRO_TEST_TARGET_FORMAT)
+ITERS = $(CAIRO_PERF_ITERATIONS)
+
+CAIRO_PERF_ENVIRONMENT = CAIRO_PERF_ITERATIONS="$(ITERS)" CAIRO_TEST_TARGET="$(TARGETS)" CAIRO_TEST_TARGET_FORMAT="$(FORMAT)" CAIRO_TEST_TARGET_EXCLUDE="$(TARGETS_EXCLUDE)"
+
+perf: cairo-perf-micro$(EXEEXT) cairo-perf-trace$(EXEEXT)
+ -$(CAIRO_PERF_ENVIRONMENT) ./cairo-perf-micro$(EXEEXT)
+ -$(CAIRO_PERF_ENVIRONMENT) ./cairo-perf-trace$(EXEEXT)
+
+html-local: index.html
+
+perf-tag.html : cairo-perf-micro${EXEEXT}
+ $(CAIRO_PERF_ENVIRONMENT) ./cairo-perf-diff -t -h $@ `git describe --abbrev=0` HEAD
+perf-commit.html : cairo-perf-micro${EXEEXT}
+ $(CAIRO_PERF_ENVIRONMENT) ./cairo-perf-diff -t -h $@ HEAD
+
+# Summarise changes in index.html, with details in links
+index.html: perf-tag.html perf-commit.html
+ echo "<html><head><title>Performance Changes</title></head><body>Against <a href=\"perf-tag.html\">"`git describe --abbrev=0`"</a><br><a href=\"perf-commit.html\">Latest commit</a></body>" > $@
+
+EXTRA_VALGRIND_FLAGS = $(CAIRO_EXTRA_VALGRIND_FLAGS)
+VALGRIND_MEMCHECK_FLAGS = \
+ --tool=memcheck \
+ --suppressions=$(top_srcdir)/test/.valgrind-suppressions \
+ --leak-check=yes --show-reachable=yes
+VALGRIND_CALLGRIND_FLAGS = \
+ --tool=callgrind
+CLEANFILES += \
+ valgrind-log \
+ callgrind.out.* \
+ index.html
+
+perf-valgrind:
+ $(MAKE) $(AM_MAKEFLAGS) perf \
+ $(top_builddir)/libtool --mode=execute \
+ valgrind $(VALGRIND_MEMCHECK_FLAGS) $(EXTRA_VALGRIND_FLAGS)' \
+ | tee valgrind-log
+
+perf-callgrind:
+ $(MAKE) $(AM_MAKEFLAGS) perf \
+ $(top_builddir)/libtool --mode=execute \
+ valgrind $(VALGRIND_CALLGRIND_FLAGS) $(EXTRA_VALGRIND_FLAGS)'
+
+.PHONY: perf perf-valgrind perf-callgrind
+
+EXTRA_DIST += Makefile.win32
diff --git a/perf/Makefile.sources b/perf/Makefile.sources
new file mode 100644
index 000000000..1fcf14809
--- /dev/null
+++ b/perf/Makefile.sources
@@ -0,0 +1,38 @@
+libcairoperf_sources = \
+ cairo-perf.c \
+ cairo-perf-report.c \
+ cairo-stats.c \
+ $(NULL)
+
+libcairoperf_external_sources = ../src/cairo-time.c
+
+libcairoperf_headers = \
+ cairo-perf.h \
+ cairo-stats.h \
+ $(NULL)
+
+cairo_analyse_trace_sources = cairo-analyse-trace.c
+cairo_analyse_trace_external_sources = ../src/cairo-error.c
+
+cairo_perf_trace_sources = cairo-perf-trace.c
+cairo_perf_trace_external_sources = \
+ ../src/cairo-error.c \
+ ../src/cairo-hash.c \
+ $(NULL)
+
+cairo_perf_micro_sources = cairo-perf-micro.c
+
+cairo_perf_diff_files_sources = cairo-perf-diff-files.c
+
+cairo_perf_print_sources = cairo-perf-print.c
+
+cairo_perf_chart_sources = cairo-perf-chart.c
+
+cairo_perf_compare_backends_sources = cairo-perf-compare-backends.c
+
+cairo_perf_graph_files_sources = \
+ cairo-perf-graph-files.c \
+ cairo-perf-graph-widget.c \
+ $(NULL)
+
+cairo_perf_graph_files_headers = cairo-perf-graph.h
diff --git a/perf/Makefile.win32 b/perf/Makefile.win32
new file mode 100644
index 000000000..084abf00e
--- /dev/null
+++ b/perf/Makefile.win32
@@ -0,0 +1,78 @@
+top_srcdir = ..
+include $(top_srcdir)/build/Makefile.win32.common
+include $(top_srcdir)/perf/Makefile.sources
+
+CFLAGS += -I$(top_srcdir)/boilerplate -I$(top_srcdir)/util/cairo-script/
+
+PERF_LIBS = \
+ $(CFG)/libcairoperf.lib \
+ $(top_builddir)/boilerplate/$(CFG)/boiler.lib \
+ $(top_builddir)/src/$(CFG)/cairo-static.lib \
+ $(NULL)
+
+PERF_EXES = \
+ $(CFG)/cairo-perf-trace.exe \
+ $(CFG)/cairo-perf-micro.exe \
+ $(CFG)/cairo-perf-diff-files.exe \
+ $(CFG)/cairo-perf-print.exe \
+ $(CFG)/cairo-perf-chart.exe \
+ $(CFG)/cairo-perf-compare-backends.exe \
+ $(NULL)
+
+all: inform $(PERF_EXES)
+
+perf: inform $(CFG)/cairo-perf-micro.exe
+ ./$(CFG)/cairo-perf-micro.exe
+
+
+libcairoperf_OBJECTS = $(patsubst %.c, $(CFG)/%-static.obj, $(libcairoperf_sources))
+
+$(CFG)/libcairoperf.lib: $(libcairoperf_OBJECTS)
+ @$(AR) $(CAIRO_ARFLAGS) -OUT:$@ $(libcairoperf_OBJECTS)
+
+cairo_perf_trace_OBJECTS = \
+ $(patsubst %.c, $(CFG)/%-static.obj, $(cairo_perf_trace_sources)) \
+ $(top_builddir)/util/cairo-script/$(CFG)/libcairo-script-interpreter.lib \
+ $(NULL)
+
+cairo_perf_micro_OBJECTS = \
+ $(patsubst %.c, $(CFG)/%-static.obj, $(cairo_perf_micro_sources)) \
+ ./micro/$(CFG)/libcairo-perf-micro.lib \
+ $(NULL)
+
+cairo_perf_diff_files_OBJECTS = $(patsubst %.c, $(CFG)/%-static.obj, $(cairo_perf_diff_files_sources))
+cairo_perf_print_OBJECTS = $(patsubst %.c, $(CFG)/%-static.obj, $(cairo_perf_print_sources))
+cairo_perf_chart_OBJECTS = $(patsubst %.c, $(CFG)/%-static.obj, $(cairo_perf_chart_sources))
+cairo_perf_compare_backends_OBJECTS = $(patsubst %.c, $(CFG)/%-static.obj, $(cairo_perf_compare_backends_sources))
+
+
+$(CFG)/cairo-perf-trace.exe: $(cairo_perf_trace_OBJECTS) $(PERF_LIBS)
+ @$(LD) $(CAIRO_LDFLAGS) -OUT:$@ $(cairo_perf_trace_OBJECTS) $(PERF_LIBS) $(CAIRO_LIBS)
+
+$(CFG)/cairo-perf-micro.exe: $(cairo_perf_micro_OBJECTS) $(PERF_LIBS)
+ @$(LD) $(CAIRO_LDFLAGS) -OUT:$@ $(cairo_perf_micro_OBJECTS) $(PERF_LIBS) $(CAIRO_LIBS)
+
+$(CFG)/cairo-perf-diff-files.exe: $(cairo_perf_diff_files_OBJECTS) $(PERF_LIBS)
+ @$(LD) $(CAIRO_LDFLAGS) -OUT:$@ $(cairo_perf_diff_files_OBJECTS) $(PERF_LIBS) $(CAIRO_LIBS)
+
+$(CFG)/cairo-perf-print.exe: $(cairo_perf_print_OBJECTS) $(PERF_LIBS)
+ @$(LD) $(CAIRO_LDFLAGS) -OUT:$@ $(cairo_perf_print_OBJECTS) $(PERF_LIBS) $(CAIRO_LIBS)
+
+$(CFG)/cairo-perf-chart.exe: $(cairo_perf_chart_OBJECTS) $(PERF_LIBS)
+ @$(LD) $(CAIRO_LDFLAGS) -OUT:$@ $(cairo_perf_chart_OBJECTS) $(PERF_LIBS) $(CAIRO_LIBS)
+
+$(CFG)/cairo-perf-compare-backends.exe: $(cairo_perf_compare_backends_OBJECTS) $(PERF_LIBS)
+ @$(LD) $(CAIRO_LDFLAGS) -OUT:$@ $(cairo_perf_compare_backends_OBJECTS) $(PERF_LIBS) $(CAIRO_LIBS)
+
+
+./micro/$(CFG)/libcairo-perf-micro.lib:
+ $(MAKE) -C micro -f Makefile.win32
+
+$(top_builddir)/src/$(CFG)/cairo-static.lib:
+ $(MAKE) -C $(top_srcdir)/src -f Makefile.win32
+
+$(top_builddir)/boilerplate/$(CFG)/boiler.lib:
+ $(MAKE) -C $(top_srcdir)/boilerplate -f Makefile.win32
+
+$(top_builddir)/util/cairo-script/$(CFG)/libcairo-script-interpreter.lib:
+ $(MAKE) -C $(top_srcdir)/util/cairo-script -f Makefile.win32
diff --git a/perf/README b/perf/README
new file mode 100644
index 000000000..9e402098a
--- /dev/null
+++ b/perf/README
@@ -0,0 +1,239 @@
+This is cairo's micro-benchmark performance test suite.
+
+One of the simplest ways to run this performance suite is:
+
+ make perf
+
+which will give a report of the speed of each individual test. See
+more details on other options for running the suite below.
+
+A macro test suite (with full traces and more intensive benchmarks) is
+also available; for this, see http://cgit.freedesktop.org/cairo-traces.
+The macro-benchmarks are better measures of actual real-world
+performance, and should be preferred over the micro-benchmarks (and over
+make perf) for identifying performance regressions or improvements. If
+you copy or symlink this repository at cairo/perf/cairo-traces, then
+make perf will run those tests as well.
+
+Running the micro-benchmarks
+----------------------------
+The micro-benchmark performance suite is composed of a series of
+hand-written, short, synthetic tests that measure the speed of doing a
+simple operation such as painting a surface or showing glyphs. These aim
+to give very good feedback on whether a performance related patch is
+successful without causing any performance degradations elsewhere.
+
+The micro-benchmarks are compiled into a single executable called
+cairo-perf-micro, which is what "make perf" executes. Some
+examples of running it:
+
+ # Report on all tests with default number of iterations:
+ ./cairo-perf-micro
+
+ # Report on 100 iterations of all gradient tests:
+ ./cairo-perf-micro -i 100 gradient
+
+ # Generate raw results for 10 iterations into cairo.perf
+ ./cairo-perf-micro -r -i 10 > cairo.perf
+ # Append 10 more iterations of the paint test
+ ./cairo-perf-micro -r -i 10 paint >> cairo.perf
+
+Raw results aren't useful for reading directly, but are quite useful
+when using cairo-perf-diff to compare separate runs (see more
+below). The advantage of using the raw mode is that test runs can be
+generated incrementally and appended to existing reports.
+
+Generating comparisons of separate runs
+---------------------------------------
+It's often useful to generate a chart showing the comparison of two
+separate runs of the cairo performance suite, (for example, after
+applying a patch intended to improve cairo's performance). The
+cairo-perf-diff script can be used to compare two report files
+generated by cairo-perf.
+
+Again, by way of example:
+
+ # Show performance changes from cairo-orig.perf to cairo-patched.perf
+ ./cairo-perf-diff cairo-orig.perf cairo-patched.perf
+
+This will work whether the data files were generate in raw mode (with
+cairo-perf -r) or cooked, (cairo-perf without -r).
+
+Finally, in its most powerful mode, cairo-perf-diff accepts two git
+revisions and will do all the work of checking each revision out,
+building it, running cairo-perf for each revision, and finally
+generating the report. Obviously, this mode only works if you are
+using cairo within a git repository, (and not from a tar file). Using
+this mode is as simple as passing the git revisions to be compared to
+cairo-perf-diff:
+
+ # Compare cairo 1.2.6 to cairo 1.4.0
+ ./cairo-perf-diff 1.2.6 1.4.0
+
+ # Measure the impact of the latest commit
+ ./cairo-perf-diff HEAD~1 HEAD
+
+As a convenience, this common desire to measure a single commit is
+supported by passing a single revision to cairo-perf-diff, in which
+case it will compare it to the immediately preceding commit. So for
+example:
+
+ # Measure the impact of the latest commit
+ ./cairo-perf-diff HEAD
+
+ # Measure the impact of an arbitrary commit by SHA-1
+ ./cairo-perf-diff aa883123d2af90
+
+Also, when passing git revisions to cairo-perf-diff like this, it will
+automatically cache results and re-use them rather than re-running
+cairo-perf over and over on the same versions. This means that if you
+ask for a report that you've generated in the past, cairo-perf-diff
+should return it immediately.
+
+Now, sometimes it is desirable to generate more iterations rather than
+re-using cached results. In this case, the -f flag can be used to
+force cairo-perf-diff to generate additional results in addition to
+what has been cached:
+
+ # Measure the impact of latest commit (force more measurement)
+ ./cairo-perf-diff -f
+
+And finally, the -f mode is most useful in conjunction with the --
+option to cairo-perf-diff which allows you to pass options to the
+underlying cairo-perf runs. This allows you to restrict the additional
+test runs to a limited subset of the tests.
+
+For example, a frequently used trick is to first generate a chart with
+a very small number of iterations for all tests:
+
+ ./cairo-perf-diff HEAD
+
+Then, if any of the results look suspicious, (say there's a slowdown
+reported in the text tests, but you think the text test shouldn't be
+affected), then you can force more iterations to be tested for only
+those tests:
+
+ ./cairo-perf-diff -f HEAD -- text
+
+Generating comparisons of different backends
+--------------------------------------------
+An alternate question that is often asked is, "how does the speed of one
+backend compare to another?". cairo-perf-compare-backends can read files
+generated by cairo-perf and produces a comparison of the backends for every
+test.
+
+Again, by way of example:
+
+ # Show relative performance of the backends
+ ./cairo-perf-compare-backends cairo.perf
+
+This will work whether the data files were generate in raw mode (with
+cairo-perf -r) or cooked, (cairo-perf without -r).
+
+
+Creating a new performance test
+-------------------------------
+This is where we could use everybody's help. If you have encountered a
+sequence of cairo operations that are slower than you would like, then
+please provide a performance test. Writing a test is very simple, it
+requires you to write only a small C file with a couple of functions,
+one of which exercises the cairo calls of interest.
+
+Here is the basic structure of a performance test file:
+
+ /* Copyright © 2006 Kind Cairo User
+ *
+ * ... Licensing information here ...
+ * Please copy the MIT blurb as in other tests
+ */
+
+ #include "cairo-perf.h"
+
+ static cairo_time_t
+ do_my_new_test (cairo_t *cr, int width, int height)
+ {
+ cairo_perf_timer_start ();
+
+ /* Make the cairo calls to be measured */
+
+ cairo_perf_timer_stop ();
+
+ return cairo_perf_timer_elapsed ();
+ }
+
+ void
+ my_new_test (cairo_perf_t *perf, cairo_t *cr, int width, int height)
+ {
+ /* First do any setup for which the execution time should not
+ * be measured. For example, this might include loading
+ * images from disk, creating patterns, etc. */
+
+ /* Then launch the actual performance testing. */
+ cairo_perf_run (perf, "my_new_test", do_my_new_test);
+
+ /* Finally, perform any cleanup from the setup above. */
+ }
+
+That's really all there is to writing a new test. The first function
+above is the one that does the real work and returns a timing
+number. The second function is the one that will be called by the
+performance test rig (see below for how to accomplish that), and
+allows for multiple performance cases to be written in one file,
+(simply call cairo_perf_run once for each case, passing the
+appropriate callback function to each).
+
+We go through this dance of indirectly calling your own function
+through cairo_perf_run so that cairo_perf_run can call your function
+many times and measure statistical properties over the many runs.
+
+Finally, to fully integrate your new test case you just need to add
+your new test to three different lists. (TODO: We should set this up
+better so that the lists are maintained automatically---computed from
+the list of files in cairo/perf, for example). Here's what needs to be
+added:
+
+ 1. Makefile.am: Add the new file name to the cairo_perf_SOURCES list
+
+ 2. cairo-perf.h: Add a new CAIRO_PERF_DECL line with the name of your
+ function, (my_new_test in the example above)
+
+ 3. cairo-perf-micro.c: Add a new row to the list at the end of the
+ file. A typical entry would look like:
+
+ { my_new_test, 16, 64 }
+
+ The last two numbers are a minimum and a maximum image size at
+ which your test should be exercised. If these values are the same,
+ then only that size will be used. If they are different, then
+ intermediate sizes will be used by doubling. So in the example
+ above, three tests would be performed at sizes of 16x16, 32x32 and
+ 64x64.
+
+
+How to run cairo-perf-diff on WINDOWS
+-------------------------------------
+This section explains the specifics of running cairo-perf-diff under
+win32 plateforms. It assumes that you have installed a UNIX-like shell
+environment such as MSYS (distributed as part of MinGW).
+
+ 1. From your Mingw32 window, be sure to have all of your MSVC environ-
+ ment variables set up for proper compilation using 'make'
+
+ 2. Add the %GitBaseDir%/Git/bin path to your environment, replacing the
+ %GitBaseDir% by whatever directory your Git version is installed to.
+
+ 3. Comment out the "UNSET CDPATH" line in the git-sh-setup script
+ (located inside the ...Git/bin directory) by putting a "#" at the
+ beginning of the line.
+
+you should be ready to go !
+
+From your mingw32 window, go to your cairo/perf directory and run the
+cairo-perf-diff script with the right arguments.
+
+Thanks for your contributions and have fun with cairo!
+
+TODO
+----
+Add a control language for crafting and running small sets of micro
+benchmarks.
diff --git a/perf/cairo-analyse-trace.c b/perf/cairo-analyse-trace.c
new file mode 100644
index 000000000..994148660
--- /dev/null
+++ b/perf/cairo-analyse-trace.c
@@ -0,0 +1,592 @@
+/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */
+/*
+ * Copyright © 2006 Mozilla Corporation
+ * Copyright © 2006 Red Hat, Inc.
+ * Copyright © 2009 Chris Wilson
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * the authors not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. The authors make no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Vladimir Vukicevic <vladimir@pobox.com>
+ * Carl Worth <cworth@cworth.org>
+ * Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#define _GNU_SOURCE 1 /* for sched_getaffinity() and getline() */
+
+#include "../cairo-version.h" /* for the real version */
+
+#include "cairo-perf.h"
+#include "cairo-stats.h"
+
+#include "cairo-boilerplate-getopt.h"
+#include <cairo-script-interpreter.h>
+#include "cairo-missing.h"
+
+/* rudely reuse bits of the library... */
+#include "../src/cairo-error-private.h"
+
+/* For basename */
+#ifdef HAVE_LIBGEN_H
+#include <libgen.h>
+#endif
+#include <ctype.h> /* isspace() */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#ifdef _MSC_VER
+#include "dirent-win32.h"
+
+static char *
+basename_no_ext (char *path)
+{
+ static char name[_MAX_FNAME + 1];
+
+ _splitpath (path, NULL, NULL, name, NULL);
+
+ name[_MAX_FNAME] = '\0';
+
+ return name;
+}
+
+
+#else
+#include <dirent.h>
+
+static char *
+basename_no_ext (char *path)
+{
+ char *dot, *name;
+
+ name = basename (path);
+
+ dot = strchr (name, '.');
+ if (dot)
+ *dot = '\0';
+
+ return name;
+}
+
+#endif
+
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include <signal.h>
+
+#if HAVE_FCFINI
+#include <fontconfig/fontconfig.h>
+#endif
+
+struct trace {
+ const cairo_boilerplate_target_t *target;
+ void *closure;
+ cairo_surface_t *surface;
+};
+
+cairo_bool_t
+cairo_perf_can_run (cairo_perf_t *perf,
+ const char *name,
+ cairo_bool_t *is_explicit)
+{
+ unsigned int i;
+ char *copy, *dot;
+ cairo_bool_t ret;
+
+ if (is_explicit)
+ *is_explicit = FALSE;
+
+ if (perf->exact_names) {
+ if (is_explicit)
+ *is_explicit = TRUE;
+ return TRUE;
+ }
+
+ if (perf->num_names == 0 && perf->num_exclude_names == 0)
+ return TRUE;
+
+ copy = xstrdup (name);
+ dot = strchr (copy, '.');
+ if (dot != NULL)
+ *dot = '\0';
+
+ if (perf->num_names) {
+ ret = TRUE;
+ for (i = 0; i < perf->num_names; i++)
+ if (strstr (copy, perf->names[i])) {
+ if (is_explicit)
+ *is_explicit = strcmp (copy, perf->names[i]) == 0;
+ goto check_exclude;
+ }
+
+ ret = FALSE;
+ goto done;
+ }
+
+check_exclude:
+ if (perf->num_exclude_names) {
+ ret = FALSE;
+ for (i = 0; i < perf->num_exclude_names; i++)
+ if (strstr (copy, perf->exclude_names[i])) {
+ if (is_explicit)
+ *is_explicit = strcmp (copy, perf->exclude_names[i]) == 0;
+ goto done;
+ }
+
+ ret = TRUE;
+ goto done;
+ }
+
+done:
+ free (copy);
+
+ return ret;
+}
+
+static cairo_surface_t *
+surface_create (void *closure,
+ cairo_content_t content,
+ double width,
+ double height,
+ long uid)
+{
+ struct trace *args = closure;
+ return cairo_surface_create_similar (args->surface, content, width, height);
+}
+
+static int user_interrupt;
+
+static void
+interrupt (int sig)
+{
+ if (user_interrupt) {
+ signal (sig, SIG_DFL);
+ raise (sig);
+ }
+
+ user_interrupt = 1;
+}
+
+static void
+describe (cairo_perf_t *perf,
+ void *closure)
+{
+ char *description = NULL;
+
+ if (perf->has_described_backend)
+ return;
+ perf->has_described_backend = TRUE;
+
+ if (perf->target->describe)
+ description = perf->target->describe (closure);
+
+ if (description == NULL)
+ return;
+
+ free (description);
+}
+
+static void
+execute (cairo_perf_t *perf,
+ struct trace *args,
+ const char *trace)
+{
+ char *trace_cpy, *name;
+ const cairo_script_interpreter_hooks_t hooks = {
+ .closure = args,
+ .surface_create = surface_create,
+ };
+
+ trace_cpy = xstrdup (trace);
+ name = basename_no_ext (trace_cpy);
+
+ if (perf->list_only) {
+ printf ("%s\n", name);
+ free (trace_cpy);
+ return;
+ }
+
+ describe (perf, args->closure);
+
+ {
+ cairo_script_interpreter_t *csi;
+ cairo_status_t status;
+ unsigned int line_no;
+
+ csi = cairo_script_interpreter_create ();
+ cairo_script_interpreter_install_hooks (csi, &hooks);
+
+ cairo_script_interpreter_run (csi, trace);
+
+ cairo_script_interpreter_finish (csi);
+
+ line_no = cairo_script_interpreter_get_line_number (csi);
+ status = cairo_script_interpreter_destroy (csi);
+ if (status) {
+ /* XXXX cairo_status_to_string is just wrong! */
+ fprintf (stderr, "Error during replay, line %d: %s\n",
+ line_no, cairo_status_to_string (status));
+ }
+ }
+ user_interrupt = 0;
+
+ free (trace_cpy);
+}
+
+static void
+usage (const char *argv0)
+{
+ fprintf (stderr,
+"Usage: %s [-l] [-i iterations] [-x exclude-file] [test-names ... | traces ...]\n"
+"\n"
+"Run the cairo trace analysis suite over the given tests (all by default)\n"
+"The command-line arguments are interpreted as follows:\n"
+"\n"
+" -i iterations; specify the number of iterations per test case\n"
+" -l list only; just list selected test case names without executing\n"
+" -x exclude; specify a file to read a list of traces to exclude\n"
+"\n"
+"If test names are given they are used as sub-string matches so a command\n"
+"such as \"%s firefox\" can be used to run all firefox traces.\n"
+"Alternatively, you can specify a list of filenames to execute.\n",
+ argv0, argv0);
+}
+
+static cairo_bool_t
+read_excludes (cairo_perf_t *perf,
+ const char *filename)
+{
+ FILE *file;
+ char *line = NULL;
+ size_t line_size = 0;
+ char *s, *t;
+
+ file = fopen (filename, "r");
+ if (file == NULL)
+ return FALSE;
+
+ while (getline (&line, &line_size, file) != -1) {
+ /* terminate the line at a comment marker '#' */
+ s = strchr (line, '#');
+ if (s)
+ *s = '\0';
+
+ /* whitespace delimits */
+ s = line;
+ while (*s != '\0' && isspace (*s))
+ s++;
+
+ t = s;
+ while (*t != '\0' && ! isspace (*t))
+ t++;
+
+ if (s != t) {
+ int i = perf->num_exclude_names;
+ perf->exclude_names = xrealloc (perf->exclude_names,
+ sizeof (char *) * (i+1));
+ perf->exclude_names[i] = strndup (s, t-s);
+ perf->num_exclude_names++;
+ }
+ }
+ free (line);
+
+ fclose (file);
+
+ return TRUE;
+}
+
+static void
+parse_options (cairo_perf_t *perf,
+ int argc,
+ char *argv[])
+{
+ char *end;
+ int c;
+
+ perf->list_only = FALSE;
+ perf->names = NULL;
+ perf->num_names = 0;
+ perf->exclude_names = NULL;
+ perf->num_exclude_names = 0;
+
+ while (1) {
+ c = _cairo_getopt (argc, argv, "i:lx:");
+ if (c == -1)
+ break;
+
+ switch (c) {
+ case 'i':
+ perf->exact_iterations = TRUE;
+ perf->iterations = strtoul (optarg, &end, 10);
+ if (*end != '\0') {
+ fprintf (stderr, "Invalid argument for -i (not an integer): %s\n",
+ optarg);
+ exit (1);
+ }
+ break;
+ case 'l':
+ perf->list_only = TRUE;
+ break;
+ case 'x':
+ if (! read_excludes (perf, optarg)) {
+ fprintf (stderr, "Invalid argument for -x (not readable file): %s\n",
+ optarg);
+ exit (1);
+ }
+ break;
+ default:
+ fprintf (stderr, "Internal error: unhandled option: %c\n", c);
+ /* fall-through */
+ case '?':
+ usage (argv[0]);
+ exit (1);
+ }
+ }
+
+ if (optind < argc) {
+ perf->names = &argv[optind];
+ perf->num_names = argc - optind;
+ }
+}
+
+static void
+cairo_perf_fini (cairo_perf_t *perf)
+{
+ cairo_boilerplate_free_targets (perf->targets);
+ cairo_boilerplate_fini ();
+
+ cairo_debug_reset_static_data ();
+#if HAVE_FCFINI
+ FcFini ();
+#endif
+}
+
+static cairo_bool_t
+have_trace_filenames (cairo_perf_t *perf)
+{
+ unsigned int i;
+
+ if (perf->num_names == 0)
+ return FALSE;
+
+#if HAVE_UNISTD_H
+ for (i = 0; i < perf->num_names; i++)
+ if (access (perf->names[i], R_OK) == 0)
+ return TRUE;
+#endif
+
+ return FALSE;
+}
+
+static cairo_status_t
+print (void *closure, const unsigned char *data, unsigned int length)
+{
+ fwrite (data, length, 1, closure);
+ return CAIRO_STATUS_SUCCESS;
+}
+
+static void
+cairo_perf_trace (cairo_perf_t *perf,
+ const cairo_boilerplate_target_t *target,
+ const char *trace)
+{
+ struct trace args;
+ cairo_surface_t *real;
+
+ args.target = target;
+ real = target->create_surface (NULL,
+ CAIRO_CONTENT_COLOR_ALPHA,
+ 1, 1,
+ 1, 1,
+ CAIRO_BOILERPLATE_MODE_PERF,
+ &args.closure);
+ args.surface =
+ cairo_surface_create_observer (real,
+ CAIRO_SURFACE_OBSERVER_RECORD_OPERATIONS);
+ cairo_surface_destroy (real);
+ if (cairo_surface_status (args.surface)) {
+ fprintf (stderr,
+ "Error: Failed to create target surface: %s\n",
+ target->name);
+ return;
+ }
+
+ printf ("Observing '%s'...", trace);
+ fflush (stdout);
+
+ execute (perf, &args, trace);
+
+ printf ("\n");
+ cairo_device_observer_print (cairo_surface_get_device (args.surface),
+ print, stdout);
+ fflush (stdout);
+
+ cairo_surface_destroy (args.surface);
+
+ if (target->cleanup)
+ target->cleanup (args.closure);
+}
+
+static void
+warn_no_traces (const char *message,
+ const char *trace_dir)
+{
+ fprintf (stderr,
+"Error: %s '%s'.\n"
+"Have you cloned the cairo-traces repository and uncompressed the traces?\n"
+" git clone git://anongit.freedesktop.org/cairo-traces\n"
+" cd cairo-traces && make\n"
+"Or set the env.var CAIRO_TRACE_DIR to point to your traces?\n",
+ message, trace_dir);
+}
+
+static int
+cairo_perf_trace_dir (cairo_perf_t *perf,
+ const cairo_boilerplate_target_t *target,
+ const char *dirname)
+{
+ DIR *dir;
+ struct dirent *de;
+ int num_traces = 0;
+ cairo_bool_t force;
+ cairo_bool_t is_explicit;
+
+ dir = opendir (dirname);
+ if (dir == NULL)
+ return 0;
+
+ force = FALSE;
+ if (cairo_perf_can_run (perf, dirname, &is_explicit))
+ force = is_explicit;
+
+ while ((de = readdir (dir)) != NULL) {
+ char *trace;
+ struct stat st;
+
+ if (de->d_name[0] == '.')
+ continue;
+
+ xasprintf (&trace, "%s/%s", dirname, de->d_name);
+ if (stat (trace, &st) != 0)
+ goto next;
+
+ if (S_ISDIR(st.st_mode)) {
+ num_traces += cairo_perf_trace_dir (perf, target, trace);
+ } else {
+ const char *dot;
+
+ dot = strrchr (de->d_name, '.');
+ if (dot == NULL)
+ goto next;
+ if (strcmp (dot, ".trace"))
+ goto next;
+
+ num_traces++;
+ if (!force && ! cairo_perf_can_run (perf, de->d_name, NULL))
+ goto next;
+
+ cairo_perf_trace (perf, target, trace);
+ }
+next:
+ free (trace);
+
+ }
+ closedir (dir);
+
+ return num_traces;
+}
+
+int
+main (int argc,
+ char *argv[])
+{
+ cairo_perf_t perf;
+ const char *trace_dir = "cairo-traces:/usr/src/cairo-traces:/usr/share/cairo-traces";
+ unsigned int n;
+ int i;
+
+ parse_options (&perf, argc, argv);
+
+ signal (SIGINT, interrupt);
+
+ if (getenv ("CAIRO_TRACE_DIR") != NULL)
+ trace_dir = getenv ("CAIRO_TRACE_DIR");
+
+ perf.targets = cairo_boilerplate_get_targets (&perf.num_targets, NULL);
+
+ /* do we have a list of filenames? */
+ perf.exact_names = have_trace_filenames (&perf);
+
+ for (i = 0; i < perf.num_targets; i++) {
+ const cairo_boilerplate_target_t *target = perf.targets[i];
+
+ if (! perf.list_only && ! target->is_measurable)
+ continue;
+
+ perf.target = target;
+ perf.has_described_backend = FALSE;
+
+ if (perf.exact_names) {
+ for (n = 0; n < perf.num_names; n++) {
+ struct stat st;
+
+ if (stat (perf.names[n], &st) == 0) {
+ if (S_ISDIR (st.st_mode)) {
+ cairo_perf_trace_dir (&perf, target, perf.names[n]);
+ } else
+ cairo_perf_trace (&perf, target, perf.names[n]);
+ }
+ }
+ } else {
+ int num_traces = 0;
+ const char *dir;
+
+ dir = trace_dir;
+ do {
+ char buf[1024];
+ const char *end = strchr (dir, ':');
+ if (end != NULL) {
+ memcpy (buf, dir, end-dir);
+ buf[end-dir] = '\0';
+ end++;
+
+ dir = buf;
+ }
+
+ num_traces += cairo_perf_trace_dir (&perf, target, dir);
+ dir = end;
+ } while (dir != NULL);
+
+ if (num_traces == 0) {
+ warn_no_traces ("Found no traces in", trace_dir);
+ return 1;
+ }
+ }
+
+ if (perf.list_only)
+ break;
+ }
+
+ cairo_perf_fini (&perf);
+
+ return 0;
+}
diff --git a/perf/cairo-perf-chart.c b/perf/cairo-perf-chart.c
new file mode 100644
index 000000000..738fe5c7b
--- /dev/null
+++ b/perf/cairo-perf-chart.c
@@ -0,0 +1,1113 @@
+/*
+ * Copyright © 2006 Red Hat, Inc.
+ * Copyright © 2009 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of the
+ * copyright holders not be used in advertising or publicity
+ * pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied
+ * warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ *
+ * Authors: Carl Worth <cworth@cworth.org>
+ * Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-perf.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <ctype.h>
+#include <math.h>
+#include <assert.h>
+
+struct chart {
+ cairo_perf_report_t *reports;
+ const char **names;
+
+ cairo_t *cr;
+ int width, height;
+ int num_tests, num_reports;
+ double min_value, max_value;
+ double *average;
+
+ cairo_bool_t use_html;
+ cairo_bool_t relative;
+};
+struct color {
+ double red, green, blue;
+};
+
+#define FONT_SIZE 12
+#define PAD (4)
+
+static double
+to_factor (double x)
+{
+#if 1
+ if (x > 1.)
+ return (x-1) * 100.;
+ else
+ return (1. - 1./x) * 100.;
+#else
+ return log (x);
+#endif
+}
+
+static int
+_double_cmp (const void *_a,
+ const void *_b)
+{
+ const double *a = _a;
+ const double *b = _b;
+
+ if (*a > *b)
+ return 1;
+ if (*a < *b)
+ return -1;
+ return 0;
+}
+
+static void
+trim_outliers (double *values,
+ int num_values,
+ double *min,
+ double *max)
+{
+ double q1, q3, iqr;
+ double outlier_min, outlier_max;
+ int i;
+
+ /* First, identify any outliers, using the definition of "mild
+ * outliers" from:
+ *
+ * http://en.wikipedia.org/wiki/Outliers
+ *
+ * Which is that outliers are any values less than Q1 - 1.5 * IQR
+ * or greater than Q3 + 1.5 * IQR where Q1 and Q3 are the first
+ * and third quartiles and IQR is the inter-quartile range (Q3 -
+ * Q1).
+ */
+ qsort (values, num_values,
+ sizeof (double), _double_cmp);
+
+ q1 = values[1*num_values / 6];
+ q3 = values[5*num_values / 6];
+
+ iqr = q3 - q1;
+
+ outlier_min = q1 - 3 * iqr;
+ outlier_max = q3 + 3 * iqr;
+
+ i = 0;
+ while (i < num_values && values[i] < outlier_min)
+ i++;
+ if (i == num_values)
+ return;
+
+ *min = values[i];
+
+ while (i < num_values && values[i] <= outlier_max)
+ i++;
+
+ *max = values[i-1];
+}
+
+static void
+find_ranges (struct chart *chart)
+{
+ test_report_t **tests, *min_test;
+ double *values;
+ int num_values, size_values;
+ double min = 0, max = 0;
+ double test_time;
+ int seen_non_null;
+ int num_tests = 0;
+ double slow_sum = 0, fast_sum = 0, sum;
+ int slow_count = 0, fast_count = 0;
+ int *count;
+ int i;
+
+ num_values = 0;
+ size_values = 64;
+ values = xmalloc (size_values * sizeof (double));
+
+ chart->average = xmalloc(chart->num_reports * sizeof(double));
+ count = xmalloc(chart->num_reports * sizeof(int));
+ for (i = 0; i < chart->num_reports; i++) {
+ chart->average[i] = 0;
+ count[i] = 0;
+ }
+
+ tests = xmalloc (chart->num_reports * sizeof (test_report_t *));
+ for (i = 0; i < chart->num_reports; i++)
+ tests[i] = chart->reports[i].tests;
+
+ while (1) {
+ /* We expect iterations values of 0 when multiple raw reports
+ * for the same test have been condensed into the stats of the
+ * first. So we just skip these later reports that have no
+ * stats. */
+ seen_non_null = 0;
+ for (i = 0; i < chart->num_reports; i++) {
+ while (tests[i]->name && tests[i]->stats.iterations == 0)
+ tests[i]++;
+ if (tests[i]->name)
+ seen_non_null++;
+ }
+ if (! seen_non_null)
+ break;
+
+ num_tests++;
+
+ /* Find the minimum of all current tests, (we have to do this
+ * in case some reports don't have a particular test). */
+ for (i = 0; i < chart->num_reports; i++) {
+ if (tests[i]->name) {
+ min_test = tests[i];
+ break;
+ }
+ }
+ for (++i; i < chart->num_reports; i++) {
+ if (tests[i]->name && test_report_cmp_name (tests[i], min_test) < 0)
+ min_test = tests[i];
+ }
+
+ test_time = 0;
+ for (i = 0; i < chart->num_reports; i++) {
+ double report_time = HUGE_VAL;
+
+ while (tests[i]->name &&
+ test_report_cmp_name (tests[i], min_test) == 0)
+ {
+ double time = tests[i]->stats.min_ticks;
+ if (time < report_time) {
+ time /= tests[i]->stats.ticks_per_ms;
+ if (time < report_time)
+ report_time = time;
+ }
+ tests[i]++;
+ }
+
+ if (report_time != HUGE_VAL) {
+ if (test_time == 0)
+ test_time = report_time;
+
+ chart->average[i] += report_time / test_time;
+ count[i]++;
+
+ if (chart->relative) {
+ if (test_time != report_time) {
+ double v = to_factor (test_time / report_time);
+ if (num_values == size_values) {
+ size_values *= 2;
+ values = xrealloc (values,
+ size_values * sizeof (double));
+ }
+ values[num_values++] = v;
+ if (v < min)
+ min = v;
+ if (v > max)
+ max = v;
+ if (v > 0)
+ fast_sum += v/100, fast_count++;
+ else
+ slow_sum += v/100, slow_count++;
+ sum += v/100;
+ printf ("%s %d: %f\n", min_test->name, num_values, v);
+ }
+ } else {
+ if (report_time < min)
+ min = report_time;
+ if (report_time > max)
+ max = report_time;
+ }
+ }
+ }
+ }
+
+ for (i = 0; i < chart->num_reports; i++) {
+ if (count[i])
+ chart->average[i] = count[i] / chart->average[i];
+ else
+ chart->average[i] = 1.;
+ }
+
+ if (chart->relative)
+ trim_outliers (values, num_values, &min, &max);
+ chart->min_value = min;
+ chart->max_value = max;
+ chart->num_tests = num_tests + !!chart->relative;
+
+ free (values);
+ free (tests);
+ free (count);
+
+ printf ("%d: slow[%d] average: %f, fast[%d] average: %f, %f\n",
+ num_values, slow_count, slow_sum / slow_count, fast_count, fast_sum / fast_count, sum / num_values);
+}
+
+#define SET_COLOR(C, R, G, B) (C)->red = (R), (C)->green = (G), (C)->blue = (B)
+static void
+hsv_to_rgb (double h,
+ double s,
+ double v,
+ struct color *color)
+{
+ double m, n, f;
+ int i;
+
+ while (h < 0)
+ h += 6.;
+ while (h > 6.)
+ h -= 6.;
+
+ if (s < 0.)
+ s = 0.;
+ if (s > 1.)
+ s = 1.;
+
+ if (v < 0.)
+ v = 0.;
+ if (v > 1.)
+ v = 1.;
+
+ i = floor (h);
+ f = h - i;
+ if ((i & 1) == 0)
+ f = 1 - f;
+
+ m = v * (1 - s);
+ n = v * (1 - s * f);
+ switch(i){
+ default:
+ case 6:
+ case 0: SET_COLOR (color, v, n, m); break;
+ case 1: SET_COLOR (color, n, v, m); break;
+ case 2: SET_COLOR (color, m, v, n); break;
+ case 3: SET_COLOR (color, m, n, v); break;
+ case 4: SET_COLOR (color, n, m, v); break;
+ case 5: SET_COLOR (color, v, m, n); break;
+ }
+}
+
+static void set_report_color (struct chart *chart, int report)
+{
+ struct color color;
+
+ hsv_to_rgb (6. / chart->num_reports * report, .7, .7, &color);
+ cairo_set_source_rgb (chart->cr, color.red, color.green, color.blue);
+}
+
+static void set_report_gradient (struct chart *chart, int report,
+ double x, double y, double w, double h)
+{
+ struct color color;
+ cairo_pattern_t *p;
+
+ hsv_to_rgb (6. / chart->num_reports * report, .7, .7, &color);
+
+ p = cairo_pattern_create_linear (x, 0, x+w, 0);
+ cairo_pattern_add_color_stop_rgba (p, 0.0,
+ color.red, color.green, color.blue,
+ .50);
+ cairo_pattern_add_color_stop_rgba (p, 0.5,
+ color.red, color.green, color.blue,
+ .50);
+ cairo_pattern_add_color_stop_rgba (p, 1.0,
+ color.red, color.green, color.blue,
+ 1.0);
+ cairo_set_source (chart->cr, p);
+ cairo_pattern_destroy (p);
+}
+
+static void
+test_background (struct chart *c,
+ int test)
+{
+ double dx, x;
+
+ dx = c->width / (double) c->num_tests;
+ x = dx * test;
+
+ if (test & 1)
+ cairo_set_source_rgba (c->cr, .2, .2, .2, .2);
+ else
+ cairo_set_source_rgba (c->cr, .8, .8, .8, .2);
+
+ cairo_rectangle (c->cr, floor (x), 0,
+ floor (dx + x) - floor (x), c->height);
+ cairo_fill (c->cr);
+}
+
+static void
+add_chart (struct chart *c,
+ int test,
+ int report,
+ double value)
+{
+ double dx, dy, x;
+
+ if (fabs (value) < 0.1)
+ return;
+
+ if (c->relative) {
+ cairo_text_extents_t extents;
+ char buf[80];
+ double y;
+
+ dy = (c->height/2. - PAD) / MAX (-c->min_value, c->max_value);
+ /* the first report is always skipped, as it is used as the baseline */
+ dx = c->width / (double) (c->num_tests * c->num_reports);
+ x = dx * (c->num_reports * test + report - .5);
+
+ cairo_rectangle (c->cr,
+ floor (x), c->height / 2.,
+ floor (x + dx) - floor (x),
+ ceil (-dy*value - c->height/2.) + c->height/2.);
+ if (dx < 5) {
+ set_report_color (c, report);
+ cairo_fill (c->cr);
+ } else {
+ set_report_gradient (c, report,
+ floor (x), c->height / 2.,
+ floor (x + dx) - floor (x),
+ ceil (-dy*value - c->height/2.) + c->height/2.);
+
+ cairo_fill_preserve (c->cr);
+ cairo_save (c->cr);
+ cairo_clip_preserve (c->cr);
+ set_report_color (c, report);
+ cairo_stroke (c->cr);
+ cairo_restore (c->cr);
+ }
+
+ /* Skip the label if the difference between the two is less than 0.1% */
+ if (fabs (value) < 0.1)
+ return;
+
+ cairo_save (c->cr);
+ cairo_set_font_size (c->cr, dx - 2);
+
+ if (value < 0) {
+ sprintf (buf, "%.1f", -value/100 + 1);
+ } else {
+ sprintf (buf, "%.1f", value/100 + 1);
+ }
+ cairo_text_extents (c->cr, buf, &extents);
+
+ /* will it be clipped? */
+ y = -dy * value;
+ if (y < -c->height/2) {
+ y = -c->height/2;
+ } else if (y > c->height/2) {
+ y = c->height/2;
+ }
+
+ if (y < 0) {
+ if (y > -extents.width - 6)
+ y -= extents.width + 6;
+ } else {
+ if (y < extents.width + 6)
+ y += extents.width + 6;
+ }
+
+ cairo_translate (c->cr,
+ floor (x) + (floor (x + dx) - floor (x))/2,
+ floor (y) + c->height/2.);
+ cairo_rotate (c->cr, -M_PI/2);
+ if (y < 0) {
+ cairo_move_to (c->cr, -extents.x_bearing -extents.width - 4, -extents.y_bearing/2);
+ } else {
+ cairo_move_to (c->cr, 2, -extents.y_bearing/2);
+ }
+
+ cairo_set_source_rgb (c->cr, .95, .95, .95);
+ cairo_show_text (c->cr, buf);
+ cairo_restore (c->cr);
+ } else {
+ dy = (c->height - PAD) / c->max_value;
+ dx = c->width / (double) (c->num_tests * (c->num_reports+1));
+ x = dx * ((c->num_reports+1) * test + report + .5);
+
+ cairo_rectangle (c->cr,
+ floor (x), c->height,
+ floor (x + dx) - floor (x),
+ floor (c->height - dy*value) - c->height);
+ if (dx < 5) {
+ set_report_color (c, report);
+ cairo_fill (c->cr);
+ } else {
+ set_report_gradient (c, report,
+ floor (x), c->height,
+ floor (x + dx) - floor (x),
+ floor (c->height - dy*value) - c->height);
+ cairo_fill_preserve (c->cr);
+ cairo_save (c->cr);
+ cairo_clip_preserve (c->cr);
+ set_report_color (c, report);
+ cairo_stroke (c->cr);
+ cairo_restore (c->cr);
+ }
+ }
+}
+
+static void
+add_average (struct chart *c,
+ int test,
+ int report,
+ double value)
+{
+ double dx, dy, x;
+ cairo_text_extents_t extents;
+ char buf[80];
+ double y;
+
+ if (fabs (value) < 0.1)
+ return;
+
+ dy = (c->height/2. - PAD) / MAX (-c->min_value, c->max_value);
+ /* the first report is always skipped, as it is used as the baseline */
+ dx = c->width / (double) (c->num_tests * c->num_reports);
+ x = dx * (c->num_reports * test + report - .5);
+
+ cairo_rectangle (c->cr,
+ floor (x), c->height / 2.,
+ floor (x + dx) - floor (x),
+ ceil (-dy*value - c->height/2.) + c->height/2.);
+ if (dx < 5) {
+ set_report_color (c, report);
+ cairo_fill (c->cr);
+ } else {
+ set_report_gradient (c, report,
+ floor (x), c->height / 2.,
+ floor (x + dx) - floor (x),
+ ceil (-dy*value - c->height/2.) + c->height/2.);
+
+ cairo_fill_preserve (c->cr);
+ cairo_save (c->cr);
+ cairo_clip_preserve (c->cr);
+ set_report_color (c, report);
+ cairo_stroke (c->cr);
+ cairo_restore (c->cr);
+ }
+
+ /* Skip the label if the difference between the two is less than 0.1% */
+ if (fabs (value) < 0.1)
+ return;
+
+ cairo_save (c->cr);
+ cairo_set_font_size (c->cr, dx - 2);
+
+ if (value < 0) {
+ sprintf (buf, "%.1f", -value/100 + 1);
+ } else {
+ sprintf (buf, "%.1f", value/100 + 1);
+ }
+ cairo_text_extents (c->cr, buf, &extents);
+
+ /* will it be clipped? */
+ y = -dy * value;
+ if (y < -c->height/2) {
+ y = -c->height/2;
+ } else if (y > c->height/2) {
+ y = c->height/2;
+ }
+
+ if (y < 0) {
+ if (y > -extents.width - 6)
+ y -= extents.width + 6;
+ } else {
+ if (y < extents.width + 6)
+ y += extents.width + 6;
+ }
+
+ cairo_translate (c->cr,
+ floor (x) + (floor (x + dx) - floor (x))/2,
+ floor (y) + c->height/2.);
+ cairo_rotate (c->cr, -M_PI/2);
+ if (y < 0) {
+ cairo_move_to (c->cr, -extents.x_bearing -extents.width - 4, -extents.y_bearing/2);
+ } else {
+ cairo_move_to (c->cr, 2, -extents.y_bearing/2);
+ }
+
+ cairo_set_source_rgb (c->cr, .95, .95, .95);
+ cairo_show_text (c->cr, buf);
+ cairo_restore (c->cr);
+}
+
+static void
+add_label (struct chart *c,
+ int test,
+ const char *label)
+{
+ cairo_text_extents_t extents;
+ double dx, x;
+
+ cairo_save (c->cr);
+ dx = c->width / (double) c->num_tests;
+ if (dx / 2 - PAD < 4)
+ return;
+ cairo_set_font_size (c->cr, dx / 2 - PAD);
+ cairo_text_extents (c->cr, label, &extents);
+
+ cairo_set_source_rgb (c->cr, .5, .5, .5);
+
+ x = (test + .5) * dx;
+ cairo_save (c->cr);
+ cairo_translate (c->cr, x, c->height - PAD / 2);
+ cairo_rotate (c->cr, -M_PI/2);
+ cairo_move_to (c->cr, 0, -extents.y_bearing/2);
+ cairo_show_text (c->cr, label);
+ cairo_restore (c->cr);
+
+ cairo_save (c->cr);
+ cairo_translate (c->cr, x, PAD / 2);
+ cairo_rotate (c->cr, -M_PI/2);
+ cairo_move_to (c->cr, -extents.width, -extents.y_bearing/2);
+ cairo_show_text (c->cr, label);
+ cairo_restore (c->cr);
+
+ cairo_restore (c->cr);
+}
+
+static void
+add_base_line (struct chart *c)
+{
+ double y;
+
+ cairo_save (c->cr);
+ cairo_set_line_width (c->cr, 2.);
+ if (c->relative) {
+ y = c->height / 2.;
+ } else {
+ y = c->height;
+ }
+ cairo_move_to (c->cr, 0, y);
+ cairo_line_to (c->cr, c->width, y);
+ cairo_set_source_rgb (c->cr, 1, 1, 1);
+ cairo_stroke (c->cr);
+ cairo_restore (c->cr);
+}
+
+static void
+add_absolute_lines (struct chart *c)
+{
+ const double dashes[] = { 2, 4 };
+ const double vlog_steps[] = { 10, 5, 4, 3, 2, 1, .5, .4, .3, .2, .1};
+ double v, y, dy;
+ unsigned int i;
+ char buf[80];
+ cairo_text_extents_t extents;
+
+ v = c->max_value / 2.;
+
+ for (i = 0; i < sizeof (vlog_steps) / sizeof (vlog_steps[0]); i++) {
+ double vlog = log (v) / log (vlog_steps[i]);
+ if (vlog > 1) {
+ v = pow (vlog_steps[i], floor (vlog));
+ goto done;
+ }
+ }
+ return;
+done:
+
+ dy = (c->height - PAD) / c->max_value;
+
+ cairo_save (c->cr);
+ cairo_set_line_width (c->cr, 1.);
+ cairo_set_dash (c->cr, dashes, sizeof (dashes) / sizeof (dashes[0]), 0);
+
+ i = 0;
+ do {
+ y = c->height - ++i * v * dy;
+ if (y < PAD)
+ break;
+
+ cairo_set_font_size (c->cr, 8);
+
+ sprintf (buf, "%.0fs", i*v/1000);
+ cairo_text_extents (c->cr, buf, &extents);
+
+ cairo_set_source_rgba (c->cr, .75, 0, 0, .95);
+ cairo_move_to (c->cr, 1-extents.x_bearing, floor (y) - (extents.height/2 + extents.y_bearing) + .5);
+ cairo_show_text (c->cr, buf);
+
+ cairo_move_to (c->cr, c->width-extents.width-1, floor (y) - (extents.height/2 + extents.y_bearing) + .5);
+ cairo_show_text (c->cr, buf);
+
+ cairo_set_source_rgba (c->cr, .75, 0, 0, .5);
+ cairo_move_to (c->cr,
+ ceil (extents.width + extents.x_bearing + 2),
+ floor (y) + .5);
+ cairo_line_to (c->cr,
+ floor (c->width - (extents.width + extents.x_bearing + 2)),
+ floor (y) + .5);
+ cairo_stroke (c->cr);
+ } while (1);
+
+ cairo_restore (c->cr);
+}
+
+static void
+add_relative_lines (struct chart *c)
+{
+ const double dashes[] = { 2, 4 };
+ const double v_steps[] = { 10, 5, 1, .5, .1, .05, .01};
+ const int precision_steps[] = { 0, 0, 0, 1, 1, 2, 2};
+ int precision;
+ double v, y, dy, mid;
+ unsigned int i;
+ char buf[80];
+ cairo_text_extents_t extents;
+
+ v = MAX (-c->min_value, c->max_value) / 200;
+
+ for (i = 0; i < sizeof (v_steps) / sizeof (v_steps[0]); i++) {
+ if (v > v_steps[i]) {
+ v = v_steps[i];
+ precision = precision_steps[i];
+ goto done;
+ }
+ }
+ return;
+done:
+
+ mid = c->height/2.;
+ dy = (mid - PAD) / MAX (-c->min_value, c->max_value);
+
+ cairo_save (c->cr);
+ cairo_set_line_width (c->cr, 1.);
+ cairo_set_dash (c->cr, dashes, sizeof (dashes) / sizeof (dashes[0]), 0);
+ cairo_set_font_size (c->cr, 8);
+
+ i = 0;
+ do {
+ y = ++i * v * dy * 100;
+ if (y > mid)
+ break;
+
+ sprintf (buf, "%.*fx", precision, i*v + 1);
+ cairo_text_extents (c->cr, buf, &extents);
+
+ cairo_set_source_rgba (c->cr, .75, 0, 0, .95);
+ cairo_move_to (c->cr, 1-extents.x_bearing, floor (mid + y) - (extents.height/2 + extents.y_bearing) + .5);
+ cairo_show_text (c->cr, buf);
+
+ cairo_move_to (c->cr, c->width-extents.width-1, floor (mid + y) - (extents.height/2 + extents.y_bearing) + .5);
+ cairo_show_text (c->cr, buf);
+
+ cairo_set_source_rgba (c->cr, 0, .75, 0, .95);
+ cairo_move_to (c->cr, 1-extents.x_bearing, ceil (mid - y) - (extents.height/2 + extents.y_bearing) + .5);
+ cairo_show_text (c->cr, buf);
+
+ cairo_move_to (c->cr, c->width-extents.width-1, ceil (mid - y) - (extents.height/2 + extents.y_bearing) + .5);
+ cairo_show_text (c->cr, buf);
+
+ /* trim the dashes to no obscure the labels */
+ cairo_set_source_rgba (c->cr, .75, 0, 0, .5);
+ cairo_move_to (c->cr,
+ ceil (extents.width + extents.x_bearing + 2),
+ floor (mid + y) + .5);
+ cairo_line_to (c->cr,
+ floor (c->width - (extents.width + 2)),
+ floor (mid + y) + .5);
+ cairo_stroke (c->cr);
+
+ cairo_set_source_rgba (c->cr, 0, .75, 0, .5);
+ cairo_move_to (c->cr,
+ ceil (extents.width + extents.x_bearing + 2),
+ ceil (mid - y) + .5);
+ cairo_line_to (c->cr,
+ floor (c->width - (extents.width + 2)),
+ ceil (mid - y) + .5);
+ cairo_stroke (c->cr);
+
+ } while (1);
+
+ cairo_restore (c->cr);
+}
+
+static void
+add_slower_faster_guide (struct chart *c)
+{
+ cairo_text_extents_t extents;
+
+ cairo_save (c->cr);
+
+ cairo_set_font_size (c->cr, FONT_SIZE);
+
+ cairo_text_extents (c->cr, "FASTER", &extents);
+ cairo_set_source_rgba (c->cr, 0, .75, 0, .5);
+ cairo_move_to (c->cr,
+ c->width/4. - extents.width/2. + extents.x_bearing,
+ 1 - extents.y_bearing);
+ cairo_show_text (c->cr, "FASTER");
+ cairo_move_to (c->cr,
+ 3*c->width/4. - extents.width/2. + extents.x_bearing,
+ 1 - extents.y_bearing);
+ cairo_show_text (c->cr, "FASTER");
+
+ cairo_text_extents (c->cr, "SLOWER", &extents);
+ cairo_set_source_rgba (c->cr, .75, 0, 0, .5);
+ cairo_move_to (c->cr,
+ c->width/4. - extents.width/2. + extents.x_bearing,
+ c->height - 1);
+ cairo_show_text (c->cr, "SLOWER");
+ cairo_move_to (c->cr,
+ 3*c->width/4. - extents.width/2. + extents.x_bearing,
+ c->height - 1);
+ cairo_show_text (c->cr, "SLOWER");
+
+ cairo_restore (c->cr);
+}
+
+static void
+cairo_perf_reports_compare (struct chart *chart,
+ cairo_bool_t print)
+{
+ test_report_t **tests, *min_test;
+ double test_time, best_time;
+ int num_test = 0;
+ int seen_non_null;
+ int i;
+
+ tests = xmalloc (chart->num_reports * sizeof (test_report_t *));
+ for (i = 0; i < chart->num_reports; i++)
+ tests[i] = chart->reports[i].tests;
+
+ if (print) {
+ if (chart->use_html) {
+ printf ("<table style=\"text-align:right\" cellspacing=\"4\">\n");
+ printf ("<tr><td></td>");
+ for (i = 0; i < chart->num_reports; i++) {
+ printf ("<td>%s</td>", chart->names[i] ? chart->names[i] : "");
+ }
+ printf ("</tr>\n");
+ }
+ }
+
+ while (1) {
+ /* We expect iterations values of 0 when multiple raw reports
+ * for the same test have been condensed into the stats of the
+ * first. So we just skip these later reports that have no
+ * stats. */
+ seen_non_null = 0;
+ for (i = 0; i < chart->num_reports; i++) {
+ while (tests[i]->name && tests[i]->stats.iterations == 0)
+ tests[i]++;
+ if (tests[i]->name)
+ seen_non_null++;
+ }
+ if (! seen_non_null)
+ break;
+
+ /* Find the minimum of all current tests, (we have to do this
+ * in case some reports don't have a particular test). */
+ for (i = 0; i < chart->num_reports; i++) {
+ if (tests[i]->name) {
+ min_test = tests[i];
+ break;
+ }
+ }
+ for (++i; i < chart->num_reports; i++) {
+ if (tests[i]->name && test_report_cmp_name (tests[i], min_test) < 0)
+ min_test = tests[i];
+ }
+
+ add_label (chart, num_test, min_test->name);
+ if (print) {
+ if (chart->use_html) {
+ printf ("<tr><td>%s</td>", min_test->name);
+ } else {
+ if (min_test->size) {
+ printf ("%16s, size %4d:\n",
+ min_test->name,
+ min_test->size);
+ } else {
+ printf ("%26s:",
+ min_test->name);
+ }
+ }
+ }
+
+ test_time = 0;
+ best_time = HUGE_VAL;
+ for (i = 0; i < chart->num_reports; i++) {
+ test_report_t *initial = tests[i];
+ double report_time = HUGE_VAL;
+
+ while (tests[i]->name &&
+ test_report_cmp_name (tests[i], min_test) == 0)
+ {
+ double time = tests[i]->stats.min_ticks;
+ if (time < report_time) {
+ time /= tests[i]->stats.ticks_per_ms;
+ if (time < report_time)
+ report_time = time;
+ }
+ tests[i]++;
+ }
+
+ if (test_time == 0 && report_time != HUGE_VAL)
+ test_time = report_time;
+ if (report_time < best_time)
+ best_time = report_time;
+
+ tests[i] = initial;
+ }
+
+ for (i = 0; i < chart->num_reports; i++) {
+ double report_time = HUGE_VAL;
+
+ while (tests[i]->name &&
+ test_report_cmp_name (tests[i], min_test) == 0)
+ {
+ double time = tests[i]->stats.min_ticks;
+ if (time > 0) {
+ time /= tests[i]->stats.ticks_per_ms;
+ if (time < report_time)
+ report_time = time;
+ }
+ tests[i]++;
+ }
+
+ if (print) {
+ if (chart->use_html) {
+ if (report_time < HUGE_VAL) {
+ if (report_time / best_time < 1.01) {
+ printf ("<td><strong>%.1f</strong></td>", report_time/1000);
+ } else {
+ printf ("<td>%.1f</td>", report_time/1000);
+ }
+ } else {
+ printf ("<td></td>");
+ }
+ } else {
+ if (report_time < HUGE_VAL)
+ printf (" %6.1f", report_time/1000);
+ else
+ printf (" ---");
+ }
+ }
+
+ if (report_time < HUGE_VAL) {
+ if (chart->relative) {
+ add_chart (chart, num_test, i,
+ to_factor (test_time / report_time));
+ } else {
+ add_chart (chart, num_test, i, report_time);
+ }
+ }
+ }
+
+ if (print) {
+ if (chart->use_html) {
+ printf ("</tr>\n");
+ } else {
+ printf ("\n");
+ }
+ }
+
+ num_test++;
+ }
+ if (chart->relative) {
+ add_label (chart, num_test, "(geometric mean)");
+ for (i = 0; i < chart->num_reports; i++)
+ add_average (chart, num_test, i, to_factor (chart->average[i]));
+ }
+ free (tests);
+
+ if (print) {
+ if (chart->use_html)
+ printf ("</table>\n");
+
+ printf ("\n");
+ for (i = 0; i < chart->num_reports; i++) {
+ if (chart->names[i]) {
+ printf ("[%s] %s\n",
+ chart->names[i], chart->reports[i].configuration);
+ } else {
+ printf ("[%d] %s\n",
+ i, chart->reports[i].configuration);
+ }
+ }
+ }
+}
+
+static void
+add_legend (struct chart *chart)
+{
+ cairo_text_extents_t extents;
+ const char *str;
+ int i, x, y;
+
+ cairo_set_font_size (chart->cr, FONT_SIZE);
+
+ x = PAD;
+ y = chart->height + PAD;
+ for (i = chart->relative; i < chart->num_reports; i++) {
+ str = chart->names[i] ?
+ chart->names[i] : chart->reports[i].configuration;
+
+ set_report_color (chart, i);
+
+ cairo_rectangle (chart->cr, x, y + 6, 8, 8);
+ cairo_fill (chart->cr);
+
+ cairo_set_source_rgb (chart->cr, 1, 1, 1);
+ cairo_move_to (chart->cr, x + 10, y + FONT_SIZE + PAD / 2.);
+ cairo_text_extents (chart->cr, str, &extents);
+ cairo_show_text (chart->cr, str);
+
+ x += 10 + 2 * PAD + ceil (extents.width);
+ }
+
+ if (chart->relative) {
+ char buf[80];
+
+ str = chart->names[0] ?
+ chart->names[0] : chart->reports[0].configuration;
+
+ sprintf (buf, "(relative to %s)", str);
+ cairo_text_extents (chart->cr, buf, &extents);
+
+ cairo_set_source_rgb (chart->cr, 1, 1, 1);
+ cairo_move_to (chart->cr,
+ chart->width - 1 - extents.width,
+ y + FONT_SIZE + PAD / 2.);
+ cairo_show_text (chart->cr, buf);
+ }
+}
+
+static void
+usage (void)
+{
+ printf("Usage:\n");
+ printf(" cairo-perf-chart [OPTION...] <result1> <result2>...<resultN>\n");
+ printf("\n");
+ printf("Help Options:\n");
+ printf(" --help, --?\tShow help options\n");
+ printf("\n");
+ printf("Application Options:\n");
+ printf(" --html\tOutput an HTML table comparing the results\n");
+ printf(" --height=\tSet the height of the output graph"\
+ " (default 480)\n");
+ printf(" --width=\tSet the width of the output graph"\
+ " (default 640)\n");
+ printf(" --name\tSet the name of graph series."\
+ " This only sets the name for the\n\t\tfirst result file."\
+ " The graph series is usually set using the\n\t\tfile name for"\
+ " the results file.\n");
+ printf("\n");
+ printf("Example:\n");
+ printf(" cairo-perf-chart --width=1024 --height=768 run1 run2 run3\n");
+ return;
+}
+
+int
+main (int argc,
+ const char *argv[])
+{
+ cairo_surface_t *surface;
+ struct chart chart;
+ test_report_t *t;
+ int i;
+
+ chart.use_html = 0;
+ chart.width = 640;
+ chart.height = 480;
+
+ chart.reports = xcalloc (argc-1, sizeof (cairo_perf_report_t));
+ chart.names = xcalloc (argc-1, sizeof (cairo_perf_report_t));
+
+ chart.num_reports = 0;
+ for (i = 1; i < argc; i++) {
+ if (strcmp (argv[i], "--html") == 0) {
+ chart.use_html = 1;
+ } else if (strncmp (argv[i], "--width=", 8) == 0) {
+ chart.width = atoi (argv[i] + 8);
+ } else if (strncmp (argv[i], "--height=", 9) == 0) {
+ chart.height = atoi (argv[i] + 9);
+ } else if (strcmp (argv[i], "--name") == 0) {
+ if (i + 1 < argc)
+ chart.names[chart.num_reports] = argv[++i];
+ } else if (strncmp (argv[i], "--name=", 7) == 0) {
+ chart.names[chart.num_reports] = argv[i] + 7;
+ } else if ((strcmp (argv[i], "--help") == 0) ||
+ (strcmp (argv[i], "--?") == 0)) {
+ usage();
+ return 0;
+ } else {
+ cairo_perf_report_load (&chart.reports[chart.num_reports++],
+ argv[i], i,
+ test_report_cmp_name);
+ }
+ }
+
+ for (chart.relative = 0; chart.relative <= 1; chart.relative++) {
+ surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
+ chart.width,
+ chart.height + (FONT_SIZE + PAD) + 2*PAD);
+ chart.cr = cairo_create (surface);
+ cairo_surface_destroy (surface);
+
+ cairo_set_source_rgb (chart.cr, 0, 0, 0);
+ cairo_paint (chart.cr);
+
+ find_ranges (&chart);
+
+ for (i = 0; i < chart.num_tests; i++)
+ test_background (&chart, i);
+ if (chart.relative) {
+ add_relative_lines (&chart);
+ add_slower_faster_guide (&chart);
+ } else
+ add_absolute_lines (&chart);
+
+ cairo_save (chart.cr);
+ cairo_rectangle (chart.cr, 0, 0, chart.width, chart.height);
+ cairo_clip (chart.cr);
+ cairo_perf_reports_compare (&chart, !chart.relative);
+ cairo_restore (chart.cr);
+
+ add_base_line (&chart);
+ add_legend (&chart);
+
+ cairo_surface_write_to_png (cairo_get_target (chart.cr),
+ chart.relative ? "relative.png" : "absolute.png");
+ cairo_destroy (chart.cr);
+ }
+
+ /* Pointless memory cleanup, (would be a great place for talloc) */
+ for (i = 0; i < chart.num_reports; i++) {
+ for (t = chart.reports[i].tests; t->name; t++) {
+ free (t->samples);
+ free (t->backend);
+ free (t->name);
+ }
+ free (chart.reports[i].tests);
+ free (chart.reports[i].configuration);
+ }
+ free (chart.names);
+ free (chart.reports);
+
+ return 0;
+}
diff --git a/perf/cairo-perf-compare-backends.c b/perf/cairo-perf-compare-backends.c
new file mode 100644
index 000000000..ff7359e1a
--- /dev/null
+++ b/perf/cairo-perf-compare-backends.c
@@ -0,0 +1,398 @@
+/*
+ * Copyright © 2006 Red Hat, Inc.
+ * Copyright © 2009 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of the
+ * copyright holders not be used in advertising or publicity
+ * pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied
+ * warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ *
+ * Authors: Carl Worth <cworth@cworth.org>
+ * Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-perf.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <ctype.h>
+#include <math.h>
+#include <assert.h>
+
+typedef struct _cairo_perf_report_options {
+ double min_change;
+ int use_utf;
+ int print_change_bars;
+} cairo_perf_report_options_t;
+
+typedef struct _cairo_perf_diff_files_args {
+ const char **filenames;
+ int num_filenames;
+ cairo_perf_report_options_t options;
+} cairo_perf_diff_files_args_t;
+
+static int
+test_diff_cmp (const void *a,
+ const void *b)
+{
+ const test_diff_t *a_diff = a;
+ const test_diff_t *b_diff = b;
+
+ /* Reverse sort by magnitude of change so larger changes come
+ * first */
+ if (a_diff->change > b_diff->change)
+ return -1;
+
+ if (a_diff->change < b_diff->change)
+ return 1;
+
+ return 0;
+}
+
+#define CHANGE_BAR_WIDTH 70
+static void
+print_change_bar (double change,
+ double max_change,
+ int use_utf)
+{
+ int units_per_cell = ceil (max_change / CHANGE_BAR_WIDTH);
+ static char const *ascii_boxes[8] = {
+ "****","***" ,"***", "**",
+ "**", "*", "*", ""
+ };
+ static char const *utf_boxes[8] = {
+ "█", "▉", "▊", "▋",
+ "▌", "▍", "▎", "▏"
+ };
+ char const **boxes = use_utf ? utf_boxes : ascii_boxes;
+
+ /* For a 1.0x speedup we want a zero-size bar to show "no
+ * change". */
+ change -= 1.0;
+
+ while (change > units_per_cell) {
+ printf ("%s", boxes[0]);
+ change -= units_per_cell;
+ }
+
+ change /= units_per_cell;
+
+ if (change > 7.5/8.0)
+ printf ("%s", boxes[0]);
+ else if (change > 6.5/8.0)
+ printf ("%s", boxes[1]);
+ else if (change > 5.5/8.0)
+ printf ("%s", boxes[2]);
+ else if (change > 4.5/8.0)
+ printf ("%s", boxes[3]);
+ else if (change > 3.5/8.0)
+ printf ("%s", boxes[4]);
+ else if (change > 2.5/8.0)
+ printf ("%s", boxes[5]);
+ else if (change > 1.5/8.0)
+ printf ("%s", boxes[6]);
+ else if (change > 0.5/8.0)
+ printf ("%s", boxes[7]);
+}
+
+static void
+test_diff_print (test_diff_t *diff,
+ double max_change,
+ cairo_perf_report_options_t *options)
+{
+ int i;
+ double test_time;
+ double change;
+
+ if (diff->tests[0]->size != 0) {
+ printf ("(%s, size: %d)\n",
+ diff->tests[0]->name,
+ diff->tests[0]->size);
+ } else {
+ printf ("(%s)\n", diff->tests[0]->name);
+ }
+
+ for (i = 0; i < diff->num_tests; i++) {
+ test_time = diff->tests[i]->stats.min_ticks;
+ test_time /= diff->tests[i]->stats.ticks_per_ms;
+ change = diff->max / test_time;
+ printf ("%8s-%s-%s\t%6.2f: %5.2fx ",
+ diff->tests[i]->backend,
+ diff->tests[i]->content,
+ diff->tests[i]->configuration,
+ diff->tests[i]->stats.min_ticks / diff->tests[i]->stats.ticks_per_ms,
+ change);
+
+ if (options->print_change_bars)
+ print_change_bar (change, max_change, options->use_utf);
+ printf ("\n");
+ }
+
+ printf("\n");
+}
+
+static void
+cairo_perf_reports_compare (cairo_perf_report_t *reports,
+ int num_reports,
+ cairo_perf_report_options_t *options)
+{
+ int i;
+ test_report_t **tests, *min_test;
+ test_diff_t *diff, *diffs;
+ int num_diffs, max_diffs;
+ double max_change;
+ double test_time;
+ int seen_non_null;
+
+ tests = xmalloc (num_reports * sizeof (test_report_t *));
+
+ max_diffs = reports[0].tests_count;
+ for (i = 0; i < num_reports; i++) {
+ tests[i] = reports[i].tests;
+ if (reports[i].tests_count > max_diffs)
+ max_diffs = reports[i].tests_count;
+ }
+
+ diff = diffs = xmalloc (max_diffs * sizeof (test_diff_t));
+
+ num_diffs = 0;
+ while (1) {
+ int num_tests;
+
+ /* We expect iterations values of 0 when multiple raw reports
+ * for the same test have been condensed into the stats of the
+ * first. So we just skip these later reports that have no
+ * stats. */
+ seen_non_null = 0;
+ for (i = 0; i < num_reports; i++) {
+ while (tests[i]->name && tests[i]->stats.iterations == 0)
+ tests[i]++;
+ if (tests[i]->name)
+ seen_non_null++;
+ }
+ if (! seen_non_null)
+ break;
+
+ /* Find the minimum of all current tests, (we have to do this
+ * in case some reports don't have a particular test). */
+ for (i = 0; i < num_reports; i++) {
+ if (tests[i]->name) {
+ min_test = tests[i];
+ break;
+ }
+ }
+ for (++i; i < num_reports; i++) {
+ if (tests[i]->name && test_report_cmp_name (tests[i], min_test) < 0)
+ min_test = tests[i];
+ }
+
+ num_tests = 0;
+ for (i = 0; i < num_reports; i++) {
+ test_report_t *test;
+ int n = 0;
+
+ test = tests[i];
+ while (test[n].name &&
+ test_report_cmp_name (&test[n], min_test) == 0)
+ {
+ n++;
+ }
+
+ num_tests += n;
+ }
+
+ /* For each report that has the current test, record it into
+ * the diff structure. */
+ diff->num_tests = 0;
+ diff->tests = xmalloc (num_tests * sizeof (test_diff_t));
+ for (i = 0; i < num_reports; i++) {
+ while (tests[i]->name &&
+ test_report_cmp_name (tests[i], min_test) == 0)
+ {
+ test_time = tests[i]->stats.min_ticks;
+ if (test_time > 0) {
+ test_time /= tests[i]->stats.ticks_per_ms;
+ if (diff->num_tests == 0) {
+ diff->min = test_time;
+ diff->max = test_time;
+ } else {
+ if (test_time < diff->min)
+ diff->min = test_time;
+ if (test_time > diff->max)
+ diff->max = test_time;
+ }
+ diff->tests[diff->num_tests++] = tests[i];
+ }
+ tests[i]++;
+ }
+ }
+ diff->change = diff->max / diff->min;
+
+ diff++;
+ num_diffs++;
+ }
+ if (num_diffs == 0)
+ goto DONE;
+
+ qsort (diffs, num_diffs, sizeof (test_diff_t), test_diff_cmp);
+
+ max_change = 1.0;
+ for (i = 0; i < num_diffs; i++) {
+ if (fabs (diffs[i].change) > max_change)
+ max_change = fabs (diffs[i].change);
+ }
+
+ for (i = 0; i < num_diffs; i++) {
+ diff = &diffs[i];
+
+ /* Discard as uninteresting a change which is less than the
+ * minimum change required, (default may be overridden on
+ * command-line). */
+ if (fabs (diff->change) - 1.0 < options->min_change)
+ continue;
+
+ test_diff_print (diff, max_change, options);
+ }
+
+ for (i = 0; i < num_diffs; i++)
+ free (diffs[i].tests);
+ DONE:
+ free (diffs);
+ free (tests);
+}
+
+static void
+usage (const char *argv0)
+{
+ char const *basename = strrchr(argv0, '/');
+ basename = basename ? basename+1 : argv0;
+ fprintf (stderr,
+ "Usage: %s [options] file [...]\n\n",
+ basename);
+ fprintf (stderr,
+ "Computes significant performance differences for cairo performance reports.\n"
+ "Each file should be the output of the cairo-perf program (or \"make perf\").\n"
+ "The following options are available:\n"
+ "\n"
+ "--no-utf Use ascii stars instead of utf-8 change bars.\n"
+ " Four stars are printed per factor of speedup.\n"
+ "\n"
+ "--no-bars Don't display change bars at all.\n\n"
+ "\n"
+ "--use-ms Use milliseconds to calculate differences.\n"
+ " (instead of ticks which are hardware dependent)\n"
+ "\n"
+ "--min-change threshold[%%]\n"
+ " Suppress all changes below the given threshold.\n"
+ " The default threshold of 0.05 or 5%% ignores any\n"
+ " speedup or slowdown of 1.05 or less. A threshold\n"
+ " of 0 will cause all output to be reported.\n"
+ );
+ exit(1);
+}
+
+static void
+parse_args (int argc,
+ char const **argv,
+ cairo_perf_diff_files_args_t *args)
+{
+ int i;
+
+ for (i = 1; i < argc; i++) {
+ if (strcmp (argv[i], "--no-utf") == 0) {
+ args->options.use_utf = 0;
+ }
+ else if (strcmp (argv[i], "--no-bars") == 0) {
+ args->options.print_change_bars = 0;
+ }
+ else if (strcmp (argv[i], "--min-change") == 0) {
+ char *end = NULL;
+ i++;
+ if (i >= argc)
+ usage (argv[0]);
+ args->options.min_change = strtod (argv[i], &end);
+ if (*end) {
+ if (*end == '%') {
+ args->options.min_change /= 100;
+ } else {
+ usage (argv[0]);
+ }
+ }
+ }
+ else {
+ args->num_filenames++;
+ args->filenames = xrealloc (args->filenames,
+ args->num_filenames * sizeof (char *));
+ args->filenames[args->num_filenames - 1] = argv[i];
+ }
+ }
+}
+
+int
+main (int argc,
+ const char *argv[])
+{
+ cairo_perf_diff_files_args_t args = {
+ NULL, /* filenames */
+ 0, /* num_filenames */
+ {
+ 0.05, /* min change */
+ 1, /* use UTF-8? */
+ 1, /* display change bars? */
+ }
+ };
+ cairo_perf_report_t *reports;
+ test_report_t *t;
+ int i;
+
+ parse_args (argc, argv, &args);
+
+ if (args.num_filenames) {
+ reports = xcalloc (args.num_filenames, sizeof (cairo_perf_report_t));
+ for (i = 0; i < args.num_filenames; i++) {
+ cairo_perf_report_load (&reports[i], args.filenames[i], i,
+ test_report_cmp_name);
+ printf ("loaded: %s, %d tests\n",
+ args.filenames[i], reports[i].tests_count);
+ }
+ } else {
+ args.num_filenames = 1;
+ reports = xcalloc (args.num_filenames, sizeof (cairo_perf_report_t));
+ cairo_perf_report_load (&reports[0], NULL, 0, test_report_cmp_name);
+ }
+
+ cairo_perf_reports_compare (reports, args.num_filenames, &args.options);
+
+ /* Pointless memory cleanup, (would be a great place for talloc) */
+ free (args.filenames);
+ for (i = 0; i < args.num_filenames; i++) {
+ for (t = reports[i].tests; t->name; t++) {
+ free (t->samples);
+ free (t->backend);
+ free (t->name);
+ }
+ free (reports[i].tests);
+ free (reports[i].configuration);
+ }
+ free (reports);
+
+ return 0;
+}
diff --git a/perf/cairo-perf-diff b/perf/cairo-perf-diff
new file mode 100755
index 000000000..5a4b7b386
--- /dev/null
+++ b/perf/cairo-perf-diff
@@ -0,0 +1,255 @@
+#!/bin/sh
+set -e
+
+usage() {
+ argv0=`basename $0`
+
+ cat >&2 << END
+Usage:
+For comparing files created my cairo-perf:
+
+ $argv0 old.perf new.perf
+
+For comparing (cached) performance of revisions:
+
+ $argv0 [OPTIONS] <revision> [-- cairo-perf options]
+ $argv0 [OPTIONS] <rev1> <rev2> [-- cairo-perf-options]
+
+If given a single revision, compares its results to that of its
+(first-parent) predecessor. Otherwise compares the two given revisions.
+The revisions can be any revision accepted by git. For example:
+
+ $argv0 HEAD # Show impact of latest commit
+ $argv0 1.2.0 1.2.4 # Compare performance of 1.2.0 to 1.2.4
+
+Options:
+
+-f, --force
+ Forces cairo-perf-diff to re-run performance tests
+ even if cached performance data is available.
+
+-h, --html
+ With this option performance changes are summarized
+ as HTML table.
+
+-t, --trace
+ Compare performance using trace replays instead of
+ microbenchmarks.
+
+Additional options can be passed the child cairo-perf process
+by separating them with a double hyphen (--). For example, to
+examine what the impact of the latest change is on the stroke
+test you might use:
+
+ $argv0 HEAD -- stroke
+
+The performance results are cached in .perf next to the .git directory.
+
+Set CAIRO_AUTOGEN_OPTIONS to pass options to autogen for both
+builds.
+END
+
+ exit 1
+}
+
+benchmark="cairo-perf-micro"
+
+# First, pull off any known options
+while true; do
+ case $1 in
+ -f|--force) force_cairo_perf="true";;
+ -h|--html) html_output="$2"; shift ;;
+ -t|--trace) benchmark="cairo-perf-trace";;
+ *) break;;
+ esac
+
+ shift
+done
+
+# Then if anything is left that still looks like an option, (begins
+# with a dash), give usage to catch --help or any other -garbage
+if [ $# -eq 0 ] || [ "`echo "$1" | sed 's/^-//'`" != "$1" ]; then
+ usage
+fi
+
+# Finally, pick up the actual revision arguments
+if [ $# -eq 1 ] || [ "$2" = "--" ]; then
+ old="$1^"
+ new="$1"
+ shift 1
+else
+ old="$1"
+ new="$2"
+ shift 2
+fi
+
+# And post-finally, pass anything after -- on to cairo-perf
+CAIRO_PERF_OPTIONS="-r -i 10"
+if [ $# -gt 0 ]; then
+ if [ "$1" = "--" ]; then
+ shift 1
+ CAIRO_PERF_OPTIONS="$CAIRO_PERF_OPTIONS $@"
+ else
+ usage
+ fi
+fi
+
+git_setup() {
+ SUBDIRECTORY_OK='Yes'
+ . "$(git --exec-path)/git-sh-setup"
+ CAIRO_DIR=`dirname $GIT_DIR`
+ if [ "$CAIRO_DIR" = "." ]; then
+ CAIRO_DIR=`pwd`
+ fi
+ CAIRO_PERF_DIR=$CAIRO_DIR/.perf
+}
+
+rev2sha() {
+ rev=$1
+ git rev-parse --verify $rev || ( echo "Cannot resolve $rev as a git object" && exit 1 )
+}
+
+cpu_count() {
+ test -f /proc/cpuinfo &&
+ grep -c '^processor[[:blank:]]\+:' /proc/cpuinfo ||
+ echo 1
+}
+
+# We cache performance output based on a two-part name capturing the
+# current performance test suite and the library being tested. We
+# capture these as the tree object of the perf directory in HEAD and
+# the tree object of the src directory of the revision being tested.
+#
+# This way, whenever the performance suite is updated, cached output
+# from old versions of the suite are automatically invalidated. Also,
+# if a commit just changes things outside of the src tree, (say it
+# changes the "test" test suite, or README or configure.in, or
+# whatever), cairo-perf-diff will be smart enough to still use cached
+# results from a run with an equivalent src tree.
+rev2perf() {
+ rev=$1
+ sha=`rev2sha $rev`
+ src_tree_sha=`rev2sha $rev:src`
+ perf_tree_sha=`rev2sha HEAD:perf`
+ script_tree_sha=`rev2sha HEAD:util/cairo-script`
+ echo "$CAIRO_PERF_DIR/${sha}-${perf_tree_sha}-${script_tree_sha}-${src_tree_sha}.perf"
+}
+rev2perf_glob() {
+ rev=$1
+ src_tree_sha=`rev2sha $rev:src`
+ perf_tree_sha=`rev2sha HEAD:perf`
+ script_tree_sha=`rev2sha HEAD:util/cairo-script`
+ echo "$CAIRO_PERF_DIR/*-${perf_tree_sha}-${script_tree_sha}-${src_tree_sha}.perf"
+}
+
+build() {
+ build_dir=$1
+ sha=$2
+
+ if [ ! -d $build_dir ]; then
+ git clone -s $CAIRO_DIR $build_dir
+ (cd $build_dir; git checkout -b tmp-cairo-perf-diff $sha)
+ fi
+ cd $build_dir
+
+ git checkout tmp-cairo-perf-diff
+ git reset --hard $sha
+
+ if [ -z "$MAKEFLAGS" ]; then
+ CPU_COUNT=`cpu_count`
+ export MAKEFLAGS="-j`expr $CPU_COUNT + 1`"
+ fi
+
+ if [ ! -e Makefile ]; then
+ ./autogen.sh $CAIRO_AUTOGEN_OPTIONS
+ fi
+
+ for file in $boilerplate_files; do
+ rsync $CAIRO_DIR/$file boilerplate
+ done
+ for file in $perf_files; do
+ rsync $CAIRO_DIR/$file perf
+ done
+ for file in $script_files; do
+ rsync $CAIRO_DIR/$file util/cairo-script
+ done
+
+ make || (rm config.cache && make)
+ (cd boilerplate && make libcairoboilerplate.la)
+
+ cd perf
+ make ${benchmark}
+}
+
+# Usage: run_cairo_perf_if_not_cached <rev> <suffix>
+# The <rev> argument must be a valid git ref-spec that can
+# be resolved to a commit. The suffix is just something
+# unique so that build directories can be separated for
+# multiple calls to this function.
+run_cairo_perf_if_not_cached() {
+ rev=$1
+ build_dir="build-$2"
+
+ owd=`pwd`
+ sha=`rev2sha $rev`
+ perf=`rev2perf $rev`
+ glob=`rev2perf_glob $rev`
+ if [ -e $glob ] && [ "$force_cairo_perf" != "true" ]; then
+ return 0
+ fi
+ if [ ! -d $CAIRO_PERF_DIR ]; then
+ echo "Creating new perf cache in $CAIRO_PERF_DIR"
+ mkdir $CAIRO_PERF_DIR
+ fi
+
+ cd $CAIRO_DIR
+ boilerplate_files=`git ls-tree --name-only HEAD boilerplate/*`
+ perf_files=`git ls-tree --name-only HEAD perf/*`
+ script_files=`git ls-tree --name-only HEAD util/cairo-script/*`
+ cd $CAIRO_PERF_DIR
+
+ build $build_dir $sha || {
+ rm -rf $build_dir
+ build $build_dir $sha || exit 1
+ }
+
+ echo "Running \"cairo-perf $CAIRO_PERF_OPTIONS\" against $rev. Results will be cached in:"
+ { ./$benchmark $CAIRO_PERF_OPTIONS || echo "*** Performance test crashed"; } >> $perf
+
+ cd $owd
+}
+
+git_setup
+
+if [ -e ./cairo-perf-diff-files ]; then
+ bindir="."
+else
+ bindir=$CAIRO_DIR/perf
+
+ # Build cairo-perf-diff-files if not available
+ if [ ! -e $bindir/cairo-perf-diff-files ]; then
+ echo "Building cairo-perf-diff-files"
+ if [ "x$OS" = "xWindows_NT" ]; then
+ make -f Makefile.win32 -C $bindir cairo-perf-diff-files CFG=debug
+ else
+ make -C $bindir cairo-perf-diff-files
+ fi
+ fi
+fi
+
+if [ ! -e $old ]; then
+ run_cairo_perf_if_not_cached $old old
+ old=`rev2perf $old`
+fi
+
+if [ ! -e $new ]; then
+ run_cairo_perf_if_not_cached $new new
+ new=`rev2perf $new`
+fi
+
+if [ -z "$html_output" ]; then
+ $bindir/cairo-perf-diff-files $old $new
+else
+ $bindir/cairo-perf-diff-files $old $new |
+ $CAIRO_DIR/perf/make-html.py > $html_output
+fi
diff --git a/perf/cairo-perf-diff-files.c b/perf/cairo-perf-diff-files.c
new file mode 100644
index 000000000..36b80cda4
--- /dev/null
+++ b/perf/cairo-perf-diff-files.c
@@ -0,0 +1,506 @@
+/*
+ * Copyright © 2006 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of the
+ * copyright holders not be used in advertising or publicity
+ * pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied
+ * warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ *
+ * Authors: Carl Worth <cworth@cworth.org>
+ */
+
+#include "cairo-perf.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <ctype.h>
+#include <math.h>
+#include <assert.h>
+
+typedef struct _cairo_perf_report_options {
+ double min_change;
+ int use_utf;
+ int print_change_bars;
+ int use_ticks;
+} cairo_perf_report_options_t;
+
+typedef struct _cairo_perf_diff_files_args {
+ const char **filenames;
+ int num_filenames;
+ cairo_perf_report_options_t options;
+} cairo_perf_diff_files_args_t;
+
+static int
+test_diff_cmp_speedup_before_slowdown (const void *a,
+ const void *b)
+{
+ const test_diff_t *a_diff = a;
+ const test_diff_t *b_diff = b;
+
+ /* First make all speedups come before all slowdowns. */
+ if (a_diff->change > 0 && b_diff->change < 0)
+ return -1;
+ if (a_diff->change < 0 && b_diff->change > 0)
+ return 1;
+
+ if (a_diff->change == b_diff->change)
+ return 0;
+
+ /* Large speedups come first. */
+ if (a_diff->change > 0) {
+ if (a_diff->change > b_diff->change)
+ return -1;
+ else
+ return 1;
+ }
+
+ /* Large slowdowns come last. */
+ if (a_diff->change < 0) {
+ if (a_diff->change < b_diff->change)
+ return 1;
+ else
+ return -1;
+ }
+
+ return 0;
+}
+
+static int
+test_diff_cmp (const void *a,
+ const void *b)
+{
+ const test_diff_t *a_diff = a;
+ const test_diff_t *b_diff = b;
+
+ /* Reverse sort by magnitude of change so larger changes come
+ * first */
+ if (a_diff->change > b_diff->change)
+ return -1;
+
+ if (a_diff->change < b_diff->change)
+ return 1;
+
+ return 0;
+}
+
+#define CHANGE_BAR_WIDTH 70
+static void
+print_change_bar (double change,
+ double max_change,
+ int use_utf)
+{
+ int units_per_cell = ceil (max_change / CHANGE_BAR_WIDTH);
+ static char const *ascii_boxes[8] = {
+ "****","***" ,"***", "**",
+ "**", "*", "*", ""
+ };
+ static char const *utf_boxes[8] = {
+ "█", "▉", "▊", "▋",
+ "▌", "▍", "▎", "▏"
+ };
+ char const **boxes = use_utf ? utf_boxes : ascii_boxes;
+
+ /* For a 1.0x speedup we want a zero-size bar to show "no
+ * change". */
+ change -= 1.0;
+
+ while (change > units_per_cell) {
+ printf ("%s", boxes[0]);
+ change -= units_per_cell;
+ }
+
+ change /= units_per_cell;
+
+ if (change > 7.5/8.0)
+ printf ("%s", boxes[0]);
+ else if (change > 6.5/8.0)
+ printf ("%s", boxes[1]);
+ else if (change > 5.5/8.0)
+ printf ("%s", boxes[2]);
+ else if (change > 4.5/8.0)
+ printf ("%s", boxes[3]);
+ else if (change > 3.5/8.0)
+ printf ("%s", boxes[4]);
+ else if (change > 2.5/8.0)
+ printf ("%s", boxes[5]);
+ else if (change > 1.5/8.0)
+ printf ("%s", boxes[6]);
+ else if (change > 0.5/8.0)
+ printf ("%s", boxes[7]);
+
+ printf ("\n");
+}
+
+static void
+test_diff_print_binary (test_diff_t *diff,
+ double max_change,
+ cairo_perf_report_options_t *options)
+{
+ if (diff->tests[0]->size)
+ printf ("%5s-%-4s %26s-%-3d",
+ diff->tests[0]->backend, diff->tests[0]->content,
+ diff->tests[0]->name, diff->tests[0]->size);
+ else
+ printf ("%5s %26s", diff->tests[0]->backend, diff->tests[0]->name);
+
+ printf (" %6.2f (%.2f %4.2f%%) -> %6.2f (%.2f %4.2f%%): %5.2fx ",
+ diff->tests[0]->stats.min_ticks / diff->tests[0]->stats.ticks_per_ms,
+ diff->tests[0]->stats.median_ticks / diff->tests[0]->stats.ticks_per_ms,
+ diff->tests[0]->stats.std_dev * 100,
+ diff->tests[1]->stats.min_ticks / diff->tests[1]->stats.ticks_per_ms,
+ diff->tests[1]->stats.median_ticks / diff->tests[1]->stats.ticks_per_ms,
+ diff->tests[1]->stats.std_dev * 100,
+ fabs (diff->change));
+
+ if (diff->change > 1.0)
+ printf ("speedup\n");
+ else
+ printf ("slowdown\n");
+
+ if (options->print_change_bars)
+ print_change_bar (fabs (diff->change), max_change,
+ options->use_utf);
+}
+
+static void
+test_diff_print_multi (test_diff_t *diff,
+ double max_change,
+ cairo_perf_report_options_t *options)
+{
+ int i;
+ double test_time;
+ double change;
+
+ if (diff->tests[0]->size) {
+ printf ("%s (backend: %s-%s, size: %d)\n",
+ diff->tests[0]->name,
+ diff->tests[0]->backend,
+ diff->tests[0]->content,
+ diff->tests[0]->size);
+ } else {
+ printf ("%s (backend: %s)\n",
+ diff->tests[0]->name,
+ diff->tests[0]->backend);
+ }
+
+ for (i = 0; i < diff->num_tests; i++) {
+ test_time = diff->tests[i]->stats.min_ticks;
+ if (! options->use_ticks)
+ test_time /= diff->tests[i]->stats.ticks_per_ms;
+ change = diff->max / test_time;
+ printf ("[%d] %6.2f: %5.2fx ",
+ diff->tests[i]->fileno,
+ diff->tests[i]->stats.min_ticks / diff->tests[i]->stats.ticks_per_ms,
+ change);
+
+ if (options->print_change_bars)
+ print_change_bar (change, max_change, options->use_utf);
+ else
+ printf("\n");
+ }
+
+ printf("\n");
+}
+
+static void
+cairo_perf_reports_compare (cairo_perf_report_t *reports,
+ int num_reports,
+ cairo_perf_report_options_t *options)
+{
+ int i;
+ test_report_t **tests, *min_test;
+ test_diff_t *diff, *diffs;
+ int num_diffs, max_diffs;
+ double max_change;
+ double test_time;
+ int seen_non_null;
+ cairo_bool_t printed_speedup = FALSE;
+ cairo_bool_t printed_slowdown = FALSE;
+
+ assert (num_reports >= 2);
+
+ tests = xmalloc (num_reports * sizeof (test_report_t *));
+
+ max_diffs = reports[0].tests_count;
+ for (i = 0; i < num_reports; i++) {
+ tests[i] = reports[i].tests;
+ if (reports[i].tests_count > max_diffs)
+ max_diffs = reports[i].tests_count;
+ }
+
+ diff = diffs = xmalloc (max_diffs * sizeof (test_diff_t));
+
+ num_diffs = 0;
+ while (1) {
+ /* We expect iterations values of 0 when multiple raw reports
+ * for the same test have been condensed into the stats of the
+ * first. So we just skip these later reports that have no
+ * stats. */
+ seen_non_null = 0;
+ for (i = 0; i < num_reports; i++) {
+ while (tests[i]->name && tests[i]->stats.iterations == 0)
+ tests[i]++;
+ if (tests[i]->name)
+ seen_non_null++;
+ }
+
+ if (seen_non_null < 2)
+ break;
+
+ /* Find the minimum of all current tests, (we have to do this
+ * in case some reports don't have a particular test). */
+ for (i = 0; i < num_reports; i++) {
+ if (tests[i]->name) {
+ min_test = tests[i];
+ break;
+ }
+ }
+ for (++i; i < num_reports; i++) {
+ if (tests[i]->name &&
+ test_report_cmp_backend_then_name (tests[i], min_test) < 0)
+ {
+ min_test = tests[i];
+ }
+ }
+
+ /* For each report that has the current test, record it into
+ * the diff structure. */
+ diff->num_tests = 0;
+ diff->tests = xmalloc (num_reports * sizeof (test_diff_t));
+ for (i = 0; i < num_reports; i++) {
+ if (tests[i]->name &&
+ test_report_cmp_backend_then_name (tests[i], min_test) == 0)
+ {
+ test_time = tests[i]->stats.min_ticks;
+ if (! options->use_ticks)
+ test_time /= tests[i]->stats.ticks_per_ms;
+ if (diff->num_tests == 0) {
+ diff->min = test_time;
+ diff->max = test_time;
+ } else {
+ if (test_time < diff->min)
+ diff->min = test_time;
+ if (test_time > diff->max)
+ diff->max = test_time;
+ }
+ diff->tests[diff->num_tests++] = tests[i];
+ tests[i]++;
+ }
+ }
+ diff->change = diff->max / diff->min;
+
+ if (num_reports == 2) {
+ double old_time, new_time;
+ if (diff->num_tests == 1) {
+ printf ("Only in %s: %s %s\n",
+ diff->tests[0]->configuration,
+ diff->tests[0]->backend,
+ diff->tests[0]->name);
+ continue;
+ }
+ old_time = diff->tests[0]->stats.min_ticks;
+ new_time = diff->tests[1]->stats.min_ticks;
+ if (! options->use_ticks) {
+ old_time /= diff->tests[0]->stats.ticks_per_ms;
+ new_time /= diff->tests[1]->stats.ticks_per_ms;
+ }
+ diff->change = old_time / new_time;
+ if (diff->change < 1.0)
+ diff->change = - 1.0 / diff->change;
+ }
+
+ diff++;
+ num_diffs++;
+ }
+ if (num_diffs == 0)
+ goto DONE;
+
+ if (num_reports == 2)
+ qsort (diffs, num_diffs, sizeof (test_diff_t),
+ test_diff_cmp_speedup_before_slowdown);
+ else
+ qsort (diffs, num_diffs, sizeof (test_diff_t), test_diff_cmp);
+
+ max_change = 1.0;
+ for (i = 0; i < num_diffs; i++) {
+ if (fabs (diffs[i].change) > max_change)
+ max_change = fabs (diffs[i].change);
+ }
+
+ if (num_reports == 2)
+ printf ("old: %s\n"
+ "new: %s\n",
+ diffs->tests[0]->configuration,
+ diffs->tests[1]->configuration);
+
+ for (i = 0; i < num_diffs; i++) {
+ diff = &diffs[i];
+
+ /* Discard as uninteresting a change which is less than the
+ * minimum change required, (default may be overriden on
+ * command-line). */
+ if (fabs (diff->change) - 1.0 < options->min_change)
+ continue;
+
+ if (num_reports == 2) {
+ if (diff->change > 1.0 && ! printed_speedup) {
+ printf ("Speedups\n"
+ "========\n");
+ printed_speedup = TRUE;
+ }
+ if (diff->change < 1.0 && ! printed_slowdown) {
+ printf ("Slowdowns\n"
+ "=========\n");
+ printed_slowdown = TRUE;
+ }
+ test_diff_print_binary (diff, max_change, options);
+ } else {
+ test_diff_print_multi (diff, max_change, options);
+ }
+ }
+
+ DONE:
+ for (i = 0; i < num_diffs; i++)
+ free (diffs[i].tests);
+ free (diffs);
+ free (tests);
+}
+
+static void
+usage (const char *argv0)
+{
+ char const *basename = strrchr(argv0, '/');
+ basename = basename ? basename+1 : argv0;
+ fprintf (stderr,
+ "Usage: %s [options] file1 file2 [...]\n\n",
+ basename);
+ fprintf (stderr,
+ "Computes significant performance differences for cairo performance reports.\n"
+ "Each file should be the output of the cairo-perf program (or \"make perf\").\n"
+ "The following options are available:\n"
+ "\n"
+ "--no-utf Use ascii stars instead of utf-8 change bars.\n"
+ " Four stars are printed per factor of speedup.\n"
+ "\n"
+ "--no-bars Don't display change bars at all.\n\n"
+ "\n"
+ "--use-ms Use milliseconds to calculate differences.\n"
+ " (instead of ticks which are hardware dependent)\n"
+ "\n"
+ "--min-change threshold[%%]\n"
+ " Suppress all changes below the given threshold.\n"
+ " The default threshold of 0.05 or 5%% ignores any\n"
+ " speedup or slowdown of 1.05 or less. A threshold\n"
+ " of 0 will cause all output to be reported.\n"
+ );
+ exit(1);
+}
+
+static void
+parse_args (int argc,
+ char const **argv,
+ cairo_perf_diff_files_args_t *args)
+{
+ int i;
+
+ for (i = 1; i < argc; i++) {
+ if (strcmp (argv[i], "--no-utf") == 0) {
+ args->options.use_utf = 0;
+ }
+ else if (strcmp (argv[i], "--no-bars") == 0) {
+ args->options.print_change_bars = 0;
+ }
+ else if (strcmp (argv[i], "--use-ms") == 0) {
+ /* default */
+ }
+ else if (strcmp (argv[i], "--use-ticks") == 0) {
+ args->options.use_ticks = 1;
+ }
+ else if (strcmp (argv[i], "--min-change") == 0) {
+ char *end = NULL;
+ i++;
+ if (i >= argc)
+ usage (argv[0]);
+ args->options.min_change = strtod (argv[i], &end);
+ if (*end) {
+ if (*end == '%') {
+ args->options.min_change /= 100;
+ } else {
+ usage (argv[0]);
+ }
+ }
+ }
+ else {
+ args->num_filenames++;
+ args->filenames = xrealloc (args->filenames,
+ args->num_filenames * sizeof (char *));
+ args->filenames[args->num_filenames - 1] = argv[i];
+ }
+ }
+}
+
+int
+main (int argc,
+ const char *argv[])
+{
+ cairo_perf_diff_files_args_t args = {
+ NULL, /* filenames */
+ 0, /* num_filenames */
+ {
+ 0.05, /* min change */
+ 1, /* use UTF-8? */
+ 1, /* display change bars? */
+ }
+ };
+ cairo_perf_report_t *reports;
+ test_report_t *t;
+ int i;
+
+ parse_args (argc, argv, &args);
+
+ if (args.num_filenames < 2)
+ usage (argv[0]);
+
+ reports = xmalloc (args.num_filenames * sizeof (cairo_perf_report_t));
+
+ for (i = 0; i < args.num_filenames; i++ ) {
+ cairo_perf_report_load (&reports[i], args.filenames[i], i, NULL);
+ printf ("[%d] %s\n", i, args.filenames[i]);
+ }
+ printf ("\n");
+
+ cairo_perf_reports_compare (reports, args.num_filenames, &args.options);
+
+ /* Pointless memory cleanup, (would be a great place for talloc) */
+ free (args.filenames);
+ for (i = 0; i < args.num_filenames; i++) {
+ for (t = reports[i].tests; t->name; t++) {
+ free (t->samples);
+ free (t->backend);
+ free (t->name);
+ }
+ free (reports[i].tests);
+ free (reports[i].configuration);
+ }
+ free (reports);
+
+ return 0;
+}
diff --git a/perf/cairo-perf-graph b/perf/cairo-perf-graph
new file mode 100755
index 000000000..a167351fc
--- /dev/null
+++ b/perf/cairo-perf-graph
@@ -0,0 +1,206 @@
+#!/bin/sh
+set -e
+
+###
+### XXX Source common functions from cairo-perf-diff
+###
+
+usage() {
+ argv0=`basename $0`
+
+ cat >&2 << END
+Usage:
+As opposed to its sibling, cairo-perf-diff, cairo-perf-graph targets
+reviewing changes between series by graphically comparing the performance
+at each commit.
+
+The two revisions can be any revision accepted by git. For example:
+
+ $argv0 1.2.0 1.2.4 # Compare performance of 1.2.0 to 1.2.4
+
+Options:
+
+-f, --force
+ Forces cairo-perf-diff to re-run performance tests
+ even if cached performance data is available.
+
+-h, --html
+ With this option performance changes are summarized
+ as HTML table.
+
+Additional options can be passed the child cairo-perf process
+by separating them with a double hyphen (--). For example, to
+examine what the impact of the latest change is on the stroke
+test you might use:
+
+ $argv0 HEAD -- stroke
+
+The performance results are cached in .perf next to the .git directory.
+
+Set CAIRO_AUTOGEN_OPTIONS to pass options to autogen for both
+builds.
+END
+
+ exit 1
+}
+
+# First, pull off any known options
+while true; do
+ case $1 in
+ -f|--force) force_cairo_perf="true";;
+ -h|--html) html_output="true";;
+ -s|--show) show_only="true";;
+ *) break;;
+ esac
+
+ shift
+done
+
+# Then if anything is left that still looks like an option, (begins
+# with a dash), give usage to catch --help or any other -garbage
+if [ $# -eq 0 ] || [ "`echo "$1" | sed 's/^-//'`" != "$1" ]; then
+ usage
+fi
+
+# Finally, pick up the actual revision arguments
+old="$1"
+new="$2"
+shift 2
+
+# And post-finally, pass anything after -- on to cairo-perf
+CAIRO_PERF_OPTIONS="-r -i 25"
+if [ $# -gt 0 ]; then
+ if [ "$1" = "--" ]; then
+ shift 1
+ CAIRO_PERF_OPTIONS="$CAIRO_PERF_OPTIONS $@"
+ else
+ usage
+ fi
+fi
+
+git_setup() {
+ SUBDIRECTORY_OK='Yes'
+ . "$(git --exec-path)/git-sh-setup"
+ CAIRO_DIR=`dirname $GIT_DIR`
+ if [ "$CAIRO_DIR" = "." ]; then
+ CAIRO_DIR=`pwd`
+ fi
+ CAIRO_PERF_DIR=$CAIRO_DIR/.perf
+}
+
+rev2sha() {
+ rev=$1
+ git rev-parse --verify $rev || ( echo "Cannot resolve $rev as a git object" && exit 1 )
+}
+
+cpu_count() {
+ test -f /proc/cpuinfo &&
+ grep -c '^processor[[:blank:]]\+:' /proc/cpuinfo ||
+ echo 1
+}
+
+# We cache performance output based on a two-part name capturing the
+# current performance test suite and the library being tested. We
+# capture these as the tree object of the perf directory in HEAD and
+# the tree object of the src directory of the revision being tested.
+#
+# This way, whenever the performance suite is updated, cached output
+# from old versions of the suite are automatically invalidated. Also,
+# if a commit just changes things outside of the src tree, (say it
+# changes the "test" test suite, or README or configure.in, or
+# whatever), cairo-perf-diff will be smart enough to still use cached
+# results from a run with an equivalent src tree.
+rev2perf() {
+ rev=$1
+ sha=`rev2sha $rev`
+ src_tree_sha=`rev2sha $rev:src`
+ perf_tree_sha=`rev2sha HEAD:perf`
+ echo "$CAIRO_PERF_DIR/${sha}-${perf_tree_sha}-${src_tree_sha}.perf"
+}
+rev2perf_glob() {
+ rev=$1
+ src_tree_sha=`rev2sha $rev:src`
+ perf_tree_sha=`rev2sha HEAD:perf`
+ echo "$CAIRO_PERF_DIR/*-${perf_tree_sha}-${src_tree_sha}.perf"
+}
+
+# Usage: run_cairo_perf_if_not_cached <rev> <suffix>
+# The <rev> argument must be a valid git ref-spec that can
+# be resolved to a commit. The suffix is just something
+# unique so that build directories can be separated for
+# multiple calls to this function.
+run_cairo_perf_if_not_cached() {
+ rev=$1
+ build_dir="build-$2"
+
+ owd=`pwd`
+ sha=`rev2sha $rev`
+ perf=`rev2perf $rev`
+ glob=`rev2perf_glob $rev`
+ if [ -e $glob ] && [ "$force_cairo_perf" != "true" ] || [ -n "$show_only" ]; then
+ return 0
+ fi
+ if [ ! -d $CAIRO_PERF_DIR ]; then
+ echo "Creating new perf cache in $CAIRO_PERF_DIR"
+ mkdir $CAIRO_PERF_DIR
+ fi
+
+ cd $CAIRO_DIR
+ boilerplate_files=`git ls-tree --name-only HEAD boilerplate/*`
+ perf_files=`git ls-tree --name-only HEAD perf/*`
+ cd $CAIRO_PERF_DIR
+
+ if [ ! -d $build_dir ]; then
+ git clone -s $CAIRO_DIR $build_dir
+ (cd $build_dir; git checkout -b tmp-cairo-perf-diff $sha)
+ fi
+ cd $build_dir
+
+ git checkout tmp-cairo-perf-diff
+ git reset --hard $sha
+
+ if [ -z "$MAKEFLAGS" ]; then
+ CPU_COUNT=`cpu_count`
+ export MAKEFLAGS="-j`expr $CPU_COUNT + 1`"
+ fi
+
+ if [ ! -e Makefile ]; then
+ CFLAGS="-O2" ./autogen.sh $CAIRO_AUTOGEN_OPTIONS
+ fi
+ make CFLAGS="-O2" || (rm config.cache && make CFLAGS="-O2")
+ for file in $boilerplate_files; do
+ rsync $CAIRO_DIR/$file boilerplate
+ done
+ (cd boilerplate; make)
+ for file in $perf_files; do
+ rsync $CAIRO_DIR/$file perf
+ done
+ cd perf;
+ make cairo-perf || exit 1
+ echo "Running \"cairo-perf $CAIRO_PERF_OPTIONS\" against $rev. Results will be cached in:"
+ echo "$perf"
+ (./cairo-perf $CAIRO_PERF_OPTIONS || echo "*** Performance test crashed") >> $perf
+ cd $owd
+}
+
+git_setup
+
+# Build cairo-perf-graph-files if not available
+if [ ! -e $CAIRO_DIR/perf/cairo-perf-graph-files ]; then
+ echo "Building cairo-perf-graph-files"
+ if [ "x$OS" = "xWindows_NT" ]; then
+ make -f Makefile.win32 -C $CAIRO_DIR/perf/ cairo-perf-graph-files CFG=debug
+ else
+ make -C $CAIRO_DIR/perf/ cairo-perf-graph-files
+ fi
+fi
+
+revs=""
+for rev in `git rev-list --reverse $old..$new`; do
+ run_cairo_perf_if_not_cached $rev rev
+ perf=`rev2perf $rev`
+ [ -e "$perf" ] && revs="$revs $perf"
+done
+
+exec $CAIRO_DIR/perf/cairo-perf-graph-files $revs
+#exec $CAIRO_DIR/libtool --mode=execute gdb --args $CAIRO_DIR/perf/cairo-perf-graph-files $revs
diff --git a/perf/cairo-perf-graph-files.c b/perf/cairo-perf-graph-files.c
new file mode 100644
index 000000000..1fd99e4ad
--- /dev/null
+++ b/perf/cairo-perf-graph-files.c
@@ -0,0 +1,604 @@
+/*
+ * Copyright © 2008 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of the
+ * copyright holders not be used in advertising or publicity
+ * pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied
+ * warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ *
+ * Authors: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-perf.h"
+#include "cairo-perf-graph.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+
+#include <cairo.h>
+
+static void
+usage (const char *argv0)
+{
+ char const *basename = strrchr (argv0, '/');
+ basename = basename ? basename+1 : argv0;
+ g_printerr ("Usage: %s [options] file1 file2 [...]\n\n", basename);
+ g_printerr ("Draws a graph illustrating the change in performance over a series.\n");
+ exit(1);
+}
+
+enum {
+ CASE_SHOWN,
+ CASE_INCONSISTENT,
+ CASE_BACKEND,
+ CASE_CONTENT,
+ CASE_NAME,
+ CASE_SIZE,
+ CASE_FG_COLOR,
+ CASE_DATA,
+ CASE_NCOLS
+};
+
+static GtkTreeStore *
+cases_to_store (test_case_t *cases)
+{
+ GtkTreeStore *store;
+ GtkTreeIter backend_iter;
+ GtkTreeIter content_iter;
+ const char *backend = NULL;
+ const char *content = NULL;
+
+ store = gtk_tree_store_new (CASE_NCOLS,
+ G_TYPE_BOOLEAN, /* shown */
+ G_TYPE_BOOLEAN, /* inconsistent */
+ G_TYPE_STRING, /* backend */
+ G_TYPE_STRING, /* content */
+ G_TYPE_STRING, /* name */
+ G_TYPE_INT, /* size */
+ GDK_TYPE_COLOR, /* fg color */
+ G_TYPE_POINTER); /* data */
+ while (cases->backend != NULL) {
+ GtkTreeIter iter;
+
+ if (backend == NULL || strcmp (backend, cases->backend)) {
+ gtk_tree_store_append (store, &backend_iter, NULL);
+ gtk_tree_store_set (store, &backend_iter,
+ CASE_SHOWN, TRUE,
+ CASE_BACKEND, cases->backend,
+ -1);
+ backend = cases->backend;
+ content = NULL;
+ }
+ if (content == NULL || strcmp (content, cases->content)) {
+ gtk_tree_store_append (store, &content_iter, &backend_iter);
+ gtk_tree_store_set (store, &content_iter,
+ CASE_SHOWN, TRUE,
+ CASE_BACKEND, cases->backend,
+ CASE_CONTENT, cases->content,
+ -1);
+ content = cases->content;
+ }
+
+ gtk_tree_store_append (store, &iter, &content_iter);
+ gtk_tree_store_set (store, &iter,
+ CASE_SHOWN, TRUE,
+ CASE_BACKEND, cases->backend,
+ CASE_CONTENT, cases->content,
+ CASE_NAME, cases->name,
+ CASE_SIZE, cases->size,
+ CASE_FG_COLOR, &cases->color,
+ CASE_DATA, cases,
+ -1);
+ cases++;
+ }
+
+ return store;
+}
+
+struct _app_data {
+ GtkWidget *window;
+
+ test_case_t *cases;
+ cairo_perf_report_t *reports;
+ int num_reports;
+
+ GtkTreeStore *case_store;
+
+ GIOChannel *git_io;
+ GtkTextBuffer *git_buffer;
+
+ GtkWidget *gv;
+};
+
+static void
+recurse_set_shown (GtkTreeModel *model,
+ GtkTreeIter *parent,
+ gboolean shown)
+{
+ GtkTreeIter iter;
+
+ if (gtk_tree_model_iter_children (model, &iter, parent)) do {
+ test_case_t *c;
+
+ gtk_tree_model_get (model, &iter, CASE_DATA, &c, -1);
+ if (c == NULL) {
+ recurse_set_shown (model, &iter, shown);
+ } else if (shown != c->shown) {
+ c->shown = shown;
+ gtk_tree_store_set (GTK_TREE_STORE (model), &iter,
+ CASE_SHOWN, shown,
+ CASE_INCONSISTENT, FALSE,
+ -1);
+ }
+ } while (gtk_tree_model_iter_next (model, &iter));
+}
+
+static gboolean
+children_consistent (GtkTreeModel *model,
+ GtkTreeIter *parent)
+{
+ GtkTreeIter iter;
+ gboolean first = TRUE;
+ gboolean first_active;
+
+ if (gtk_tree_model_iter_children (model, &iter, parent)) do {
+ gboolean active, inconsistent;
+
+ gtk_tree_model_get (model, &iter,
+ CASE_INCONSISTENT, &inconsistent,
+ CASE_SHOWN, &active,
+ -1);
+ if (inconsistent)
+ return FALSE;
+
+ if (first) {
+ first_active = active;
+ first = FALSE;
+ } else if (active != first_active)
+ return FALSE;
+ } while (gtk_tree_model_iter_next (model, &iter));
+
+ return TRUE;
+}
+
+static void
+check_consistent (GtkTreeModel *model,
+ GtkTreeIter *child)
+{
+ GtkTreeIter parent;
+
+ if (gtk_tree_model_iter_parent (model, &parent, child)) {
+ gtk_tree_store_set (GTK_TREE_STORE (model), &parent,
+ CASE_INCONSISTENT,
+ ! children_consistent (model, &parent),
+ -1);
+ check_consistent (model, &parent);
+ }
+}
+
+static void
+show_case_toggled (GtkCellRendererToggle *cell,
+ gchar *str,
+ struct _app_data *app)
+{
+ GtkTreeModel *model;
+ GtkTreePath *path;
+ GtkTreeIter iter;
+ test_case_t *c;
+ gboolean active;
+
+ active = ! gtk_cell_renderer_toggle_get_active (cell);
+
+ model = GTK_TREE_MODEL (app->case_store);
+
+ path = gtk_tree_path_new_from_string (str);
+ gtk_tree_model_get_iter (model, &iter, path);
+ gtk_tree_path_free (path);
+
+ gtk_tree_store_set (app->case_store, &iter,
+ CASE_SHOWN, active,
+ CASE_INCONSISTENT, FALSE,
+ -1);
+ gtk_tree_model_get (model, &iter, CASE_DATA, &c, -1);
+ if (c != NULL) {
+ if (active == c->shown)
+ return;
+
+ c->shown = active;
+ } else {
+ recurse_set_shown (model, &iter, active);
+ }
+ check_consistent (model, &iter);
+
+ graph_view_update_visible ((GraphView *) app->gv);
+}
+
+static gboolean
+git_read (GIOChannel *io,
+ GIOCondition cond,
+ struct _app_data *app)
+{
+ int fd;
+
+ fd = g_io_channel_unix_get_fd (io);
+ do {
+ char buf[4096];
+ int len;
+ GtkTextIter end;
+
+ len = read (fd, buf, sizeof (buf));
+ if (len <= 0) {
+ int err = len ? errno : 0;
+ switch (err) {
+ case EAGAIN:
+ case EINTR:
+ return TRUE;
+ default:
+ g_io_channel_unref (app->git_io);
+ app->git_io = NULL;
+ return FALSE;
+ }
+ }
+
+ gtk_text_buffer_get_end_iter (app->git_buffer, &end);
+ gtk_text_buffer_insert (app->git_buffer, &end, buf, len);
+ } while (TRUE);
+}
+
+static void
+do_git (struct _app_data *app,
+ char **argv)
+{
+ gint output;
+ GError *error = NULL;
+ GtkTextIter start, stop;
+ long flags;
+
+ if (! g_spawn_async_with_pipes (NULL, argv, NULL,
+ G_SPAWN_SEARCH_PATH |
+ G_SPAWN_STDERR_TO_DEV_NULL |
+ G_SPAWN_FILE_AND_ARGV_ZERO,
+ NULL, NULL, NULL,
+ NULL, &output, NULL,
+ &error))
+ {
+ g_error ("spawn failed: %s", error->message);
+ }
+
+ if (app->git_io) {
+ g_io_channel_shutdown (app->git_io, FALSE, NULL);
+ g_io_channel_unref (app->git_io);
+ }
+
+ gtk_text_buffer_get_bounds (app->git_buffer, &start, &stop);
+ gtk_text_buffer_delete (app->git_buffer, &start, &stop);
+
+ flags = fcntl (output, F_GETFL);
+ if ((flags & O_NONBLOCK) == 0)
+ fcntl (output, F_SETFL, flags | O_NONBLOCK);
+
+ app->git_io = g_io_channel_unix_new (output);
+ g_io_add_watch (app->git_io, G_IO_IN | G_IO_HUP, (GIOFunc) git_read, app);
+}
+
+static void
+gv_report_selected (GraphView *gv,
+ int i,
+ struct _app_data *app)
+{
+ cairo_perf_report_t *report;
+ char *hyphen;
+
+ if (i == -1)
+ return;
+
+ report = &app->reports[i];
+ hyphen = strchr (report->configuration, '-');
+ if (hyphen != NULL) {
+ int len = hyphen - report->configuration;
+ char *id = g_malloc (len + 1);
+ char *argv[5];
+
+ memcpy (id, report->configuration, len);
+ id[len] = '\0';
+
+ argv[0] = (char *) "git";
+ argv[1] = (char *) "git";
+ argv[2] = (char *) "show";
+ argv[3] = id;
+ argv[4] = NULL;
+
+ do_git (app, argv);
+ g_free (id);
+ }
+}
+
+static GtkWidget *
+window_create (test_case_t *cases,
+ cairo_perf_report_t *reports,
+ int num_reports)
+{
+ GtkWidget *window, *table, *w;
+ GtkWidget *tv, *sw;
+ GtkTreeStore *store;
+ GtkTreeViewColumn *column;
+ GtkCellRenderer *renderer;
+ struct _app_data *data;
+
+
+ data = g_new0 (struct _app_data, 1);
+ data->cases = cases;
+ data->reports = reports;
+ data->num_reports = num_reports;
+
+ window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ gtk_window_set_title (GTK_WINDOW (window), "Cairo Performance Graph");
+ g_object_set_data_full (G_OBJECT (window),
+ "app-data", data, (GDestroyNotify)g_free);
+
+ data->window = window;
+
+ table = gtk_table_new (2, 2, FALSE);
+
+ /* legend & show/hide lines (categorised) */
+ tv = gtk_tree_view_new ();
+ store = cases_to_store (cases);
+ data->case_store = store;
+ gtk_tree_view_set_model (GTK_TREE_VIEW (tv), GTK_TREE_MODEL (store));
+
+ renderer = gtk_cell_renderer_toggle_new ();
+ column = gtk_tree_view_column_new_with_attributes (NULL,
+ renderer,
+ "active", CASE_SHOWN,
+ "inconsistent", CASE_INCONSISTENT,
+ NULL);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (tv), column);
+ g_signal_connect (renderer, "toggled",
+ G_CALLBACK (show_case_toggled), data);
+
+ renderer = gtk_cell_renderer_text_new ();
+ column = gtk_tree_view_column_new_with_attributes ("Backend",
+ renderer,
+ "text", CASE_BACKEND,
+ NULL);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (tv), column);
+
+ renderer = gtk_cell_renderer_text_new ();
+ column = gtk_tree_view_column_new_with_attributes ("Content",
+ renderer,
+ "text", CASE_CONTENT,
+ NULL);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (tv), column);
+
+ renderer = gtk_cell_renderer_text_new ();
+ column = gtk_tree_view_column_new_with_attributes ("Test",
+ renderer,
+ "text", CASE_NAME,
+ "foreground-gdk", CASE_FG_COLOR,
+ NULL);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (tv), column);
+
+ renderer = gtk_cell_renderer_text_new ();
+ column = gtk_tree_view_column_new_with_attributes ("Size",
+ renderer,
+ "text", CASE_SIZE,
+ NULL);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (tv), column);
+
+ gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (tv), TRUE);
+ g_object_unref (store);
+
+ sw = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
+ GTK_POLICY_NEVER,
+ GTK_POLICY_AUTOMATIC);
+ gtk_container_add (GTK_CONTAINER (sw), tv);
+ gtk_widget_show (tv);
+ gtk_table_attach (GTK_TABLE (table), sw,
+ 0, 1, 0, 2,
+ GTK_FILL, GTK_FILL,
+ 4, 4);
+ gtk_widget_show (sw);
+
+ /* the performance chart */
+ w = graph_view_new ();
+ data->gv = w;
+ g_signal_connect (w, "report-selected",
+ G_CALLBACK (gv_report_selected), data);
+ graph_view_set_reports ((GraphView *)w, cases, reports, num_reports);
+ gtk_table_attach (GTK_TABLE (table), w,
+ 1, 2, 0, 1,
+ GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND,
+ 4, 4);
+ gtk_widget_show (w);
+
+ /* interesting information - presumably the commit log */
+ w = gtk_text_view_new ();
+ data->git_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (w));
+ sw = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
+ GTK_POLICY_NEVER,
+ GTK_POLICY_AUTOMATIC);
+ gtk_container_add (GTK_CONTAINER (sw), w);
+ gtk_widget_show (w);
+ gtk_table_attach (GTK_TABLE (table), sw,
+ 1, 2, 1, 2,
+ GTK_FILL, GTK_FILL | GTK_EXPAND,
+ 4, 4);
+ gtk_widget_show (sw);
+
+ gtk_container_add (GTK_CONTAINER (window), table);
+ gtk_widget_show (table);
+
+ return window;
+}
+
+static void
+name_to_color (const char *name,
+ GdkColor *color)
+{
+ gint v = g_str_hash (name);
+
+ color->red = ((v >> 0) & 0xff) / 384. * 0xffff;
+ color->green = ((v >> 8) & 0xff) / 384. * 0xffff;
+ color->blue = ((v >> 16) & 0xff) / 384. * 0xffff;
+}
+
+static test_case_t *
+test_cases_from_reports (cairo_perf_report_t *reports,
+ int num_reports)
+{
+ test_case_t *cases, *c;
+ test_report_t **tests;
+ int i, j;
+ int num_tests;
+
+ num_tests = 0;
+ for (i = 0; i < num_reports; i++) {
+ for (j = 0; reports[i].tests[j].name != NULL; j++)
+ ;
+ if (j > num_tests)
+ num_tests = j;
+ }
+
+ cases = xcalloc (num_tests+1, sizeof (test_case_t));
+ tests = xmalloc (num_reports * sizeof (test_report_t *));
+ for (i = 0; i < num_reports; i++)
+ tests[i] = reports[i].tests;
+
+ c = cases;
+ while (1) {
+ int seen_non_null;
+ test_report_t *min_test;
+
+ /* We expect iterations values of 0 when multiple raw reports
+ * for the same test have been condensed into the stats of the
+ * first. So we just skip these later reports that have no
+ * stats. */
+ seen_non_null = 0;
+ for (i = 0; i < num_reports; i++) {
+ while (tests[i]->name && tests[i]->stats.iterations == 0)
+ tests[i]++;
+ if (tests[i]->name)
+ seen_non_null++;
+ }
+
+ if (seen_non_null < 2)
+ break;
+
+ /* Find the minimum of all current tests, (we have to do this
+ * in case some reports don't have a particular test). */
+ for (i = 0; i < num_reports; i++) {
+ if (tests[i]->name) {
+ min_test = tests[i];
+ break;
+ }
+ }
+ for (++i; i < num_reports; i++) {
+ if (tests[i]->name &&
+ test_report_cmp_backend_then_name (tests[i], min_test) < 0)
+ {
+ min_test = tests[i];
+ }
+ }
+
+ c->min_test = min_test;
+ c->backend = min_test->backend;
+ c->content = min_test->content;
+ c->name = min_test->name;
+ c->size = min_test->size;
+ c->baseline = min_test->stats.min_ticks;
+ c->min = c->max = 1.;
+ c->shown = TRUE;
+ name_to_color (c->name, &c->color);
+
+ for (i = 0; i < num_reports; i++) {
+ if (tests[i]->name &&
+ test_report_cmp_backend_then_name (tests[i], min_test) == 0)
+ {
+ tests[i]++;
+ break;
+ }
+ }
+
+ for (++i; i < num_reports; i++) {
+ if (tests[i]->name &&
+ test_report_cmp_backend_then_name (tests[i], min_test) == 0)
+ {
+ double v = tests[i]->stats.min_ticks / c->baseline;
+ if (v < c->min)
+ c->min = v;
+ if (v > c->max)
+ c->max = v;
+ tests[i]++;
+ }
+ }
+
+ c++;
+ }
+ free (tests);
+
+ return cases;
+}
+int
+main (int argc,
+ char *argv[])
+{
+ cairo_perf_report_t *reports;
+ test_case_t *cases;
+ test_report_t *t;
+ int i;
+ GtkWidget *window;
+
+ gtk_init (&argc, &argv);
+
+ if (argc < 3)
+ usage (argv[0]);
+
+ reports = xmalloc ((argc-1) * sizeof (cairo_perf_report_t));
+ for (i = 1; i < argc; i++ )
+ cairo_perf_report_load (&reports[i-1], argv[i], i, NULL);
+
+ cases = test_cases_from_reports (reports, argc-1);
+
+ window = window_create (cases, reports, argc-1);
+ g_signal_connect (window, "delete-event",
+ G_CALLBACK (gtk_main_quit), NULL);
+ gtk_widget_show (window);
+
+ gtk_main ();
+
+ /* Pointless memory cleanup, (would be a great place for talloc) */
+ free (cases);
+ for (i = 0; i < argc-1; i++) {
+ for (t = reports[i].tests; t->name; t++) {
+ free (t->samples);
+ free (t->backend);
+ free (t->name);
+ }
+ free (reports[i].tests);
+ free (reports[i].configuration);
+ }
+ free (reports);
+
+ return 0;
+}
diff --git a/perf/cairo-perf-graph-widget.c b/perf/cairo-perf-graph-widget.c
new file mode 100644
index 000000000..41311f7ee
--- /dev/null
+++ b/perf/cairo-perf-graph-widget.c
@@ -0,0 +1,604 @@
+/*
+ * Copyright © 2008 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of the
+ * copyright holders not be used in advertising or publicity
+ * pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied
+ * warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ *
+ * Authors: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-perf.h"
+#include "cairo-perf-graph.h"
+
+#include <gtk/gtk.h>
+
+struct _GraphView {
+ GtkWidget widget;
+
+ test_case_t *cases;
+ cairo_perf_report_t *reports;
+ int num_reports;
+ double ymin, ymax;
+
+ int selected_report;
+};
+
+typedef struct _GraphViewClass {
+ GtkWidgetClass parent_class;
+} GraphViewClass;
+
+static GType graph_view_get_type (void);
+
+enum {
+ REPORT_SELECTED,
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL];
+
+G_DEFINE_TYPE (GraphView, graph_view, GTK_TYPE_WIDGET)
+
+static void
+draw_baseline_performance (test_case_t *cases,
+ cairo_perf_report_t *reports,
+ int num_reports,
+ cairo_t *cr,
+ const cairo_matrix_t *m)
+{
+ test_report_t **tests;
+ double dots[2] = { 0, 1.};
+ int i;
+
+ tests = xmalloc (num_reports * sizeof (test_report_t *));
+ for (i = 0; i < num_reports; i++)
+ tests[i] = reports[i].tests;
+
+ while (cases->backend != NULL) {
+ test_report_t *min_test;
+ double baseline, last_y;
+ double x, y;
+
+ if (! cases->shown) {
+ cases++;
+ continue;
+ }
+
+ min_test = cases->min_test;
+
+ for (i = 0; i < num_reports; i++) {
+ while (tests[i]->name &&
+ test_report_cmp_backend_then_name (tests[i], min_test) < 0)
+ {
+ tests[i]++;
+ }
+ }
+
+ /* first the stroke */
+ cairo_save (cr);
+ cairo_set_line_width (cr, 2.);
+ gdk_cairo_set_source_color (cr, &cases->color);
+ for (i = 0; i < num_reports; i++) {
+ if (tests[i]->name &&
+ test_report_cmp_backend_then_name (tests[i], min_test) == 0)
+ {
+ baseline = tests[i]->stats.min_ticks;
+
+ x = i; y = 0;
+ cairo_matrix_transform_point (m, &x, &y);
+ x = floor (x);
+ y = floor (y);
+ cairo_move_to (cr, x, y);
+ last_y = y;
+ break;
+ }
+ }
+
+ for (++i; i < num_reports; i++) {
+ if (tests[i]->name &&
+ test_report_cmp_backend_then_name (tests[i], min_test) == 0)
+ {
+ x = i, y = tests[i]->stats.min_ticks / baseline;
+
+ if (y < 1.)
+ y = -1./y + 1;
+ else
+ y -= 1;
+
+ cairo_matrix_transform_point (m, &x, &y);
+ x = floor (x);
+ y = floor (y);
+ cairo_line_to (cr, x, last_y);
+ cairo_line_to (cr, x, y);
+ last_y = y;
+ }
+ }
+ {
+ x = num_reports, y = 0;
+ cairo_matrix_transform_point (m, &x, &y);
+ x = floor (x);
+ cairo_line_to (cr, x, last_y);
+ }
+
+ cairo_set_line_width (cr, 1.);
+ cairo_stroke (cr);
+
+ /* then draw the points */
+ for (i = 0; i < num_reports; i++) {
+ if (tests[i]->name &&
+ test_report_cmp_backend_then_name (tests[i], min_test) == 0)
+ {
+ baseline = tests[i]->stats.min_ticks;
+
+ x = i; y = 0;
+ cairo_matrix_transform_point (m, &x, &y);
+ x = floor (x);
+ y = floor (y);
+ cairo_move_to (cr, x, y);
+ cairo_close_path (cr);
+ last_y = y;
+
+ tests[i]++;
+ break;
+ }
+ }
+
+ for (++i; i < num_reports; i++) {
+ if (tests[i]->name &&
+ test_report_cmp_backend_then_name (tests[i], min_test) == 0)
+ {
+ x = i, y = tests[i]->stats.min_ticks / baseline;
+
+ if (y < 1.)
+ y = -1./y + 1;
+ else
+ y -= 1;
+
+ cairo_matrix_transform_point (m, &x, &y);
+ x = floor (x);
+ y = floor (y);
+ cairo_move_to (cr, x, last_y);
+ cairo_close_path (cr);
+ cairo_move_to (cr, x, y);
+ cairo_close_path (cr);
+ last_y = y;
+
+ tests[i]++;
+ }
+ }
+ {
+ x = num_reports, y = 0;
+ cairo_matrix_transform_point (m, &x, &y);
+ x = floor (x);
+ cairo_move_to (cr, x, last_y);
+ cairo_close_path (cr);
+ }
+ cairo_set_source_rgba (cr, 0, 0, 0, .5);
+ cairo_set_dash (cr, dots, 2, 0.);
+ cairo_set_line_width (cr, 3.);
+ cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
+ cairo_stroke (cr);
+ cairo_restore (cr);
+
+ cases++;
+ }
+ free (tests);
+}
+
+static void
+draw_hline (cairo_t *cr,
+ const cairo_matrix_t *m,
+ double y0,
+ double xmin,
+ double xmax)
+{
+ double x, y;
+ double py_offset;
+
+ py_offset = fmod (cairo_get_line_width (cr) / 2., 1.);
+
+ x = xmin; y = y0;
+ cairo_matrix_transform_point (m, &x, &y);
+ cairo_move_to (cr, floor (x), floor (y) + py_offset);
+
+ x = xmax; y = y0;
+ cairo_matrix_transform_point (m, &x, &y);
+ cairo_line_to (cr, ceil (x), floor (y) + py_offset);
+
+ cairo_stroke (cr);
+}
+
+static void
+draw_label (cairo_t *cr,
+ const cairo_matrix_t *m,
+ double y0,
+ double xmin,
+ double xmax)
+{
+ double x, y;
+ char buf[80];
+ cairo_text_extents_t extents;
+
+ snprintf (buf, sizeof (buf), "%.0fx", fabs (y0));
+ cairo_text_extents (cr, buf, &extents);
+
+ x = xmin; y = y0;
+ cairo_matrix_transform_point (m, &x, &y);
+ cairo_move_to (cr,
+ x - extents.width - 4,
+ y - (extents.height/2. + extents.y_bearing));
+ cairo_show_text (cr, buf);
+
+
+ snprintf (buf, sizeof (buf), "%.0fx", fabs (y0));
+ cairo_text_extents (cr, buf, &extents);
+
+ x = xmax; y = y0;
+ cairo_matrix_transform_point (m, &x, &y);
+ cairo_move_to (cr,
+ x + 4,
+ y - (extents.height/2. + extents.y_bearing));
+ cairo_show_text (cr, buf);
+}
+
+#define ALIGN_X(v) ((v)<<0)
+#define ALIGN_Y(v) ((v)<<2)
+static void
+draw_rotated_label (cairo_t *cr,
+ const char *text,
+ double x,
+ double y,
+ double angle,
+ int align)
+{
+ cairo_text_extents_t extents;
+
+ cairo_text_extents (cr, text, &extents);
+
+ cairo_save (cr); {
+ cairo_translate (cr, x, y);
+ cairo_rotate (cr, angle);
+ switch (align) {
+ case ALIGN_X(0) | ALIGN_Y(0):
+ cairo_move_to (cr,
+ -extents.x_bearing,
+ -extents.y_bearing);
+ break;
+ case ALIGN_X(0) | ALIGN_Y(1):
+ cairo_move_to (cr,
+ -extents.x_bearing,
+ - (extents.height/2. + extents.y_bearing));
+ break;
+ case ALIGN_X(0) | ALIGN_Y(2):
+ cairo_move_to (cr,
+ -extents.x_bearing,
+ - (extents.height + extents.y_bearing));
+ break;
+
+ case ALIGN_X(1) | ALIGN_Y(0):
+ cairo_move_to (cr,
+ - (extents.width/2. + extents.x_bearing),
+ -extents.y_bearing);
+ break;
+ case ALIGN_X(1) | ALIGN_Y(1):
+ cairo_move_to (cr,
+ - (extents.width/2. + extents.x_bearing),
+ - (extents.height/2. + extents.y_bearing));
+ break;
+ case ALIGN_X(1) | ALIGN_Y(2):
+ cairo_move_to (cr,
+ - (extents.width/2. + extents.x_bearing),
+ - (extents.height + extents.y_bearing));
+ break;
+
+ case ALIGN_X(2) | ALIGN_Y(0):
+ cairo_move_to (cr,
+ - (extents.width + extents.x_bearing),
+ -extents.y_bearing);
+ break;
+ case ALIGN_X(2) | ALIGN_Y(1):
+ cairo_move_to (cr,
+ - (extents.width + extents.x_bearing),
+ - (extents.height/2. + extents.y_bearing));
+ break;
+ case ALIGN_X(2) | ALIGN_Y(2):
+ cairo_move_to (cr,
+ - (extents.width + extents.x_bearing),
+ - (extents.height + extents.y_bearing));
+ break;
+ }
+ cairo_show_text (cr, text);
+ } cairo_restore (cr);
+}
+
+#define PAD 36
+static void
+graph_view_draw (GraphView *self,
+ cairo_t *cr)
+{
+ cairo_matrix_t m;
+ const double dash[2] = {4, 4};
+ double range;
+ int i;
+
+ if (self->widget.allocation.width < 4 *PAD)
+ return;
+ if (self->widget.allocation.height < 3 *PAD)
+ return;
+
+ range = floor (self->ymax+1) - ceil (self->ymin-1);
+
+ cairo_matrix_init_translate (&m, PAD, self->widget.allocation.height - PAD);
+ cairo_matrix_scale (&m,
+ (self->widget.allocation.width-2*PAD)/(self->num_reports),
+ -(self->widget.allocation.height-2*PAD)/range);
+ cairo_matrix_translate (&m, 0, floor (self->ymax+1));
+
+ if (self->selected_report != -1) {
+ cairo_save (cr); {
+ double x0, x1, y;
+ x0 = self->selected_report; y = 0;
+ cairo_matrix_transform_point (&m, &x0, &y);
+ x0 = floor (x0);
+ x1 = self->selected_report + 1; y = 0;
+ cairo_matrix_transform_point (&m, &x1, &y);
+ x1 = ceil (x1);
+ y = (x1 - x0) / 8;
+ y = MIN (y, PAD / 2);
+ x0 -= y;
+ x1 += y;
+ cairo_rectangle (cr, x0, PAD/2, x1-x0, self->widget.allocation.height-2*PAD + PAD);
+ gdk_cairo_set_source_color (cr, &self->widget.style->base[GTK_STATE_SELECTED]);
+ cairo_fill (cr);
+ } cairo_restore (cr);
+ }
+
+ cairo_save (cr); {
+ cairo_pattern_t *linear;
+ double x, y;
+
+ gdk_cairo_set_source_color (cr,
+ &self->widget.style->fg[GTK_WIDGET_STATE (self)]);
+ cairo_set_line_width (cr, 2.);
+ draw_hline (cr, &m, 0, 0, self->num_reports);
+
+ cairo_set_line_width (cr, 1.);
+ cairo_set_dash (cr, NULL, 0, 0);
+
+ for (i = ceil (self->ymin-1); i <= floor (self->ymax+1); i++) {
+ if (i != 0)
+ draw_hline (cr, &m, i, 0, self->num_reports);
+ }
+
+ cairo_set_font_size (cr, 11);
+
+ linear = cairo_pattern_create_linear (0, PAD, 0, self->widget.allocation.height-2*PAD);
+ cairo_pattern_add_color_stop_rgb (linear, 0, 0, 1, 0);
+ cairo_pattern_add_color_stop_rgb (linear, 1, 1, 0, 0);
+ cairo_set_source (cr, linear);
+ cairo_pattern_destroy (linear);
+
+ for (i = ceil (self->ymin-1); i <= floor (self->ymax+1); i++) {
+ if (i != 0)
+ draw_label (cr, &m, i, 0, self->num_reports);
+ }
+
+ x = 0, y = floor (self->ymax+1);
+ cairo_matrix_transform_point (&m, &x, &y);
+ draw_rotated_label (cr, "Faster", x - 7, y + 14,
+ 270./360 * 2 * G_PI,
+ ALIGN_X(2) | ALIGN_Y(1));
+ x = self->num_reports, y = floor (self->ymax+1);
+ cairo_matrix_transform_point (&m, &x, &y);
+ draw_rotated_label (cr, "Faster", x + 11, y + 14,
+ 270./360 * 2 * G_PI,
+ ALIGN_X(2) | ALIGN_Y(1));
+
+ x = 0, y = ceil (self->ymin-1);
+ cairo_matrix_transform_point (&m, &x, &y);
+ draw_rotated_label (cr, "Slower", x - 7, y - 14,
+ 90./360 * 2 * G_PI,
+ ALIGN_X(2) | ALIGN_Y(1));
+ x = self->num_reports, y = ceil (self->ymin-1);
+ cairo_matrix_transform_point (&m, &x, &y);
+ draw_rotated_label (cr, "Slower", x + 11, y - 14,
+ 90./360 * 2 * G_PI,
+ ALIGN_X(2) | ALIGN_Y(1));
+ } cairo_restore (cr);
+
+ draw_baseline_performance (self->cases,
+ self->reports, self->num_reports,
+ cr, &m);
+
+ cairo_save (cr); {
+ cairo_set_source_rgb (cr, 0.7, 0.7, 0.7);
+ cairo_set_line_width (cr, 1.);
+ cairo_set_dash (cr, dash, 2, 0);
+ draw_hline (cr, &m, 0, 0, self->num_reports);
+ } cairo_restore (cr);
+}
+
+static gboolean
+graph_view_expose (GtkWidget *w,
+ GdkEventExpose *ev)
+{
+ GraphView *self = (GraphView *) w;
+ cairo_t *cr;
+
+ cr = gdk_cairo_create (w->window);
+ gdk_cairo_set_source_color (cr, &w->style->base[GTK_WIDGET_STATE (w)]);
+ cairo_paint (cr);
+
+ graph_view_draw (self, cr);
+
+ cairo_destroy (cr);
+
+ return FALSE;
+}
+
+static gboolean
+graph_view_button_press (GtkWidget *w,
+ GdkEventButton *ev)
+{
+ GraphView *self = (GraphView *) w;
+ cairo_matrix_t m;
+ double x,y;
+ int i;
+
+ cairo_matrix_init_translate (&m, PAD, self->widget.allocation.height-PAD);
+ cairo_matrix_scale (&m, (self->widget.allocation.width-2*PAD)/self->num_reports, -(self->widget.allocation.height-2*PAD)/(self->ymax - self->ymin));
+ cairo_matrix_translate (&m, 0, -self->ymin);
+ cairo_matrix_invert (&m);
+
+ x = ev->x;
+ y = ev->y;
+ cairo_matrix_transform_point (&m, &x, &y);
+
+ i = floor (x);
+ if (i < 0 || i >= self->num_reports)
+ i = -1;
+
+ if (i != self->selected_report) {
+ self->selected_report = i;
+ gtk_widget_queue_draw (w);
+
+ g_signal_emit (w, signals[REPORT_SELECTED], 0, i);
+ }
+
+ return FALSE;
+}
+
+static gboolean
+graph_view_button_release (GtkWidget *w,
+ GdkEventButton *ev)
+{
+ GraphView *self = (GraphView *) w;
+
+ return FALSE;
+}
+
+static void
+graph_view_realize (GtkWidget *widget)
+{
+ GdkWindowAttr attributes;
+
+ GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
+
+ attributes.window_type = GDK_WINDOW_CHILD;
+ attributes.x = widget->allocation.x;
+ attributes.y = widget->allocation.y;
+ attributes.width = widget->allocation.width;
+ attributes.height = widget->allocation.height;
+ attributes.wclass = GDK_INPUT_OUTPUT;
+ attributes.visual = gtk_widget_get_visual (widget);
+ attributes.colormap = gtk_widget_get_colormap (widget);
+ attributes.event_mask = gtk_widget_get_events (widget) |
+ GDK_BUTTON_PRESS_MASK |
+ GDK_BUTTON_RELEASE_MASK |
+ GDK_EXPOSURE_MASK;
+
+ widget->window = gdk_window_new (gtk_widget_get_parent_window (widget),
+ &attributes,
+ GDK_WA_X | GDK_WA_Y |
+ GDK_WA_VISUAL | GDK_WA_COLORMAP);
+ gdk_window_set_user_data (widget->window, widget);
+
+ widget->style = gtk_style_attach (widget->style, widget->window);
+ gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
+}
+
+static void
+graph_view_finalize (GObject *obj)
+{
+ G_OBJECT_CLASS (graph_view_parent_class)->finalize (obj);
+}
+
+static void
+graph_view_class_init (GraphViewClass *klass)
+{
+ GObjectClass *object_class = (GObjectClass *) klass;
+ GtkWidgetClass *widget_class = (GtkWidgetClass *) klass;
+
+ object_class->finalize = graph_view_finalize;
+
+ widget_class->realize = graph_view_realize;
+ widget_class->expose_event = graph_view_expose;
+ widget_class->button_press_event = graph_view_button_press;
+ widget_class->button_release_event = graph_view_button_release;
+
+ signals[REPORT_SELECTED] =
+ g_signal_new ("report-selected",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_FIRST,
+ 0,//G_STRUCT_OFFSET (GraphView, report_selected),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__INT,
+ G_TYPE_NONE, 1, G_TYPE_INT);
+}
+
+static void
+graph_view_init (GraphView *self)
+{
+ self->selected_report = -1;
+}
+
+GtkWidget *
+graph_view_new (void)
+{
+ return g_object_new (graph_view_get_type (), NULL);
+}
+
+void
+graph_view_update_visible (GraphView *gv)
+{
+ double min, max;
+ test_case_t *cases;
+
+ cases = gv->cases;
+
+ min = max = 1.;
+ while (cases->name != NULL) {
+ if (cases->shown) {
+ if (cases->min < min)
+ min = cases->min;
+ if (cases->max > max)
+ max = cases->max;
+ }
+ cases++;
+ }
+ gv->ymin = -1/min + 1;
+ gv->ymax = max - 1;
+
+ gtk_widget_queue_draw (&gv->widget);
+}
+
+void
+graph_view_set_reports (GraphView *gv,
+ test_case_t *cases,
+ cairo_perf_report_t *reports,
+ int num_reports)
+{
+ /* XXX ownership? */
+ gv->cases = cases;
+ gv->reports = reports;
+ gv->num_reports = num_reports;
+
+ graph_view_update_visible (gv);
+}
diff --git a/perf/cairo-perf-graph.h b/perf/cairo-perf-graph.h
new file mode 100644
index 000000000..4cb62165f
--- /dev/null
+++ b/perf/cairo-perf-graph.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright © 2008 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of the
+ * copyright holders not be used in advertising or publicity
+ * pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied
+ * warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ *
+ * Authors: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#ifndef CAIRO_PERF_GRAPH_H
+#define CAIRO_PERF_GRAPH_H
+
+#include <gtk/gtk.h>
+
+#include "cairo-perf.h"
+
+typedef struct _test_case {
+ const char *backend;
+ const char *content;
+ const char *name;
+ int size;
+
+ test_report_t *min_test;
+
+ cairo_bool_t shown;
+ double baseline;
+ double min, max;
+ GdkColor color;
+} test_case_t;
+
+typedef struct _GraphView GraphView;
+
+GtkWidget *
+graph_view_new (void);
+
+void
+graph_view_set_reports (GraphView *gv,
+ test_case_t *tests,
+ cairo_perf_report_t *reports,
+ int num_reports);
+
+void
+graph_view_update_visible (GraphView *gv);
+
+#endif
diff --git a/perf/cairo-perf-micro.c b/perf/cairo-perf-micro.c
new file mode 100644
index 000000000..d6b52c446
--- /dev/null
+++ b/perf/cairo-perf-micro.c
@@ -0,0 +1,594 @@
+/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */
+/*
+ * Copyright © 2006 Mozilla Corporation
+ * Copyright © 2006 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * the authors not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. The authors make no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Vladimir Vukicevic <vladimir@pobox.com>
+ * Carl Worth <cworth@cworth.org>
+ */
+
+#define _GNU_SOURCE 1 /* for sched_getaffinity() */
+
+#include "../cairo-version.h" /* for the real version */
+
+#include "cairo-perf.h"
+#include "cairo-stats.h"
+
+#include "cairo-boilerplate-getopt.h"
+
+/* For basename */
+#ifdef HAVE_LIBGEN_H
+#include <libgen.h>
+#endif
+
+#if HAVE_FCFINI
+#include <fontconfig/fontconfig.h>
+#endif
+
+#ifdef HAVE_SCHED_H
+#include <sched.h>
+#endif
+
+#define CAIRO_PERF_ITERATIONS_DEFAULT 100
+#define CAIRO_PERF_LOW_STD_DEV 0.03
+#define CAIRO_PERF_STABLE_STD_DEV_COUNT 5
+#define CAIRO_PERF_ITERATION_MS_DEFAULT 2000
+#define CAIRO_PERF_ITERATION_MS_FAST 5
+
+typedef struct _cairo_perf_case {
+ CAIRO_PERF_RUN_DECL (*run);
+ cairo_bool_t (*enabled) (cairo_perf_t *perf);
+ unsigned int min_size;
+ unsigned int max_size;
+} cairo_perf_case_t;
+
+const cairo_perf_case_t perf_cases[];
+
+static const char *
+_content_to_string (cairo_content_t content,
+ cairo_bool_t similar)
+{
+ switch (content|similar) {
+ case CAIRO_CONTENT_COLOR:
+ return "rgb";
+ case CAIRO_CONTENT_COLOR|1:
+ return "rgb&";
+ case CAIRO_CONTENT_ALPHA:
+ return "a";
+ case CAIRO_CONTENT_ALPHA|1:
+ return "a&";
+ case CAIRO_CONTENT_COLOR_ALPHA:
+ return "rgba";
+ case CAIRO_CONTENT_COLOR_ALPHA|1:
+ return "rgba&";
+ default:
+ return "<unknown_content>";
+ }
+}
+
+static cairo_bool_t
+cairo_perf_has_similar (cairo_perf_t *perf)
+{
+ cairo_surface_t *target;
+
+ if (getenv ("CAIRO_TEST_SIMILAR") == NULL)
+ return FALSE;
+
+ /* exclude the image backend */
+ target = cairo_get_target (perf->cr);
+ if (cairo_surface_get_type (target) == CAIRO_SURFACE_TYPE_IMAGE)
+ return FALSE;
+
+ return TRUE;
+}
+
+cairo_bool_t
+cairo_perf_can_run (cairo_perf_t *perf,
+ const char *name,
+ cairo_bool_t *is_explicit)
+{
+ unsigned int i;
+
+ if (is_explicit)
+ *is_explicit = FALSE;
+
+ if (perf->num_names == 0)
+ return TRUE;
+
+ for (i = 0; i < perf->num_names; i++) {
+ if (strstr (name, perf->names[i])) {
+ if (is_explicit)
+ *is_explicit = FALSE;
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+static unsigned
+cairo_perf_calibrate (cairo_perf_t *perf,
+ cairo_perf_func_t perf_func)
+{
+ cairo_time_t calibration, calibration_max;
+ unsigned loops, min_loops;
+
+ min_loops = 1;
+ calibration = perf_func (perf->cr, perf->size, perf->size, min_loops);
+
+ if (!perf->fast_and_sloppy) {
+ calibration_max = _cairo_time_from_s (perf->ms_per_iteration * 0.0001 / 4);
+ while (calibration < calibration_max) {
+ min_loops *= 2;
+ calibration = perf_func (perf->cr, perf->size, perf->size, min_loops);
+ }
+ }
+
+ /* XXX
+ * Compute the number of loops required for the timing
+ * interval to be perf->ms_per_iteration milliseconds. This
+ * helps to eliminate sampling variance due to timing and
+ * other systematic errors. However, it also hides
+ * synchronisation overhead as we attempt to process a large
+ * batch of identical operations in a single shot. This can be
+ * considered both good and bad... It would be good to perform
+ * a more rigorous analysis of the synchronisation overhead,
+ * that is to estimate the time for loop=0.
+ */
+ loops = _cairo_time_from_s (perf->ms_per_iteration * 0.001 * min_loops / calibration);
+ min_loops = perf->fast_and_sloppy ? 1 : 10;
+ if (loops < min_loops)
+ loops = min_loops;
+
+ return loops;
+}
+
+void
+cairo_perf_run (cairo_perf_t *perf,
+ const char *name,
+ cairo_perf_func_t perf_func,
+ cairo_count_func_t count_func)
+{
+ static cairo_bool_t first_run = TRUE;
+ unsigned int i, similar, similar_iters;
+ cairo_time_t *times;
+ cairo_stats_t stats = {0.0, 0.0};
+ int low_std_dev_count;
+
+ if (perf->list_only) {
+ printf ("%s\n", name);
+ return;
+ }
+
+ if (first_run) {
+ if (perf->raw) {
+ printf ("[ # ] %s.%-s %s %s %s ...\n",
+ "backend", "content", "test-size", "ticks-per-ms", "time(ticks)");
+ }
+
+ if (perf->summary) {
+ fprintf (perf->summary,
+ "[ # ] %8s.%-4s %28s %8s %8s %5s %5s %s %s\n",
+ "backend", "content", "test-size", "min(ticks)", "min(ms)", "median(ms)",
+ "stddev.", "iterations", "overhead");
+ }
+ first_run = FALSE;
+ }
+
+ times = perf->times;
+
+ if (getenv ("CAIRO_PERF_OUTPUT") != NULL) { /* check output */
+ char *filename;
+ cairo_status_t status;
+
+ xasprintf (&filename, "%s.%s.%s.%d.out.png",
+ name, perf->target->name,
+ _content_to_string (perf->target->content, 0),
+ perf->size);
+ cairo_save (perf->cr);
+ perf_func (perf->cr, perf->size, perf->size, 1);
+ cairo_restore (perf->cr);
+ status = cairo_surface_write_to_png (cairo_get_target (perf->cr), filename);
+ if (status) {
+ fprintf (stderr, "Failed to generate output check '%s': %s\n",
+ filename, cairo_status_to_string (status));
+ return;
+ }
+
+ free (filename);
+ }
+
+ if (cairo_perf_has_similar (perf))
+ similar_iters = 2;
+ else
+ similar_iters = 1;
+
+ for (similar = 0; similar < similar_iters; similar++) {
+ unsigned loops;
+
+ if (perf->summary) {
+ fprintf (perf->summary,
+ "[%3d] %8s.%-5s %26s.%-3d ",
+ perf->test_number, perf->target->name,
+ _content_to_string (perf->target->content, similar),
+ name, perf->size);
+ fflush (perf->summary);
+ }
+
+ /* We run one iteration in advance to warm caches and calibrate. */
+ cairo_perf_yield ();
+ if (similar)
+ cairo_push_group_with_content (perf->cr,
+ cairo_boilerplate_content (perf->target->content));
+ else
+ cairo_save (perf->cr);
+ perf_func (perf->cr, perf->size, perf->size, 1);
+ loops = cairo_perf_calibrate (perf, perf_func);
+ if (similar)
+ cairo_pattern_destroy (cairo_pop_group (perf->cr));
+ else
+ cairo_restore (perf->cr);
+
+ low_std_dev_count = 0;
+ for (i =0; i < perf->iterations; i++) {
+ cairo_perf_yield ();
+ if (similar)
+ cairo_push_group_with_content (perf->cr,
+ cairo_boilerplate_content (perf->target->content));
+ else
+ cairo_save (perf->cr);
+ times[i] = perf_func (perf->cr, perf->size, perf->size, loops) ;
+ if (similar)
+ cairo_pattern_destroy (cairo_pop_group (perf->cr));
+ else
+ cairo_restore (perf->cr);
+ if (perf->raw) {
+ if (i == 0)
+ printf ("[*] %s.%s %s.%d %g",
+ perf->target->name,
+ _content_to_string (perf->target->content, similar),
+ name, perf->size,
+ _cairo_time_to_double (_cairo_time_from_s (1.)) / 1000.);
+ printf (" %lld", (long long) (times[i] / (double) loops));
+ } else if (! perf->exact_iterations) {
+ if (i > 0) {
+ _cairo_stats_compute (&stats, times, i+1);
+
+ if (stats.std_dev <= CAIRO_PERF_LOW_STD_DEV) {
+ low_std_dev_count++;
+ if (low_std_dev_count >= CAIRO_PERF_STABLE_STD_DEV_COUNT)
+ break;
+ } else {
+ low_std_dev_count = 0;
+ }
+ }
+ }
+ }
+
+ if (perf->raw)
+ printf ("\n");
+
+ if (perf->summary) {
+ _cairo_stats_compute (&stats, times, i);
+ if (count_func != NULL) {
+ double count = count_func (perf->cr, perf->size, perf->size);
+ fprintf (perf->summary,
+ "%.3f [%10lld/%d] %#8.3f %#8.3f %#5.2f%% %3d: %.2f\n",
+ stats.min_ticks /(double) loops,
+ (long long) stats.min_ticks, loops,
+ _cairo_time_to_s (stats.min_ticks) * 1000.0 / loops,
+ _cairo_time_to_s (stats.median_ticks) * 1000.0 / loops,
+ stats.std_dev * 100.0, stats.iterations,
+ count / _cairo_time_to_s (stats.min_ticks));
+ } else {
+ fprintf (perf->summary,
+ "%.3f [%10lld/%d] %#8.3f %#8.3f %#5.2f%% %3d\n",
+ stats.min_ticks /(double) loops,
+ (long long) stats.min_ticks, loops,
+ _cairo_time_to_s (stats.min_ticks) * 1000.0 / loops,
+ _cairo_time_to_s (stats.median_ticks) * 1000.0 / loops,
+ stats.std_dev * 100.0, stats.iterations);
+ }
+ fflush (perf->summary);
+ }
+
+ perf->test_number++;
+ }
+}
+
+static void
+usage (const char *argv0)
+{
+ fprintf (stderr,
+"Usage: %s [-flrv] [-i iterations] [test-names ...]\n"
+"\n"
+"Run the cairo performance test suite over the given tests (all by default)\n"
+"The command-line arguments are interpreted as follows:\n"
+"\n"
+" -f fast; faster, less accurate\n"
+" -i iterations; specify the number of iterations per test case\n"
+" -l list only; just list selected test case names without executing\n"
+" -r raw; display each time measurement instead of summary statistics\n"
+" -v verbose; in raw mode also show the summaries\n"
+"\n"
+"If test names are given they are used as sub-string matches so a command\n"
+"such as \"%s text\" can be used to run all text test cases.\n",
+ argv0, argv0);
+}
+
+static void
+parse_options (cairo_perf_t *perf,
+ int argc,
+ char *argv[])
+{
+ int c;
+ const char *iters;
+ const char *ms = NULL;
+ char *end;
+ int verbose = 0;
+
+ if ((iters = getenv("CAIRO_PERF_ITERATIONS")) && *iters)
+ perf->iterations = strtol(iters, NULL, 0);
+ else
+ perf->iterations = CAIRO_PERF_ITERATIONS_DEFAULT;
+ perf->exact_iterations = 0;
+
+ perf->fast_and_sloppy = FALSE;
+ perf->ms_per_iteration = CAIRO_PERF_ITERATION_MS_DEFAULT;
+ if ((ms = getenv("CAIRO_PERF_ITERATION_MS")) && *ms) {
+ perf->ms_per_iteration = atof(ms);
+ }
+
+ perf->raw = FALSE;
+ perf->list_only = FALSE;
+ perf->names = NULL;
+ perf->num_names = 0;
+ perf->summary = stdout;
+
+ while (1) {
+ c = _cairo_getopt (argc, argv, "fi:lrv");
+ if (c == -1)
+ break;
+
+ switch (c) {
+ case 'f':
+ perf->fast_and_sloppy = TRUE;
+ if (ms == NULL)
+ perf->ms_per_iteration = CAIRO_PERF_ITERATION_MS_FAST;
+ break;
+ case 'i':
+ perf->exact_iterations = TRUE;
+ perf->iterations = strtoul (optarg, &end, 10);
+ if (*end != '\0') {
+ fprintf (stderr, "Invalid argument for -i (not an integer): %s\n",
+ optarg);
+ exit (1);
+ }
+ break;
+ case 'l':
+ perf->list_only = TRUE;
+ break;
+ case 'r':
+ perf->raw = TRUE;
+ perf->summary = NULL;
+ break;
+ case 'v':
+ verbose = 1;
+ break;
+ default:
+ fprintf (stderr, "Internal error: unhandled option: %c\n", c);
+ /* fall-through */
+ case '?':
+ usage (argv[0]);
+ exit (1);
+ }
+ }
+
+ if (verbose && perf->summary == NULL)
+ perf->summary = stderr;
+
+ if (optind < argc) {
+ perf->names = &argv[optind];
+ perf->num_names = argc - optind;
+ }
+}
+
+static int
+check_cpu_affinity (void)
+{
+#ifdef HAVE_SCHED_GETAFFINITY
+
+ cpu_set_t affinity;
+ int i, cpu_count;
+
+ if (sched_getaffinity(0, sizeof(affinity), &affinity)) {
+ perror("sched_getaffinity");
+ return -1;
+ }
+
+ for(i = 0, cpu_count = 0; i < CPU_SETSIZE; ++i) {
+ if (CPU_ISSET(i, &affinity))
+ ++cpu_count;
+ }
+
+ if (cpu_count > 1) {
+ fputs(
+ "WARNING: cairo-perf has not been bound to a single CPU.\n",
+ stderr);
+ return -1;
+ }
+
+ return 0;
+#else
+ fputs(
+ "WARNING: Cannot check CPU affinity for this platform.\n",
+ stderr);
+ return -1;
+#endif
+}
+
+static void
+cairo_perf_fini (cairo_perf_t *perf)
+{
+ cairo_boilerplate_free_targets (perf->targets);
+ cairo_boilerplate_fini ();
+
+ free (perf->times);
+ cairo_debug_reset_static_data ();
+#if HAVE_FCFINI
+ FcFini ();
+#endif
+}
+
+
+int
+main (int argc,
+ char *argv[])
+{
+ int i, j;
+ cairo_perf_t perf;
+ cairo_surface_t *surface;
+
+ parse_options (&perf, argc, argv);
+
+ if (check_cpu_affinity()) {
+ fputs(
+ "NOTICE: cairo-perf and the X server should be bound to CPUs (either the same\n"
+ "or separate) on SMP systems. Not doing so causes random results when the X\n"
+ "server is moved to or from cairo-perf's CPU during the benchmarks:\n"
+ "\n"
+ " $ sudo taskset -cp 0 $(pidof X)\n"
+ " $ taskset -cp 1 $$\n"
+ "\n"
+ "See taskset(1) for information about changing CPU affinity.\n",
+ stderr);
+ }
+
+ perf.targets = cairo_boilerplate_get_targets (&perf.num_targets, NULL);
+ perf.times = xmalloc (perf.iterations * sizeof (cairo_time_t));
+
+ for (i = 0; i < perf.num_targets; i++) {
+ const cairo_boilerplate_target_t *target = perf.targets[i];
+
+ if (! target->is_measurable)
+ continue;
+
+ perf.target = target;
+ perf.test_number = 0;
+
+ for (j = 0; perf_cases[j].run; j++) {
+ const cairo_perf_case_t *perf_case = &perf_cases[j];
+
+ if (! perf_case->enabled (&perf))
+ continue;
+
+ for (perf.size = perf_case->min_size;
+ perf.size <= perf_case->max_size;
+ perf.size *= 2)
+ {
+ void *closure;
+
+ surface = (target->create_surface) (NULL,
+ target->content,
+ perf.size, perf.size,
+ perf.size, perf.size,
+ CAIRO_BOILERPLATE_MODE_PERF,
+ &closure);
+ if (surface == NULL) {
+ fprintf (stderr,
+ "Error: Failed to create target surface: %s\n",
+ target->name);
+ continue;
+ }
+
+ cairo_perf_timer_set_synchronize (target->synchronize, closure);
+
+ perf.cr = cairo_create (surface);
+
+ perf_case->run (&perf, perf.cr, perf.size, perf.size);
+
+ if (cairo_status (perf.cr)) {
+ fprintf (stderr, "Error: Test left cairo in an error state: %s\n",
+ cairo_status_to_string (cairo_status (perf.cr)));
+ }
+
+ cairo_destroy (perf.cr);
+ cairo_surface_destroy (surface);
+
+ if (target->cleanup)
+ target->cleanup (closure);
+ }
+ }
+ }
+
+ cairo_perf_fini (&perf);
+
+ return 0;
+}
+
+#define FUNC(f) f, f##_enabled
+const cairo_perf_case_t perf_cases[] = {
+ { FUNC(pixel), 1, 1 },
+ { FUNC(a1_pixel), 1, 1 },
+ { FUNC(paint), 64, 512},
+ { FUNC(paint_with_alpha), 64, 512},
+ { FUNC(fill), 64, 512},
+ { FUNC(stroke), 64, 512},
+ { FUNC(text), 64, 512},
+ { FUNC(glyphs), 64, 512},
+ { FUNC(mask), 64, 512},
+ { FUNC(line), 32, 512},
+ { FUNC(a1_line), 32, 512},
+ { FUNC(curve), 32, 512},
+ { FUNC(a1_curve), 32, 512},
+ { FUNC(disjoint), 64, 512},
+ { FUNC(hatching), 64, 512},
+ { FUNC(tessellate), 100, 100},
+ { FUNC(subimage_copy), 16, 512},
+ { FUNC(hash_table), 16, 16},
+ { FUNC(pattern_create_radial), 16, 16},
+ { FUNC(zrusin), 415, 415},
+ { FUNC(world_map), 800, 800},
+ { FUNC(box_outline), 100, 100},
+ { FUNC(mosaic), 800, 800 },
+ { FUNC(long_lines), 100, 100},
+ { FUNC(unaligned_clip), 100, 100},
+ { FUNC(rectangles), 512, 512},
+ { FUNC(rounded_rectangles), 512, 512},
+ { FUNC(long_dashed_lines), 512, 512},
+ { FUNC(composite_checker), 16, 512},
+ { FUNC(twin), 800, 800},
+ { FUNC(dragon), 1024, 1024 },
+ { FUNC(sierpinski), 32, 1024 },
+ { FUNC(pythagoras_tree), 768, 768 },
+ { FUNC(intersections), 512, 512 },
+ { FUNC(many_strokes), 32, 512 },
+ { FUNC(wide_strokes), 32, 512 },
+ { FUNC(many_fills), 32, 512 },
+ { FUNC(wide_fills), 32, 512 },
+ { FUNC(many_curves), 32, 512 },
+ { FUNC(spiral), 512, 512 },
+ { FUNC(wave), 500, 500 },
+ { FUNC(fill_clip), 16, 512 },
+ { FUNC(tiger), 16, 1024 },
+ { NULL }
+};
diff --git a/perf/cairo-perf-print.c b/perf/cairo-perf-print.c
new file mode 100644
index 000000000..d7ae1311e
--- /dev/null
+++ b/perf/cairo-perf-print.c
@@ -0,0 +1,139 @@
+/*
+ * Copyright © 2006 Red Hat, Inc.
+ * Copyright © 2009 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of the
+ * copyright holders not be used in advertising or publicity
+ * pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied
+ * warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ *
+ * Authors: Carl Worth <cworth@cworth.org>
+ * Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "cairo-perf.h"
+#include "cairo-stats.h"
+
+#include <stdio.h>
+
+#if HAVE_UNISTD_H && HAVE_SYS_IOCTL_H
+#define USE_TERMINAL_SIZE 1
+#else
+#define USE_TERMINAL_SIZE 0
+#endif
+
+#if USE_TERMINAL_SIZE
+#include <unistd.h>
+#include <sys/ioctl.h>
+#endif
+
+static void
+report_print (const cairo_perf_report_t *report,
+ int show_histogram)
+{
+ const test_report_t *test;
+ cairo_histogram_t h;
+
+ if (show_histogram) {
+ int num_rows = 23;
+ int num_cols = 80;
+
+#if USE_TERMINAL_SIZE
+ int fd = fileno(stdout);
+ if (isatty(fd)) {
+ struct winsize ws;
+
+ if(ioctl(fd, TIOCGWINSZ, &ws) == 0 ) {
+ num_rows = ws.ws_row - 1;
+ num_cols = ws.ws_col;
+ }
+ }
+#endif
+
+ if (!_cairo_histogram_init (&h, num_cols, num_rows))
+ show_histogram = 0;
+ }
+
+ for (test = report->tests; test->name != NULL; test++) {
+ if (test->stats.iterations == 0)
+ continue;
+
+ if (show_histogram) {
+ const cairo_time_t *values;
+ int num_values;
+
+ if (show_histogram > 1) {
+ values = test->stats.values;
+ num_values = test->stats.iterations;
+ } else {
+ values = test->samples;
+ num_values = test->samples_count;
+ }
+
+ if (_cairo_histogram_compute (&h, values, num_values))
+ _cairo_histogram_printf (&h, stdout);
+ }
+
+ if (test->size) {
+ printf ("%5s-%-4s %26s-%-3d ",
+ test->backend, test->content,
+ test->name, test->size);
+ } else {
+ printf ("%5s %26s ", test->backend, test->name);
+ }
+ printf("%6.2f %4.2f%% (%d/%d)\n",
+ test->stats.median_ticks / test->stats.ticks_per_ms,
+ test->stats.std_dev * 100,
+ test->stats.iterations, test->samples_count);
+ }
+
+ if (show_histogram)
+ _cairo_histogram_fini (&h);
+}
+
+int
+main (int argc,
+ const char *argv[])
+{
+ cairo_bool_t show_histogram = 0;
+ int i;
+
+ for (i = 1; i < argc; i++ ) {
+ cairo_perf_report_t report;
+
+ if (strcmp(argv[i], "--histogram") == 0) {
+ show_histogram = 1;
+ continue;
+ }
+
+ if (strcmp(argv[i], "--short-histogram") == 0) {
+ show_histogram = 2;
+ continue;
+ }
+
+ cairo_perf_report_load (&report, argv[i], i, NULL);
+ report_print (&report, show_histogram);
+ }
+
+ return 0;
+}
diff --git a/perf/cairo-perf-report.c b/perf/cairo-perf-report.c
new file mode 100644
index 000000000..2325f4793
--- /dev/null
+++ b/perf/cairo-perf-report.c
@@ -0,0 +1,454 @@
+/*
+ * Copyright © 2006 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of the
+ * copyright holders not be used in advertising or publicity
+ * pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied
+ * warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ *
+ * Authors: Carl Worth <cworth@cworth.org>
+ */
+
+#define _GETDELIM 1/* for getline() on AIX */
+
+#include "cairo-perf.h"
+#include "cairo-missing.h"
+#include "cairo-stats.h"
+
+/* We use _GNU_SOURCE for getline and strndup if available. */
+#ifndef _GNU_SOURCE
+# define _GNU_SOURCE
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <ctype.h>
+#include <math.h>
+#include <assert.h>
+#ifdef HAVE_LIBGEN_H
+#include <libgen.h>
+#endif
+
+#ifdef _MSC_VER
+static long long
+strtoll (const char *nptr,
+ char **endptr,
+ int base);
+
+static char *
+basename (char *path);
+#endif
+
+/* Ad-hoc parsing, macros with a strong dependence on the calling
+ * context, and plenty of other ugliness is here. But at least it's
+ * not perl... */
+#define parse_error(...) fprintf(stderr, __VA_ARGS__); return TEST_REPORT_STATUS_ERROR;
+#define skip_char(c) \
+do { \
+ if (*s && *s == (c)) { \
+ s++; \
+ } else { \
+ parse_error ("expected '%c' but found '%c'", c, *s); \
+ } \
+} while (0)
+#define skip_space() while (*s && (*s == ' ' || *s == '\t')) s++;
+#define parse_int(result) \
+do { \
+ (result) = strtol (s, &end, 10); \
+ if (*s && end != s) { \
+ s = end; \
+ } else { \
+ parse_error("expected integer but found %s", s); \
+ } \
+} while (0)
+#define parse_long_long(result) \
+do { \
+ (result) = strtoll (s, &end, 10); \
+ if (*s && end != s) { \
+ s = end; \
+ } else { \
+ parse_error("expected integer but found %s", s); \
+ } \
+} while (0)
+#define parse_double(result) \
+do { \
+ (result) = strtod (s, &end); \
+ if (*s && end != s) { \
+ s = end; \
+ } else { \
+ parse_error("expected floating-point value but found %s", s); \
+ } \
+} while (0)
+/* Here a string is simply a sequence of non-whitespace */
+#define parse_string(result) \
+do { \
+ for (end = s; *end; end++) \
+ if (isspace (*end)) \
+ break; \
+ (result) = strndup (s, end - s); \
+ if ((result) == NULL) { \
+ fprintf (stderr, "Out of memory.\n"); \
+ exit (1); \
+ } \
+ s = end; \
+} while (0)
+
+static test_report_status_t
+test_report_parse (test_report_t *report,
+ int fileno,
+ char *line,
+ char *configuration)
+{
+ char *end;
+ char *s = line;
+ cairo_bool_t is_raw = FALSE;
+ double min_time, median_time;
+
+ /* The code here looks funny unless you understand that these are
+ * all macro calls, (and then the code just looks sick). */
+ if (*s == '\n')
+ return TEST_REPORT_STATUS_COMMENT;
+
+ skip_char ('[');
+ skip_space ();
+ if (*s == '#')
+ return TEST_REPORT_STATUS_COMMENT;
+ if (*s == '*') {
+ s++;
+ is_raw = TRUE;
+ } else {
+ parse_int (report->id);
+ }
+ skip_char (']');
+
+ skip_space ();
+
+ report->fileno = fileno;
+ report->configuration = configuration;
+ parse_string (report->backend);
+ end = strrchr (report->backend, '.');
+ if (end)
+ *end++ = '\0';
+ report->content = end ? end : xstrdup ("???");
+
+ skip_space ();
+
+ parse_string (report->name);
+ end = strrchr (report->name, '.');
+ if (end)
+ *end++ = '\0';
+ report->size = end ? atoi (end) : 0;
+
+ skip_space ();
+
+ report->samples = NULL;
+ report->samples_size = 0;
+ report->samples_count = 0;
+
+ if (is_raw) {
+ parse_double (report->stats.ticks_per_ms);
+ skip_space ();
+
+ report->samples_size = 5;
+ report->samples = xmalloc (report->samples_size * sizeof (cairo_time_t));
+ report->stats.min_ticks = 0;
+ do {
+ if (report->samples_count == report->samples_size) {
+ report->samples_size *= 2;
+ report->samples = xrealloc (report->samples,
+ report->samples_size * sizeof (cairo_time_t));
+ }
+ parse_long_long (report->samples[report->samples_count]);
+ if (report->samples_count == 0) {
+ report->stats.min_ticks =
+ report->samples[report->samples_count];
+ } else if (report->stats.min_ticks >
+ report->samples[report->samples_count]){
+ report->stats.min_ticks =
+ report->samples[report->samples_count];
+ }
+ report->samples_count++;
+ skip_space ();
+ } while (*s && *s != '\n');
+ report->stats.iterations = 0;
+ if (*s) skip_char ('\n');
+ } else {
+ parse_double (report->stats.min_ticks);
+ skip_space ();
+
+ parse_double (min_time);
+ report->stats.ticks_per_ms = report->stats.min_ticks / min_time;
+
+ skip_space ();
+
+ parse_double (median_time);
+ report->stats.median_ticks = median_time * report->stats.ticks_per_ms;
+
+ skip_space ();
+
+ parse_double (report->stats.std_dev);
+ report->stats.std_dev /= 100.0;
+ skip_char ('%');
+
+ skip_space ();
+
+ parse_int (report->stats.iterations);
+
+ skip_space ();
+ skip_char ('\n');
+ }
+
+ return TEST_REPORT_STATUS_SUCCESS;
+}
+
+/* We provide hereafter a win32 implementation of the basename
+ * and strtoll functions which are not available otherwise.
+ * The basename function is fully compliant to its GNU specs.
+ */
+#ifdef _MSC_VER
+long long
+strtoll (const char *nptr,
+ char **endptr,
+ int base)
+{
+ return _atoi64(nptr);
+}
+
+static char *
+basename (char *path)
+{
+ char *end, *s;
+
+ end = (path + strlen(path) - 1);
+ while (end && (end >= path + 1) && (*end == '/')) {
+ *end = '\0';
+ end--;
+ }
+
+ s = strrchr(path, '/');
+ if (s) {
+ if (s == end) {
+ return s;
+ } else {
+ return s+1;
+ }
+ } else {
+ return path;
+ }
+}
+#endif /* ifndef _MSC_VER */
+
+int
+test_report_cmp_backend_then_name (const void *a,
+ const void *b)
+{
+ const test_report_t *a_test = a;
+ const test_report_t *b_test = b;
+
+ int cmp;
+
+ cmp = strcmp (a_test->backend, b_test->backend);
+ if (cmp)
+ return cmp;
+
+ cmp = strcmp (a_test->content, b_test->content);
+ if (cmp)
+ return cmp;
+
+ /* A NULL name is a list-termination marker, so force it last. */
+ if (a_test->name == NULL)
+ if (b_test->name == NULL)
+ return 0;
+ else
+ return 1;
+ else if (b_test->name == NULL)
+ return -1;
+
+ cmp = strcmp (a_test->name, b_test->name);
+ if (cmp)
+ return cmp;
+
+ if (a_test->size < b_test->size)
+ return -1;
+ if (a_test->size > b_test->size)
+ return 1;
+
+ return 0;
+}
+
+int
+test_report_cmp_name (const void *a,
+ const void *b)
+{
+ const test_report_t *a_test = a;
+ const test_report_t *b_test = b;
+
+ int cmp;
+
+ /* A NULL name is a list-termination marker, so force it last. */
+ if (a_test->name == NULL)
+ if (b_test->name == NULL)
+ return 0;
+ else
+ return 1;
+ else if (b_test->name == NULL)
+ return -1;
+
+ cmp = strcmp (a_test->name, b_test->name);
+ if (cmp)
+ return cmp;
+
+ if (a_test->size < b_test->size)
+ return -1;
+ if (a_test->size > b_test->size)
+ return 1;
+
+ return 0;
+}
+
+void
+cairo_perf_report_sort_and_compute_stats (cairo_perf_report_t *report,
+ int (*cmp) (const void*, const void*))
+{
+ test_report_t *base, *next, *last, *t;
+
+ if (cmp == NULL)
+ cmp = test_report_cmp_backend_then_name;
+
+ /* First we sort, since the diff needs both lists in the same
+ * order */
+ qsort (report->tests, report->tests_count, sizeof (test_report_t), cmp);
+
+ /* The sorting also brings all related raw reports together so we
+ * can condense them and compute the stats.
+ */
+ base = &report->tests[0];
+ last = &report->tests[report->tests_count - 1];
+ while (base <= last) {
+ next = base+1;
+ if (next <= last) {
+ while (next <= last &&
+ test_report_cmp_backend_then_name (base, next) == 0)
+ {
+ next++;
+ }
+ if (next != base) {
+ unsigned int new_samples_count = base->samples_count;
+ for (t = base + 1; t < next; t++)
+ new_samples_count += t->samples_count;
+ if (new_samples_count > base->samples_size) {
+ base->samples_size = new_samples_count;
+ base->samples = xrealloc (base->samples,
+ base->samples_size * sizeof (cairo_time_t));
+ }
+ for (t = base + 1; t < next; t++) {
+ memcpy (&base->samples[base->samples_count], t->samples,
+ t->samples_count * sizeof (cairo_time_t));
+ base->samples_count += t->samples_count;
+ }
+ }
+ }
+ if (base->samples)
+ _cairo_stats_compute (&base->stats, base->samples, base->samples_count);
+ base = next;
+ }
+}
+
+void
+cairo_perf_report_load (cairo_perf_report_t *report,
+ const char *filename, int id,
+ int (*cmp) (const void *, const void *))
+{
+ FILE *file;
+ test_report_status_t status;
+ int line_number = 0;
+ char *line = NULL;
+ size_t line_size = 0;
+ char *configuration;
+ char *dot;
+ char *baseName;
+ const char *name;
+
+ name = filename;
+ if (name == NULL)
+ name = "stdin";
+
+ configuration = xstrdup (name);
+ baseName = basename (configuration);
+ report->configuration = xstrdup (baseName);
+ free (configuration);
+
+ dot = strrchr (report->configuration, '.');
+ if (dot)
+ *dot = '\0';
+
+ report->name = name;
+ report->tests_size = 16;
+ report->tests = xmalloc (report->tests_size * sizeof (test_report_t));
+ report->tests_count = 0;
+ report->fileno = id;
+
+ if (filename == NULL) {
+ file = stdin;
+ } else {
+ file = fopen (filename, "r");
+ if (file == NULL) {
+ fprintf (stderr, "Failed to open %s: %s\n",
+ filename, strerror (errno));
+ exit (1);
+ }
+ }
+
+ while (1) {
+ if (report->tests_count == report->tests_size) {
+ report->tests_size *= 2;
+ report->tests = xrealloc (report->tests,
+ report->tests_size * sizeof (test_report_t));
+ }
+
+ line_number++;
+ if (getline (&line, &line_size, file) == -1)
+ break;
+
+ status = test_report_parse (&report->tests[report->tests_count],
+ id, line, report->configuration);
+ if (status == TEST_REPORT_STATUS_ERROR)
+ fprintf (stderr, "Ignoring unrecognized line %d of %s:\n%s",
+ line_number, filename, line);
+ if (status == TEST_REPORT_STATUS_SUCCESS)
+ report->tests_count++;
+ /* Do nothing on TEST_REPORT_STATUS_COMMENT */
+ }
+
+ free (line);
+
+ if (filename != NULL)
+ fclose (file);
+
+ cairo_perf_report_sort_and_compute_stats (report, cmp);
+
+ /* Add one final report with a NULL name to terminate the list. */
+ if (report->tests_count == report->tests_size) {
+ report->tests_size *= 2;
+ report->tests = xrealloc (report->tests,
+ report->tests_size * sizeof (test_report_t));
+ }
+ report->tests[report->tests_count].name = NULL;
+}
diff --git a/perf/cairo-perf-trace.c b/perf/cairo-perf-trace.c
new file mode 100644
index 000000000..02e0e29f9
--- /dev/null
+++ b/perf/cairo-perf-trace.c
@@ -0,0 +1,1067 @@
+/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */
+/*
+ * Copyright © 2006 Mozilla Corporation
+ * Copyright © 2006 Red Hat, Inc.
+ * Copyright © 2009 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * the authors not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. The authors make no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Vladimir Vukicevic <vladimir@pobox.com>
+ * Carl Worth <cworth@cworth.org>
+ * Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#define _GNU_SOURCE 1 /* for sched_getaffinity() and getline() */
+
+#include "../cairo-version.h" /* for the real version */
+
+#include "cairo-missing.h"
+#include "cairo-perf.h"
+#include "cairo-stats.h"
+
+#include "cairo-boilerplate-getopt.h"
+#include <cairo-script-interpreter.h>
+#include <cairo-types-private.h> /* for INTERNAL_SURFACE_TYPE */
+
+/* rudely reuse bits of the library... */
+#include "../src/cairo-hash-private.h"
+#include "../src/cairo-error-private.h"
+
+/* For basename */
+#ifdef HAVE_LIBGEN_H
+#include <libgen.h>
+#endif
+#include <ctype.h> /* isspace() */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#ifdef _MSC_VER
+#include "dirent-win32.h"
+
+static char *
+basename_no_ext (char *path)
+{
+ static char name[_MAX_FNAME + 1];
+
+ _splitpath (path, NULL, NULL, name, NULL);
+
+ name[_MAX_FNAME] = '\0';
+
+ return name;
+}
+
+
+#else
+#include <dirent.h>
+
+static char *
+basename_no_ext (char *path)
+{
+ char *dot, *name;
+
+ name = basename (path);
+
+ dot = strrchr (name, '.');
+ if (dot)
+ *dot = '\0';
+
+ return name;
+}
+
+#endif
+
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include <signal.h>
+
+#if HAVE_FCFINI
+#include <fontconfig/fontconfig.h>
+#endif
+
+#define CAIRO_PERF_ITERATIONS_DEFAULT 15
+#define CAIRO_PERF_LOW_STD_DEV 0.05
+#define CAIRO_PERF_MIN_STD_DEV_COUNT 3
+#define CAIRO_PERF_STABLE_STD_DEV_COUNT 3
+
+struct trace {
+ const cairo_boilerplate_target_t *target;
+ void *closure;
+ cairo_surface_t *surface;
+ cairo_bool_t observe;
+ int tile_size;
+};
+
+cairo_bool_t
+cairo_perf_can_run (cairo_perf_t *perf,
+ const char *name,
+ cairo_bool_t *is_explicit)
+{
+ unsigned int i;
+ char *copy, *dot;
+ cairo_bool_t ret;
+
+ if (is_explicit)
+ *is_explicit = FALSE;
+
+ if (perf->exact_names) {
+ if (is_explicit)
+ *is_explicit = TRUE;
+ return TRUE;
+ }
+
+ if (perf->num_names == 0 && perf->num_exclude_names == 0)
+ return TRUE;
+
+ copy = xstrdup (name);
+ dot = strrchr (copy, '.');
+ if (dot != NULL)
+ *dot = '\0';
+
+ if (perf->num_names) {
+ ret = TRUE;
+ for (i = 0; i < perf->num_names; i++)
+ if (strstr (copy, perf->names[i])) {
+ if (is_explicit)
+ *is_explicit = strcmp (copy, perf->names[i]) == 0;
+ goto check_exclude;
+ }
+
+ ret = FALSE;
+ goto done;
+ }
+
+check_exclude:
+ if (perf->num_exclude_names) {
+ ret = FALSE;
+ for (i = 0; i < perf->num_exclude_names; i++)
+ if (strstr (copy, perf->exclude_names[i])) {
+ if (is_explicit)
+ *is_explicit = strcmp (copy, perf->exclude_names[i]) == 0;
+ goto done;
+ }
+
+ ret = TRUE;
+ goto done;
+ }
+
+done:
+ free (copy);
+
+ return ret;
+}
+
+static void
+fill_surface (cairo_surface_t *surface)
+{
+ cairo_t *cr = cairo_create (surface);
+ /* This needs to be an operation that the backends can't optimise away */
+ cairo_set_source_rgba (cr, 0.5, 0.5, 0.5, 0.5);
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+ cairo_paint (cr);
+ cairo_destroy (cr);
+}
+
+struct scache {
+ cairo_hash_entry_t entry;
+ cairo_content_t content;
+ int width, height;
+ cairo_surface_t *surface;
+};
+
+static cairo_hash_table_t *surface_cache;
+static cairo_surface_t *surface_holdovers[16];
+
+static cairo_bool_t
+scache_equal (const void *A,
+ const void *B)
+{
+ const struct scache *a = A, *b = B;
+ return a->entry.hash == b->entry.hash;
+}
+
+static void
+scache_mark_active (cairo_surface_t *surface)
+{
+ cairo_surface_t *t0, *t1;
+ unsigned n;
+
+ if (surface_cache == NULL)
+ return;
+
+ t0 = cairo_surface_reference (surface);
+ for (n = 0; n < ARRAY_LENGTH (surface_holdovers); n++) {
+ if (surface_holdovers[n] == surface) {
+ surface_holdovers[n] = t0;
+ t0 = surface;
+ break;
+ }
+
+ t1 = surface_holdovers[n];
+ surface_holdovers[n] = t0;
+ t0 = t1;
+ }
+ cairo_surface_destroy (t0);
+}
+
+static void
+scache_clear (void)
+{
+ unsigned n;
+
+ if (surface_cache == NULL)
+ return;
+
+ for (n = 0; n < ARRAY_LENGTH (surface_holdovers); n++) {
+ cairo_surface_destroy (surface_holdovers[n]);
+ surface_holdovers[n] = NULL;
+ }
+}
+
+static void
+scache_remove (void *closure)
+{
+ _cairo_hash_table_remove (surface_cache, closure);
+ free (closure);
+}
+
+static cairo_surface_t *
+_similar_surface_create (void *closure,
+ cairo_content_t content,
+ double width,
+ double height,
+ long uid)
+{
+ struct trace *args = closure;
+ cairo_surface_t *surface;
+ struct scache skey, *s;
+
+ if (args->observe)
+ return cairo_surface_create_similar (args->surface,
+ content, width, height);
+
+ if (uid == 0 || surface_cache == NULL)
+ return args->target->create_similar (args->surface, content, width, height);
+
+ skey.entry.hash = uid;
+ s = _cairo_hash_table_lookup (surface_cache, &skey.entry);
+ if (s != NULL) {
+ if (s->content == content &&
+ s->width == width &&
+ s->height == height)
+ {
+ return cairo_surface_reference (s->surface);
+ }
+
+ /* The surface has been resized, allow the original entry to expire
+ * as it becomes inactive.
+ */
+ }
+
+ surface = args->target->create_similar (args->surface, content, width, height);
+ s = malloc (sizeof (struct scache));
+ if (s == NULL)
+ return surface;
+
+ s->entry.hash = uid;
+ s->content = content;
+ s->width = width;
+ s->height = height;
+ s->surface = surface;
+ if (_cairo_hash_table_insert (surface_cache, &s->entry)) {
+ free (s);
+ } else if (cairo_surface_set_user_data
+ (surface,
+ (const cairo_user_data_key_t *) &surface_cache,
+ s, scache_remove))
+ {
+ scache_remove (s);
+ }
+
+ return surface;
+}
+
+static cairo_surface_t *
+_source_image_create (void *closure,
+ cairo_format_t format,
+ int width,
+ int height,
+ long uid)
+{
+ struct trace *args = closure;
+
+ return cairo_surface_create_similar_image (args->surface,
+ format, width, height);
+}
+
+static cairo_t *
+_context_create (void *closure,
+ cairo_surface_t *surface)
+{
+ scache_mark_active (surface);
+ return cairo_create (surface);
+}
+
+static int user_interrupt;
+
+static void
+interrupt (int sig)
+{
+ if (user_interrupt) {
+ signal (sig, SIG_DFL);
+ raise (sig);
+ }
+
+ user_interrupt = 1;
+}
+
+static void
+describe (cairo_perf_t *perf,
+ void *closure)
+{
+ char *description = NULL;
+
+ if (perf->has_described_backend)
+ return;
+ perf->has_described_backend = TRUE;
+
+ if (perf->target->describe)
+ description = perf->target->describe (closure);
+
+ if (description == NULL)
+ return;
+
+ if (perf->raw) {
+ printf ("[ # ] %s: %s\n", perf->target->name, description);
+ }
+
+ if (perf->summary) {
+ fprintf (perf->summary,
+ "[ # ] %8s: %s\n",
+ perf->target->name,
+ description);
+ }
+
+ free (description);
+}
+
+static void
+usage (const char *argv0)
+{
+ fprintf (stderr,
+"Usage: %s [-clrsv] [-i iterations] [-t tile-size] [-x exclude-file] [test-names ... | traces ...]\n"
+"\n"
+"Run the cairo performance test suite over the given tests (all by default)\n"
+"The command-line arguments are interpreted as follows:\n"
+"\n"
+" -c use surface cache; keep a cache of surfaces to be reused\n"
+" -i iterations; specify the number of iterations per test case\n"
+" -l list only; just list selected test case names without executing\n"
+" -r raw; display each time measurement instead of summary statistics\n"
+" -s sync; only sum the elapsed time of the indiviual operations\n"
+" -t tile size; draw to tiled surfaces\n"
+" -v verbose; in raw mode also show the summaries\n"
+" -x exclude; specify a file to read a list of traces to exclude\n"
+"\n"
+"If test names are given they are used as sub-string matches so a command\n"
+"such as \"%s firefox\" can be used to run all firefox traces.\n"
+"Alternatively, you can specify a list of filenames to execute.\n",
+ argv0, argv0);
+}
+
+static cairo_bool_t
+read_excludes (cairo_perf_t *perf,
+ const char *filename)
+{
+ FILE *file;
+ char *line = NULL;
+ size_t line_size = 0;
+ char *s, *t;
+
+ file = fopen (filename, "r");
+ if (file == NULL)
+ return FALSE;
+
+ while (getline (&line, &line_size, file) != -1) {
+ /* terminate the line at a comment marker '#' */
+ s = strchr (line, '#');
+ if (s)
+ *s = '\0';
+
+ /* whitespace delimits */
+ s = line;
+ while (*s != '\0' && isspace (*s))
+ s++;
+
+ t = s;
+ while (*t != '\0' && ! isspace (*t))
+ t++;
+
+ if (s != t) {
+ int i = perf->num_exclude_names;
+ perf->exclude_names = xrealloc (perf->exclude_names,
+ sizeof (char *) * (i+1));
+ perf->exclude_names[i] = strndup (s, t-s);
+ perf->num_exclude_names++;
+ }
+ }
+ free (line);
+
+ fclose (file);
+
+ return TRUE;
+}
+
+static void
+parse_options (cairo_perf_t *perf,
+ int argc,
+ char *argv[])
+{
+ int c;
+ const char *iters;
+ char *end;
+ int verbose = 0;
+ int use_surface_cache = 0;
+
+ if ((iters = getenv ("CAIRO_PERF_ITERATIONS")) && *iters)
+ perf->iterations = strtol (iters, NULL, 0);
+ else
+ perf->iterations = CAIRO_PERF_ITERATIONS_DEFAULT;
+ perf->exact_iterations = 0;
+
+ perf->raw = FALSE;
+ perf->observe = FALSE;
+ perf->list_only = FALSE;
+ perf->tile_size = 0;
+ perf->names = NULL;
+ perf->num_names = 0;
+ perf->summary = stdout;
+ perf->summary_continuous = FALSE;
+ perf->exclude_names = NULL;
+ perf->num_exclude_names = 0;
+
+ while (1) {
+ c = _cairo_getopt (argc, argv, "ci:lrst:vx:");
+ if (c == -1)
+ break;
+
+ switch (c) {
+ case 'c':
+ use_surface_cache = 1;
+ break;
+ case 'i':
+ perf->exact_iterations = TRUE;
+ perf->iterations = strtoul (optarg, &end, 10);
+ if (*end != '\0') {
+ fprintf (stderr, "Invalid argument for -i (not an integer): %s\n",
+ optarg);
+ exit (1);
+ }
+ break;
+ case 'l':
+ perf->list_only = TRUE;
+ break;
+ case 'r':
+ perf->raw = TRUE;
+ perf->summary = NULL;
+ break;
+ case 's':
+ perf->observe = TRUE;
+ break;
+ case 't':
+ perf->tile_size = strtoul (optarg, &end, 10);
+ if (*end != '\0') {
+ fprintf (stderr, "Invalid argument for -t (not an integer): %s\n",
+ optarg);
+ exit (1);
+ }
+ break;
+ case 'v':
+ verbose = 1;
+ break;
+ case 'x':
+ if (! read_excludes (perf, optarg)) {
+ fprintf (stderr, "Invalid argument for -x (not readable file): %s\n",
+ optarg);
+ exit (1);
+ }
+ break;
+ default:
+ fprintf (stderr, "Internal error: unhandled option: %c\n", c);
+ /* fall-through */
+ case '?':
+ usage (argv[0]);
+ exit (1);
+ }
+ }
+
+ if (perf->observe && perf->tile_size) {
+ fprintf (stderr, "Can't mix observer and tiling. Sorry.\n");
+ exit (1);
+ }
+
+ if (verbose && perf->summary == NULL)
+ perf->summary = stderr;
+#if HAVE_UNISTD_H
+ if (perf->summary && isatty (fileno (perf->summary)))
+ perf->summary_continuous = TRUE;
+#endif
+
+ if (optind < argc) {
+ perf->names = &argv[optind];
+ perf->num_names = argc - optind;
+ }
+
+ if (use_surface_cache)
+ surface_cache = _cairo_hash_table_create (scache_equal);
+}
+
+static void
+cairo_perf_fini (cairo_perf_t *perf)
+{
+ cairo_boilerplate_free_targets (perf->targets);
+ cairo_boilerplate_fini ();
+
+ free (perf->times);
+ cairo_debug_reset_static_data ();
+#if HAVE_FCFINI
+ FcFini ();
+#endif
+}
+
+static cairo_bool_t
+have_trace_filenames (cairo_perf_t *perf)
+{
+ unsigned int i;
+
+ if (perf->num_names == 0)
+ return FALSE;
+
+#if HAVE_UNISTD_H
+ for (i = 0; i < perf->num_names; i++)
+ if (access (perf->names[i], R_OK) == 0)
+ return TRUE;
+#endif
+
+ return FALSE;
+}
+
+static void
+_tiling_surface_finish (cairo_surface_t *observer,
+ cairo_surface_t *target,
+ void *closure)
+{
+ struct trace *args = closure;
+ cairo_surface_t *surface;
+ cairo_content_t content;
+ cairo_rectangle_t r;
+ int width, height;
+ int x, y, w, h;
+
+ cairo_recording_surface_get_extents (target, &r);
+ w = r.width;
+ h = r.height;
+
+ content = cairo_surface_get_content (target);
+
+ for (y = 0; y < h; y += args->tile_size) {
+ height = args->tile_size;
+ if (y + height > h)
+ height = h - y;
+
+ for (x = 0; x < w; x += args->tile_size) {
+ cairo_t *cr;
+
+ width = args->tile_size;
+ if (x + width > w)
+ width = w - x;
+
+ /* XXX to correctly observe the playback we would need
+ * to replay the target onto the observer directly.
+ */
+ surface = args->target->create_similar (args->surface,
+ content, width, height);
+
+ cr = cairo_create (surface);
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_set_source_surface (cr, target, -x, -y);
+ cairo_paint (cr);
+ cairo_destroy (cr);
+
+ cairo_surface_destroy (surface);
+ }
+ }
+}
+
+static cairo_surface_t *
+_tiling_surface_create (void *closure,
+ cairo_content_t content,
+ double width,
+ double height,
+ long uid)
+{
+ cairo_rectangle_t r;
+ cairo_surface_t *surface, *observer;
+
+ r.x = r.y = 0;
+ r.width = width;
+ r.height = height;
+
+ surface = cairo_recording_surface_create (content, &r);
+ observer = cairo_surface_create_observer (surface,
+ CAIRO_SURFACE_OBSERVER_NORMAL);
+ cairo_surface_destroy (surface);
+
+ cairo_surface_observer_add_finish_callback (observer,
+ _tiling_surface_finish,
+ closure);
+
+ return observer;
+}
+
+static void
+cairo_perf_trace (cairo_perf_t *perf,
+ const cairo_boilerplate_target_t *target,
+ const char *trace)
+{
+ static cairo_bool_t first_run = TRUE;
+ unsigned int i;
+ cairo_time_t *times, *paint, *mask, *fill, *stroke, *glyphs;
+ cairo_stats_t stats = {0.0, 0.0};
+ struct trace args = { target };
+ int low_std_dev_count;
+ char *trace_cpy, *name;
+ const cairo_script_interpreter_hooks_t hooks = {
+ &args,
+ perf->tile_size ? _tiling_surface_create : _similar_surface_create,
+ NULL, /* surface_destroy */
+ _context_create,
+ NULL, /* context_destroy */
+ NULL, /* show_page */
+ NULL, /* copy_page */
+ _source_image_create,
+ };
+
+ args.tile_size = perf->tile_size;
+ args.observe = perf->observe;
+
+ trace_cpy = xstrdup (trace);
+ name = basename_no_ext (trace_cpy);
+
+ if (perf->list_only) {
+ printf ("%s\n", name);
+ free (trace_cpy);
+ return;
+ }
+
+ if (first_run) {
+ if (perf->raw) {
+ printf ("[ # ] %s.%-s %s %s %s ...\n",
+ "backend", "content", "test-size", "ticks-per-ms", "time(ticks)");
+ }
+
+ if (perf->summary) {
+ if (perf->observe) {
+ fprintf (perf->summary,
+ "[ # ] %8s %28s %9s %9s %9s %9s %9s %9s %5s\n",
+ "backend", "test",
+ "total(s)", "paint(s)", "mask(s)", "fill(s)", "stroke(s)", "glyphs(s)",
+ "count");
+ } else {
+ fprintf (perf->summary,
+ "[ # ] %8s %28s %8s %5s %5s %s\n",
+ "backend", "test", "min(s)", "median(s)",
+ "stddev.", "count");
+ }
+ }
+ first_run = FALSE;
+ }
+
+ times = perf->times;
+ paint = times + perf->iterations;
+ mask = paint + perf->iterations;
+ stroke = mask + perf->iterations;
+ fill = stroke + perf->iterations;
+ glyphs = fill + perf->iterations;
+
+ low_std_dev_count = 0;
+ for (i = 0; i < perf->iterations && ! user_interrupt; i++) {
+ cairo_script_interpreter_t *csi;
+ cairo_status_t status;
+ unsigned int line_no;
+
+ args.surface = target->create_surface (NULL,
+ CAIRO_CONTENT_COLOR_ALPHA,
+ 1, 1,
+ 1, 1,
+ CAIRO_BOILERPLATE_MODE_PERF,
+ &args.closure);
+ fill_surface(args.surface); /* remove any clear flags */
+
+ if (perf->observe) {
+ cairo_surface_t *obs;
+ obs = cairo_surface_create_observer (args.surface,
+ CAIRO_SURFACE_OBSERVER_NORMAL);
+ cairo_surface_destroy (args.surface);
+ args.surface = obs;
+ }
+ if (cairo_surface_status (args.surface)) {
+ fprintf (stderr,
+ "Error: Failed to create target surface: %s\n",
+ target->name);
+ return;
+ }
+
+ cairo_perf_timer_set_synchronize (target->synchronize, args.closure);
+
+ if (i == 0) {
+ describe (perf, args.closure);
+ if (perf->summary) {
+ fprintf (perf->summary,
+ "[%3d] %8s %28s ",
+ perf->test_number,
+ perf->target->name,
+ name);
+ fflush (perf->summary);
+ }
+ }
+
+ csi = cairo_script_interpreter_create ();
+ cairo_script_interpreter_install_hooks (csi, &hooks);
+
+ if (! perf->observe) {
+ cairo_perf_yield ();
+ cairo_perf_timer_start ();
+ }
+
+ cairo_script_interpreter_run (csi, trace);
+ line_no = cairo_script_interpreter_get_line_number (csi);
+
+ /* Finish before querying timings in case we are using an intermediate
+ * target and so need to destroy all surfaces before rendering
+ * commences.
+ */
+ cairo_script_interpreter_finish (csi);
+
+ if (perf->observe) {
+ cairo_device_t *observer = cairo_surface_get_device (args.surface);
+ times[i] = _cairo_time_from_s (1.e-9 * cairo_device_observer_elapsed (observer));
+ paint[i] = _cairo_time_from_s (1.e-9 * cairo_device_observer_paint_elapsed (observer));
+ mask[i] = _cairo_time_from_s (1.e-9 * cairo_device_observer_mask_elapsed (observer));
+ stroke[i] = _cairo_time_from_s (1.e-9 * cairo_device_observer_stroke_elapsed (observer));
+ fill[i] = _cairo_time_from_s (1.e-9 * cairo_device_observer_fill_elapsed (observer));
+ glyphs[i] = _cairo_time_from_s (1.e-9 * cairo_device_observer_glyphs_elapsed (observer));
+ } else {
+ fill_surface (args.surface); /* queue a write to the sync'ed surface */
+ cairo_perf_timer_stop ();
+ times[i] = cairo_perf_timer_elapsed ();
+ }
+
+ scache_clear ();
+
+ cairo_surface_destroy (args.surface);
+
+ if (target->cleanup)
+ target->cleanup (args.closure);
+
+ status = cairo_script_interpreter_destroy (csi);
+ if (status) {
+ if (perf->summary) {
+ fprintf (perf->summary, "Error during replay, line %d: %s\n",
+ line_no,
+ cairo_status_to_string (status));
+ }
+ goto out;
+ }
+
+ if (perf->raw) {
+ if (i == 0)
+ printf ("[*] %s.%s %s.%d %g",
+ perf->target->name,
+ "rgba",
+ name,
+ 0,
+ _cairo_time_to_double (_cairo_time_from_s (1)) / 1000.);
+ printf (" %lld", (long long) times[i]);
+ fflush (stdout);
+ } else if (! perf->exact_iterations) {
+ if (i > CAIRO_PERF_MIN_STD_DEV_COUNT) {
+ _cairo_stats_compute (&stats, times, i+1);
+
+ if (stats.std_dev <= CAIRO_PERF_LOW_STD_DEV) {
+ if (++low_std_dev_count >= CAIRO_PERF_STABLE_STD_DEV_COUNT)
+ break;
+ } else {
+ low_std_dev_count = 0;
+ }
+ }
+ }
+
+ if (perf->summary && perf->summary_continuous) {
+ _cairo_stats_compute (&stats, times, i+1);
+
+ fprintf (perf->summary,
+ "\r[%3d] %8s %28s ",
+ perf->test_number,
+ perf->target->name,
+ name);
+ if (perf->observe) {
+ fprintf (perf->summary,
+ " %#9.3f", _cairo_time_to_s (stats.median_ticks));
+
+ _cairo_stats_compute (&stats, paint, i+1);
+ fprintf (perf->summary,
+ " %#9.3f", _cairo_time_to_s (stats.median_ticks));
+
+ _cairo_stats_compute (&stats, mask, i+1);
+ fprintf (perf->summary,
+ " %#9.3f", _cairo_time_to_s (stats.median_ticks));
+
+ _cairo_stats_compute (&stats, fill, i+1);
+ fprintf (perf->summary,
+ " %#9.3f", _cairo_time_to_s (stats.median_ticks));
+
+ _cairo_stats_compute (&stats, stroke, i+1);
+ fprintf (perf->summary,
+ " %#9.3f", _cairo_time_to_s (stats.median_ticks));
+
+ _cairo_stats_compute (&stats, glyphs, i+1);
+ fprintf (perf->summary,
+ " %#9.3f", _cairo_time_to_s (stats.median_ticks));
+
+ fprintf (perf->summary,
+ " %5d", i+1);
+ } else {
+ fprintf (perf->summary,
+ "%#8.3f %#8.3f %#6.2f%% %4d/%d",
+ _cairo_time_to_s (stats.min_ticks),
+ _cairo_time_to_s (stats.median_ticks),
+ stats.std_dev * 100.0,
+ stats.iterations, i+1);
+ }
+ fflush (perf->summary);
+ }
+ }
+ user_interrupt = 0;
+
+ if (perf->summary) {
+ _cairo_stats_compute (&stats, times, i);
+ if (perf->summary_continuous) {
+ fprintf (perf->summary,
+ "\r[%3d] %8s %28s ",
+ perf->test_number,
+ perf->target->name,
+ name);
+ }
+ if (perf->observe) {
+ fprintf (perf->summary,
+ " %#9.3f", _cairo_time_to_s (stats.median_ticks));
+
+ _cairo_stats_compute (&stats, paint, i);
+ fprintf (perf->summary,
+ " %#9.3f", _cairo_time_to_s (stats.median_ticks));
+
+ _cairo_stats_compute (&stats, mask, i);
+ fprintf (perf->summary,
+ " %#9.3f", _cairo_time_to_s (stats.median_ticks));
+
+ _cairo_stats_compute (&stats, fill, i);
+ fprintf (perf->summary,
+ " %#9.3f", _cairo_time_to_s (stats.median_ticks));
+
+ _cairo_stats_compute (&stats, stroke, i);
+ fprintf (perf->summary,
+ " %#9.3f", _cairo_time_to_s (stats.median_ticks));
+
+ _cairo_stats_compute (&stats, glyphs, i);
+ fprintf (perf->summary,
+ " %#9.3f", _cairo_time_to_s (stats.median_ticks));
+
+ fprintf (perf->summary,
+ " %5d\n", i);
+ } else {
+ fprintf (perf->summary,
+ "%#8.3f %#8.3f %#6.2f%% %4d/%d\n",
+ _cairo_time_to_s (stats.min_ticks),
+ _cairo_time_to_s (stats.median_ticks),
+ stats.std_dev * 100.0,
+ stats.iterations, i);
+ }
+ fflush (perf->summary);
+ }
+
+out:
+ if (perf->raw) {
+ printf ("\n");
+ fflush (stdout);
+ }
+
+ perf->test_number++;
+ free (trace_cpy);
+}
+
+static void
+warn_no_traces (const char *message,
+ const char *trace_dir)
+{
+ fprintf (stderr,
+"Error: %s '%s'.\n"
+"Have you cloned the cairo-traces repository and uncompressed the traces?\n"
+" git clone git://anongit.freedesktop.org/cairo-traces\n"
+" cd cairo-traces && make\n"
+"Or set the env.var CAIRO_TRACE_DIR to point to your traces?\n",
+ message, trace_dir);
+}
+
+static int
+cairo_perf_trace_dir (cairo_perf_t *perf,
+ const cairo_boilerplate_target_t *target,
+ const char *dirname)
+{
+ DIR *dir;
+ struct dirent *de;
+ int num_traces = 0;
+ cairo_bool_t force;
+ cairo_bool_t is_explicit;
+
+ dir = opendir (dirname);
+ if (dir == NULL)
+ return 0;
+
+ force = FALSE;
+ if (cairo_perf_can_run (perf, dirname, &is_explicit))
+ force = is_explicit;
+
+ while ((de = readdir (dir)) != NULL) {
+ char *trace;
+ struct stat st;
+
+ if (de->d_name[0] == '.')
+ continue;
+
+ xasprintf (&trace, "%s/%s", dirname, de->d_name);
+ if (stat (trace, &st) != 0)
+ goto next;
+
+ if (S_ISDIR(st.st_mode)) {
+ num_traces += cairo_perf_trace_dir (perf, target, trace);
+ } else {
+ const char *dot;
+
+ dot = strrchr (de->d_name, '.');
+ if (dot == NULL)
+ goto next;
+ if (strcmp (dot, ".trace"))
+ goto next;
+
+ num_traces++;
+ if (!force && ! cairo_perf_can_run (perf, de->d_name, NULL))
+ goto next;
+
+ cairo_perf_trace (perf, target, trace);
+ }
+next:
+ free (trace);
+
+ }
+ closedir (dir);
+
+ return num_traces;
+}
+
+int
+main (int argc,
+ char *argv[])
+{
+ cairo_perf_t perf;
+ const char *trace_dir = "cairo-traces:/usr/src/cairo-traces:/usr/share/cairo-traces";
+ unsigned int n;
+ int i;
+
+ parse_options (&perf, argc, argv);
+
+ signal (SIGINT, interrupt);
+
+ if (getenv ("CAIRO_TRACE_DIR") != NULL)
+ trace_dir = getenv ("CAIRO_TRACE_DIR");
+
+ perf.targets = cairo_boilerplate_get_targets (&perf.num_targets, NULL);
+ perf.times = xmalloc (6 * perf.iterations * sizeof (cairo_time_t));
+
+ /* do we have a list of filenames? */
+ perf.exact_names = have_trace_filenames (&perf);
+
+ for (i = 0; i < perf.num_targets; i++) {
+ const cairo_boilerplate_target_t *target = perf.targets[i];
+
+ if (! perf.list_only && ! target->is_measurable)
+ continue;
+
+ perf.target = target;
+ perf.test_number = 0;
+ perf.has_described_backend = FALSE;
+
+ if (perf.exact_names) {
+ for (n = 0; n < perf.num_names; n++) {
+ struct stat st;
+
+ if (stat (perf.names[n], &st) == 0) {
+ if (S_ISDIR (st.st_mode)) {
+ cairo_perf_trace_dir (&perf, target, perf.names[n]);
+ } else
+ cairo_perf_trace (&perf, target, perf.names[n]);
+ }
+ }
+ } else {
+ int num_traces = 0;
+ const char *dir;
+
+ dir = trace_dir;
+ do {
+ char buf[1024];
+ const char *end = strchr (dir, ':');
+ if (end != NULL) {
+ memcpy (buf, dir, end-dir);
+ buf[end-dir] = '\0';
+ end++;
+
+ dir = buf;
+ }
+
+ num_traces += cairo_perf_trace_dir (&perf, target, dir);
+ dir = end;
+ } while (dir != NULL);
+
+ if (num_traces == 0) {
+ warn_no_traces ("Found no traces in", trace_dir);
+ return 1;
+ }
+ }
+
+ if (perf.list_only)
+ break;
+ }
+
+ cairo_perf_fini (&perf);
+
+ return 0;
+}
diff --git a/perf/cairo-perf.c b/perf/cairo-perf.c
new file mode 100644
index 000000000..18db0c544
--- /dev/null
+++ b/perf/cairo-perf.c
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2007 Netlabs
+ * Copyright (c) 2006 Mozilla Corporation
+ * Copyright (c) 2006 Red Hat, Inc.
+ * Copyright (c) 2011 Andrea Canciani
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * the authors not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. The authors make no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Peter Weilbacher <mozilla@weilbacher.org>
+ * Vladimir Vukicevic <vladimir@pobox.com> (win32/linux code)
+ * Carl Worth <cworth@cworth.org> (win32/linux code)
+ * Andrea Canciani <ranma42@gmail.com>
+ */
+
+#include "cairo-perf.h"
+#include "../src/cairo-time-private.h"
+
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#if defined(__OS2__)
+#define INCL_BASE
+#include <os2.h>
+#elif defined(_WIN32)
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#elif defined(_POSIX_PRIORITY_SCHEDULING)
+#include <sched.h>
+#endif
+
+
+/* timers */
+static cairo_time_t timer;
+static cairo_perf_timer_synchronize_t cairo_perf_timer_synchronize = NULL;
+static void *cairo_perf_timer_synchronize_closure = NULL;
+
+void
+cairo_perf_timer_set_synchronize (cairo_perf_timer_synchronize_t synchronize,
+ void *closure)
+{
+ cairo_perf_timer_synchronize = synchronize;
+ cairo_perf_timer_synchronize_closure = closure;
+}
+
+void
+cairo_perf_timer_start (void)
+{
+ timer = _cairo_time_get ();
+}
+
+void
+cairo_perf_timer_stop (void)
+{
+ if (cairo_perf_timer_synchronize)
+ cairo_perf_timer_synchronize (cairo_perf_timer_synchronize_closure);
+
+ timer = _cairo_time_get_delta (timer);
+}
+
+cairo_time_t
+cairo_perf_timer_elapsed (void)
+{
+ return timer;
+}
+
+void
+cairo_perf_yield (void)
+{
+ /* try to deactivate this thread until the scheduler calls it again */
+
+#if defined(__OS2__)
+ DosSleep (0);
+#elif defined(_WIN32)
+ SleepEx(0, TRUE);
+#elif defined(_POSIX_PRIORITY_SCHEDULING)
+ sched_yield ();
+#else
+ sleep (0);
+#endif
+}
diff --git a/perf/cairo-perf.h b/perf/cairo-perf.h
new file mode 100644
index 000000000..eb53d13c2
--- /dev/null
+++ b/perf/cairo-perf.h
@@ -0,0 +1,250 @@
+/*
+ * Copyright © 2006 Mozilla Corporation
+ * Copyright © 2006 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * the authors not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. The authors make no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Vladimir Vukicevic <vladimir@pobox.com>
+ * Carl Worth <cworth@cworth.org>
+ */
+
+#ifndef _CAIRO_PERF_H_
+#define _CAIRO_PERF_H_
+
+#include "cairo-boilerplate.h"
+#include "../src/cairo-time-private.h"
+#include <stdio.h>
+
+typedef struct _cairo_stats {
+ cairo_time_t min_ticks;
+ cairo_time_t median_ticks;
+ double ticks_per_ms;
+ double std_dev;
+ int iterations;
+ cairo_time_t *values;
+} cairo_stats_t;
+
+typedef struct _cairo_histogram {
+ int width, height, max_count;
+ int num_columns, num_rows;
+ cairo_time_t min_value, max_value;
+ int *columns;
+} cairo_histogram_t;
+
+
+/* timers */
+
+void
+cairo_perf_timer_start (void);
+
+void
+cairo_perf_timer_stop (void);
+
+typedef void
+(*cairo_perf_timer_synchronize_t) (void *closure);
+
+void
+cairo_perf_timer_set_synchronize (cairo_perf_timer_synchronize_t synchronize,
+ void *closure);
+
+cairo_time_t
+cairo_perf_timer_elapsed (void);
+
+/* yield */
+
+void
+cairo_perf_yield (void);
+
+/* running a test case */
+typedef struct _cairo_perf {
+ FILE *summary;
+ cairo_bool_t summary_continuous;
+
+ /* Options from command-line */
+ unsigned int iterations;
+ cairo_bool_t exact_iterations;
+ cairo_bool_t raw;
+ cairo_bool_t list_only;
+ cairo_bool_t observe;
+ char **names;
+ unsigned int num_names;
+ char **exclude_names;
+ unsigned int num_exclude_names;
+ cairo_bool_t exact_names;
+
+ double ms_per_iteration;
+ cairo_bool_t fast_and_sloppy;
+
+ unsigned int tile_size;
+
+ /* Stuff used internally */
+ cairo_time_t *times;
+ const cairo_boilerplate_target_t **targets;
+ int num_targets;
+ const cairo_boilerplate_target_t *target;
+ cairo_bool_t has_described_backend;
+ unsigned int test_number;
+ unsigned int size;
+ cairo_t *cr;
+} cairo_perf_t;
+
+typedef cairo_time_t
+(*cairo_perf_func_t) (cairo_t *cr, int width, int height, int loops);
+
+typedef double
+(*cairo_count_func_t) (cairo_t *cr, int width, int height);
+
+cairo_bool_t
+cairo_perf_can_run (cairo_perf_t *perf,
+ const char *name,
+ cairo_bool_t *is_explicit);
+
+void
+cairo_perf_run (cairo_perf_t *perf,
+ const char *name,
+ cairo_perf_func_t perf_func,
+ cairo_count_func_t count_func);
+
+void
+cairo_perf_cover_sources_and_operators (cairo_perf_t *perf,
+ const char *name,
+ cairo_perf_func_t perf_func,
+ cairo_count_func_t count_func);
+
+/* reporter convenience routines */
+
+typedef struct _test_report {
+ int id;
+ int fileno;
+ const char *configuration;
+ char *backend;
+ char *content;
+ char *name;
+ int size;
+
+ /* The samples only exists for "raw" reports */
+ cairo_time_t *samples;
+ unsigned int samples_size;
+ unsigned int samples_count;
+
+ /* The stats are either read directly or computed from samples.
+ * If the stats have not yet been computed from samples, then
+ * iterations will be 0. */
+ cairo_stats_t stats;
+} test_report_t;
+
+typedef struct _test_diff {
+ test_report_t **tests;
+ int num_tests;
+ double min;
+ double max;
+ double change;
+} test_diff_t;
+
+typedef struct _cairo_perf_report {
+ char *configuration;
+ const char *name;
+ int fileno;
+ test_report_t *tests;
+ int tests_size;
+ int tests_count;
+} cairo_perf_report_t;
+
+typedef enum {
+ TEST_REPORT_STATUS_SUCCESS,
+ TEST_REPORT_STATUS_COMMENT,
+ TEST_REPORT_STATUS_ERROR
+} test_report_status_t;
+
+void
+cairo_perf_report_load (cairo_perf_report_t *report,
+ const char *filename, int id,
+ int (*cmp) (const void *, const void *));
+
+void
+cairo_perf_report_sort_and_compute_stats (cairo_perf_report_t *report,
+ int (*cmp) (const void *, const void *));
+
+int
+test_report_cmp_backend_then_name (const void *a,
+ const void *b);
+
+int
+test_report_cmp_name (const void *a,
+ const void *b);
+
+#define CAIRO_PERF_ENABLED_DECL(func) cairo_bool_t (func ## _enabled) (cairo_perf_t *perf)
+#define CAIRO_PERF_RUN_DECL(func) void (func) (cairo_perf_t *perf, cairo_t *cr, int width, int height)
+
+#define CAIRO_PERF_DECL(func) CAIRO_PERF_RUN_DECL(func); CAIRO_PERF_ENABLED_DECL(func)
+
+#ifndef MIN
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
+#endif
+
+#ifndef MAX
+#define MAX(a, b) ((a) > (b) ? (a) : (b))
+#endif
+
+CAIRO_PERF_DECL (fill);
+CAIRO_PERF_DECL (paint);
+CAIRO_PERF_DECL (paint_with_alpha);
+CAIRO_PERF_DECL (mask);
+CAIRO_PERF_DECL (stroke);
+CAIRO_PERF_DECL (subimage_copy);
+CAIRO_PERF_DECL (disjoint);
+CAIRO_PERF_DECL (hatching);
+CAIRO_PERF_DECL (tessellate);
+CAIRO_PERF_DECL (text);
+CAIRO_PERF_DECL (glyphs);
+CAIRO_PERF_DECL (hash_table);
+CAIRO_PERF_DECL (pattern_create_radial);
+CAIRO_PERF_DECL (zrusin);
+CAIRO_PERF_DECL (world_map);
+CAIRO_PERF_DECL (box_outline);
+CAIRO_PERF_DECL (mosaic);
+CAIRO_PERF_DECL (long_lines);
+CAIRO_PERF_DECL (unaligned_clip);
+CAIRO_PERF_DECL (rectangles);
+CAIRO_PERF_DECL (rounded_rectangles);
+CAIRO_PERF_DECL (long_dashed_lines);
+CAIRO_PERF_DECL (composite_checker);
+CAIRO_PERF_DECL (twin);
+CAIRO_PERF_DECL (dragon);
+CAIRO_PERF_DECL (pythagoras_tree);
+CAIRO_PERF_DECL (intersections);
+CAIRO_PERF_DECL (spiral);
+CAIRO_PERF_DECL (wave);
+CAIRO_PERF_DECL (many_strokes);
+CAIRO_PERF_DECL (wide_strokes);
+CAIRO_PERF_DECL (many_fills);
+CAIRO_PERF_DECL (wide_fills);
+CAIRO_PERF_DECL (many_curves);
+CAIRO_PERF_DECL (curve);
+CAIRO_PERF_DECL (a1_curve);
+CAIRO_PERF_DECL (line);
+CAIRO_PERF_DECL (a1_line);
+CAIRO_PERF_DECL (pixel);
+CAIRO_PERF_DECL (a1_pixel);
+CAIRO_PERF_DECL (sierpinski);
+CAIRO_PERF_DECL (fill_clip);
+CAIRO_PERF_DECL (tiger);
+
+#endif
diff --git a/perf/cairo-stats.c b/perf/cairo-stats.c
new file mode 100644
index 000000000..aee9fe8b5
--- /dev/null
+++ b/perf/cairo-stats.c
@@ -0,0 +1,182 @@
+/*
+ * Copyright © 2006 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * the authors not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. The authors make no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Carl Worth <cworth@cworth.org>
+ */
+
+#include "cairo-stats.h"
+
+#include <assert.h>
+
+void
+_cairo_stats_compute (cairo_stats_t *stats,
+ cairo_time_t *values,
+ int num_values)
+{
+ cairo_time_t sum, mean, q1, q3, iqr;
+ cairo_time_t outlier_min, outlier_max;
+ int i, min_valid, num_valid;
+ double s;
+
+ assert (num_values > 0);
+
+ if (num_values == 1) {
+ stats->min_ticks = stats->median_ticks = values[0];
+ stats->std_dev = 0;
+ stats->iterations = 1;
+ stats->values = values;
+ return;
+ }
+
+ /* First, identify any outliers, using the definition of "mild
+ * outliers" from:
+ *
+ * http://en.wikipedia.org/wiki/Outliers
+ *
+ * Which is that outliers are any values less than Q1 - 1.5 * IQR
+ * or greater than Q3 + 1.5 * IQR where Q1 and Q3 are the first
+ * and third quartiles and IQR is the inter-quartile range (Q3 -
+ * Q1).
+ */
+ num_valid = num_values;
+ do {
+ num_values = num_valid;
+ qsort (values, num_values, sizeof (cairo_time_t), _cairo_time_cmp);
+
+ q1 = values[1*num_values/4];
+ q3 = values[3*num_values/4];
+
+ /* XXX assumes we have native uint64_t */
+ iqr = q3 - q1;
+ outlier_min = q1 - 3 * iqr / 2;
+ outlier_max = q3 + 3 * iqr / 2;
+
+ for (i = 0; i < num_values && values[i] < outlier_min; i++)
+ ;
+ min_valid = i;
+
+ for (i = 0; i < num_values && values[i] <= outlier_max; i++)
+ ;
+ num_valid = i - min_valid;
+ assert(num_valid);
+ values += min_valid;
+ } while (num_valid != num_values);
+
+ stats->values = values;
+ stats->iterations = num_valid;
+ stats->min_ticks = values[0];
+ stats->median_ticks = values[num_valid / 2];
+
+ sum = 0;
+ for (i = 0; i < num_valid; i++)
+ sum = _cairo_time_add (sum, values[i]);
+ mean = sum / num_valid;
+
+ /* Let's use a normalized std. deviation for easier comparison. */
+ s = 0;
+ for (i = 0; i < num_valid; i++) {
+ double delta = (values[i] - mean) / (double)mean;
+ s += delta * delta;
+ }
+ stats->std_dev = sqrt(s / num_valid);
+}
+
+cairo_bool_t
+_cairo_histogram_init (cairo_histogram_t *h,
+ int width, int height)
+{
+ h->width = width;
+ h->height = height;
+ if (h->width < 2 || h->height < 1)
+ return FALSE;
+
+ h->num_columns = width - 2;
+ h->num_rows = height - 1;
+ h->columns = malloc (sizeof(int)*h->num_columns);
+ return h->columns != NULL;
+}
+
+cairo_bool_t
+_cairo_histogram_compute (cairo_histogram_t *h,
+ const cairo_time_t *values,
+ int num_values)
+{
+ cairo_time_t delta;
+ int i;
+
+ if (num_values == 0)
+ return FALSE;
+
+ h->min_value = values[0];
+ h->max_value = values[0];
+
+ for (i = 1; i < num_values; i++) {
+ if (values[i] < h->min_value)
+ h->min_value = values[i];
+ if (values[i] > h->max_value)
+ h->max_value = values[i];
+ }
+
+ delta = h->max_value - h->min_value;
+ if (delta == 0)
+ return FALSE;
+
+ memset(h->columns, 0, sizeof(int)*h->num_columns);
+ h->max_count = 0;
+
+ for (i = 0; i < num_values; i++) {
+ int count = h->columns[(values[i] - h->min_value) * (h->num_columns - 1) / delta]++;
+ if (count > h->max_count)
+ h->max_count = count;
+ }
+
+ return TRUE;
+}
+
+void
+_cairo_histogram_printf (cairo_histogram_t *h,
+ FILE *file)
+{
+ int x, y, num_rows;
+
+ num_rows = h->num_rows;
+ if (h->max_count < num_rows)
+ num_rows = h->max_count;
+ for (y = 0; y < num_rows; y++) {
+ int min_count = ((num_rows - y - 1) * h->max_count) / num_rows + h->max_count / (2*num_rows);
+ fprintf (file, "|");
+ for (x = 0; x < h->num_columns; x++)
+ fprintf (file, "%c", h->columns[x] > min_count ? 'x' : ' ');
+ fprintf (file, "|\n");
+ }
+
+ fprintf(file, ".");
+ for (x = 0; x < h->num_columns; x++)
+ fprintf (file, "-");
+ fprintf (file, ".\n");
+}
+
+void
+_cairo_histogram_fini (cairo_histogram_t *h)
+{
+ free(h->columns);
+}
diff --git a/perf/cairo-stats.h b/perf/cairo-stats.h
new file mode 100644
index 000000000..2b32d67ae
--- /dev/null
+++ b/perf/cairo-stats.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright © 2006 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * the authors not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. The authors make no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Carl Worth <cworth@cworth.org>
+ */
+
+#ifndef _CAIRO_STATS_H_
+#define _CAIRO_STATS_H_
+
+#include "cairo-perf.h"
+
+void
+_cairo_stats_compute (cairo_stats_t *stats,
+ cairo_time_t *values,
+ int num_values);
+
+cairo_bool_t
+_cairo_histogram_init (cairo_histogram_t *h,
+ int width, int height);
+
+cairo_bool_t
+_cairo_histogram_compute (cairo_histogram_t *h,
+ const cairo_time_t *values,
+ int num_values);
+
+void
+_cairo_histogram_printf (cairo_histogram_t *h,
+ FILE *file);
+
+void
+_cairo_histogram_fini (cairo_histogram_t *h);
+
+#endif /* _CAIRO_STATS_H_ */
diff --git a/perf/dirent-win32.h b/perf/dirent-win32.h
new file mode 100644
index 000000000..0f2ed05e5
--- /dev/null
+++ b/perf/dirent-win32.h
@@ -0,0 +1,102 @@
+/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */
+/*
+ * Copyright 2011 Andrea Canciani
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * the authors not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. The authors make no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Andrea Canciani <ranma42@gmail.com>
+ */
+
+#include "cairo-compiler-private.h"
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+#define stat _stat
+
+#define S_ISDIR(s) ((s) & _S_IFDIR)
+
+struct dirent {
+ ino_t d_ino;
+ char d_name[FILENAME_MAX + 1];
+};
+
+typedef struct _DIR {
+ HANDLE handle;
+ cairo_bool_t has_next;
+ WIN32_FIND_DATA data;
+ struct dirent de;
+} DIR;
+
+static DIR *
+opendir(const char *dirname)
+{
+ DIR *dirp;
+
+ dirp = malloc (sizeof (*dirp));
+ if (unlikely (dirp == NULL))
+ return NULL;
+
+ dirp->handle = FindFirstFile(dirname, &dirp->data);
+
+ if (unlikely (dirp->handle == INVALID_HANDLE_VALUE)) {
+ free (dirp);
+ return NULL;
+ }
+
+ memcpy (dirp->de.d_name, dirp->data.cFileName,
+ sizeof (dirp->data.cFileName));
+ dirp->de.d_name[FILENAME_MAX] = '\0';
+
+ dirp->has_next = TRUE;
+
+ return dirp;
+}
+
+static int
+closedir(DIR *dirp)
+{
+ int ret;
+
+ ret = ! FindClose (dirp->handle);
+
+ free (dirp);
+
+ /* TODO: set errno */
+
+ return ret;
+}
+
+static struct dirent *
+readdir(DIR *dirp)
+{
+ if (! dirp->has_next)
+ return NULL;
+
+ /* COMPILE_TIME_ASSERT (FILENAME_MAX == sizeof (dirp->data.cFileName)); */
+
+ memcpy (dirp->de.d_name, dirp->data.cFileName,
+ sizeof (dirp->data.cFileName));
+ dirp->de.d_name[FILENAME_MAX] = '\0';
+
+ dirp->has_next = FindNextFile (dirp->handle, &dirp->data);
+
+ return &dirp->de;
+}
diff --git a/perf/make-html.py b/perf/make-html.py
new file mode 100755
index 000000000..0b4533581
--- /dev/null
+++ b/perf/make-html.py
@@ -0,0 +1,88 @@
+#!/usr/bin/python
+
+from string import strip
+from sys import stdin
+
+targets = {}
+smilies = {'slowdown': '&#9785;' , 'speedup': '&#9786;'}
+
+for line in stdin:
+ line = map(strip, filter(None, line.split(' ')))
+
+ if 9 == len(line):
+ target, name = line[0:2]
+ factor, dir = line[-2:]
+
+ name = name.split('-')
+ name, size = '-'.join(name[:-1]), name[-1]
+
+ target_tests = targets.get(target, {})
+ name_tests = target_tests.get(name, {})
+
+ name_tests[int(size)] = (factor, dir)
+ target_tests[name] = name_tests
+ targets[target] = target_tests
+
+print '''\
+<html><head>
+<title>Performance Changes</title>
+<style type="text/css">/*<![CDATA[*/
+ body { background: white; color: black; }
+ table { border-collapse: collapse; }
+
+ th, td { border: 1px solid silver; padding: 0.2em; }
+ td { text-align: center; }
+ th:first-child { text-align: left; }
+ th { background: #eee; }
+
+ /* those colors also should work for color blinds */
+ td.slowdown { background: #f93; }
+ td.speedup { background: #6f9; }
+/*]]>*/</style>
+</head><body>
+<h1>Performance Changes</h1>'''
+
+targets = targets.items()
+targets.sort(lambda a, b: cmp(a[0], b[0]))
+
+for target, names in targets:
+ sizes = {}
+
+ for tests in names.values():
+ for size in tests.keys():
+ sizes[size] = True
+
+ sizes = sizes.keys()
+ sizes.sort()
+
+ names = names.items()
+ names.sort(lambda a, b: cmp(a[0], b[0]))
+
+ print '<h2><a name="%s">%s</a></h2>' % (target, target)
+ print '<table><thead><tr><th>&nbsp;</th>'
+
+ for size in sizes:
+ print '<th>%s</th>' % size
+
+ print '</tr></thead><tbody>'
+
+ for name, tests in names:
+ print '<tr><th>%s</th>' % name
+
+ for size in sizes:
+ result = tests.get(size)
+
+ if result:
+ factor, dir = result
+ print '<td class="%s">%s %s</td>' % (
+ dir, factor, smilies[dir])
+
+ else:
+ print '<td>&nbsp;</td>'
+
+ print '</tr>'
+
+
+ print '</tbody></table>'
+
+print '</body></html>'
diff --git a/perf/micro/Makefile.am b/perf/micro/Makefile.am
new file mode 100644
index 000000000..3edbf531c
--- /dev/null
+++ b/perf/micro/Makefile.am
@@ -0,0 +1,16 @@
+include $(top_srcdir)/build/Makefile.am.common
+
+include $(top_srcdir)/perf/micro/Makefile.sources
+
+noinst_LTLIBRARIES = libcairo-perf-micro.la
+libcairo_perf_micro_la_SOURCES = \
+ $(libcairo_perf_micro_sources) \
+ $(libcairo_perf_micro_headers)
+
+AM_CPPFLAGS = \
+ -I$(srcdir) \
+ -I$(top_srcdir)/boilerplate \
+ -I$(top_srcdir)/src \
+ -I$(top_srcdir)/perf \
+ -I$(top_builddir)/src \
+ $(CAIRO_CFLAGS)
diff --git a/perf/micro/Makefile.sources b/perf/micro/Makefile.sources
new file mode 100644
index 000000000..19ead179d
--- /dev/null
+++ b/perf/micro/Makefile.sources
@@ -0,0 +1,51 @@
+libcairo_perf_micro_sources = \
+ cairo-perf-cover.c \
+ box-outline.c \
+ composite-checker.c \
+ disjoint.c \
+ fill.c \
+ hatching.c \
+ hash-table.c \
+ line.c \
+ a1-line.c \
+ long-lines.c \
+ mosaic.c \
+ paint.c \
+ paint-with-alpha.c \
+ mask.c \
+ pattern_create_radial.c \
+ rectangles.c \
+ rounded-rectangles.c \
+ stroke.c \
+ subimage_copy.c \
+ tessellate.c \
+ text.c \
+ tiger.c \
+ glyphs.c \
+ twin.c \
+ unaligned-clip.c \
+ wave.c \
+ world-map.c \
+ zrusin.c \
+ long-dashed-lines.c \
+ dragon.c \
+ pythagoras-tree.c \
+ intersections.c \
+ many-strokes.c \
+ wide-strokes.c \
+ many-fills.c \
+ wide-fills.c \
+ many-curves.c \
+ curve.c \
+ a1-curve.c \
+ spiral.c \
+ pixel.c \
+ sierpinski.c \
+ fill-clip.c \
+ $(NULL)
+
+libcairo_perf_micro_headers = \
+ mosaic.h \
+ world-map.h \
+ zrusin-another.h \
+ $(NULL)
diff --git a/perf/micro/Makefile.win32 b/perf/micro/Makefile.win32
new file mode 100644
index 000000000..f41f781d7
--- /dev/null
+++ b/perf/micro/Makefile.win32
@@ -0,0 +1,12 @@
+top_srcdir = ../..
+include $(top_srcdir)/build/Makefile.win32.common
+include $(top_srcdir)/perf/micro/Makefile.sources
+
+CFLAGS += -I$(top_srcdir)/perf -I$(top_srcdir)/boilerplate/
+
+OBJECTS = $(patsubst %.c, $(CFG)/%-static.obj, $(libcairo_perf_micro_sources))
+
+all: inform $(CFG)/libcairo-perf-micro.lib
+
+$(CFG)/libcairo-perf-micro.lib: $(OBJECTS)
+ @$(AR) $(CAIRO_ARFLAGS) -OUT:$@ $(OBJECTS)
diff --git a/perf/micro/a1-curve.c b/perf/micro/a1-curve.c
new file mode 100644
index 000000000..594c46d5c
--- /dev/null
+++ b/perf/micro/a1-curve.c
@@ -0,0 +1,112 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-perf.h"
+
+static uint32_t state;
+
+static double
+uniform_random (double minval, double maxval)
+{
+ static uint32_t const poly = 0x9a795537U;
+ uint32_t n = 32;
+ while (n-->0)
+ state = 2*state < state ? (2*state ^ poly) : 2*state;
+ return minval + state * (maxval - minval) / 4294967296.0;
+}
+
+static cairo_time_t
+do_curve_stroke (cairo_t *cr, int width, int height, int loops)
+{
+ state = 0xc0ffee;
+ cairo_set_line_width (cr, 2.);
+ cairo_perf_timer_start ();
+
+ while (loops--) {
+ double x1 = uniform_random (0, width);
+ double x2 = uniform_random (0, width);
+ double x3 = uniform_random (0, width);
+ double y1 = uniform_random (0, height);
+ double y2 = uniform_random (0, height);
+ double y3 = uniform_random (0, height);
+ cairo_move_to (cr, uniform_random (0, width), uniform_random (0, height));
+ cairo_curve_to (cr, x1, y1, x2, y2, x3, y3);
+ cairo_stroke(cr);
+ }
+
+ cairo_perf_timer_stop ();
+
+ return cairo_perf_timer_elapsed ();
+}
+
+static cairo_time_t
+do_curve_fill (cairo_t *cr, int width, int height, int loops)
+{
+ state = 0xc0ffee;
+ cairo_perf_timer_start ();
+
+ while (loops--) {
+ double x0 = uniform_random (0, width);
+ double x1 = uniform_random (0, width);
+ double x2 = uniform_random (0, width);
+ double x3 = uniform_random (0, width);
+ double xm = uniform_random (0, width);
+ double xn = uniform_random (0, width);
+ double y0 = uniform_random (0, height);
+ double y1 = uniform_random (0, height);
+ double y2 = uniform_random (0, height);
+ double y3 = uniform_random (0, height);
+ double ym = uniform_random (0, height);
+ double yn = uniform_random (0, height);
+
+ cairo_move_to (cr, xm, ym);
+ cairo_curve_to (cr, x1, y1, x2, y2, xn, yn);
+ cairo_curve_to (cr, x3, y3, x0, y0, xm, ym);
+ cairo_close_path (cr);
+
+ cairo_fill(cr);
+ }
+
+ cairo_perf_timer_stop ();
+
+ return cairo_perf_timer_elapsed ();
+}
+
+cairo_bool_t
+a1_curve_enabled (cairo_perf_t *perf)
+{
+ return cairo_perf_can_run (perf, "a1-curve", NULL);
+}
+
+void
+a1_curve (cairo_perf_t *perf, cairo_t *cr, int width, int height)
+{
+ cairo_set_source_rgb (cr, 1., 1., 1.);
+ cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE);
+
+ cairo_perf_run (perf, "a1-curve-stroked", do_curve_stroke, NULL);
+ cairo_perf_run (perf, "a1-curve-filled", do_curve_fill, NULL);
+}
diff --git a/perf/micro/a1-line.c b/perf/micro/a1-line.c
new file mode 100644
index 000000000..ae8660212
--- /dev/null
+++ b/perf/micro/a1-line.c
@@ -0,0 +1,223 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-perf.h"
+
+static cairo_time_t
+horizontal (cairo_t *cr, int width, int height, int loops)
+{
+ double h = height/2 + .5;
+
+ cairo_move_to (cr, 0, h);
+ cairo_line_to (cr, width, h);
+
+ cairo_perf_timer_start ();
+
+ while (loops--)
+ cairo_stroke_preserve (cr);
+
+ cairo_perf_timer_stop ();
+
+ cairo_new_path (cr);
+
+ return cairo_perf_timer_elapsed ();
+}
+
+static cairo_time_t
+horizontal_hair (cairo_t *cr, int width, int height, int loops)
+{
+ cairo_set_line_width (cr, 1.);
+ return horizontal (cr, width, height, loops);
+}
+
+static cairo_time_t
+horizontal_wide (cairo_t *cr, int width, int height, int loops)
+{
+ cairo_set_line_width (cr, 5.);
+ return horizontal (cr, width, height, loops);
+}
+
+static cairo_time_t
+nearly_horizontal (cairo_t *cr, int width, int height, int loops)
+{
+ double h = height/2;
+
+ cairo_move_to (cr, 0, h);
+ cairo_line_to (cr, width, h+1);
+
+ cairo_perf_timer_start ();
+
+ while (loops--)
+ cairo_stroke_preserve (cr);
+
+ cairo_perf_timer_stop ();
+
+ cairo_new_path (cr);
+
+ return cairo_perf_timer_elapsed ();
+}
+
+static cairo_time_t
+nearly_horizontal_hair (cairo_t *cr, int width, int height, int loops)
+{
+ cairo_set_line_width (cr, 1.);
+ return nearly_horizontal (cr, width, height, loops);
+}
+
+static cairo_time_t
+nearly_horizontal_wide (cairo_t *cr, int width, int height, int loops)
+{
+ cairo_set_line_width (cr, 5.);
+ return nearly_horizontal (cr, width, height, loops);
+}
+
+
+static cairo_time_t
+vertical (cairo_t *cr, int width, int height, int loops)
+{
+ double w = width/2 + .5;
+
+ cairo_move_to (cr, w, 0);
+ cairo_line_to (cr, w, height);
+
+ cairo_perf_timer_start ();
+
+ while (loops--)
+ cairo_stroke_preserve (cr);
+
+ cairo_perf_timer_stop ();
+
+ cairo_new_path (cr);
+
+ return cairo_perf_timer_elapsed ();
+}
+
+static cairo_time_t
+vertical_hair (cairo_t *cr, int width, int height, int loops)
+{
+ cairo_set_line_width (cr, 1.);
+ return vertical (cr, width, height, loops);
+}
+
+static cairo_time_t
+vertical_wide (cairo_t *cr, int width, int height, int loops)
+{
+ cairo_set_line_width (cr, 5.);
+ return vertical (cr, width, height, loops);
+}
+
+static cairo_time_t
+nearly_vertical (cairo_t *cr, int width, int height, int loops)
+{
+ double w = width/2;
+
+ cairo_move_to (cr, w, 0);
+ cairo_line_to (cr, w+1, height);
+
+ cairo_perf_timer_start ();
+
+ while (loops--)
+ cairo_stroke_preserve (cr);
+
+ cairo_perf_timer_stop ();
+
+ cairo_new_path (cr);
+
+ return cairo_perf_timer_elapsed ();
+}
+
+static cairo_time_t
+nearly_vertical_hair (cairo_t *cr, int width, int height, int loops)
+{
+ cairo_set_line_width (cr, 1.);
+ return nearly_vertical (cr, width, height, loops);
+}
+
+static cairo_time_t
+nearly_vertical_wide (cairo_t *cr, int width, int height, int loops)
+{
+ cairo_set_line_width (cr, 5.);
+ return nearly_vertical (cr, width, height, loops);
+}
+
+
+static cairo_time_t
+diagonal (cairo_t *cr, int width, int height, int loops)
+{
+ cairo_move_to (cr, 0, 0);
+ cairo_line_to (cr, width, height);
+
+ cairo_perf_timer_start ();
+
+ while (loops--)
+ cairo_stroke_preserve (cr);
+
+ cairo_perf_timer_stop ();
+
+ cairo_new_path (cr);
+
+ return cairo_perf_timer_elapsed ();
+}
+
+static cairo_time_t
+diagonal_hair (cairo_t *cr, int width, int height, int loops)
+{
+ cairo_set_line_width (cr, 1.);
+ return diagonal (cr, width, height, loops);
+}
+
+static cairo_time_t
+diagonal_wide (cairo_t *cr, int width, int height, int loops)
+{
+ cairo_set_line_width (cr, 5.);
+ return diagonal (cr, width, height, loops);
+}
+
+cairo_bool_t
+a1_line_enabled (cairo_perf_t *perf)
+{
+ return cairo_perf_can_run (perf, "a1-line", NULL);
+}
+
+void
+a1_line (cairo_perf_t *perf, cairo_t *cr, int width, int height)
+{
+ cairo_set_source_rgb (cr, 1., 1., 1.);
+ cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE);
+
+ cairo_perf_run (perf, "a1-line-hh", horizontal_hair, NULL);
+ cairo_perf_run (perf, "a1-line-hw", horizontal_wide, NULL);
+ cairo_perf_run (perf, "a1-line-nhh", nearly_horizontal_hair, NULL);
+ cairo_perf_run (perf, "a1-line-nhw", nearly_horizontal_wide, NULL);
+
+ cairo_perf_run (perf, "a1-line-vh", vertical_hair, NULL);
+ cairo_perf_run (perf, "a1-line-vw", vertical_wide, NULL);
+ cairo_perf_run (perf, "a1-line-nvh", nearly_vertical_hair, NULL);
+ cairo_perf_run (perf, "a1-line-nvw", nearly_vertical_wide, NULL);
+
+ cairo_perf_run (perf, "a1-line-dh", diagonal_hair, NULL);
+ cairo_perf_run (perf, "a1-line-dw", diagonal_wide, NULL);
+}
diff --git a/perf/micro/box-outline.c b/perf/micro/box-outline.c
new file mode 100644
index 000000000..1e654eb95
--- /dev/null
+++ b/perf/micro/box-outline.c
@@ -0,0 +1,215 @@
+/*
+ * Copyright © 2006 Red Hat, Inc.
+ *
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+#include "cairo-perf.h"
+
+/* This test case is designed to illustrate a performance bug that
+ * exists in cairo in which using cairo_stroke is much slower than
+ * cairo_fill to draw an identical figure, (and in particular a figure
+ * that is much more natural to draw with cairo_stroke). The figure is
+ * a 100x100 square outline 1-pixel wide, nicely pixel aligned.
+ *
+ * The performance bug should affect any path whose resulting contour
+ * consists only of pixel-aligned horizontal and vertical elements.
+ *
+ * Initial testing on on machine shows stroke as 5x slower than fill
+ * for the xlib backend and 16x slower for the image backend.
+ */
+
+static cairo_time_t
+box_outline_stroke (cairo_t *cr, int width, int height, int loops)
+{
+ cairo_set_source_rgb (cr, 0, 0, 1); /* blue */
+ cairo_paint (cr);
+
+ cairo_rectangle (cr,
+ 1.5, 1.5,
+ width - 3, height - 3);
+ cairo_set_line_width (cr, 1.0);
+ cairo_set_source_rgb (cr, 1, 0, 0); /* red */
+
+ cairo_perf_timer_start ();
+
+ while (loops--)
+ cairo_stroke_preserve (cr);
+
+ cairo_perf_timer_stop ();
+
+ cairo_new_path (cr);
+
+ return cairo_perf_timer_elapsed ();
+}
+
+static cairo_time_t
+box_outline_alpha_stroke (cairo_t *cr, int width, int height, int loops)
+{
+ cairo_set_source_rgb (cr, 0, 0, 1); /* blue */
+ cairo_paint (cr);
+
+ cairo_rectangle (cr,
+ 1.5, 1.5,
+ width - 3, height - 3);
+ cairo_set_line_width (cr, 1.0);
+ cairo_set_source_rgba (cr, 1, 0, 0, .5); /* red */
+
+ cairo_perf_timer_start ();
+
+ while (loops--)
+ cairo_stroke_preserve (cr);
+
+ cairo_perf_timer_stop ();
+
+ cairo_new_path (cr);
+
+ return cairo_perf_timer_elapsed ();
+}
+
+static cairo_time_t
+box_outline_aa_stroke (cairo_t *cr, int width, int height, int loops)
+{
+ cairo_set_source_rgb (cr, 0, 0, 1); /* blue */
+ cairo_paint (cr);
+
+ cairo_translate (cr, .5, .5);
+ cairo_rectangle (cr,
+ 1.5, 1.5,
+ width - 3, height - 3);
+ cairo_set_line_width (cr, 1.0);
+ cairo_set_source_rgb (cr, 1, 0, 0); /* red */
+
+ cairo_perf_timer_start ();
+
+ while (loops--)
+ cairo_stroke_preserve (cr);
+
+ cairo_perf_timer_stop ();
+
+ cairo_new_path (cr);
+
+ return cairo_perf_timer_elapsed ();
+}
+
+static cairo_time_t
+box_outline_fill (cairo_t *cr, int width, int height, int loops)
+{
+ cairo_set_source_rgb (cr, 0, 0, 1); /* blue */
+ cairo_paint (cr);
+
+ cairo_rectangle (cr,
+ 1.0, 1.0,
+ width - 2, height - 2);
+ cairo_rectangle (cr,
+ 2.0, 2.0,
+ width - 4, height - 4);
+ cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
+ cairo_set_source_rgb (cr, 0, 1, 0); /* green */
+
+ cairo_perf_timer_start ();
+
+ while (loops--)
+ cairo_fill_preserve (cr);
+
+ cairo_perf_timer_stop ();
+
+ cairo_new_path (cr);
+
+ return cairo_perf_timer_elapsed ();
+}
+
+static cairo_time_t
+box_outline_alpha_fill (cairo_t *cr, int width, int height, int loops)
+{
+ cairo_set_source_rgb (cr, 0, 0, 1); /* blue */
+ cairo_paint (cr);
+
+ cairo_rectangle (cr,
+ 1.0, 1.0,
+ width - 2, height - 2);
+ cairo_rectangle (cr,
+ 2.0, 2.0,
+ width - 4, height - 4);
+ cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
+ cairo_set_source_rgba (cr, 0, 1, 0, .5); /* green */
+
+ cairo_perf_timer_start ();
+
+ while (loops--)
+ cairo_fill_preserve (cr);
+
+ cairo_perf_timer_stop ();
+
+ cairo_new_path (cr);
+
+ return cairo_perf_timer_elapsed ();
+}
+
+static cairo_time_t
+box_outline_aa_fill (cairo_t *cr, int width, int height, int loops)
+{
+ cairo_set_source_rgb (cr, 0, 0, 1); /* blue */
+ cairo_paint (cr);
+
+ cairo_translate (cr, .5, .5);
+ cairo_rectangle (cr,
+ 1.0, 1.0,
+ width - 2, height - 2);
+ cairo_rectangle (cr,
+ 2.0, 2.0,
+ width - 4, height - 4);
+ cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
+ cairo_set_source_rgb (cr, 0, 1, 0); /* green */
+
+ cairo_perf_timer_start ();
+
+ while (loops--)
+ cairo_fill_preserve (cr);
+
+ cairo_perf_timer_stop ();
+
+ cairo_new_path (cr);
+
+ return cairo_perf_timer_elapsed ();
+}
+
+cairo_bool_t
+box_outline_enabled (cairo_perf_t *perf)
+{
+ return cairo_perf_can_run (perf, "box-outline", NULL);
+}
+
+void
+box_outline (cairo_perf_t *perf, cairo_t *cr, int width, int height)
+{
+ cairo_perf_run (perf, "box-outline-stroke", box_outline_stroke, NULL);
+ cairo_perf_run (perf, "box-outline-fill", box_outline_fill, NULL);
+
+ cairo_perf_run (perf, "box-outline-alpha-stroke", box_outline_alpha_stroke, NULL);
+ cairo_perf_run (perf, "box-outline-alpha-fill", box_outline_alpha_fill, NULL);
+
+ cairo_perf_run (perf, "box-outline-aa-stroke", box_outline_aa_stroke, NULL);
+ cairo_perf_run (perf, "box-outline-aa-fill", box_outline_aa_fill, NULL);
+}
diff --git a/perf/micro/cairo-perf-cover.c b/perf/micro/cairo-perf-cover.c
new file mode 100644
index 000000000..c2499021f
--- /dev/null
+++ b/perf/micro/cairo-perf-cover.c
@@ -0,0 +1,339 @@
+/*
+ * Copyright © 2006 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+#include "cairo-perf.h"
+
+static void
+init_and_set_source_surface (cairo_t *cr,
+ cairo_surface_t *source,
+ int width,
+ int height)
+{
+ cairo_t *cr2;
+
+ /* Fill it with something known */
+ cr2 = cairo_create (source);
+ cairo_set_operator (cr2, CAIRO_OPERATOR_SOURCE);
+ cairo_set_source_rgb (cr2, 0, 0, 1); /* blue */
+ cairo_paint (cr2);
+
+ cairo_set_source_rgba (cr2, 1, 0, 0, 0.5); /* 50% red */
+ cairo_new_path (cr2);
+ cairo_rectangle (cr2, 0, 0, width/2.0, height/2.0);
+ cairo_rectangle (cr2, width/2.0, height/2.0, width/2.0, height/2.0);
+ cairo_fill (cr2);
+
+ cairo_set_source_surface (cr, cairo_get_target (cr2), 0, 0);
+ cairo_destroy (cr2);
+}
+
+static void
+set_source_solid_rgb (cairo_t *cr,
+ int width,
+ int height)
+{
+ cairo_set_source_rgb (cr, 0.2, 0.6, 0.9);
+}
+
+static void
+set_source_solid_rgba (cairo_t *cr,
+ int width,
+ int height)
+{
+ cairo_set_source_rgba (cr, 0.2, 0.6, 0.9, 0.7);
+}
+
+static void
+set_source_image_surface_rgb (cairo_t *cr,
+ int width,
+ int height)
+{
+ cairo_surface_t *source;
+
+ source = cairo_image_surface_create (CAIRO_FORMAT_RGB24,
+ width, height);
+ init_and_set_source_surface (cr, source, width, height);
+
+ cairo_surface_destroy (source);
+}
+
+static void
+set_source_image_surface_rgba (cairo_t *cr,
+ int width,
+ int height)
+{
+ cairo_surface_t *source;
+
+ source = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
+ width, height);
+ init_and_set_source_surface (cr, source, width, height);
+
+ cairo_surface_destroy (source);
+}
+
+static void
+set_source_image_surface_rgba_mag (cairo_t *cr,
+ int width,
+ int height)
+{
+ cairo_surface_t *source;
+
+ source = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
+ width/2, height/2);
+ cairo_scale(cr, 2.1, 2.1);
+ init_and_set_source_surface (cr, source, width/2, height/2);
+ cairo_scale(cr, 1/2.1, 1/2.1);
+
+ cairo_surface_destroy (source);
+}
+
+static void
+set_source_image_surface_rgba_min (cairo_t *cr,
+ int width,
+ int height)
+{
+ cairo_surface_t *source;
+
+ source = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
+ width*2, height*2);
+ cairo_scale(cr, 1/1.9, 1/1.9);
+ init_and_set_source_surface (cr, source, width*2, height*2);
+ cairo_scale(cr, 1.9, 1.9);
+
+ cairo_surface_destroy (source);
+}
+
+static void
+set_source_similar_surface_rgb (cairo_t *cr,
+ int width,
+ int height)
+{
+ cairo_surface_t *source;
+
+ source = cairo_surface_create_similar (cairo_get_group_target (cr),
+ CAIRO_CONTENT_COLOR,
+ width, height);
+ init_and_set_source_surface (cr, source, width, height);
+
+ cairo_surface_destroy (source);
+}
+
+static void
+set_source_similar_surface_rgba (cairo_t *cr,
+ int width,
+ int height)
+{
+ cairo_surface_t *source;
+
+ source = cairo_surface_create_similar (cairo_get_group_target (cr),
+ CAIRO_CONTENT_COLOR_ALPHA,
+ width, height);
+ init_and_set_source_surface (cr, source, width, height);
+
+ cairo_surface_destroy (source);
+}
+
+static void
+set_source_similar_surface_rgba_mag (cairo_t *cr,
+ int width,
+ int height)
+{
+ cairo_surface_t *source;
+
+ source = cairo_surface_create_similar (cairo_get_group_target (cr),
+ CAIRO_CONTENT_COLOR_ALPHA,
+ width/2, height/2);
+ cairo_scale(cr, 2.1, 2.1);
+ init_and_set_source_surface (cr, source, width/2, height/2);
+ cairo_scale(cr, 1/2.1, 1/2.1);
+
+ cairo_surface_destroy (source);
+}
+
+static void
+set_source_similar_surface_rgba_min (cairo_t *cr,
+ int width,
+ int height)
+{
+ cairo_surface_t *source;
+
+ source = cairo_surface_create_similar (cairo_get_group_target (cr),
+ CAIRO_CONTENT_COLOR_ALPHA,
+ width*2, height*2);
+ cairo_scale(cr, 1/1.9, 1/1.9);
+ init_and_set_source_surface (cr, source, width*2, height*2);
+ cairo_scale(cr, 1.9, 1.9);
+
+ cairo_surface_destroy (source);
+}
+
+static void
+set_source_linear_rgb (cairo_t *cr,
+ int width,
+ int height)
+{
+ cairo_pattern_t *linear;
+
+ linear = cairo_pattern_create_linear (0.0, 0.0, width, height);
+ cairo_pattern_add_color_stop_rgb (linear, 0.0, 1, 0, 0); /* red */
+ cairo_pattern_add_color_stop_rgb (linear, 1.0, 0, 0, 1); /* blue */
+
+ cairo_set_source (cr, linear);
+
+ cairo_pattern_destroy (linear);
+}
+
+static void
+set_source_linear_rgba (cairo_t *cr,
+ int width,
+ int height)
+{
+ cairo_pattern_t *linear;
+
+ linear = cairo_pattern_create_linear (0.0, 0.0, width, height);
+ cairo_pattern_add_color_stop_rgba (linear, 0.0, 1, 0, 0, 0.5); /* 50% red */
+ cairo_pattern_add_color_stop_rgba (linear, 1.0, 0, 0, 1, 0.0); /* 0% blue */
+
+ cairo_set_source (cr, linear);
+
+ cairo_pattern_destroy (linear);
+}
+
+static void
+set_source_linear3_rgb (cairo_t *cr,
+ int width,
+ int height)
+{
+ cairo_pattern_t *linear;
+
+ linear = cairo_pattern_create_linear (0.0, 0.0, width, height);
+ cairo_pattern_add_color_stop_rgb (linear, 0.0, 1, 0, 0); /* red */
+ cairo_pattern_add_color_stop_rgb (linear, 0.5, 0, 1, 0); /* green */
+ cairo_pattern_add_color_stop_rgb (linear, 1.0, 0, 0, 1); /* blue */
+
+ cairo_set_source (cr, linear);
+
+ cairo_pattern_destroy (linear);
+}
+
+static void
+set_source_linear3_rgba (cairo_t *cr,
+ int width,
+ int height)
+{
+ cairo_pattern_t *linear;
+
+ linear = cairo_pattern_create_linear (0.0, 0.0, width, height);
+ cairo_pattern_add_color_stop_rgba (linear, 0.0, 1, 0, 0, 0.5); /* 50% red */
+ cairo_pattern_add_color_stop_rgba (linear, 0.5, 0, 1, 0, 0.0); /* 0% green */
+ cairo_pattern_add_color_stop_rgba (linear, 1.0, 0, 0, 1, 0.5); /* 50% blue */
+
+ cairo_set_source (cr, linear);
+
+ cairo_pattern_destroy (linear);
+}
+
+static void
+set_source_radial_rgb (cairo_t *cr,
+ int width,
+ int height)
+{
+ cairo_pattern_t *radial;
+
+ radial = cairo_pattern_create_radial (width/2.0, height/2.0, 0.0,
+ width/2.0, height/2.0, width/2.0);
+ cairo_pattern_add_color_stop_rgb (radial, 0.0, 1, 0, 0); /* red */
+ cairo_pattern_add_color_stop_rgb (radial, 1.0, 0, 0, 1); /* blue */
+
+ cairo_set_source (cr, radial);
+
+ cairo_pattern_destroy (radial);
+}
+
+static void
+set_source_radial_rgba (cairo_t *cr,
+ int width,
+ int height)
+{
+ cairo_pattern_t *radial;
+
+ radial = cairo_pattern_create_radial (width/2.0, height/2.0, 0.0,
+ width/2.0, height/2.0, width/2.0);
+ cairo_pattern_add_color_stop_rgba (radial, 0.0, 1, 0, 0, 0.5); /* 50% red */
+ cairo_pattern_add_color_stop_rgba (radial, 1.0, 0, 0, 1, 0.0); /* 0% blue */
+
+ cairo_set_source (cr, radial);
+
+ cairo_pattern_destroy (radial);
+}
+
+typedef void (*set_source_func_t) (cairo_t *cr, int width, int height);
+
+void
+cairo_perf_cover_sources_and_operators (cairo_perf_t *perf,
+ const char *name,
+ cairo_perf_func_t perf_func,
+ cairo_count_func_t count_func)
+{
+ unsigned int i, j;
+ char *expanded_name;
+
+ struct { set_source_func_t set_source; const char *name; } sources[] = {
+ { set_source_solid_rgb, "solid-rgb" },
+ { set_source_solid_rgba, "solid-rgba" },
+ { set_source_image_surface_rgb, "image-rgb" },
+ { set_source_image_surface_rgba, "image-rgba" },
+ { set_source_image_surface_rgba_mag, "image-rgba-mag" },
+ { set_source_image_surface_rgba_min, "image-rgba-min" },
+ { set_source_similar_surface_rgb, "similar-rgb" },
+ { set_source_similar_surface_rgba, "similar-rgba" },
+ { set_source_similar_surface_rgba_mag, "similar-rgba-mag" },
+ { set_source_similar_surface_rgba_min, "similar-rgba-min" },
+ { set_source_linear_rgb, "linear-rgb" },
+ { set_source_linear_rgba, "linear-rgba" },
+ { set_source_linear3_rgb, "linear3-rgb" },
+ { set_source_linear3_rgba, "linear3-rgba" },
+ { set_source_radial_rgb, "radial-rgb" },
+ { set_source_radial_rgba, "radial-rgba" }
+ };
+
+ struct { cairo_operator_t op; const char *name; } operators[] = {
+ { CAIRO_OPERATOR_OVER, "over" },
+ { CAIRO_OPERATOR_SOURCE, "source" }
+ };
+
+ for (i = 0; i < ARRAY_LENGTH (sources); i++) {
+ (sources[i].set_source) (perf->cr, perf->size, perf->size);
+
+ for (j = 0; j < ARRAY_LENGTH (operators); j++) {
+ cairo_set_operator (perf->cr, operators[j].op);
+
+ xasprintf (&expanded_name, "%s_%s_%s",
+ name, sources[i].name, operators[j].name);
+ cairo_perf_run (perf, expanded_name, perf_func, count_func);
+ free (expanded_name);
+ }
+ }
+}
diff --git a/perf/micro/composite-checker.c b/perf/micro/composite-checker.c
new file mode 100644
index 000000000..d6d17ab63
--- /dev/null
+++ b/perf/micro/composite-checker.c
@@ -0,0 +1,117 @@
+/*
+ * Copyright © 2007 Björn Lindqvist
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Björn Lindqvist <bjourne@gmail.com>
+ */
+
+#include "cairo-perf.h"
+
+/* This test case measures how much time cairo takes to render the
+ * equivalent of the following gdk-pixbuf operation:
+ *
+ * gdk_pixbuf_composite_color(dest,
+ * 0, 0, DST_SIZE, DST_SIZE,
+ * 0, 0,
+ * SCALE, SCALE,
+ * gdk.INTERP_NEAREST,
+ * 255,
+ * 0, 0,
+ * 8, 0x33333333, 0x88888888);
+ *
+ * Cairo is (at the time of writing) about 2-3 times as slow as
+ * gdk-pixbuf.
+ */
+#define PAT_SIZE 16
+#define SRC_SIZE 64
+
+static cairo_pattern_t *checkerboard = NULL;
+static cairo_pattern_t *src_pattern = NULL;
+
+static cairo_time_t
+do_composite_checker (cairo_t *cr,
+ int width,
+ int height,
+ int loops)
+{
+ /* Compute zoom so that the src_pattern covers the whole output image. */
+ double xscale = width / (double) SRC_SIZE;
+ double yscale = height / (double) SRC_SIZE;
+
+ cairo_perf_timer_start ();
+
+ while (loops--) {
+ /* Fill the surface with our background. */
+ cairo_identity_matrix (cr);
+ cairo_set_source (cr, checkerboard);
+ cairo_paint (cr);
+
+ /* Draw the scaled image on top. */
+ cairo_scale (cr, xscale, yscale);
+ cairo_set_source (cr, src_pattern);
+ cairo_paint (cr);
+ }
+
+ cairo_perf_timer_stop ();
+ return cairo_perf_timer_elapsed ();
+}
+
+cairo_bool_t
+composite_checker_enabled (cairo_perf_t *perf)
+{
+ return cairo_perf_can_run (perf, "composite-checker", NULL);
+}
+
+void
+composite_checker (cairo_perf_t *perf,
+ cairo_t *cr,
+ int width,
+ int height)
+{
+ cairo_surface_t *image;
+
+ /* Create the checker pattern. We don't actually need to draw
+ * anything on it since that wouldn't affect performance.
+ */
+ image = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
+ PAT_SIZE,
+ PAT_SIZE);
+ checkerboard = cairo_pattern_create_for_surface (image);
+ cairo_pattern_set_filter (checkerboard, CAIRO_FILTER_NEAREST);
+ cairo_pattern_set_extend (checkerboard, CAIRO_EXTEND_REPEAT);
+ cairo_surface_destroy (image);
+
+ /* Create the image source pattern. Again we use the NEAREST
+ * filtering which should be fastest.
+ */
+ image = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
+ SRC_SIZE,
+ SRC_SIZE);
+ src_pattern = cairo_pattern_create_for_surface (image);
+ cairo_pattern_set_filter (src_pattern, CAIRO_FILTER_NEAREST);
+ cairo_surface_destroy (image);
+
+ cairo_perf_run (perf, "composite-checker", do_composite_checker, NULL);
+
+ cairo_pattern_destroy (checkerboard);
+ cairo_pattern_destroy (src_pattern);
+}
diff --git a/perf/micro/curve.c b/perf/micro/curve.c
new file mode 100644
index 000000000..3b5a16342
--- /dev/null
+++ b/perf/micro/curve.c
@@ -0,0 +1,111 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-perf.h"
+
+static uint32_t state;
+
+static double
+uniform_random (double minval, double maxval)
+{
+ static uint32_t const poly = 0x9a795537U;
+ uint32_t n = 32;
+ while (n-->0)
+ state = 2*state < state ? (2*state ^ poly) : 2*state;
+ return minval + state * (maxval - minval) / 4294967296.0;
+}
+
+static cairo_time_t
+do_curve_stroke (cairo_t *cr, int width, int height, int loops)
+{
+ state = 0xc0ffee;
+ cairo_set_line_width (cr, 2.);
+ cairo_perf_timer_start ();
+
+ while (loops--) {
+ double x1 = uniform_random (0, width);
+ double x2 = uniform_random (0, width);
+ double x3 = uniform_random (0, width);
+ double y1 = uniform_random (0, height);
+ double y2 = uniform_random (0, height);
+ double y3 = uniform_random (0, height);
+ cairo_move_to (cr, uniform_random (0, width), uniform_random (0, height));
+ cairo_curve_to (cr, x1, y1, x2, y2, x3, y3);
+ cairo_stroke(cr);
+ }
+
+ cairo_perf_timer_stop ();
+
+ return cairo_perf_timer_elapsed ();
+}
+
+static cairo_time_t
+do_curve_fill (cairo_t *cr, int width, int height, int loops)
+{
+ state = 0xc0ffee;
+ cairo_perf_timer_start ();
+
+ while (loops--) {
+ double x0 = uniform_random (0, width);
+ double x1 = uniform_random (0, width);
+ double x2 = uniform_random (0, width);
+ double x3 = uniform_random (0, width);
+ double xm = uniform_random (0, width);
+ double xn = uniform_random (0, width);
+ double y0 = uniform_random (0, height);
+ double y1 = uniform_random (0, height);
+ double y2 = uniform_random (0, height);
+ double y3 = uniform_random (0, height);
+ double ym = uniform_random (0, height);
+ double yn = uniform_random (0, height);
+
+ cairo_move_to (cr, xm, ym);
+ cairo_curve_to (cr, x1, y1, x2, y2, xn, yn);
+ cairo_curve_to (cr, x3, y3, x0, y0, xm, ym);
+ cairo_close_path (cr);
+
+ cairo_fill(cr);
+ }
+
+ cairo_perf_timer_stop ();
+
+ return cairo_perf_timer_elapsed ();
+}
+
+cairo_bool_t
+curve_enabled (cairo_perf_t *perf)
+{
+ return cairo_perf_can_run (perf, "curve", NULL);
+}
+
+void
+curve (cairo_perf_t *perf, cairo_t *cr, int width, int height)
+{
+ cairo_set_source_rgb (cr, 1., 1., 1.);
+
+ cairo_perf_run (perf, "curve-stroked", do_curve_stroke, NULL);
+ cairo_perf_run (perf, "curve-filled", do_curve_fill, NULL);
+}
diff --git a/perf/micro/disjoint.c b/perf/micro/disjoint.c
new file mode 100644
index 000000000..847860c7e
--- /dev/null
+++ b/perf/micro/disjoint.c
@@ -0,0 +1,101 @@
+/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
+/* cairo - a vector graphics library with display and print output
+ *
+ * Copyright (c) 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include "cairo-perf.h"
+#include <assert.h>
+
+#define STEP 5
+
+static void path (cairo_t *cr, int width, int height)
+{
+ int i;
+
+ cairo_rectangle (cr, 0, 0, width, height);
+ cairo_clip (cr);
+
+ cairo_translate (cr, width/2, height/2);
+ cairo_rotate (cr, M_PI/4);
+ cairo_translate (cr, -width/2, -height/2);
+
+ for (i = 0; i < width; i += STEP) {
+ cairo_rectangle (cr, i, -2, 1, height+4);
+ cairo_rectangle (cr, -2, i, width+4, 1);
+ }
+}
+
+static void clip (cairo_t *cr, int width, int height)
+{
+ int i, j;
+
+ for (j = 0; j < height; j += 2*STEP) {
+ for (i = 0; i < width; i += 2*STEP)
+ cairo_rectangle (cr, i, j, STEP, STEP);
+
+ j += 2*STEP;
+ for (i = 0; i < width; i += 2*STEP)
+ cairo_rectangle (cr, i+STEP/2, j, STEP, STEP);
+ }
+
+ cairo_clip (cr);
+}
+
+static cairo_time_t
+draw (cairo_t *cr, int width, int height, int loops)
+{
+ cairo_save (cr);
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+ cairo_set_source_rgb (cr, 1, 0, 0);
+
+ cairo_perf_timer_start ();
+ while (loops--) {
+ cairo_save (cr);
+ clip (cr, width, height);
+ path (cr, width, height);
+ cairo_fill (cr);
+ cairo_restore (cr);
+ }
+ cairo_perf_timer_stop ();
+
+ cairo_restore (cr);
+
+ return cairo_perf_timer_elapsed ();
+}
+
+cairo_bool_t
+disjoint_enabled (cairo_perf_t *perf)
+{
+ return cairo_perf_can_run (perf, "disjoint", NULL);
+}
+
+void
+disjoint (cairo_perf_t *perf, cairo_t *cr, int width, int height)
+{
+ if (! cairo_perf_can_run (perf, "disjoint", NULL))
+ return;
+
+ cairo_perf_run (perf, "disjoint", draw, NULL);
+}
diff --git a/perf/micro/dragon.c b/perf/micro/dragon.c
new file mode 100644
index 000000000..aa5daf534
--- /dev/null
+++ b/perf/micro/dragon.c
@@ -0,0 +1,277 @@
+/*
+ * Copyright © 2007 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Chris Wilson not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Chris Wilson makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ *
+ * Inspiration (and path!) taken from
+ * http://labs.trolltech.com/blogs/2007/08/31/rasterizing-dragons/
+ */
+
+#include "cairo-perf.h"
+
+static inline int
+next_pot (int v)
+{
+ v--;
+ v |= v >> 1;
+ v |= v >> 2;
+ v |= v >> 4;
+ v |= v >> 8;
+ v |= v >> 16;
+ v++;
+ return v;
+}
+
+static cairo_bool_t
+direction (int i)
+{
+ int pivot, np2;
+
+ if (i < 2)
+ return TRUE;
+
+ np2 = next_pot (i + 1);
+ if (np2 == i + 1)
+ return TRUE;
+
+ pivot = np2 / 2 - 1;
+ return ! direction (2 * pivot - i);
+}
+
+static void
+path (cairo_t *cr, int step, int dir, int iterations)
+{
+ double dx, dy;
+ int i;
+
+ switch (dir) {
+ default:
+ case 0: dx = step; dy = 0; break;
+ case 1: dx = -step; dy = 0; break;
+ case 2: dx = 0; dy = step; break;
+ case 3: dx = 0; dy = -step; break;
+ }
+
+ for (i = 0; i < iterations; i++) {
+ cairo_rel_line_to (cr, dx, dy);
+
+ if (direction (i)) {
+ double t = dx;
+ dx = dy;
+ dy = -t;
+ } else {
+ double t = dx;
+ dx = -dy;
+ dy = t;
+ }
+ }
+}
+
+static cairo_time_t
+do_dragon (cairo_t *cr, int width, int height, int loops)
+{
+ cairo_pattern_t *pattern;
+ double cx, cy, r;
+
+ cx = cy = .5 * MAX (width, height);
+ r = .5 * MIN (width, height);
+
+ cairo_perf_timer_start ();
+
+ while (loops--) {
+ pattern = cairo_pattern_create_radial (cx, cy, 0., cx, cy, r);
+ cairo_pattern_add_color_stop_rgb (pattern, 0., .0, .0, .0);
+ cairo_pattern_add_color_stop_rgb (pattern, 0.25, .5, .4, .4);
+ cairo_pattern_add_color_stop_rgb (pattern, .5, .8, .8, .9);
+ cairo_pattern_add_color_stop_rgb (pattern, 1., .9, .9, 1.);
+ cairo_set_source (cr, pattern);
+ cairo_pattern_destroy (pattern);
+ cairo_paint (cr);
+
+ cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
+ cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND);
+ cairo_set_line_width (cr, 4.);
+
+ cairo_move_to (cr, cx, cy);
+ path (cr, 12, 0, 2048);
+ pattern = cairo_pattern_create_radial (cx, cy, 0., cx, cy, r);
+ cairo_pattern_add_color_stop_rgb (pattern, 0., 1., 1., 1.);
+ cairo_pattern_add_color_stop_rgb (pattern, 1., 0., 0., 0.);
+ cairo_set_source (cr, pattern);
+ cairo_pattern_destroy (pattern);
+ cairo_stroke(cr);
+
+ cairo_move_to (cr, cx, cy);
+ path (cr, 12, 1, 2048);
+ pattern = cairo_pattern_create_radial (cx, cy, 0., cx, cy, r);
+ cairo_pattern_add_color_stop_rgb (pattern, 1., 1., 1., 0.);
+ cairo_pattern_add_color_stop_rgb (pattern, 0., 1., 0., 0.);
+ cairo_set_source (cr, pattern);
+ cairo_pattern_destroy (pattern);
+ cairo_stroke(cr);
+
+ cairo_move_to (cr, cx, cy);
+ path (cr, 12, 2, 2048);
+ pattern = cairo_pattern_create_radial (cx, cy, 0., cx, cy, r);
+ cairo_pattern_add_color_stop_rgb (pattern, 1., 0., 1., 1.);
+ cairo_pattern_add_color_stop_rgb (pattern, 0., 0., 1., 0.);
+ cairo_set_source (cr, pattern);
+ cairo_pattern_destroy (pattern);
+ cairo_stroke(cr);
+
+ cairo_move_to (cr, cx, cy);
+ path (cr, 12, 3, 2048);
+ pattern = cairo_pattern_create_radial (cx, cy, 0., cx, cy, r);
+ cairo_pattern_add_color_stop_rgb (pattern, 1., 1., 0., 1.);
+ cairo_pattern_add_color_stop_rgb (pattern, 0., 0., 0., 1.);
+ cairo_set_source (cr, pattern);
+ cairo_pattern_destroy (pattern);
+ cairo_stroke(cr);
+ }
+
+ cairo_perf_timer_stop ();
+
+ return cairo_perf_timer_elapsed ();
+}
+
+static cairo_time_t
+do_dragon_solid (cairo_t *cr, int width, int height, int loops)
+{
+ double cx, cy;
+
+ cx = cy = .5 * MAX (width, height);
+
+ cairo_perf_timer_start ();
+
+ while (loops--) {
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ cairo_paint (cr);
+
+ cairo_set_line_width (cr, 4.);
+
+ cairo_move_to (cr, cx, cy);
+ path (cr, 12, 0, 2048);
+ cairo_set_source_rgb (cr, 1, 0, 0);
+ cairo_stroke(cr);
+
+ cairo_move_to (cr, cx, cy);
+ path (cr, 12, 1, 2048);
+ cairo_set_source_rgb (cr, 0, 1, 0);
+ cairo_stroke(cr);
+
+ cairo_move_to (cr, cx, cy);
+ path (cr, 12, 2, 2048);
+ cairo_set_source_rgb (cr, 0, 0, 1);
+ cairo_stroke(cr);
+
+ cairo_move_to (cr, cx, cy);
+ path (cr, 12, 3, 2048);
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_stroke(cr);
+ }
+
+ cairo_perf_timer_stop ();
+
+ return cairo_perf_timer_elapsed ();
+}
+
+static cairo_time_t
+do_dragon_solid_unaligned (cairo_t *cr, int width, int height, int loops)
+{
+ cairo_translate (cr, 0.01, 0.01);
+ return do_dragon_solid (cr, width, height, loops);
+}
+
+static cairo_time_t
+do_dragon_solid_aligned_clip (cairo_t *cr, int width, int height, int loops)
+{
+ cairo_reset_clip (cr);
+ cairo_rectangle (cr, 10, 10, width/2 + 10, height/2 + 10);
+ cairo_rectangle (cr, width/2-20, height/2-20, width/2 + 10, height/2 + 10);
+ cairo_clip (cr);
+
+ return do_dragon_solid (cr, width, height, loops);
+}
+
+static cairo_time_t
+do_dragon_unaligned_solid_aligned_clip (cairo_t *cr, int width, int height, int loops)
+{
+ cairo_translate (cr, 0.01, 0.01);
+ cairo_reset_clip (cr);
+ cairo_rectangle (cr, 10, 10, width/2 + 10, height/2 + 10);
+ cairo_rectangle (cr, width/2-20, height/2-20, width/2 + 10, height/2 + 10);
+ cairo_clip (cr);
+
+ return do_dragon_solid (cr, width, height, loops);
+}
+
+static cairo_time_t
+do_dragon_solid_unaligned_clip (cairo_t *cr, int width, int height, int loops)
+{
+ cairo_reset_clip (cr);
+ cairo_rectangle (cr, 10.5, 10.5, width/2 + 10, height/2 + 10);
+ cairo_rectangle (cr, width/2-20, height/2-20, width/2 + 9.5, height/2 + 9.5);
+ cairo_clip (cr);
+
+ return do_dragon_solid (cr, width, height, loops);
+}
+
+static cairo_time_t
+do_dragon_unaligned_solid_unaligned_clip (cairo_t *cr, int width, int height, int loops)
+{
+ cairo_translate (cr, 0.01, 0.01);
+ cairo_reset_clip (cr);
+ cairo_rectangle (cr, 10.5, 10.5, width/2 + 10, height/2 + 10);
+ cairo_rectangle (cr, width/2-20, height/2-20, width/2 + 9.5, height/2 + 9.5);
+ cairo_clip (cr);
+
+ return do_dragon_solid (cr, width, height, loops);
+}
+
+static cairo_time_t
+do_dragon_solid_circle_clip (cairo_t *cr, int width, int height, int loops)
+{
+ cairo_reset_clip (cr);
+ cairo_arc (cr, width/2., height/2., MIN (width, height)/2. - 10, 0, 2 * M_PI);
+ cairo_clip (cr);
+
+ return do_dragon_solid (cr, width, height, loops);
+}
+
+cairo_bool_t
+dragon_enabled (cairo_perf_t *perf)
+{
+ return cairo_perf_can_run (perf, "dragon", NULL);
+}
+
+void
+dragon (cairo_perf_t *perf, cairo_t *cr, int width, int height)
+{
+ cairo_perf_run (perf, "dragon-solid", do_dragon_solid, NULL);
+ cairo_perf_run (perf, "dragon-unaligned-solid", do_dragon_solid_unaligned, NULL);
+ cairo_perf_run (perf, "dragon-solid-aligned-clip", do_dragon_solid_aligned_clip, NULL);
+ cairo_perf_run (perf, "dragon-unaligned-solid-aligned-clip", do_dragon_unaligned_solid_aligned_clip, NULL);
+ cairo_perf_run (perf, "dragon-solid-unaligned-clip", do_dragon_solid_unaligned_clip, NULL);
+ cairo_perf_run (perf, "dragon-unaligned-solid-unaligned-clip", do_dragon_unaligned_solid_unaligned_clip, NULL);
+ cairo_perf_run (perf, "dragon-solid-circle-clip", do_dragon_solid_circle_clip, NULL);
+ cairo_perf_run (perf, "dragon", do_dragon, NULL);
+}
diff --git a/perf/micro/fill-clip.c b/perf/micro/fill-clip.c
new file mode 100644
index 000000000..2d014aca8
--- /dev/null
+++ b/perf/micro/fill-clip.c
@@ -0,0 +1,126 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+/* Compares the overhead for WebKit's drawRect() */
+
+#include "cairo-perf.h"
+
+#include <pixman.h>
+
+static cairo_time_t
+clip_paint (cairo_t *cr, int width, int height, int loops)
+{
+ int x = width/4, w = width/2;
+ int y = height/4, h = height/2;
+
+ cairo_perf_timer_start ();
+
+ while (loops--) {
+ cairo_reset_clip (cr);
+ cairo_rectangle (cr, x, y, w, h);
+ cairo_clip (cr);
+ cairo_paint (cr);
+ }
+
+ cairo_perf_timer_stop ();
+
+ return cairo_perf_timer_elapsed ();
+}
+
+static cairo_time_t
+rect_fill (cairo_t *cr, int width, int height, int loops)
+{
+ int x = width/4, w = width/2;
+ int y = height/4, h = height/2;
+
+ cairo_perf_timer_start ();
+
+ while (loops--) {
+ cairo_rectangle (cr, x, y, w, h);
+ cairo_fill (cr);
+ }
+
+ cairo_perf_timer_stop ();
+
+ return cairo_perf_timer_elapsed ();
+}
+
+static cairo_time_t
+direct (cairo_t *cr, int width, int height, int loops)
+{
+ int x = width/4, w = width/2;
+ int y = height/4, h = height/2;
+ cairo_surface_t *surface, *image;
+ uint8_t *data;
+ int stride, bpp;
+
+
+ surface = cairo_get_target (cr);
+ image = cairo_surface_map_to_image (surface, NULL);
+ data = cairo_image_surface_get_data (image);
+ stride = cairo_image_surface_get_stride (image);
+
+ switch (cairo_image_surface_get_format (image)) {
+ default:
+ case CAIRO_FORMAT_INVALID:
+ case CAIRO_FORMAT_A1: bpp = 0; break;
+ case CAIRO_FORMAT_A8: bpp = 8; break;
+ case CAIRO_FORMAT_RGB16_565: bpp = 16; break;
+ case CAIRO_FORMAT_RGB24:
+ case CAIRO_FORMAT_RGB30:
+ case CAIRO_FORMAT_ARGB32: bpp = 32; break;
+ }
+
+ cairo_perf_timer_start ();
+
+ while (loops--) {
+ pixman_fill ((uint32_t *)data, stride / sizeof(uint32_t), bpp,
+ x, y, w, h,
+ -1);
+ }
+
+ cairo_perf_timer_stop ();
+
+ cairo_surface_unmap_image (surface, image);
+
+ return cairo_perf_timer_elapsed ();
+}
+
+cairo_bool_t
+fill_clip_enabled (cairo_perf_t *perf)
+{
+ return cairo_perf_can_run (perf, "fillclip", NULL);
+}
+
+void
+fill_clip (cairo_perf_t *perf, cairo_t *cr, int width, int height)
+{
+ cairo_set_source_rgb (cr, 1., 1., 1.);
+
+ cairo_perf_run (perf, "fillclip-clip", clip_paint, NULL);
+ cairo_perf_run (perf, "fillclip-fill", rect_fill, NULL);
+ cairo_perf_run (perf, "fillclip-direct", direct, NULL);
+}
diff --git a/perf/micro/fill.c b/perf/micro/fill.c
new file mode 100644
index 000000000..d356c26d5
--- /dev/null
+++ b/perf/micro/fill.c
@@ -0,0 +1,122 @@
+/*
+ * Copyright © 2006 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+#include "cairo-perf.h"
+
+static cairo_time_t
+do_fill (cairo_t *cr, int width, int height, int loops)
+{
+ cairo_arc (cr,
+ width/2.0, height/2.0,
+ width/3.0,
+ 0, 2 * M_PI);
+
+ cairo_perf_timer_start ();
+
+ while (loops--)
+ cairo_fill_preserve (cr);
+
+ cairo_perf_timer_stop ();
+
+ cairo_new_path (cr);
+
+ return cairo_perf_timer_elapsed ();
+}
+
+static cairo_time_t
+do_fill_annuli (cairo_t *cr, int width, int height, int loops)
+{
+ cairo_new_sub_path (cr);
+ cairo_arc (cr,
+ width/2.0, height/2.0,
+ width/3.0,
+ 0, 2 * M_PI);
+
+ cairo_new_sub_path (cr);
+ cairo_arc_negative (cr,
+ width/2.0, height/2.0,
+ width/4.0,
+ 2 * M_PI, 0);
+
+ cairo_new_sub_path (cr);
+ cairo_arc (cr,
+ width/2.0, height/2.0,
+ width/6.0,
+ 0, 2 * M_PI);
+
+ cairo_new_sub_path (cr);
+ cairo_arc_negative (cr,
+ width/2.0, height/2.0,
+ width/8.0,
+ 2 * M_PI, 0);
+
+ cairo_perf_timer_start ();
+
+ while (loops--)
+ cairo_fill_preserve (cr);
+
+ cairo_perf_timer_stop ();
+
+ cairo_new_path (cr);
+
+ return cairo_perf_timer_elapsed ();
+}
+
+static cairo_time_t
+do_fill_eo_noaa (cairo_t *cr, int width, int height, int loops)
+{
+ cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE);
+ cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
+
+ cairo_arc (cr,
+ width/2.0, height/2.0,
+ width/3.0,
+ 0, 2 * M_PI);
+
+ cairo_perf_timer_start ();
+
+ while (loops--)
+ cairo_fill_preserve (cr);
+
+ cairo_perf_timer_stop ();
+
+ cairo_new_path (cr);
+
+ return cairo_perf_timer_elapsed ();
+}
+
+cairo_bool_t
+fill_enabled (cairo_perf_t *perf)
+{
+ return cairo_perf_can_run (perf, "fill", NULL);
+}
+
+void
+fill (cairo_perf_t *perf, cairo_t *cr, int width, int height)
+{
+ cairo_perf_cover_sources_and_operators (perf, "fill", do_fill, NULL);
+ cairo_perf_cover_sources_and_operators (perf, "fill-annuli", do_fill_annuli, NULL);
+ cairo_perf_cover_sources_and_operators (perf, "fill-eo-noaa", do_fill_eo_noaa, NULL);
+}
diff --git a/perf/micro/glyphs.c b/perf/micro/glyphs.c
new file mode 100644
index 000000000..5f088b29e
--- /dev/null
+++ b/perf/micro/glyphs.c
@@ -0,0 +1,202 @@
+/*
+ * Copyright © 2006 Red Hat, Inc.
+ * Copyright © 2009 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ * Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-perf.h"
+
+static cairo_time_t
+do_glyphs (double font_size,
+ cairo_antialias_t antialias,
+ cairo_t *cr, int width, int height, int loops)
+{
+ const char text[] = "the jay, pig, fox, zebra and my wolves quack";
+ cairo_scaled_font_t *scaled_font;
+ cairo_glyph_t *glyphs = NULL, *glyphs_copy;
+ cairo_text_extents_t extents;
+ cairo_font_options_t *options;
+ cairo_status_t status;
+ double x, y;
+ int num_glyphs, n;
+
+ options = cairo_font_options_create ();
+ cairo_font_options_set_antialias (options, antialias);
+ cairo_set_font_options (cr, options);
+ cairo_font_options_destroy (options);
+
+ cairo_select_font_face (cr,
+ "@cairo:",
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_NORMAL);
+ cairo_set_font_size (cr, font_size);
+ scaled_font = cairo_get_scaled_font (cr);
+ status = cairo_scaled_font_text_to_glyphs (scaled_font, 0., 0.,
+ text, -1,
+ &glyphs, &num_glyphs,
+ NULL, NULL,
+ NULL);
+ if (status)
+ return 0;
+
+ glyphs_copy = cairo_glyph_allocate (num_glyphs);
+ if (glyphs_copy == NULL) {
+ cairo_glyph_free (glyphs);
+ return 0;
+ }
+
+ cairo_scaled_font_glyph_extents (scaled_font,
+ glyphs, num_glyphs,
+ &extents);
+
+ cairo_perf_timer_start ();
+
+ while (loops--) {
+ y = 0;
+ do {
+ x = 0;
+ do {
+ for (n = 0; n < num_glyphs; n++) {
+ glyphs_copy[n] = glyphs[n];
+ glyphs_copy[n].x += x;
+ glyphs_copy[n].y += y;
+ }
+ cairo_show_glyphs (cr, glyphs_copy, num_glyphs);
+
+ x += extents.width;
+ } while (x < width);
+ y += extents.height;
+ } while (y < height);
+ }
+
+ cairo_perf_timer_stop ();
+
+ cairo_glyph_free (glyphs);
+ cairo_glyph_free (glyphs_copy);
+
+ return cairo_perf_timer_elapsed ();
+}
+
+static double
+count_glyphs (double font_size,
+ cairo_antialias_t antialias,
+ cairo_t *cr, int width, int height)
+{
+ const char text[] = "the jay, pig, fox, zebra and my wolves quack";
+ cairo_scaled_font_t *scaled_font;
+ cairo_glyph_t *glyphs = NULL;
+ cairo_text_extents_t extents;
+ cairo_font_options_t *options;
+ cairo_status_t status;
+ int num_glyphs;
+ int glyphs_per_line, lines_per_loop;
+
+ options = cairo_font_options_create ();
+ cairo_font_options_set_antialias (options, antialias);
+ cairo_set_font_options (cr, options);
+ cairo_font_options_destroy (options);
+
+ cairo_select_font_face (cr,
+ "@cairo:",
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_NORMAL);
+ cairo_set_font_size (cr, font_size);
+ scaled_font = cairo_get_scaled_font (cr);
+ status = cairo_scaled_font_text_to_glyphs (scaled_font, 0., 0.,
+ text, -1,
+ &glyphs, &num_glyphs,
+ NULL, NULL,
+ NULL);
+ if (status)
+ return 0;
+
+ cairo_scaled_font_glyph_extents (scaled_font,
+ glyphs, num_glyphs,
+ &extents);
+ cairo_glyph_free (glyphs);
+
+ glyphs_per_line = num_glyphs * width / extents.width + 1;
+ lines_per_loop = height / extents.height + 1;
+ return glyphs_per_line * lines_per_loop / 1000.; /* kiloglyphs */
+}
+
+#define DECL(name,size, aa) \
+static cairo_time_t \
+do_glyphs##name (cairo_t *cr, int width, int height, int loops) \
+{ \
+ return do_glyphs (size, aa, cr, width, height, loops); \
+} \
+\
+static double \
+count_glyphs##name (cairo_t *cr, int width, int height) \
+{ \
+ return count_glyphs (size, aa, cr, width, height); \
+}
+
+DECL(8, 8, CAIRO_ANTIALIAS_GRAY)
+DECL(10, 10, CAIRO_ANTIALIAS_GRAY)
+DECL(12, 12, CAIRO_ANTIALIAS_GRAY)
+DECL(16, 16, CAIRO_ANTIALIAS_GRAY)
+DECL(20, 20, CAIRO_ANTIALIAS_GRAY)
+DECL(24, 24, CAIRO_ANTIALIAS_GRAY)
+DECL(32, 32, CAIRO_ANTIALIAS_GRAY)
+DECL(40, 40, CAIRO_ANTIALIAS_GRAY)
+DECL(48, 48, CAIRO_ANTIALIAS_GRAY)
+
+DECL(8ca, 8, CAIRO_ANTIALIAS_SUBPIXEL)
+DECL(48ca, 48, CAIRO_ANTIALIAS_SUBPIXEL)
+
+DECL(8mono, 8, CAIRO_ANTIALIAS_NONE)
+DECL(48mono, 48, CAIRO_ANTIALIAS_NONE)
+
+cairo_bool_t
+glyphs_enabled (cairo_perf_t *perf)
+{
+ return cairo_perf_can_run (perf, "glyphs", NULL);
+}
+
+void
+glyphs (cairo_perf_t *perf, cairo_t *cr, int width, int height)
+{
+ cairo_perf_cover_sources_and_operators (perf, "glyphs8mono", do_glyphs8mono, count_glyphs8mono);
+ cairo_perf_cover_sources_and_operators (perf, "glyphs8", do_glyphs8, count_glyphs8);
+ cairo_perf_cover_sources_and_operators (perf, "glyphs8ca", do_glyphs8ca, count_glyphs8ca);
+
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+ cairo_set_source_rgb (cr, 0, 0, 0);
+
+ cairo_perf_run (perf, "glyphs8", do_glyphs8, count_glyphs8);
+ cairo_perf_run (perf, "glyphs10", do_glyphs10, count_glyphs10);
+ cairo_perf_run (perf, "glyphs12", do_glyphs12, count_glyphs12);
+ cairo_perf_run (perf, "glyphs16", do_glyphs16, count_glyphs16);
+ cairo_perf_run (perf, "glyphs20", do_glyphs20, count_glyphs20);
+ cairo_perf_run (perf, "glyphs24", do_glyphs24, count_glyphs24);
+ cairo_perf_run (perf, "glyphs32", do_glyphs32, count_glyphs32);
+ cairo_perf_run (perf, "glyphs40", do_glyphs40, count_glyphs40);
+ cairo_perf_run (perf, "glyphs48", do_glyphs48, count_glyphs48);
+
+ cairo_perf_cover_sources_and_operators (perf, "glyphs48mono", do_glyphs48mono, count_glyphs48mono);
+ cairo_perf_cover_sources_and_operators (perf, "glyphs48", do_glyphs48, count_glyphs48);
+ cairo_perf_cover_sources_and_operators (perf, "glyphs48ca", do_glyphs48ca, count_glyphs48ca);
+}
diff --git a/perf/micro/hash-table.c b/perf/micro/hash-table.c
new file mode 100644
index 000000000..d16291770
--- /dev/null
+++ b/perf/micro/hash-table.c
@@ -0,0 +1,115 @@
+/*
+ * Copyright © 2011 Andrea Canciani
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Andrea Canciani <ranma42@gmail.com>
+ */
+
+#include "cairo-perf.h"
+
+#define ITER 1000
+#define HOLDOVERS 256
+#define LIVE_ENTRIES 257
+#define ACTIVE_FONTS (LIVE_ENTRIES - HOLDOVERS - 1)
+
+/*
+ * The original implementation of hash tables was very inefficient, as
+ * pointed out in https://bugs.freedesktop.org/show_bug.cgi?id=17399
+ *
+ * This benchmark tries to fill up the scaled_font_map hash table to
+ * show the O(n) behavior.
+ */
+
+static cairo_time_t
+do_hash_table (cairo_t *cr, int width, int height, int loops)
+{
+ /*
+ * Microsoft C Compiler complains that:
+ * error C2466: cannot allocate an array of constant size 0
+ * so we add an unused element to make it happy
+ */
+ cairo_scaled_font_t *active_fonts[ACTIVE_FONTS + 1];
+ cairo_matrix_t m;
+ int i;
+
+ cairo_matrix_init_identity (&m);
+
+ /* Touch HOLDOVERS scaled fonts to fill up the holdover list. */
+ for (i = 0; i < HOLDOVERS; i++) {
+ m.yy = m.xx * (i + 1);
+ cairo_set_font_matrix (cr, &m);
+ cairo_get_scaled_font (cr);
+ }
+
+ /*
+ * Reference some scaled fonts so that they will be kept in the
+ * scaled fonts map. We want LIVE_ENTRIES elements in the font
+ * map, but cairo keeps HOLDOVERS recently used fonts in it and we
+ * will be activating a new font in the cr context, so we just
+ * keep references to ACTIVE_FONTS fonts.
+ *
+ * Note: setting LIVE_ENTRIES == HOLDOVERS+1 means that we keep no
+ * font in active_fonts and the slowness is caused by the holdover
+ * fonts only.
+ */
+ for (i = 0; i < ACTIVE_FONTS; i++) {
+ cairo_scaled_font_t *scaled_font;
+
+ m.yy = m.xx * (i + 1);
+ cairo_set_font_matrix (cr, &m);
+
+ scaled_font = cairo_get_scaled_font (cr);
+ active_fonts[i] = cairo_scaled_font_reference (scaled_font);
+ }
+
+ cairo_perf_timer_start ();
+
+ while (loops--) {
+ m.xx += 1.0;
+
+ /* Generate ITER new scaled fonts per loop */
+ for (i = 0; i < ITER; i++) {
+ m.yy = m.xx * (i + 1);
+ cairo_set_font_matrix (cr, &m);
+ cairo_get_scaled_font (cr);
+ }
+ }
+
+ cairo_perf_timer_stop ();
+
+ for (i = 0; i < ACTIVE_FONTS; i++)
+ cairo_scaled_font_destroy (active_fonts[i]);
+
+ return cairo_perf_timer_elapsed ();
+}
+
+cairo_bool_t
+hash_table_enabled (cairo_perf_t *perf)
+{
+ return cairo_perf_can_run (perf, "hash-table", NULL);
+}
+
+void
+hash_table (cairo_perf_t *perf, cairo_t *cr, int width, int height)
+{
+ cairo_perf_cover_sources_and_operators (perf, "hash-table",
+ do_hash_table, NULL);
+}
diff --git a/perf/micro/hatching.c b/perf/micro/hatching.c
new file mode 100644
index 000000000..d1d9fb8a6
--- /dev/null
+++ b/perf/micro/hatching.c
@@ -0,0 +1,202 @@
+/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
+/* cairo - a vector graphics library with display and print output
+ *
+ * Copyright (c) 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include "cairo-perf.h"
+#include <assert.h>
+
+
+#define STEP 5
+#define WIDTH 100
+#define HEIGHT 100
+
+static void path (cairo_t *cr, unsigned int width, unsigned int height)
+{
+ unsigned int i;
+
+ for (i = 0; i < width+1; i += STEP) {
+ cairo_rectangle (cr, i-1, -1, 2, height+2);
+ cairo_rectangle (cr, -1, i-1, width+2, 2);
+ }
+}
+
+static void aa (cairo_t *cr)
+{
+ cairo_set_antialias (cr, CAIRO_ANTIALIAS_DEFAULT);
+}
+
+static void mono (cairo_t *cr)
+{
+ cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE);
+}
+
+static void aligned (cairo_t *cr, int width, int height)
+{
+}
+
+static void misaligned (cairo_t *cr, int width, int height)
+{
+ cairo_translate (cr, 0.25, 0.25);
+}
+
+static void rotated (cairo_t *cr, int width, int height)
+{
+ cairo_translate (cr, width/2, height/2);
+ cairo_rotate (cr, M_PI/4);
+ cairo_translate (cr, -width/2, -height/2);
+}
+
+static void clip (cairo_t *cr)
+{
+ cairo_clip (cr);
+ cairo_paint (cr);
+}
+
+static void clip_alpha (cairo_t *cr)
+{
+ cairo_clip (cr);
+ cairo_paint_with_alpha (cr, .5);
+}
+
+static cairo_time_t
+draw (cairo_t *cr,
+ void (*prepare) (cairo_t *cr),
+ void (*transform) (cairo_t *cr, int width, int height),
+ void (*op) (cairo_t *cr),
+ int width, int height, int loops)
+{
+ cairo_save (cr);
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+ cairo_set_source_rgb (cr, 1, 0, 0);
+
+ prepare (cr);
+
+ cairo_perf_timer_start ();
+ while (loops--) {
+ cairo_save (cr);
+ transform (cr, width, height);
+ path (cr, width, height);
+ op (cr);
+ cairo_restore (cr);
+ }
+ cairo_perf_timer_stop ();
+
+ cairo_restore (cr);
+
+ return cairo_perf_timer_elapsed ();
+}
+
+static cairo_time_t
+draw_aligned_aa (cairo_t *cr, int width, int height, int loops)
+{
+ return draw(cr, aa, aligned, cairo_fill,
+ width, height, loops);
+}
+
+static cairo_time_t
+draw_misaligned_aa (cairo_t *cr, int width, int height, int loops)
+{
+ return draw(cr, aa, misaligned, cairo_fill,
+ width, height, loops);
+}
+
+static cairo_time_t
+draw_rotated_aa (cairo_t *cr, int width, int height, int loops)
+{
+ return draw(cr, aa, rotated, cairo_fill,
+ width, height, loops);
+}
+
+static cairo_time_t
+draw_aligned_mono (cairo_t *cr, int width, int height, int loops)
+{
+ return draw(cr, mono, aligned, cairo_fill,
+ width, height, loops);
+}
+
+static cairo_time_t
+draw_misaligned_mono (cairo_t *cr, int width, int height, int loops)
+{
+ return draw(cr, mono, misaligned, cairo_fill,
+ width, height, loops);
+}
+
+static cairo_time_t
+draw_rotated_mono (cairo_t *cr, int width, int height, int loops)
+{
+ return draw(cr, mono, rotated, cairo_fill,
+ width, height, loops);
+}
+
+#define F(name, op,transform,aa) \
+static cairo_time_t \
+draw_##name (cairo_t *cr, int width, int height, int loops) \
+{ return draw(cr, (aa), (transform), (op), width, height, loops); }
+
+F(clip_aligned, clip, aligned, aa)
+F(clip_misaligned, clip, misaligned, aa)
+F(clip_rotated, clip, rotated, aa)
+F(clip_aligned_mono, clip, aligned, mono)
+F(clip_misaligned_mono, clip, misaligned, mono)
+F(clip_rotated_mono, clip, rotated, mono)
+
+F(clip_alpha_aligned, clip_alpha, aligned, aa)
+F(clip_alpha_misaligned, clip_alpha, misaligned, aa)
+F(clip_alpha_rotated, clip_alpha, rotated, aa)
+F(clip_alpha_aligned_mono, clip_alpha, aligned, mono)
+F(clip_alpha_misaligned_mono, clip_alpha, misaligned, mono)
+F(clip_alpha_rotated_mono, clip_alpha, rotated, mono)
+
+cairo_bool_t
+hatching_enabled (cairo_perf_t *perf)
+{
+ return cairo_perf_can_run (perf, "hatching", NULL);
+}
+
+void
+hatching (cairo_perf_t *perf, cairo_t *cr, int width, int height)
+{
+ cairo_perf_run (perf, "hatching-aligned-aa", draw_aligned_aa, NULL);
+ cairo_perf_run (perf, "hatching-misaligned-aa", draw_misaligned_aa, NULL);
+ cairo_perf_run (perf, "hatching-rotated-aa", draw_rotated_aa, NULL);
+ cairo_perf_run (perf, "hatching-aligned-mono", draw_aligned_mono, NULL);
+ cairo_perf_run (perf, "hatching-misaligned-mono", draw_misaligned_mono, NULL);
+ cairo_perf_run (perf, "hatching-rotated-mono", draw_rotated_mono, NULL);
+
+ cairo_perf_run (perf, "hatching-clip-aligned-aa", draw_clip_aligned, NULL);
+ cairo_perf_run (perf, "hatching-clip-misaligned-aa", draw_clip_misaligned, NULL);
+ cairo_perf_run (perf, "hatching-clip-rotated-aa", draw_clip_rotated, NULL);
+ cairo_perf_run (perf, "hatching-clip-aligned-mono", draw_clip_aligned_mono, NULL);
+ cairo_perf_run (perf, "hatching-clip-misaligned-mono", draw_clip_misaligned_mono, NULL);
+ cairo_perf_run (perf, "hatching-clip-rotated-mono", draw_clip_rotated_mono, NULL);
+
+ cairo_perf_run (perf, "hatching-clip-alpha-aligned-aa", draw_clip_alpha_aligned, NULL);
+ cairo_perf_run (perf, "hatching-clip-alpha-misaligned-aa", draw_clip_alpha_misaligned, NULL);
+ cairo_perf_run (perf, "hatching-clip-alpha-rotated-aa", draw_clip_alpha_rotated, NULL);
+ cairo_perf_run (perf, "hatching-clip-alpha-aligned-mono", draw_clip_alpha_aligned_mono, NULL);
+ cairo_perf_run (perf, "hatching-clip-alpha-misaligned-mono", draw_clip_alpha_misaligned_mono, NULL);
+ cairo_perf_run (perf, "hatching-clip-alpha-rotated-mono", draw_clip_alpha_rotated_mono, NULL);
+}
diff --git a/perf/micro/intersections.c b/perf/micro/intersections.c
new file mode 100644
index 000000000..57931faf8
--- /dev/null
+++ b/perf/micro/intersections.c
@@ -0,0 +1,160 @@
+/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
+/* cairo - a vector graphics library with display and print output
+ *
+ * Copyright (c) 2008 M Joonas Pihlaja
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include "cairo-perf.h"
+
+#define NUM_SEGMENTS 256
+
+static unsigned state;
+static double
+uniform_random (double minval, double maxval)
+{
+ static unsigned const poly = 0x9a795537U;
+ unsigned n = 32;
+ while (n-->0)
+ state = 2*state < state ? (2*state ^ poly) : 2*state;
+ return minval + state * (maxval - minval) / 4294967296.0;
+}
+
+static cairo_time_t
+draw_random (cairo_t *cr, cairo_fill_rule_t fill_rule,
+ int width, int height, int loops)
+{
+ double x[NUM_SEGMENTS];
+ double y[NUM_SEGMENTS];
+ int i;
+
+ cairo_save (cr);
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ cairo_paint (cr);
+
+ for (i = 0; i < NUM_SEGMENTS; i++) {
+ x[i] = uniform_random (0, width);
+ y[i] = uniform_random (0, height);
+ }
+
+ state = 0x12345678;
+ cairo_translate (cr, 1, 1);
+ cairo_set_fill_rule (cr, fill_rule);
+ cairo_set_source_rgb (cr, 1, 0, 0);
+
+ cairo_new_path (cr);
+ cairo_move_to (cr, 0, 0);
+ for (i = 0; i < NUM_SEGMENTS; i++)
+ cairo_line_to (cr, x[i], y[i]);
+ cairo_close_path (cr);
+
+ cairo_perf_timer_start ();
+ while (loops--)
+ cairo_fill_preserve (cr);
+ cairo_perf_timer_stop ();
+
+ cairo_restore (cr);
+
+ return cairo_perf_timer_elapsed ();
+}
+
+static cairo_time_t
+draw_random_curve (cairo_t *cr, cairo_fill_rule_t fill_rule,
+ int width, int height, int loops)
+{
+ double x[3*NUM_SEGMENTS];
+ double y[3*NUM_SEGMENTS];
+ int i;
+
+ cairo_save (cr);
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ cairo_paint (cr);
+
+ for (i = 0; i < 3*NUM_SEGMENTS; i++) {
+ x[i] = uniform_random (0, width);
+ y[i] = uniform_random (0, height);
+ }
+
+ state = 0x12345678;
+ cairo_translate (cr, 1, 1);
+ cairo_set_fill_rule (cr, fill_rule);
+ cairo_set_source_rgb (cr, 1, 0, 0);
+
+ cairo_new_path (cr);
+ cairo_move_to (cr, 0, 0);
+ for (i = 0; i < NUM_SEGMENTS; i++) {
+ cairo_curve_to (cr,
+ x[3*i+0], y[3*i+0],
+ x[3*i+1], y[3*i+1],
+ x[3*i+2], y[3*i+2]);
+ }
+ cairo_close_path (cr);
+
+ cairo_perf_timer_start ();
+ while (loops--)
+ cairo_fill_preserve (cr);
+ cairo_perf_timer_stop ();
+
+ cairo_restore (cr);
+
+ return cairo_perf_timer_elapsed ();
+}
+
+static cairo_time_t
+random_eo (cairo_t *cr, int width, int height, int loops)
+{
+ return draw_random (cr, CAIRO_FILL_RULE_EVEN_ODD, width, height, loops);
+}
+
+static cairo_time_t
+random_nz (cairo_t *cr, int width, int height, int loops)
+{
+ return draw_random (cr, CAIRO_FILL_RULE_WINDING, width, height, loops);
+}
+
+static cairo_time_t
+random_curve_eo (cairo_t *cr, int width, int height, int loops)
+{
+ return draw_random_curve (cr, CAIRO_FILL_RULE_EVEN_ODD, width, height, loops);
+}
+
+static cairo_time_t
+random_curve_nz (cairo_t *cr, int width, int height, int loops)
+{
+ return draw_random_curve (cr, CAIRO_FILL_RULE_WINDING, width, height, loops);
+}
+
+cairo_bool_t
+intersections_enabled (cairo_perf_t *perf)
+{
+ return cairo_perf_can_run (perf, "intersections", NULL);
+}
+
+void
+intersections (cairo_perf_t *perf, cairo_t *cr, int width, int height)
+{
+ cairo_perf_run (perf, "intersections-nz-fill", random_nz, NULL);
+ cairo_perf_run (perf, "intersections-eo-fill", random_eo, NULL);
+
+ cairo_perf_run (perf, "intersections-nz-curve-fill", random_curve_nz, NULL);
+ cairo_perf_run (perf, "intersections-eo-curve-fill", random_curve_eo, NULL);
+}
diff --git a/perf/micro/line.c b/perf/micro/line.c
new file mode 100644
index 000000000..3ed5f8dac
--- /dev/null
+++ b/perf/micro/line.c
@@ -0,0 +1,222 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-perf.h"
+
+static cairo_time_t
+horizontal (cairo_t *cr, int width, int height, int loops)
+{
+ double h = height/2 + .5;
+
+ cairo_move_to (cr, 0, h);
+ cairo_line_to (cr, width, h);
+
+ cairo_perf_timer_start ();
+
+ while (loops--)
+ cairo_stroke_preserve (cr);
+
+ cairo_perf_timer_stop ();
+
+ cairo_new_path (cr);
+
+ return cairo_perf_timer_elapsed ();
+}
+
+static cairo_time_t
+horizontal_hair (cairo_t *cr, int width, int height, int loops)
+{
+ cairo_set_line_width (cr, 1.);
+ return horizontal (cr, width, height, loops);
+}
+
+static cairo_time_t
+horizontal_wide (cairo_t *cr, int width, int height, int loops)
+{
+ cairo_set_line_width (cr, 5.);
+ return horizontal (cr, width, height, loops);
+}
+
+static cairo_time_t
+nearly_horizontal (cairo_t *cr, int width, int height, int loops)
+{
+ double h = height/2;
+
+ cairo_move_to (cr, 0, h);
+ cairo_line_to (cr, width, h+1);
+
+ cairo_perf_timer_start ();
+
+ while (loops--)
+ cairo_stroke_preserve (cr);
+
+ cairo_perf_timer_stop ();
+
+ cairo_new_path (cr);
+
+ return cairo_perf_timer_elapsed ();
+}
+
+static cairo_time_t
+nearly_horizontal_hair (cairo_t *cr, int width, int height, int loops)
+{
+ cairo_set_line_width (cr, 1.);
+ return nearly_horizontal (cr, width, height, loops);
+}
+
+static cairo_time_t
+nearly_horizontal_wide (cairo_t *cr, int width, int height, int loops)
+{
+ cairo_set_line_width (cr, 5.);
+ return nearly_horizontal (cr, width, height, loops);
+}
+
+
+static cairo_time_t
+vertical (cairo_t *cr, int width, int height, int loops)
+{
+ double w = width/2 + .5;
+
+ cairo_move_to (cr, w, 0);
+ cairo_line_to (cr, w, height);
+
+ cairo_perf_timer_start ();
+
+ while (loops--)
+ cairo_stroke_preserve (cr);
+
+ cairo_perf_timer_stop ();
+
+ cairo_new_path (cr);
+
+ return cairo_perf_timer_elapsed ();
+}
+
+static cairo_time_t
+vertical_hair (cairo_t *cr, int width, int height, int loops)
+{
+ cairo_set_line_width (cr, 1.);
+ return vertical (cr, width, height, loops);
+}
+
+static cairo_time_t
+vertical_wide (cairo_t *cr, int width, int height, int loops)
+{
+ cairo_set_line_width (cr, 5.);
+ return vertical (cr, width, height, loops);
+}
+
+static cairo_time_t
+nearly_vertical (cairo_t *cr, int width, int height, int loops)
+{
+ double w = width/2;
+
+ cairo_move_to (cr, w, 0);
+ cairo_line_to (cr, w+1, height);
+
+ cairo_perf_timer_start ();
+
+ while (loops--)
+ cairo_stroke_preserve (cr);
+
+ cairo_perf_timer_stop ();
+
+ cairo_new_path (cr);
+
+ return cairo_perf_timer_elapsed ();
+}
+
+static cairo_time_t
+nearly_vertical_hair (cairo_t *cr, int width, int height, int loops)
+{
+ cairo_set_line_width (cr, 1.);
+ return nearly_vertical (cr, width, height, loops);
+}
+
+static cairo_time_t
+nearly_vertical_wide (cairo_t *cr, int width, int height, int loops)
+{
+ cairo_set_line_width (cr, 5.);
+ return nearly_vertical (cr, width, height, loops);
+}
+
+
+static cairo_time_t
+diagonal (cairo_t *cr, int width, int height, int loops)
+{
+ cairo_move_to (cr, 0, 0);
+ cairo_line_to (cr, width, height);
+
+ cairo_perf_timer_start ();
+
+ while (loops--)
+ cairo_stroke_preserve (cr);
+
+ cairo_perf_timer_stop ();
+
+ cairo_new_path (cr);
+
+ return cairo_perf_timer_elapsed ();
+}
+
+static cairo_time_t
+diagonal_hair (cairo_t *cr, int width, int height, int loops)
+{
+ cairo_set_line_width (cr, 1.);
+ return diagonal (cr, width, height, loops);
+}
+
+static cairo_time_t
+diagonal_wide (cairo_t *cr, int width, int height, int loops)
+{
+ cairo_set_line_width (cr, 5.);
+ return diagonal (cr, width, height, loops);
+}
+
+cairo_bool_t
+line_enabled (cairo_perf_t *perf)
+{
+ return cairo_perf_can_run (perf, "line", NULL);
+}
+
+void
+line (cairo_perf_t *perf, cairo_t *cr, int width, int height)
+{
+ cairo_set_source_rgb (cr, 1., 1., 1.);
+
+ cairo_perf_run (perf, "line-hh", horizontal_hair, NULL);
+ cairo_perf_run (perf, "line-hw", horizontal_wide, NULL);
+ cairo_perf_run (perf, "line-nhh", nearly_horizontal_hair, NULL);
+ cairo_perf_run (perf, "line-nhw", nearly_horizontal_wide, NULL);
+
+ cairo_perf_run (perf, "line-vh", vertical_hair, NULL);
+ cairo_perf_run (perf, "line-vw", vertical_wide, NULL);
+ cairo_perf_run (perf, "line-nvh", nearly_vertical_hair, NULL);
+ cairo_perf_run (perf, "line-nvw", nearly_vertical_wide, NULL);
+
+ cairo_perf_run (perf, "line-dh", diagonal_hair, NULL);
+ cairo_perf_run (perf, "line-dw", diagonal_wide, NULL);
+}
diff --git a/perf/micro/long-dashed-lines.c b/perf/micro/long-dashed-lines.c
new file mode 100644
index 000000000..ba66a4af4
--- /dev/null
+++ b/perf/micro/long-dashed-lines.c
@@ -0,0 +1,74 @@
+/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
+/*
+ * Copyright © 2007 Mozilla Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Vladimir Vukicevic <vladimir@pobox.com>
+ */
+
+#include "cairo-perf.h"
+
+static cairo_time_t
+do_long_dashed_lines (cairo_t *cr, int width, int height, int loops)
+{
+ double dash[2] = { 2.0, 2.0 };
+ int i;
+
+ cairo_save (cr);
+ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
+ cairo_paint (cr);
+
+ cairo_set_source_rgb (cr, 1.0, 0.0, 0.0);
+ cairo_set_dash (cr, dash, 2, 0.0);
+
+ cairo_new_path (cr);
+ cairo_set_line_width (cr, 1.0);
+
+ for (i = 0; i < height-1; i++) {
+ double y0 = (double) i + 0.5;
+ cairo_move_to (cr, 0.0, y0);
+ cairo_line_to (cr, width, y0);
+ }
+
+ cairo_perf_timer_start ();
+
+ while (loops--)
+ cairo_stroke_preserve (cr);
+
+ cairo_perf_timer_stop ();
+
+ cairo_restore (cr);
+
+ return cairo_perf_timer_elapsed ();
+}
+
+cairo_bool_t
+long_dashed_lines_enabled (cairo_perf_t *perf)
+{
+ return cairo_perf_can_run (perf, "long-dashed-lines", NULL);
+}
+
+void
+long_dashed_lines (cairo_perf_t *perf, cairo_t *cr, int width, int height)
+{
+ cairo_perf_run (perf, "long-dashed-lines", do_long_dashed_lines, NULL);
+}
diff --git a/perf/micro/long-lines.c b/perf/micro/long-lines.c
new file mode 100644
index 000000000..a0d134c2d
--- /dev/null
+++ b/perf/micro/long-lines.c
@@ -0,0 +1,148 @@
+/*
+ * Copyright © 2006 Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+#include "cairo-perf.h"
+
+/* This test case is designed to illustrate a performance bug in
+ * drawing very long lines, where most of the line is out of bounds of
+ * the destination surface, (but some portion of the line is
+ * visibile). These results are in the "long-lines-uncropped" report.
+ *
+ * For comparison, this test also renders the visible portions of the
+ * same lines, (this is the "long-lines-cropped" report).
+ */
+
+typedef enum {
+ LONG_LINES_CROPPED = 0x1,
+ LONG_LINES_ONCE = 0x2,
+} long_lines_crop_t;
+#define NUM_LINES 20
+#define LONG_FACTOR 50.0
+
+static cairo_time_t
+do_long_lines (cairo_t *cr, int width, int height, int loops, long_lines_crop_t crop)
+{
+ int i;
+ double x, y, dx, dy, min_x, min_y, max_x, max_y;
+ double outer_width, outer_height;
+
+ cairo_save (cr);
+
+ cairo_translate (cr, width / 2, height / 2);
+
+ if (crop & LONG_LINES_CROPPED) {
+ outer_width = width;
+ outer_height = height;
+ cairo_set_source_rgb (cr, 0.0, 1.0, 0.0); /* green */
+ } else {
+ outer_width = LONG_FACTOR * width;
+ outer_height = LONG_FACTOR * height;
+ cairo_set_source_rgb (cr, 1.0, 0.0, 0.0); /* red */
+ }
+
+ min_x = x = - outer_width / 2.0;
+ min_y = y = - outer_height / 2.0;
+ max_x = outer_width / 2.0;
+ max_y = outer_height / 2.0;
+ dx = outer_width / NUM_LINES;
+ dy = outer_height / NUM_LINES;
+
+ cairo_perf_timer_start ();
+
+ while (loops--) {
+ for (i = 0; i <= NUM_LINES; i++) {
+ cairo_move_to (cr, 0, 0);
+ cairo_line_to (cr, x, min_y);
+ if ((crop & LONG_LINES_ONCE) == 0)
+ cairo_stroke (cr);
+
+ cairo_move_to (cr, 0, 0);
+ cairo_line_to (cr, x, max_y);
+ if ((crop & LONG_LINES_ONCE) == 0)
+ cairo_stroke (cr);
+
+ cairo_move_to (cr, 0, 0);
+ cairo_line_to (cr, min_x, y);
+ if ((crop & LONG_LINES_ONCE) == 0)
+ cairo_stroke (cr);
+
+ cairo_move_to (cr, 0, 0);
+ cairo_line_to (cr, max_x, y);
+ if ((crop & LONG_LINES_ONCE) == 0)
+ cairo_stroke (cr);
+
+ x += dx;
+ y += dy;
+ }
+ if (crop & LONG_LINES_ONCE)
+ cairo_stroke (cr);
+ }
+
+ cairo_perf_timer_stop ();
+
+ cairo_restore (cr);
+
+ return cairo_perf_timer_elapsed ();
+}
+
+static cairo_time_t
+long_lines_uncropped (cairo_t *cr, int width, int height, int loops)
+{
+ return do_long_lines (cr, width, height, loops, 0);
+}
+
+static cairo_time_t
+long_lines_uncropped_once (cairo_t *cr, int width, int height, int loops)
+{
+ return do_long_lines (cr, width, height, loops, LONG_LINES_ONCE);
+}
+
+static cairo_time_t
+long_lines_cropped (cairo_t *cr, int width, int height, int loops)
+{
+ return do_long_lines (cr, width, height, loops, LONG_LINES_CROPPED);
+}
+
+static cairo_time_t
+long_lines_cropped_once (cairo_t *cr, int width, int height, int loops)
+{
+ return do_long_lines (cr, width, height, loops, LONG_LINES_CROPPED | LONG_LINES_ONCE);
+}
+
+cairo_bool_t
+long_lines_enabled (cairo_perf_t *perf)
+{
+ return cairo_perf_can_run (perf, "long-lines", NULL);
+}
+
+void
+long_lines (cairo_perf_t *perf, cairo_t *cr, int width, int height)
+{
+ cairo_perf_run (perf, "long-lines-uncropped", long_lines_uncropped, NULL);
+ cairo_perf_run (perf, "long-lines-uncropped-once", long_lines_uncropped_once, NULL);
+ cairo_perf_run (perf, "long-lines-cropped", long_lines_cropped, NULL);
+ cairo_perf_run (perf, "long-lines-cropped-once", long_lines_cropped_once, NULL);
+}
diff --git a/perf/micro/many-curves.c b/perf/micro/many-curves.c
new file mode 100644
index 000000000..f985d349a
--- /dev/null
+++ b/perf/micro/many-curves.c
@@ -0,0 +1,135 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-perf.h"
+
+static uint32_t state;
+
+static double
+uniform_random (double minval, double maxval)
+{
+ static uint32_t const poly = 0x9a795537U;
+ uint32_t n = 32;
+ while (n-->0)
+ state = 2*state < state ? (2*state ^ poly) : 2*state;
+ return minval + state * (maxval - minval) / 4294967296.0;
+}
+
+static cairo_time_t
+do_many_curves_stroked (cairo_t *cr, int width, int height, int loops)
+{
+ int count;
+
+ state = 0xc0ffee;
+ cairo_move_to (cr, uniform_random (0, width), uniform_random (0, height));
+ for (count = 0; count < 1000; count++) {
+ double x1 = uniform_random (0, width);
+ double x2 = uniform_random (0, width);
+ double x3 = uniform_random (0, width);
+ double y1 = uniform_random (0, height);
+ double y2 = uniform_random (0, height);
+ double y3 = uniform_random (0, height);
+ cairo_curve_to (cr, x1, y1, x2, y2, x3, y3);
+ }
+
+ cairo_perf_timer_start ();
+
+ while (loops--)
+ cairo_stroke_preserve (cr);
+
+ cairo_perf_timer_stop ();
+
+ cairo_new_path (cr);
+
+ return cairo_perf_timer_elapsed ();
+}
+
+static cairo_time_t
+do_many_curves_hair_stroked (cairo_t *cr, int width, int height, int loops)
+{
+ cairo_set_line_width (cr, 1.);
+ return do_many_curves_stroked (cr, width, height, loops);
+}
+
+static cairo_time_t
+do_many_curves_wide_stroked (cairo_t *cr, int width, int height, int loops)
+{
+ cairo_set_line_width (cr, 5.);
+ return do_many_curves_stroked (cr, width, height, loops);
+}
+
+static cairo_time_t
+do_many_curves_filled (cairo_t *cr, int width, int height, int loops)
+{
+ int count;
+
+ state = 0xc0ffee;
+ for (count = 0; count < 1000; count++) {
+ double x0 = uniform_random (0, width);
+ double x1 = uniform_random (0, width);
+ double x2 = uniform_random (0, width);
+ double x3 = uniform_random (0, width);
+ double xm = uniform_random (0, width);
+ double xn = uniform_random (0, width);
+ double y0 = uniform_random (0, height);
+ double y1 = uniform_random (0, height);
+ double y2 = uniform_random (0, height);
+ double y3 = uniform_random (0, height);
+ double ym = uniform_random (0, height);
+ double yn = uniform_random (0, height);
+ cairo_move_to (cr, xm, ym);
+ cairo_curve_to (cr, x1, y1, x2, y2, xn, yn);
+ cairo_curve_to (cr, x3, y3, x0, y0, xm, ym);
+ cairo_close_path (cr);
+ }
+
+ cairo_perf_timer_start ();
+
+ while (loops--)
+ cairo_fill_preserve (cr);
+
+ cairo_perf_timer_stop ();
+
+ cairo_new_path (cr);
+
+ return cairo_perf_timer_elapsed ();
+}
+
+cairo_bool_t
+many_curves_enabled (cairo_perf_t *perf)
+{
+ return cairo_perf_can_run (perf, "many-curves", NULL);
+}
+
+void
+many_curves (cairo_perf_t *perf, cairo_t *cr, int width, int height)
+{
+ cairo_set_source_rgb (cr, 1., 1., 1.);
+
+ cairo_perf_run (perf, "many-curves-hair-stroked", do_many_curves_hair_stroked, NULL);
+ cairo_perf_run (perf, "many-curves-wide-stroked", do_many_curves_wide_stroked, NULL);
+ cairo_perf_run (perf, "many-curves-filled", do_many_curves_filled, NULL);
+}
diff --git a/perf/micro/many-fills.c b/perf/micro/many-fills.c
new file mode 100644
index 000000000..9d3fd6435
--- /dev/null
+++ b/perf/micro/many-fills.c
@@ -0,0 +1,187 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+
+/* This is a variant on many strokes where we precompute
+ * a simplified stroke-to-path.
+ * When we have a real stroke-to-path, it would useful to compare the cost
+ * of stroking vs filling the "identical" paths.
+ */
+
+#include "cairo-perf.h"
+
+static uint32_t state;
+
+static double
+uniform_random (double minval, double maxval)
+{
+ static uint32_t const poly = 0x9a795537U;
+ uint32_t n = 32;
+ while (n-->0)
+ state = 2*state < state ? (2*state ^ poly) : 2*state;
+ return minval + state * (maxval - minval) / 4294967296.0;
+}
+
+static cairo_time_t
+do_many_fills_ha (cairo_t *cr, int width, int height, int loops)
+{
+ int count;
+
+ state = 0xc0ffee;
+ for (count = 0; count < 1000; count++) {
+ double y = floor (uniform_random (0, height));
+ double x = floor (uniform_random (0, width));
+ cairo_rectangle (cr, x, y, ceil (uniform_random (0, width)) - x, 1);
+ }
+
+ cairo_perf_timer_start ();
+
+ while (loops--)
+ cairo_fill_preserve (cr);
+
+ cairo_perf_timer_stop ();
+
+ cairo_new_path (cr);
+
+ return cairo_perf_timer_elapsed ();
+}
+
+static cairo_time_t
+do_many_fills_h (cairo_t *cr, int width, int height, int loops)
+{
+ int count;
+
+ state = 0xc0ffee;
+ for (count = 0; count < 1000; count++) {
+ double y = uniform_random (0, height);
+ double x = uniform_random (0, width);
+ cairo_rectangle (cr, x, y, uniform_random (0, width) - x, 1);
+ }
+
+ cairo_perf_timer_start ();
+
+ while (loops--)
+ cairo_fill_preserve (cr);
+
+ cairo_perf_timer_stop ();
+
+ cairo_new_path (cr);
+
+ return cairo_perf_timer_elapsed ();
+}
+
+static cairo_time_t
+do_many_fills_va (cairo_t *cr, int width, int height, int loops)
+{
+ int count;
+
+ state = 0xc0ffee;
+ for (count = 0; count < 1000; count++) {
+ double x = floor (uniform_random (0, width));
+ double y = floor (uniform_random (0, height));
+ cairo_rectangle (cr, x, y, 1, ceil (uniform_random (0, height) - y));
+ }
+
+ cairo_perf_timer_start ();
+
+ while (loops--)
+ cairo_fill_preserve (cr);
+
+ cairo_perf_timer_stop ();
+
+ cairo_new_path (cr);
+
+ return cairo_perf_timer_elapsed ();
+}
+
+static cairo_time_t
+do_many_fills_v (cairo_t *cr, int width, int height, int loops)
+{
+ int count;
+
+ state = 0xc0ffee;
+ for (count = 0; count < 1000; count++) {
+ double x = uniform_random (0, width);
+ double y = uniform_random (0, height);
+ cairo_rectangle (cr, x, y, 1, uniform_random (0, height) - y);
+ }
+
+ cairo_perf_timer_start ();
+
+ while (loops--)
+ cairo_fill_preserve (cr);
+
+ cairo_perf_timer_stop ();
+
+ cairo_new_path (cr);
+
+ return cairo_perf_timer_elapsed ();
+}
+
+static cairo_time_t
+do_many_fills (cairo_t *cr, int width, int height, int loops)
+{
+ int count;
+
+ /* lots and lots of overlapping stroke-like fills */
+ state = 0xc0ffee;
+ for (count = 0; count < 1000; count++) {
+ cairo_save (cr);
+ cairo_translate (cr,
+ uniform_random (0, width),
+ uniform_random (0, height));
+ cairo_rotate (cr, uniform_random (-M_PI,M_PI));
+ cairo_rectangle (cr, 0, 0, uniform_random (0, width), 1);
+ cairo_restore (cr);
+ }
+
+ cairo_perf_timer_start ();
+
+ while (loops--)
+ cairo_fill_preserve (cr);
+
+ cairo_perf_timer_stop ();
+
+ cairo_new_path (cr);
+
+ return cairo_perf_timer_elapsed ();
+}
+
+cairo_bool_t
+many_fills_enabled (cairo_perf_t *perf)
+{
+ return cairo_perf_can_run (perf, "many-fills", NULL);
+}
+
+void
+many_fills (cairo_perf_t *perf, cairo_t *cr, int width, int height)
+{
+ cairo_perf_run (perf, "many-fills-halign", do_many_fills_ha, NULL);
+ cairo_perf_run (perf, "many-fills-valign", do_many_fills_va, NULL);
+ cairo_perf_run (perf, "many-fills-horizontal", do_many_fills_h, NULL);
+ cairo_perf_run (perf, "many-fills-vertical", do_many_fills_v, NULL);
+ cairo_perf_run (perf, "many-fills-random", do_many_fills, NULL);
+}
diff --git a/perf/micro/many-strokes.c b/perf/micro/many-strokes.c
new file mode 100644
index 000000000..9aeb393de
--- /dev/null
+++ b/perf/micro/many-strokes.c
@@ -0,0 +1,186 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-perf.h"
+
+static uint32_t state;
+
+static double
+uniform_random (double minval, double maxval)
+{
+ static uint32_t const poly = 0x9a795537U;
+ uint32_t n = 32;
+ while (n-->0)
+ state = 2*state < state ? (2*state ^ poly) : 2*state;
+ return minval + state * (maxval - minval) / 4294967296.0;
+}
+
+static cairo_time_t
+do_many_strokes_ha (cairo_t *cr, int width, int height, int loops)
+{
+ int count;
+
+ state = 0xc0ffee;
+ for (count = 0; count < 1000; count++) {
+ double h = floor (uniform_random (0, height)) + .5;
+ cairo_move_to (cr, floor (uniform_random (0, width)), h);
+ cairo_line_to (cr, ceil (uniform_random (0, width)), h);
+ }
+
+ cairo_set_line_width (cr, 1.);
+
+ cairo_perf_timer_start ();
+
+ while (loops--)
+ cairo_stroke_preserve (cr);
+
+ cairo_perf_timer_stop ();
+
+ cairo_new_path (cr);
+
+ return cairo_perf_timer_elapsed ();
+}
+
+static cairo_time_t
+do_many_strokes_h (cairo_t *cr, int width, int height, int loops)
+{
+ int count;
+
+ state = 0xc0ffee;
+ for (count = 0; count < 1000; count++) {
+ double h = uniform_random (0, height);
+ cairo_move_to (cr, uniform_random (0, width), h);
+ cairo_line_to (cr, uniform_random (0, width), h);
+ }
+
+ cairo_set_line_width (cr, 1.);
+
+ cairo_perf_timer_start ();
+
+ while (loops--)
+ cairo_stroke_preserve (cr);
+
+ cairo_perf_timer_stop ();
+
+ cairo_new_path (cr);
+
+ return cairo_perf_timer_elapsed ();
+}
+
+static cairo_time_t
+do_many_strokes_va (cairo_t *cr, int width, int height, int loops)
+{
+ int count;
+
+ state = 0xc0ffee;
+ for (count = 0; count < 1000; count++) {
+ double v = floor (uniform_random (0, width)) + .5;
+ cairo_move_to (cr, v, floor (uniform_random (0, height)));
+ cairo_line_to (cr, v, ceil (uniform_random (0, height)));
+ }
+
+ cairo_set_line_width (cr, 1.);
+
+ cairo_perf_timer_start ();
+
+ while (loops--)
+ cairo_stroke_preserve (cr);
+
+ cairo_perf_timer_stop ();
+
+ cairo_new_path (cr);
+
+ return cairo_perf_timer_elapsed ();
+}
+
+static cairo_time_t
+do_many_strokes_v (cairo_t *cr, int width, int height, int loops)
+{
+ int count;
+
+ state = 0xc0ffee;
+ for (count = 0; count < 1000; count++) {
+ double v = uniform_random (0, width);
+ cairo_move_to (cr, v, uniform_random (0, height));
+ cairo_line_to (cr, v, uniform_random (0, height));
+ }
+
+ cairo_set_line_width (cr, 1.);
+
+ cairo_perf_timer_start ();
+
+ while (loops--)
+ cairo_stroke_preserve (cr);
+
+ cairo_perf_timer_stop ();
+
+ cairo_new_path (cr);
+
+ return cairo_perf_timer_elapsed ();
+}
+
+static cairo_time_t
+do_many_strokes (cairo_t *cr, int width, int height, int loops)
+{
+ int count;
+
+ /* lots and lots of overlapping strokes */
+ state = 0xc0ffee;
+ for (count = 0; count < 1000; count++) {
+ cairo_line_to (cr,
+ uniform_random (0, width),
+ uniform_random (0, height));
+ }
+
+ cairo_set_line_width (cr, 1.);
+
+ cairo_perf_timer_start ();
+
+ while (loops--)
+ cairo_stroke_preserve (cr);
+
+ cairo_perf_timer_stop ();
+
+ cairo_new_path (cr);
+
+ return cairo_perf_timer_elapsed ();
+}
+
+cairo_bool_t
+many_strokes_enabled (cairo_perf_t *perf)
+{
+ return cairo_perf_can_run (perf, "many-strokes", NULL);
+}
+
+void
+many_strokes (cairo_perf_t *perf, cairo_t *cr, int width, int height)
+{
+ cairo_perf_run (perf, "many-strokes-halign", do_many_strokes_ha, NULL);
+ cairo_perf_run (perf, "many-strokes-valign", do_many_strokes_va, NULL);
+ cairo_perf_run (perf, "many-strokes-horizontal", do_many_strokes_h, NULL);
+ cairo_perf_run (perf, "many-strokes-vertical", do_many_strokes_v, NULL);
+ cairo_perf_run (perf, "many-strokes-random", do_many_strokes, NULL);
+}
diff --git a/perf/micro/mask.c b/perf/micro/mask.c
new file mode 100644
index 000000000..11a3ba730
--- /dev/null
+++ b/perf/micro/mask.c
@@ -0,0 +1,305 @@
+/*
+ * Copyright © 2006 Red Hat, Inc.
+ * Copyright © 2009 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ * Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-perf.h"
+
+static cairo_time_t
+do_mask_solid (cairo_t *cr, int width, int height, int loops)
+{
+ cairo_pattern_t *mask;
+
+ mask = cairo_pattern_create_rgba (0, 0, 0, .5);
+
+ cairo_perf_timer_start ();
+
+ while (loops--)
+ cairo_mask (cr, mask);
+
+ cairo_perf_timer_stop ();
+
+ cairo_pattern_destroy (mask);
+
+ return cairo_perf_timer_elapsed ();
+}
+
+static cairo_surface_t *
+init_surface (cairo_surface_t *surface, int width, int height)
+{
+ cairo_t *cr;
+
+ cr = cairo_create (surface);
+ cairo_surface_destroy (surface);
+
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_set_source_rgb (cr, 0, 0, 0); /* back */
+ cairo_paint (cr);
+
+ cairo_set_source_rgba (cr, 1, 1, 1, 0.5); /* 50% */
+ cairo_new_path (cr);
+ cairo_rectangle (cr, 0, 0, width/2.0, height/2.0);
+ cairo_rectangle (cr, width/2.0, height/2.0, width/2.0, height/2.0);
+ cairo_fill (cr);
+
+ surface = cairo_surface_reference (cairo_get_target (cr));
+ cairo_destroy (cr);
+
+ return surface;
+}
+
+static cairo_time_t
+do_mask_image (cairo_t *cr, int width, int height, int loops)
+{
+ cairo_surface_t *surface;
+ cairo_pattern_t *mask;
+
+ surface = cairo_image_surface_create (CAIRO_FORMAT_A8, width, height);
+ mask = cairo_pattern_create_for_surface (init_surface (surface,
+ width,
+ height));
+ cairo_surface_destroy (surface);
+
+ cairo_perf_timer_start ();
+
+ while (loops--)
+ cairo_mask (cr, mask);
+
+ cairo_perf_timer_stop ();
+
+ cairo_pattern_destroy (mask);
+
+ return cairo_perf_timer_elapsed ();
+}
+
+static cairo_time_t
+do_mask_image_half (cairo_t *cr, int width, int height, int loops)
+{
+ cairo_surface_t *surface;
+ cairo_pattern_t *mask;
+ cairo_matrix_t matrix;
+
+ surface = cairo_image_surface_create (CAIRO_FORMAT_A8, width, height);
+ mask = cairo_pattern_create_for_surface (init_surface (surface,
+ width,
+ height));
+ cairo_surface_destroy (surface);
+ cairo_matrix_init_scale (&matrix, .5, .5);
+ cairo_pattern_set_matrix (mask, &matrix);
+
+ cairo_perf_timer_start ();
+
+ while (loops--)
+ cairo_mask (cr, mask);
+
+ cairo_perf_timer_stop ();
+
+ cairo_pattern_destroy (mask);
+
+ return cairo_perf_timer_elapsed ();
+}
+
+static cairo_time_t
+do_mask_image_double (cairo_t *cr, int width, int height, int loops)
+{
+ cairo_surface_t *surface;
+ cairo_pattern_t *mask;
+ cairo_matrix_t matrix;
+
+ surface = cairo_image_surface_create (CAIRO_FORMAT_A8, width, height);
+ mask = cairo_pattern_create_for_surface (init_surface (surface,
+ width,
+ height));
+ cairo_surface_destroy (surface);
+ cairo_matrix_init_scale (&matrix, 2., 2.);
+ cairo_pattern_set_matrix (mask, &matrix);
+
+ cairo_perf_timer_start ();
+
+ while (loops--)
+ cairo_mask (cr, mask);
+
+ cairo_perf_timer_stop ();
+
+ cairo_pattern_destroy (mask);
+
+ return cairo_perf_timer_elapsed ();
+}
+
+static cairo_time_t
+do_mask_similar (cairo_t *cr, int width, int height, int loops)
+{
+ cairo_surface_t *surface;
+ cairo_pattern_t *mask;
+
+ surface = cairo_surface_create_similar (cairo_get_group_target (cr),
+ CAIRO_CONTENT_ALPHA, width, height);
+ mask = cairo_pattern_create_for_surface (init_surface (surface,
+ width,
+ height));
+ cairo_surface_destroy (surface);
+
+ cairo_perf_timer_start ();
+
+ while (loops--)
+ cairo_mask (cr, mask);
+
+ cairo_perf_timer_stop ();
+
+ cairo_pattern_destroy (mask);
+
+ return cairo_perf_timer_elapsed ();
+}
+
+static cairo_time_t
+do_mask_similar_half (cairo_t *cr, int width, int height, int loops)
+{
+ cairo_surface_t *surface;
+ cairo_pattern_t *mask;
+ cairo_matrix_t matrix;
+
+ surface = cairo_surface_create_similar (cairo_get_group_target (cr),
+ CAIRO_CONTENT_ALPHA, width, height);
+ mask = cairo_pattern_create_for_surface (init_surface (surface,
+ width,
+ height));
+ cairo_surface_destroy (surface);
+ cairo_matrix_init_scale (&matrix, .5, .5);
+ cairo_pattern_set_matrix (mask, &matrix);
+
+ cairo_perf_timer_start ();
+
+ while (loops--)
+ cairo_mask (cr, mask);
+
+ cairo_perf_timer_stop ();
+
+ cairo_pattern_destroy (mask);
+
+ return cairo_perf_timer_elapsed ();
+}
+
+static cairo_time_t
+do_mask_similar_double (cairo_t *cr, int width, int height, int loops)
+{
+ cairo_surface_t *surface;
+ cairo_pattern_t *mask;
+ cairo_matrix_t matrix;
+
+ surface = cairo_surface_create_similar (cairo_get_group_target (cr),
+ CAIRO_CONTENT_ALPHA, width, height);
+ mask = cairo_pattern_create_for_surface (init_surface (surface,
+ width,
+ height));
+ cairo_surface_destroy (surface);
+ cairo_matrix_init_scale (&matrix, 2., 2.);
+ cairo_pattern_set_matrix (mask, &matrix);
+
+ cairo_perf_timer_start ();
+
+ while (loops--)
+ cairo_mask (cr, mask);
+
+ cairo_perf_timer_stop ();
+
+ cairo_pattern_destroy (mask);
+
+ return cairo_perf_timer_elapsed ();
+}
+
+static cairo_time_t
+do_mask_linear (cairo_t *cr, int width, int height, int loops)
+{
+ cairo_pattern_t *mask;
+
+ mask = cairo_pattern_create_linear (0.0, 0.0, width, height);
+ cairo_pattern_add_color_stop_rgba (mask, 0.0, 0, 0, 0, 0.5); /* 50% */
+ cairo_pattern_add_color_stop_rgba (mask, 0.0, 0, 0, 0, 1.0); /* 100% */
+
+ cairo_perf_timer_start ();
+
+ while (loops--)
+ cairo_mask (cr, mask);
+
+ cairo_perf_timer_stop ();
+
+ cairo_pattern_destroy (mask);
+
+ return cairo_perf_timer_elapsed ();
+}
+
+static cairo_time_t
+do_mask_radial (cairo_t *cr, int width, int height, int loops)
+{
+ cairo_pattern_t *mask;
+
+ mask = cairo_pattern_create_radial (width/2.0, height/2.0, 0.0,
+ width/2.0, height/2.0, width/2.0);
+ cairo_pattern_add_color_stop_rgba (mask, 0.0, 0, 0, 0, 0.5); /* 50% */
+ cairo_pattern_add_color_stop_rgba (mask, 0.0, 0, 0, 0, 1.0); /* 100% */
+
+ cairo_perf_timer_start ();
+
+ while (loops--)
+ cairo_mask (cr, mask);
+
+ cairo_perf_timer_stop ();
+
+ cairo_pattern_destroy (mask);
+
+ return cairo_perf_timer_elapsed ();
+}
+
+cairo_bool_t
+mask_enabled (cairo_perf_t *perf)
+{
+ return cairo_perf_can_run (perf, "mask", NULL);
+}
+
+void
+mask (cairo_perf_t *perf, cairo_t *cr, int width, int height)
+{
+ if (! cairo_perf_can_run (perf, "mask", NULL))
+ return;
+
+ cairo_perf_cover_sources_and_operators (perf, "mask-solid",
+ do_mask_solid, NULL);
+ cairo_perf_cover_sources_and_operators (perf, "mask-image",
+ do_mask_image, NULL);
+ cairo_perf_cover_sources_and_operators (perf, "mask-image-half",
+ do_mask_image_half, NULL);
+ cairo_perf_cover_sources_and_operators (perf, "mask-image-double",
+ do_mask_image_double, NULL);
+ cairo_perf_cover_sources_and_operators (perf, "mask-similar",
+ do_mask_similar, NULL);
+ cairo_perf_cover_sources_and_operators (perf, "mask-similar-half",
+ do_mask_similar_half, NULL);
+ cairo_perf_cover_sources_and_operators (perf, "mask-similar-double",
+ do_mask_similar_double, NULL);
+ cairo_perf_cover_sources_and_operators (perf, "mask-linear",
+ do_mask_linear, NULL);
+ cairo_perf_cover_sources_and_operators (perf, "mask-radial",
+ do_mask_radial, NULL);
+}
diff --git a/perf/micro/mosaic.c b/perf/micro/mosaic.c
new file mode 100644
index 000000000..ed30ae555
--- /dev/null
+++ b/perf/micro/mosaic.c
@@ -0,0 +1,176 @@
+/*
+ * Copyright © 2006 Joonas Pihlaja
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Joonas Pihlaja <jpihlaja@cc.helsinki.fi>
+ */
+#include "cairo-perf.h"
+
+/* Options passed in flags to mosaic_perform(): */
+#define MOSAIC_FILL 1 /* do rasterise */
+#define MOSAIC_TESSELLATE 0 /* just tessellate */
+#define MOSAIC_CURVE_TO 2 /* use curve bounded regions */
+#define MOSAIC_LINE_TO 0 /* use line bounded regions */
+
+struct mosaic_region {
+ unsigned rgb; /* colour of this region in 0xRRGGBB format */
+ unsigned ncurves; /* number of boundary curves. */
+};
+
+struct mosaic_region_iter {
+ int do_curves;
+ struct mosaic_region const *region;
+ double const *points;
+};
+
+#include "mosaic.h"
+
+static void
+mosaic_region_iter_init (struct mosaic_region_iter *iter, int do_curves)
+{
+ iter->region = mosaic_regions;
+ iter->points = mosaic_curve_points;
+ iter->do_curves = do_curves;
+}
+
+/* Create the next closed region as a path. */
+static int
+mosaic_next_path (cairo_t *cr, struct mosaic_region_iter *iter)
+{
+ double const *points = iter->points;
+ unsigned i;
+ unsigned ncurves = iter->region->ncurves;
+ if (0 == ncurves) {
+ return 0;
+ }
+
+ cairo_new_path (cr);
+ cairo_move_to (cr, points[0], points[1]);
+ points += 2;
+ for (i=0; i < ncurves; i++, points += 6) {
+ if (iter->do_curves) {
+ cairo_curve_to (cr,
+ points[0], points[1],
+ points[2], points[3],
+ points[4], points[5]);
+ }
+ else {
+ cairo_line_to (cr,
+ points[4], points[5]);
+ }
+ }
+ cairo_close_path (cr);
+ {
+ unsigned rgb = iter->region->rgb;
+ double r = ((rgb >> 16) & 255) / 255.0;
+ double g = ((rgb >> 8) & 255) / 255.0;
+ double b = ((rgb >> 0) & 255) / 255.0;
+ cairo_set_source_rgb (cr, r, g, b);
+ }
+
+ iter->points = iter->points + 2*(1 + 3*iter->region->ncurves);
+ iter->region++;
+ return 1;
+}
+
+static cairo_time_t
+mosaic_perform(cairo_t *cr, unsigned flags, int width, int height, int loops)
+{
+ struct mosaic_region_iter iter;
+
+ /* Scale to fit the window.*/
+ double minx = -40.7;
+ double maxx = 955.1;
+ double miny = -88.4;
+ double maxy = 884.5;
+
+ cairo_identity_matrix (cr);
+
+ if (flags & MOSAIC_FILL) {
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_rectangle (cr, 0, 0, width, height);
+ cairo_fill (cr);
+ }
+
+ cairo_scale (cr, width / (maxx - minx) , height / (maxy - miny));
+ cairo_translate (cr, -minx, -miny);
+
+ /* Iterate over all closed regions in the mosaic filling or
+ * tessellating them as dictated by the flags. */
+
+ cairo_perf_timer_start ();
+ while (loops--) {
+ mosaic_region_iter_init (&iter, flags & MOSAIC_CURVE_TO);
+ while (mosaic_next_path (cr, &iter)) {
+ if (flags & MOSAIC_FILL) {
+ cairo_fill (cr);
+ }
+ else {
+ double x, y;
+ cairo_get_current_point (cr, &x, &y);
+ cairo_in_fill (cr, x, y);
+ }
+ }
+ }
+ cairo_perf_timer_stop ();
+
+ return cairo_perf_timer_elapsed ();
+}
+
+static cairo_time_t
+mosaic_fill_curves (cairo_t *cr, int width, int height, int loops)
+{
+ return mosaic_perform (cr, MOSAIC_FILL | MOSAIC_CURVE_TO, width, height, loops);
+}
+
+static cairo_time_t
+mosaic_fill_lines (cairo_t *cr, int width, int height, int loops)
+{
+ return mosaic_perform (cr, MOSAIC_FILL | MOSAIC_LINE_TO, width, height, loops);
+}
+
+static cairo_time_t
+mosaic_tessellate_lines (cairo_t *cr, int width, int height, int loops)
+{
+ return mosaic_perform (cr, MOSAIC_TESSELLATE | MOSAIC_LINE_TO, width, height, loops);
+}
+
+static cairo_time_t
+mosaic_tessellate_curves (cairo_t *cr, int width, int height, int loops)
+{
+ return mosaic_perform (cr, MOSAIC_TESSELLATE | MOSAIC_CURVE_TO, width, height, loops);
+}
+
+cairo_bool_t
+mosaic_enabled (cairo_perf_t *perf)
+{
+ return cairo_perf_can_run (perf, "mosaic", NULL);
+}
+
+void
+mosaic (cairo_perf_t *perf, cairo_t *cr, int width, int height)
+{
+ cairo_perf_run (perf, "mosaic-fill-curves", mosaic_fill_curves, NULL);
+ cairo_perf_run (perf, "mosaic-fill-lines", mosaic_fill_lines, NULL);
+ cairo_perf_run (perf, "mosaic-tessellate-curves", mosaic_tessellate_curves, NULL);
+ cairo_perf_run (perf, "mosaic-tessellate-lines", mosaic_tessellate_lines, NULL);
+}
diff --git a/perf/micro/mosaic.h b/perf/micro/mosaic.h
new file mode 100644
index 000000000..e106864a3
--- /dev/null
+++ b/perf/micro/mosaic.h
@@ -0,0 +1,4387 @@
+/* Synthesised data. */
+static struct mosaic_region const mosaic_regions[] = {
+{0xef55b4,7},{0xf93bc6,11},{0xf28085,5},{0x92acbc,7},
+{0x85c3b1,7},{0xc3bc79,5},{0xd09d8d,5},{0xa788cb,8},
+{0xeff90f,14},{0x976ef2,4},{0xf230d8,5},{0xe226ef,6},
+{0xf49571,9},{0xcb6cc1,4},{0xc8af80,5},{0xf71ce7,8},
+{0xd38b9a,6},{0xf70ff2,8},{0xec907e,4},{0xf44abc,5},
+{0xf42bd8,7},{0xcbbc71,5},{0xf7a45f,5},{0xb15aec,3},
+{0xfc6995,9},{0x42bef9,7},{0x83afc6,5},{0xbe9f9a,6},
+{0x95ef76,6},{0xfcc33b,20},{0xbc5ae2,5},{0x69f997,7},
+{0x9f69f2,7},{0x79bec3,7},{0xda3de2,6},{0x76dda7,6},
+{0xc888aa,7},{0xd871b1,9},{0xda29f7,14},{0xe03dda,9},
+{0xec29e2,5},{0xd82bf4,6},{0x8b8de2,6},{0xf7af52,3},
+{0x9f69f2,7},{0xf46c9a,9},{0xf74fb1,5},{0x21eaef,9},
+{0xea769a,8},{0x0feffc,5},{0xdada45,8},{0xafce7b,6},
+{0x48bef4,6},{0x9a79e5,3},{0xe2fc1c,7},{0xc3be76,9},
+{0xb9c37e,5},{0xc6b183,10},{0xa2acac,3},{0xc395a2,4},
+{0xbc88b4,7},{0xeaf41c,5},{0xea24ea,4},{0xd038f2,5},
+{0x5ae2bc,9},{0xdac15f,8},{0x5fe5b4,6},{0xce5ad3,15},
+{0xf419ec,4},{0xa7bc97,11},{0xea4ac3,6},{0xd02ef9,5},
+{0xb995aa,5},{0xef808b,6},{0xe22bea,34},{0xe24fc6,4},
+{0xef12f9,7},{0x7b9de0,8},{0x85ec85,4},{0xfc7e80,12},
+{0x9a85d8,5},{0xfc00fc,7},{0x9d90ce,5},{0xf4be45,9},
+{0xe5e52e,3},{0xfc0cef,7},{0xd83be5,8},{0x4dc6e5,5},
+{0xacda73,9},{0x4fc8e0,6},{0xbc88b6,4},{0xb4bc8b,6},
+{0xec45c6,8},{0x71d3b6,4},{0xe73dd5,5},{0x21fcda,4},
+{0xe055c6,9},{0x3becd0,8},{0x57e0c1,5},{0x71bec8,9},
+{0x8be28b,4},{0x4dddd0,9},{0xda9a85,6},{0xaa6ce2,4},
+{0x5ad5cb,9},{0x67f49d,12},{0xfc07f7,9},{0x42c8ec,16},
+{0xefc148,4},{0xda6eb1,7},{0x55bee7,4},{0xd33bea,6},
+{0x809fd8,14},{0xd82ef2,4},{0x21ddfc,5},{0x83e097,7},
+{0x8bcba2,9},{0xd864bc,8},{0xa7d87b,6},{0xc3a78d,6},
+{0xb9a79a,8},{0xd59590,3},{0xfc0af2,6},{0xe52be7,7},
+{0xce52d8,5},{0xe22bea,4},{0xe719f7,5},{0x909fcb,3},
+{0xa7da76,6},{0xdd38e5,4},{0xfc55aa,6},{0x19f2ef,6},
+{0x83da9d,5},{0x9fc892,6},{0xe51ef4,9},{0xce3dec,5},
+{0xea3dd0,7},{0x4ad3dd,6},{0x6ea2e7,5},{0xf92bd3,4},
+{0xc34aea,8},{0x2eddef,4},{0xe7799a,8},{0xe5799a,11},
+{0xe224f2,3},{0xf90af7,6},{0x61a2f4,6},{0xb67ec6,13},
+{0xe75cb4,7},{0xfcb945,16},{0xd3b173,7},{0xfc00fc,6},
+{0xd5ef33,5},{0x699df4,9},{0xf707f9,4},{0xdaea33,6},
+{0xe2dd38,3},{0xf2d036,5},{0xf248c1,6},{0xeaf21c,5},
+{0xec40cb,7},{0xf24abc,5},{0xf42bd8,4},{0xa757f9,5},
+{0xd02ef9,6},{0xfc0cf2,7},{0xb16cda,5},{0xea36d8,8},
+{0xd036f4,7},{0xb648fc,3},{0xea4dc1,4},{0x64c8cb,7},
+{0xfc05f7,3},{0xfc00fc,4},{0xf4a75f,6},{0xc85ad5,5},
+{0xd873ac,5},{0xd5a77b,11},{0xe7c84a,4},{0xec19f4,7},
+{0xc864ce,7},{0xcece5c,5},{0xe08b8d,5},{0xd84dd3,3},
+{0x07f9f7,9},{0x5cefac,3},{0xfc02f9,4},{0xd048e0,8},
+{0xef55b6,4},{0xa269ec,7},{0xec12f9,3},{0xd380a4,11},
+{0x5fcbd0,6},{0x90c1a7,5},{0x95dd85,5},{0xceda4f,9},
+{0x4fb9f2,14},{0xb65aea,7},{0xea838d,5},{0xf917ea,4},
+{0xc833fc,9},{0xe252c3,9},{0xef0ffc,7},{0x1cf2ec,9},
+{0x9f6cef,4},{0xf73dc6,12},{0x90b6b4,5},{0xb44ff7,7},
+{0xea2be2,12},{0xd02efc,17},{0xa276e2,4},{0x79c1c1,3},
+{0xc855dd,9},{0xb1d571,8},{0xb645fc,6},{0xd03bef,6},
+{0x42eccb,9},{0xea67aa,5},{0x9079ef,6},{0x9de773,7},
+{0xe55abc,6},{0xf421e5,3},{0x5cf9a4,6},{0xc373c1,5},
+{0x5fe2b6,4},{0xea24ec,6},{0x9af967,4},{0xf7be45,5},
+{0xd333f4,5},{0xc6d061,8},{0xb96cd3,8},{0xda64b9,6},
+{0xe79779,4},{0xac67e7,6},{0xcb67c8,4},{0xa45cf7,3},
+{0xd3859f,3},{0xd857c8,4},{0x42c1f7,8},{0xaf61e7,6},
+{0xea14fc,6},{0xda33ea,10},{0x5af2af,5},{0xbe40f9,3},
+{0x9de773,3},{0xe72be5,4},{0x4ae7c6,5},{0xaa88c8,8},
+{0x36f9cb,3},{0xc1a790,8},{0xf905fc,5},{0xbcaa95,6},
+{0x839dda,3},{0xfc00fc,6},{0xb6d86c,3},{0xdd40da,6},
+{0xb46cda,7},{0x839fd5,4},{0xc167d3,13},{0xf20ff7,9},
+{0xe024f4,9},{0xf41ee5,4},{0x909ad0,10},{0xb1d376,8},
+{0xce2efc,5},{0x29d5f9,7},{0xd0b96e,6},{0xdd69b4,5},
+{0xfc05f7,5},{0xdd26f7,4},{0xea1eef,6},{0xb64df7,9},
+{0x21e5f2,3},{0x4fd8d0,6},{0xd345e0,7},{0xfc00fc,3},
+{0xe569ac,5},{0xecb655,11},{0xfc5aa2,9},{0xb4d571,7},
+{0xaa57f7,6},{0xfc00fc,7},{0xe729ea,10},{0xea24ea,11},
+{0xb14df9,5},{0xf707fc,7},{0x5cd8c3,5},{0xea17f9,9},
+{0xc3d364,6},{0xa77ed3,4},{0x9569f9,8},{0x0ff4f4,4},
+{0xbc9aa4,7},{0xc140f7,10},{0xf705fc,8},{0xb44df9,4},
+{0xa479dd,5},{0xf705fc,5},{0xce8d9d,5},{0xf905f9,5},
+{0xdd2bef,7},{0xea14f9,5},{0xddbc61,5},{0xc13dfc,8},
+{0x79c8b6,10},{0xf79a67,6},{0xb4a79f,12},{0x97a7bc,7},
+{0xb9c17e,4},{0xf430d5,3},{0x2ee0ea,7},{0xf919e7,4},
+{0xeada33,9},{0xa2da7e,7},{0x8bec80,6},{0xf412f4,5},
+{0xa767ec,3},{0xd824fc,7},{0xe224f2,3},{0xfc07f7,4},
+{0xfc00fc,3},{0xe55cb6,8},{0xf9768b,7},{0xe5b45f,3},
+{0xd5978b,4},{0xf917e7,5},{0xf70ff4,7},{0x95e283,6},
+{0xb4b98d,5},{0xc83bf4,8},{0x9f88d3,7},{0xa473e0,9},
+{0x9569fc,10},{0x926cf9,7},{0xef14f4,7},{0xf7679a,4},
+{0xaa80ce,9},{0x45f9b9,5},{0xb4a2a2,10},{0xac88c6,5},
+{0xe75ab6,6},{0xa2fc5a,3},{0xc65cd8,7},{0x64e0b6,5},
+{0xfc6992,7},{0xf717ec,4},{0xf438ce,10},{0xf755ac,4},
+{0xf7aa57,6},{0xb9b688,3},{0xcb4de2,4},{0xf9f70a,9},
+{0x92d392,8},{0xef2be0,7},{0x92a7be,4},{0xa276e2,4},
+{0xc34fe5,5},{0xd5c164,9},{0xf219ec,4},{0xef5aaf,8},
+{0xa7c68d,6},{0xd369bc,7},{0xf912ef,4},{0xb9b48b,6},
+{0x3bc6f9,6},{0xe54ac8,5},{0xf71ce7,9},{0xbc4def,8},
+{0xe271a7,3},{0xcbc16e,5},{0x3dfcc1,3},{0x97bea2,7},
+{0xaaa4aa,13},{0x73ef95,5},{0xf74fb1,4},{0xc148ef,17},
+{0xfc26d8,4},{0xfc02fc,6},{0xb1da6c,6},{0xd5d84d,7},
+{0xf96c95,5},{0xf90fef,3},{0xea7b92,7},{0xbc4def,4},
+{0xf2a264,8},{0x40dadd,12},{0xf214f4,4},{0x38c3fc,3},
+{0xf705fc,7},{0xa29db9,3},{0xaaf25f,4},{0xdd9a83,12},
+{0xc188b1,6},{0xa27bda,9},{0x36dde5,4},{0x85bcb9,7},
+{0xfc00fc,5},{0xe76ca4,4},{0x95b6ac,6},{0xb6d071,7},
+{0xc857d8,3},{0xfc2bd3,4},{0xfc5aa4,4},{0xf417ec,5},
+{0xb471d3,7},{0x92b1b6,4},{0x6c90fc,7},{0x5abce2,7},
+{0xcb55d8,3},{0xce30f9,5},{0xea7b95,3},{0xec17f7,6},
+{0xf70ff4,3},{0xaa73dd,9},{0x9d69f4,3},{0xb457ef,6},
+{0xf236d0,6},{0x64e0b4,7},{0xddcb52,4},{0xd0d355,7},
+{0x5fd5c3,6},{0xf42bd8,12},{0x55e2c1,4},{0xb1b492,4},
+{0xdd4dd0,4},{0xbc88b6,3},{0xea21ec,4},{0xf7649d,8},
+{0xb16cda,3},{0x9fa4b6,8},{0xea17f9,4},{0x1efce0,3},
+{0xbec179,7},{0xbeb18b,6},{0x9da4b6,6},{0x48b4fc,4},
+{0x7bfc83,14},{0xacf25c,10},{0xe0d842,4},{0xf9768b,5},
+{0xf90ff2,7},{0xfc00fc,8},{0xf20ff7,5},{0xec7e90,7},
+{0xbc42f9,3},{0xf712ef,5},{0xf902fc,6},{0xf77e83,7},
+{0xb1b197,5},{0xda6cb4,7},{0xf4a264,7},{0xa78dc6,6},
+{0xf21cea,4},{0xa48dc8,6},{0x6997f9,5},{0x67d3be,5},
+{0x4ad0e0,6},{0xcbbe6e,6},{0xcb76b6,10},{0xd030f9,6},
+{0xa29fb6,6},{0xda24fc,5},{0xf4bc48,3},{0xd0909a,6},
+{0xf252b6,8},{0x6cb4da,4},{0xdd40dd,11},{0x8b71fc,9},
+{0x80c8af,7},{0xb15fe7,4},{0x79ef90,6},{0x71b1d8,7},
+{0x61a4f2,9},{0x42dadd,6},{0xaf4ffc,3},{0x9a79e7,5},
+{0xea17f7,6},{0xc89f92,4},{0xb6d869,12},{0xda2eef,4},
+{0xf72ed5,6},{0xe057c3,6},{0xb6b190,6},{0xda48d5,5},
+{0xe0a476,3},{0xfce01c,6},{0x9dbe9f,13},{0xafce7e,4},
+{0xf905fc,6},{0xfc0cef,5},{0x9facaf,6},{0xb6af95,6},
+{0x52ced8,6},{0xd373b4,3},{0xce5cd0,8},{0xe752c1,5},
+{0xf7ac55,8},{0x7bbec1,6},{0xb4d571,4},{0xf90af7,5},
+{0xc833fc,7},{0xbe4dec,8},{0x92beaa,8},{0xfcb945,7},
+{0xc1d067,3},{0xdd45d8,7},{0xceb971,3},{0xf44ab9,4},
+{0xbeac8d,4},{0xf2af5a,15},{0xe05ac1,11},{0xd38b9d,4},
+{0xec0ffc,4},{0x80ec8d,7},{0xd0af7b,6},{0xef5cac,5},
+{0xdaa776,4},{0xd052d8,5},{0xb461e5,8},{0xef8388,7},
+{0xbea297,8},{0xce83a7,5},{0xda2ef2,3},{0x73b6ce,5},
+{0x83ec8b,9},{0xc840f2,7},{0xfc4faf,8},{0xfc14e7,4},
+{0xe742d0,9},{0x52aff7,4},{0xf214f4,4},{0x26f7da,5},
+{0xf2b94d,6},{0xe02eea,6},{0x76fc85,3},{0x858de7,4},
+{0xbc97a4,6},{0xd8aa79,4},{0x9d73ea,4},{0xdda279,5},
+{0xafc385,7},{0x33dde7,6},{0x64acea,8},{0xacce80,7},
+{0xef26e2,7},{0xb957e7,4},{0xdad548,4},{0xaf57f4,5},
+{0x9f73e5,3},{0xeae02e,7},{0xf70af7,8},{0xfc00fc,4},
+{0xea6ca4,6},{0x8885ec,3},{0xe23dda,4},{0xb461e5,10},
+{0xdd928b,6},{0x76cbb6,7},{0xfc00fc,5},{0xce8d9d,8},
+{0xafb692,12},{0xe79083,7},{0xfc0af2,3},{0xf926d8,8},
+{0xe219fc,5},{0xe7bc55,5},{0xcebc6e,3},{0xda73aa,4},
+{0xfc00fc,4},{0x52dace,5},{0xbcd864,6},{0x67e7ac,4},
+{0x33f9cb,3},{0x8bafc1,11},{0xd871af,6},{0xe78390,10},
+{0xb688bc,8},{0x5addc1,6},{0xf2d036,4},{0xf70ff2,9},
+{0xf4ea19,9},{0xfc02f9,6},{0x839fd8,3},{0xdd4dce,5},
+{0xec3dce,6},{0xcea783,6},{0xcbe745,5},{0xc1b483,7},
+{0x799fe0,5},{0xd340e7,7},{0x29ddf2,3},{0x73daac,6},
+{0xea33da,5},{0xe224f2,3},{0xd34fd5,5},{0xe245d3,8},
+{0xfc1edd,10},{0x3bf2cb,4},{0xdd9f7e,26},{0xe02eec,5},
+{0xf47195,4},{0xa461f4,5},{0x3ddae0,3},{0xaf5fea,6},
+{0xbccb73,6},{0xea26ea,8},{0xd82bf7,6},{0xac6ce0,7},
+{0xe524ef,4},{0xb6da69,6},{0xf224e2,5},{0xb95ce5,7},
+{0x73a4e0,7},{0xa4e076,7},{0xfc02f9,8},{0xec1eec,4},
+{0xf7da29,6},{0xc369ce,6},{0xd5c65c,9},{0xe51ef4,4},
+{0xf2a264,4},{0x809ddd,5},{0xd045e2,7},{0xaac888,6},
+{0xb44af9,3},{0xd84ad8,7},{0xf4ef14,5},{0x3bf7c8,5},
+{0xe730e0,4},{0x97b6ac,7},{0x8bda95,5},{0x88ec83,8},
+{0xece529,8},{0x9a80dd,10},{0xf412f4,7},{0x36efd5,6},
+{0xf95ca4,9},{0xd838e7,6},{0x9a69f7,7},{0xf730d3,4},
+{0xd526fc,5},{0x9f76e2,6},{0xe28395,8},{0xecaa61,6},
+{0x4ff4b4,7},{0xd079af,7},{0xa469ea,10},{0xfc21da,7},
+{0xb471d5,6},{0x7b88f7,4},{0xfc6797,4},{0x9daab4,5},
+{0x29f2dd,7},{0x8388ec,7},{0x4df9b1,4},{0xeaf21e,5},
+{0xf4c340,10},{0xf212f7,3},{0xf407fc,5},{0x4fb9ef,9},
+{0xd3b471,6},{0xef4dbe,12},{0x4af4bc,7},{0xe224f2,6},
+{0x36d0f2,8},{0xf707fc,4},{0xfc8d71,9},{0x95bea4,6},
+{0x90ef7b,4},{0x5adac6,5},{0x97b9a7,4},{0xc3c671,6},
+{0xfc12ec,5},{0xea1ef2,5},{0x8dd09d,4},{0xd82bf7,7},
+{0xb18dbc,7},{0xbc64da,6},{0xf28d7b,4},{0xef19ef,5},
+{0xc1e555,6},{0xfc3bc3,6},{0x9f88d3,5},{0xc3ec48,9},
+{0xc8979a,5},{0x5cc6d8,4},{0xf78080,6},{0xb17bcb,8},
+{0xea12fc,6},{0xc195a2,7},{0xef33d8,3},{0xa783ce,3},
+{0xf40af9,5},{0xa288d0,6},{0xf248be,4},{0x14e7fc,5},
+{0x83d3a4,8},{0xb4cb79,6},{0xbc7ebe,3},{0xfc8873,6},
+{0xe038e0,6},{0xc3ef48,6},{0xa25afc,10},{0xc1a792,6},
+{0x8d90dd,9},{0xc1be7b,5},{0x8bec80,5},{0xa4ef64,5},
+{0x38f7c8,11},{0xaf6eda,4},{0xd073b4,5},{0x79ceb4,7},
+{0xd5e540,6},{0xfc0fec,5},{0xf917ea,7},{0x64c8cb,4},
+{0x69e7a7,6},{0xa77ed3,5},{0xe52be7,6},{0x5aaaf4,7},
+{0xcb85a7,5},{0x8392e2,4},{0x5cb4ea,6},{0xe729e7,6},
+{0xc873bc,5},{0xeabc52,7},{0xf438ce,7},{0xea48c8,5},
+{0xef17f4,4},{0xfc00fc,6},{0xf97b85,14},{0x67ace7,3},
+{0xf452b1,7},{0xe2e038,4},{0xa4a7af,5},{0xddb469,3},
+{0xf21cec,7},{0x7bbec1,3},{0xda38e5,8},{0xc6a292,9},
+{0x6ecebc,9},{0x8dda90,4},{0xf921e0,8},{0xc88da4,5},
+{0x92aabc,4},{0x9a9dc3,5},{0x8dd895,4},{0x64d3c3,9},
+{0xa2f95f,7},{0xdd36e5,8},{0x83e790,11},{0xef26e2,5},
+{0xef55b4,9},{0x5fc3d8,6},{0xfc57a4,7},{0x9785dd,5},
+{0x809ddd,4},{0xc66cc8,8},{0xf236d3,5},{0xd338ef,6},
+{0xd8839f,4},{0xef30d8,3},{0x9a9ac6,5},{0xfc05f9,11},
+{0x958bda,11},{0xf902fc,8},{0xbe42f9,4},{0xbce557,6},
+{0xef4fb9,6},{0xf9af52,5},{0x97d38d,5},{0xf902fc,7},
+{0xf4a261,4},{0xd88897,7},{0x92e77e,7},{0x6c9df2,6},
+{0xce85a4,4},{0x9ae07e,8},{0xb1f255,8},{0xc6929f,6},
+{0xf2af5a,10},{0xe2977e,5},{0xe5cb4a,5},{0xfc14e7,3},
+{0xc14aef,3},{0xaff257,3},{0xe21cf9,11},{0xd05ccb,5},
+{0xf2ec1c,8},{0xb4b98b,9},{0xc183b6,3},{0xb455f2,7},
+{0x83aace,4},{0xe51cf9,4},{0xdd4fce,4},{0xb47ec8,3},
+{0x92da8b,4},{0xecb952,4},{0xf70af7,6},{0x7bbcc1,6},
+{0xf40cf9,5},{0xe2ce48,5},{0xf7b14f,5},{0xdd40da,4},
+{0x4fb9f2,7},{0x6eb1da,5},{0x9d90ce,6},{0xcb55d8,5},
+{0xd02efc,8},{0xd36eb9,6},{0xfc0cef,5},{0xe071aa,9},
+{0xe7ac67,3},{0xf4f40f,6},{0xe267af,4},{0xc3da5c,5},
+{0xb945fc,4},{0xeada33,6},{0x7197f2,7},{0xfc00fc,8},
+{0xd09d8d,5},{0x6e9fea,8},{0xd3a77e,4},{0xaa5ff2,6},
+{0xe269ac,5},{0xf426e0,6},{0xfc00fc,5},{0xec6ca2,10},
+{0xc638fc,7},{0xe54fc6,5},{0x5ac6da,3},{0xce67c6,6},
+{0xbe42f9,5},{0xce38f2,5},{0xbe5ae2,3},{0xd3ec38,8},
+{0x8b76f7,8},{0xb180c8,4},{0xd538ec,4},{0xddef2b,9},
+{0xf9c838,5},{0xf457ac,4},{0xf95aa7,7},{0xaf69e0,9},
+{0x67efa2,5},{0xa280d8,4},{0xa7d57b,7},{0xcbaf7e,4},
+{0x837bf9,4},{0xddc15c,6},{0xe221f4,3},{0xc6b480,5},
+{0xbc90af,10},{0x4dd3da,4},{0xbcb983,4},{0xe77997,7},
+{0xe05fb9,9},{0xc1b980,8},{0xdd55c6,7},{0xaf97b1,9},
+{0xec838b,4},{0xc39d9a,9},{0x6c97f7,5},{0xf7b44f,3},
+{0xb69fa4,7},{0x90ea7e,7},{0xe067b1,5},{0xd5cb5a,4},
+{0xc19a9f,8},{0xac67e7,8},{0xcee745,4},{0xf436d0,4},
+{0x73b1d5,7},{0xd3d84f,5},{0xdd42d8,5},{0xea907e,6},
+{0xc83bf4,7},{0xd84fd3,6},{0xe28890,3},{0x38e2e0,8},
+{0xec67a7,6},{0xcbc16e,8},{0x4ab1fc,7},{0x92d590,3},
+{0xaad876,4},{0xb683c1,4},{0xaa55f9,5},{0xea24ea,6},
+{0xf90fef,6},{0xf738c8,3},{0xcb5ad5,7},{0xec21ec,5},
+{0xce61c8,3},{0xa76ce7,3},{0xf41ee5,7},{0xcebe6c,3},
+{0x57dac6,9},{0xf46e97,3},{0x8be08d,7},{0xc148ef,9},
+{0xf926da,8},{0xe029ef,6},{0xfc00fc,5},{0x3dcbf2,4},
+{0xef0ffc,5},{0x95b6ac,9},{0x7be59a,5},{0xda2ef2,8},
+{0xda30ef,5},{0xfc24d8,3},{0x73d3b4,3},{0xddf229,4},
+{0x8883ef,5},{0x5aefaf,6},{0x9797cb,6},{0xcbc16c,5},
+{0xef19f2,5},{0xd3bc6c,3},{0xda5cc3,8},{0x52f9ac,7},
+{0xa7c888,4},{0x69d8b6,7},{0xbc45f7,7},{0xfc02fc,4},
+{0xb4b195,6},{0xe58d85,4},{0x9776ea,6},{0xf255b1,6},
+{0x76dda7,3},{0xe55ab9,8},{0xe230e7,5},{0x3bd0ec,5},
+{0xe219fc,6},{0xcbac83,5},{0xe548ce,7},{0xdd5cbe,3},
+{0xf412f4,5},{0xf9738d,9},{0xdd40da,4},{0x90c6a2,10},
+{0xe038e2,4},{0x6eddaf,8},{0xf23dcb,12},{0xec4fbc,6},
+{0xc8d35c,6},{0xf238d0,6},{0x90cb9f,6},{0xa46ee5,5},
+{0xaf8bbe,5},{0xc1a495,5},{0xc679b9,4},{0xec29e2,6},
+{0xf9649d,6},{0xf924da,6},{0xe224f2,5},{0x8d71f9,7},
+{0xf2cb3d,5},{0xb6cb79,4},{0xa4dd76,6},{0xe52ee5,3},
+{0xaa8bc3,3},{0x838dea,7},{0xf9ea17,5},{0x88c8aa,6},
+{0x73e0a7,5},{0xd09595,6},{0xf7d82b,10},{0xec7397,4},
+{0xfc02fc,7},{0xf72ed3,5},{0xd03dec,4},{0x80cbaf,5},
+{0xf921dd,7},{0x9fcb90,8},{0xbe95a7,4},{0x69eaa4,8},
+{0xf20ff7,5},{0x69e7a7,9},{0xf924da,3},{0xecdd30,6},
+{0xc1d861,4},{0xb967d8,5},{0xb157ef,6},{0xb9bc85,5},
+{0xb192b4,8},{0xda38e5,3},{0xea1eef,6},{0x12f7ef,4},
+{0x6e90f9,6},{0xd573b1,6},{0xdd24f7,5},{0xd5d055,7},
+{0xc86ec1,4},{0xf21ee7,7},{0xa261f4,6},{0xe555c1,4},
+{0xf78b79,6},{0xf78080,5},{0x80b4c3,7},{0xf414ef,4},
+{0xf70ff2,6},{0xea52bc,6},{0xd04ddd,7},{0xf90af4,5},
+{0xe78b88,4},{0xf29f67,6},{0x79b6c8,4},{0xa48dc8,5},
+{0x5fa4f4,4},{0xea14fc,3},{0xf23bcb,7},{0xf738cb,5},
+{0x4fb1f9,3},{0x5ae2bc,7},{0xfcac4f,5},{0xa283d3,7},
+{0xef24e7,7},{0xe5e52e,4},{0x929ace,4},{0xcb36f9,8},
+{0xea21ef,5},{0xf2d038,6},{0x48d8d8,4},{0xec40ce,6},
+{0xf90af7,5},{0xf921dd,7},{0xd8e042,5},{0x21ddf9,4},
+{0x5fb9e2,8},{0xf72ed3,4},{0xfc2ed0,5},{0xf712ef,6},
+{0x57d8cb,5},{0x19fce2,9},{0xe7f71c,9},{0x7be59a,4},
+{0x6cfc90,5},{0xec3bd0,5},{0xea26e7,8},{0x36d5ec,5},
+{0xac76d8,3},{0xa4a4b1,3},{0xef12f7,4},{0x6eb9d3,6},
+{0xe714fc,5},{0xe224f2,5},{0x3bead5,4},{0x8de783,9},
+{0x40d5e2,8},{0x9764fc,7},{0xf705fc,3},{0x8d88e2,8},
+{0xe269ac,6},{0xda33ec,7},{0xd03bec,3},{0xbe6cd0,6},
+{0x8bf479,5},{0xf912ec,8},{0xe5b461,7},{0xaf5aef,6},
+{0xc34fe5,7},{0xd038ef,6},{0x38f9c8,7},{0xf43dc6,3},
+{0xceb973,5},{0xe526ec,4},{0xf902fc,7},{0xbc48f7,4},
+{0,0}
+};
+
+static double const mosaic_curve_points[] = {
+20.3, 216.5, 27.0, 209.8, 17.4, 200.0, 14.5, 183.5, 14.2, 181.8,
+13.5, 181.6, 13.9, 180.0, 28.3, 126.1, 29.2, 126.3, 44.2, 72.5,
+44.4, 71.7, 44.2, 70.8, 44.2, 70.8, 44.2, 70.8, 44.4, 71.7,
+44.2, 72.5, 36.1, 121.4, 36.0, 121.3, 27.9, 170.2, 24.1, 193.3,
+33.8, 203.1, 20.3, 216.5, 82.6, 583.9, 82.5, 583.6, 84.3, 583.3,
+84.2, 583.1, 88.1, 600.0, 87.2, 600.2, 90.2, 617.3, 92.4, 630.1,
+92.4, 630.1, 94.7, 642.9, 96.8, 655.3, 96.8, 655.3, 99.0, 667.8,
+100.0, 673.7, 100.1, 673.7, 101.1, 679.7, 107.4, 716.3, 107.3, 716.3,
+113.7, 752.9, 115.3, 762.1, 117.1, 771.4, 117.1, 771.4, 117.1, 771.4,
+115.3, 762.1, 113.7, 752.9, 108.9, 726.8, 108.9, 726.8, 104.1, 700.7,
+97.1, 662.7, 97.1, 662.7, 90.1, 624.8, 86.3, 604.3, 85.5, 604.5,
+82.6, 583.9, 37.6, 265.6, 38.8, 286.4, 41.0, 287.6, 36.1, 307.5,
+38.5, 298.0, 34.3, 297.0, 32.5, 286.5, 26.4, 251.5, 21.6, 251.7,
+20.3, 216.5, 33.8, 203.1, 24.1, 193.3, 27.9, 170.2, 43.4, 214.1,
+34.7, 217.8, 37.6, 265.6, 27.9, 170.2, 36.0, 121.3, 36.1, 121.4,
+44.2, 72.5, 43.5, 76.1, 44.0, 76.2, 43.9, 79.8, 43.7, 85.4,
+43.7, 85.4, 43.5, 91.0, 41.9, 137.6, 41.9, 137.6, 40.3, 184.2,
+39.2, 217.8, 39.2, 217.8, 38.1, 251.5, 37.8, 258.5, 36.7, 258.7,
+37.6, 265.6, 34.7, 217.8, 43.4, 214.1, 27.9, 170.2, -16.2, 299.0,
+-16.2, 299.0, -15.8, 297.4, -15.4, 295.8, -10.3, 274.5, -10.2, 274.5,
+-5.1, 253.1, -1.7, 238.6, -1.9, 238.6, 1.6, 224.2, 2.5, 220.5,
+2.8, 220.6, 3.6, 216.9, -0.6, 235.0, -0.7, 235.0, -5.1, 253.1,
+-10.2, 274.5, -10.3, 274.5, -15.4, 295.8, -15.8, 297.4, -16.2, 299.0,
+-16.2, 299.0, 242.4, -11.8, 258.9, -17.0, 261.0, -11.0, 277.2, -16.9,
+183.6, 17.7, 182.4, 14.3, 87.6, 45.5, 87.3, 45.5, 87.3, 45.5,
+87.1, 45.6, 71.7, 49.5, 71.2, 48.0, 56.4, 53.5, 148.8, 19.4,
+148.5, 18.2, 242.4, -11.8, 56.4, 53.5, 52.5, 54.8, 51.1, 57.0,
+48.5, 55.6, 47.9, 55.2, 48.4, 50.6, 50.0, 50.0, 134.7, 18.5,
+135.0, 19.0, 221.1, -8.6, 231.2, -11.9, 232.5, -8.1, 242.4, -11.8,
+148.5, 18.2, 148.8, 19.4, 56.4, 53.5, 194.7, 17.8, 158.4, 27.2,
+158.4, 27.2, 122.0, 36.6, 117.5, 37.7, 117.5, 37.7, 112.9, 38.9,
+100.2, 42.2, 100.2, 42.2, 87.6, 45.5, 87.3, 45.5, 87.3, 45.5,
+87.1, 45.6, 182.1, 14.3, 181.1, 10.8, 277.2, -16.9, 303.4, -24.5,
+307.1, -14.6, 331.7, -25.0, 266.4, 2.6, 263.7, -3.7, 195.7, 17.5,
+195.2, 17.7, 195.2, 17.7, 194.7, 17.8, 331.7, -25.0, 364.2, -33.4,
+365.0, -31.6, 398.6, -34.9, 387.8, -33.8, 388.0, -32.1, 377.4, -29.4,
+370.0, -27.5, 370.0, -27.5, 362.6, -25.6, 362.3, -25.5, 362.3, -25.5,
+362.0, -25.4, 355.9, -23.9, 355.9, -23.9, 349.8, -22.3, 341.8, -20.2,
+341.8, -20.2, 333.7, -18.1, 318.3, -14.2, 318.3, -14.2, 303.0, -10.2,
+300.6, -9.6, 300.6, -9.6, 298.2, -9.0, 281.5, -4.7, 281.5, -4.7,
+264.9, -0.3, 254.1, 2.4, 254.1, 2.4, 243.2, 5.2, 227.9, 9.2,
+227.9, 9.2, 212.6, 13.1, 204.2, 15.3, 204.2, 15.3, 195.7, 17.5,
+195.2, 17.7, 195.2, 17.7, 194.7, 17.8, 263.2, -3.6, 262.3, -7.1,
+331.7, -25.0, -5.1, 253.1, -0.7, 235.0, -0.6, 235.0, 3.6, 216.9,
+7.2, 203.0, 5.7, 202.2, 11.4, 189.1, 6.4, 200.6, 8.2, 201.4,
+5.0, 213.7, -0.0, 233.4, 2.9, 234.7, -5.1, 253.1, 0.7, 536.2,
+13.6, 573.8, 15.5, 574.7, 18.7, 614.1, 18.8, 616.3, 7.9, 620.2,
+7.3, 619.4, -4.6, 602.1, -1.2, 599.1, -6.2, 577.9, -16.0, 536.4,
+-28.8, 533.6, -22.2, 494.1, -25.4, 512.7, -6.9, 513.8, 0.7, 536.2,
+-22.2, 494.1, -26.0, 485.6, -28.6, 477.0, -25.8, 475.4, -22.7, 473.6,
+-14.7, 479.5, -10.5, 487.2, -3.6, 500.3, -7.1, 502.1, -3.7, 517.0,
+-2.5, 522.1, -2.5, 522.1, -1.4, 527.1, -0.3, 531.7, -1.6, 532.5,
+0.7, 536.2, -6.9, 513.8, -25.4, 512.7, -22.2, 494.1, 19.0, 510.1,
+21.7, 515.4, 24.2, 514.1, 29.4, 518.2, 30.9, 519.3, 30.9, 519.3,
+32.3, 520.4, 56.0, 538.7, 58.2, 536.4, 79.7, 557.1, 82.9, 560.1,
+80.6, 562.5, 81.6, 567.8, 82.9, 575.5, 83.7, 575.4, 84.2, 583.1,
+84.3, 583.3, 82.5, 583.6, 82.6, 583.9, 75.0, 587.4, 75.2, 587.9,
+67.4, 591.0, 67.4, 591.1, 67.2, 590.6, 66.9, 590.2, 42.9, 550.1,
+40.5, 551.4, 19.0, 510.1, 121.8, 800.9, 121.7, 801.1, 122.3, 801.2,
+122.4, 801.6, 123.7, 808.3, 126.5, 809.3, 124.7, 815.1, 125.1, 813.8,
+120.1, 813.3, 119.5, 810.6, 118.6, 806.2, 120.3, 805.6, 121.8, 800.9,
+0.7, 495.9, 3.7, 500.5, 5.2, 499.5, 9.8, 503.0, 14.4, 506.5,
+15.9, 505.5, 19.0, 510.1, 40.5, 551.4, 42.9, 550.1, 66.9, 590.2,
+63.6, 584.5, 63.1, 584.8, 59.4, 579.4, 30.0, 537.7, 28.5, 538.7,
+0.7, 495.9, 113.7, 752.9, 115.3, 762.1, 117.1, 771.4, 117.1, 771.4,
+117.4, 773.4, 117.4, 773.4, 117.8, 775.3, 120.1, 788.5, 120.3, 788.4,
+122.4, 801.6, 122.3, 801.2, 121.7, 801.1, 121.8, 800.9, 121.4, 800.4,
+121.4, 800.4, 121.0, 799.9, 120.6, 799.4, 120.6, 799.4, 120.3, 798.9,
+95.0, 767.1, 74.8, 770.0, 69.8, 735.3, 71.5, 747.0, 95.6, 739.1,
+113.7, 752.9, 69.8, 735.3, 69.0, 734.9, 68.4, 733.7, 68.5, 733.6,
+75.3, 725.8, 76.1, 726.5, 83.8, 719.4, 89.1, 714.5, 89.1, 714.5,
+94.4, 709.6, 99.2, 705.1, 104.9, 702.6, 104.1, 700.7, 108.9, 726.8,
+108.9, 726.8, 113.7, 752.9, 95.6, 739.1, 71.5, 747.0, 69.8, 735.3,
+19.0, 613.9, 22.4, 604.2, 32.4, 607.6, 45.7, 601.3, 56.0, 596.4,
+56.0, 596.4, 66.3, 591.6, 66.9, 591.3, 66.9, 591.3, 67.4, 591.0,
+75.2, 587.9, 75.0, 587.4, 82.6, 583.9, 85.5, 604.5, 86.3, 604.3,
+90.1, 624.8, 90.1, 624.5, 88.9, 624.6, 87.8, 624.5, 64.0, 620.8,
+64.0, 620.8, 40.2, 617.2, 29.6, 615.5, 19.7, 612.1, 19.0, 613.9,
+121.0, 799.9, 121.4, 800.4, 121.4, 800.4, 121.8, 800.9, 120.3, 805.6,
+118.6, 806.2, 119.5, 810.6, 108.1, 806.7, 98.9, 800.6, 99.9, 793.4,
+99.6, 795.2, 110.5, 796.3, 121.0, 799.9, 191.6, 801.6, 213.6, 817.8,
+197.0, 840.4, 202.3, 879.2, 202.4, 880.2, 203.0, 880.7, 202.6, 881.2,
+202.1, 881.7, 201.1, 881.7, 200.4, 881.1, 187.5, 870.7, 176.8, 871.5,
+175.5, 859.3, 172.4, 831.7, 200.2, 807.9, 191.6, 801.6, 32.3, 520.4,
+30.9, 519.3, 30.9, 519.3, 29.4, 518.2, 27.6, 505.3, 28.9, 505.1,
+28.3, 492.1, 26.0, 440.3, 25.5, 440.3, 23.7, 388.5, 24.2, 405.2,
+24.7, 405.2, 25.8, 421.8, 27.0, 439.3, 27.0, 439.3, 28.1, 456.8,
+29.1, 470.9, 29.1, 470.9, 30.0, 485.1, 31.1, 502.7, 32.6, 502.7,
+32.3, 520.4, -3.7, 517.0, -7.1, 502.1, -3.6, 500.3, -10.5, 487.2,
+-10.8, 490.3, -6.1, 490.7, -1.6, 494.1, -0.5, 495.0, -0.1, 494.8,
+0.7, 495.9, 28.5, 538.7, 30.0, 537.7, 59.4, 579.4, 64.3, 555.8,
+22.9, 552.0, -3.7, 517.0, 83.8, 719.4, 76.1, 726.5, 75.3, 725.8,
+68.5, 733.6, 49.9, 724.3, 45.1, 717.9, 40.0, 697.6, 42.0, 705.5,
+51.1, 703.2, 62.2, 708.7, 69.0, 712.1, 69.0, 712.1, 75.8, 715.5,
+79.8, 717.4, 83.9, 719.1, 83.8, 719.4, 69.7, 767.2, 66.2, 756.5,
+57.4, 760.4, 50.0, 750.0, 44.4, 742.1, 50.3, 736.4, 43.7, 730.7,
+60.1, 745.0, 63.1, 746.8, 69.7, 767.2, 943.6, 608.8, 941.3, 609.3,
+947.5, 623.9, 942.6, 627.8, 892.0, 668.3, 889.0, 665.2, 832.4, 697.7,
+848.6, 688.4, 847.2, 685.9, 861.9, 674.1, 867.3, 669.8, 867.3, 669.8,
+872.6, 665.6, 875.3, 663.4, 875.3, 663.4, 878.0, 661.2, 891.5, 650.5,
+891.5, 650.5, 904.9, 639.8, 906.2, 638.7, 906.2, 638.7, 907.5, 637.7,
+909.8, 635.8, 909.8, 635.8, 912.2, 633.9, 927.9, 621.4, 926.1, 612.3,
+943.6, 608.8, 743.8, 661.6, 749.6, 670.9, 741.5, 681.2, 747.9, 684.8,
+733.2, 676.6, 737.6, 668.6, 727.2, 652.4, 722.1, 644.3, 722.1, 644.3,
+716.9, 636.3, 711.2, 627.4, 711.2, 627.4, 705.5, 618.5, 701.1, 611.6,
+695.6, 610.5, 696.7, 604.7, 695.8, 609.3, 701.3, 610.3, 706.0, 615.9,
+724.9, 638.7, 728.6, 636.5, 743.8, 661.6, 947.6, 328.1, 940.6, 361.9,
+953.7, 364.0, 954.4, 400.0, 955.1, 438.8, 952.6, 438.9, 950.4, 477.7,
+950.5, 475.0, 950.3, 475.0, 950.3, 472.2, 949.8, 448.4, 949.8, 448.4,
+949.4, 424.6, 948.5, 376.3, 938.1, 374.2, 947.6, 328.1, 846.3, 117.0,
+890.0, 147.0, 890.5, 146.4, 933.3, 177.7, 934.1, 178.3, 932.8, 180.3,
+933.6, 180.8, 919.3, 171.9, 920.0, 170.9, 906.3, 160.9, 890.8, 149.6,
+890.8, 149.6, 875.3, 138.2, 872.0, 135.8, 872.0, 135.8, 868.7, 133.4,
+857.5, 125.2, 857.7, 124.9, 846.3, 117.0, 408.1, 154.0, 408.9, 154.9,
+409.6, 155.6, 409.4, 156.0, 393.6, 178.5, 392.8, 177.9, 376.1, 199.9,
+371.9, 205.6, 372.2, 205.9, 367.6, 211.2, 370.8, 207.5, 370.5, 207.2,
+373.3, 203.2, 390.6, 178.7, 390.6, 178.7, 407.9, 154.3, 408.0, 154.2,
+408.2, 154.1, 408.1, 154.0, 142.2, 652.8, 141.2, 609.9, 142.1, 609.9,
+142.0, 567.0, 142.0, 543.5, 142.0, 543.5, 141.9, 520.0, 141.9, 517.7,
+141.9, 517.7, 141.9, 515.4, 141.9, 494.5, 141.9, 494.5, 141.9, 473.6,
+141.9, 472.3, 141.9, 472.3, 141.9, 471.0, 141.8, 468.7, 141.8, 468.7,
+141.8, 466.3, 141.8, 452.9, 141.5, 452.9, 141.8, 439.5, 141.8, 441.3,
+142.0, 441.3, 142.3, 443.2, 144.2, 457.2, 144.2, 457.2, 146.2, 471.3,
+146.6, 474.8, 146.6, 474.8, 147.1, 478.3, 147.4, 480.0, 147.4, 480.0,
+147.6, 481.7, 148.8, 490.4, 148.8, 490.4, 150.0, 499.1, 150.2, 500.3,
+150.2, 500.3, 150.3, 501.5, 153.2, 522.1, 153.2, 522.1, 156.0, 542.8,
+156.8, 548.2, 156.8, 548.2, 157.5, 553.7, 157.8, 556.1, 158.5, 556.2,
+158.2, 558.4, 155.4, 578.7, 154.7, 578.6, 151.3, 598.8, 147.6, 620.7,
+147.6, 620.7, 143.9, 642.6, 143.9, 642.7, 143.9, 642.7, 143.9, 642.7,
+143.1, 647.7, 142.1, 647.8, 142.2, 652.8, -1.6, 494.1, -6.1, 490.7,
+-10.8, 490.3, -10.5, 487.2, -14.7, 479.5, -22.7, 473.6, -25.8, 475.4,
+-37.3, 443.0, -39.2, 441.2, -38.9, 407.2, -39.0, 422.7, -32.2, 422.8,
+-25.5, 438.4, -13.6, 466.3, -10.5, 465.3, -1.6, 494.1, 15.1, 196.4,
+24.9, 282.2, 18.9, 282.9, 22.8, 369.5, 22.8, 369.5, 22.8, 369.6,
+22.8, 369.6, 19.8, 367.5, 17.9, 368.2, 16.8, 365.3, 14.8, 360.0,
+16.8, 359.2, 16.7, 353.2, 16.6, 347.1, 16.6, 347.1, 16.6, 341.0,
+16.4, 326.7, 16.4, 326.7, 16.3, 312.3, 15.7, 254.3, 21.6, 253.7,
+15.1, 196.4, -1.4, 527.1, -2.5, 522.1, -2.5, 522.1, -3.7, 517.0,
+22.9, 552.0, 64.3, 555.8, 59.4, 579.4, 63.1, 584.8, 63.6, 584.5,
+66.9, 590.2, 67.2, 590.6, 67.4, 591.1, 67.4, 591.0, 66.9, 591.3,
+66.9, 591.3, 66.3, 591.6, 44.0, 571.1, 44.3, 570.7, 22.4, 549.7,
+10.5, 538.4, 8.8, 539.8, -1.4, 527.1, 87.8, 624.5, 88.9, 624.6,
+90.1, 624.5, 90.1, 624.8, 97.1, 662.7, 97.1, 662.7, 104.1, 700.7,
+104.9, 702.6, 99.2, 705.1, 94.4, 709.6, 91.2, 708.1, 93.8, 702.6,
+93.3, 695.5, 92.9, 690.2, 92.9, 690.2, 92.5, 684.9, 91.2, 668.6,
+91.2, 668.6, 89.9, 652.3, 88.9, 638.4, 87.7, 638.4, 87.8, 624.5,
+120.3, 798.9, 120.6, 799.4, 120.6, 799.4, 121.0, 799.9, 110.5, 796.3,
+99.6, 795.2, 99.9, 793.4, 83.2, 782.8, 82.9, 782.0, 69.7, 767.2,
+63.1, 746.8, 60.1, 745.0, 43.7, 730.7, 42.4, 728.8, 43.7, 727.6,
+42.2, 726.3, 82.0, 761.7, 81.3, 762.5, 120.3, 798.9, 42.2, 726.3,
+28.8, 709.3, 29.6, 704.7, 27.9, 682.3, 28.5, 690.4, 33.9, 690.0,
+40.0, 697.6, 45.1, 717.9, 49.9, 724.3, 68.5, 733.6, 68.4, 733.7,
+69.0, 734.9, 69.8, 735.3, 74.8, 770.0, 95.0, 767.1, 120.3, 798.9,
+81.3, 762.5, 82.0, 761.7, 42.2, 726.3, 703.4, 562.7, 701.7, 552.1,
+711.8, 549.5, 722.0, 537.9, 721.3, 538.6, 722.2, 539.4, 722.5, 540.9,
+723.8, 548.1, 723.8, 548.1, 725.0, 555.3, 730.5, 586.1, 730.5, 586.1,
+735.9, 616.8, 737.4, 625.4, 738.6, 625.3, 739.0, 634.0, 738.8, 631.5,
+737.7, 631.5, 736.5, 629.0, 719.9, 595.9, 708.9, 597.6, 703.4, 562.7,
+539.8, 359.6, 539.7, 358.7, 539.2, 358.7, 538.6, 357.9, 519.1, 327.4,
+519.1, 327.4, 499.6, 296.9, 492.6, 286.0, 492.4, 286.2, 485.7, 275.1,
+486.0, 275.6, 486.2, 275.5, 486.8, 275.9, 488.5, 277.1, 488.5, 277.1,
+490.3, 278.3, 512.4, 293.3, 515.9, 289.9, 534.6, 308.4, 538.8, 312.6,
+535.4, 316.0, 536.1, 323.7, 536.4, 326.7, 536.4, 326.7, 536.7, 329.8,
+538.3, 344.7, 538.8, 344.7, 539.8, 359.6, 672.2, 402.1, 674.0, 400.5,
+680.5, 407.7, 688.8, 413.4, 692.6, 416.0, 692.6, 416.0, 696.4, 418.5,
+698.9, 420.3, 700.7, 419.7, 701.5, 422.0, 705.6, 434.7, 703.8, 435.3,
+706.2, 448.6, 706.9, 452.6, 706.9, 452.6, 707.6, 456.6, 710.3, 471.8,
+713.6, 472.0, 713.0, 487.0, 713.1, 483.1, 709.8, 483.0, 706.7, 478.9,
+704.9, 476.6, 704.9, 476.6, 703.1, 474.3, 701.9, 472.8, 701.9, 472.8,
+700.8, 471.3, 696.3, 465.5, 696.3, 465.5, 691.8, 459.8, 689.2, 456.4,
+689.2, 456.4, 686.6, 453.1, 678.3, 442.4, 678.3, 442.4, 669.9, 431.6,
+669.6, 431.2, 669.3, 431.2, 669.3, 430.8, 670.4, 416.4, 664.2, 409.2,
+672.2, 402.1, 669.3, 430.8, 662.6, 432.2, 659.8, 418.7, 650.4, 406.5,
+639.5, 392.5, 639.5, 392.5, 628.6, 378.5, 623.6, 372.1, 625.2, 368.3,
+618.6, 365.6, 636.3, 372.9, 634.8, 376.6, 650.9, 387.6, 657.0, 391.8,
+657.0, 391.8, 663.1, 395.9, 666.5, 398.2, 666.5, 398.2, 669.9, 400.6,
+670.3, 400.8, 670.3, 400.8, 670.6, 401.0, 671.4, 401.6, 672.2, 401.6,
+672.2, 402.1, 664.2, 409.2, 670.4, 416.4, 669.3, 430.8, 150.3, 501.5,
+150.2, 500.3, 150.2, 500.3, 150.0, 499.1, 164.5, 478.5, 165.2, 479.0,
+180.4, 458.9, 203.0, 428.9, 200.5, 426.6, 225.7, 398.9, 203.9, 422.9,
+206.4, 425.2, 187.1, 451.5, 168.7, 476.5, 169.4, 477.1, 150.3, 501.5,
+198.1, 70.3, 213.7, 72.4, 227.1, 73.6, 228.3, 81.5, 229.1, 86.3,
+215.3, 88.6, 202.2, 95.7, 194.5, 100.0, 194.5, 100.0, 186.7, 104.2,
+177.5, 109.3, 170.2, 107.4, 168.4, 114.3, 173.7, 93.6, 181.1, 95.5,
+193.8, 76.7, 195.9, 73.5, 196.4, 70.1, 198.1, 70.3, 140.7, 133.4,
+137.8, 135.0, 133.7, 132.2, 133.2, 133.5, 134.7, 129.7, 137.9, 130.9,
+142.6, 128.4, 147.4, 125.8, 147.4, 125.8, 152.1, 123.1, 160.3, 118.7,
+160.3, 118.7, 168.4, 114.3, 170.2, 107.4, 177.5, 109.3, 186.7, 104.2,
+164.3, 119.7, 164.5, 120.3, 140.7, 133.4, 134.9, 228.4, 136.6, 240.3,
+129.2, 247.8, 116.4, 255.3, 118.9, 253.8, 111.2, 244.9, 114.4, 240.4,
+120.5, 231.5, 135.5, 232.9, 134.9, 228.4, 151.3, 598.8, 154.7, 578.6,
+155.4, 578.7, 158.2, 558.4, 157.7, 560.5, 158.5, 560.6, 158.8, 562.8,
+161.6, 583.3, 161.6, 583.3, 164.4, 603.8, 165.1, 609.2, 165.1, 609.2,
+165.9, 614.5, 169.9, 643.5, 169.9, 643.5, 173.9, 672.6, 174.5, 677.0,
+173.8, 677.2, 175.1, 681.5, 162.5, 640.3, 157.1, 641.0, 151.3, 598.8,
+141.4, 568.5, 141.4, 567.7, 142.1, 567.7, 142.0, 567.0, 142.1, 609.9,
+141.2, 609.9, 142.2, 652.8, 142.4, 726.7, 142.4, 726.7, 142.5, 800.7,
+142.5, 811.8, 142.5, 811.8, 142.6, 822.9, 142.6, 826.8, 142.7, 830.7,
+142.6, 830.7, 138.4, 830.8, 134.1, 827.1, 133.9, 823.2, 131.5, 765.1,
+135.6, 765.0, 137.3, 706.8, 137.6, 699.6, 137.6, 699.6, 137.8, 692.5,
+139.6, 630.5, 139.3, 630.5, 141.4, 568.5, 94.7, 642.9, 92.4, 630.1,
+92.4, 630.1, 90.2, 617.3, 90.6, 608.0, 93.4, 608.1, 96.7, 598.9,
+98.3, 594.2, 99.8, 594.3, 100.0, 589.5, 98.9, 614.8, 97.5, 614.8,
+95.0, 640.0, 94.8, 641.5, 94.4, 641.6, 94.7, 642.9, 118.9, 272.9,
+120.5, 292.1, 121.5, 292.0, 124.1, 311.0, 126.7, 329.9, 126.7, 329.9,
+129.3, 348.8, 135.5, 394.1, 136.9, 394.0, 141.8, 439.5, 141.5, 452.9,
+141.8, 452.9, 141.8, 466.3, 142.0, 464.7, 139.8, 464.7, 139.2, 462.7,
+138.1, 459.0, 138.8, 458.8, 138.4, 454.9, 135.2, 425.6, 135.2, 425.6,
+132.1, 396.2, 130.6, 382.7, 130.6, 382.7, 129.2, 369.3, 124.0, 321.1,
+123.1, 321.2, 118.9, 272.9, 44.2, 353.6, 40.0, 349.1, 42.9, 346.4,
+41.7, 339.3, 40.6, 332.9, 43.2, 329.6, 39.5, 326.5, 51.9, 336.6,
+49.3, 339.9, 59.1, 353.3, 60.0, 354.6, 60.0, 354.6, 60.9, 355.8,
+66.5, 363.4, 66.5, 363.4, 72.1, 371.0, 73.1, 372.4, 73.1, 372.4,
+74.1, 373.8, 74.2, 373.9, 74.1, 374.0, 74.3, 374.1, 59.2, 363.9,
+56.3, 366.5, 44.2, 353.6, -15.4, 295.8, -10.3, 274.5, -10.2, 274.5,
+-5.1, 253.1, 2.9, 234.7, -0.0, 233.4, 5.0, 213.7, 2.7, 222.5,
+2.8, 222.5, 0.6, 231.3, -3.2, 247.1, -3.2, 247.2, -7.1, 263.0,
+-11.2, 279.4, -12.0, 279.2, -15.4, 295.8, 22.8, 369.5, 18.9, 282.9,
+24.9, 282.2, 15.1, 196.4, 14.8, 189.9, 16.1, 189.6, 14.5, 183.5,
+17.4, 200.0, 27.0, 209.8, 20.3, 216.5, 21.6, 251.7, 26.4, 251.5,
+32.5, 286.5, 33.4, 293.8, 31.6, 294.0, 30.7, 301.5, 30.7, 301.8,
+30.7, 301.8, 30.7, 302.0, 29.9, 308.7, 29.9, 308.7, 29.1, 315.3,
+26.0, 342.4, 19.7, 343.1, 22.8, 369.5, 78.4, 549.9, 78.8, 550.4,
+78.6, 550.6, 78.7, 551.4, 79.2, 554.2, 78.0, 556.0, 79.7, 557.1,
+58.2, 536.4, 56.0, 538.7, 32.3, 520.4, 32.6, 502.7, 31.1, 502.7,
+30.0, 485.1, 30.0, 486.7, 31.2, 486.7, 32.4, 488.3, 55.4, 519.1,
+55.7, 518.9, 78.4, 549.9, 45.7, 601.3, 32.4, 607.6, 22.4, 604.2,
+19.0, 613.9, 18.8, 614.0, 18.6, 614.0, 18.7, 614.1, 15.5, 574.7,
+13.6, 573.8, 0.7, 536.2, -1.6, 532.5, -0.3, 531.7, -1.4, 527.1,
+8.8, 539.8, 10.5, 538.4, 22.4, 549.7, 37.4, 573.4, 47.0, 576.2,
+45.7, 601.3, 22.4, 549.7, 44.3, 570.7, 44.0, 571.1, 66.3, 591.6,
+56.0, 596.4, 56.0, 596.4, 45.7, 601.3, 47.0, 576.2, 37.4, 573.4,
+22.4, 549.7, 62.2, 708.7, 51.1, 703.2, 42.0, 705.5, 40.0, 697.6,
+33.9, 690.0, 28.5, 690.4, 27.9, 682.3, 21.2, 668.6, 25.2, 654.1,
+18.3, 653.0, 32.9, 655.3, 30.8, 668.9, 43.3, 684.7, 49.6, 692.7,
+49.6, 692.7, 55.9, 700.7, 56.1, 701.0, 56.1, 701.0, 56.3, 701.2,
+59.3, 705.0, 58.6, 707.9, 62.2, 708.7, 773.1, 619.7, 757.0, 625.1,
+754.8, 618.3, 736.4, 616.8, 736.2, 616.8, 735.9, 616.9, 735.9, 616.8,
+730.5, 586.1, 730.5, 586.1, 725.0, 555.3, 725.3, 557.0, 726.8, 556.9,
+728.5, 558.4, 734.7, 564.0, 734.7, 564.0, 741.0, 569.6, 750.7, 578.2,
+750.7, 578.2, 760.4, 586.8, 768.9, 594.4, 768.9, 594.4, 777.5, 602.0,
+778.0, 602.4, 778.5, 602.6, 778.4, 602.8, 776.3, 611.4, 778.0, 618.1,
+773.1, 619.7, 778.4, 602.8, 780.2, 601.8, 783.2, 607.1, 787.9, 611.3,
+791.7, 614.6, 792.8, 613.9, 795.5, 618.0, 796.2, 619.0, 795.2, 621.3,
+794.7, 621.4, 784.0, 622.2, 778.2, 625.5, 773.1, 619.7, 778.0, 618.1,
+776.3, 611.4, 778.4, 602.8, 767.2, 714.9, 766.5, 712.4, 765.7, 712.6,
+764.3, 710.3, 759.7, 703.1, 759.7, 703.1, 755.2, 696.0, 751.5, 690.4,
+750.0, 690.9, 747.9, 684.8, 741.5, 681.2, 749.6, 670.9, 743.8, 661.6,
+741.7, 649.6, 741.7, 649.6, 739.6, 637.7, 739.3, 635.8, 739.3, 635.8,
+739.0, 634.0, 738.6, 625.3, 737.4, 625.4, 735.9, 616.8, 735.9, 616.9,
+736.2, 616.8, 736.4, 616.8, 741.7, 632.9, 741.5, 633.0, 746.6, 649.2,
+756.9, 682.0, 757.7, 681.8, 767.2, 714.9, 787.2, 480.4, 785.4, 487.8,
+809.3, 488.9, 823.0, 504.7, 825.6, 507.8, 817.7, 516.8, 819.7, 518.2,
+799.8, 504.6, 783.7, 494.5, 787.2, 480.4, 760.1, 584.4, 760.7, 585.0,
+759.7, 586.2, 760.4, 586.8, 750.7, 578.2, 750.7, 578.2, 741.0, 569.6,
+744.4, 572.8, 744.8, 572.5, 748.5, 575.4, 754.3, 579.9, 754.8, 579.3,
+760.1, 584.4, 781.1, 677.4, 781.0, 677.3, 781.2, 676.2, 781.4, 676.2,
+796.6, 675.2, 796.6, 675.8, 811.9, 675.4, 814.5, 675.3, 814.5, 675.3,
+817.1, 675.3, 839.5, 674.7, 855.1, 664.1, 861.9, 674.1, 847.2, 685.9,
+848.6, 688.4, 832.4, 697.7, 829.2, 700.2, 827.7, 703.0, 825.4, 702.1,
+802.0, 692.9, 803.0, 690.2, 781.1, 677.4, 825.4, 702.1, 824.6, 718.3,
+804.0, 723.6, 778.2, 732.1, 776.6, 732.6, 771.7, 726.6, 770.7, 720.3,
+769.6, 713.9, 772.4, 713.4, 774.0, 706.6, 777.6, 692.0, 776.3, 677.8,
+781.1, 677.4, 803.0, 690.2, 802.0, 692.9, 825.4, 702.1, 736.5, 629.0,
+737.7, 631.5, 738.8, 631.5, 739.0, 634.0, 739.3, 635.8, 739.3, 635.8,
+739.6, 637.7, 737.6, 633.7, 738.1, 633.5, 736.6, 629.3, 736.5, 629.2,
+736.6, 629.2, 736.5, 629.0, 939.3, 263.2, 939.2, 262.7, 941.3, 262.5,
+941.3, 262.2, 945.5, 295.0, 945.9, 295.1, 947.6, 328.1, 938.1, 374.2,
+948.5, 376.3, 949.4, 424.6, 949.3, 413.7, 948.7, 413.7, 948.0, 402.8,
+943.6, 333.0, 942.6, 333.0, 939.3, 263.2, 933.8, 398.2, 945.1, 423.2,
+939.9, 425.5, 945.9, 452.8, 948.1, 462.5, 948.5, 462.5, 950.3, 472.2,
+950.3, 475.0, 950.5, 475.0, 950.4, 477.7, 949.9, 489.9, 944.7, 492.2,
+949.1, 502.2, 932.5, 464.7, 937.5, 462.4, 926.0, 422.7, 923.8, 415.2,
+923.8, 415.2, 921.6, 407.7, 920.4, 403.4, 920.4, 403.4, 919.1, 399.2,
+916.7, 390.9, 916.1, 382.5, 914.3, 382.6, 923.5, 382.0, 929.2, 388.1,
+933.8, 398.2, 924.1, 500.9, 935.4, 520.1, 931.7, 522.3, 939.4, 543.8,
+942.7, 553.0, 944.8, 552.8, 946.0, 562.3, 947.5, 574.7, 945.5, 574.9,
+944.7, 587.6, 944.7, 587.5, 944.5, 587.5, 944.3, 587.3, 934.6, 580.7,
+934.6, 580.7, 924.9, 574.1, 919.9, 570.7, 915.1, 570.9, 915.0, 567.3,
+913.8, 541.2, 918.6, 541.0, 922.2, 514.6, 923.1, 507.7, 926.8, 505.5,
+924.1, 500.9, 926.0, 422.7, 937.5, 462.4, 932.5, 464.7, 949.1, 502.2,
+953.3, 531.4, 952.7, 533.4, 946.0, 562.3, 944.8, 552.8, 942.7, 553.0,
+939.4, 543.8, 934.7, 516.5, 936.3, 516.2, 933.3, 488.7, 932.5, 482.0,
+932.5, 482.0, 931.8, 475.4, 928.9, 449.0, 938.8, 442.6, 926.0, 422.7,
+669.9, 400.6, 666.5, 398.2, 666.5, 398.2, 663.1, 395.9, 663.0, 395.4,
+665.6, 394.7, 668.1, 393.5, 684.8, 385.5, 684.8, 385.5, 701.4, 377.5,
+711.7, 372.6, 711.7, 372.6, 722.0, 367.6, 725.4, 366.0, 725.4, 366.0,
+728.7, 364.4, 730.3, 363.7, 730.3, 363.7, 731.8, 362.9, 732.7, 362.5,
+732.7, 362.5, 733.6, 362.1, 740.2, 358.9, 740.2, 358.9, 746.8, 355.7,
+750.9, 353.7, 750.9, 353.7, 755.0, 351.7, 767.9, 345.5, 767.9, 345.5,
+780.8, 339.3, 815.8, 322.6, 815.8, 322.7, 850.7, 305.9, 851.2, 305.7,
+851.6, 305.3, 851.6, 305.3, 851.6, 305.3, 851.2, 305.7, 850.7, 305.9,
+805.7, 329.5, 805.7, 329.5, 760.6, 353.1, 715.3, 376.8, 716.7, 380.0,
+669.9, 400.6, 676.7, 19.0, 678.1, 20.5, 689.6, 2.0, 699.1, 3.6,
+713.8, 6.3, 713.2, 14.6, 725.3, 27.5, 724.0, 26.2, 723.0, 27.1,
+720.8, 26.7, 698.7, 22.8, 689.0, 32.0, 676.7, 19.0, 446.7, 132.3,
+433.1, 136.8, 432.6, 135.3, 418.6, 138.4, 413.9, 139.4, 413.9, 139.4,
+409.3, 140.3, 408.6, 140.5, 408.6, 140.5, 408.0, 140.6, 404.3, 141.4,
+404.3, 142.2, 400.6, 142.2, 400.0, 142.2, 399.3, 141.0, 399.5, 140.5,
+401.5, 136.3, 401.3, 134.8, 405.1, 132.7, 408.4, 130.9, 409.4, 132.7,
+413.7, 132.6, 414.0, 132.6, 414.0, 132.6, 414.2, 132.6, 424.1, 132.5,
+424.1, 132.5, 434.0, 132.5, 435.4, 132.4, 435.4, 132.4, 436.8, 132.4,
+441.7, 132.4, 442.2, 133.8, 446.7, 132.3, 359.9, 57.9, 372.4, 77.4,
+383.0, 94.8, 375.4, 102.9, 379.1, 99.0, 363.7, 84.6, 352.0, 66.3,
+345.7, 56.6, 345.7, 56.6, 339.5, 46.8, 338.4, 45.2, 338.4, 45.2,
+337.4, 43.5, 327.7, 28.4, 331.8, 22.0, 318.0, 13.2, 343.0, 29.2,
+343.7, 32.5, 359.9, 57.9, 318.0, 13.2, 309.1, 2.6, 299.8, -3.8,
+303.0, -10.2, 318.3, -14.2, 318.3, -14.2, 333.7, -18.1, 336.3, -17.9,
+335.7, -12.3, 337.7, -6.6, 348.8, 25.7, 370.5, 47.3, 359.9, 57.9,
+343.7, 32.5, 343.0, 29.2, 318.0, 13.2, 393.4, 131.0, 382.3, 118.8,
+382.3, 117.9, 375.4, 102.9, 383.0, 94.8, 372.4, 77.4, 359.9, 57.9,
+370.5, 47.3, 348.8, 25.7, 337.7, -6.6, 365.8, 53.1, 362.5, 54.7,
+387.3, 116.0, 390.3, 123.5, 388.3, 125.4, 393.4, 131.0, 290.4, 2.4,
+289.0, 0.5, 293.4, -4.2, 298.2, -9.0, 300.6, -9.6, 300.6, -9.6,
+303.0, -10.2, 299.8, -3.8, 309.1, 2.6, 318.0, 13.2, 331.8, 22.0,
+327.7, 28.4, 337.4, 43.5, 336.2, 41.4, 335.5, 41.8, 333.5, 40.1,
+311.9, 21.3, 306.7, 25.1, 290.4, 2.4, 432.1, 236.3, 431.1, 225.7,
+431.2, 225.7, 430.8, 215.1, 431.0, 219.5, 431.2, 219.5, 431.6, 223.8,
+431.8, 226.0, 431.8, 226.0, 432.0, 228.2, 435.6, 267.5, 435.6, 267.5,
+439.3, 306.7, 441.3, 329.1, 441.3, 329.1, 443.4, 351.4, 443.9, 357.8,
+443.9, 357.8, 444.5, 364.1, 444.8, 366.7, 444.8, 366.7, 445.0, 369.4,
+446.9, 389.4, 446.9, 389.4, 448.7, 409.5, 452.1, 447.0, 452.1, 447.0,
+455.6, 484.5, 456.5, 494.1, 456.5, 494.1, 457.3, 503.6, 461.1, 544.5,
+461.1, 544.5, 464.8, 585.3, 466.5, 603.5, 466.6, 603.5, 468.2, 621.6,
+469.3, 634.5, 469.2, 634.5, 470.3, 647.3, 471.5, 660.3, 471.7, 660.3,
+472.9, 673.2, 473.3, 677.4, 473.3, 677.4, 473.7, 681.5, 473.9, 684.3,
+474.0, 684.3, 474.2, 687.1, 474.9, 695.0, 474.8, 695.0, 475.5, 702.9,
+476.7, 715.9, 476.8, 715.9, 478.0, 728.9, 480.1, 750.5, 480.0, 750.5,
+482.0, 772.1, 482.3, 775.1, 482.3, 775.1, 482.5, 778.1, 483.9, 793.3,
+485.3, 808.6, 485.3, 808.6, 485.3, 808.6, 483.9, 793.3, 482.5, 778.1,
+482.3, 775.1, 482.3, 775.1, 482.0, 772.1, 480.0, 750.5, 480.1, 750.5,
+478.0, 728.9, 476.8, 715.9, 476.7, 715.9, 475.5, 702.9, 472.9, 675.1,
+472.9, 675.1, 470.3, 647.3, 469.3, 635.9, 469.4, 635.9, 468.4, 624.5,
+468.3, 623.1, 468.3, 623.1, 468.2, 621.6, 466.6, 603.5, 466.5, 603.5,
+464.8, 585.3, 461.1, 544.5, 461.1, 544.5, 457.3, 503.6, 456.5, 494.1,
+456.5, 494.1, 455.6, 484.5, 452.1, 447.0, 452.1, 447.0, 448.7, 409.5,
+446.9, 389.4, 446.9, 389.4, 445.0, 369.4, 438.6, 302.8, 438.2, 302.9,
+432.1, 236.3, 431.6, 223.8, 431.2, 219.5, 431.0, 219.5, 430.8, 215.1,
+429.9, 201.0, 423.5, 197.5, 429.1, 186.9, 427.2, 190.5, 437.8, 193.7,
+438.3, 201.1, 439.0, 212.2, 437.1, 213.6, 431.6, 223.8, 94.7, 97.2,
+96.3, 96.3, 94.0, 92.2, 93.3, 87.3, 91.4, 73.5, 91.4, 73.5,
+89.5, 59.8, 88.5, 52.6, 84.6, 48.1, 87.6, 45.5, 100.2, 42.2,
+100.2, 42.2, 112.9, 38.9, 122.8, 39.1, 132.9, 43.7, 132.6, 46.2,
+130.6, 63.5, 120.5, 62.4, 108.5, 78.6, 101.6, 87.9, 103.9, 91.9,
+94.7, 97.2, 236.1, 70.1, 237.2, 70.5, 237.2, 74.9, 235.3, 77.7,
+233.3, 80.6, 231.3, 82.1, 228.3, 81.5, 227.1, 73.6, 213.7, 72.4,
+198.1, 70.3, 187.3, 66.3, 178.2, 59.9, 176.5, 62.4, 179.9, 57.6,
+189.0, 64.0, 201.4, 65.6, 203.1, 65.8, 203.1, 65.8, 204.7, 66.0,
+207.8, 66.4, 207.8, 66.4, 210.8, 66.8, 223.5, 68.4, 225.0, 65.1,
+236.1, 70.1, 239.1, 42.7, 241.4, 39.6, 239.6, 38.3, 240.1, 33.8,
+241.7, 19.5, 235.9, 15.3, 243.2, 5.2, 254.1, 2.4, 254.1, 2.4,
+264.9, -0.3, 262.4, 22.3, 253.8, 22.5, 239.1, 42.7, 264.9, -0.3,
+281.5, -4.7, 281.5, -4.7, 298.2, -9.0, 293.4, -4.2, 289.0, 0.5,
+290.4, 2.4, 281.5, 15.3, 281.5, 15.3, 272.6, 28.3, 271.6, 29.7,
+271.6, 29.7, 270.6, 31.1, 270.6, 31.2, 270.6, 31.2, 270.6, 31.2,
+267.6, 35.6, 267.6, 35.6, 264.6, 39.9, 257.8, 49.7, 257.8, 49.7,
+251.1, 59.5, 245.9, 67.1, 246.6, 67.8, 240.6, 74.8, 238.8, 76.9,
+235.8, 78.2, 235.3, 77.7, 237.2, 74.9, 237.2, 70.5, 236.1, 70.1,
+237.6, 56.4, 234.1, 55.0, 239.1, 42.7, 253.8, 22.5, 262.4, 22.3,
+264.9, -0.3, 202.2, 95.7, 215.3, 88.6, 229.1, 86.3, 228.3, 81.5,
+231.3, 82.1, 233.3, 80.6, 235.3, 77.7, 235.8, 78.2, 238.8, 76.9,
+240.6, 74.8, 223.0, 102.9, 229.0, 115.3, 202.9, 129.5, 209.8, 125.8,
+195.3, 108.8, 202.2, 95.7, 202.9, 129.5, 202.9, 131.1, 202.0, 132.5,
+200.8, 132.6, 185.0, 134.2, 184.8, 132.8, 168.8, 133.0, 156.7, 133.2,
+156.7, 133.2, 144.7, 133.3, 142.7, 133.4, 142.0, 132.4, 140.7, 133.4,
+164.5, 120.3, 164.3, 119.7, 186.7, 104.2, 194.5, 100.0, 194.5, 100.0,
+202.2, 95.7, 195.3, 108.8, 209.8, 125.8, 202.9, 129.5, 167.7, 180.7,
+147.7, 192.0, 153.2, 201.8, 138.8, 222.8, 136.8, 225.6, 137.5, 226.5,
+134.9, 228.4, 135.5, 232.9, 120.5, 231.5, 114.4, 240.4, 114.8, 240.2,
+113.1, 237.7, 113.9, 236.9, 139.8, 207.9, 135.3, 199.1, 167.7, 180.7,
+143.9, 642.6, 147.6, 620.7, 147.6, 620.7, 151.3, 598.8, 157.1, 641.0,
+162.5, 640.3, 175.1, 681.5, 177.5, 690.6, 176.4, 690.9, 177.7, 700.4,
+179.3, 711.9, 179.3, 711.9, 180.9, 723.4, 182.7, 737.0, 182.7, 737.0,
+184.6, 750.6, 184.7, 751.0, 184.6, 751.1, 184.7, 751.5, 171.2, 715.6,
+171.3, 715.6, 157.8, 679.7, 156.0, 674.9, 156.0, 674.9, 154.3, 670.2,
+149.1, 656.4, 144.5, 656.6, 143.9, 642.6, 125.1, 606.5, 125.7, 587.3,
+144.0, 585.9, 141.4, 568.5, 139.3, 630.5, 139.6, 630.5, 137.8, 692.5,
+152.3, 658.4, 123.9, 649.3, 125.1, 606.5, 95.0, 640.0, 97.5, 614.8,
+98.9, 614.8, 100.0, 589.5, 104.7, 567.6, 107.5, 568.2, 115.1, 546.9,
+120.5, 531.4, 124.2, 531.8, 126.0, 515.9, 122.8, 543.6, 119.2, 543.2,
+112.4, 570.4, 108.5, 585.7, 108.5, 585.7, 104.7, 601.1, 102.4, 610.2,
+102.4, 610.2, 100.1, 619.4, 97.5, 629.7, 94.9, 629.7, 95.0, 640.0,
+10.6, 447.0, 22.3, 456.0, 16.9, 463.2, 23.2, 479.3, 25.8, 485.7,
+27.2, 485.5, 28.3, 492.1, 28.9, 505.1, 27.6, 505.3, 29.4, 518.2,
+24.2, 514.1, 21.7, 515.4, 19.0, 510.1, 15.9, 505.5, 14.4, 506.5,
+9.8, 503.0, 7.7, 499.0, 9.9, 497.9, 9.9, 492.8, 10.1, 481.1,
+10.1, 481.1, 10.2, 469.4, 10.4, 458.2, 15.8, 451.1, 10.6, 447.0,
+-22.1, 363.9, -22.7, 362.5, -22.7, 362.5, -23.3, 361.1, -25.7, 355.0,
+-26.1, 355.1, -28.1, 348.9, -28.3, 348.1, -27.4, 347.8, -27.6, 347.1,
+-24.5, 355.0, -25.0, 355.2, -22.3, 363.3, -22.2, 363.6, -22.2, 363.6,
+-22.1, 363.9, -24.7, 334.6, -20.5, 316.8, -20.4, 316.8, -16.2, 299.0,
+-16.2, 299.0, -15.8, 297.4, -15.4, 295.8, -12.0, 279.2, -11.2, 279.4,
+-7.1, 263.0, -3.2, 247.2, -3.2, 247.1, 0.6, 231.3, -3.2, 247.1,
+-3.2, 247.2, -7.1, 263.0, -11.2, 279.4, -12.0, 279.2, -15.4, 295.8,
+-15.8, 297.4, -16.2, 299.0, -16.2, 299.0, -19.1, 311.6, -19.1, 311.6,
+-22.1, 324.1, -23.3, 329.4, -23.4, 329.3, -24.7, 334.6, 30.7, 301.5,
+31.6, 294.0, 33.4, 293.8, 32.5, 286.5, 34.3, 297.0, 38.5, 298.0,
+36.1, 307.5, 37.1, 313.2, 37.1, 313.2, 38.1, 318.9, 38.5, 321.0,
+38.5, 321.0, 38.9, 323.2, 39.0, 324.0, 38.9, 324.0, 39.1, 324.7,
+34.8, 313.2, 32.8, 313.5, 30.7, 301.5, 77.0, 541.9, 79.2, 544.8,
+76.2, 547.2, 78.4, 549.9, 55.7, 518.9, 55.4, 519.1, 32.4, 488.3,
+38.9, 497.4, 39.6, 496.9, 46.7, 505.5, 61.9, 523.7, 63.3, 522.7,
+77.0, 541.9, 774.0, 706.6, 772.4, 713.4, 769.6, 713.9, 770.7, 720.3,
+770.8, 720.0, 770.4, 719.9, 770.2, 719.5, 768.7, 717.2, 768.1, 717.4,
+767.2, 714.9, 757.7, 681.8, 756.9, 682.0, 746.6, 649.2, 747.7, 652.9,
+748.3, 652.7, 750.0, 656.2, 762.0, 681.4, 765.5, 680.3, 774.0, 706.6,
+745.8, 465.5, 745.6, 465.3, 745.7, 465.1, 745.7, 464.8, 744.9, 457.9,
+747.0, 452.1, 744.0, 451.0, 767.8, 459.9, 767.8, 463.2, 787.2, 480.4,
+783.7, 494.5, 799.8, 504.6, 819.7, 518.2, 820.2, 518.7, 819.5, 519.3,
+819.2, 520.3, 818.8, 522.1, 819.5, 522.9, 818.4, 523.8, 818.2, 523.9,
+817.5, 523.1, 816.7, 522.4, 781.2, 494.0, 781.1, 494.2, 745.8, 465.5,
+728.5, 558.4, 726.8, 556.9, 725.3, 557.0, 725.0, 555.3, 723.8, 548.1,
+723.8, 548.1, 722.5, 540.9, 722.7, 542.5, 723.0, 542.4, 723.5, 543.9,
+726.0, 551.2, 727.5, 551.0, 728.5, 558.4, 811.9, 675.4, 796.6, 675.8,
+796.6, 675.2, 781.4, 676.2, 776.8, 671.7, 782.5, 663.2, 787.3, 651.6,
+787.0, 652.4, 788.9, 653.1, 790.4, 654.6, 797.3, 661.3, 797.3, 661.3,
+804.3, 668.0, 808.1, 671.7, 809.7, 676.2, 811.9, 675.4, 736.6, 629.3,
+738.1, 633.5, 737.6, 633.7, 739.6, 637.7, 741.7, 649.6, 741.7, 649.6,
+743.8, 661.6, 728.6, 636.5, 724.9, 638.7, 706.0, 615.9, 708.2, 625.6,
+722.7, 620.4, 736.6, 629.3, 706.0, 615.9, 701.3, 610.3, 695.8, 609.3,
+696.7, 604.7, 696.3, 604.2, 696.3, 604.1, 696.0, 603.6, 690.6, 595.2,
+687.4, 596.0, 685.3, 586.9, 684.6, 584.2, 687.8, 583.4, 690.4, 580.0,
+694.8, 574.1, 694.8, 574.1, 699.3, 568.1, 701.3, 565.4, 704.0, 563.8,
+703.4, 562.7, 708.9, 597.6, 719.9, 595.9, 736.5, 629.0, 736.6, 629.2,
+736.5, 629.2, 736.6, 629.3, 722.7, 620.4, 708.2, 625.6, 706.0, 615.9,
+628.6, 378.5, 639.5, 392.5, 639.5, 392.5, 650.4, 406.5, 654.9, 441.5,
+646.0, 442.7, 641.6, 478.9, 641.5, 479.0, 641.5, 479.0, 641.5, 479.0,
+641.1, 482.9, 641.1, 482.9, 640.6, 486.8, 639.5, 496.1, 635.1, 498.0,
+638.3, 505.4, 632.9, 492.8, 637.2, 490.9, 636.1, 476.4, 634.1, 450.4,
+634.1, 450.4, 632.1, 424.4, 630.4, 401.5, 618.0, 388.9, 628.6, 378.5,
+641.6, 478.9, 646.0, 442.7, 654.9, 441.5, 650.4, 406.5, 659.8, 418.7,
+662.6, 432.2, 669.3, 430.8, 669.3, 431.2, 669.6, 431.2, 669.9, 431.6,
+665.0, 440.8, 664.6, 440.6, 659.2, 449.5, 650.4, 464.2, 639.0, 466.5,
+641.6, 478.9, 914.0, 381.7, 920.2, 370.0, 908.9, 364.0, 903.7, 346.4,
+903.5, 345.5, 903.5, 345.5, 903.2, 344.7, 896.6, 321.9, 896.6, 321.9,
+890.0, 299.2, 888.4, 293.8, 888.2, 293.8, 886.8, 288.4, 886.8, 288.3,
+887.1, 288.3, 887.3, 288.2, 895.2, 284.4, 895.2, 284.4, 903.1, 280.6,
+905.1, 279.6, 907.3, 278.8, 907.2, 278.6, 914.2, 299.5, 915.4, 300.0,
+916.8, 321.8, 918.8, 351.5, 926.7, 357.7, 914.0, 381.7, 916.8, 321.8,
+940.6, 341.7, 935.4, 360.4, 933.8, 398.2, 929.2, 388.1, 923.5, 382.0,
+914.3, 382.6, 914.0, 382.4, 914.0, 382.1, 914.0, 381.7, 926.7, 357.7,
+918.8, 351.5, 916.8, 321.8, 869.9, 395.5, 869.6, 395.5, 869.6, 393.4,
+869.3, 391.2, 866.2, 370.9, 866.2, 370.9, 863.2, 350.6, 862.8, 348.1,
+862.8, 348.1, 862.4, 345.6, 861.4, 338.7, 861.4, 338.7, 860.4, 331.9,
+859.2, 323.7, 857.8, 323.7, 858.0, 315.5, 857.9, 319.1, 859.2, 319.2,
+860.5, 322.8, 865.3, 336.2, 868.2, 335.8, 870.1, 349.6, 872.9, 370.0,
+870.0, 370.4, 869.9, 391.2, 869.9, 393.4, 869.9, 395.5, 869.9, 395.5,
+860.5, 322.8, 859.2, 319.2, 857.9, 319.1, 858.0, 315.5, 856.6, 309.4,
+853.5, 305.6, 856.1, 303.1, 867.9, 292.0, 870.8, 290.2, 886.8, 288.4,
+888.2, 293.8, 888.4, 293.8, 890.0, 299.2, 887.6, 305.1, 884.3, 303.7,
+878.7, 308.3, 869.6, 315.5, 870.9, 319.1, 860.5, 322.8, 694.7, 409.5,
+693.6, 408.7, 690.9, 414.1, 688.8, 413.4, 680.5, 407.7, 674.0, 400.5,
+672.2, 402.1, 672.2, 401.6, 671.4, 401.6, 670.6, 401.0, 682.8, 405.0,
+684.5, 402.5, 694.7, 409.5, 860.4, 331.9, 861.4, 338.7, 861.4, 338.7,
+862.4, 345.6, 858.9, 351.0, 855.0, 348.4, 847.6, 351.2, 844.2, 352.5,
+844.2, 352.5, 840.8, 353.8, 820.4, 361.5, 820.4, 361.5, 799.9, 369.3,
+792.1, 372.2, 792.1, 372.2, 784.2, 375.2, 782.6, 375.8, 782.5, 375.6,
+781.0, 376.4, 805.0, 362.6, 805.1, 362.9, 829.3, 349.3, 835.8, 345.6,
+835.8, 345.6, 842.4, 342.0, 851.4, 336.9, 852.6, 330.4, 860.4, 331.9,
+625.4, 361.6, 634.8, 368.9, 633.8, 370.2, 642.2, 378.7, 646.5, 383.2,
+645.7, 384.7, 650.9, 387.6, 634.8, 376.6, 636.3, 372.9, 618.6, 365.6,
+607.2, 357.8, 607.2, 357.8, 595.7, 350.0, 591.1, 346.9, 591.1, 346.9,
+586.5, 343.8, 560.5, 326.1, 560.5, 326.1, 534.6, 308.4, 515.9, 289.9,
+512.4, 293.3, 490.3, 278.3, 494.6, 281.3, 494.8, 281.0, 499.3, 283.8,
+500.2, 284.4, 500.2, 284.4, 501.2, 285.0, 543.6, 311.2, 543.6, 311.2,
+586.0, 337.3, 592.2, 341.2, 592.2, 341.2, 598.4, 345.0, 611.9, 353.3,
+612.9, 352.0, 625.4, 361.6, 251.1, 59.5, 257.8, 49.7, 257.8, 49.7,
+264.6, 39.9, 245.2, 81.7, 243.4, 80.9, 222.1, 121.8, 201.5, 161.7,
+201.5, 161.7, 180.9, 201.5, 171.0, 220.5, 170.9, 220.4, 161.1, 239.4,
+158.7, 243.9, 156.5, 248.6, 156.5, 248.6, 156.5, 248.6, 158.7, 243.9,
+161.1, 239.4, 180.0, 201.5, 180.0, 201.5, 199.0, 163.7, 219.1, 123.5,
+219.1, 123.5, 239.2, 83.3, 245.2, 71.4, 244.4, 70.9, 251.1, 59.5,
+474.9, 881.8, 473.8, 882.9, 470.8, 882.1, 470.7, 882.0, 466.7, 848.4,
+468.7, 848.1, 466.7, 814.3, 465.8, 799.3, 465.8, 799.3, 464.9, 784.3,
+463.3, 759.1, 463.2, 759.1, 461.7, 734.0, 460.1, 708.3, 460.2, 708.3,
+458.7, 682.6, 457.9, 669.3, 457.9, 669.3, 457.1, 655.9, 455.3, 625.3,
+455.3, 625.3, 453.5, 594.6, 453.1, 588.3, 453.1, 588.3, 452.8, 581.9,
+452.6, 578.7, 452.6, 578.7, 452.4, 575.5, 451.9, 567.7, 451.9, 567.7,
+451.5, 559.9, 449.9, 533.5, 450.3, 533.5, 448.3, 507.2, 454.4, 587.2,
+454.0, 587.3, 459.7, 667.4, 462.4, 705.5, 462.4, 705.5, 465.1, 743.6,
+468.5, 791.8, 468.5, 791.8, 471.9, 840.0, 473.3, 859.1, 473.3, 859.1,
+474.7, 878.3, 474.8, 880.1, 475.7, 881.1, 474.9, 881.8, 140.0, 48.9,
+137.3, 46.4, 136.3, 47.5, 132.6, 46.2, 132.9, 43.7, 122.8, 39.1,
+112.9, 38.9, 117.5, 37.7, 117.5, 37.7, 122.0, 36.6, 132.0, 40.2,
+132.1, 41.6, 140.0, 48.9, 168.8, 133.0, 184.8, 132.8, 185.0, 134.2,
+200.8, 132.6, 200.1, 132.2, 196.4, 139.0, 192.0, 145.4, 182.2, 159.7,
+183.0, 160.3, 172.4, 174.0, 173.0, 173.1, 172.2, 172.5, 172.1, 171.1,
+171.0, 158.5, 171.0, 158.5, 169.9, 145.9, 169.7, 143.6, 169.7, 143.6,
+169.5, 141.3, 169.2, 137.2, 168.1, 133.2, 168.8, 133.0, 142.5, 800.7,
+142.4, 726.7, 142.4, 726.7, 142.2, 652.8, 142.1, 647.8, 143.1, 647.7,
+143.9, 642.7, 144.9, 660.2, 143.8, 660.2, 143.6, 677.7, 143.1, 739.2,
+139.1, 739.4, 142.5, 800.7, 112.4, 570.4, 119.2, 543.2, 122.8, 543.6,
+126.0, 515.9, 127.1, 511.9, 127.4, 512.0, 128.8, 508.0, 135.1, 490.1,
+135.1, 490.1, 141.5, 472.1, 141.7, 471.6, 142.0, 471.5, 141.9, 471.0,
+141.9, 472.3, 141.9, 472.3, 141.9, 473.6, 127.5, 522.1, 130.1, 523.1,
+112.4, 570.4, 132.1, 396.2, 135.2, 425.6, 135.2, 425.6, 138.4, 454.9,
+109.9, 423.8, 122.8, 412.0, 107.3, 369.1, 106.3, 366.5, 106.3, 366.5,
+105.4, 363.9, 98.1, 343.8, 98.1, 343.8, 90.8, 323.7, 84.3, 305.5,
+84.3, 305.5, 77.7, 287.3, 72.4, 272.6, 72.4, 272.6, 67.0, 257.9,
+64.0, 249.4, 64.0, 249.4, 60.9, 240.9, 58.1, 233.2, 58.4, 225.5,
+55.3, 225.4, 59.1, 225.6, 58.8, 233.2, 62.3, 240.9, 63.3, 243.2,
+63.3, 243.2, 64.3, 245.5, 70.8, 259.9, 70.8, 259.9, 77.2, 274.3,
+90.8, 304.5, 90.8, 304.5, 104.4, 334.7, 106.6, 339.6, 106.6, 339.6,
+108.8, 344.5, 120.5, 370.3, 124.8, 369.2, 132.1, 396.2, 73.9, 510.3,
+74.7, 516.4, 72.5, 516.8, 73.7, 522.7, 63.8, 473.9, 62.6, 474.0,
+56.6, 424.6, 60.5, 456.8, 63.0, 456.5, 69.5, 488.4, 71.7, 499.4,
+72.6, 499.3, 73.9, 510.3, -25.5, 438.4, -32.2, 422.8, -39.0, 422.7,
+-38.9, 407.2, -40.1, 403.8, -40.7, 403.4, -40.2, 400.0, -38.5, 387.8,
+-34.0, 376.1, -34.5, 375.9, -29.2, 377.4, -32.6, 389.3, -30.6, 402.7,
+-28.1, 420.5, -20.0, 435.3, -25.5, 438.4, 22.8, 369.7, 23.3, 379.1,
+23.2, 379.1, 23.7, 388.5, 25.5, 440.3, 26.0, 440.3, 28.3, 492.1,
+27.2, 485.5, 25.8, 485.7, 23.2, 479.3, 22.2, 474.7, 23.2, 474.4,
+23.2, 469.6, 23.1, 435.6, 23.1, 435.6, 22.9, 401.7, 22.9, 387.5,
+22.9, 387.5, 22.8, 373.4, 22.8, 371.5, 22.9, 371.5, 22.8, 369.7,
+-7.1, 263.0, -3.2, 247.2, -3.2, 247.1, 0.6, 231.3, 2.8, 222.5,
+2.7, 222.5, 5.0, 213.7, 8.2, 201.4, 6.4, 200.6, 11.4, 189.1,
+12.6, 184.6, 11.6, 184.0, 13.9, 180.0, 13.5, 181.6, 14.2, 181.8,
+14.5, 183.5, 16.1, 189.6, 14.8, 189.9, 15.1, 196.4, 21.6, 253.7,
+15.7, 254.3, 16.3, 312.3, 18.3, 298.8, 9.2, 297.5, 2.2, 282.6,
+-2.5, 272.8, -6.8, 272.9, -7.1, 263.0, 25.8, 421.8, 24.7, 405.2,
+24.2, 405.2, 23.7, 388.5, 23.2, 379.1, 23.3, 379.1, 22.8, 369.7,
+22.8, 369.7, 22.8, 369.7, 22.8, 369.6, 22.8, 369.6, 22.8, 369.5,
+22.8, 369.5, 19.7, 343.1, 26.0, 342.4, 29.1, 315.3, 35.6, 352.4,
+27.9, 353.7, 26.8, 392.2, 26.7, 393.2, 26.7, 393.2, 26.7, 394.2,
+26.2, 408.0, 20.2, 411.2, 25.8, 421.8, 55.5, 418.2, 55.0, 421.2,
+56.0, 421.4, 56.6, 424.6, 62.6, 474.0, 63.8, 473.9, 73.7, 522.7,
+75.4, 532.3, 71.5, 538.3, 77.0, 541.9, 63.3, 522.7, 61.9, 523.7,
+46.7, 505.5, 40.6, 486.7, 48.9, 484.0, 51.0, 462.5, 53.2, 440.3,
+52.2, 440.2, 55.5, 418.2, 40.2, 617.2, 64.0, 620.8, 64.0, 620.8,
+87.8, 624.5, 87.7, 638.4, 88.9, 638.4, 89.9, 652.3, 89.9, 652.3,
+89.7, 652.3, 89.4, 652.2, 80.8, 650.5, 80.8, 650.5, 72.2, 648.9,
+62.8, 647.0, 59.0, 650.8, 53.4, 645.1, 43.1, 634.9, 38.9, 618.0,
+40.2, 617.2, 53.4, 645.1, 53.2, 643.6, 47.9, 644.1, 42.5, 643.0,
+35.6, 641.6, 35.6, 641.6, 28.8, 640.3, 21.0, 638.8, 17.9, 641.9,
+13.1, 637.2, 7.2, 631.4, 5.5, 627.2, 7.3, 619.4, 7.9, 620.2,
+18.8, 616.3, 18.7, 614.1, 18.6, 614.0, 18.8, 614.0, 19.0, 613.9,
+19.7, 612.1, 29.6, 615.5, 40.2, 617.2, 38.9, 618.0, 43.1, 634.9,
+53.4, 645.1, 75.8, 715.5, 69.0, 712.1, 69.0, 712.1, 62.2, 708.7,
+58.6, 707.9, 59.3, 705.0, 56.3, 701.2, 67.0, 706.5, 68.6, 706.3,
+75.8, 715.5, 789.1, 644.2, 787.8, 644.4, 788.2, 647.9, 787.3, 651.6,
+782.5, 663.2, 776.8, 671.7, 781.4, 676.2, 781.2, 676.2, 781.0, 677.3,
+781.1, 677.4, 776.3, 677.8, 777.6, 692.0, 774.0, 706.6, 765.5, 680.3,
+762.0, 681.4, 750.0, 656.2, 752.4, 646.1, 769.1, 646.7, 789.1, 644.2,
+750.0, 656.2, 748.3, 652.7, 747.7, 652.9, 746.6, 649.2, 741.5, 633.0,
+741.7, 632.9, 736.4, 616.8, 754.8, 618.3, 757.0, 625.1, 773.1, 619.7,
+778.2, 625.5, 784.0, 622.2, 794.7, 621.4, 794.7, 621.4, 794.2, 623.3,
+793.8, 625.1, 791.5, 634.7, 795.2, 639.9, 789.1, 644.2, 769.1, 646.7,
+752.4, 646.1, 750.0, 656.2, 748.1, 484.6, 742.7, 479.3, 750.7, 468.2,
+745.8, 465.5, 781.1, 494.2, 781.2, 494.0, 816.7, 522.4, 809.9, 516.5,
+808.6, 518.0, 800.5, 513.5, 793.3, 509.5, 793.3, 509.5, 786.1, 505.6,
+767.1, 495.1, 762.9, 499.3, 748.1, 484.6, 907.8, 630.0, 907.7, 629.7,
+907.1, 629.8, 907.1, 629.4, 904.8, 615.5, 904.2, 615.5, 903.1, 601.5,
+903.9, 612.2, 904.8, 612.1, 906.6, 622.8, 907.2, 626.4, 907.5, 626.4,
+907.8, 630.0, 595.7, 350.0, 607.2, 357.8, 607.2, 357.8, 618.6, 365.6,
+625.2, 368.3, 623.6, 372.1, 628.6, 378.5, 618.0, 388.9, 630.4, 401.5,
+632.1, 424.4, 604.2, 402.0, 614.7, 388.9, 597.3, 353.4, 596.5, 351.7,
+597.0, 350.8, 595.7, 350.0, 659.2, 449.5, 664.6, 440.6, 665.0, 440.8,
+669.9, 431.6, 678.3, 442.4, 678.3, 442.4, 686.6, 453.1, 683.8, 457.8,
+665.3, 457.3, 659.2, 449.5, 948.0, 402.8, 948.7, 413.7, 949.3, 413.7,
+949.4, 424.6, 949.8, 448.4, 949.8, 448.4, 950.3, 472.2, 948.5, 462.5,
+948.1, 462.5, 945.9, 452.8, 942.7, 430.1, 943.4, 430.0, 940.8, 407.3,
+937.7, 379.2, 924.2, 357.6, 934.6, 351.1, 927.8, 355.4, 942.7, 376.7,
+948.0, 402.8, 934.6, 351.1, 927.7, 310.9, 923.3, 310.1, 925.5, 269.8,
+925.6, 266.1, 939.6, 265.2, 939.3, 263.2, 942.6, 333.0, 943.6, 333.0,
+948.0, 402.8, 942.7, 376.7, 927.8, 355.4, 934.6, 351.1, 914.7, 275.0,
+914.5, 273.9, 918.0, 273.4, 921.4, 271.7, 923.2, 270.9, 923.2, 270.9,
+925.0, 270.0, 925.2, 269.9, 925.5, 269.9, 925.5, 269.8, 923.3, 310.1,
+927.7, 310.9, 934.6, 351.1, 924.2, 357.6, 937.7, 379.2, 940.8, 407.3,
+923.8, 342.2, 924.2, 341.6, 914.7, 275.0, 940.8, 407.3, 943.4, 430.0,
+942.7, 430.1, 945.9, 452.8, 939.9, 425.5, 945.1, 423.2, 933.8, 398.2,
+935.4, 360.4, 940.6, 341.7, 916.8, 321.8, 915.4, 300.0, 914.2, 299.5,
+907.2, 278.6, 907.1, 277.0, 914.9, 275.8, 914.7, 275.0, 924.2, 341.6,
+923.8, 342.2, 940.8, 407.3, 760.6, 353.1, 805.7, 329.5, 805.7, 329.5,
+850.7, 305.9, 823.3, 315.5, 825.7, 322.5, 800.7, 339.1, 776.8, 355.0,
+776.8, 355.0, 752.8, 370.9, 744.0, 376.7, 738.7, 374.4, 735.2, 382.6,
+742.6, 365.5, 745.0, 363.5, 760.6, 353.1, 735.2, 382.6, 717.6, 397.7,
+715.7, 395.5, 696.2, 408.5, 695.5, 409.0, 695.3, 409.6, 694.7, 409.5,
+684.5, 402.5, 682.8, 405.0, 670.6, 401.0, 670.3, 400.8, 670.3, 400.8,
+669.9, 400.6, 716.7, 380.0, 715.3, 376.8, 760.6, 353.1, 745.0, 363.5,
+742.6, 365.5, 735.2, 382.6, 829.3, 349.3, 805.1, 362.9, 805.0, 362.6,
+781.0, 376.4, 775.0, 379.5, 774.6, 378.8, 768.3, 381.2, 766.2, 382.0,
+766.2, 382.0, 764.0, 382.8, 751.7, 387.5, 751.7, 387.5, 739.4, 392.2,
+727.0, 396.9, 727.0, 396.9, 714.5, 401.6, 705.4, 405.0, 702.9, 402.3,
+696.2, 408.5, 715.7, 395.5, 717.6, 397.7, 735.2, 382.6, 738.7, 374.4,
+744.0, 376.7, 752.8, 370.9, 790.2, 357.7, 794.5, 342.5, 829.3, 349.3,
+823.9, 404.0, 808.4, 391.3, 812.1, 386.9, 800.2, 369.8, 800.1, 369.5,
+800.0, 369.2, 799.9, 369.3, 820.4, 361.5, 820.4, 361.5, 840.8, 353.8,
+846.5, 358.5, 834.3, 373.1, 827.8, 392.5, 825.8, 398.3, 822.2, 402.7,
+823.9, 404.0, 520.2, 128.3, 522.8, 135.7, 526.6, 134.1, 530.8, 141.2,
+541.2, 158.9, 540.1, 159.5, 549.5, 177.8, 563.9, 205.9, 566.4, 204.8,
+578.3, 234.0, 576.1, 228.6, 572.1, 230.5, 569.0, 225.3, 554.9, 201.4,
+556.5, 200.5, 544.1, 175.8, 542.3, 172.2, 542.3, 172.2, 540.5, 168.7,
+530.3, 148.5, 527.6, 149.4, 520.2, 128.3, 649.0, 299.7, 641.0, 276.2,
+628.3, 280.5, 607.6, 261.2, 603.6, 257.5, 603.6, 257.5, 599.6, 253.8,
+588.9, 243.9, 586.1, 245.8, 578.3, 234.0, 566.4, 204.8, 563.9, 205.9,
+549.5, 177.8, 581.3, 186.8, 575.0, 209.0, 600.5, 240.3, 624.8, 270.0,
+637.5, 265.7, 649.0, 299.7, 621.3, 242.7, 629.3, 253.2, 624.4, 257.5,
+633.4, 266.7, 601.5, 234.1, 604.4, 231.3, 575.4, 195.8, 570.5, 189.8,
+571.2, 189.2, 565.6, 183.9, 578.8, 196.4, 578.2, 197.1, 590.7, 210.4,
+606.0, 226.5, 607.9, 225.1, 621.3, 242.7, 607.6, 261.2, 628.3, 280.5,
+641.0, 276.2, 649.0, 299.7, 666.4, 315.9, 667.6, 314.8, 683.8, 332.1,
+680.1, 328.1, 678.1, 330.1, 674.0, 326.3, 640.0, 294.7, 639.4, 295.1,
+607.6, 261.2, 538.5, 273.3, 548.2, 283.1, 548.2, 283.1, 557.8, 293.0,
+582.8, 318.3, 582.8, 318.3, 607.8, 343.7, 616.6, 352.7, 617.9, 362.6,
+625.4, 361.6, 612.9, 352.0, 611.9, 353.3, 598.4, 345.0, 568.0, 314.6,
+570.6, 312.1, 542.8, 279.0, 542.2, 278.3, 542.2, 278.2, 541.6, 277.4,
+540.5, 275.8, 540.5, 275.8, 539.3, 274.3, 538.9, 273.8, 538.9, 273.7,
+538.5, 273.3, 671.6, 22.5, 673.6, 20.2, 674.3, 18.8, 676.7, 19.0,
+689.0, 32.0, 698.7, 22.8, 720.8, 26.7, 691.3, 60.0, 674.9, 71.6,
+633.3, 68.0, 650.3, 69.5, 651.8, 44.7, 671.6, 22.5, 633.3, 68.0,
+619.2, 79.9, 616.0, 76.2, 598.7, 84.3, 570.9, 97.4, 571.6, 99.2,
+543.0, 110.6, 550.9, 107.4, 550.2, 105.6, 557.4, 100.7, 560.1, 98.9,
+560.1, 98.9, 562.7, 97.1, 566.7, 94.4, 566.7, 94.4, 570.6, 91.6,
+605.0, 68.1, 605.0, 68.1, 639.3, 44.6, 655.4, 33.6, 667.9, 36.8,
+671.6, 22.5, 651.8, 44.7, 650.3, 69.5, 633.3, 68.0, 623.1, 94.6,
+622.0, 94.0, 621.5, 95.0, 619.9, 95.3, 615.1, 96.3, 615.1, 96.3,
+610.4, 97.3, 600.3, 99.5, 600.3, 99.5, 590.2, 101.6, 580.0, 103.8,
+580.0, 103.8, 569.8, 106.0, 569.2, 106.1, 569.2, 106.1, 568.7, 106.2,
+561.4, 107.8, 561.4, 107.8, 554.1, 109.4, 547.3, 110.8, 547.4, 111.5,
+540.5, 112.3, 541.8, 112.1, 541.7, 111.2, 543.0, 110.6, 571.6, 99.2,
+570.9, 97.4, 598.7, 84.3, 599.2, 84.1, 599.4, 84.6, 600.1, 84.9,
+611.6, 89.7, 612.1, 88.8, 623.1, 94.6, 528.8, -39.2, 527.3, -47.3,
+543.8, -57.6, 542.7, -58.6, 554.3, -47.9, 557.9, -30.8, 549.9, -19.7,
+550.9, -21.1, 530.9, -27.9, 528.8, -39.2, 686.9, -7.4, 688.8, -8.6,
+700.2, 0.9, 699.1, 3.6, 689.6, 2.0, 678.1, 20.5, 676.7, 19.0,
+674.3, 18.8, 673.6, 20.2, 671.6, 22.5, 667.9, 36.8, 655.4, 33.6,
+639.3, 44.6, 643.9, 42.0, 643.1, 40.5, 646.9, 36.3, 666.9, 14.4,
+662.7, 7.7, 686.9, -7.4, 432.7, -43.8, 494.1, -60.9, 493.9, -61.6,
+555.8, -76.8, 554.4, -76.4, 555.1, -74.3, 553.5, -73.6, 548.9, -71.4,
+548.5, -72.3, 543.4, -71.1, 508.4, -62.5, 508.4, -62.5, 473.5, -53.9,
+471.6, -53.4, 471.6, -53.4, 469.8, -53.0, 451.2, -48.4, 451.1, -48.9,
+432.7, -43.8, 223.1, 199.1, 223.1, 199.1, 232.3, 166.6, 241.5, 134.0,
+245.6, 119.3, 245.6, 119.3, 249.8, 104.6, 253.8, 90.4, 253.9, 90.4,
+257.9, 76.1, 260.2, 67.8, 260.2, 67.8, 262.6, 59.6, 266.1, 47.2,
+266.1, 47.2, 269.6, 34.9, 270.1, 33.1, 270.0, 33.1, 270.6, 31.2,
+270.6, 31.2, 270.6, 31.2, 270.6, 31.1, 270.1, 33.0, 270.1, 33.0,
+269.6, 34.9, 266.1, 47.2, 266.1, 47.2, 262.6, 59.6, 260.2, 67.8,
+260.2, 67.8, 257.9, 76.1, 253.9, 90.4, 253.8, 90.4, 249.8, 104.6,
+245.6, 119.3, 245.6, 119.3, 241.5, 134.0, 232.3, 166.6, 223.1, 199.1,
+223.1, 199.1, 149.0, 461.3, 149.0, 461.3, 149.7, 458.6, 150.5, 455.9,
+178.7, 356.3, 175.0, 355.1, 206.8, 256.7, 206.6, 257.2, 214.0, 259.0,
+213.8, 260.1, 210.0, 283.9, 206.3, 283.4, 198.8, 306.6, 194.5, 320.1,
+194.5, 320.1, 190.1, 333.6, 170.3, 394.7, 170.2, 394.7, 150.5, 455.9,
+149.7, 458.6, 149.0, 461.3, 149.0, 461.3, 238.0, 140.7, 239.4, 137.2,
+240.6, 137.6, 241.5, 134.0, 232.3, 166.6, 223.1, 199.1, 223.1, 199.1,
+215.0, 227.9, 215.1, 227.9, 206.8, 256.7, 194.4, 299.9, 194.2, 299.8,
+181.8, 343.0, 179.0, 352.7, 179.1, 352.8, 176.4, 362.5, 165.4, 402.3,
+165.4, 402.3, 154.3, 442.2, 152.4, 449.0, 150.5, 455.9, 150.5, 455.9,
+150.5, 455.9, 152.4, 449.0, 154.3, 442.2, 165.4, 402.3, 165.4, 402.3,
+176.4, 362.5, 179.1, 352.8, 179.0, 352.7, 181.8, 343.0, 189.6, 315.0,
+189.6, 315.0, 197.4, 286.9, 200.1, 277.3, 200.1, 277.3, 202.7, 267.7,
+214.8, 224.2, 214.8, 224.2, 226.9, 180.6, 231.1, 165.6, 231.1, 165.6,
+235.3, 150.5, 235.5, 149.5, 235.5, 149.5, 235.8, 148.5, 236.9, 144.6,
+236.5, 144.5, 238.0, 140.7, 222.1, 121.8, 243.4, 80.9, 245.2, 81.7,
+264.6, 39.9, 267.6, 35.6, 267.6, 35.6, 270.6, 31.2, 269.1, 45.7,
+266.6, 45.4, 262.6, 59.6, 260.2, 67.8, 260.2, 67.8, 257.9, 76.1,
+253.9, 90.4, 253.8, 90.4, 249.8, 104.6, 247.0, 109.7, 244.2, 108.1,
+238.5, 111.6, 230.3, 116.7, 224.7, 114.7, 222.1, 121.8, 161.1, 239.4,
+158.7, 243.9, 156.5, 248.6, 156.5, 248.6, 156.0, 249.5, 156.0, 249.5,
+155.5, 250.4, 147.2, 266.5, 138.9, 282.6, 138.9, 282.6, 138.9, 282.6,
+147.2, 266.5, 155.5, 250.4, 156.0, 249.5, 156.0, 249.5, 156.5, 248.6,
+156.5, 248.6, 158.7, 243.9, 161.1, 239.4, 464.8, 585.3, 461.1, 544.5,
+461.1, 544.5, 457.3, 503.6, 457.3, 502.5, 458.0, 502.4, 458.7, 501.2,
+460.2, 498.5, 460.2, 498.5, 461.7, 495.7, 462.7, 493.9, 463.8, 493.9,
+463.8, 492.1, 465.4, 538.7, 484.5, 550.0, 464.8, 585.3, 209.1, 647.2,
+209.1, 646.8, 209.3, 646.8, 209.5, 646.5, 212.6, 641.2, 212.6, 641.2,
+215.7, 636.0, 218.1, 631.9, 217.3, 628.6, 220.5, 627.8, 219.5, 628.1,
+220.3, 631.4, 220.0, 634.9, 219.1, 648.1, 219.1, 648.1, 218.1, 661.3,
+214.3, 713.1, 225.7, 716.7, 210.6, 764.9, 221.5, 730.2, 210.1, 726.6,
+209.6, 688.4, 209.5, 676.0, 209.5, 676.0, 209.3, 663.7, 209.2, 655.4,
+209.0, 655.4, 209.1, 647.2, 466.7, 814.3, 468.7, 848.1, 466.7, 848.4,
+470.7, 882.0, 470.1, 884.5, 460.2, 884.2, 450.3, 882.5, 450.5, 882.6,
+450.8, 880.6, 451.3, 878.7, 459.0, 846.5, 464.5, 813.9, 466.7, 814.3,
+131.9, 102.5, 132.2, 103.4, 132.6, 103.2, 133.3, 103.9, 134.2, 104.8,
+134.2, 104.8, 135.1, 105.7, 136.0, 106.7, 136.0, 106.7, 136.9, 107.6,
+144.5, 115.4, 149.7, 114.0, 152.1, 123.1, 147.4, 125.8, 147.4, 125.8,
+142.6, 128.4, 133.5, 119.1, 136.9, 115.6, 131.9, 102.5, 172.1, 171.1,
+172.2, 172.5, 173.0, 173.1, 172.4, 174.0, 172.0, 175.3, 170.6, 175.3,
+170.7, 176.4, 170.5, 173.8, 170.6, 173.2, 172.1, 171.1, 188.5, 778.9,
+183.6, 784.8, 193.4, 790.8, 191.6, 801.6, 200.2, 807.9, 172.4, 831.7,
+175.5, 859.3, 176.2, 858.1, 164.7, 854.8, 164.5, 849.8, 163.8, 836.8,
+169.0, 836.5, 173.5, 823.2, 181.0, 801.1, 174.5, 795.6, 188.5, 778.9,
+124.4, 697.1, 123.6, 699.9, 136.9, 701.5, 137.3, 706.8, 135.6, 765.0,
+131.5, 765.1, 133.9, 823.2, 134.3, 819.7, 127.4, 820.2, 124.7, 815.1,
+126.5, 809.3, 123.7, 808.3, 122.4, 801.6, 120.3, 788.4, 120.1, 788.5,
+117.8, 775.3, 118.5, 736.2, 113.8, 734.1, 124.4, 697.1, 117.8, 775.3,
+117.4, 773.4, 117.4, 773.4, 117.1, 771.4, 109.1, 725.5, 98.5, 724.9,
+101.1, 679.7, 100.7, 686.7, 111.3, 687.3, 121.5, 694.9, 123.0, 696.0,
+124.5, 696.1, 124.4, 697.1, 113.8, 734.1, 118.5, 736.2, 117.8, 775.3,
+113.5, 633.8, 113.4, 625.4, 117.1, 625.4, 120.7, 617.0, 122.9, 611.8,
+126.2, 611.0, 125.1, 606.5, 123.9, 649.3, 152.3, 658.4, 137.8, 692.5,
+137.6, 699.6, 137.6, 699.6, 137.3, 706.8, 136.9, 701.5, 123.6, 699.9,
+124.4, 697.1, 124.5, 696.1, 123.0, 696.0, 121.5, 694.9, 116.3, 664.6,
+113.8, 664.4, 113.5, 633.8, 121.5, 694.9, 111.3, 687.3, 100.7, 686.7,
+101.1, 679.7, 100.1, 673.7, 100.0, 673.7, 99.0, 667.8, 98.9, 666.1,
+99.7, 666.1, 100.4, 664.5, 107.0, 649.1, 118.6, 641.1, 113.5, 633.8,
+113.8, 664.4, 116.3, 664.6, 121.5, 694.9, 104.7, 601.1, 108.5, 585.7,
+108.5, 585.7, 112.4, 570.4, 130.1, 523.1, 127.5, 522.1, 141.9, 473.6,
+141.9, 494.5, 141.9, 494.5, 141.9, 515.4, 129.0, 559.9, 126.7, 560.0,
+104.7, 601.1, 74.1, 373.8, 73.1, 372.4, 73.1, 372.4, 72.1, 371.0,
+72.8, 344.1, 73.9, 344.1, 75.7, 317.2, 75.8, 314.6, 76.0, 314.7,
+76.0, 312.1, 75.6, 328.2, 75.5, 328.2, 75.0, 344.2, 74.5, 359.0,
+75.7, 359.1, 74.1, 373.8, 38.1, 251.5, 39.2, 217.8, 39.2, 217.8,
+40.3, 184.2, 38.1, 193.9, 44.4, 195.3, 48.4, 206.4, 49.9, 210.5,
+49.9, 210.5, 51.4, 214.6, 53.3, 220.0, 53.3, 220.0, 55.3, 225.4,
+58.4, 225.5, 58.1, 233.2, 60.9, 240.9, 55.0, 249.8, 37.7, 250.5,
+38.1, 251.5, 69.5, 488.4, 63.0, 456.5, 60.5, 456.8, 56.6, 424.6,
+56.0, 421.4, 55.0, 421.2, 55.5, 418.2, 52.4, 400.5, 52.4, 400.5,
+49.3, 382.8, 48.7, 379.6, 48.7, 379.6, 48.2, 376.4, 46.4, 366.3,
+46.6, 366.3, 44.6, 356.3, 49.8, 382.7, 49.6, 382.7, 54.6, 409.2,
+62.0, 448.8, 64.4, 448.5, 69.5, 488.4, 104.4, 482.2, 105.1, 470.7,
+92.8, 469.9, 81.3, 457.6, 78.2, 454.3, 75.5, 454.7, 75.1, 451.0,
+72.7, 430.8, 69.3, 428.3, 75.8, 409.9, 73.3, 416.9, 79.5, 419.1,
+83.1, 428.3, 93.7, 455.2, 106.0, 456.0, 104.4, 482.2, 9.9, 492.8,
+9.9, 497.9, 7.7, 499.0, 9.8, 503.0, 5.2, 499.5, 3.7, 500.5,
+0.7, 495.9, -0.1, 494.8, -0.5, 495.0, -1.6, 494.1, -10.5, 465.3,
+-13.6, 466.3, -25.5, 438.4, -20.0, 435.3, -28.1, 420.5, -30.6, 402.7,
+-30.4, 406.9, -28.8, 406.8, -27.0, 410.9, -26.2, 412.5, -26.2, 412.5,
+-25.5, 414.1, -7.8, 453.5, -6.0, 452.8, 9.9, 492.8, 23.2, 469.6,
+23.2, 474.4, 22.2, 474.7, 23.2, 479.3, 16.9, 463.2, 22.3, 456.0,
+10.6, 447.0, -2.7, 413.2, -2.5, 413.1, -15.8, 379.3, -17.1, 376.1,
+-18.6, 372.9, -18.6, 372.9, -18.6, 372.9, -17.1, 376.1, -15.8, 379.3,
+-10.6, 391.4, -10.6, 391.4, -5.3, 403.6, 8.9, 436.6, 10.5, 436.0,
+23.2, 469.6, 16.7, 353.2, 16.8, 359.2, 14.8, 360.0, 16.8, 365.3,
+9.7, 365.8, 1.8, 359.9, 1.7, 354.3, 1.7, 353.8, 12.1, 349.8,
+16.7, 353.2, 26.7, 394.2, 27.9, 354.8, 27.4, 354.7, 29.1, 315.3,
+29.9, 308.7, 29.9, 308.7, 30.7, 302.0, 29.3, 347.1, 28.7, 347.1,
+26.8, 392.2, 26.7, 393.2, 26.7, 393.2, 26.7, 394.2, 51.0, 462.5,
+48.9, 484.0, 40.6, 486.7, 46.7, 505.5, 39.6, 496.9, 38.9, 497.4,
+32.4, 488.3, 31.2, 486.7, 30.0, 486.7, 30.0, 485.1, 29.1, 470.9,
+29.1, 470.9, 28.1, 456.8, 34.9, 416.1, 36.8, 416.2, 48.2, 376.4,
+48.7, 379.6, 48.7, 379.6, 49.3, 382.8, 50.6, 422.6, 51.9, 422.7,
+51.0, 462.5, 49.3, 382.8, 52.4, 400.5, 52.4, 400.5, 55.5, 418.2,
+52.2, 440.2, 53.2, 440.3, 51.0, 462.5, 51.9, 422.7, 50.6, 422.6,
+49.3, 382.8, 43.3, 684.7, 30.8, 668.9, 32.9, 655.3, 18.3, 653.0,
+14.0, 646.2, 10.3, 640.7, 13.1, 637.2, 17.9, 641.9, 21.0, 638.8,
+28.8, 640.3, 40.9, 659.4, 51.2, 675.0, 43.3, 684.7, 713.3, 489.1,
+712.7, 488.6, 713.1, 488.1, 713.0, 487.0, 713.6, 472.0, 710.3, 471.8,
+707.6, 456.6, 726.2, 469.7, 719.9, 478.6, 732.3, 500.6, 732.8, 501.5,
+732.5, 501.9, 733.3, 502.3, 728.0, 499.4, 728.2, 499.0, 723.2, 495.6,
+718.2, 492.3, 717.8, 492.9, 713.3, 489.1, 752.2, 518.9, 756.0, 528.8,
+751.3, 539.8, 754.8, 540.6, 745.8, 538.6, 748.0, 528.5, 741.2, 516.5,
+739.2, 512.8, 736.7, 509.4, 737.1, 509.1, 738.4, 508.1, 740.9, 511.5,
+744.7, 514.0, 748.4, 516.4, 750.9, 515.5, 752.2, 518.9, 839.3, 624.0,
+867.6, 630.5, 867.6, 630.8, 895.8, 637.6, 900.4, 638.7, 903.8, 641.2,
+904.9, 639.8, 891.5, 650.5, 891.5, 650.5, 878.0, 661.2, 856.0, 656.1,
+859.1, 643.0, 840.1, 624.8, 839.7, 624.4, 839.8, 624.1, 839.3, 624.0,
+835.3, 566.8, 835.3, 566.8, 836.0, 567.4, 836.7, 568.0, 857.1, 585.8,
+857.1, 585.8, 877.5, 603.6, 892.3, 616.5, 892.3, 616.5, 907.1, 629.4,
+907.1, 629.8, 907.7, 629.7, 907.8, 630.0, 910.0, 632.0, 912.3, 632.1,
+912.2, 633.9, 909.8, 635.8, 909.8, 635.8, 907.5, 637.7, 884.6, 619.5,
+886.4, 617.2, 865.4, 596.6, 865.0, 596.2, 865.1, 596.1, 864.8, 595.8,
+852.2, 583.3, 852.1, 583.4, 839.5, 570.9, 838.1, 569.5, 838.2, 569.5,
+836.7, 568.0, 836.0, 567.4, 835.3, 566.8, 835.3, 566.8, 845.9, 561.2,
+855.0, 547.1, 858.7, 547.4, 874.5, 539.8, 876.3, 539.0, 881.2, 544.2,
+881.1, 544.3, 877.6, 549.8, 874.2, 547.6, 867.3, 550.9, 856.6, 556.1,
+851.4, 552.7, 845.9, 561.2, 819.2, 520.3, 819.5, 519.3, 820.2, 518.7,
+819.7, 518.2, 817.7, 516.8, 825.6, 507.8, 823.0, 504.7, 839.9, 508.5,
+838.4, 515.2, 853.8, 525.7, 864.1, 532.8, 875.5, 535.3, 874.5, 539.8,
+858.7, 547.4, 855.0, 547.1, 845.9, 561.2, 842.7, 563.6, 839.5, 565.7,
+839.6, 565.9, 826.2, 545.2, 828.8, 543.4, 819.2, 520.3, 839.6, 565.9,
+839.8, 566.4, 838.3, 567.7, 836.7, 568.0, 836.0, 567.4, 835.3, 566.8,
+835.3, 566.8, 824.6, 557.5, 824.6, 557.5, 813.9, 548.1, 813.3, 547.6,
+812.6, 547.5, 812.7, 547.1, 814.9, 535.3, 815.5, 535.4, 818.4, 523.8,
+819.5, 522.9, 818.8, 522.1, 819.2, 520.3, 828.8, 543.4, 826.2, 545.2,
+839.6, 565.9, 906.6, 622.8, 904.8, 612.1, 903.9, 612.2, 903.1, 601.5,
+900.4, 583.4, 900.5, 583.4, 897.9, 565.3, 897.9, 565.1, 897.9, 565.1,
+897.9, 564.9, 899.5, 575.6, 899.5, 575.6, 901.1, 586.3, 903.8, 604.5,
+904.2, 604.5, 906.6, 622.8, 597.3, 353.4, 614.7, 388.9, 604.2, 402.0,
+632.1, 424.4, 634.1, 450.4, 634.1, 450.4, 636.1, 476.4, 636.0, 474.9,
+635.6, 474.9, 635.2, 473.4, 630.7, 459.4, 630.7, 459.4, 626.3, 445.3,
+611.8, 399.4, 586.5, 392.3, 597.3, 353.4, 690.4, 580.0, 687.8, 583.4,
+684.6, 584.2, 685.3, 586.9, 684.2, 587.1, 681.3, 582.6, 682.0, 581.7,
+683.9, 579.2, 689.6, 578.7, 690.4, 580.0, 911.3, 564.9, 903.7, 560.0,
+903.9, 559.8, 896.4, 554.7, 894.9, 553.7, 894.4, 554.0, 893.3, 552.6,
+892.7, 551.8, 893.2, 551.5, 893.0, 550.3, 892.0, 543.8, 892.0, 543.8,
+891.0, 537.3, 890.9, 536.6, 891.2, 536.4, 890.9, 536.0, 895.6, 542.1,
+895.3, 542.3, 899.8, 548.7, 905.1, 556.1, 905.1, 556.1, 910.3, 563.5,
+910.4, 563.6, 910.4, 563.6, 910.5, 563.7, 910.9, 564.3, 910.8, 564.5,
+911.3, 564.9, 881.4, 472.9, 881.6, 434.2, 875.4, 434.2, 869.9, 395.5,
+869.9, 395.5, 869.9, 393.4, 869.9, 391.2, 876.0, 432.0, 881.6, 432.1,
+881.4, 472.9, 921.6, 407.7, 923.8, 415.2, 923.8, 415.2, 926.0, 422.7,
+938.8, 442.6, 928.9, 449.0, 931.8, 475.4, 930.9, 463.2, 930.0, 463.3,
+928.2, 451.2, 924.9, 429.4, 923.3, 429.6, 921.6, 407.7, 903.7, 346.4,
+908.9, 364.0, 920.2, 370.0, 914.0, 381.7, 914.0, 382.1, 914.0, 382.4,
+914.3, 382.6, 916.1, 382.5, 916.7, 390.9, 919.1, 399.2, 917.7, 404.6,
+913.4, 403.5, 907.7, 407.8, 901.1, 412.8, 896.0, 419.1, 894.4, 417.8,
+884.3, 409.7, 889.3, 403.4, 884.2, 389.0, 883.6, 387.4, 882.6, 387.0,
+883.1, 385.9, 892.3, 365.7, 890.9, 348.1, 903.7, 346.4, 842.4, 342.0,
+835.8, 345.6, 835.8, 345.6, 829.3, 349.3, 794.5, 342.5, 790.2, 357.7,
+752.8, 370.9, 776.8, 355.0, 776.8, 355.0, 800.7, 339.1, 819.2, 333.1,
+823.5, 335.2, 842.4, 342.0, 800.7, 339.1, 825.7, 322.5, 823.3, 315.5,
+850.7, 305.9, 851.2, 305.7, 851.6, 305.3, 851.6, 305.3, 853.8, 304.2,
+856.0, 302.9, 856.1, 303.1, 853.5, 305.6, 856.6, 309.4, 858.0, 315.5,
+857.8, 323.7, 859.2, 323.7, 860.4, 331.9, 852.6, 330.4, 851.4, 336.9,
+842.4, 342.0, 823.5, 335.2, 819.2, 333.1, 800.7, 339.1, 847.6, 351.2,
+855.0, 348.4, 858.9, 351.0, 862.4, 345.6, 862.8, 348.1, 862.8, 348.1,
+863.2, 350.6, 856.3, 353.2, 847.8, 352.0, 847.6, 351.2, 765.4, 446.9,
+783.7, 457.2, 781.5, 461.2, 797.5, 475.5, 815.2, 491.3, 815.2, 491.3,
+832.8, 507.0, 837.8, 511.5, 837.8, 511.5, 842.9, 516.0, 848.3, 520.8,
+847.5, 522.2, 853.8, 525.7, 838.4, 515.2, 839.9, 508.5, 823.0, 504.7,
+809.3, 488.9, 785.4, 487.8, 787.2, 480.4, 767.8, 463.2, 767.8, 459.9,
+744.0, 451.0, 728.2, 440.2, 728.2, 440.2, 712.4, 429.4, 706.9, 425.7,
+706.9, 425.7, 701.5, 422.0, 700.7, 419.7, 698.9, 420.3, 696.4, 418.5,
+731.1, 432.1, 733.1, 428.7, 765.4, 446.9, 696.4, 418.5, 692.6, 416.0,
+692.6, 416.0, 688.8, 413.4, 690.9, 414.1, 693.6, 408.7, 694.7, 409.5,
+695.3, 409.6, 695.5, 409.0, 696.2, 408.5, 702.9, 402.3, 705.4, 405.0,
+714.5, 401.6, 743.6, 417.7, 763.2, 449.1, 765.4, 446.9, 733.1, 428.7,
+731.1, 432.1, 696.4, 418.5, 493.2, 122.4, 496.6, 123.8, 497.6, 121.5,
+502.0, 120.5, 507.0, 119.4, 507.6, 117.2, 512.1, 118.4, 515.0, 119.1,
+517.6, 122.8, 516.9, 124.3, 516.4, 125.4, 513.3, 124.0, 509.6, 123.7,
+501.4, 123.1, 500.4, 125.4, 493.2, 122.4, 600.5, 240.3, 575.0, 209.0,
+581.3, 186.8, 549.5, 177.8, 540.1, 159.5, 541.2, 158.9, 530.8, 141.2,
+553.1, 149.7, 548.2, 162.6, 565.6, 183.9, 571.2, 189.2, 570.5, 189.8,
+575.4, 195.8, 588.8, 217.5, 581.6, 227.2, 600.5, 240.3, 575.4, 195.8,
+604.4, 231.3, 601.5, 234.1, 633.4, 266.7, 639.4, 274.1, 639.4, 274.1,
+645.4, 281.4, 659.5, 298.6, 659.5, 298.6, 673.5, 315.8, 673.6, 315.8,
+673.6, 315.8, 673.6, 315.9, 685.1, 330.0, 687.0, 328.8, 696.7, 344.0,
+692.1, 336.9, 690.2, 338.1, 683.8, 332.1, 667.6, 314.8, 666.4, 315.9,
+649.0, 299.7, 637.5, 265.7, 624.8, 270.0, 600.5, 240.3, 581.6, 227.2,
+588.8, 217.5, 575.4, 195.8, 903.1, 280.6, 895.2, 284.4, 895.2, 284.4,
+887.3, 288.2, 883.2, 288.4, 883.0, 285.2, 878.8, 282.3, 854.6, 265.6,
+854.6, 265.6, 830.4, 249.0, 825.3, 245.5, 825.3, 245.5, 820.2, 241.9,
+794.8, 224.5, 794.8, 224.5, 769.5, 207.0, 768.4, 206.2, 768.4, 206.2,
+767.2, 205.4, 760.5, 200.8, 761.2, 199.3, 753.8, 196.2, 766.9, 201.7,
+766.2, 203.2, 778.7, 210.2, 792.9, 218.3, 792.9, 218.3, 807.2, 226.4,
+812.6, 229.4, 812.6, 229.4, 817.9, 232.4, 842.6, 246.4, 842.6, 246.4,
+867.2, 260.3, 875.7, 265.1, 875.7, 265.1, 884.2, 269.9, 892.2, 274.4,
+892.2, 274.4, 900.1, 278.9, 901.6, 279.7, 902.5, 281.0, 903.1, 280.6,
+517.7, 117.1, 520.7, 121.1, 529.1, 114.7, 540.5, 112.3, 547.4, 111.5,
+547.3, 110.8, 554.1, 109.4, 555.5, 109.5, 555.2, 111.7, 556.4, 114.1,
+567.2, 135.5, 567.2, 135.5, 578.0, 156.8, 579.1, 158.9, 579.1, 158.9,
+580.1, 161.0, 582.9, 166.5, 581.2, 168.9, 585.7, 172.0, 550.0, 147.0,
+543.3, 151.0, 517.7, 117.1, 599.6, 253.8, 603.6, 257.5, 603.6, 257.5,
+607.6, 261.2, 639.4, 295.1, 640.0, 294.7, 674.0, 326.3, 671.5, 323.8,
+670.3, 325.0, 667.7, 322.6, 653.1, 308.9, 653.6, 308.4, 639.5, 294.1,
+619.6, 274.0, 619.4, 274.2, 599.6, 253.8, 701.4, 377.5, 684.8, 385.5,
+684.8, 385.5, 668.1, 393.5, 665.9, 393.6, 665.6, 386.2, 663.1, 378.8,
+655.2, 355.4, 654.4, 331.7, 647.2, 331.9, 673.6, 331.1, 691.7, 348.8,
+701.4, 377.5, 439.9, 203.6, 440.2, 203.0, 439.1, 202.4, 438.3, 201.1,
+437.8, 193.7, 427.2, 190.5, 429.1, 186.9, 422.4, 176.3, 422.4, 176.3,
+415.7, 165.8, 412.5, 160.9, 412.5, 160.9, 409.4, 156.0, 409.6, 155.6,
+408.9, 154.9, 408.1, 154.0, 404.3, 148.1, 400.6, 148.2, 400.6, 142.2,
+404.3, 142.2, 404.3, 141.4, 408.0, 140.6, 430.6, 159.3, 436.6, 157.6,
+449.3, 182.6, 452.6, 189.1, 445.7, 193.8, 439.9, 203.6, 600.1, 84.9,
+599.4, 84.6, 599.2, 84.1, 598.7, 84.3, 616.0, 76.2, 619.2, 79.9,
+633.3, 68.0, 674.9, 71.6, 691.3, 60.0, 720.8, 26.7, 723.0, 27.1,
+724.0, 26.2, 725.3, 27.5, 726.3, 27.9, 726.7, 29.3, 727.1, 29.1,
+715.7, 35.3, 715.2, 34.3, 703.4, 39.5, 701.1, 40.5, 701.1, 40.5,
+698.9, 41.5, 662.7, 57.4, 662.7, 57.4, 626.5, 73.3, 613.3, 79.1,
+613.5, 79.6, 600.1, 84.9, 557.4, 100.7, 550.2, 105.6, 550.9, 107.4,
+543.0, 110.6, 541.7, 111.2, 541.8, 112.1, 540.5, 112.3, 529.1, 114.7,
+520.7, 121.1, 517.7, 117.1, 514.9, 117.8, 514.9, 117.8, 512.1, 118.4,
+507.6, 117.2, 507.0, 119.4, 502.0, 120.5, 503.0, 121.8, 506.6, 118.9,
+511.2, 117.2, 534.3, 109.0, 533.6, 105.7, 557.4, 100.7, 387.3, 116.0,
+362.5, 54.7, 365.8, 53.1, 337.7, -6.6, 335.7, -12.3, 336.3, -17.9,
+333.7, -18.1, 341.8, -20.2, 341.8, -20.2, 349.8, -22.3, 351.7, -22.3,
+352.8, -20.5, 353.5, -18.0, 364.2, 19.6, 363.0, 19.9, 372.6, 57.9,
+374.7, 66.1, 374.7, 66.1, 376.8, 74.3, 379.0, 83.0, 379.0, 83.0,
+381.2, 91.7, 383.3, 100.2, 383.3, 100.2, 385.5, 108.7, 386.4, 112.4,
+385.9, 112.6, 387.3, 116.0, 428.6, -42.8, 428.6, -42.8, 430.6, -43.3,
+432.7, -43.8, 451.1, -48.9, 451.2, -48.4, 469.8, -53.0, 451.2, -48.4,
+451.1, -48.9, 432.7, -43.8, 430.6, -43.3, 428.6, -42.8, 428.6, -42.8,
+215.0, 260.7, 214.8, 260.9, 214.4, 260.4, 213.8, 260.1, 214.0, 259.0,
+206.6, 257.2, 206.8, 256.7, 215.1, 227.9, 215.0, 227.9, 223.1, 199.1,
+223.1, 199.1, 232.3, 166.6, 241.5, 134.0, 245.6, 119.3, 245.6, 119.3,
+249.8, 104.6, 253.8, 90.4, 253.9, 90.4, 257.9, 76.1, 257.0, 79.3,
+257.2, 79.3, 256.4, 82.5, 248.0, 118.7, 248.0, 118.7, 239.6, 154.9,
+232.4, 185.6, 232.4, 185.6, 225.3, 216.3, 225.1, 217.0, 225.1, 217.0,
+225.0, 217.7, 220.2, 238.1, 220.2, 238.1, 215.5, 258.6, 215.2, 259.7,
+215.6, 260.1, 215.0, 260.7, 142.3, 443.2, 142.0, 441.3, 141.8, 441.3,
+141.8, 439.5, 136.9, 394.0, 135.5, 394.1, 129.3, 348.8, 129.9, 332.1,
+133.8, 320.3, 146.4, 316.0, 141.9, 317.5, 146.0, 329.6, 145.6, 343.2,
+143.9, 393.2, 144.3, 393.2, 142.3, 443.2, 192.0, 145.4, 196.4, 139.0,
+200.1, 132.2, 200.8, 132.6, 202.0, 132.5, 202.9, 131.1, 202.9, 129.5,
+229.0, 115.3, 223.0, 102.9, 240.6, 74.8, 246.6, 67.8, 245.9, 67.1,
+251.1, 59.5, 244.4, 70.9, 245.2, 71.4, 239.2, 83.3, 236.4, 88.2,
+235.7, 87.8, 232.3, 92.4, 212.1, 118.9, 212.5, 119.2, 192.0, 145.4,
+470.3, 647.3, 471.5, 660.3, 471.7, 660.3, 472.9, 673.2, 473.3, 677.4,
+473.3, 677.4, 473.7, 681.5, 473.9, 684.3, 474.0, 684.3, 474.2, 687.1,
+474.9, 695.0, 474.8, 695.0, 475.5, 702.9, 468.6, 699.9, 471.3, 693.5,
+467.1, 684.1, 466.6, 682.9, 466.6, 682.9, 466.1, 681.7, 464.4, 678.0,
+464.4, 678.0, 462.8, 674.3, 461.2, 670.9, 460.0, 671.0, 459.7, 667.4,
+454.0, 587.3, 454.4, 587.2, 448.3, 507.2, 447.9, 501.2, 448.0, 501.2,
+447.6, 495.3, 446.7, 480.6, 448.0, 480.4, 445.8, 465.9, 459.4, 556.4,
+458.5, 556.6, 470.3, 647.3, 445.8, 465.9, 444.2, 452.7, 445.1, 452.6,
+444.3, 439.3, 443.4, 424.6, 443.4, 424.6, 442.5, 409.9, 442.2, 404.5,
+442.2, 404.5, 441.8, 399.1, 440.9, 383.7, 440.9, 383.7, 440.0, 368.4,
+440.0, 367.4, 440.0, 367.4, 439.9, 366.4, 436.0, 301.4, 432.8, 301.4,
+432.1, 236.3, 432.5, 271.5, 435.8, 271.5, 439.3, 306.7, 441.3, 329.1,
+441.3, 329.1, 443.4, 351.4, 443.9, 357.8, 443.9, 357.8, 444.5, 364.1,
+444.8, 366.7, 444.8, 366.7, 445.0, 369.4, 446.9, 389.4, 446.9, 389.4,
+448.7, 409.5, 452.1, 447.0, 452.1, 447.0, 455.6, 484.5, 456.5, 494.1,
+456.5, 494.1, 457.3, 503.6, 461.1, 544.5, 461.1, 544.5, 464.8, 585.3,
+466.5, 603.5, 466.6, 603.5, 468.2, 621.6, 469.3, 634.5, 469.2, 634.5,
+470.3, 647.3, 458.5, 556.6, 459.4, 556.4, 445.8, 465.9, 465.1, 743.6,
+462.4, 705.5, 462.4, 705.5, 459.7, 667.4, 460.0, 671.0, 461.2, 670.9,
+462.8, 674.3, 463.8, 680.1, 463.0, 680.2, 463.2, 686.2, 464.1, 714.9,
+459.9, 715.7, 465.1, 743.6, 519.2, 392.8, 519.8, 404.6, 512.4, 405.1,
+505.5, 417.3, 505.6, 417.1, 505.4, 417.0, 505.5, 416.9, 512.2, 404.8,
+519.7, 404.5, 519.2, 392.8, 210.2, 770.6, 213.3, 782.9, 209.2, 783.9,
+208.2, 797.2, 205.3, 838.2, 215.2, 875.8, 202.3, 879.2, 197.0, 840.4,
+213.6, 817.8, 191.6, 801.6, 193.4, 790.8, 183.6, 784.8, 188.5, 778.9,
+187.3, 770.3, 187.3, 770.3, 186.1, 761.7, 185.4, 756.6, 185.4, 756.6,
+184.7, 751.5, 184.6, 751.1, 184.7, 751.0, 184.6, 750.6, 192.1, 756.1,
+191.9, 756.3, 199.2, 762.1, 204.7, 766.3, 208.8, 765.3, 210.2, 770.6,
+156.0, 542.8, 153.2, 522.1, 153.2, 522.1, 150.3, 501.5, 169.4, 477.1,
+168.7, 476.5, 187.1, 451.5, 174.1, 457.5, 180.4, 471.0, 173.8, 490.6,
+173.3, 491.8, 173.3, 491.8, 172.9, 493.1, 172.9, 493.2, 172.9, 493.2,
+172.8, 493.4, 170.6, 500.0, 170.6, 500.0, 168.3, 506.7, 165.8, 514.0,
+165.8, 514.0, 163.3, 521.4, 159.6, 532.1, 152.2, 536.9, 156.0, 542.8,
+224.3, 529.2, 225.0, 523.0, 227.6, 517.0, 228.5, 517.2, 229.2, 517.3,
+228.1, 523.5, 227.6, 529.8, 227.1, 537.3, 227.1, 537.3, 226.5, 544.9,
+223.5, 586.4, 225.4, 586.6, 220.5, 627.8, 217.3, 628.6, 218.1, 631.9,
+215.7, 636.0, 217.8, 582.5, 218.6, 582.4, 224.3, 529.2, 348.9, 883.3,
+337.1, 885.5, 330.9, 889.1, 324.4, 882.9, 320.9, 879.5, 326.7, 873.5,
+329.0, 864.1, 329.5, 862.2, 329.5, 862.2, 329.9, 860.4, 336.9, 831.8,
+354.5, 813.4, 343.8, 803.1, 363.8, 822.4, 346.2, 840.7, 348.6, 878.3,
+348.7, 880.8, 349.2, 883.2, 348.9, 883.3, 415.7, 165.8, 422.4, 176.3,
+422.4, 176.3, 429.1, 186.9, 423.5, 197.5, 429.9, 201.0, 430.8, 215.1,
+431.2, 225.7, 431.1, 225.7, 432.1, 236.3, 432.8, 301.4, 436.0, 301.4,
+439.9, 366.4, 439.3, 344.4, 437.2, 344.4, 434.6, 322.4, 429.7, 281.8,
+429.7, 281.8, 424.8, 241.2, 422.1, 218.7, 422.1, 218.7, 419.4, 196.3,
+417.8, 183.6, 417.8, 183.6, 416.3, 171.0, 416.0, 168.4, 417.1, 167.5,
+415.7, 165.8, 101.2, 144.6, 99.2, 144.7, 92.1, 120.2, 94.7, 97.2,
+103.9, 91.9, 101.6, 87.9, 108.5, 78.6, 110.8, 77.7, 113.0, 83.2,
+117.6, 87.9, 121.3, 91.7, 125.8, 93.0, 125.1, 95.6, 117.7, 121.4,
+114.4, 143.8, 101.2, 144.6, 125.1, 95.6, 124.6, 96.2, 129.7, 98.4,
+131.9, 102.5, 136.9, 115.6, 133.5, 119.1, 142.6, 128.4, 137.9, 130.9,
+134.7, 129.7, 133.2, 133.5, 117.6, 142.0, 118.6, 144.8, 102.0, 150.6,
+102.6, 150.4, 100.2, 147.0, 101.2, 144.6, 114.4, 143.8, 117.7, 121.4,
+125.1, 95.6, 117.6, 87.9, 113.0, 83.2, 110.8, 77.7, 108.5, 78.6,
+120.5, 62.4, 130.6, 63.5, 132.6, 46.2, 136.3, 47.5, 137.3, 46.4,
+140.0, 48.9, 141.8, 49.5, 141.8, 49.5, 143.5, 50.2, 158.4, 55.7,
+158.7, 55.1, 173.3, 61.2, 173.1, 61.1, 172.9, 61.9, 172.3, 62.2,
+145.1, 75.3, 146.4, 80.5, 117.6, 87.9, 172.3, 62.2, 164.6, 64.4,
+165.9, 69.1, 159.4, 76.0, 146.4, 90.0, 147.1, 90.7, 133.3, 103.9,
+132.6, 103.2, 132.2, 103.4, 131.9, 102.5, 129.7, 98.4, 124.6, 96.2,
+125.1, 95.6, 125.8, 93.0, 121.3, 91.7, 117.6, 87.9, 146.4, 80.5,
+145.1, 75.3, 172.3, 62.2, 135.1, 105.7, 134.2, 104.8, 134.2, 104.8,
+133.3, 103.9, 147.1, 90.7, 146.4, 90.0, 159.4, 76.0, 160.9, 77.5,
+148.2, 91.7, 135.1, 105.7, 143.5, 50.2, 141.8, 49.5, 141.8, 49.5,
+140.0, 48.9, 132.1, 41.6, 132.0, 40.2, 122.0, 36.6, 158.4, 27.2,
+158.4, 27.2, 194.7, 17.8, 195.2, 17.7, 195.2, 17.7, 195.7, 17.5,
+195.6, 18.0, 195.1, 17.9, 194.6, 18.2, 169.0, 34.2, 169.7, 35.4,
+143.5, 50.2, 210.8, 66.8, 207.8, 66.4, 207.8, 66.4, 204.7, 66.0,
+205.6, 39.5, 199.5, 33.8, 212.6, 13.1, 227.9, 9.2, 227.9, 9.2,
+243.2, 5.2, 235.9, 15.3, 241.7, 19.5, 240.1, 33.8, 230.1, 52.8,
+227.1, 52.1, 210.8, 66.8, 240.1, 33.8, 239.6, 38.3, 241.4, 39.6,
+239.1, 42.7, 234.1, 55.0, 237.6, 56.4, 236.1, 70.1, 225.0, 65.1,
+223.5, 68.4, 210.8, 66.8, 227.1, 52.1, 230.1, 52.8, 240.1, 33.8,
+169.9, 145.9, 171.0, 158.5, 171.0, 158.5, 172.1, 171.1, 170.6, 173.2,
+170.5, 173.8, 170.7, 176.4, 169.6, 178.8, 169.5, 178.8, 167.7, 180.7,
+135.3, 199.1, 139.8, 207.9, 113.9, 236.9, 114.0, 236.7, 113.7, 236.5,
+113.8, 236.3, 141.7, 191.0, 135.0, 185.0, 169.9, 145.9, 142.6, 822.9,
+142.5, 811.8, 142.5, 811.8, 142.5, 800.7, 139.1, 739.4, 143.1, 739.2,
+143.6, 677.7, 143.1, 739.2, 139.1, 739.4, 142.5, 800.7, 142.5, 811.8,
+142.5, 811.8, 142.6, 822.9, 100.4, 664.5, 99.7, 666.1, 98.9, 666.1,
+99.0, 667.8, 96.8, 655.3, 96.8, 655.3, 94.7, 642.9, 94.4, 641.6,
+94.8, 641.5, 95.0, 640.0, 94.9, 629.7, 97.5, 629.7, 100.1, 619.4,
+104.9, 640.9, 100.9, 641.9, 100.4, 664.5, 107.3, 369.1, 122.8, 412.0,
+109.9, 423.8, 138.4, 454.9, 138.8, 458.8, 138.1, 459.0, 139.2, 462.7,
+139.3, 461.7, 138.0, 461.7, 137.6, 460.5, 133.2, 448.6, 133.6, 448.4,
+129.6, 436.3, 118.4, 402.7, 122.3, 400.9, 107.3, 369.1, 38.1, 318.9,
+37.1, 313.2, 37.1, 313.2, 36.1, 307.5, 41.0, 287.6, 38.8, 286.4,
+37.6, 265.6, 36.7, 258.7, 37.8, 258.5, 38.1, 251.5, 37.7, 250.5,
+55.0, 249.8, 60.9, 240.9, 64.0, 249.4, 64.0, 249.4, 67.0, 257.9,
+67.4, 260.4, 65.7, 260.7, 64.4, 263.4, 62.8, 266.8, 62.8, 266.8,
+61.2, 270.1, 49.7, 294.5, 53.0, 296.7, 38.1, 318.9, 75.3, 375.5,
+75.1, 375.7, 76.4, 376.3, 76.5, 377.0, 76.7, 393.4, 76.1, 393.5,
+75.8, 409.9, 69.3, 428.3, 72.7, 430.8, 75.1, 451.0, 74.5, 479.7,
+74.5, 479.7, 74.0, 508.4, 74.0, 509.4, 73.7, 509.4, 73.9, 510.3,
+72.6, 499.3, 71.7, 499.4, 69.5, 488.4, 64.4, 448.5, 62.0, 448.8,
+54.6, 409.2, 55.5, 391.8, 64.2, 391.8, 75.3, 375.5, 54.6, 409.2,
+49.6, 382.7, 49.8, 382.7, 44.6, 356.3, 44.4, 354.9, 44.9, 354.0,
+44.2, 353.6, 59.7, 362.8, 59.2, 363.6, 74.1, 373.8, 74.2, 373.9,
+74.1, 374.0, 74.3, 374.1, 74.8, 374.8, 75.5, 375.2, 75.3, 375.5,
+64.2, 391.8, 55.5, 391.8, 54.6, 409.2, 124.4, 503.4, 112.1, 498.8,
+111.2, 494.5, 104.4, 482.2, 106.0, 456.0, 93.7, 455.2, 83.1, 428.3,
+106.5, 437.0, 99.0, 457.2, 114.9, 486.1, 119.6, 494.7, 117.4, 500.8,
+124.4, 503.4, 81.3, 457.6, 92.8, 469.9, 105.1, 470.7, 104.4, 482.2,
+111.2, 494.5, 112.1, 498.8, 124.4, 503.4, 124.6, 503.6, 124.8, 503.8,
+124.8, 503.8, 118.5, 510.7, 114.8, 518.5, 111.8, 517.1, 102.1, 512.9,
+105.6, 505.0, 99.3, 492.8, 90.3, 475.2, 76.1, 468.4, 81.3, 457.6,
+96.7, 598.9, 93.4, 608.1, 90.6, 608.0, 90.2, 617.3, 87.2, 600.2,
+88.1, 600.0, 84.2, 583.1, 83.7, 575.4, 82.9, 575.5, 81.6, 567.8,
+92.0, 581.1, 93.8, 582.6, 96.7, 598.9, 10.2, 469.4, 10.1, 481.1,
+10.1, 481.1, 9.9, 492.8, -6.0, 452.8, -7.8, 453.5, -25.5, 414.1,
+-25.9, 441.5, -3.1, 439.7, 10.2, 469.4, 22.9, 401.7, 23.1, 435.6,
+23.1, 435.6, 23.2, 469.6, 10.5, 436.0, 8.9, 436.6, -5.3, 403.6,
+-5.3, 402.7, 21.1, 397.3, 22.9, 401.7, 16.6, 341.0, 16.6, 347.1,
+16.6, 347.1, 16.7, 353.2, 12.1, 349.8, 1.7, 353.8, 1.7, 354.3,
+-2.9, 353.3, -5.9, 347.4, -6.7, 348.2, 1.5, 340.8, 6.2, 338.8,
+16.6, 341.0, 41.7, 339.3, 42.9, 346.4, 40.0, 349.1, 44.2, 353.6,
+44.9, 354.0, 44.4, 354.9, 44.6, 356.3, 46.6, 366.3, 46.4, 366.3,
+48.2, 376.4, 36.8, 416.2, 34.9, 416.1, 28.1, 456.8, 27.0, 439.3,
+27.0, 439.3, 25.8, 421.8, 20.2, 411.2, 26.2, 408.0, 26.7, 394.2,
+26.7, 393.2, 26.7, 393.2, 26.8, 392.2, 34.0, 365.7, 30.5, 364.1,
+41.7, 339.3, 26.8, 392.2, 28.7, 347.1, 29.3, 347.1, 30.7, 302.0,
+30.7, 301.8, 30.7, 301.8, 30.7, 301.5, 32.8, 313.5, 34.8, 313.2,
+39.1, 324.7, 39.4, 325.6, 39.3, 325.6, 39.5, 326.5, 43.2, 329.6,
+40.6, 332.9, 41.7, 339.3, 30.5, 364.1, 34.0, 365.7, 26.8, 392.2,
+55.9, 700.7, 49.6, 692.7, 49.6, 692.7, 43.3, 684.7, 51.2, 675.0,
+40.9, 659.4, 28.8, 640.3, 35.6, 641.6, 35.6, 641.6, 42.5, 643.0,
+49.8, 654.0, 45.7, 656.7, 48.9, 670.5, 49.3, 672.3, 49.3, 672.3,
+49.7, 674.1, 52.8, 687.4, 61.0, 692.4, 55.9, 700.7, 782.5, 583.1,
+784.1, 591.8, 781.5, 601.4, 777.5, 602.0, 768.9, 594.4, 768.9, 594.4,
+760.4, 586.8, 759.7, 586.2, 760.7, 585.0, 760.1, 584.4, 759.3, 578.0,
+759.3, 578.0, 758.5, 571.7, 756.7, 556.1, 756.7, 556.1, 754.8, 540.6,
+751.3, 539.8, 756.0, 528.8, 752.2, 518.9, 751.4, 512.5, 751.4, 512.5,
+750.7, 506.1, 750.4, 503.8, 751.0, 503.5, 750.1, 501.5, 758.6, 521.0,
+758.0, 521.3, 765.8, 541.1, 774.1, 562.1, 778.3, 561.3, 782.5, 583.1,
+797.6, 609.5, 797.4, 609.5, 797.2, 611.1, 796.8, 612.7, 796.7, 613.2,
+796.7, 613.2, 796.5, 613.7, 796.0, 615.9, 795.4, 618.0, 795.5, 618.0,
+792.8, 613.9, 791.7, 614.6, 787.9, 611.3, 788.4, 609.3, 793.0, 608.8,
+797.6, 609.5, 741.2, 516.5, 748.0, 528.5, 745.8, 538.6, 754.8, 540.6,
+756.7, 556.1, 756.7, 556.1, 758.5, 571.7, 744.7, 547.0, 744.6, 544.7,
+741.2, 516.5, 712.4, 429.4, 728.2, 440.2, 728.2, 440.2, 744.0, 451.0,
+747.0, 452.1, 744.9, 457.9, 745.7, 464.8, 726.1, 451.4, 714.7, 448.8,
+712.4, 429.4, 790.4, 654.6, 788.9, 653.1, 787.0, 652.4, 787.3, 651.6,
+788.2, 647.9, 787.8, 644.4, 789.1, 644.2, 795.2, 639.9, 791.5, 634.7,
+793.8, 625.1, 795.5, 639.4, 793.9, 640.3, 790.4, 654.6, 864.8, 595.8,
+886.2, 616.7, 887.3, 615.6, 907.5, 637.7, 906.2, 638.7, 906.2, 638.7,
+904.9, 639.8, 903.8, 641.2, 900.4, 638.7, 895.8, 637.6, 878.7, 618.8,
+880.6, 617.1, 865.4, 596.6, 865.0, 596.2, 865.1, 596.1, 864.8, 595.8,
+867.3, 550.9, 874.2, 547.6, 877.6, 549.8, 881.1, 544.3, 882.5, 544.0,
+882.9, 545.5, 884.7, 546.7, 889.0, 549.7, 889.0, 549.7, 893.3, 552.6,
+894.4, 554.0, 894.9, 553.7, 896.4, 554.7, 898.2, 559.5, 897.2, 559.8,
+897.9, 564.9, 897.9, 565.1, 897.9, 565.1, 897.9, 565.3, 887.3, 560.5,
+887.4, 560.3, 876.8, 555.4, 872.1, 553.1, 867.2, 551.2, 867.3, 550.9,
+944.3, 587.3, 944.5, 587.5, 944.7, 587.5, 944.7, 587.6, 944.5, 594.2,
+941.1, 599.0, 944.0, 600.9, 941.0, 598.8, 944.0, 594.1, 944.3, 587.3,
+699.3, 568.1, 694.8, 574.1, 694.8, 574.1, 690.4, 580.0, 689.6, 578.7,
+683.9, 579.2, 682.0, 581.7, 676.7, 578.5, 678.1, 576.1, 674.6, 570.2,
+674.6, 570.3, 674.8, 570.2, 675.1, 570.2, 678.1, 569.9, 678.1, 569.9,
+681.0, 569.7, 683.3, 569.5, 683.3, 569.5, 685.5, 569.3, 689.4, 569.0,
+689.4, 569.0, 693.3, 568.6, 696.3, 568.4, 699.0, 569.1, 699.3, 568.1,
+902.2, 454.4, 901.6, 452.4, 906.3, 450.0, 905.6, 449.0, 911.4, 456.8,
+909.0, 458.6, 912.4, 468.1, 913.8, 472.2, 916.2, 472.8, 915.3, 476.2,
+915.9, 473.9, 913.5, 473.3, 911.8, 470.4, 907.0, 462.4, 904.7, 463.1,
+902.2, 454.4, 904.5, 446.0, 904.0, 446.7, 905.9, 447.7, 905.6, 449.0,
+906.3, 450.0, 901.6, 452.4, 902.2, 454.4, 895.7, 464.8, 895.7, 464.8,
+889.2, 475.3, 886.7, 479.4, 886.2, 479.1, 884.2, 483.4, 888.4, 474.4,
+888.9, 474.6, 893.7, 465.8, 899.1, 455.9, 898.0, 455.1, 904.5, 446.0,
+928.2, 451.2, 930.0, 463.3, 930.9, 463.2, 931.8, 475.4, 932.5, 482.0,
+932.5, 482.0, 933.3, 488.7, 930.5, 470.0, 930.2, 470.0, 928.2, 451.2,
+903.2, 344.7, 903.5, 345.5, 903.5, 345.5, 903.7, 346.4, 890.9, 348.1,
+892.3, 365.7, 883.1, 385.9, 878.4, 386.3, 876.6, 367.7, 870.1, 349.6,
+868.2, 335.8, 865.3, 336.2, 860.5, 322.8, 870.9, 319.1, 869.6, 315.5,
+878.7, 308.3, 895.8, 317.0, 891.2, 326.3, 903.2, 344.7, 878.7, 308.3,
+884.3, 303.7, 887.6, 305.1, 890.0, 299.2, 896.6, 321.9, 896.6, 321.9,
+903.2, 344.7, 891.2, 326.3, 895.8, 317.0, 878.7, 308.3, 881.9, 476.0,
+884.0, 479.6, 882.6, 480.5, 883.2, 484.9, 883.7, 488.2, 882.5, 489.1,
+884.2, 491.5, 852.8, 448.7, 850.1, 450.0, 823.9, 404.0, 822.2, 402.7,
+825.8, 398.3, 827.8, 392.5, 836.4, 396.3, 833.9, 401.9, 840.0, 411.3,
+860.9, 443.7, 862.4, 442.8, 881.9, 476.0, 818.3, 452.4, 792.2, 417.7,
+787.3, 419.8, 768.3, 381.2, 774.6, 378.8, 775.0, 379.5, 781.0, 376.4,
+782.5, 375.6, 782.6, 375.8, 784.2, 375.2, 788.2, 380.2, 786.9, 381.2,
+789.5, 387.2, 790.0, 388.3, 790.0, 388.3, 790.5, 389.3, 801.8, 415.0,
+801.8, 415.0, 813.2, 440.7, 815.7, 446.5, 814.6, 447.4, 818.3, 452.4,
+466.5, 128.1, 478.5, 122.4, 479.7, 123.8, 493.2, 122.4, 500.4, 125.4,
+501.4, 123.1, 509.6, 123.7, 499.2, 128.7, 497.4, 124.9, 485.3, 126.2,
+475.9, 127.1, 474.5, 124.3, 466.5, 128.1, 585.0, 128.1, 613.5, 142.1,
+613.5, 142.1, 641.9, 156.2, 676.6, 173.2, 676.6, 173.2, 711.3, 190.3,
+757.7, 213.1, 757.7, 213.1, 804.0, 236.0, 817.2, 242.5, 818.0, 241.3,
+830.4, 249.0, 854.6, 265.6, 854.6, 265.6, 878.8, 282.3, 875.3, 279.8,
+874.9, 280.3, 871.1, 278.3, 836.2, 260.0, 836.2, 260.0, 801.3, 241.7,
+762.4, 221.2, 762.4, 221.2, 723.5, 200.8, 706.2, 191.7, 706.2, 191.7,
+689.0, 182.7, 673.1, 174.3, 673.1, 174.3, 657.2, 166.0, 632.0, 152.8,
+632.0, 152.8, 606.8, 139.6, 596.9, 134.4, 596.9, 134.4, 587.0, 129.2,
+586.0, 128.7, 586.0, 128.6, 585.0, 128.1, 641.9, 156.2, 613.0, 150.9,
+614.5, 142.7, 587.0, 129.2, 586.0, 128.7, 586.0, 128.6, 585.0, 128.1,
+580.8, 126.0, 580.8, 126.0, 576.5, 124.0, 566.5, 119.0, 565.8, 120.1,
+556.4, 114.1, 555.2, 111.7, 555.5, 109.5, 554.1, 109.4, 561.4, 107.8,
+561.4, 107.8, 568.7, 106.2, 569.6, 106.1, 569.7, 106.9, 570.7, 107.6,
+589.3, 120.3, 589.3, 120.3, 607.9, 133.0, 624.9, 144.6, 623.4, 152.8,
+641.9, 156.2, 590.7, 210.4, 578.2, 197.1, 578.8, 196.4, 565.6, 183.9,
+548.2, 162.6, 553.1, 149.7, 530.8, 141.2, 526.6, 134.1, 522.8, 135.7,
+520.2, 128.3, 518.5, 126.3, 518.5, 126.3, 516.9, 124.3, 517.6, 122.8,
+515.0, 119.1, 512.1, 118.4, 514.9, 117.8, 514.9, 117.8, 517.7, 117.1,
+543.3, 151.0, 550.0, 147.0, 585.7, 172.0, 592.1, 178.0, 592.9, 180.0,
+594.1, 188.7, 595.5, 199.2, 590.6, 210.4, 590.7, 210.4, 594.1, 188.7,
+611.0, 203.2, 605.0, 210.3, 615.8, 231.9, 618.6, 237.3, 617.0, 239.1,
+621.3, 242.7, 607.9, 225.1, 606.0, 226.5, 590.7, 210.4, 590.6, 210.4,
+595.5, 199.2, 594.1, 188.7, 639.5, 294.1, 653.6, 308.4, 653.1, 308.9,
+667.7, 322.6, 668.5, 315.8, 652.9, 313.9, 638.2, 305.2, 631.6, 301.3,
+631.6, 301.3, 625.1, 297.5, 617.2, 292.8, 617.2, 292.8, 609.4, 288.2,
+606.9, 286.8, 606.9, 286.8, 604.4, 285.3, 563.4, 261.1, 563.4, 261.1,
+522.4, 236.9, 515.1, 232.6, 515.4, 231.9, 507.7, 228.3, 542.5, 244.8,
+542.1, 245.5, 576.5, 262.7, 583.2, 266.0, 583.2, 266.0, 589.9, 269.3,
+614.7, 281.7, 616.9, 278.6, 639.5, 294.1, 645.5, 326.8, 643.2, 325.5,
+644.4, 323.5, 643.3, 320.2, 640.7, 312.7, 641.4, 305.5, 638.2, 305.2,
+652.9, 313.9, 668.5, 315.8, 667.7, 322.6, 670.3, 325.0, 671.5, 323.8,
+674.0, 326.3, 678.1, 330.1, 680.1, 328.1, 683.8, 332.1, 690.2, 338.1,
+692.1, 336.9, 696.7, 344.0, 707.9, 354.5, 705.9, 360.5, 719.2, 365.0,
+680.3, 351.9, 681.2, 347.8, 645.5, 326.8, 719.2, 365.0, 720.8, 365.9,
+721.7, 367.9, 722.0, 367.6, 711.7, 372.6, 711.7, 372.6, 701.4, 377.5,
+691.7, 348.8, 673.6, 331.1, 647.2, 331.9, 645.5, 330.3, 647.2, 327.6,
+645.5, 326.8, 681.2, 347.8, 680.3, 351.9, 719.2, 365.0, 557.8, 293.0,
+554.0, 281.8, 548.5, 283.7, 539.3, 274.3, 538.9, 273.8, 538.9, 273.7,
+538.5, 273.3, 507.0, 241.3, 500.5, 245.8, 475.5, 209.3, 485.1, 223.3,
+491.6, 218.8, 507.7, 228.3, 515.4, 231.9, 515.1, 232.6, 522.4, 236.9,
+528.3, 242.6, 526.9, 244.1, 531.4, 251.2, 544.6, 272.1, 550.1, 270.2,
+557.8, 293.0, 642.2, 378.7, 633.8, 370.2, 634.8, 368.9, 625.4, 361.6,
+617.9, 362.6, 616.6, 352.7, 607.8, 343.7, 603.3, 334.3, 607.1, 332.5,
+606.5, 321.3, 605.9, 310.6, 602.1, 301.3, 605.3, 300.0, 605.8, 299.8,
+609.5, 309.1, 613.8, 318.3, 628.0, 348.5, 633.7, 347.0, 642.2, 378.7,
+539.3, 274.3, 568.9, 309.5, 571.0, 308.0, 598.4, 345.0, 592.2, 341.2,
+592.2, 341.2, 586.0, 337.3, 562.7, 309.6, 564.4, 308.2, 542.8, 279.0,
+542.2, 278.3, 542.2, 278.2, 541.6, 277.4, 540.5, 275.8, 540.5, 275.8,
+539.3, 274.3, 752.7, 51.9, 761.8, 53.9, 768.8, 63.8, 769.2, 63.4,
+761.8, 72.8, 753.9, 66.6, 738.7, 69.9, 734.5, 70.8, 731.7, 69.2,
+730.2, 71.7, 735.2, 63.3, 738.0, 64.9, 745.7, 58.1, 749.2, 55.0,
+750.0, 51.3, 752.7, 51.9, 646.9, 36.3, 643.1, 40.5, 643.9, 42.0,
+639.3, 44.6, 605.0, 68.1, 605.0, 68.1, 570.6, 91.6, 571.5, 91.2,
+568.6, 86.9, 569.6, 86.2, 606.8, 59.2, 607.4, 59.9, 646.9, 36.3,
+570.6, -20.1, 571.5, -18.3, 569.8, -17.4, 568.9, -14.7, 563.3, 3.6,
+558.4, 22.2, 557.7, 22.0, 548.9, 19.7, 553.8, 1.1, 549.9, -19.7,
+557.9, -30.8, 554.3, -47.9, 542.7, -58.6, 542.5, -60.0, 545.4, -61.3,
+545.1, -61.8, 559.4, -42.1, 559.6, -41.9, 570.6, -20.1, 545.1, -61.8,
+544.5, -62.9, 546.5, -63.9, 548.0, -65.9, 548.5, -66.6, 548.5, -66.6,
+549.1, -67.4, 551.3, -70.5, 551.3, -70.5, 553.5, -73.6, 555.1, -74.3,
+554.4, -76.4, 555.8, -76.8, 573.0, -82.6, 573.8, -87.4, 590.9, -86.2,
+589.5, -86.3, 589.1, -80.4, 587.3, -74.6, 582.2, -57.8, 582.2, -57.8,
+577.0, -41.0, 573.8, -30.5, 568.1, -21.8, 570.6, -20.1, 559.6, -41.9,
+559.4, -42.1, 545.1, -61.8, 372.6, 57.9, 363.0, 19.9, 364.2, 19.6,
+353.5, -18.0, 364.4, -22.7, 397.1, 8.3, 406.0, 43.4, 406.7, 46.2,
+376.1, 61.9, 372.6, 57.9, 413.0, -8.1, 406.0, -8.8, 406.1, -14.5,
+400.1, -21.7, 400.6, -21.2, 401.0, -21.6, 402.0, -21.5, 407.8, -20.9,
+407.8, -20.9, 413.6, -20.3, 432.0, -18.4, 432.0, -18.4, 450.5, -16.5,
+460.8, -15.4, 461.5, -12.2, 471.0, -14.3, 442.7, -8.0, 441.4, -5.2,
+413.0, -8.1, 376.9, -24.1, 383.0, -17.7, 390.0, -26.2, 400.1, -21.7,
+406.1, -14.5, 406.0, -8.8, 413.0, -8.1, 426.1, 5.7, 426.1, 5.7,
+439.2, 19.5, 452.4, 33.4, 452.6, 33.3, 465.6, 47.3, 464.7, 46.3,
+464.5, 46.4, 463.4, 45.6, 462.7, 45.0, 462.7, 45.0, 462.0, 44.4,
+419.5, 10.2, 413.9, 15.4, 376.9, -24.1, 543.4, -71.1, 548.5, -72.3,
+548.9, -71.4, 553.5, -73.6, 551.3, -70.5, 551.3, -70.5, 549.1, -67.4,
+546.8, -66.8, 543.5, -71.2, 543.4, -71.1, 198.8, 306.6, 206.3, 283.4,
+210.0, 283.9, 213.8, 260.1, 214.4, 260.4, 214.8, 260.9, 215.0, 260.7,
+220.4, 263.4, 226.1, 264.6, 225.8, 266.0, 222.7, 280.5, 217.0, 279.3,
+208.2, 292.5, 203.5, 299.5, 200.1, 299.0, 198.8, 306.6, 147.1, 478.3,
+146.6, 474.8, 146.6, 474.8, 146.2, 471.3, 146.7, 466.2, 147.4, 466.2,
+149.0, 461.3, 169.4, 397.4, 166.0, 396.1, 190.1, 333.6, 191.7, 329.4,
+197.8, 326.4, 200.5, 328.0, 201.3, 328.4, 198.8, 332.8, 197.1, 337.6,
+193.8, 346.9, 193.8, 346.9, 190.4, 356.3, 186.4, 367.7, 186.4, 367.7,
+182.4, 379.0, 167.7, 420.4, 167.8, 420.5, 153.1, 461.8, 153.0, 462.3,
+152.8, 462.2, 152.7, 462.6, 150.9, 467.6, 150.9, 467.6, 149.2, 472.6,
+148.1, 475.5, 146.9, 478.2, 147.1, 478.3, 154.3, 442.2, 152.4, 449.0,
+150.5, 455.9, 150.5, 455.9, 149.7, 458.6, 149.0, 461.3, 149.0, 461.3,
+147.4, 466.2, 146.7, 466.2, 146.2, 471.3, 144.2, 457.2, 144.2, 457.2,
+142.3, 443.2, 144.3, 393.2, 143.9, 393.2, 145.6, 343.2, 145.5, 345.7,
+145.8, 345.7, 146.0, 348.1, 147.8, 368.2, 147.8, 368.2, 149.5, 388.3,
+149.9, 392.5, 149.9, 392.5, 150.3, 396.7, 152.3, 419.4, 154.2, 419.4,
+154.3, 442.2, 179.6, 252.5, 179.3, 254.6, 178.6, 254.5, 177.5, 256.5,
+176.7, 258.1, 176.2, 259.8, 175.9, 259.7, 165.2, 256.7, 165.2, 255.9,
+155.5, 250.4, 156.0, 249.5, 156.0, 249.5, 156.5, 248.6, 168.7, 225.0,
+162.9, 207.3, 180.9, 201.5, 174.6, 203.5, 180.4, 221.2, 179.9, 241.0,
+179.8, 246.7, 180.5, 246.8, 179.6, 252.5, 158.1, 293.8, 157.1, 294.1,
+157.4, 294.9, 156.8, 296.1, 151.6, 306.0, 151.6, 306.0, 146.4, 316.0,
+133.8, 320.3, 129.9, 332.1, 129.3, 348.8, 126.7, 329.9, 126.7, 329.9,
+124.1, 311.0, 124.0, 309.1, 124.5, 307.9, 126.2, 307.0, 141.5, 299.2,
+141.8, 299.5, 158.1, 293.8, 126.2, 307.0, 128.3, 307.6, 131.2, 297.3,
+136.3, 287.5, 137.6, 285.0, 137.6, 285.0, 138.9, 282.6, 138.9, 282.6,
+147.2, 266.5, 155.5, 250.4, 165.2, 255.9, 165.2, 256.7, 175.9, 259.7,
+178.1, 263.9, 172.0, 267.1, 168.1, 274.5, 163.1, 284.1, 165.8, 287.7,
+158.1, 293.8, 141.8, 299.5, 141.5, 299.2, 126.2, 307.0, 136.3, 287.5,
+131.2, 297.3, 128.3, 307.6, 126.2, 307.0, 124.5, 307.9, 124.0, 309.1,
+124.1, 311.0, 121.5, 292.0, 120.5, 292.1, 118.9, 272.9, 118.7, 271.9,
+118.7, 271.9, 118.6, 270.9, 117.5, 263.1, 114.0, 261.7, 116.4, 255.3,
+129.2, 247.8, 136.6, 240.3, 134.9, 228.4, 137.5, 226.5, 136.8, 225.6,
+138.8, 222.8, 141.1, 225.7, 138.6, 227.7, 138.4, 232.7, 137.5, 255.7,
+137.5, 255.7, 136.6, 278.7, 136.5, 283.1, 137.7, 283.6, 136.3, 287.5,
+467.1, 684.1, 471.3, 693.5, 468.6, 699.9, 475.5, 702.9, 476.7, 715.9,
+476.8, 715.9, 478.0, 728.9, 480.1, 750.5, 480.0, 750.5, 482.0, 772.1,
+482.3, 775.1, 482.3, 775.1, 482.5, 778.1, 483.9, 793.3, 485.3, 808.6,
+485.3, 808.6, 486.4, 819.9, 486.4, 819.9, 487.4, 831.1, 488.3, 840.2,
+487.8, 840.3, 489.1, 849.3, 483.2, 808.5, 483.6, 808.5, 478.2, 767.6,
+477.9, 765.3, 477.9, 765.2, 477.6, 762.9, 474.2, 737.2, 474.2, 737.2,
+470.8, 711.5, 469.0, 697.8, 461.8, 693.8, 467.1, 684.1, 537.5, 359.8,
+537.4, 359.8, 528.4, 376.3, 519.2, 392.8, 519.7, 404.5, 512.2, 404.8,
+505.5, 416.9, 507.3, 414.7, 505.3, 413.0, 505.1, 409.1, 504.5, 396.8,
+498.4, 392.8, 503.9, 384.4, 514.7, 368.1, 529.8, 355.6, 537.5, 359.8,
+503.9, 384.4, 505.6, 383.9, 503.6, 377.8, 503.3, 371.1, 503.1, 368.1,
+503.1, 368.1, 503.0, 365.1, 501.6, 337.8, 501.6, 337.8, 500.3, 310.6,
+500.0, 303.7, 503.1, 301.2, 499.6, 296.9, 519.1, 327.4, 519.1, 327.4,
+538.6, 357.9, 538.9, 358.3, 538.4, 359.2, 537.5, 359.8, 529.8, 355.6,
+514.7, 368.1, 503.9, 384.4, 481.0, 448.9, 480.0, 450.8, 484.4, 452.5,
+484.1, 455.6, 483.6, 460.0, 481.8, 459.8, 479.4, 464.0, 471.6, 478.1,
+471.6, 478.1, 463.8, 492.1, 463.8, 493.9, 462.7, 493.9, 461.7, 495.7,
+471.1, 472.2, 468.8, 470.9, 481.0, 448.9, 505.1, 409.1, 505.3, 413.0,
+507.3, 414.7, 505.5, 416.9, 505.4, 417.0, 505.6, 417.1, 505.5, 417.3,
+495.2, 435.9, 495.2, 435.8, 484.8, 454.4, 484.4, 455.0, 483.9, 455.4,
+484.1, 455.6, 484.4, 452.5, 480.0, 450.8, 481.0, 448.9, 480.5, 447.8,
+480.5, 447.8, 480.0, 446.7, 467.1, 418.0, 463.1, 419.2, 454.1, 389.4,
+455.0, 392.5, 459.0, 391.3, 463.9, 393.2, 484.5, 401.1, 486.1, 398.3,
+505.1, 409.1, 180.9, 723.4, 179.3, 711.9, 179.3, 711.9, 177.7, 700.4,
+188.2, 671.9, 189.3, 670.2, 209.1, 647.2, 209.0, 655.4, 209.2, 655.4,
+209.3, 663.7, 208.7, 667.8, 207.4, 667.6, 205.6, 671.5, 199.2, 685.0,
+199.2, 685.0, 192.8, 698.4, 186.8, 710.9, 188.3, 722.5, 180.9, 723.4,
+157.5, 553.7, 156.8, 548.2, 156.8, 548.2, 156.0, 542.8, 152.2, 536.9,
+159.6, 532.1, 163.3, 521.4, 165.9, 522.6, 161.2, 532.8, 159.2, 544.2,
+158.4, 549.0, 156.4, 553.2, 157.5, 553.7, 209.5, 646.5, 209.3, 646.8,
+209.1, 646.8, 209.1, 647.2, 189.3, 670.2, 188.2, 671.9, 177.7, 700.4,
+176.4, 690.9, 177.5, 690.6, 175.1, 681.5, 173.8, 677.2, 174.5, 677.0,
+173.9, 672.6, 177.4, 657.8, 178.9, 658.2, 184.0, 643.8, 187.0, 635.3,
+187.0, 635.3, 189.9, 626.9, 194.9, 612.9, 204.3, 603.4, 199.8, 598.9,
+214.1, 613.2, 204.9, 622.6, 209.5, 646.5, 199.8, 598.9, 204.3, 563.1,
+235.1, 554.2, 224.3, 529.2, 218.6, 582.4, 217.8, 582.5, 215.7, 636.0,
+212.6, 641.2, 212.6, 641.2, 209.5, 646.5, 204.9, 622.6, 214.1, 613.2,
+199.8, 598.9, 464.9, 784.3, 465.8, 799.3, 465.8, 799.3, 466.7, 814.3,
+464.5, 813.9, 459.0, 846.5, 451.3, 878.7, 452.4, 874.2, 451.9, 874.1,
+452.6, 869.4, 453.3, 865.0, 453.3, 865.0, 453.9, 860.5, 457.1, 838.5,
+457.1, 838.5, 460.2, 816.6, 462.5, 801.0, 462.5, 801.0, 464.7, 785.5,
+464.8, 784.9, 464.9, 784.9, 464.9, 784.3, 387.9, 282.3, 363.9, 266.8,
+367.7, 256.8, 355.0, 227.9, 354.1, 225.8, 357.9, 224.1, 360.7, 220.3,
+361.3, 219.5, 361.3, 219.5, 361.9, 218.8, 364.7, 215.0, 364.7, 215.0,
+367.6, 211.2, 372.2, 205.9, 371.9, 205.6, 376.1, 199.9, 376.0, 199.9,
+376.8, 204.7, 377.5, 209.4, 377.6, 210.3, 377.6, 210.3, 377.8, 211.3,
+380.0, 227.2, 380.0, 227.2, 382.3, 243.1, 382.5, 244.4, 382.5, 244.4,
+382.7, 245.8, 385.3, 264.0, 377.8, 275.8, 387.9, 282.3, 136.9, 107.6,
+136.0, 106.7, 136.0, 106.7, 135.1, 105.7, 148.2, 91.7, 160.9, 77.5,
+159.4, 76.0, 165.9, 69.1, 164.6, 64.4, 172.3, 62.2, 172.9, 61.9,
+173.1, 61.1, 173.3, 61.2, 174.9, 61.2, 174.9, 61.8, 176.5, 62.4,
+178.2, 59.9, 187.3, 66.3, 198.1, 70.3, 196.4, 70.1, 195.9, 73.5,
+193.8, 76.7, 166.2, 93.6, 165.9, 93.3, 136.9, 107.6, 193.8, 76.7,
+181.1, 95.5, 173.7, 93.6, 168.4, 114.3, 160.3, 118.7, 160.3, 118.7,
+152.1, 123.1, 149.7, 114.0, 144.5, 115.4, 136.9, 107.6, 165.9, 93.3,
+166.2, 93.6, 193.8, 76.7, 194.6, 18.2, 195.1, 17.9, 195.6, 18.0,
+195.7, 17.5, 204.2, 15.3, 204.2, 15.3, 212.6, 13.1, 199.5, 33.8,
+205.6, 39.5, 204.7, 66.0, 203.1, 65.8, 203.1, 65.8, 201.4, 65.6,
+196.5, 42.2, 197.4, 42.0, 194.6, 18.2, 201.4, 65.6, 189.0, 64.0,
+179.9, 57.6, 176.5, 62.4, 174.9, 61.8, 174.9, 61.2, 173.3, 61.2,
+158.7, 55.1, 158.4, 55.7, 143.5, 50.2, 169.7, 35.4, 169.0, 34.2,
+194.6, 18.2, 197.4, 42.0, 196.5, 42.2, 201.4, 65.6, 169.5, 141.3,
+169.7, 143.6, 169.7, 143.6, 169.9, 145.9, 135.0, 185.0, 141.7, 191.0,
+113.8, 236.3, 122.6, 230.0, 103.4, 212.0, 107.5, 190.5, 109.2, 182.0,
+116.5, 183.4, 125.4, 176.3, 147.5, 158.8, 146.3, 157.1, 169.5, 141.3,
+157.8, 679.7, 171.7, 714.9, 171.3, 715.1, 184.6, 750.6, 184.7, 751.0,
+184.6, 751.1, 184.7, 751.5, 185.4, 756.6, 185.4, 756.6, 186.1, 761.7,
+175.0, 733.1, 176.1, 732.7, 166.1, 703.6, 162.0, 691.7, 162.5, 691.5,
+157.8, 679.7, 120.7, 617.0, 117.1, 625.4, 113.4, 625.4, 113.5, 633.8,
+118.6, 641.1, 107.0, 649.1, 100.4, 664.5, 100.9, 641.9, 104.9, 640.9,
+100.1, 619.4, 102.4, 610.2, 102.4, 610.2, 104.7, 601.1, 126.7, 560.0,
+129.0, 559.9, 141.9, 515.4, 141.9, 517.7, 141.9, 517.7, 141.9, 520.0,
+131.8, 568.6, 132.7, 568.8, 120.7, 617.0, 141.9, 520.0, 142.0, 543.5,
+142.0, 543.5, 142.0, 567.0, 142.1, 567.7, 141.4, 567.7, 141.4, 568.5,
+144.0, 585.9, 125.7, 587.3, 125.1, 606.5, 126.2, 611.0, 122.9, 611.8,
+120.7, 617.0, 132.7, 568.8, 131.8, 568.6, 141.9, 520.0, 69.2, 152.0,
+67.3, 142.3, 67.1, 140.6, 70.8, 131.7, 69.4, 135.0, 72.3, 136.2,
+73.9, 140.7, 79.7, 157.5, 83.2, 157.1, 85.5, 174.4, 84.6, 167.9,
+81.1, 168.4, 76.7, 162.3, 73.0, 157.2, 70.3, 157.7, 69.2, 152.0,
+67.4, 174.6, 67.4, 174.8, 67.4, 174.8, 67.4, 175.0, 67.2, 178.0,
+67.2, 178.0, 66.9, 181.0, 64.6, 210.9, 69.8, 212.3, 62.3, 240.9,
+58.8, 233.2, 59.1, 225.6, 55.3, 225.4, 53.3, 220.0, 53.3, 220.0,
+51.4, 214.6, 54.3, 199.5, 57.2, 200.1, 63.0, 185.6, 63.0, 185.5,
+63.0, 185.5, 63.0, 185.5, 65.2, 180.0, 65.2, 180.0, 67.4, 174.6,
+55.5, 87.2, 51.3, 86.0, 53.0, 79.9, 50.5, 72.6, 49.1, 68.4,
+49.1, 68.4, 47.6, 64.1, 47.2, 62.9, 46.6, 62.8, 46.8, 61.7,
+47.1, 58.6, 46.5, 57.3, 48.5, 55.6, 51.1, 57.0, 52.5, 54.8,
+56.4, 53.5, 71.2, 48.0, 71.7, 49.5, 87.1, 45.6, 87.3, 45.5,
+87.3, 45.5, 87.6, 45.5, 84.6, 48.1, 88.5, 52.6, 89.5, 59.8,
+88.8, 71.2, 92.0, 76.9, 85.1, 82.4, 75.0, 90.6, 68.6, 90.9,
+55.5, 87.2, 85.1, 82.4, 93.5, 106.7, 82.1, 112.3, 73.9, 140.7,
+72.3, 136.2, 69.4, 135.0, 70.8, 131.7, 65.7, 116.8, 65.7, 116.8,
+60.6, 101.9, 58.2, 95.1, 58.2, 95.1, 55.9, 88.2, 55.7, 87.7,
+55.6, 87.2, 55.5, 87.2, 68.6, 90.9, 75.0, 90.6, 85.1, 82.4,
+93.3, 87.3, 94.0, 92.2, 96.3, 96.3, 94.7, 97.2, 92.1, 120.2,
+99.2, 144.7, 101.2, 144.6, 100.2, 147.0, 102.6, 150.4, 102.0, 150.6,
+104.8, 170.5, 104.8, 170.5, 107.5, 190.5, 103.4, 212.0, 122.6, 230.0,
+113.8, 236.3, 113.7, 236.5, 114.0, 236.7, 113.9, 236.9, 113.1, 237.7,
+114.8, 240.2, 114.4, 240.4, 111.2, 244.9, 118.9, 253.8, 116.4, 255.3,
+114.0, 261.7, 117.5, 263.1, 118.6, 270.9, 119.2, 266.7, 117.0, 266.4,
+115.5, 261.9, 104.1, 228.6, 97.0, 229.5, 92.6, 195.2, 85.9, 142.1,
+92.2, 141.2, 93.3, 87.3, 92.6, 195.2, 92.7, 191.9, 91.4, 191.9,
+90.3, 188.5, 87.9, 181.5, 87.9, 181.5, 85.5, 174.4, 83.2, 157.1,
+79.7, 157.5, 73.9, 140.7, 82.1, 112.3, 93.5, 106.7, 85.1, 82.4,
+92.0, 76.9, 88.8, 71.2, 89.5, 59.8, 91.4, 73.5, 91.4, 73.5,
+93.3, 87.3, 92.2, 141.2, 85.9, 142.1, 92.6, 195.2, 75.0, 344.2,
+75.5, 328.2, 75.6, 328.2, 76.0, 312.1, 76.6, 299.7, 83.2, 291.6,
+77.7, 287.3, 84.3, 305.5, 84.3, 305.5, 90.8, 323.7, 90.3, 334.3,
+75.0, 344.2, 75.0, 344.2, 75.7, 317.2, 73.9, 344.1, 72.8, 344.1,
+72.1, 371.0, 66.5, 363.4, 66.5, 363.4, 60.9, 355.8, 62.3, 336.1,
+82.3, 326.3, 75.7, 317.2, 114.9, 486.1, 99.0, 457.2, 106.5, 437.0,
+83.1, 428.3, 79.5, 419.1, 73.3, 416.9, 75.8, 409.9, 76.1, 393.5,
+76.7, 393.4, 76.5, 377.0, 75.7, 380.0, 79.3, 381.0, 82.2, 384.9,
+82.6, 385.4, 82.7, 385.3, 82.9, 385.9, 88.9, 404.1, 88.8, 404.2,
+94.6, 422.5, 104.7, 454.3, 119.4, 483.8, 114.9, 486.1, 74.0, 508.4,
+74.5, 479.7, 74.5, 479.7, 75.1, 451.0, 75.5, 454.7, 78.2, 454.3,
+81.3, 457.6, 76.1, 468.4, 90.3, 475.2, 99.3, 492.8, 97.9, 502.2,
+73.8, 508.0, 74.0, 508.4, 99.3, 492.8, 105.6, 505.0, 102.1, 512.9,
+111.8, 517.1, 106.8, 534.3, 97.8, 531.6, 83.8, 546.1, 81.2, 548.7,
+81.6, 549.3, 78.7, 551.4, 78.6, 550.6, 78.8, 550.4, 78.4, 549.9,
+76.2, 547.2, 79.2, 544.8, 77.0, 541.9, 71.5, 538.3, 75.4, 532.3,
+73.7, 522.7, 72.5, 516.8, 74.7, 516.4, 73.9, 510.3, 73.7, 509.4,
+74.0, 509.4, 74.0, 508.4, 73.8, 508.0, 97.9, 502.2, 99.3, 492.8,
+115.1, 546.9, 107.5, 568.2, 104.7, 567.6, 100.0, 589.5, 99.8, 594.3,
+98.3, 594.2, 96.7, 598.9, 93.8, 582.6, 92.0, 581.1, 81.6, 567.8,
+80.6, 562.5, 82.9, 560.1, 79.7, 557.1, 78.0, 556.0, 79.2, 554.2,
+78.7, 551.4, 81.6, 549.3, 81.2, 548.7, 83.8, 546.1, 99.1, 544.2,
+113.0, 541.4, 115.1, 546.9, 83.8, 546.1, 97.8, 531.6, 106.8, 534.3,
+111.8, 517.1, 114.8, 518.5, 118.5, 510.7, 124.8, 503.8, 125.4, 503.4,
+128.5, 505.7, 128.8, 508.0, 127.4, 512.0, 127.1, 511.9, 126.0, 515.9,
+124.2, 531.8, 120.5, 531.4, 115.1, 546.9, 113.0, 541.4, 99.1, 544.2,
+83.8, 546.1, -27.0, 410.9, -28.8, 406.8, -30.4, 406.9, -30.6, 402.7,
+-32.6, 389.3, -29.2, 377.4, -34.5, 375.9, -34.7, 373.3, -32.7, 373.0,
+-33.2, 370.6, -29.2, 388.7, -30.4, 389.0, -27.5, 407.4, -27.2, 409.2,
+-27.8, 409.6, -27.0, 410.9, -22.3, 363.3, -25.0, 355.2, -24.5, 355.0,
+-27.6, 347.1, -27.8, 346.5, -27.1, 346.3, -27.3, 345.7, -24.5, 354.4,
+-20.5, 355.6, -22.3, 363.3, 2.2, 282.6, 9.2, 297.5, 18.3, 298.8,
+16.3, 312.3, 16.4, 326.7, 16.4, 326.7, 16.6, 341.0, 6.2, 338.8,
+1.5, 340.8, -6.7, 348.2, -16.5, 346.7, -15.9, 341.8, -24.8, 335.0,
+-24.8, 335.0, -24.7, 334.8, -24.7, 334.6, -23.4, 329.3, -23.3, 329.4,
+-22.1, 324.1, -11.1, 302.8, -14.7, 287.8, 2.2, 282.6, -22.1, 324.1,
+-32.6, 302.0, -22.3, 289.0, -7.1, 263.0, -6.8, 272.9, -2.5, 272.8,
+2.2, 282.6, -14.7, 287.8, -11.1, 302.8, -22.1, 324.1, 48.9, 670.5,
+45.7, 656.7, 49.8, 654.0, 42.5, 643.0, 47.9, 644.1, 53.2, 643.6,
+53.4, 645.1, 59.0, 650.8, 62.8, 647.0, 72.2, 648.9, 70.0, 661.3,
+58.1, 672.3, 48.9, 670.5, 749.0, 492.6, 747.0, 491.5, 749.8, 485.2,
+748.1, 484.6, 762.9, 499.3, 767.1, 495.1, 786.1, 505.6, 785.1, 497.0,
+766.0, 502.0, 749.0, 492.6, 804.0, 583.1, 804.0, 596.3, 804.0, 598.2,
+797.6, 609.5, 793.0, 608.8, 788.4, 609.3, 787.9, 611.3, 783.2, 607.1,
+780.2, 601.8, 778.4, 602.8, 778.5, 602.6, 778.0, 602.4, 777.5, 602.0,
+781.5, 601.4, 784.1, 591.8, 782.5, 583.1, 787.8, 562.4, 787.8, 562.4,
+793.2, 541.7, 795.3, 533.5, 799.3, 532.4, 797.4, 525.2, 804.7, 553.1,
+803.9, 554.2, 804.0, 583.1, 797.4, 525.2, 797.1, 519.5, 798.1, 513.8,
+800.5, 513.5, 808.6, 518.0, 809.9, 516.5, 816.7, 522.4, 817.5, 523.1,
+818.2, 523.9, 818.4, 523.8, 815.5, 535.4, 814.9, 535.3, 812.7, 547.1,
+810.7, 555.2, 810.7, 555.2, 808.8, 563.4, 806.4, 573.2, 801.5, 574.7,
+804.0, 583.1, 803.9, 554.2, 804.7, 553.1, 797.4, 525.2, 713.5, 490.2,
+713.2, 490.0, 713.6, 489.3, 713.3, 489.1, 717.8, 492.9, 718.2, 492.3,
+723.2, 495.6, 722.6, 492.1, 718.1, 493.2, 713.5, 490.2, 744.7, 514.0,
+740.9, 511.5, 738.4, 508.1, 737.1, 509.1, 734.5, 506.4, 735.2, 505.7,
+733.3, 502.3, 732.5, 501.9, 732.8, 501.5, 732.3, 500.6, 738.7, 507.1,
+740.3, 506.3, 744.7, 514.0, 840.1, 624.8, 859.1, 643.0, 856.0, 656.1,
+878.0, 661.2, 875.3, 663.4, 875.3, 663.4, 872.6, 665.6, 862.1, 657.6,
+864.1, 655.0, 855.7, 644.3, 849.0, 635.9, 849.0, 635.9, 842.2, 627.4,
+841.2, 626.1, 841.3, 625.9, 840.1, 624.8, 839.5, 570.9, 839.5, 570.9,
+847.4, 578.7, 855.2, 586.5, 855.4, 586.6, 855.4, 586.6, 855.5, 586.8,
+860.1, 591.3, 860.2, 591.2, 864.8, 595.8, 865.1, 596.1, 865.0, 596.2,
+865.4, 596.6, 860.4, 591.7, 860.4, 591.7, 855.5, 586.8, 855.4, 586.6,
+855.4, 586.6, 855.2, 586.5, 847.4, 578.7, 839.5, 570.9, 839.5, 570.9,
+877.5, 603.6, 857.1, 585.8, 857.1, 585.8, 836.7, 568.0, 838.3, 567.7,
+839.8, 566.4, 839.6, 565.9, 839.5, 565.7, 842.7, 563.6, 845.9, 561.2,
+851.4, 552.7, 856.6, 556.1, 867.3, 550.9, 867.2, 551.2, 872.1, 553.1,
+876.8, 555.4, 881.3, 578.7, 884.1, 601.5, 877.5, 603.6, 876.8, 555.4,
+887.4, 560.3, 887.3, 560.5, 897.9, 565.3, 900.5, 583.4, 900.4, 583.4,
+903.1, 601.5, 904.2, 615.5, 904.8, 615.5, 907.1, 629.4, 892.3, 616.5,
+892.3, 616.5, 877.5, 603.6, 884.1, 601.5, 881.3, 578.7, 876.8, 555.4,
+924.9, 574.1, 934.6, 580.7, 934.6, 580.7, 944.3, 587.3, 944.0, 594.1,
+941.0, 598.8, 944.0, 600.9, 943.8, 604.9, 945.7, 606.7, 943.6, 608.8,
+926.1, 612.3, 927.9, 621.4, 912.2, 633.9, 912.3, 632.1, 910.0, 632.0,
+907.8, 630.0, 907.5, 626.4, 907.2, 626.4, 906.6, 622.8, 904.2, 604.5,
+903.8, 604.5, 901.1, 586.3, 904.6, 577.0, 913.1, 573.8, 924.9, 574.1,
+901.1, 586.3, 896.6, 584.8, 899.5, 575.8, 897.9, 565.3, 897.9, 565.1,
+897.9, 565.1, 897.9, 564.9, 897.2, 559.8, 898.2, 559.5, 896.4, 554.7,
+903.9, 559.8, 903.7, 560.0, 911.3, 564.9, 913.1, 566.1, 913.1, 566.1,
+915.0, 567.3, 915.1, 570.9, 919.9, 570.7, 924.9, 574.1, 913.1, 573.8,
+904.6, 577.0, 901.1, 586.3, 556.4, 358.5, 563.7, 373.2, 565.8, 372.2,
+575.2, 385.9, 582.9, 397.1, 582.9, 397.1, 590.6, 408.4, 612.9, 440.9,
+613.2, 440.7, 635.2, 473.4, 635.6, 474.9, 636.0, 474.9, 636.1, 476.4,
+637.2, 490.9, 632.9, 492.8, 638.3, 505.4, 638.4, 507.7, 638.1, 507.7,
+637.8, 510.0, 637.6, 511.1, 638.0, 511.3, 637.5, 512.3, 637.6, 512.1,
+637.2, 511.8, 636.9, 511.4, 596.6, 435.0, 594.5, 436.0, 556.4, 358.5,
+636.9, 511.4, 631.2, 500.0, 630.0, 500.6, 623.1, 489.8, 602.2, 457.1,
+602.2, 457.1, 581.3, 424.5, 580.7, 423.6, 580.7, 423.6, 580.1, 422.7,
+576.4, 416.8, 576.4, 416.8, 572.6, 410.9, 568.0, 403.6, 568.0, 403.6,
+563.3, 396.4, 554.4, 382.5, 554.4, 382.5, 545.5, 368.5, 542.6, 364.1,
+540.9, 364.5, 539.8, 359.6, 538.8, 344.7, 538.3, 344.7, 536.7, 329.8,
+545.6, 329.2, 548.0, 343.3, 556.4, 358.5, 594.5, 436.0, 596.6, 435.0,
+636.9, 511.4, 675.1, 570.2, 674.8, 570.2, 674.6, 570.3, 674.6, 570.2,
+665.5, 556.2, 665.7, 556.0, 656.7, 541.9, 653.1, 536.2, 653.0, 536.3,
+649.4, 530.7, 645.6, 524.9, 641.9, 519.1, 641.9, 519.1, 641.9, 519.1,
+645.6, 524.9, 649.4, 530.7, 653.0, 536.3, 653.1, 536.2, 656.7, 541.9,
+665.9, 556.0, 666.1, 555.9, 675.1, 570.2, 899.8, 548.7, 895.3, 542.3,
+895.6, 542.1, 890.9, 536.0, 885.0, 514.4, 887.5, 513.7, 884.2, 491.5,
+882.5, 489.1, 883.7, 488.2, 883.2, 484.9, 883.2, 484.2, 883.7, 484.2,
+884.2, 483.4, 886.2, 479.1, 886.7, 479.4, 889.2, 475.3, 894.8, 486.7,
+891.1, 488.4, 893.0, 501.6, 896.4, 525.1, 901.3, 525.5, 899.8, 548.7,
+884.2, 389.0, 889.3, 403.4, 884.3, 409.7, 894.4, 417.8, 899.5, 431.9,
+904.7, 432.0, 904.5, 446.0, 898.0, 455.1, 899.1, 455.9, 893.7, 465.8,
+881.0, 430.2, 883.6, 427.3, 884.2, 389.0, 893.7, 465.8, 888.9, 474.6,
+888.4, 474.4, 884.2, 483.4, 883.7, 484.2, 883.2, 484.2, 883.2, 484.9,
+882.6, 480.5, 884.0, 479.6, 881.9, 476.0, 881.7, 474.5, 881.7, 474.5,
+881.4, 472.9, 881.6, 432.1, 876.0, 432.0, 869.9, 391.2, 870.0, 370.4,
+872.9, 370.0, 870.1, 349.6, 876.6, 367.7, 878.4, 386.3, 883.1, 385.9,
+882.6, 387.0, 883.6, 387.4, 884.2, 389.0, 883.6, 427.3, 881.0, 430.2,
+893.7, 465.8, 912.4, 468.1, 909.0, 458.6, 911.4, 456.8, 905.6, 449.0,
+905.9, 447.7, 904.0, 446.7, 904.5, 446.0, 904.7, 432.0, 899.5, 431.9,
+894.4, 417.8, 896.0, 419.1, 901.1, 412.8, 907.7, 407.8, 917.5, 435.3,
+913.9, 438.2, 912.4, 468.1, 907.7, 407.8, 913.4, 403.5, 917.7, 404.6,
+919.1, 399.2, 920.4, 403.4, 920.4, 403.4, 921.6, 407.7, 923.3, 429.6,
+924.9, 429.4, 928.2, 451.2, 930.2, 470.0, 930.5, 470.0, 933.3, 488.7,
+936.3, 516.2, 934.7, 516.5, 939.4, 543.8, 931.7, 522.3, 935.4, 520.1,
+924.1, 500.9, 921.1, 492.4, 921.1, 492.4, 918.1, 484.0, 916.7, 480.1,
+916.7, 480.1, 915.3, 476.2, 916.2, 472.8, 913.8, 472.2, 912.4, 468.1,
+913.9, 438.2, 917.5, 435.3, 907.7, 407.8, 869.3, 391.2, 869.6, 393.4,
+869.6, 395.5, 869.9, 395.5, 875.4, 434.2, 881.6, 434.2, 881.4, 472.9,
+881.7, 474.5, 881.7, 474.5, 881.9, 476.0, 862.4, 442.8, 860.9, 443.7,
+840.0, 411.3, 838.8, 403.6, 853.7, 399.5, 869.3, 391.2, 840.0, 411.3,
+833.9, 401.9, 836.4, 396.3, 827.8, 392.5, 834.3, 373.1, 846.5, 358.5,
+840.8, 353.8, 844.2, 352.5, 844.2, 352.5, 847.6, 351.2, 847.8, 352.0,
+856.3, 353.2, 863.2, 350.6, 866.2, 370.9, 866.2, 370.9, 869.3, 391.2,
+853.7, 399.5, 838.8, 403.6, 840.0, 411.3, 797.4, 463.4, 818.1, 481.9,
+832.6, 485.1, 832.8, 507.0, 815.2, 491.3, 815.2, 491.3, 797.5, 475.5,
+794.5, 471.9, 800.4, 466.1, 797.4, 463.4, 797.5, 475.5, 781.5, 461.2,
+783.7, 457.2, 765.4, 446.9, 763.2, 449.1, 743.6, 417.7, 714.5, 401.6,
+727.0, 396.9, 727.0, 396.9, 739.4, 392.2, 746.0, 393.0, 745.1, 399.2,
+750.9, 406.3, 764.3, 422.8, 764.3, 422.8, 777.8, 439.4, 787.6, 451.4,
+790.1, 450.1, 797.4, 463.4, 800.4, 466.1, 794.5, 471.9, 797.5, 475.5,
+764.0, 382.8, 766.2, 382.0, 766.2, 382.0, 768.3, 381.2, 787.3, 419.8,
+792.2, 417.7, 818.3, 452.4, 839.0, 481.8, 837.6, 483.0, 859.8, 511.3,
+811.2, 449.2, 812.7, 448.1, 765.5, 384.9, 764.8, 383.9, 763.8, 383.1,
+764.0, 382.8, 875.4, 533.5, 871.8, 528.1, 871.7, 528.3, 868.0, 523.0,
+863.9, 517.2, 863.9, 517.2, 859.8, 511.3, 837.6, 483.0, 839.0, 481.8,
+818.3, 452.4, 814.6, 447.4, 815.7, 446.5, 813.2, 440.7, 831.1, 465.0,
+830.0, 465.8, 846.8, 490.9, 848.1, 492.9, 848.1, 492.9, 849.5, 494.8,
+862.4, 514.2, 862.6, 514.1, 875.4, 533.5, 544.1, 175.8, 556.5, 200.5,
+554.9, 201.4, 569.0, 225.3, 561.9, 229.4, 547.8, 205.6, 526.7, 186.0,
+525.3, 184.7, 524.4, 183.1, 523.9, 183.4, 533.0, 178.0, 540.5, 172.5,
+544.1, 175.8, 526.7, 186.0, 547.8, 205.6, 561.9, 229.4, 569.0, 225.3,
+572.1, 230.5, 576.1, 228.6, 578.3, 234.0, 586.1, 245.8, 588.9, 243.9,
+599.6, 253.8, 619.4, 274.2, 619.6, 274.0, 639.5, 294.1, 616.9, 278.6,
+614.7, 281.7, 589.9, 269.3, 577.6, 260.4, 580.3, 256.7, 570.7, 244.0,
+560.1, 230.0, 560.1, 230.0, 549.5, 216.0, 544.8, 209.8, 544.8, 209.8,
+540.0, 203.6, 538.5, 201.6, 538.5, 201.6, 537.0, 199.6, 531.9, 192.8,
+533.2, 191.2, 526.7, 186.0, 606.5, 321.3, 607.1, 332.5, 603.3, 334.3,
+607.8, 343.7, 582.8, 318.3, 582.8, 318.3, 557.8, 293.0, 550.1, 270.2,
+544.6, 272.1, 531.4, 251.2, 574.7, 276.3, 574.1, 282.0, 606.5, 321.3,
+531.4, 251.2, 526.9, 244.1, 528.3, 242.6, 522.4, 236.9, 563.4, 261.1,
+563.4, 261.1, 604.4, 285.3, 606.6, 286.8, 604.7, 289.6, 604.9, 294.0,
+605.1, 297.0, 605.1, 297.0, 605.3, 300.0, 602.1, 301.3, 605.9, 310.6,
+606.5, 321.3, 574.1, 282.0, 574.7, 276.3, 531.4, 251.2, 604.9, 294.0,
+604.7, 289.6, 606.6, 286.8, 604.4, 285.3, 606.9, 286.8, 606.9, 286.8,
+609.4, 288.2, 609.6, 291.0, 605.3, 294.2, 604.9, 294.0, 542.8, 279.0,
+564.4, 308.2, 562.7, 309.6, 586.0, 337.3, 543.6, 311.2, 543.6, 311.2,
+501.2, 285.0, 505.9, 288.8, 510.0, 283.7, 518.8, 282.5, 530.8, 280.7,
+536.5, 273.8, 542.8, 279.0, 567.3, 73.7, 569.0, 78.4, 568.2, 78.7,
+569.1, 83.6, 569.4, 84.9, 569.4, 84.9, 569.6, 86.2, 568.6, 86.9,
+571.5, 91.2, 570.6, 91.6, 566.7, 94.4, 566.7, 94.4, 562.7, 97.1,
+561.8, 97.0, 561.9, 94.1, 561.1, 91.2, 553.1, 61.2, 553.1, 61.2,
+545.1, 31.1, 543.1, 23.6, 543.1, 23.6, 541.1, 16.0, 535.7, -4.2,
+538.8, -5.6, 530.3, -24.4, 551.9, 23.2, 549.6, 24.4, 567.3, 73.7,
+530.3, -24.4, 529.7, -26.0, 529.8, -26.1, 529.4, -27.8, 528.2, -32.2,
+527.2, -32.2, 527.0, -36.7, 526.9, -37.9, 528.8, -39.2, 528.8, -39.2,
+530.9, -27.9, 550.9, -21.1, 549.9, -19.7, 553.8, 1.1, 548.9, 19.7,
+557.7, 22.0, 560.4, 36.7, 560.4, 36.7, 563.1, 51.4, 565.2, 62.6,
+562.9, 63.6, 567.3, 73.7, 549.6, 24.4, 551.9, 23.2, 530.3, -24.4,
+682.2, -11.8, 682.8, -12.2, 687.1, -7.7, 686.9, -7.4, 662.7, 7.7,
+666.9, 14.4, 646.9, 36.3, 607.4, 59.9, 606.8, 59.2, 569.6, 86.2,
+569.4, 84.9, 569.4, 84.9, 569.1, 83.6, 588.0, 66.3, 588.8, 67.1,
+608.4, 50.5, 624.1, 37.2, 624.1, 37.2, 639.9, 23.9, 661.0, 6.1,
+659.3, 3.5, 682.2, -11.8, 376.8, 74.3, 374.7, 66.1, 374.7, 66.1,
+372.6, 57.9, 376.1, 61.9, 406.7, 46.2, 406.0, 43.4, 413.5, 43.8,
+421.0, 59.2, 420.2, 60.1, 406.4, 74.7, 398.1, 75.3, 376.8, 74.3,
+439.2, 19.5, 426.1, 5.7, 426.1, 5.7, 413.0, -8.1, 441.4, -5.2,
+442.7, -8.0, 471.0, -14.3, 488.5, -14.8, 498.8, -2.9, 506.1, -10.7,
+482.9, 14.0, 473.1, 18.6, 439.2, 19.5, 506.1, -10.7, 506.9, -11.0,
+507.9, -10.1, 508.1, -10.5, 487.9, 19.2, 487.4, 18.9, 466.1, 47.9,
+466.2, 47.8, 465.9, 47.6, 465.6, 47.3, 452.6, 33.3, 452.4, 33.4,
+439.2, 19.5, 473.1, 18.6, 482.9, 14.0, 506.1, -10.7, 424.5, 65.0,
+422.7, 62.3, 422.4, 62.5, 420.2, 60.1, 421.0, 59.2, 413.5, 43.8,
+406.0, 43.4, 397.1, 8.3, 364.4, -22.7, 353.5, -18.0, 352.8, -20.5,
+351.7, -22.3, 349.8, -22.3, 355.9, -23.9, 355.9, -23.9, 362.0, -25.4,
+371.9, -18.7, 369.3, -14.8, 376.6, -4.2, 383.0, 5.0, 383.0, 5.0,
+389.3, 14.2, 396.6, 24.7, 396.6, 24.7, 403.8, 35.1, 414.2, 50.1,
+414.5, 49.8, 424.5, 65.0, 414.0, -38.8, 421.4, -40.7, 421.3, -40.9,
+428.6, -42.8, 449.2, -48.0, 449.2, -47.9, 469.8, -53.0, 471.6, -53.4,
+471.6, -53.4, 473.5, -53.9, 443.7, -46.3, 443.8, -46.2, 414.0, -38.8,
+208.2, 292.5, 217.0, 279.3, 222.7, 280.5, 225.8, 266.0, 239.8, 263.1,
+242.0, 274.1, 258.3, 282.1, 260.9, 283.4, 260.9, 283.4, 263.4, 284.6,
+267.9, 286.8, 272.4, 286.8, 272.4, 289.1, 272.4, 291.5, 267.9, 291.5,
+263.4, 293.9, 252.2, 300.0, 252.2, 300.0, 241.0, 306.0, 240.2, 306.5,
+239.9, 307.2, 239.3, 307.0, 223.5, 300.4, 211.9, 303.7, 208.2, 292.5,
+239.3, 307.0, 240.1, 309.9, 227.5, 313.4, 215.6, 319.8, 208.1, 323.9,
+208.1, 323.9, 200.5, 328.0, 197.8, 326.4, 191.7, 329.4, 190.1, 333.6,
+194.5, 320.1, 194.5, 320.1, 198.8, 306.6, 200.1, 299.0, 203.5, 299.5,
+208.2, 292.5, 211.9, 303.7, 223.5, 300.4, 239.3, 307.0, 238.5, 111.6,
+244.2, 108.1, 247.0, 109.7, 249.8, 104.6, 245.6, 119.3, 245.6, 119.3,
+241.5, 134.0, 240.6, 137.6, 239.4, 137.2, 238.0, 140.7, 230.1, 155.8,
+230.1, 155.8, 222.2, 171.0, 200.9, 211.7, 203.3, 213.2, 179.6, 252.5,
+180.5, 246.8, 179.8, 246.7, 179.9, 241.0, 207.3, 175.5, 206.2, 174.7,
+238.5, 111.6, 179.9, 241.0, 180.4, 221.2, 174.6, 203.5, 180.9, 201.5,
+201.5, 161.7, 201.5, 161.7, 222.1, 121.8, 224.7, 114.7, 230.3, 116.7,
+238.5, 111.6, 206.2, 174.7, 207.3, 175.5, 179.9, 241.0, 199.0, 163.7,
+180.0, 201.5, 180.0, 201.5, 161.1, 239.4, 150.1, 261.1, 150.0, 261.0,
+138.9, 282.6, 137.6, 285.0, 137.6, 285.0, 136.3, 287.5, 137.7, 283.6,
+136.5, 283.1, 136.6, 278.7, 146.3, 257.4, 147.8, 258.1, 159.0, 237.4,
+179.0, 200.6, 206.9, 171.3, 199.0, 163.7, 477.6, 762.9, 483.4, 806.1,
+483.5, 806.0, 489.1, 849.3, 489.8, 854.9, 489.6, 854.9, 490.1, 860.6,
+490.8, 868.4, 490.2, 868.5, 491.6, 876.2, 489.4, 864.4, 490.1, 864.3,
+488.6, 852.4, 483.4, 810.0, 483.4, 810.0, 478.2, 767.6, 477.9, 765.3,
+477.9, 765.2, 477.6, 762.9, 491.9, 847.9, 491.7, 854.3, 493.4, 859.1,
+490.1, 860.6, 489.6, 854.9, 489.8, 854.9, 489.1, 849.3, 487.8, 840.3,
+488.3, 840.2, 487.4, 831.1, 485.8, 836.4, 489.1, 837.4, 490.8, 843.6,
+491.4, 845.8, 492.0, 845.8, 491.9, 847.9, 501.5, 451.5, 496.1, 456.3,
+485.1, 452.0, 484.8, 454.4, 495.2, 435.8, 495.2, 435.9, 505.5, 417.3,
+512.4, 405.1, 519.8, 404.6, 519.2, 392.8, 528.4, 376.3, 537.4, 359.8,
+537.5, 359.8, 538.4, 359.2, 538.9, 358.3, 538.6, 357.9, 539.2, 358.7,
+539.7, 358.7, 539.8, 359.6, 540.9, 364.5, 542.6, 364.1, 545.5, 368.5,
+533.3, 400.4, 529.4, 398.9, 513.3, 429.3, 507.4, 440.4, 510.3, 443.7,
+501.5, 451.5, 468.2, 621.6, 466.6, 603.5, 466.5, 603.5, 464.8, 585.3,
+484.5, 550.0, 465.4, 538.7, 463.8, 492.1, 471.6, 478.1, 471.6, 478.1,
+479.4, 464.0, 488.2, 493.2, 477.1, 496.5, 474.8, 529.0, 474.7, 530.5,
+474.7, 530.5, 474.6, 531.9, 472.3, 563.6, 472.3, 563.6, 470.1, 595.2,
+469.2, 607.8, 469.2, 607.8, 468.3, 620.3, 468.2, 621.0, 468.1, 621.0,
+468.2, 621.6, 458.7, 501.2, 458.0, 502.4, 457.3, 502.5, 457.3, 503.6,
+456.5, 494.1, 456.5, 494.1, 455.6, 484.5, 452.4, 490.2, 457.9, 492.8,
+458.7, 501.2, 480.2, 266.5, 481.8, 271.2, 482.9, 270.8, 485.7, 275.1,
+492.4, 286.2, 492.6, 286.0, 499.6, 296.9, 503.1, 301.2, 500.0, 303.7,
+500.3, 310.6, 492.2, 303.8, 495.4, 300.0, 490.6, 289.4, 485.4, 277.9,
+484.3, 278.3, 480.2, 266.5, 205.6, 671.5, 207.4, 667.6, 208.7, 667.8,
+209.3, 663.7, 209.5, 676.0, 209.5, 676.0, 209.6, 688.4, 212.5, 682.3,
+205.7, 680.0, 205.6, 671.5, 173.8, 490.6, 180.4, 471.0, 174.1, 457.5,
+187.1, 451.5, 206.4, 425.2, 203.9, 422.9, 225.7, 398.9, 231.9, 390.5,
+230.2, 388.0, 238.3, 382.2, 236.2, 383.7, 239.4, 387.0, 237.7, 390.2,
+229.6, 406.0, 228.1, 405.3, 218.5, 420.3, 211.9, 430.8, 211.9, 430.8,
+205.2, 441.3, 189.5, 466.0, 196.2, 478.0, 173.8, 490.6, 434.6, 322.4,
+437.2, 344.4, 439.3, 344.4, 439.9, 366.4, 440.0, 367.4, 440.0, 367.4,
+440.0, 368.4, 432.0, 356.0, 432.4, 355.7, 424.7, 343.1, 424.2, 342.3,
+424.2, 342.3, 423.8, 341.6, 419.6, 334.6, 419.6, 334.6, 415.3, 327.6,
+405.7, 311.6, 405.7, 311.6, 396.0, 295.6, 392.0, 289.0, 389.9, 289.5,
+387.9, 282.3, 377.8, 275.8, 385.3, 264.0, 382.7, 245.8, 379.9, 250.3,
+390.0, 256.5, 397.3, 267.3, 407.0, 281.7, 407.0, 281.7, 416.8, 296.1,
+417.2, 296.7, 417.2, 296.7, 417.5, 297.2, 420.5, 301.6, 420.5, 301.6,
+423.4, 305.9, 429.0, 314.1, 432.1, 313.3, 434.6, 322.4, 209.1, 881.3,
+209.0, 881.8, 205.6, 882.1, 202.6, 881.2, 203.0, 880.7, 202.4, 880.2,
+202.3, 879.2, 215.2, 875.8, 205.3, 838.2, 208.2, 797.2, 203.1, 821.6,
+208.5, 822.8, 208.8, 848.4, 209.0, 864.8, 212.1, 865.4, 209.1, 881.3,
+322.4, 303.2, 317.5, 312.0, 320.3, 313.4, 316.6, 322.9, 314.1, 329.5,
+313.2, 329.1, 309.8, 335.3, 309.5, 336.0, 309.4, 336.0, 309.1, 336.7,
+315.6, 319.9, 313.8, 318.9, 322.4, 303.2, 309.8, 335.3, 313.2, 329.1,
+314.1, 329.5, 316.6, 322.9, 311.6, 347.8, 309.5, 347.3, 302.4, 371.7,
+301.0, 376.6, 301.0, 376.6, 299.6, 381.6, 296.0, 393.7, 296.0, 393.7,
+292.5, 405.8, 292.3, 406.5, 292.3, 406.5, 292.1, 407.2, 291.4, 409.5,
+291.4, 409.5, 290.7, 411.9, 283.9, 435.5, 283.9, 435.5, 277.0, 459.0,
+274.5, 467.6, 274.5, 467.6, 272.0, 476.1, 270.8, 480.4, 270.8, 480.4,
+269.5, 484.6, 256.2, 529.7, 256.2, 529.6, 242.9, 574.7, 241.7, 578.5,
+241.8, 578.5, 240.7, 582.4, 236.3, 598.2, 231.9, 614.0, 231.9, 614.0,
+231.9, 614.0, 236.3, 598.2, 240.7, 582.4, 241.8, 578.5, 241.7, 578.5,
+242.9, 574.7, 267.7, 486.1, 267.8, 486.1, 292.4, 397.5, 300.9, 367.2,
+300.6, 367.1, 309.1, 336.7, 309.4, 336.0, 309.5, 336.0, 309.8, 335.3,
+144.7, 133.3, 156.7, 133.2, 156.7, 133.2, 168.8, 133.0, 168.1, 133.2,
+169.2, 137.2, 169.5, 141.3, 146.3, 157.1, 147.5, 158.8, 125.4, 176.3,
+127.9, 177.1, 129.1, 148.9, 144.7, 133.3, 125.4, 176.3, 116.5, 183.4,
+109.2, 182.0, 107.5, 190.5, 104.8, 170.5, 104.8, 170.5, 102.0, 150.6,
+118.6, 144.8, 117.6, 142.0, 133.2, 133.5, 133.7, 132.2, 137.8, 135.0,
+140.7, 133.4, 142.0, 132.4, 142.7, 133.4, 144.7, 133.3, 129.1, 148.9,
+127.9, 177.1, 125.4, 176.3, 115.5, 261.9, 117.0, 266.4, 119.2, 266.7,
+118.6, 270.9, 118.7, 271.9, 118.7, 271.9, 118.9, 272.9, 123.6, 317.8,
+123.5, 317.8, 128.3, 362.6, 128.7, 366.0, 129.2, 369.3, 129.2, 369.3,
+129.2, 369.3, 128.7, 366.0, 128.3, 362.6, 121.9, 312.3, 120.9, 312.4,
+115.5, 261.9, 60.6, 101.9, 65.7, 116.8, 65.7, 116.8, 70.8, 131.7,
+67.1, 140.6, 67.3, 142.3, 69.2, 152.0, 68.3, 163.3, 69.5, 163.5,
+67.4, 174.6, 65.2, 180.0, 65.2, 180.0, 63.0, 185.5, 63.2, 185.1,
+63.0, 185.0, 63.0, 184.6, 62.5, 168.3, 62.5, 168.3, 62.1, 152.1,
+61.3, 127.0, 51.6, 122.9, 60.6, 101.9, 129.6, 436.3, 133.6, 448.4,
+133.2, 448.6, 137.6, 460.5, 122.5, 453.7, 126.3, 445.1, 115.1, 429.8,
+105.8, 417.1, 108.9, 409.5, 96.5, 404.4, 115.6, 412.2, 112.5, 419.8,
+128.4, 435.2, 129.0, 435.8, 129.3, 435.7, 129.6, 436.3, 38.9, 323.2,
+38.5, 321.0, 38.5, 321.0, 38.1, 318.9, 53.0, 296.7, 49.7, 294.5,
+61.2, 270.1, 65.4, 294.0, 51.2, 297.2, 38.9, 323.2, 115.1, 429.8,
+126.3, 445.1, 122.5, 453.7, 137.6, 460.5, 138.0, 461.7, 139.3, 461.7,
+139.2, 462.7, 139.8, 464.7, 142.0, 464.7, 141.8, 466.3, 141.8, 468.7,
+141.8, 468.7, 141.9, 471.0, 142.0, 471.5, 141.7, 471.6, 141.5, 472.1,
+130.0, 454.6, 130.4, 454.3, 119.3, 436.5, 117.2, 433.1, 117.5, 432.9,
+115.1, 429.8, -27.5, 407.4, -30.4, 389.0, -29.2, 388.7, -33.2, 370.6,
+-33.3, 359.7, -34.8, 355.3, -28.1, 348.9, -26.1, 355.1, -25.7, 355.0,
+-23.3, 361.1, -23.0, 384.2, -14.8, 395.3, -27.5, 407.4, -23.3, 361.1,
+-22.7, 362.5, -22.7, 362.5, -22.1, 363.9, -20.4, 368.4, -20.4, 368.4,
+-18.6, 372.9, -4.0, 410.0, -0.8, 409.0, 10.6, 447.0, 15.8, 451.1,
+10.4, 458.2, 10.2, 469.4, -3.1, 439.7, -25.9, 441.5, -25.5, 414.1,
+-26.2, 412.5, -26.2, 412.5, -27.0, 410.9, -27.8, 409.6, -27.2, 409.2,
+-27.5, 407.4, -14.8, 395.3, -23.0, 384.2, -23.3, 361.1, -15.8, 379.3,
+-17.1, 376.1, -18.6, 372.9, -18.6, 372.9, -20.4, 368.4, -20.4, 368.4,
+-22.1, 363.9, -22.2, 363.6, -22.2, 363.6, -22.3, 363.3, -20.5, 355.6,
+-24.5, 354.4, -27.3, 345.7, -27.8, 340.5, -25.4, 335.0, -24.8, 335.0,
+-15.9, 341.8, -16.5, 346.7, -6.7, 348.2, -5.9, 347.4, -2.9, 353.3,
+1.7, 354.3, 1.8, 359.9, 9.7, 365.8, 16.8, 365.3, 17.9, 368.2,
+19.8, 367.5, 22.8, 369.6, 22.8, 369.7, 22.8, 369.7, 22.8, 369.7,
+22.9, 371.5, 22.8, 371.5, 22.8, 373.4, 3.9, 378.1, 3.5, 379.5,
+-15.8, 379.3, 22.8, 373.4, 22.9, 387.5, 22.9, 387.5, 22.9, 401.7,
+21.1, 397.3, -5.3, 402.7, -5.3, 403.6, -10.6, 391.4, -10.6, 391.4,
+-15.8, 379.3, 3.5, 379.5, 3.9, 378.1, 22.8, 373.4, 89.4, 652.2,
+89.7, 652.3, 89.9, 652.3, 89.9, 652.3, 91.2, 668.6, 91.2, 668.6,
+92.5, 684.9, 87.9, 684.0, 90.7, 668.6, 89.4, 652.2, 765.8, 541.1,
+758.0, 521.3, 758.6, 521.0, 750.1, 501.5, 748.7, 497.4, 750.1, 492.7,
+749.0, 492.6, 766.0, 502.0, 785.1, 497.0, 786.1, 505.6, 793.3, 509.5,
+793.3, 509.5, 800.5, 513.5, 798.1, 513.8, 797.1, 519.5, 797.4, 525.2,
+799.3, 532.4, 795.3, 533.5, 793.2, 541.7, 782.4, 547.1, 773.3, 548.1,
+765.8, 541.1, 793.2, 541.7, 787.8, 562.4, 787.8, 562.4, 782.5, 583.1,
+778.3, 561.3, 774.1, 562.1, 765.8, 541.1, 773.3, 548.1, 782.4, 547.1,
+793.2, 541.7, 748.5, 575.4, 744.8, 572.5, 744.4, 572.8, 741.0, 569.6,
+734.7, 564.0, 734.7, 564.0, 728.5, 558.4, 727.5, 551.0, 726.0, 551.2,
+723.5, 543.9, 738.5, 556.7, 737.2, 558.8, 748.5, 575.4, 723.5, 543.9,
+723.0, 542.4, 722.7, 542.5, 722.5, 540.9, 722.2, 539.4, 721.3, 538.6,
+722.0, 537.9, 720.3, 528.5, 720.3, 528.5, 718.6, 519.2, 716.1, 504.7,
+710.9, 503.7, 713.5, 490.2, 718.1, 493.2, 722.6, 492.1, 723.2, 495.6,
+728.2, 499.0, 728.0, 499.4, 733.3, 502.3, 735.2, 505.7, 734.5, 506.4,
+737.1, 509.1, 736.7, 509.4, 739.2, 512.8, 741.2, 516.5, 744.6, 544.7,
+744.7, 547.0, 758.5, 571.7, 759.3, 578.0, 759.3, 578.0, 760.1, 584.4,
+754.8, 579.3, 754.3, 579.9, 748.5, 575.4, 737.2, 558.8, 738.5, 556.7,
+723.5, 543.9, 750.7, 506.1, 751.4, 512.5, 751.4, 512.5, 752.2, 518.9,
+750.9, 515.5, 748.4, 516.4, 744.7, 514.0, 740.3, 506.3, 738.7, 507.1,
+732.3, 500.6, 719.9, 478.6, 726.2, 469.7, 707.6, 456.6, 706.9, 452.6,
+706.9, 452.6, 706.2, 448.6, 730.0, 476.0, 730.8, 475.8, 750.7, 506.1,
+706.2, 448.6, 703.8, 435.3, 705.6, 434.7, 701.5, 422.0, 706.9, 425.7,
+706.9, 425.7, 712.4, 429.4, 714.7, 448.8, 726.1, 451.4, 745.7, 464.8,
+745.7, 465.1, 745.6, 465.3, 745.8, 465.5, 750.7, 468.2, 742.7, 479.3,
+748.1, 484.6, 749.8, 485.2, 747.0, 491.5, 749.0, 492.6, 750.1, 492.7,
+748.7, 497.4, 750.1, 501.5, 751.0, 503.5, 750.4, 503.8, 750.7, 506.1,
+730.8, 475.8, 730.0, 476.0, 706.2, 448.6, 835.7, 623.1, 836.7, 624.3,
+837.6, 623.4, 839.3, 624.0, 839.8, 624.1, 839.7, 624.4, 840.1, 624.8,
+841.3, 625.9, 841.2, 626.1, 842.2, 627.4, 838.6, 626.1, 838.1, 626.0,
+835.7, 623.1, 855.5, 586.8, 860.4, 591.7, 860.4, 591.7, 865.4, 596.6,
+880.6, 617.1, 878.7, 618.8, 895.8, 637.6, 867.6, 630.8, 867.6, 630.5,
+839.3, 624.0, 837.6, 623.4, 836.7, 624.3, 835.7, 623.1, 831.7, 622.2,
+828.2, 620.5, 827.8, 621.3, 835.7, 605.4, 839.2, 607.1, 850.6, 593.0,
+853.0, 589.9, 853.9, 586.4, 855.5, 586.8, 575.2, 385.9, 565.8, 372.2,
+563.7, 373.2, 556.4, 358.5, 548.0, 343.3, 545.6, 329.2, 536.7, 329.8,
+536.4, 326.7, 536.4, 326.7, 536.1, 323.7, 544.7, 334.1, 543.4, 335.2,
+550.6, 346.8, 562.9, 366.3, 565.0, 365.3, 575.2, 385.9, 626.3, 445.3,
+630.7, 459.4, 630.7, 459.4, 635.2, 473.4, 613.2, 440.7, 612.9, 440.9,
+590.6, 408.4, 585.9, 399.5, 595.0, 392.5, 589.2, 386.5, 612.9, 411.0,
+610.1, 414.7, 626.3, 445.3, 589.2, 386.5, 586.2, 380.6, 588.8, 379.2,
+588.3, 372.0, 587.4, 357.9, 582.3, 356.2, 586.5, 343.8, 591.1, 346.9,
+591.1, 346.9, 595.7, 350.0, 597.0, 350.8, 596.5, 351.7, 597.3, 353.4,
+586.5, 392.3, 611.8, 399.4, 626.3, 445.3, 610.1, 414.7, 612.9, 411.0,
+589.2, 386.5, 718.6, 519.2, 720.3, 528.5, 720.3, 528.5, 722.0, 537.9,
+711.8, 549.5, 701.7, 552.1, 703.4, 562.7, 704.0, 563.8, 701.3, 565.4,
+699.3, 568.1, 699.0, 569.1, 696.3, 568.4, 693.3, 568.6, 692.5, 565.5,
+695.3, 564.7, 697.3, 560.8, 700.6, 554.3, 700.6, 554.3, 704.0, 547.8,
+711.3, 533.5, 707.0, 525.6, 718.6, 519.2, 910.3, 563.5, 905.1, 556.1,
+905.1, 556.1, 899.8, 548.7, 901.3, 525.5, 896.4, 525.1, 893.0, 501.6,
+910.5, 526.3, 905.8, 531.9, 910.3, 563.5, 842.9, 516.0, 837.8, 511.5,
+837.8, 511.5, 832.8, 507.0, 832.6, 485.1, 818.1, 481.9, 797.4, 463.4,
+790.1, 450.1, 787.6, 451.4, 777.8, 439.4, 810.7, 477.4, 811.2, 477.0,
+842.9, 516.0, 846.8, 490.9, 830.0, 465.8, 831.1, 465.0, 813.2, 440.7,
+801.8, 415.0, 801.8, 415.0, 790.5, 389.3, 819.3, 429.5, 814.6, 432.8,
+838.7, 476.3, 842.8, 483.6, 842.0, 484.2, 846.8, 490.9, 485.3, 126.2,
+497.4, 124.9, 499.2, 128.7, 509.6, 123.7, 513.3, 124.0, 516.4, 125.4,
+516.9, 124.3, 518.5, 126.3, 518.5, 126.3, 520.2, 128.3, 527.6, 149.4,
+530.3, 148.5, 540.5, 168.7, 511.7, 166.9, 504.0, 153.5, 485.3, 126.2,
+540.5, 168.7, 542.3, 172.2, 542.3, 172.2, 544.1, 175.8, 540.5, 172.5,
+533.0, 178.0, 523.9, 183.4, 497.6, 169.5, 501.3, 162.4, 478.7, 141.4,
+471.8, 134.9, 471.2, 135.4, 464.8, 128.5, 465.1, 128.8, 465.7, 128.2,
+466.5, 128.1, 474.5, 124.3, 475.9, 127.1, 485.3, 126.2, 504.0, 153.5,
+511.7, 166.9, 540.5, 168.7, 804.5, 87.9, 824.8, 103.2, 825.5, 102.3,
+846.3, 117.0, 857.7, 124.9, 857.5, 125.2, 868.7, 133.4, 863.2, 129.3,
+863.1, 129.5, 857.5, 125.5, 831.0, 106.7, 830.4, 107.5, 804.5, 87.9,
+936.1, 245.9, 931.1, 239.5, 929.4, 240.9, 922.7, 235.8, 918.0, 232.3,
+918.1, 232.3, 913.4, 228.8, 876.6, 201.0, 876.6, 201.0, 839.8, 173.3,
+834.8, 169.5, 834.0, 165.0, 829.8, 165.7, 840.9, 163.7, 841.7, 168.3,
+853.6, 170.8, 864.6, 173.1, 868.4, 168.9, 875.6, 175.5, 909.7, 206.5,
+907.6, 209.3, 936.1, 245.9, 686.0, 149.5, 684.1, 135.7, 669.1, 137.8,
+652.1, 126.1, 638.8, 117.0, 638.8, 117.0, 625.6, 107.8, 618.0, 102.6,
+613.6, 104.6, 610.4, 97.3, 615.1, 96.3, 615.1, 96.3, 619.9, 95.3,
+629.9, 99.9, 628.7, 102.5, 637.5, 109.8, 644.5, 115.4, 644.5, 115.4,
+651.4, 121.1, 668.7, 135.3, 683.8, 133.2, 686.0, 149.5, 576.5, 124.0,
+580.8, 126.0, 580.8, 126.0, 585.0, 128.1, 586.0, 128.6, 586.0, 128.7,
+587.0, 129.2, 581.8, 126.6, 581.7, 126.7, 576.5, 124.0, 795.1, 271.6,
+794.1, 271.2, 796.8, 263.4, 798.5, 255.3, 799.9, 248.5, 802.0, 241.9,
+801.3, 241.7, 836.2, 260.0, 836.2, 260.0, 871.1, 278.3, 867.9, 276.4,
+867.0, 277.9, 862.9, 277.6, 829.0, 274.6, 826.3, 282.4, 795.1, 271.6,
+820.2, 241.9, 825.3, 245.5, 825.3, 245.5, 830.4, 249.0, 818.0, 241.3,
+817.2, 242.5, 804.0, 236.0, 810.9, 240.7, 812.5, 238.1, 820.2, 241.9,
+707.8, 186.5, 709.9, 187.9, 709.2, 189.3, 711.3, 190.3, 676.6, 173.2,
+676.6, 173.2, 641.9, 156.2, 623.4, 152.8, 624.9, 144.6, 607.9, 133.0,
+634.7, 139.2, 633.0, 146.5, 658.2, 159.9, 674.4, 168.6, 674.4, 168.6,
+690.7, 177.3, 699.2, 181.9, 699.6, 181.4, 707.8, 186.5, 625.1, 297.5,
+631.6, 301.3, 631.6, 301.3, 638.2, 305.2, 641.4, 305.5, 640.7, 312.7,
+643.3, 320.2, 631.5, 313.3, 629.5, 310.4, 625.1, 297.5, 444.3, 210.5,
+441.2, 208.2, 439.3, 206.5, 439.9, 203.6, 441.9, 192.6, 444.6, 193.1,
+449.3, 182.6, 449.3, 182.6, 449.3, 182.6, 449.3, 182.6, 449.3, 182.6,
+449.3, 182.6, 449.3, 182.6, 462.4, 196.0, 462.4, 196.0, 475.5, 209.3,
+500.5, 245.8, 507.0, 241.3, 538.5, 273.3, 538.9, 273.7, 538.9, 273.8,
+539.3, 274.3, 540.5, 275.8, 540.5, 275.8, 541.6, 277.4, 492.6, 244.5,
+492.1, 245.1, 444.3, 210.5, 626.5, 73.3, 662.7, 57.4, 662.7, 57.4,
+698.9, 41.5, 692.2, 43.1, 696.0, 54.8, 688.7, 58.0, 659.8, 70.7,
+638.4, 53.9, 626.5, 73.3, 688.7, 58.0, 684.0, 56.9, 681.7, 71.7,
+672.7, 84.0, 671.9, 85.1, 670.9, 84.4, 669.1, 84.8, 646.1, 89.7,
+646.1, 94.6, 623.1, 94.6, 612.1, 88.8, 611.6, 89.7, 600.1, 84.9,
+613.5, 79.6, 613.3, 79.1, 626.5, 73.3, 638.4, 53.9, 659.8, 70.7,
+688.7, 58.0, 682.9, 81.8, 678.3, 83.9, 673.3, 81.8, 672.7, 84.0,
+681.7, 71.7, 684.0, 56.9, 688.7, 58.0, 696.0, 54.8, 692.2, 43.1,
+698.9, 41.5, 701.1, 40.5, 701.1, 40.5, 703.4, 39.5, 695.5, 59.7,
+693.9, 59.1, 684.5, 78.6, 683.7, 80.2, 684.2, 81.2, 682.9, 81.8,
+438.1, 128.0, 441.8, 124.7, 441.4, 124.4, 444.8, 120.8, 470.4, 92.8,
+470.4, 92.8, 496.1, 64.9, 506.3, 53.8, 506.3, 53.8, 516.5, 42.7,
+528.8, 29.4, 525.8, 22.1, 541.1, 16.0, 543.1, 23.6, 543.1, 23.6,
+545.1, 31.1, 545.2, 32.4, 543.6, 32.5, 542.1, 33.9, 490.1, 80.9,
+490.4, 81.3, 438.1, 128.0, 444.8, 120.8, 441.4, 124.4, 441.8, 124.7,
+438.1, 128.0, 436.1, 130.2, 436.4, 132.0, 434.0, 132.5, 424.1, 132.5,
+424.1, 132.5, 414.2, 132.6, 424.2, 121.8, 428.9, 123.9, 444.8, 120.8,
+428.3, 100.5, 430.0, 102.1, 417.9, 114.9, 407.5, 129.4, 406.3, 131.1,
+406.3, 131.1, 405.1, 132.7, 401.3, 134.8, 401.5, 136.3, 399.5, 140.5,
+395.8, 140.0, 395.9, 136.0, 393.4, 131.0, 388.3, 125.4, 390.3, 123.5,
+387.3, 116.0, 385.9, 112.6, 386.4, 112.4, 385.5, 108.7, 405.6, 101.1,
+419.0, 91.7, 428.3, 100.5, 376.6, -4.2, 369.3, -14.8, 371.9, -18.7,
+362.0, -25.4, 362.3, -25.5, 362.3, -25.5, 362.6, -25.6, 369.8, -25.0,
+371.8, -27.7, 376.9, -24.1, 413.9, 15.4, 419.5, 10.2, 462.0, 44.4,
+443.6, 22.3, 435.3, 29.2, 408.7, 14.0, 392.6, 4.9, 390.5, 7.5,
+376.6, -4.2, 354.9, 111.6, 352.6, 104.8, 354.4, 104.1, 353.9, 96.6,
+353.5, 89.0, 353.5, 89.0, 353.0, 81.4, 352.5, 73.8, 356.0, 70.2,
+352.0, 66.3, 363.7, 84.6, 379.1, 99.0, 375.4, 102.9, 382.3, 117.9,
+382.3, 118.8, 393.4, 131.0, 395.9, 136.0, 395.8, 140.0, 399.5, 140.5,
+399.3, 141.0, 400.0, 142.2, 400.6, 142.2, 400.6, 148.2, 404.3, 148.1,
+408.1, 154.0, 408.2, 154.1, 408.0, 154.2, 407.9, 154.3, 404.6, 151.9,
+404.7, 151.7, 401.4, 149.1, 381.1, 132.7, 381.1, 132.7, 360.7, 116.3,
+357.8, 114.0, 355.9, 114.6, 354.9, 111.6, 354.1, 229.1, 355.0, 230.2,
+349.9, 234.6, 345.7, 240.1, 343.2, 243.5, 340.1, 246.3, 340.6, 246.9,
+334.1, 239.5, 330.2, 231.4, 333.8, 226.6, 336.9, 222.5, 349.0, 223.4,
+354.1, 229.1, 180.4, 458.9, 165.2, 479.0, 164.5, 478.5, 150.0, 499.1,
+148.8, 490.4, 148.8, 490.4, 147.6, 481.7, 151.1, 474.2, 155.4, 476.2,
+163.2, 470.8, 171.8, 464.8, 176.5, 467.1, 180.4, 458.9, 215.6, 319.8,
+227.5, 313.4, 240.1, 309.9, 239.3, 307.0, 239.9, 307.2, 240.2, 306.5,
+241.0, 306.0, 240.7, 308.1, 240.5, 309.0, 238.9, 309.9, 227.8, 315.9,
+216.7, 313.2, 215.6, 319.8, 222.2, 171.0, 230.1, 155.8, 230.1, 155.8,
+238.0, 140.7, 236.5, 144.5, 236.9, 144.6, 235.8, 148.5, 229.8, 160.1,
+225.6, 158.8, 222.2, 171.0, 176.4, 362.5, 165.4, 402.3, 165.4, 402.3,
+154.3, 442.2, 154.2, 419.4, 152.3, 419.4, 150.3, 396.7, 150.3, 396.6,
+150.3, 396.6, 150.4, 396.6, 163.4, 379.5, 177.8, 378.3, 176.4, 362.5,
+138.4, 232.7, 138.6, 227.7, 141.1, 225.7, 138.8, 222.8, 153.2, 201.8,
+147.7, 192.0, 167.7, 180.7, 169.5, 178.8, 169.6, 178.8, 170.7, 176.4,
+170.6, 175.3, 172.0, 175.3, 172.4, 174.0, 183.0, 160.3, 182.2, 159.7,
+192.0, 145.4, 212.5, 119.2, 212.1, 118.9, 232.3, 92.4, 204.5, 142.4,
+200.4, 140.1, 168.4, 187.8, 153.4, 210.2, 155.7, 212.2, 138.4, 232.7,
+470.8, 711.5, 474.2, 737.2, 474.2, 737.2, 477.6, 762.9, 477.9, 765.2,
+477.9, 765.3, 478.2, 767.6, 474.5, 739.6, 474.2, 739.6, 470.8, 711.5,
+498.0, 805.1, 500.3, 782.9, 501.2, 783.0, 504.3, 760.8, 504.4, 760.3,
+504.4, 760.3, 504.4, 759.9, 513.1, 698.6, 512.1, 698.4, 521.8, 637.3,
+523.2, 628.6, 524.2, 628.7, 526.6, 620.2, 535.0, 590.1, 535.0, 590.1,
+543.4, 560.1, 544.6, 555.9, 545.0, 555.9, 545.8, 551.6, 524.2, 668.1,
+523.8, 668.0, 501.9, 784.4, 500.0, 794.8, 499.1, 794.7, 498.0, 805.1,
+504.3, 760.8, 501.2, 783.0, 500.3, 782.9, 498.0, 805.1, 495.0, 826.5,
+495.9, 826.7, 491.9, 847.9, 492.0, 845.8, 491.4, 845.8, 490.8, 843.6,
+496.7, 802.1, 496.6, 802.0, 504.3, 760.8, 580.1, 422.7, 580.7, 423.6,
+580.7, 423.6, 581.3, 424.5, 581.4, 425.1, 580.6, 425.6, 580.8, 426.0,
+580.0, 424.7, 579.7, 424.1, 580.1, 422.7, 448.7, 409.5, 446.9, 389.4,
+446.9, 389.4, 445.0, 369.4, 445.1, 370.9, 445.7, 370.9, 446.4, 372.4,
+447.4, 374.6, 447.4, 374.6, 448.4, 376.8, 449.8, 380.1, 449.8, 380.1,
+451.3, 383.3, 452.7, 386.4, 452.7, 386.4, 454.1, 389.4, 463.1, 419.2,
+467.1, 418.0, 480.0, 446.7, 483.6, 433.2, 458.4, 430.8, 448.7, 409.5,
+480.0, 446.7, 480.5, 447.8, 480.5, 447.8, 481.0, 448.9, 468.8, 470.9,
+471.1, 472.2, 461.7, 495.7, 460.2, 498.5, 460.2, 498.5, 458.7, 501.2,
+457.9, 492.8, 452.4, 490.2, 455.6, 484.5, 452.1, 447.0, 452.1, 447.0,
+448.7, 409.5, 458.4, 430.8, 483.6, 433.2, 480.0, 446.7, 192.8, 698.4,
+199.2, 685.0, 199.2, 685.0, 205.6, 671.5, 205.7, 680.0, 212.5, 682.3,
+209.6, 688.4, 210.1, 726.6, 221.5, 730.2, 210.6, 764.9, 210.6, 767.8,
+209.7, 770.5, 210.2, 770.6, 208.8, 765.3, 204.7, 766.3, 199.2, 762.1,
+191.8, 731.2, 190.6, 729.9, 192.8, 698.4, 199.2, 762.1, 191.9, 756.3,
+192.1, 756.1, 184.6, 750.6, 182.7, 737.0, 182.7, 737.0, 180.9, 723.4,
+188.3, 722.5, 186.8, 710.9, 192.8, 698.4, 190.6, 729.9, 191.8, 731.2,
+199.2, 762.1, 236.2, 411.3, 233.8, 419.9, 235.6, 420.4, 234.9, 429.5,
+234.5, 434.5, 234.5, 434.5, 234.2, 439.5, 233.2, 453.4, 233.2, 453.4,
+232.2, 467.3, 231.7, 473.0, 231.7, 473.0, 231.3, 478.7, 229.9, 497.9,
+231.2, 498.1, 228.5, 517.2, 227.6, 517.0, 225.0, 523.0, 224.3, 529.2,
+235.1, 554.2, 204.3, 563.1, 199.8, 598.9, 204.3, 603.4, 194.9, 612.9,
+189.9, 626.9, 193.1, 620.6, 191.5, 619.8, 193.0, 612.6, 197.7, 591.0,
+197.7, 591.0, 202.3, 569.3, 204.0, 561.3, 204.0, 561.3, 205.8, 553.2,
+209.1, 537.8, 209.1, 537.8, 212.4, 522.3, 218.1, 495.7, 218.1, 495.7,
+223.8, 469.2, 230.0, 440.3, 228.3, 439.8, 236.2, 411.3, 348.6, 878.3,
+346.2, 840.7, 363.8, 822.4, 343.8, 803.1, 345.5, 776.0, 350.3, 776.3,
+356.8, 749.4, 361.1, 731.7, 358.3, 730.5, 365.4, 714.0, 361.6, 722.8,
+364.4, 724.0, 363.4, 734.1, 362.4, 743.8, 362.4, 743.8, 361.4, 753.6,
+360.9, 758.8, 360.9, 758.8, 360.3, 764.1, 360.0, 767.1, 360.0, 767.1,
+359.7, 770.2, 359.2, 775.3, 359.1, 775.3, 358.6, 780.4, 354.5, 820.5,
+354.5, 820.5, 350.4, 860.7, 349.5, 869.5, 347.6, 869.7, 348.6, 878.3,
+424.8, 241.2, 429.7, 281.8, 429.7, 281.8, 434.6, 322.4, 432.1, 313.3,
+429.0, 314.1, 423.4, 305.9, 419.6, 275.8, 424.1, 275.2, 424.7, 244.6,
+424.8, 242.9, 425.0, 242.8, 424.8, 241.2, 278.9, 391.8, 258.1, 432.7,
+256.9, 432.0, 234.8, 472.2, 233.1, 475.5, 230.4, 476.9, 231.3, 478.7,
+231.7, 473.0, 231.7, 473.0, 232.2, 467.3, 244.9, 442.6, 246.9, 443.6,
+261.6, 419.8, 270.2, 405.8, 271.4, 406.4, 278.9, 391.8, 142.6, 812.3,
+142.0, 745.0, 143.1, 745.0, 143.6, 677.7, 143.8, 660.2, 144.9, 660.2,
+143.9, 642.7, 143.9, 642.7, 143.9, 642.7, 143.9, 642.6, 144.5, 656.6,
+149.1, 656.4, 154.3, 670.2, 155.2, 672.8, 155.2, 673.1, 155.0, 675.9,
+150.4, 732.9, 149.8, 732.8, 144.7, 789.8, 143.7, 801.1, 142.5, 801.1,
+142.6, 812.3, 166.1, 703.6, 176.1, 732.7, 175.0, 733.1, 186.1, 761.7,
+187.3, 770.3, 187.3, 770.3, 188.5, 778.9, 183.8, 801.5, 180.9, 800.9,
+173.4, 823.0, 173.4, 823.1, 173.5, 823.2, 173.5, 823.2, 173.5, 823.2,
+173.4, 823.1, 173.4, 823.0, 171.5, 807.5, 171.5, 807.5, 169.5, 791.9,
+165.2, 757.5, 162.3, 757.6, 160.9, 723.1, 160.5, 713.5, 169.8, 709.3,
+166.1, 703.6, 160.9, 723.1, 152.3, 701.7, 157.9, 699.5, 155.0, 675.9,
+155.2, 673.1, 155.2, 672.8, 154.3, 670.2, 156.0, 674.9, 156.0, 674.9,
+157.8, 679.7, 162.5, 691.5, 162.0, 691.7, 166.1, 703.6, 169.8, 709.3,
+160.5, 713.5, 160.9, 723.1, 90.3, 188.5, 91.4, 191.9, 92.7, 191.9,
+92.6, 195.2, 97.0, 229.5, 104.1, 228.6, 115.5, 261.9, 120.9, 312.4,
+121.9, 312.3, 128.3, 362.6, 127.0, 342.9, 124.1, 343.2, 119.8, 323.7,
+119.2, 321.0, 119.2, 321.0, 118.7, 318.3, 114.6, 299.8, 114.6, 299.8,
+110.6, 281.3, 100.4, 234.9, 100.0, 235.0, 90.3, 188.5, 55.9, 88.2,
+58.2, 95.1, 58.2, 95.1, 60.6, 101.9, 51.6, 122.9, 61.3, 127.0,
+62.1, 152.1, 51.9, 122.6, 56.8, 120.2, 55.9, 88.2, 128.4, 435.2,
+112.5, 419.8, 115.6, 412.2, 96.5, 404.4, 88.8, 396.0, 89.7, 395.1,
+82.9, 385.9, 82.7, 385.3, 82.6, 385.4, 82.2, 384.9, 88.2, 391.3,
+88.1, 391.4, 94.0, 397.8, 111.2, 416.5, 120.2, 413.2, 128.4, 435.2,
+59.1, 353.3, 49.3, 339.9, 51.9, 336.6, 39.5, 326.5, 39.3, 325.6,
+39.4, 325.6, 39.1, 324.7, 38.9, 324.0, 39.0, 324.0, 38.9, 323.2,
+51.2, 297.2, 65.4, 294.0, 61.2, 270.1, 62.8, 266.8, 62.8, 266.8,
+64.4, 263.4, 63.2, 308.4, 74.8, 313.5, 59.1, 353.3, 64.4, 263.4,
+65.7, 260.7, 67.4, 260.4, 67.0, 257.9, 72.4, 272.6, 72.4, 272.6,
+77.7, 287.3, 83.2, 291.6, 76.6, 299.7, 76.0, 312.1, 76.0, 314.7,
+75.8, 314.6, 75.7, 317.2, 82.3, 326.3, 62.3, 336.1, 60.9, 355.8,
+60.0, 354.6, 60.0, 354.6, 59.1, 353.3, 74.8, 313.5, 63.2, 308.4,
+64.4, 263.4, 94.6, 422.5, 88.8, 404.2, 88.9, 404.1, 82.9, 385.9,
+89.7, 395.1, 88.8, 396.0, 96.5, 404.4, 108.9, 409.5, 105.8, 417.1,
+115.1, 429.8, 117.5, 432.9, 117.2, 433.1, 119.3, 436.5, 106.1, 431.9,
+102.1, 433.0, 94.6, 422.5, 119.3, 436.5, 130.4, 454.3, 130.0, 454.6,
+141.5, 472.1, 135.1, 490.1, 135.1, 490.1, 128.8, 508.0, 128.5, 505.7,
+125.4, 503.4, 124.8, 503.8, 124.8, 503.8, 124.6, 503.6, 124.4, 503.4,
+117.4, 500.8, 119.6, 494.7, 114.9, 486.1, 119.4, 483.8, 104.7, 454.3,
+94.6, 422.5, 102.1, 433.0, 106.1, 431.9, 119.3, 436.5, 93.3, 695.5,
+93.8, 702.6, 91.2, 708.1, 94.4, 709.6, 89.1, 714.5, 89.1, 714.5,
+83.8, 719.4, 83.9, 719.1, 79.8, 717.4, 75.8, 715.5, 68.6, 706.3,
+67.0, 706.5, 56.3, 701.2, 56.1, 701.0, 56.1, 701.0, 55.9, 700.7,
+61.0, 692.4, 52.8, 687.4, 49.7, 674.1, 69.7, 671.4, 74.7, 680.8,
+93.3, 695.5, 49.7, 674.1, 49.3, 672.3, 49.3, 672.3, 48.9, 670.5,
+58.1, 672.3, 70.0, 661.3, 72.2, 648.9, 80.8, 650.5, 80.8, 650.5,
+89.4, 652.2, 90.7, 668.6, 87.9, 684.0, 92.5, 684.9, 92.9, 690.2,
+92.9, 690.2, 93.3, 695.5, 74.7, 680.8, 69.7, 671.4, 49.7, 674.1,
+855.7, 644.3, 864.1, 655.0, 862.1, 657.6, 872.6, 665.6, 867.3, 669.8,
+867.3, 669.8, 861.9, 674.1, 855.1, 664.1, 839.5, 674.7, 817.1, 675.3,
+814.8, 664.3, 834.4, 648.1, 855.7, 644.3, 850.6, 593.0, 839.2, 607.1,
+835.7, 605.4, 827.8, 621.3, 824.4, 623.7, 821.5, 619.7, 815.2, 618.2,
+805.9, 616.0, 805.7, 616.5, 796.5, 613.7, 796.7, 613.2, 796.7, 613.2,
+796.8, 612.7, 806.7, 608.6, 806.9, 609.0, 817.0, 605.3, 833.8, 599.1,
+848.1, 589.4, 850.6, 593.0, 550.6, 346.8, 543.4, 335.2, 544.7, 334.1,
+536.1, 323.7, 535.4, 316.0, 538.8, 312.6, 534.6, 308.4, 560.5, 326.1,
+560.5, 326.1, 586.5, 343.8, 582.3, 356.2, 587.4, 357.9, 588.3, 372.0,
+570.6, 373.5, 567.0, 362.0, 550.6, 346.8, 588.3, 372.0, 588.8, 379.2,
+586.2, 380.6, 589.2, 386.5, 595.0, 392.5, 585.9, 399.5, 590.6, 408.4,
+582.9, 397.1, 582.9, 397.1, 575.2, 385.9, 565.0, 365.3, 562.9, 366.3,
+550.6, 346.8, 567.0, 362.0, 570.6, 373.5, 588.3, 372.0, 706.7, 478.9,
+709.8, 483.0, 713.1, 483.1, 713.0, 487.0, 713.1, 488.1, 712.7, 488.6,
+713.3, 489.1, 713.6, 489.3, 713.2, 490.0, 713.5, 490.2, 710.9, 503.7,
+716.1, 504.7, 718.6, 519.2, 707.0, 525.6, 711.3, 533.5, 704.0, 547.8,
+694.7, 516.5, 701.7, 512.8, 706.7, 478.9, 922.2, 514.6, 918.6, 541.0,
+913.8, 541.2, 915.0, 567.3, 913.1, 566.1, 913.1, 566.1, 911.3, 564.9,
+910.8, 564.5, 910.9, 564.3, 910.5, 563.7, 912.9, 551.4, 913.4, 551.5,
+916.3, 539.2, 916.9, 536.7, 916.9, 536.7, 917.5, 534.2, 919.9, 524.4,
+921.4, 524.5, 922.2, 514.6, 868.0, 523.0, 871.7, 528.3, 871.8, 528.1,
+875.4, 533.5, 880.0, 540.1, 880.9, 539.6, 884.7, 546.7, 882.9, 545.5,
+882.5, 544.0, 881.1, 544.3, 881.2, 544.2, 876.3, 539.0, 874.5, 539.8,
+875.5, 535.3, 864.1, 532.8, 853.8, 525.7, 847.5, 522.2, 848.3, 520.8,
+842.9, 516.0, 811.2, 477.0, 810.7, 477.4, 777.8, 439.4, 764.3, 422.8,
+764.3, 422.8, 750.9, 406.3, 794.4, 444.7, 792.0, 447.3, 833.2, 488.3,
+850.6, 505.7, 851.2, 505.1, 868.0, 523.0, 800.2, 369.8, 812.1, 386.9,
+808.4, 391.3, 823.9, 404.0, 850.1, 450.0, 852.8, 448.7, 884.2, 491.5,
+887.5, 513.7, 885.0, 514.4, 890.9, 536.0, 891.2, 536.4, 890.9, 536.6,
+891.0, 537.3, 856.2, 473.4, 856.3, 473.3, 821.7, 409.3, 810.9, 389.5,
+794.8, 382.7, 800.2, 369.8, 906.3, 160.9, 920.0, 170.9, 919.3, 171.9,
+933.6, 180.8, 935.5, 182.7, 933.6, 187.9, 934.2, 187.9, 907.8, 185.9,
+908.1, 182.4, 882.0, 176.8, 878.8, 176.1, 878.8, 176.1, 875.6, 175.5,
+868.4, 168.9, 864.6, 173.1, 853.6, 170.8, 877.1, 159.7, 881.0, 157.7,
+906.3, 160.9, 938.0, 227.0, 943.7, 234.1, 941.1, 238.1, 940.0, 248.8,
+940.2, 247.6, 937.7, 247.7, 936.1, 245.9, 907.6, 209.3, 909.7, 206.5,
+875.6, 175.5, 878.8, 176.1, 878.8, 176.1, 882.0, 176.8, 910.9, 200.7,
+914.7, 198.1, 938.0, 227.0, 882.0, 176.8, 908.1, 182.4, 907.8, 185.9,
+934.2, 187.9, 945.0, 197.5, 932.2, 225.8, 938.0, 227.0, 914.7, 198.1,
+910.9, 200.7, 882.0, 176.8, 913.4, 228.8, 924.8, 237.3, 924.8, 237.3,
+936.1, 245.9, 937.7, 247.7, 940.2, 247.6, 940.0, 248.8, 940.1, 248.9,
+940.0, 249.0, 940.1, 249.1, 934.5, 244.9, 934.5, 244.9, 929.0, 240.6,
+925.8, 238.2, 925.8, 238.2, 922.7, 235.8, 918.0, 232.3, 918.1, 232.3,
+913.4, 228.8, 681.9, 99.4, 674.2, 94.0, 674.0, 93.0, 669.1, 84.8,
+670.9, 84.4, 671.9, 85.1, 672.7, 84.0, 673.3, 81.8, 678.3, 83.9,
+682.9, 81.8, 696.7, 78.9, 697.8, 73.4, 710.6, 75.9, 721.9, 78.2,
+720.8, 83.6, 731.1, 91.4, 735.2, 94.5, 735.9, 98.2, 739.3, 97.6,
+715.3, 102.1, 714.6, 98.4, 689.9, 99.1, 685.9, 99.3, 684.6, 101.2,
+681.9, 99.4, 767.4, 197.3, 774.3, 201.8, 772.5, 209.7, 778.7, 210.2,
+766.2, 203.2, 766.9, 201.7, 753.8, 196.2, 720.3, 174.2, 722.5, 153.6,
+687.8, 150.7, 729.3, 154.2, 728.8, 172.1, 767.4, 197.3, 862.9, 277.6,
+867.0, 277.9, 867.9, 276.4, 871.1, 278.3, 874.9, 280.3, 875.3, 279.8,
+878.8, 282.3, 883.0, 285.2, 883.2, 288.4, 887.3, 288.2, 887.1, 288.3,
+886.8, 288.3, 886.8, 288.4, 870.8, 290.2, 867.9, 292.0, 856.1, 303.1,
+856.0, 302.9, 853.8, 304.2, 851.6, 305.3, 816.2, 322.3, 817.1, 324.5,
+780.8, 339.3, 782.3, 338.7, 780.3, 335.4, 782.0, 333.8, 789.5, 326.7,
+790.6, 327.8, 799.3, 321.8, 802.4, 319.6, 802.4, 319.6, 805.6, 317.4,
+834.2, 297.5, 833.0, 295.4, 862.9, 277.6, 657.9, 132.4, 654.5, 130.0,
+655.6, 128.2, 652.1, 126.1, 669.1, 137.8, 684.1, 135.7, 686.0, 149.5,
+686.9, 150.1, 686.9, 150.1, 687.8, 150.7, 720.3, 173.2, 720.2, 173.3,
+752.8, 195.8, 753.2, 196.1, 753.4, 195.9, 753.8, 196.2, 761.2, 199.3,
+760.5, 200.8, 767.2, 205.4, 764.9, 203.8, 764.9, 203.9, 762.5, 202.3,
+757.6, 199.0, 757.6, 199.0, 752.8, 195.8, 705.4, 164.1, 704.8, 164.9,
+657.9, 132.4, 625.6, 107.8, 638.8, 117.0, 638.8, 117.0, 652.1, 126.1,
+655.6, 128.2, 654.5, 130.0, 657.9, 132.4, 661.1, 135.9, 661.1, 135.9,
+664.3, 139.4, 666.3, 141.5, 666.0, 142.0, 668.3, 143.7, 662.0, 139.2,
+662.4, 138.7, 656.5, 133.7, 646.2, 125.1, 646.2, 125.1, 635.9, 116.5,
+630.8, 112.2, 631.3, 111.2, 625.6, 107.8, 529.6, 223.2, 534.4, 238.6,
+552.7, 230.3, 570.7, 244.0, 580.3, 256.7, 577.6, 260.4, 589.9, 269.3,
+583.2, 266.0, 583.2, 266.0, 576.5, 262.7, 552.2, 244.1, 537.3, 247.9,
+529.6, 223.2, 576.5, 262.7, 542.1, 245.5, 542.5, 244.8, 507.7, 228.3,
+491.6, 218.8, 485.1, 223.3, 475.5, 209.3, 462.4, 196.0, 462.4, 196.0,
+449.3, 182.6, 451.0, 184.5, 451.8, 183.9, 454.2, 185.1, 491.9, 204.2,
+494.1, 200.7, 529.6, 223.2, 537.3, 247.9, 552.2, 244.1, 576.5, 262.7,
+454.2, 185.1, 451.8, 183.9, 451.0, 184.5, 449.3, 182.6, 449.3, 182.6,
+449.3, 182.6, 449.3, 182.6, 436.6, 157.6, 430.6, 159.3, 408.0, 140.6,
+408.6, 140.5, 408.6, 140.5, 409.3, 140.3, 415.1, 145.5, 414.8, 145.9,
+420.4, 151.4, 434.4, 165.4, 434.4, 165.4, 448.4, 179.4, 451.3, 182.2,
+453.2, 181.7, 454.2, 185.1, 613.8, 318.3, 609.5, 309.1, 605.8, 299.8,
+605.3, 300.0, 605.1, 297.0, 605.1, 297.0, 604.9, 294.0, 605.3, 294.2,
+609.6, 291.0, 609.4, 288.2, 617.2, 292.8, 617.2, 292.8, 625.1, 297.5,
+629.5, 310.4, 631.5, 313.3, 643.3, 320.2, 644.4, 323.5, 643.2, 325.5,
+645.5, 326.8, 647.2, 327.6, 645.5, 330.3, 647.2, 331.9, 654.4, 331.7,
+655.2, 355.4, 663.1, 378.8, 631.4, 365.8, 636.9, 349.7, 613.8, 318.3,
+663.1, 378.8, 665.6, 386.2, 665.9, 393.6, 668.1, 393.5, 665.6, 394.7,
+663.0, 395.4, 663.1, 395.9, 657.0, 391.8, 657.0, 391.8, 650.9, 387.6,
+645.7, 384.7, 646.5, 383.2, 642.2, 378.7, 633.7, 347.0, 628.0, 348.5,
+613.8, 318.3, 636.9, 349.7, 631.4, 365.8, 663.1, 378.8, 499.3, 283.8,
+494.8, 281.0, 494.6, 281.3, 490.3, 278.3, 488.5, 277.1, 488.5, 277.1,
+486.8, 275.9, 493.1, 279.8, 493.2, 279.7, 499.3, 283.8, 745.7, 58.1,
+738.0, 64.9, 735.2, 63.3, 730.2, 71.7, 721.6, 76.1, 720.4, 73.8,
+710.6, 75.9, 697.8, 73.4, 696.7, 78.9, 682.9, 81.8, 684.2, 81.2,
+683.7, 80.2, 684.5, 78.6, 714.6, 67.2, 714.3, 62.8, 745.7, 58.1,
+684.5, 78.6, 693.9, 59.1, 695.5, 59.7, 703.4, 39.5, 715.2, 34.3,
+715.7, 35.3, 727.1, 29.1, 740.2, 32.1, 738.4, 39.7, 750.0, 50.0,
+751.2, 51.1, 752.8, 51.7, 752.7, 51.9, 750.0, 51.3, 749.2, 55.0,
+745.7, 58.1, 714.3, 62.8, 714.6, 67.2, 684.5, 78.6, 542.1, 33.9,
+543.6, 32.5, 545.2, 32.4, 545.1, 31.1, 553.1, 61.2, 553.1, 61.2,
+561.1, 91.2, 561.8, 66.9, 553.0, 66.6, 544.8, 42.1, 543.5, 38.0,
+542.0, 37.9, 542.1, 33.9, 407.5, 129.4, 417.9, 114.9, 430.0, 102.1,
+428.3, 100.5, 434.4, 92.1, 434.4, 92.1, 440.4, 83.6, 447.0, 74.6,
+447.0, 74.6, 453.5, 65.5, 459.8, 56.7, 459.8, 56.7, 466.1, 47.9,
+487.4, 18.9, 487.9, 19.2, 508.1, -10.5, 509.0, -11.6, 509.0, -11.6,
+509.8, -12.8, 518.4, -24.7, 515.8, -28.1, 527.0, -36.7, 527.2, -32.2,
+528.2, -32.2, 529.4, -27.8, 519.7, -10.1, 516.9, -11.6, 504.3, 4.5,
+492.4, 20.0, 492.4, 20.0, 480.4, 35.4, 462.3, 58.7, 462.3, 58.7,
+444.3, 82.0, 425.9, 105.7, 427.1, 106.7, 407.5, 129.4, 638.1, -51.9,
+648.3, -56.7, 681.7, -32.3, 682.2, -11.8, 659.3, 3.5, 661.0, 6.1,
+639.9, 23.9, 642.7, 22.6, 639.7, 16.2, 639.5, 8.4, 638.8, -21.7,
+627.0, -46.6, 638.1, -51.9, 590.4, 20.7, 590.0, 21.0, 591.9, 23.2,
+593.4, 25.8, 600.9, 38.2, 611.7, 42.7, 608.4, 50.5, 588.8, 67.1,
+588.0, 66.3, 569.1, 83.6, 568.2, 78.7, 569.0, 78.4, 567.3, 73.7,
+562.9, 63.6, 565.2, 62.6, 563.1, 51.4, 570.9, 33.5, 574.9, 33.8,
+590.4, 20.7, 563.1, 51.4, 560.4, 36.7, 560.4, 36.7, 557.7, 22.0,
+558.4, 22.2, 563.3, 3.6, 568.9, -14.7, 567.4, -13.1, 573.7, -6.8,
+578.5, 1.0, 583.6, 9.6, 583.6, 9.6, 588.8, 18.1, 589.6, 19.4,
+590.7, 20.3, 590.4, 20.7, 574.9, 33.8, 570.9, 33.5, 563.1, 51.4,
+381.2, 91.7, 379.0, 83.0, 379.0, 83.0, 376.8, 74.3, 398.1, 75.3,
+406.4, 74.7, 420.2, 60.1, 422.4, 62.5, 422.7, 62.3, 424.5, 65.0,
+424.7, 65.3, 424.7, 65.3, 424.9, 65.5, 429.1, 70.4, 432.4, 75.9,
+433.3, 75.3, 410.5, 89.0, 407.1, 92.2, 381.2, 91.7, 433.3, 75.3,
+436.2, 74.9, 441.1, 80.3, 440.4, 83.6, 434.4, 92.1, 434.4, 92.1,
+428.3, 100.5, 419.0, 91.7, 405.6, 101.1, 385.5, 108.7, 383.3, 100.2,
+383.3, 100.2, 381.2, 91.7, 407.1, 92.2, 410.5, 89.0, 433.3, 75.3,
+389.3, 14.2, 383.0, 5.0, 383.0, 5.0, 376.6, -4.2, 390.5, 7.5,
+392.6, 4.9, 408.7, 14.0, 405.6, 9.6, 396.6, 18.3, 389.3, 14.2,
+436.9, -32.1, 422.6, -36.7, 419.5, -26.5, 402.0, -21.5, 401.0, -21.6,
+400.6, -21.2, 400.1, -21.7, 390.0, -26.2, 383.0, -17.7, 376.9, -24.1,
+371.8, -27.7, 369.8, -25.0, 362.6, -25.6, 370.0, -27.5, 370.0, -27.5,
+377.4, -29.4, 407.0, -32.0, 410.3, -40.7, 436.9, -32.1, 377.4, -29.4,
+388.0, -32.1, 387.8, -33.8, 398.6, -34.9, 399.3, -35.1, 399.3, -34.9,
+400.0, -35.1, 407.0, -36.9, 407.0, -37.0, 414.0, -38.8, 441.9, -46.0,
+441.9, -45.9, 469.8, -53.0, 471.6, -53.4, 471.6, -53.4, 473.5, -53.9,
+508.4, -62.5, 508.4, -62.5, 543.4, -71.1, 543.5, -71.2, 546.8, -66.8,
+549.1, -67.4, 548.5, -66.6, 548.5, -66.6, 548.0, -65.9, 523.9, -58.0,
+523.8, -58.5, 499.5, -51.2, 493.8, -49.4, 493.8, -49.4, 488.0, -47.7,
+474.0, -43.4, 474.0, -43.4, 460.0, -39.1, 448.4, -35.6, 448.7, -33.5,
+436.9, -32.1, 410.3, -40.7, 407.0, -32.0, 377.4, -29.4, 413.6, -20.3,
+407.8, -20.9, 407.8, -20.9, 402.0, -21.5, 419.5, -26.5, 422.6, -36.7,
+436.9, -32.1, 448.7, -33.5, 448.4, -35.6, 460.0, -39.1, 437.7, -27.9,
+437.4, -27.6, 413.6, -20.3, 262.6, 59.6, 266.1, 47.2, 266.1, 47.2,
+269.6, 34.9, 275.0, 35.4, 273.9, 47.9, 278.3, 61.0, 280.9, 68.7,
+282.6, 68.5, 283.5, 76.5, 283.3, 74.8, 281.6, 75.0, 279.7, 73.4,
+278.0, 72.0, 278.0, 72.0, 276.3, 70.7, 269.4, 65.1, 263.8, 66.2,
+262.6, 59.6, 258.3, 282.1, 242.0, 274.1, 239.8, 263.1, 225.8, 266.0,
+226.1, 264.6, 220.4, 263.4, 215.0, 260.7, 215.6, 260.1, 215.2, 259.7,
+215.5, 258.6, 231.4, 266.1, 230.9, 267.1, 246.4, 275.6, 252.4, 278.8,
+252.2, 279.3, 258.3, 282.1, 328.2, 263.3, 327.4, 271.4, 317.3, 278.9,
+316.7, 278.6, 304.2, 270.5, 309.3, 262.4, 302.0, 246.3, 292.6, 225.6,
+289.8, 226.5, 283.1, 204.9, 281.7, 200.4, 287.8, 196.8, 285.8, 194.3,
+306.2, 219.1, 302.8, 221.9, 319.8, 249.5, 324.0, 256.4, 328.9, 256.9,
+328.2, 263.3, 302.0, 246.3, 309.3, 262.4, 304.2, 270.5, 316.7, 278.6,
+317.4, 281.6, 313.8, 282.4, 310.9, 286.3, 304.9, 294.2, 305.5, 301.5,
+298.9, 302.1, 287.0, 303.2, 286.3, 295.9, 273.8, 289.7, 273.2, 289.5,
+272.7, 289.1, 272.7, 289.2, 286.8, 267.4, 283.3, 250.8, 302.0, 246.3,
+272.7, 289.2, 272.7, 289.2, 272.6, 289.1, 272.4, 289.1, 272.4, 286.8,
+267.9, 286.8, 263.4, 284.6, 262.5, 271.2, 266.8, 270.9, 270.2, 257.1,
+276.7, 231.0, 269.4, 209.6, 283.1, 204.9, 289.8, 226.5, 292.6, 225.6,
+302.0, 246.3, 283.3, 250.8, 286.8, 267.4, 272.7, 289.2, 355.1, 114.2,
+354.4, 113.6, 355.4, 111.8, 354.9, 111.6, 355.9, 114.6, 357.8, 114.0,
+360.7, 116.3, 360.6, 115.1, 357.3, 116.0, 355.1, 114.2, 290.3, 313.5,
+264.4, 347.9, 264.3, 347.9, 238.3, 382.2, 230.2, 388.0, 231.9, 390.5,
+225.7, 398.9, 200.5, 426.6, 203.0, 428.9, 180.4, 458.9, 176.5, 467.1,
+171.8, 464.8, 163.2, 470.8, 180.2, 443.2, 183.7, 445.4, 204.3, 420.0,
+243.4, 371.5, 243.4, 371.5, 282.5, 323.1, 284.3, 320.9, 284.3, 320.9,
+286.0, 318.8, 288.1, 316.1, 288.2, 316.2, 290.3, 313.5, 176.4, 420.6,
+168.2, 442.5, 164.8, 441.2, 153.1, 461.8, 153.0, 462.3, 152.8, 462.2,
+152.7, 462.6, 167.5, 420.8, 166.8, 420.5, 182.4, 379.0, 181.0, 382.6,
+181.8, 382.9, 181.3, 386.7, 178.8, 403.7, 182.3, 404.9, 176.4, 420.6,
+177.5, 256.5, 178.6, 254.5, 179.3, 254.6, 179.6, 252.5, 203.3, 213.2,
+200.9, 211.7, 222.2, 171.0, 225.6, 158.8, 229.8, 160.1, 235.8, 148.5,
+235.5, 149.5, 235.5, 149.5, 235.3, 150.5, 230.0, 160.7, 229.8, 160.6,
+224.3, 170.6, 214.9, 187.9, 214.9, 187.9, 205.5, 205.2, 192.6, 228.8,
+192.5, 228.8, 179.6, 252.5, 179.3, 254.6, 178.6, 254.5, 177.5, 256.5,
+146.0, 348.1, 145.8, 345.7, 145.5, 345.7, 145.6, 343.2, 146.0, 329.6,
+141.9, 317.5, 146.4, 316.0, 151.6, 306.0, 151.6, 306.0, 156.8, 296.1,
+155.4, 298.3, 156.2, 298.9, 155.7, 301.6, 154.8, 305.8, 154.8, 305.8,
+154.0, 309.9, 150.0, 329.0, 150.8, 329.2, 146.0, 348.1, 159.0, 237.4,
+147.8, 258.1, 146.3, 257.4, 136.6, 278.7, 137.5, 255.7, 137.5, 255.7,
+138.4, 232.7, 155.7, 212.2, 153.4, 210.2, 168.4, 187.8, 169.4, 188.0,
+167.3, 213.8, 159.0, 237.4, 168.4, 187.8, 200.4, 140.1, 204.5, 142.4,
+232.3, 92.4, 235.7, 87.8, 236.4, 88.2, 239.2, 83.3, 219.1, 123.5,
+219.1, 123.5, 199.0, 163.7, 206.9, 171.3, 179.0, 200.6, 159.0, 237.4,
+167.3, 213.8, 169.4, 188.0, 168.4, 187.8, 471.9, 840.0, 468.5, 791.8,
+468.5, 791.8, 465.1, 743.6, 463.7, 718.3, 464.4, 718.2, 463.6, 692.9,
+463.5, 690.2, 463.4, 690.2, 463.3, 687.6, 463.2, 686.9, 463.2, 686.2,
+463.2, 686.2, 463.2, 686.2, 463.2, 686.9, 463.3, 687.6, 463.4, 690.2,
+463.5, 690.2, 463.6, 692.9, 467.8, 766.4, 469.7, 766.4, 471.9, 840.0,
+704.6, 772.1, 709.6, 768.3, 709.0, 767.6, 713.4, 763.0, 716.6, 759.7,
+716.6, 759.7, 719.8, 756.4, 725.4, 750.5, 725.4, 750.5, 731.1, 744.7,
+735.2, 740.4, 735.2, 740.4, 739.3, 736.1, 751.8, 723.2, 750.1, 721.0,
+764.3, 710.3, 765.7, 712.6, 766.5, 712.4, 767.2, 714.9, 768.1, 717.4,
+768.7, 717.2, 770.2, 719.5, 739.2, 747.8, 738.0, 746.6, 704.6, 772.1,
+530.8, 680.6, 529.6, 688.2, 529.9, 688.2, 529.0, 695.8, 526.4, 716.5,
+526.4, 716.5, 523.8, 737.3, 519.5, 772.2, 519.5, 772.2, 515.2, 807.1,
+512.6, 828.3, 512.6, 828.3, 510.0, 849.6, 508.0, 865.3, 511.1, 866.3,
+506.1, 880.9, 505.7, 882.1, 499.2, 880.7, 499.2, 881.1, 505.3, 820.4,
+508.7, 820.8, 518.2, 760.4, 524.5, 720.5, 524.2, 720.5, 530.8, 680.6,
+504.4, 759.9, 504.4, 760.3, 504.4, 760.3, 504.3, 760.8, 496.6, 802.0,
+496.7, 802.1, 490.8, 843.6, 489.1, 837.4, 485.8, 836.4, 487.4, 831.1,
+486.4, 819.9, 486.4, 819.9, 485.3, 808.6, 485.3, 808.6, 483.9, 793.3,
+482.5, 778.1, 485.1, 756.8, 480.5, 747.8, 494.2, 736.4, 491.4, 738.7,
+499.5, 748.0, 504.4, 759.9, 494.2, 736.4, 501.4, 685.9, 537.8, 673.8,
+521.8, 637.3, 512.1, 698.4, 513.1, 698.6, 504.4, 759.9, 499.5, 748.0,
+491.4, 738.7, 494.2, 736.4, 572.6, 410.9, 576.4, 416.8, 576.4, 416.8,
+580.1, 422.7, 579.7, 424.1, 580.0, 424.7, 580.8, 426.0, 580.2, 430.4,
+579.6, 430.3, 578.5, 434.6, 577.9, 436.5, 578.4, 438.1, 577.4, 438.4,
+563.8, 442.5, 563.3, 440.9, 549.3, 443.3, 545.6, 443.9, 543.5, 442.4,
+541.9, 444.6, 555.1, 426.2, 553.8, 421.7, 572.6, 410.9, 482.0, 772.1,
+480.0, 750.5, 480.1, 750.5, 478.0, 728.9, 478.3, 721.1, 484.7, 720.8,
+484.0, 713.4, 486.7, 742.4, 492.0, 746.3, 482.0, 772.1, 446.9, 345.2,
+448.3, 351.9, 446.0, 352.4, 445.1, 359.6, 444.8, 361.9, 444.1, 362.0,
+444.5, 364.1, 443.9, 357.8, 443.9, 357.8, 443.4, 351.4, 443.8, 348.2,
+447.5, 347.8, 446.9, 345.2, 406.2, 718.4, 412.9, 726.6, 407.7, 747.1,
+403.8, 747.8, 396.2, 749.3, 393.5, 735.4, 383.3, 722.9, 376.1, 714.2,
+374.3, 704.6, 369.0, 705.6, 385.7, 702.3, 395.6, 705.4, 406.2, 718.4,
+451.5, 559.9, 451.9, 567.7, 451.9, 567.7, 452.4, 575.5, 452.6, 578.7,
+452.6, 578.7, 452.8, 581.9, 453.1, 588.3, 453.1, 588.3, 453.5, 594.6,
+455.3, 625.3, 455.3, 625.3, 457.1, 655.9, 457.9, 669.3, 457.9, 669.3,
+458.7, 682.6, 460.2, 708.3, 460.1, 708.3, 461.7, 734.0, 463.2, 759.1,
+463.3, 759.1, 464.9, 784.3, 464.9, 784.9, 464.8, 784.9, 464.7, 785.5,
+463.1, 759.8, 463.2, 759.7, 461.7, 734.0, 460.1, 708.3, 460.2, 708.3,
+458.7, 682.6, 457.9, 669.3, 457.9, 669.3, 457.1, 655.9, 455.3, 625.3,
+455.3, 625.3, 453.5, 594.6, 453.1, 588.3, 453.1, 588.3, 452.8, 581.9,
+452.6, 578.7, 452.6, 578.7, 452.4, 575.5, 451.9, 567.7, 451.9, 567.7,
+451.5, 559.9, 358.6, 780.4, 359.1, 775.3, 359.2, 775.3, 359.7, 770.2,
+360.0, 767.1, 360.0, 767.1, 360.3, 764.1, 360.9, 758.8, 360.9, 758.8,
+361.4, 753.6, 362.4, 743.8, 362.4, 743.8, 363.4, 734.1, 364.4, 724.0,
+361.6, 722.8, 365.4, 714.0, 365.5, 713.7, 365.5, 713.7, 365.5, 713.5,
+364.5, 723.8, 364.5, 723.8, 363.4, 734.1, 362.4, 743.8, 362.4, 743.8,
+361.4, 753.6, 360.9, 758.8, 360.9, 758.8, 360.3, 764.1, 360.0, 767.1,
+360.0, 767.1, 359.7, 770.2, 359.2, 775.3, 359.1, 775.3, 358.6, 780.4,
+419.4, 196.3, 422.1, 218.7, 422.1, 218.7, 424.8, 241.2, 425.0, 242.8,
+424.8, 242.9, 424.7, 244.6, 423.4, 234.8, 423.6, 234.8, 422.5, 225.0,
+421.0, 210.6, 421.3, 210.6, 419.4, 196.3, 356.8, 749.4, 350.3, 776.3,
+345.5, 776.0, 343.8, 803.1, 354.5, 813.4, 336.9, 831.8, 329.9, 860.4,
+330.6, 857.7, 330.0, 857.6, 330.6, 854.9, 343.4, 802.1, 343.4, 802.1,
+356.8, 749.4, 369.0, 519.0, 376.4, 514.0, 386.1, 528.3, 403.2, 537.7,
+403.4, 537.8, 403.4, 537.8, 403.6, 538.0, 405.6, 539.1, 407.7, 539.3,
+407.6, 540.2, 405.2, 559.0, 409.8, 571.4, 398.6, 577.3, 394.5, 579.5,
+387.8, 566.8, 377.0, 556.3, 376.7, 556.1, 376.5, 556.1, 376.5, 555.8,
+372.5, 537.4, 363.0, 523.0, 369.0, 519.0, 376.5, 555.8, 376.3, 552.5,
+373.2, 552.6, 370.0, 549.5, 362.3, 542.1, 362.3, 542.1, 354.7, 534.6,
+341.8, 522.1, 341.8, 522.1, 329.0, 509.6, 314.1, 495.1, 316.5, 484.7,
+299.2, 480.6, 336.5, 489.3, 341.5, 492.2, 369.0, 519.0, 363.0, 523.0,
+372.5, 537.4, 376.5, 555.8, 403.2, 537.7, 386.1, 528.3, 376.4, 514.0,
+369.0, 519.0, 341.5, 492.2, 336.5, 489.3, 299.2, 480.6, 295.0, 478.2,
+296.3, 475.1, 292.1, 473.7, 302.0, 476.9, 301.3, 479.0, 310.5, 484.3,
+356.8, 511.0, 357.2, 510.5, 403.2, 537.7, 324.0, 409.5, 317.7, 409.2,
+311.5, 396.8, 312.2, 396.0, 316.9, 390.7, 323.6, 396.7, 334.9, 397.3,
+338.5, 397.5, 340.5, 399.4, 342.0, 397.7, 335.1, 405.5, 332.6, 410.0,
+324.0, 409.5, 278.7, 425.6, 285.6, 411.6, 288.9, 412.4, 292.4, 397.5,
+267.8, 486.1, 267.7, 486.1, 242.9, 574.7, 250.8, 548.1, 249.4, 547.7,
+255.8, 520.7, 267.2, 473.2, 267.2, 473.2, 278.6, 425.7, 278.7, 425.6,
+278.7, 425.6, 278.7, 425.6, 278.6, 425.7, 275.1, 429.0, 276.4, 430.3,
+274.1, 435.0, 273.4, 436.3, 273.4, 436.3, 272.8, 437.6, 262.3, 459.0,
+262.3, 459.0, 251.8, 480.4, 239.7, 505.1, 242.2, 506.7, 227.6, 529.8,
+228.1, 523.5, 229.2, 517.3, 228.5, 517.2, 231.2, 498.1, 229.9, 497.9,
+231.3, 478.7, 230.4, 476.9, 233.1, 475.5, 234.8, 472.2, 256.1, 448.4,
+255.5, 447.6, 278.6, 425.7, 234.8, 472.2, 256.9, 432.0, 258.1, 432.7,
+278.9, 391.8, 294.0, 364.3, 294.0, 364.3, 309.1, 336.7, 309.4, 336.0,
+309.5, 336.0, 309.8, 335.3, 301.3, 366.5, 302.9, 367.1, 292.4, 397.5,
+288.9, 412.4, 285.6, 411.6, 278.7, 425.6, 278.7, 425.6, 278.7, 425.6,
+278.6, 425.7, 255.5, 447.6, 256.1, 448.4, 234.8, 472.2, 173.4, 823.0,
+173.4, 823.1, 173.5, 823.2, 173.5, 823.2, 169.0, 836.5, 163.8, 836.8,
+164.5, 849.8, 156.3, 851.7, 151.6, 841.8, 142.6, 830.7, 142.7, 830.7,
+142.6, 826.8, 142.6, 822.9, 142.6, 817.6, 142.3, 817.6, 142.6, 812.3,
+142.5, 801.1, 143.7, 801.1, 144.7, 789.8, 143.9, 791.3, 147.5, 793.0,
+150.3, 796.2, 161.8, 809.6, 161.9, 809.6, 173.4, 823.0, 119.8, 323.7,
+124.1, 343.2, 127.0, 342.9, 128.3, 362.6, 128.7, 366.0, 129.2, 369.3,
+129.2, 369.3, 130.6, 382.7, 130.6, 382.7, 132.1, 396.2, 124.8, 369.2,
+120.5, 370.3, 108.8, 344.5, 107.3, 335.3, 122.1, 325.8, 119.8, 323.7,
+63.0, 185.6, 57.2, 200.1, 54.3, 199.5, 51.4, 214.6, 49.9, 210.5,
+49.9, 210.5, 48.4, 206.4, 53.0, 194.9, 65.5, 192.5, 63.0, 185.6,
+105.4, 363.9, 106.3, 366.5, 106.3, 366.5, 107.3, 369.1, 122.3, 400.9,
+118.4, 402.7, 129.6, 436.3, 129.3, 435.7, 129.0, 435.8, 128.4, 435.2,
+120.2, 413.2, 111.2, 416.5, 94.0, 397.8, 89.6, 384.1, 97.9, 380.0,
+105.4, 363.9, 94.0, 397.8, 88.1, 391.4, 88.2, 391.3, 82.2, 384.9,
+79.3, 381.0, 75.7, 380.0, 76.5, 377.0, 76.4, 376.3, 75.1, 375.7,
+75.3, 375.5, 75.5, 375.2, 74.8, 374.8, 74.3, 374.1, 74.1, 374.0,
+74.2, 373.9, 74.1, 373.8, 75.7, 359.1, 74.5, 359.0, 75.0, 344.2,
+75.0, 344.2, 90.3, 334.3, 90.8, 323.7, 98.1, 343.8, 98.1, 343.8,
+105.4, 363.9, 97.9, 380.0, 89.6, 384.1, 94.0, 397.8, 804.3, 668.0,
+797.3, 661.3, 797.3, 661.3, 790.4, 654.6, 793.9, 640.3, 795.5, 639.4,
+793.8, 625.1, 794.2, 623.3, 794.7, 621.4, 794.7, 621.4, 795.2, 621.3,
+796.2, 619.0, 795.5, 618.0, 795.4, 618.0, 796.0, 615.9, 796.5, 613.7,
+805.7, 616.5, 805.9, 616.0, 815.2, 618.2, 818.6, 641.9, 817.6, 648.5,
+804.3, 668.0, 815.2, 618.2, 821.5, 619.7, 824.4, 623.7, 827.8, 621.3,
+828.2, 620.5, 831.7, 622.2, 835.7, 623.1, 838.1, 626.0, 838.6, 626.1,
+842.2, 627.4, 849.0, 635.9, 849.0, 635.9, 855.7, 644.3, 834.4, 648.1,
+814.8, 664.3, 817.1, 675.3, 814.5, 675.3, 814.5, 675.3, 811.9, 675.4,
+809.7, 676.2, 808.1, 671.7, 804.3, 668.0, 817.6, 648.5, 818.6, 641.9,
+815.2, 618.2, 813.9, 548.1, 824.6, 557.5, 824.6, 557.5, 835.3, 566.8,
+837.5, 568.8, 837.4, 568.9, 839.5, 570.9, 839.5, 570.9, 847.4, 578.7,
+855.2, 586.5, 834.2, 567.7, 833.9, 567.9, 813.9, 548.1, 703.1, 474.3,
+704.9, 476.6, 704.9, 476.6, 706.7, 478.9, 701.7, 512.8, 694.7, 516.5,
+704.0, 547.8, 700.6, 554.3, 700.6, 554.3, 697.3, 560.8, 694.3, 542.7,
+698.6, 542.0, 699.8, 523.1, 700.3, 515.6, 700.3, 515.6, 700.8, 508.2,
+701.6, 497.2, 701.6, 497.2, 702.3, 486.2, 702.5, 483.1, 702.5, 483.1,
+702.7, 480.0, 702.8, 478.7, 702.8, 478.7, 702.9, 477.3, 703.0, 475.8,
+703.5, 474.5, 703.1, 474.3, 918.1, 484.0, 921.1, 492.4, 921.1, 492.4,
+924.1, 500.9, 926.8, 505.5, 923.1, 507.7, 922.2, 514.6, 921.4, 524.5,
+919.9, 524.4, 917.5, 534.2, 914.2, 509.6, 913.3, 508.2, 918.1, 484.0,
+765.5, 384.9, 812.7, 448.1, 811.2, 449.2, 859.8, 511.3, 863.9, 517.2,
+863.9, 517.2, 868.0, 523.0, 851.2, 505.1, 850.6, 505.7, 833.2, 488.3,
+796.5, 438.8, 810.5, 423.8, 765.5, 384.9, 833.2, 488.3, 792.0, 447.3,
+794.4, 444.7, 750.9, 406.3, 745.1, 399.2, 746.0, 393.0, 739.4, 392.2,
+751.7, 387.5, 751.7, 387.5, 764.0, 382.8, 763.8, 383.1, 764.8, 383.9,
+765.5, 384.9, 810.5, 423.8, 796.5, 438.8, 833.2, 488.3, 789.5, 387.2,
+786.9, 381.2, 788.2, 380.2, 784.2, 375.2, 792.1, 372.2, 792.1, 372.2,
+799.9, 369.3, 800.0, 369.2, 800.1, 369.5, 800.2, 369.8, 794.8, 382.7,
+810.9, 389.5, 821.7, 409.3, 820.1, 403.3, 814.9, 404.7, 808.2, 400.0,
+798.9, 393.6, 797.2, 395.2, 789.5, 387.2, 875.3, 138.2, 890.8, 149.6,
+890.8, 149.6, 906.3, 160.9, 881.0, 157.7, 877.1, 159.7, 853.6, 170.8,
+841.7, 168.3, 840.9, 163.7, 829.8, 165.7, 822.6, 162.9, 818.5, 154.8,
+816.9, 156.1, 832.1, 143.9, 836.9, 149.9, 857.0, 143.8, 866.1, 141.0,
+868.0, 135.7, 875.3, 138.2, 839.8, 173.3, 876.6, 201.0, 876.6, 201.0,
+913.4, 228.8, 918.1, 232.3, 918.0, 232.3, 922.7, 235.8, 881.2, 204.6,
+881.1, 204.8, 839.8, 173.3, 774.9, 157.7, 800.5, 192.0, 799.6, 193.6,
+817.9, 232.4, 812.6, 229.4, 812.6, 229.4, 807.2, 226.4, 799.9, 216.7,
+801.9, 215.2, 796.7, 204.0, 785.8, 180.8, 789.9, 177.8, 774.9, 157.7,
+742.1, 168.4, 748.6, 172.2, 747.3, 174.3, 752.5, 180.3, 759.9, 188.8,
+758.0, 193.0, 767.4, 197.3, 728.8, 172.1, 729.3, 154.2, 687.8, 150.7,
+686.9, 150.1, 686.9, 150.1, 686.0, 149.5, 683.8, 133.2, 668.7, 135.3,
+651.4, 121.1, 699.3, 137.2, 698.0, 142.6, 742.1, 168.4, 799.3, 321.8,
+790.6, 327.8, 789.5, 326.7, 782.0, 333.8, 782.8, 333.4, 782.3, 332.4,
+782.6, 330.9, 783.7, 325.5, 781.7, 321.8, 784.9, 320.1, 790.0, 317.2,
+799.1, 322.4, 799.3, 321.8, 664.3, 139.4, 661.1, 135.9, 661.1, 135.9,
+657.9, 132.4, 704.8, 164.9, 705.4, 164.1, 752.8, 195.8, 716.3, 163.2,
+711.0, 169.1, 669.2, 142.5, 666.8, 140.9, 666.5, 141.3, 664.3, 139.4,
+658.2, 159.9, 633.0, 146.5, 634.7, 139.2, 607.9, 133.0, 589.3, 120.3,
+589.3, 120.3, 570.7, 107.6, 572.4, 108.8, 572.5, 108.7, 574.2, 109.7,
+593.2, 121.1, 593.2, 121.1, 612.2, 132.4, 635.2, 146.2, 637.3, 162.6,
+658.2, 159.9, 549.5, 216.0, 560.1, 230.0, 560.1, 230.0, 570.7, 244.0,
+552.7, 230.3, 534.4, 238.6, 529.6, 223.2, 494.1, 200.7, 491.9, 204.2,
+454.2, 185.1, 453.2, 181.7, 451.3, 182.2, 448.4, 179.4, 466.8, 183.8,
+466.3, 185.9, 484.2, 192.4, 511.4, 202.2, 511.4, 202.2, 538.5, 212.0,
+544.0, 214.0, 545.7, 212.3, 549.5, 216.0, 468.4, 248.2, 463.1, 244.0,
+464.6, 242.2, 460.7, 236.1, 452.5, 223.3, 456.0, 216.4, 444.3, 210.5,
+492.1, 245.1, 492.6, 244.5, 541.6, 277.4, 542.2, 278.2, 542.2, 278.3,
+542.8, 279.0, 536.5, 273.8, 530.8, 280.7, 518.8, 282.5, 491.3, 271.0,
+492.2, 267.1, 468.4, 248.2, 518.8, 282.5, 510.0, 283.7, 505.9, 288.8,
+501.2, 285.0, 500.2, 284.4, 500.2, 284.4, 499.3, 283.8, 493.2, 279.7,
+493.1, 279.8, 486.8, 275.9, 486.2, 275.5, 486.0, 275.6, 485.7, 275.1,
+482.9, 270.8, 481.8, 271.2, 480.2, 266.5, 477.7, 262.6, 477.7, 262.6,
+475.1, 258.7, 471.8, 253.4, 473.2, 250.8, 468.4, 248.2, 492.2, 267.1,
+491.3, 271.0, 518.8, 282.5, 504.3, 4.5, 516.9, -11.6, 519.7, -10.1,
+529.4, -27.8, 529.8, -26.1, 529.7, -26.0, 530.3, -24.4, 538.8, -5.6,
+535.7, -4.2, 541.1, 16.0, 525.8, 22.1, 528.8, 29.4, 516.5, 42.7,
+516.9, 42.3, 516.0, 41.4, 515.6, 40.0, 510.5, 23.9, 510.5, 23.9,
+505.4, 7.7, 504.9, 6.1, 503.8, 5.4, 504.3, 4.5, 639.5, 8.4,
+639.7, 16.2, 642.7, 22.6, 639.9, 23.9, 624.1, 37.2, 624.1, 37.2,
+608.4, 50.5, 611.7, 42.7, 600.9, 38.2, 593.4, 25.8, 593.3, 25.3,
+597.4, 24.3, 601.4, 22.8, 610.8, 19.2, 610.8, 19.2, 620.2, 15.7,
+624.8, 14.0, 624.8, 14.0, 629.3, 12.3, 634.4, 10.4, 638.2, 7.0,
+639.5, 8.4, 453.5, 65.5, 447.0, 74.6, 447.0, 74.6, 440.4, 83.6,
+441.1, 80.3, 436.2, 74.9, 433.3, 75.3, 432.4, 75.9, 429.1, 70.4,
+424.9, 65.5, 436.5, 59.9, 447.5, 58.4, 453.5, 65.5, 450.5, -16.5,
+432.0, -18.4, 432.0, -18.4, 413.6, -20.3, 437.4, -27.6, 437.7, -27.9,
+460.0, -39.1, 474.0, -43.4, 474.0, -43.4, 488.0, -47.7, 479.7, -27.7,
+472.1, -24.4, 450.5, -16.5, 265.1, 182.1, 248.9, 202.2, 226.0, 217.1,
+225.3, 216.3, 232.4, 185.6, 232.4, 185.6, 239.6, 154.9, 239.5, 155.4,
+240.3, 155.6, 240.9, 156.3, 249.7, 165.6, 249.7, 165.6, 258.5, 175.0,
+261.8, 178.5, 265.5, 181.5, 265.1, 182.1, 286.3, 163.8, 287.4, 159.2,
+290.1, 157.2, 295.2, 156.1, 293.8, 156.4, 295.6, 160.6, 293.7, 162.2,
+291.1, 164.4, 286.7, 162.2, 286.3, 163.8, 319.8, 249.5, 302.8, 221.9,
+306.2, 219.1, 285.8, 194.3, 281.7, 180.7, 289.7, 178.2, 293.7, 162.2,
+295.6, 160.6, 293.8, 156.4, 295.2, 156.1, 298.4, 143.3, 298.4, 143.3,
+301.6, 130.4, 301.6, 130.4, 301.5, 130.3, 301.5, 130.3, 301.5, 130.3,
+301.6, 130.4, 301.6, 130.4, 310.7, 190.0, 333.2, 195.5, 319.8, 249.5,
+301.6, 130.4, 302.9, 144.6, 306.2, 144.2, 310.9, 158.1, 320.4, 186.5,
+320.4, 186.5, 329.9, 214.9, 331.8, 220.7, 331.8, 220.7, 333.8, 226.6,
+330.2, 231.4, 334.1, 239.5, 340.6, 246.9, 340.9, 248.6, 339.1, 248.9,
+337.6, 250.9, 332.9, 257.1, 332.4, 263.6, 328.2, 263.3, 328.9, 256.9,
+324.0, 256.4, 319.8, 249.5, 333.2, 195.5, 310.7, 190.0, 301.6, 130.4,
+356.7, 139.2, 350.2, 134.3, 353.0, 126.2, 355.1, 114.2, 357.3, 116.0,
+360.6, 115.1, 360.7, 116.3, 381.1, 132.7, 381.1, 132.7, 401.4, 149.1,
+401.6, 148.1, 373.4, 151.7, 356.7, 139.2, 299.7, 125.0, 289.1, 108.1,
+282.8, 103.1, 286.7, 86.0, 287.4, 82.9, 297.8, 85.2, 308.9, 84.4,
+315.9, 83.9, 321.9, 81.1, 323.0, 83.4, 325.0, 87.7, 319.0, 90.5,
+315.0, 97.6, 310.1, 106.4, 310.1, 106.4, 305.2, 115.3, 302.5, 120.1,
+298.3, 122.7, 299.7, 125.0, 181.3, 386.7, 181.8, 382.9, 181.0, 382.6,
+182.4, 379.0, 186.4, 367.7, 186.4, 367.7, 190.4, 356.3, 188.2, 371.8,
+186.6, 371.8, 181.3, 386.7, 224.3, 170.6, 229.8, 160.6, 230.0, 160.7,
+235.3, 150.5, 231.1, 165.6, 231.1, 165.6, 226.9, 180.6, 227.0, 180.2,
+226.8, 180.1, 226.7, 179.6, 225.5, 175.1, 223.2, 174.4, 224.3, 170.6,
+155.7, 301.6, 156.2, 298.9, 155.4, 298.3, 156.8, 296.1, 157.4, 294.9,
+157.1, 294.1, 158.1, 293.8, 165.8, 287.7, 163.1, 284.1, 168.1, 274.5,
+182.5, 266.1, 189.3, 262.0, 202.7, 267.7, 200.1, 277.3, 200.1, 277.3,
+197.4, 286.9, 194.8, 290.7, 192.0, 288.8, 186.7, 290.7, 179.3, 293.3,
+179.3, 293.3, 172.0, 295.9, 171.2, 296.2, 171.2, 296.2, 170.5, 296.4,
+164.9, 298.4, 164.9, 298.4, 159.2, 300.4, 157.5, 301.0, 155.8, 301.9,
+155.7, 301.6, 474.7, 878.3, 473.3, 859.1, 473.3, 859.1, 471.9, 840.0,
+469.7, 766.4, 467.8, 766.4, 463.6, 692.9, 463.5, 690.2, 463.4, 690.2,
+463.3, 687.6, 463.4, 690.2, 463.5, 690.2, 463.6, 692.9, 467.8, 766.4,
+469.7, 766.4, 471.9, 840.0, 473.3, 859.1, 473.3, 859.1, 474.7, 878.3,
+703.6, 773.3, 704.1, 772.7, 704.0, 772.6, 704.6, 772.1, 738.0, 746.6,
+739.2, 747.8, 770.2, 719.5, 770.4, 719.9, 770.8, 720.0, 770.7, 720.3,
+771.7, 726.6, 776.6, 732.6, 778.2, 732.1, 769.4, 744.7, 763.0, 739.6,
+750.0, 750.0, 696.0, 793.3, 704.4, 809.3, 644.3, 839.4, 681.2, 820.9,
+673.9, 806.3, 703.6, 773.3, 644.3, 839.4, 633.2, 850.9, 632.6, 850.6,
+619.8, 860.2, 624.5, 856.6, 623.9, 855.9, 628.1, 851.5, 661.0, 817.4,
+661.0, 817.4, 693.8, 783.4, 698.7, 778.3, 698.9, 778.5, 703.6, 773.3,
+673.9, 806.3, 681.2, 820.9, 644.3, 839.4, 518.2, 760.4, 508.7, 820.8,
+505.3, 820.4, 499.2, 881.1, 499.0, 882.0, 494.5, 882.9, 492.0, 881.3,
+490.7, 880.5, 491.8, 878.8, 491.6, 876.2, 490.2, 868.5, 490.8, 868.4,
+490.1, 860.6, 493.4, 859.1, 491.7, 854.3, 491.9, 847.9, 495.9, 826.7,
+495.0, 826.5, 498.0, 805.1, 499.1, 794.7, 500.0, 794.8, 501.9, 784.4,
+507.8, 771.4, 517.9, 772.6, 518.2, 760.4, 501.9, 784.4, 516.1, 671.5,
+522.3, 672.2, 543.4, 560.1, 544.6, 555.9, 545.0, 555.9, 545.8, 551.6,
+546.7, 548.5, 546.1, 548.2, 547.5, 545.3, 546.7, 546.9, 547.3, 547.2,
+547.1, 549.0, 545.2, 564.5, 545.2, 564.5, 543.2, 580.0, 542.6, 585.6,
+542.6, 585.6, 541.9, 591.3, 540.1, 605.1, 540.1, 605.1, 538.4, 619.0,
+537.3, 627.8, 537.3, 627.8, 536.3, 636.7, 533.8, 656.3, 533.8, 656.3,
+531.4, 675.9, 531.1, 678.3, 531.2, 678.3, 530.8, 680.6, 524.2, 720.5,
+524.5, 720.5, 518.2, 760.4, 517.9, 772.6, 507.8, 771.4, 501.9, 784.4,
+563.3, 396.4, 568.0, 403.6, 568.0, 403.6, 572.6, 410.9, 553.8, 421.7,
+555.1, 426.2, 541.9, 444.6, 541.1, 445.4, 540.4, 444.8, 539.0, 445.1,
+528.2, 446.9, 528.2, 446.9, 517.4, 448.8, 509.5, 450.2, 501.5, 451.9,
+501.5, 451.5, 510.3, 443.7, 507.4, 440.4, 513.3, 429.3, 535.4, 409.6,
+535.8, 404.9, 563.3, 396.4, 513.3, 429.3, 529.4, 398.9, 533.3, 400.4,
+545.5, 368.5, 554.4, 382.5, 554.4, 382.5, 563.3, 396.4, 535.8, 404.9,
+535.4, 409.6, 513.3, 429.3, 526.6, 620.2, 524.2, 628.7, 523.2, 628.6,
+521.8, 637.3, 537.8, 673.8, 501.4, 685.9, 494.2, 736.4, 480.5, 747.8,
+485.1, 756.8, 482.5, 778.1, 482.3, 775.1, 482.3, 775.1, 482.0, 772.1,
+492.0, 746.3, 486.7, 742.4, 484.0, 713.4, 490.1, 684.0, 495.0, 685.1,
+506.0, 656.7, 507.2, 653.4, 506.8, 653.2, 508.5, 650.2, 517.1, 634.9,
+514.4, 631.9, 526.6, 620.2, 508.5, 650.2, 506.3, 648.9, 514.9, 633.7,
+521.3, 617.1, 524.2, 609.7, 524.2, 609.7, 527.1, 602.3, 535.2, 581.2,
+542.9, 581.4, 543.4, 560.1, 535.0, 590.1, 535.0, 590.1, 526.6, 620.2,
+514.4, 631.9, 517.1, 634.9, 508.5, 650.2, 451.2, 311.6, 452.2, 312.4,
+450.9, 313.9, 450.6, 316.3, 448.7, 330.7, 449.8, 331.0, 446.9, 345.2,
+447.5, 347.8, 443.8, 348.2, 443.4, 351.4, 441.3, 329.1, 441.3, 329.1,
+439.3, 306.7, 439.0, 307.9, 446.5, 307.6, 451.2, 311.6, 490.6, 289.4,
+495.4, 300.0, 492.2, 303.8, 500.3, 310.6, 501.6, 337.8, 501.6, 337.8,
+503.0, 365.1, 487.6, 331.4, 492.5, 327.4, 490.6, 289.4, 453.6, 292.6,
+451.1, 287.9, 456.2, 280.0, 455.2, 279.7, 461.1, 281.5, 459.3, 287.6,
+463.5, 295.5, 465.0, 298.4, 464.4, 300.7, 466.5, 301.3, 459.4, 299.2,
+456.8, 298.7, 453.6, 292.6, 184.0, 643.8, 178.9, 658.2, 177.4, 657.8,
+173.9, 672.6, 169.9, 643.5, 169.9, 643.5, 165.9, 614.5, 163.2, 624.8,
+174.0, 627.6, 182.2, 640.8, 183.1, 642.3, 184.3, 642.6, 184.0, 643.8,
+218.5, 420.3, 228.1, 405.3, 229.6, 406.0, 237.7, 390.2, 232.9, 392.7,
+238.0, 401.0, 236.2, 411.3, 228.3, 439.8, 230.0, 440.3, 223.8, 469.2,
+233.1, 461.9, 221.4, 447.0, 219.0, 424.9, 218.8, 422.6, 217.7, 422.0,
+218.5, 420.3, 421.1, 484.6, 422.3, 473.1, 423.9, 473.2, 426.6, 461.9,
+427.4, 458.4, 428.0, 458.4, 428.3, 454.9, 425.3, 497.4, 424.7, 497.4,
+421.2, 539.9, 420.9, 543.2, 420.6, 543.2, 420.6, 546.5, 420.4, 532.8,
+420.7, 532.8, 420.8, 519.2, 421.0, 501.9, 419.4, 501.7, 421.1, 484.6,
+422.5, 225.0, 423.6, 234.8, 423.4, 234.8, 424.7, 244.6, 424.1, 275.2,
+419.6, 275.8, 423.4, 305.9, 420.5, 301.6, 420.5, 301.6, 417.5, 297.2,
+417.2, 261.1, 417.7, 260.8, 422.5, 225.0, 355.0, 647.4, 355.7, 641.6,
+358.4, 641.9, 358.8, 636.1, 356.5, 665.5, 360.6, 667.3, 351.3, 694.7,
+358.7, 672.9, 352.0, 670.9, 355.0, 647.4, 376.3, 669.4, 377.1, 669.7,
+372.0, 686.8, 367.8, 704.1, 366.7, 708.8, 366.7, 708.8, 365.5, 713.5,
+365.5, 713.7, 365.5, 713.7, 365.4, 714.0, 358.3, 730.5, 361.1, 731.7,
+356.8, 749.4, 343.4, 802.1, 343.4, 802.1, 330.6, 854.9, 337.9, 833.6,
+333.6, 832.1, 336.5, 809.4, 337.2, 803.9, 337.2, 803.9, 337.9, 798.5,
+338.4, 794.6, 338.4, 794.6, 338.9, 790.7, 339.9, 783.2, 339.9, 783.2,
+340.8, 775.8, 345.8, 737.4, 338.7, 735.0, 350.7, 699.0, 356.4, 681.9,
+368.6, 667.1, 376.3, 669.4, 292.5, 405.8, 296.0, 393.7, 296.0, 393.7,
+299.6, 381.6, 301.7, 380.5, 305.9, 388.8, 312.2, 396.0, 311.5, 396.8,
+317.7, 409.2, 324.0, 409.5, 326.5, 412.4, 326.5, 412.4, 329.1, 415.3,
+332.3, 419.0, 331.6, 421.7, 335.5, 422.7, 313.3, 417.0, 306.0, 421.3,
+292.5, 405.8, 302.4, 371.7, 309.5, 347.3, 311.6, 347.8, 316.6, 322.9,
+320.3, 313.4, 317.5, 312.0, 322.4, 303.2, 327.4, 285.8, 327.4, 285.8,
+332.5, 268.4, 332.7, 267.9, 333.0, 267.6, 332.8, 267.4, 338.5, 275.2,
+344.3, 276.1, 343.5, 283.5, 341.6, 301.3, 335.5, 300.7, 327.5, 317.9,
+326.6, 319.9, 326.6, 319.9, 325.6, 322.0, 319.1, 335.8, 319.1, 335.8,
+312.7, 349.7, 310.3, 354.7, 310.3, 354.7, 308.0, 359.7, 305.2, 365.7,
+303.9, 365.4, 302.4, 371.7, 420.4, 487.6, 421.6, 491.2, 419.3, 491.9,
+418.3, 496.3, 418.2, 496.3, 418.2, 496.3, 418.2, 496.4, 416.2, 504.6,
+411.6, 510.8, 414.3, 512.8, 385.3, 491.1, 389.9, 484.9, 365.6, 457.1,
+362.0, 453.0, 362.0, 453.0, 358.5, 448.9, 350.7, 440.1, 352.6, 437.1,
+343.0, 431.2, 380.2, 454.0, 378.3, 457.0, 413.7, 482.7, 417.0, 485.2,
+419.3, 484.4, 420.4, 487.6, 303.1, 319.5, 315.6, 292.9, 311.4, 286.3,
+332.5, 268.4, 327.4, 285.8, 327.4, 285.8, 322.4, 303.2, 313.8, 318.9,
+315.6, 319.9, 309.1, 336.7, 294.0, 364.3, 294.0, 364.3, 278.9, 391.8,
+271.4, 406.4, 270.2, 405.8, 261.6, 419.8, 278.8, 368.5, 280.1, 368.6,
+303.1, 319.5, 261.6, 419.8, 246.9, 443.6, 244.9, 442.6, 232.2, 467.3,
+233.2, 453.4, 233.2, 453.4, 234.2, 439.5, 264.1, 377.3, 252.0, 356.3,
+303.1, 319.5, 280.1, 368.6, 278.8, 368.5, 261.6, 419.8, 234.9, 429.5,
+235.6, 420.4, 233.8, 419.9, 236.2, 411.3, 238.0, 401.0, 232.9, 392.7,
+237.7, 390.2, 239.4, 387.0, 236.2, 383.7, 238.3, 382.2, 258.8, 351.6,
+260.3, 352.6, 282.5, 323.1, 284.3, 320.9, 284.3, 320.9, 286.0, 318.8,
+288.1, 316.1, 288.2, 316.2, 290.3, 313.5, 294.6, 307.8, 294.6, 307.8,
+298.9, 302.1, 305.5, 301.5, 304.9, 294.2, 310.9, 286.3, 274.5, 358.7,
+276.4, 360.0, 234.9, 429.5, 310.9, 286.3, 313.8, 282.4, 317.4, 281.6,
+316.7, 278.6, 317.3, 278.9, 327.4, 271.4, 328.2, 263.3, 332.4, 263.6,
+332.9, 257.1, 337.6, 250.9, 340.4, 253.4, 335.2, 259.1, 332.8, 267.4,
+333.0, 267.6, 332.7, 267.9, 332.5, 268.4, 311.4, 286.3, 315.6, 292.9,
+303.1, 319.5, 252.0, 356.3, 264.1, 377.3, 234.2, 439.5, 234.5, 434.5,
+234.5, 434.5, 234.9, 429.5, 276.4, 360.0, 274.5, 358.7, 310.9, 286.3,
+240.7, 582.4, 236.3, 598.2, 231.9, 614.0, 231.9, 614.0, 226.4, 633.0,
+226.3, 633.0, 220.8, 652.1, 219.4, 656.7, 217.9, 656.8, 218.1, 661.3,
+219.1, 648.1, 219.1, 648.1, 220.0, 634.9, 225.6, 614.0, 228.0, 614.6,
+236.0, 594.4, 238.4, 588.4, 239.4, 588.6, 240.7, 582.4, 169.5, 791.9,
+171.5, 807.5, 171.5, 807.5, 173.4, 823.0, 161.9, 809.6, 161.8, 809.6,
+150.3, 796.2, 150.1, 795.3, 166.5, 788.4, 169.5, 791.9, 150.3, 796.2,
+147.5, 793.0, 143.9, 791.3, 144.7, 789.8, 149.8, 732.8, 150.4, 732.9,
+155.0, 675.9, 157.9, 699.5, 152.3, 701.7, 160.9, 723.1, 162.3, 757.6,
+165.2, 757.5, 169.5, 791.9, 166.5, 788.4, 150.1, 795.3, 150.3, 796.2,
+76.7, 162.3, 81.1, 168.4, 84.6, 167.9, 85.5, 174.4, 87.9, 181.5,
+87.9, 181.5, 90.3, 188.5, 100.0, 235.0, 100.4, 234.9, 110.6, 281.3,
+108.8, 272.7, 108.2, 272.8, 105.7, 264.3, 104.5, 259.8, 104.5, 259.8,
+103.2, 255.3, 89.9, 208.8, 87.0, 209.4, 76.7, 162.3, 50.5, 72.6,
+53.0, 79.9, 51.3, 86.0, 55.5, 87.2, 55.6, 87.2, 55.7, 87.7,
+55.9, 88.2, 56.8, 120.2, 51.9, 122.6, 62.1, 152.1, 62.5, 168.3,
+62.5, 168.3, 63.0, 184.6, 66.0, 173.1, 61.6, 171.9, 60.2, 159.3,
+55.4, 116.0, 53.3, 116.1, 50.5, 72.6, 817.0, 605.3, 806.9, 609.0,
+806.7, 608.6, 796.8, 612.7, 797.2, 611.1, 797.4, 609.5, 797.6, 609.5,
+804.0, 598.2, 804.0, 596.3, 804.0, 583.1, 801.5, 574.7, 806.4, 573.2,
+808.8, 563.4, 819.0, 580.8, 821.5, 586.4, 817.0, 605.3, 808.8, 563.4,
+810.7, 555.2, 810.7, 555.2, 812.7, 547.1, 812.6, 547.5, 813.3, 547.6,
+813.9, 548.1, 833.9, 567.9, 834.2, 567.7, 855.2, 586.5, 855.4, 586.6,
+855.4, 586.6, 855.5, 586.8, 853.9, 586.4, 853.0, 589.9, 850.6, 593.0,
+848.1, 589.4, 833.8, 599.1, 817.0, 605.3, 821.5, 586.4, 819.0, 580.8,
+808.8, 563.4, 911.8, 470.4, 913.5, 473.3, 915.9, 473.9, 915.3, 476.2,
+916.7, 480.1, 916.7, 480.1, 918.1, 484.0, 913.3, 508.2, 914.2, 509.6,
+917.5, 534.2, 916.9, 536.7, 916.9, 536.7, 916.3, 539.2, 913.2, 504.9,
+912.4, 504.8, 911.8, 470.4, 916.3, 539.2, 913.4, 551.5, 912.9, 551.4,
+910.5, 563.7, 910.4, 563.6, 910.4, 563.6, 910.3, 563.5, 905.8, 531.9,
+910.5, 526.3, 893.0, 501.6, 891.1, 488.4, 894.8, 486.7, 889.2, 475.3,
+895.7, 464.8, 895.7, 464.8, 902.2, 454.4, 904.7, 463.1, 907.0, 462.4,
+911.8, 470.4, 912.4, 504.8, 913.2, 504.9, 916.3, 539.2, 849.5, 494.8,
+848.1, 492.9, 848.1, 492.9, 846.8, 490.9, 842.0, 484.2, 842.8, 483.6,
+838.7, 476.3, 844.7, 485.2, 844.3, 485.5, 849.5, 494.8, 738.7, 69.9,
+753.9, 66.6, 761.8, 72.8, 769.2, 63.4, 788.7, 68.7, 786.9, 75.6,
+804.5, 87.9, 830.4, 107.5, 831.0, 106.7, 857.5, 125.5, 854.9, 123.5,
+854.5, 124.1, 851.4, 122.6, 813.2, 104.8, 813.2, 104.8, 775.0, 86.9,
+756.8, 78.4, 741.7, 82.2, 738.7, 69.9, 760.7, 133.2, 746.8, 120.3,
+752.8, 100.3, 740.9, 98.7, 768.4, 102.3, 766.4, 118.0, 791.8, 137.2,
+792.9, 137.9, 792.8, 138.7, 793.9, 138.7, 788.0, 138.5, 788.0, 137.7,
+782.2, 136.8, 771.4, 135.0, 767.4, 139.3, 760.7, 133.2, 684.7, 102.6,
+683.4, 102.7, 682.1, 99.2, 681.9, 99.4, 684.6, 101.2, 685.9, 99.3,
+689.9, 99.1, 689.7, 98.8, 687.4, 102.5, 684.7, 102.6, 705.7, 126.7,
+727.5, 138.7, 723.1, 146.6, 740.5, 166.5, 741.3, 167.5, 741.1, 167.9,
+742.1, 168.4, 698.0, 142.6, 699.3, 137.2, 651.4, 121.1, 644.5, 115.4,
+644.5, 115.4, 637.5, 109.8, 672.1, 113.3, 676.0, 110.3, 705.7, 126.7,
+637.5, 109.8, 628.7, 102.5, 629.9, 99.9, 619.9, 95.3, 621.5, 95.0,
+622.0, 94.0, 623.1, 94.6, 646.1, 94.6, 646.1, 89.7, 669.1, 84.8,
+674.0, 93.0, 674.2, 94.0, 681.9, 99.4, 682.1, 99.2, 683.4, 102.7,
+684.7, 102.6, 692.8, 111.8, 692.8, 111.8, 700.8, 121.1, 703.3, 123.9,
+702.9, 126.2, 705.7, 126.7, 676.0, 110.3, 672.1, 113.3, 637.5, 109.8,
+629.3, 214.7, 629.4, 214.6, 627.9, 213.2, 626.6, 211.7, 620.0, 204.5,
+620.0, 204.5, 613.4, 197.3, 608.6, 192.1, 608.6, 192.1, 603.8, 186.8,
+591.9, 173.9, 591.5, 174.3, 580.1, 161.0, 579.1, 158.9, 579.1, 158.9,
+578.0, 156.8, 578.1, 157.0, 578.3, 156.9, 578.7, 157.1, 580.9, 157.7,
+580.9, 157.7, 583.1, 158.4, 618.0, 168.9, 623.6, 160.4, 653.0, 179.5,
+652.8, 179.4, 647.2, 188.0, 641.5, 196.5, 635.4, 205.6, 636.9, 207.0,
+629.3, 214.7, 689.0, 182.7, 706.2, 191.7, 706.2, 191.7, 723.5, 200.8,
+715.9, 194.0, 712.7, 197.5, 701.9, 194.3, 698.4, 193.2, 697.4, 194.4,
+695.0, 192.2, 691.0, 188.6, 693.0, 183.9, 689.0, 182.7, 626.8, 212.0,
+626.7, 211.8, 626.7, 211.8, 626.6, 211.7, 627.9, 213.2, 629.4, 214.6,
+629.3, 214.7, 633.7, 219.4, 633.7, 219.4, 638.0, 224.2, 638.4, 224.6,
+638.4, 224.6, 638.7, 224.9, 645.6, 232.5, 645.6, 232.5, 652.5, 240.0,
+665.2, 253.8, 665.2, 253.8, 677.8, 267.5, 681.5, 271.6, 681.5, 271.6,
+685.2, 275.6, 685.8, 276.2, 685.8, 276.2, 686.3, 276.8, 688.5, 279.2,
+688.5, 279.2, 690.7, 281.6, 697.1, 288.6, 697.1, 288.6, 703.6, 295.6,
+710.4, 303.0, 710.4, 303.0, 717.1, 310.4, 720.6, 314.2, 720.6, 314.2,
+724.0, 317.9, 730.1, 324.6, 736.2, 331.2, 736.2, 331.2, 736.2, 331.2,
+730.1, 324.6, 724.0, 317.9, 720.6, 314.2, 720.6, 314.2, 717.1, 310.4,
+710.4, 303.0, 710.4, 303.0, 703.6, 295.6, 697.1, 288.6, 697.1, 288.6,
+690.7, 281.6, 688.5, 279.2, 688.5, 279.2, 686.3, 276.8, 685.8, 276.2,
+685.8, 276.2, 685.2, 275.6, 681.5, 271.6, 681.5, 271.6, 677.8, 267.5,
+665.2, 253.8, 665.2, 253.8, 652.5, 240.0, 645.6, 232.5, 645.6, 232.5,
+638.7, 224.9, 638.4, 224.6, 638.4, 224.6, 638.0, 224.2, 633.7, 219.4,
+633.7, 219.4, 629.3, 214.7, 628.1, 213.3, 628.0, 213.3, 626.8, 212.0,
+626.8, 212.0, 626.8, 212.0, 626.8, 212.0, 645.8, 239.4, 690.1, 300.2,
+690.2, 300.2, 731.8, 362.9, 730.3, 363.7, 730.3, 363.7, 728.7, 364.4,
+716.2, 348.6, 717.6, 347.6, 706.4, 330.7, 696.0, 315.0, 696.0, 315.0,
+685.6, 299.3, 665.7, 269.4, 667.0, 268.4, 645.8, 239.4, 792.6, 283.1,
+791.4, 277.9, 793.4, 271.7, 795.1, 271.6, 826.3, 282.4, 829.0, 274.6,
+862.9, 277.6, 833.0, 295.4, 834.2, 297.5, 805.6, 317.4, 800.5, 317.8,
+796.7, 300.8, 792.6, 283.1, 805.6, 317.4, 802.4, 319.6, 802.4, 319.6,
+799.3, 321.8, 799.1, 322.4, 790.0, 317.2, 784.9, 320.1, 784.8, 320.1,
+785.1, 318.9, 785.4, 317.7, 789.0, 300.4, 788.8, 283.1, 792.6, 283.1,
+796.7, 300.8, 800.5, 317.8, 805.6, 317.4, 669.2, 142.5, 711.0, 169.1,
+716.3, 163.2, 752.8, 195.8, 757.6, 199.0, 757.6, 199.0, 762.5, 202.3,
+715.8, 172.5, 715.3, 173.2, 669.2, 142.5, 656.5, 133.7, 662.4, 138.7,
+662.0, 139.2, 668.3, 143.7, 682.3, 157.8, 681.8, 158.3, 695.4, 173.0,
+701.6, 179.8, 707.8, 186.6, 707.8, 186.5, 699.6, 181.4, 699.2, 181.9,
+690.7, 177.3, 677.9, 165.3, 679.7, 163.4, 668.8, 149.5, 662.6, 141.6,
+657.2, 142.1, 656.5, 133.7, 484.2, 192.4, 466.3, 185.9, 466.8, 183.8,
+448.4, 179.4, 434.4, 165.4, 434.4, 165.4, 420.4, 151.4, 423.0, 154.3,
+423.8, 153.6, 427.2, 155.8, 427.8, 156.2, 427.8, 156.2, 428.4, 156.5,
+441.0, 164.6, 441.0, 164.6, 453.6, 172.7, 468.9, 182.5, 483.2, 193.7,
+484.2, 192.4, 511.2, 117.2, 506.6, 118.9, 503.0, 121.8, 502.0, 120.5,
+497.6, 121.5, 496.6, 123.8, 493.2, 122.4, 479.7, 123.8, 478.5, 122.4,
+466.5, 128.1, 465.7, 128.2, 465.1, 128.8, 464.8, 128.5, 464.3, 128.6,
+464.0, 128.4, 463.7, 128.7, 497.3, 92.4, 497.5, 92.6, 531.3, 56.5,
+537.7, 49.7, 541.4, 50.9, 544.1, 42.8, 531.4, 81.3, 530.5, 81.6,
+511.2, 117.2, 544.1, 42.8, 544.3, 42.4, 544.9, 42.3, 544.8, 42.1,
+553.0, 66.6, 561.8, 66.9, 561.1, 91.2, 561.9, 94.1, 561.8, 97.0,
+562.7, 97.1, 560.1, 98.9, 560.1, 98.9, 557.4, 100.7, 533.6, 105.7,
+534.3, 109.0, 511.2, 117.2, 530.5, 81.6, 531.4, 81.3, 544.1, 42.8,
+436.8, 132.4, 435.4, 132.4, 435.4, 132.4, 434.0, 132.5, 436.4, 132.0,
+436.1, 130.2, 438.1, 128.0, 490.4, 81.3, 490.1, 80.9, 542.1, 33.9,
+542.0, 37.9, 543.5, 38.0, 544.8, 42.1, 544.9, 42.3, 544.3, 42.4,
+544.1, 42.8, 541.4, 50.9, 537.7, 49.7, 531.3, 56.5, 484.8, 95.3,
+484.6, 95.1, 436.8, 132.4, 531.3, 56.5, 497.5, 92.6, 497.3, 92.4,
+463.7, 128.7, 458.1, 133.7, 455.3, 131.1, 446.7, 132.3, 442.2, 133.8,
+441.7, 132.4, 436.8, 132.4, 484.6, 95.1, 484.8, 95.3, 531.3, 56.5,
+612.3, -75.3, 626.2, -73.9, 633.4, -66.3, 638.1, -51.9, 627.0, -46.6,
+638.8, -21.7, 639.5, 8.4, 638.2, 7.0, 634.4, 10.4, 629.3, 12.3,
+619.7, -9.4, 624.7, -11.6, 620.1, -35.4, 618.2, -44.7, 618.2, -44.7,
+616.4, -54.1, 614.4, -64.7, 615.4, -75.0, 612.3, -75.3, 403.8, 35.1,
+396.6, 24.7, 396.6, 24.7, 389.3, 14.2, 396.6, 18.3, 405.6, 9.6,
+408.7, 14.0, 435.3, 29.2, 443.6, 22.3, 462.0, 44.4, 462.7, 45.0,
+462.7, 45.0, 463.4, 45.6, 433.6, 40.8, 431.0, 46.6, 403.8, 35.1,
+463.4, 45.6, 464.5, 46.4, 464.7, 46.3, 465.6, 47.3, 465.9, 47.6,
+466.2, 47.8, 466.1, 47.9, 459.8, 56.7, 459.8, 56.7, 453.5, 65.5,
+447.5, 58.4, 436.5, 59.9, 424.9, 65.5, 424.7, 65.3, 424.7, 65.3,
+424.5, 65.0, 414.5, 49.8, 414.2, 50.1, 403.8, 35.1, 431.0, 46.6,
+433.6, 40.8, 463.4, 45.6, 509.8, -12.8, 509.0, -11.6, 509.0, -11.6,
+508.1, -10.5, 507.9, -10.1, 506.9, -11.0, 506.1, -10.7, 498.8, -2.9,
+488.5, -14.8, 471.0, -14.3, 461.5, -12.2, 460.8, -15.4, 450.5, -16.5,
+472.1, -24.4, 479.7, -27.7, 488.0, -47.7, 493.8, -49.4, 493.8, -49.4,
+499.5, -51.2, 509.6, -35.0, 505.7, -32.2, 509.8, -12.8, 499.5, -51.2,
+523.8, -58.5, 523.9, -58.0, 548.0, -65.9, 546.5, -63.9, 544.5, -62.9,
+545.1, -61.8, 545.4, -61.3, 542.5, -60.0, 542.7, -58.6, 543.8, -57.6,
+527.3, -47.3, 528.8, -39.2, 528.8, -39.2, 526.9, -37.9, 527.0, -36.7,
+515.8, -28.1, 518.4, -24.7, 509.8, -12.8, 505.7, -32.2, 509.6, -35.0,
+499.5, -51.2, 284.2, 78.5, 283.5, 81.8, 285.4, 82.2, 286.7, 86.0,
+282.8, 103.1, 289.1, 108.1, 299.7, 125.0, 300.6, 127.6, 301.9, 127.8,
+301.5, 130.3, 299.6, 143.4, 300.6, 144.3, 295.2, 156.1, 290.1, 157.2,
+287.4, 159.2, 286.3, 163.8, 280.3, 169.0, 280.3, 169.0, 274.3, 174.1,
+271.1, 176.8, 268.3, 176.5, 268.0, 179.5, 273.3, 128.7, 274.2, 128.6,
+284.2, 78.5, 373.3, 203.2, 370.5, 207.2, 370.8, 207.5, 367.6, 211.2,
+364.7, 215.0, 364.7, 215.0, 361.9, 218.8, 356.5, 189.2, 344.2, 177.1,
+358.0, 158.3, 349.9, 169.3, 369.1, 180.1, 373.3, 203.2, 358.0, 158.3,
+356.2, 151.9, 357.5, 151.5, 357.1, 144.7, 356.9, 141.9, 357.2, 139.2,
+356.7, 139.2, 373.4, 151.7, 401.6, 148.1, 401.4, 149.1, 404.7, 151.7,
+404.6, 151.9, 407.9, 154.3, 390.6, 178.7, 390.6, 178.7, 373.3, 203.2,
+369.1, 180.1, 349.9, 169.3, 358.0, 158.3, 308.9, 84.4, 297.8, 85.2,
+287.4, 82.9, 286.7, 86.0, 285.4, 82.2, 283.5, 81.8, 284.2, 78.5,
+283.8, 77.5, 283.8, 77.5, 283.5, 76.5, 282.6, 68.5, 280.9, 68.7,
+278.3, 61.0, 282.4, 55.0, 292.3, 52.8, 297.3, 56.6, 307.6, 64.5,
+312.6, 74.0, 308.9, 84.4, 297.3, 56.6, 297.3, 55.1, 303.3, 55.2,
+309.4, 53.8, 320.2, 51.3, 320.2, 51.3, 331.0, 48.8, 335.2, 47.8,
+337.5, 45.1, 339.5, 46.8, 345.7, 56.6, 345.7, 56.6, 352.0, 66.3,
+356.0, 70.2, 352.5, 73.8, 353.0, 81.4, 343.1, 87.8, 339.5, 82.3,
+326.0, 83.2, 324.5, 83.3, 324.5, 83.3, 323.0, 83.4, 321.9, 81.1,
+315.9, 83.9, 308.9, 84.4, 312.6, 74.0, 307.6, 64.5, 297.3, 56.6,
+333.5, 40.1, 335.5, 41.8, 336.2, 41.4, 337.4, 43.5, 338.4, 45.2,
+338.4, 45.2, 339.5, 46.8, 337.5, 45.1, 335.2, 47.8, 331.0, 48.8,
+329.4, 47.0, 330.6, 42.5, 333.5, 40.1, 273.8, 289.7, 286.3, 295.9,
+287.0, 303.2, 298.9, 302.1, 294.6, 307.8, 294.6, 307.8, 290.3, 313.5,
+288.2, 316.2, 288.1, 316.1, 286.0, 318.8, 277.3, 306.1, 269.1, 295.9,
+273.8, 289.7, 204.3, 420.0, 183.7, 445.4, 180.2, 443.2, 163.2, 470.8,
+155.4, 476.2, 151.1, 474.2, 147.6, 481.7, 147.4, 480.0, 147.4, 480.0,
+147.1, 478.3, 146.9, 478.2, 148.1, 475.5, 149.2, 472.6, 175.8, 445.4,
+173.8, 423.9, 204.3, 420.0, 213.9, 354.1, 211.2, 376.4, 202.0, 375.3,
+190.1, 396.4, 185.5, 404.4, 185.5, 404.4, 181.0, 412.4, 178.7, 416.5,
+176.4, 416.5, 176.4, 420.6, 182.3, 404.9, 178.8, 403.7, 181.3, 386.7,
+186.6, 371.8, 188.2, 371.8, 190.4, 356.3, 193.8, 346.9, 193.8, 346.9,
+197.1, 337.6, 204.7, 336.9, 214.8, 347.0, 213.9, 354.1, 197.1, 337.6,
+198.8, 332.8, 201.3, 328.4, 200.5, 328.0, 208.1, 323.9, 208.1, 323.9,
+215.6, 319.8, 216.7, 313.2, 227.8, 315.9, 238.9, 309.9, 237.8, 332.4,
+226.4, 331.9, 214.0, 353.9, 214.0, 354.0, 213.9, 354.1, 213.9, 354.1,
+214.8, 347.0, 204.7, 336.9, 197.1, 337.6, 205.5, 205.2, 214.9, 187.9,
+214.9, 187.9, 224.3, 170.6, 223.2, 174.4, 225.5, 175.1, 226.7, 179.6,
+218.9, 193.9, 203.1, 195.7, 205.5, 205.2, 226.7, 179.6, 226.8, 180.1,
+227.0, 180.2, 226.9, 180.6, 214.8, 224.2, 214.8, 224.2, 202.7, 267.7,
+189.3, 262.0, 182.5, 266.1, 168.1, 274.5, 172.0, 267.1, 178.1, 263.9,
+175.9, 259.7, 176.2, 259.8, 176.7, 258.1, 177.5, 256.5, 191.5, 230.8,
+189.8, 229.7, 205.5, 205.2, 203.1, 195.7, 218.9, 193.9, 226.7, 179.6,
+186.7, 290.7, 192.0, 288.8, 194.8, 290.7, 197.4, 286.9, 189.6, 315.0,
+189.6, 315.0, 181.8, 343.0, 182.1, 342.0, 181.9, 342.0, 182.0, 340.9,
+183.7, 322.7, 183.7, 322.7, 185.4, 304.5, 186.1, 297.6, 183.3, 295.7,
+186.7, 290.7, 463.6, 692.9, 463.5, 690.2, 463.4, 690.2, 463.3, 687.6,
+463.2, 686.9, 463.2, 686.2, 463.2, 686.2, 463.0, 680.2, 463.8, 680.1,
+462.8, 674.3, 464.4, 678.0, 464.4, 678.0, 466.1, 681.7, 466.3, 687.2,
+466.0, 687.8, 463.6, 692.9, 578.5, 434.6, 579.6, 430.3, 580.2, 430.4,
+580.8, 426.0, 580.6, 425.6, 581.4, 425.1, 581.3, 424.5, 602.2, 457.1,
+602.2, 457.1, 623.1, 489.8, 628.7, 470.0, 598.0, 464.0, 578.5, 434.6,
+673.6, 757.7, 672.3, 759.2, 679.5, 765.3, 685.5, 772.8, 689.7, 778.1,
+694.9, 781.9, 693.8, 783.4, 661.0, 817.4, 661.0, 817.4, 628.1, 851.5,
+629.8, 849.8, 629.2, 849.3, 630.3, 847.0, 634.0, 839.4, 634.0, 839.4,
+637.6, 831.9, 639.3, 828.4, 639.3, 828.4, 641.0, 824.9, 657.3, 791.3,
+650.1, 785.2, 673.6, 757.7, 491.4, 532.6, 491.9, 530.4, 503.1, 533.1,
+514.8, 533.6, 520.0, 533.8, 525.1, 533.3, 525.2, 534.0, 525.8, 540.2,
+520.7, 540.8, 516.3, 547.5, 512.5, 553.3, 509.0, 559.2, 508.7, 559.0,
+496.5, 551.7, 488.9, 543.1, 491.4, 532.6, 474.8, 529.0, 477.1, 496.5,
+488.2, 493.2, 479.4, 464.0, 481.8, 459.8, 483.6, 460.0, 484.1, 455.6,
+483.9, 455.4, 484.4, 455.0, 484.8, 454.4, 485.1, 452.0, 496.1, 456.3,
+501.5, 451.5, 501.5, 451.9, 509.5, 450.2, 517.4, 448.8, 517.2, 464.4,
+509.2, 464.3, 501.0, 479.8, 499.7, 482.2, 499.7, 482.2, 498.4, 484.5,
+486.6, 506.8, 469.2, 522.9, 474.8, 529.0, 527.1, 602.3, 524.2, 609.7,
+524.2, 609.7, 521.3, 617.1, 515.0, 592.1, 519.4, 590.9, 517.5, 564.7,
+517.0, 557.6, 517.0, 557.6, 516.5, 550.4, 516.4, 549.0, 515.7, 548.6,
+516.3, 547.5, 520.7, 540.8, 525.8, 540.2, 525.2, 534.0, 536.3, 517.1,
+536.3, 517.1, 547.5, 500.3, 551.2, 494.6, 553.7, 495.1, 555.0, 488.9,
+543.5, 546.1, 541.9, 545.8, 527.1, 602.3, 555.0, 488.9, 555.3, 487.8,
+555.7, 487.9, 556.3, 486.9, 562.9, 477.0, 563.1, 466.9, 569.4, 467.1,
+566.8, 467.0, 566.6, 477.0, 563.8, 487.0, 562.8, 490.6, 562.8, 490.6,
+561.8, 494.2, 556.7, 512.6, 556.7, 512.6, 551.5, 531.1, 549.5, 538.2,
+549.5, 538.2, 547.5, 545.3, 546.1, 548.2, 546.7, 548.5, 545.8, 551.6,
+545.0, 555.9, 544.6, 555.9, 543.4, 560.1, 542.9, 581.4, 535.2, 581.2,
+527.1, 602.3, 541.9, 545.8, 543.5, 546.1, 555.0, 488.9, 432.0, 228.2,
+431.8, 226.0, 431.8, 226.0, 431.6, 223.8, 437.1, 213.6, 439.0, 212.2,
+438.3, 201.1, 439.1, 202.4, 440.2, 203.0, 439.9, 203.6, 439.3, 206.5,
+441.2, 208.2, 444.3, 210.5, 456.0, 216.4, 452.5, 223.3, 460.7, 236.1,
+464.0, 254.6, 453.1, 274.4, 455.8, 275.1, 438.7, 270.4, 443.2, 252.0,
+432.0, 228.2, 455.8, 275.1, 456.6, 276.9, 455.5, 277.4, 455.2, 279.7,
+456.2, 280.0, 451.1, 287.9, 453.6, 292.6, 452.4, 302.1, 456.5, 306.3,
+451.2, 311.6, 446.5, 307.6, 439.0, 307.9, 439.3, 306.7, 435.6, 267.5,
+435.6, 267.5, 432.0, 228.2, 443.2, 252.0, 438.7, 270.4, 455.8, 275.1,
+475.1, 258.7, 477.7, 262.6, 477.7, 262.6, 480.2, 266.5, 484.3, 278.3,
+485.4, 277.9, 490.6, 289.4, 492.5, 327.4, 487.6, 331.4, 503.0, 365.1,
+503.1, 368.1, 503.1, 368.1, 503.3, 371.1, 497.3, 363.5, 498.7, 362.4,
+494.1, 353.7, 486.4, 339.0, 486.4, 339.0, 478.6, 324.2, 472.6, 312.8,
+472.6, 312.8, 466.5, 301.3, 464.4, 300.7, 465.0, 298.4, 463.5, 295.5,
+467.3, 276.7, 465.7, 275.0, 475.1, 258.7, 463.5, 295.5, 459.3, 287.6,
+461.1, 281.5, 455.2, 279.7, 455.5, 277.4, 456.6, 276.9, 455.8, 275.1,
+453.1, 274.4, 464.0, 254.6, 460.7, 236.1, 464.6, 242.2, 463.1, 244.0,
+468.4, 248.2, 473.2, 250.8, 471.8, 253.4, 475.1, 258.7, 465.7, 275.0,
+467.3, 276.7, 463.5, 295.5, 494.1, 353.7, 498.7, 362.4, 497.3, 363.5,
+503.3, 371.1, 503.6, 377.8, 505.6, 383.9, 503.9, 384.4, 498.4, 392.8,
+504.5, 396.8, 505.1, 409.1, 486.1, 398.3, 484.5, 401.1, 463.9, 393.2,
+464.2, 393.4, 466.8, 389.5, 469.6, 385.7, 480.9, 370.9, 480.9, 370.9,
+492.2, 356.2, 493.2, 355.0, 494.4, 354.1, 494.1, 353.7, 185.8, 516.6,
+187.6, 526.3, 190.7, 525.7, 195.7, 534.8, 200.7, 544.0, 203.9, 543.4,
+205.8, 553.2, 204.0, 561.3, 204.0, 561.3, 202.3, 569.3, 189.3, 545.5,
+190.9, 543.6, 185.8, 516.6, 195.7, 534.8, 190.7, 525.7, 187.6, 526.3,
+185.8, 516.6, 179.3, 504.9, 178.5, 505.2, 172.9, 493.1, 173.3, 491.8,
+173.3, 491.8, 173.8, 490.6, 196.2, 478.0, 189.5, 466.0, 205.2, 441.3,
+222.8, 476.9, 207.3, 489.8, 195.7, 534.8, 418.3, 496.3, 419.3, 491.9,
+421.6, 491.2, 420.4, 487.6, 420.7, 486.1, 421.1, 486.1, 421.1, 484.6,
+419.4, 501.7, 421.0, 501.9, 420.8, 519.2, 421.1, 514.2, 420.3, 514.1,
+419.7, 509.1, 419.0, 502.7, 419.0, 502.7, 418.3, 496.4, 418.3, 496.3,
+418.3, 496.3, 418.3, 496.3, 412.4, 667.3, 410.4, 684.4, 413.1, 685.3,
+407.6, 701.4, 411.8, 689.1, 408.8, 688.1, 409.9, 674.8, 410.7, 664.7,
+410.7, 664.7, 411.6, 654.6, 415.4, 609.0, 415.4, 609.0, 419.2, 563.4,
+419.9, 555.0, 419.9, 555.0, 420.6, 546.5, 420.6, 543.2, 420.9, 543.2,
+421.2, 539.9, 417.4, 595.7, 417.3, 595.6, 413.5, 651.4, 413.0, 659.4,
+413.3, 659.4, 412.4, 667.3, 427.3, 776.5, 428.0, 780.3, 430.1, 779.9,
+433.0, 783.4, 446.6, 800.0, 455.1, 797.7, 460.2, 816.6, 457.1, 838.5,
+457.1, 838.5, 453.9, 860.5, 455.4, 855.6, 452.0, 854.6, 450.1, 848.6,
+444.2, 830.0, 444.2, 830.0, 438.3, 811.3, 432.8, 793.9, 430.7, 794.3,
+427.3, 776.5, 406.6, 883.8, 406.0, 882.6, 403.3, 884.1, 400.0, 884.0,
+374.4, 883.8, 374.2, 886.1, 348.9, 883.3, 349.2, 883.2, 348.7, 880.8,
+348.6, 878.3, 347.6, 869.7, 349.5, 869.5, 350.4, 860.7, 355.0, 857.9,
+358.6, 864.1, 366.8, 867.4, 382.6, 873.9, 382.6, 873.9, 398.3, 880.4,
+402.4, 882.1, 405.1, 880.8, 406.6, 883.8, 377.5, 209.4, 376.8, 204.7,
+376.0, 199.9, 376.1, 199.9, 392.8, 177.9, 393.6, 178.5, 409.4, 156.0,
+412.5, 160.9, 412.5, 160.9, 415.7, 165.8, 417.1, 167.5, 416.0, 168.4,
+416.3, 171.0, 416.3, 171.1, 416.1, 171.1, 416.0, 171.3, 413.9, 173.3,
+413.9, 173.3, 411.9, 175.4, 394.7, 192.4, 397.1, 195.9, 377.5, 209.4,
+225.8, 746.3, 226.0, 752.9, 224.7, 752.9, 223.6, 759.5, 217.9, 793.6,
+217.9, 793.6, 212.2, 827.7, 210.5, 838.1, 207.5, 838.4, 208.8, 848.4,
+208.5, 822.8, 203.1, 821.6, 208.2, 797.2, 209.2, 783.9, 213.3, 782.9,
+210.2, 770.6, 209.7, 770.5, 210.6, 767.8, 210.6, 764.9, 225.7, 716.7,
+214.3, 713.1, 218.1, 661.3, 217.9, 656.8, 219.4, 656.7, 220.8, 652.1,
+223.9, 661.3, 221.3, 662.2, 221.9, 672.3, 223.8, 709.3, 225.1, 709.3,
+225.8, 746.3, 377.7, 663.3, 378.7, 665.6, 378.0, 667.1, 376.3, 669.4,
+368.6, 667.1, 356.4, 681.9, 350.7, 699.0, 351.9, 697.8, 351.0, 696.9,
+351.3, 694.7, 360.6, 667.3, 356.5, 665.5, 358.8, 636.1, 359.1, 633.6,
+359.1, 633.6, 359.5, 631.2, 359.5, 631.2, 359.5, 631.2, 359.5, 631.2,
+368.6, 647.3, 370.4, 646.5, 377.7, 663.3, 365.6, 457.1, 389.9, 484.9,
+385.3, 491.1, 414.3, 512.8, 419.1, 522.3, 413.0, 527.4, 407.6, 540.2,
+407.7, 539.3, 405.6, 539.1, 403.6, 538.0, 401.5, 535.4, 402.1, 534.9,
+400.7, 531.7, 387.8, 504.4, 387.8, 504.4, 374.9, 477.0, 370.3, 467.0,
+373.1, 463.9, 365.6, 457.1, 396.0, 295.6, 405.7, 311.6, 405.7, 311.6,
+415.3, 327.6, 415.1, 326.1, 403.1, 330.3, 400.9, 326.8, 393.5, 314.7,
+398.5, 311.6, 396.1, 296.5, 396.1, 296.0, 396.2, 296.0, 396.0, 295.6,
+429.5, 402.8, 428.6, 401.2, 424.0, 404.3, 422.4, 402.4, 409.9, 388.2,
+410.4, 387.3, 401.3, 370.6, 404.8, 377.1, 406.3, 376.3, 411.3, 382.1,
+420.4, 392.5, 423.1, 391.0, 429.5, 402.8, 327.5, 317.9, 335.5, 300.7,
+341.6, 301.3, 343.5, 283.5, 344.7, 282.9, 350.0, 293.2, 356.4, 303.0,
+363.8, 314.1, 363.8, 314.1, 371.2, 325.2, 376.4, 333.1, 375.3, 339.9,
+381.6, 341.0, 353.4, 336.2, 341.1, 338.4, 327.5, 317.9, 413.7, 482.7,
+378.3, 457.0, 380.2, 454.0, 343.0, 431.2, 338.6, 427.9, 339.3, 427.0,
+335.5, 422.7, 331.6, 421.7, 332.3, 419.0, 329.1, 415.3, 342.3, 424.3,
+341.6, 425.3, 354.1, 435.3, 359.8, 439.8, 359.8, 439.8, 365.4, 444.3,
+366.7, 445.3, 366.7, 445.3, 367.9, 446.3, 390.8, 464.5, 388.8, 467.8,
+413.7, 482.7, 274.1, 435.0, 276.4, 430.3, 275.1, 429.0, 278.6, 425.7,
+278.7, 425.6, 278.7, 425.6, 278.7, 425.6, 268.4, 467.8, 268.3, 467.8,
+258.1, 510.1, 256.8, 515.4, 255.8, 520.7, 255.8, 520.7, 255.8, 520.7,
+256.8, 515.4, 258.1, 510.1, 259.6, 503.2, 259.6, 503.2, 261.0, 496.3,
+267.6, 465.7, 266.5, 465.4, 274.1, 435.0, 64.3, 245.5, 63.3, 243.2,
+63.3, 243.2, 62.3, 240.9, 69.8, 212.3, 64.6, 210.9, 66.9, 181.0,
+65.6, 193.9, 66.4, 193.9, 65.9, 206.9, 65.1, 226.2, 66.4, 226.4,
+64.3, 245.5, 43.9, 79.8, 44.0, 76.2, 43.5, 76.1, 44.2, 72.5,
+44.4, 71.7, 44.2, 70.8, 44.2, 70.8, 45.3, 66.2, 44.7, 65.8,
+46.8, 61.7, 46.6, 62.8, 47.2, 62.9, 47.6, 64.1, 46.3, 72.1,
+46.9, 72.5, 43.9, 79.8, 649.4, 530.7, 645.6, 524.9, 641.9, 519.1,
+641.9, 519.1, 639.7, 515.7, 639.7, 515.7, 637.5, 512.3, 637.5, 512.3,
+637.5, 512.3, 637.5, 512.3, 638.0, 511.3, 637.6, 511.1, 637.8, 510.0,
+652.4, 503.5, 652.8, 504.4, 667.8, 498.9, 677.4, 495.4, 677.4, 495.4,
+687.0, 491.8, 694.7, 489.0, 700.5, 484.1, 702.3, 486.2, 701.6, 497.2,
+701.6, 497.2, 700.8, 508.2, 698.8, 512.4, 695.2, 510.7, 689.5, 513.1,
+669.4, 521.9, 670.2, 528.0, 649.4, 530.7, 700.8, 471.3, 701.9, 472.8,
+701.9, 472.8, 703.1, 474.3, 703.5, 474.5, 703.0, 475.8, 702.9, 477.3,
+701.0, 474.9, 700.6, 474.2, 700.8, 471.3, 808.2, 400.0, 814.9, 404.7,
+820.1, 403.3, 821.7, 409.3, 859.1, 470.9, 856.4, 472.5, 890.9, 536.0,
+891.2, 536.4, 890.9, 536.6, 891.0, 537.3, 892.0, 543.8, 892.0, 543.8,
+893.0, 550.3, 848.4, 476.5, 847.1, 476.9, 808.2, 400.0, 893.0, 550.3,
+893.2, 551.5, 892.7, 551.8, 893.3, 552.6, 889.0, 549.7, 889.0, 549.7,
+884.7, 546.7, 880.9, 539.6, 880.0, 540.1, 875.4, 533.5, 862.6, 514.1,
+862.4, 514.2, 849.5, 494.8, 844.3, 485.5, 844.7, 485.2, 838.7, 476.3,
+814.6, 432.8, 819.3, 429.5, 790.5, 389.3, 790.0, 388.3, 790.0, 388.3,
+789.5, 387.2, 797.2, 395.2, 798.9, 393.6, 808.2, 400.0, 847.1, 476.9,
+848.4, 476.5, 893.0, 550.3, 731.1, 91.4, 720.8, 83.6, 721.9, 78.2,
+710.6, 75.9, 720.4, 73.8, 721.6, 76.1, 730.2, 71.7, 731.7, 69.2,
+734.5, 70.8, 738.7, 69.9, 741.7, 82.2, 756.8, 78.4, 775.0, 86.9,
+771.2, 83.6, 767.7, 87.7, 760.4, 88.4, 745.7, 89.9, 744.5, 94.7,
+731.1, 91.4, 782.2, 136.8, 788.0, 137.7, 788.0, 138.5, 793.9, 138.7,
+800.7, 141.9, 800.0, 143.3, 806.2, 148.0, 811.6, 152.0, 811.6, 152.0,
+816.9, 156.1, 818.5, 154.8, 822.6, 162.9, 829.8, 165.7, 834.0, 165.0,
+834.8, 169.5, 839.8, 173.3, 876.6, 201.0, 876.6, 201.0, 913.4, 228.8,
+918.1, 232.3, 918.0, 232.3, 922.7, 235.8, 925.8, 238.2, 925.8, 238.2,
+929.0, 240.6, 912.7, 229.3, 912.8, 229.1, 896.6, 217.7, 896.5, 217.6,
+896.4, 217.7, 896.3, 217.7, 858.2, 190.7, 858.3, 190.6, 820.2, 163.7,
+801.2, 150.2, 798.9, 152.6, 782.2, 136.8, 782.6, 330.9, 782.3, 332.4,
+782.8, 333.4, 782.0, 333.8, 780.3, 335.4, 782.3, 338.7, 780.8, 339.3,
+767.9, 345.5, 767.9, 345.5, 755.0, 351.7, 744.1, 349.8, 745.6, 341.5,
+736.2, 331.2, 736.2, 331.2, 730.1, 324.6, 724.0, 317.9, 748.1, 316.3,
+748.5, 323.3, 773.0, 328.8, 777.8, 329.9, 778.5, 328.6, 782.6, 330.9,
+578.7, 157.1, 578.3, 156.9, 578.1, 157.0, 578.0, 156.8, 567.2, 135.5,
+567.2, 135.5, 556.4, 114.1, 565.8, 120.1, 566.5, 119.0, 576.5, 124.0,
+581.7, 126.7, 581.8, 126.6, 587.0, 129.2, 596.9, 134.4, 596.9, 134.4,
+606.8, 139.6, 603.3, 151.5, 592.9, 148.5, 578.7, 157.1, 690.7, 281.6,
+697.1, 288.6, 697.1, 288.6, 703.6, 295.6, 710.4, 303.0, 710.4, 303.0,
+717.1, 310.4, 720.6, 314.2, 720.6, 314.2, 724.0, 317.9, 730.1, 324.6,
+736.2, 331.2, 736.2, 331.2, 745.6, 341.5, 744.1, 349.8, 755.0, 351.7,
+750.9, 353.7, 750.9, 353.7, 746.8, 355.7, 734.4, 346.0, 737.0, 342.8,
+727.2, 329.8, 708.9, 305.7, 707.9, 306.5, 690.7, 281.6, 645.4, 281.4,
+639.4, 274.1, 639.4, 274.1, 633.4, 266.7, 624.4, 257.5, 629.3, 253.2,
+621.3, 242.7, 617.0, 239.1, 618.6, 237.3, 615.8, 231.9, 631.1, 256.4,
+632.5, 255.7, 645.4, 281.4, 695.4, 173.0, 681.8, 158.3, 682.3, 157.8,
+668.3, 143.7, 666.0, 142.0, 666.3, 141.5, 664.3, 139.4, 666.5, 141.3,
+666.8, 140.9, 669.2, 142.5, 711.0, 169.1, 716.3, 163.2, 752.8, 195.8,
+753.2, 196.1, 753.4, 195.9, 753.8, 196.2, 758.2, 199.1, 758.1, 199.2,
+762.5, 202.3, 764.9, 203.9, 764.9, 203.8, 767.2, 205.4, 768.4, 206.2,
+768.4, 206.2, 769.5, 207.0, 732.3, 190.2, 729.6, 194.5, 695.4, 173.0,
+769.5, 207.0, 794.8, 224.5, 794.8, 224.5, 820.2, 241.9, 812.5, 238.1,
+810.9, 240.7, 804.0, 236.0, 757.7, 213.1, 757.7, 213.1, 711.3, 190.3,
+709.2, 189.3, 709.9, 187.9, 707.8, 186.5, 707.8, 186.6, 701.6, 179.8,
+695.4, 173.0, 729.6, 194.5, 732.3, 190.2, 769.5, 207.0, 574.2, 109.7,
+572.5, 108.7, 572.4, 108.8, 570.7, 107.6, 569.7, 106.9, 569.6, 106.1,
+568.7, 106.2, 569.2, 106.1, 569.2, 106.1, 569.8, 106.0, 572.2, 107.5,
+572.8, 107.4, 574.2, 109.7, 538.5, 212.0, 511.4, 202.2, 511.4, 202.2,
+484.2, 192.4, 483.2, 193.7, 468.9, 182.5, 453.6, 172.7, 477.3, 175.2,
+476.5, 183.3, 499.3, 193.9, 505.2, 196.6, 505.2, 196.6, 511.1, 199.4,
+524.8, 205.7, 524.1, 208.3, 538.5, 212.0, 480.4, 35.4, 492.4, 20.0,
+492.4, 20.0, 504.3, 4.5, 503.8, 5.4, 504.9, 6.1, 505.4, 7.7,
+500.4, 15.2, 499.3, 14.5, 493.2, 21.2, 486.8, 28.3, 485.7, 27.5,
+480.4, 35.4, 413.7, 132.6, 409.4, 132.7, 408.4, 130.9, 405.1, 132.7,
+406.3, 131.1, 406.3, 131.1, 407.5, 129.4, 427.1, 106.7, 425.9, 105.7,
+444.3, 82.0, 453.8, 73.5, 465.3, 82.3, 470.6, 73.3, 450.2, 107.6,
+442.5, 103.1, 414.2, 132.6, 414.0, 132.6, 414.0, 132.6, 413.7, 132.6,
+470.6, 73.3, 480.3, 65.3, 491.4, 73.5, 496.1, 64.9, 470.4, 92.8,
+470.4, 92.8, 444.8, 120.8, 428.9, 123.9, 424.2, 121.8, 414.2, 132.6,
+414.0, 132.6, 414.0, 132.6, 413.7, 132.6, 442.0, 102.8, 439.1, 99.2,
+470.6, 73.3, 578.5, 1.0, 573.7, -6.8, 567.4, -13.1, 568.9, -14.7,
+569.8, -17.4, 571.5, -18.3, 570.6, -20.1, 568.1, -21.8, 573.8, -30.5,
+577.0, -41.0, 574.6, -40.2, 577.3, -31.7, 577.7, -22.4, 578.1, -10.7,
+584.0, -3.9, 578.5, 1.0, 240.9, 156.3, 240.3, 155.6, 239.5, 155.4,
+239.6, 154.9, 248.0, 118.7, 248.0, 118.7, 256.4, 82.5, 253.0, 96.4,
+253.5, 96.5, 250.6, 110.4, 245.7, 133.4, 246.6, 133.6, 240.9, 156.3,
+254.9, 243.8, 255.7, 242.2, 250.0, 239.5, 245.2, 235.3, 235.1, 226.5,
+234.7, 226.9, 225.0, 217.7, 225.1, 217.0, 225.1, 217.0, 225.3, 216.3,
+226.0, 217.1, 248.9, 202.2, 265.1, 182.1, 266.6, 180.8, 266.6, 180.8,
+268.0, 179.5, 268.3, 176.5, 271.1, 176.8, 274.3, 174.1, 267.1, 209.5,
+270.2, 211.6, 254.9, 243.8, 274.3, 174.1, 280.3, 169.0, 280.3, 169.0,
+286.3, 163.8, 286.7, 162.2, 291.1, 164.4, 293.7, 162.2, 289.7, 178.2,
+281.7, 180.7, 285.8, 194.3, 287.8, 196.8, 281.7, 200.4, 283.1, 204.9,
+269.4, 209.6, 276.7, 231.0, 270.2, 257.1, 270.8, 256.4, 254.6, 250.1,
+254.9, 243.8, 270.2, 211.6, 267.1, 209.5, 274.3, 174.1, 245.2, 235.3,
+250.0, 239.5, 255.7, 242.2, 254.9, 243.8, 254.6, 250.1, 270.8, 256.4,
+270.2, 257.1, 266.8, 270.9, 262.5, 271.2, 263.4, 284.6, 260.9, 283.4,
+260.9, 283.4, 258.3, 282.1, 252.2, 279.3, 252.4, 278.8, 246.4, 275.6,
+241.1, 256.7, 240.2, 253.9, 245.2, 235.3, 246.4, 275.6, 230.9, 267.1,
+231.4, 266.1, 215.5, 258.6, 220.2, 238.1, 220.2, 238.1, 225.0, 217.7,
+234.7, 226.9, 235.1, 226.5, 245.2, 235.3, 240.2, 253.9, 241.1, 256.7,
+246.4, 275.6, 357.1, 144.7, 357.5, 151.5, 356.2, 151.9, 358.0, 158.3,
+344.2, 177.1, 356.5, 189.2, 361.9, 218.8, 361.3, 219.5, 361.3, 219.5,
+360.7, 220.3, 355.7, 209.1, 352.7, 208.9, 352.1, 197.2, 350.9, 171.1,
+353.2, 170.7, 357.1, 144.7, 310.9, 158.1, 306.2, 144.2, 302.9, 144.6,
+301.6, 130.4, 301.6, 130.4, 301.5, 130.3, 301.5, 130.3, 301.9, 127.8,
+300.6, 127.6, 299.7, 125.0, 298.3, 122.7, 302.5, 120.1, 305.2, 115.3,
+310.9, 124.6, 306.7, 127.1, 308.3, 138.9, 309.6, 148.5, 305.7, 151.6,
+310.9, 158.1, 309.4, 53.8, 303.3, 55.2, 297.3, 55.1, 297.3, 56.6,
+292.3, 52.8, 282.4, 55.0, 278.3, 61.0, 273.9, 47.9, 275.0, 35.4,
+269.6, 34.9, 270.1, 33.0, 270.1, 33.0, 270.6, 31.1, 271.6, 29.7,
+271.6, 29.7, 272.6, 28.3, 291.9, 39.5, 295.2, 37.4, 309.4, 53.8,
+272.6, 28.3, 281.5, 15.3, 281.5, 15.3, 290.4, 2.4, 306.7, 25.1,
+311.9, 21.3, 333.5, 40.1, 330.6, 42.5, 329.4, 47.0, 331.0, 48.8,
+320.2, 51.3, 320.2, 51.3, 309.4, 53.8, 295.2, 37.4, 291.9, 39.5,
+272.6, 28.3, 263.4, 293.9, 267.9, 291.5, 272.4, 291.5, 272.4, 289.1,
+272.6, 289.1, 272.7, 289.2, 272.7, 289.2, 272.7, 289.1, 273.2, 289.5,
+273.8, 289.7, 269.1, 295.9, 277.3, 306.1, 286.0, 318.8, 284.3, 320.9,
+284.3, 320.9, 282.5, 323.1, 275.2, 330.1, 274.9, 329.8, 267.3, 336.5,
+265.5, 338.1, 265.4, 339.8, 263.7, 339.6, 263.6, 339.6, 263.7, 337.9,
+263.7, 336.2, 263.6, 315.1, 259.6, 314.3, 263.4, 293.9, 153.1, 461.8,
+164.8, 441.2, 168.2, 442.5, 176.4, 420.6, 176.4, 416.5, 178.7, 416.5,
+181.0, 412.4, 186.9, 405.9, 190.4, 408.1, 194.2, 400.8, 180.4, 426.9,
+177.6, 425.5, 161.0, 450.1, 157.1, 456.0, 156.4, 455.6, 153.1, 461.8,
+149.5, 388.3, 147.8, 368.2, 147.8, 368.2, 146.0, 348.1, 150.8, 329.2,
+150.0, 329.0, 154.0, 309.9, 158.2, 344.5, 152.0, 345.3, 150.0, 380.7,
+149.8, 384.5, 149.1, 384.6, 149.5, 388.3, 488.6, 852.4, 490.1, 864.3,
+489.4, 864.4, 491.6, 876.2, 491.8, 878.8, 490.7, 880.5, 492.0, 881.3,
+484.3, 884.0, 483.2, 883.3, 474.9, 881.8, 475.7, 881.1, 474.8, 880.1,
+474.7, 878.3, 473.9, 865.1, 467.8, 861.9, 473.1, 852.0, 474.8, 848.9,
+485.7, 848.5, 488.6, 852.4, 473.1, 852.0, 460.8, 773.6, 466.9, 772.5,
+463.6, 692.9, 466.0, 687.8, 466.3, 687.2, 466.1, 681.7, 466.6, 682.9,
+466.6, 682.9, 467.1, 684.1, 461.8, 693.8, 469.0, 697.8, 470.8, 711.5,
+474.2, 737.2, 474.2, 737.2, 477.6, 762.9, 477.9, 765.2, 477.9, 765.3,
+478.2, 767.6, 483.4, 810.0, 483.4, 810.0, 488.6, 852.4, 485.7, 848.5,
+474.8, 848.9, 473.1, 852.0, 580.6, 496.9, 580.8, 495.0, 576.3, 494.4,
+572.1, 491.9, 568.0, 489.5, 564.1, 489.9, 563.8, 487.0, 566.6, 477.0,
+566.8, 467.0, 569.4, 467.1, 572.1, 457.2, 568.4, 453.0, 574.9, 447.3,
+572.0, 449.9, 575.7, 454.1, 576.4, 460.9, 578.5, 478.9, 583.0, 479.5,
+580.6, 496.9, 570.5, 776.6, 568.1, 777.6, 568.6, 778.9, 566.7, 781.1,
+553.8, 796.7, 553.8, 796.7, 540.9, 812.3, 525.4, 830.9, 521.3, 851.8,
+510.0, 849.6, 512.6, 828.3, 512.6, 828.3, 515.2, 807.1, 515.6, 805.4,
+517.5, 805.8, 519.9, 804.5, 533.1, 797.2, 533.1, 797.2, 546.4, 789.9,
+558.4, 783.3, 557.9, 782.0, 570.5, 776.6, 538.4, 619.0, 540.1, 605.1,
+540.1, 605.1, 541.9, 591.3, 541.1, 592.1, 553.2, 598.7, 552.4, 604.6,
+551.4, 612.5, 537.6, 618.0, 538.4, 619.0, 476.1, 608.4, 475.7, 614.6,
+466.7, 616.9, 468.3, 620.3, 469.2, 607.8, 469.2, 607.8, 470.1, 595.2,
+468.0, 598.4, 476.6, 602.1, 476.1, 608.4, 470.1, 595.2, 472.3, 563.6,
+472.3, 563.6, 474.6, 531.9, 475.4, 529.7, 486.1, 528.4, 491.4, 532.6,
+488.9, 543.1, 496.5, 551.7, 508.7, 559.0, 503.3, 585.9, 497.1, 588.7,
+476.1, 608.4, 476.6, 602.1, 468.0, 598.4, 470.1, 595.2, 549.3, 443.3,
+563.3, 440.9, 563.8, 442.5, 577.4, 438.4, 576.8, 438.4, 576.1, 442.9,
+574.9, 447.3, 568.4, 453.0, 572.1, 457.2, 569.4, 467.1, 563.1, 466.9,
+562.9, 477.0, 556.3, 486.9, 544.2, 472.5, 552.8, 465.2, 549.3, 443.5,
+549.3, 443.4, 549.3, 443.3, 549.3, 443.3, 516.5, 550.4, 517.0, 557.6,
+517.0, 557.6, 517.5, 564.7, 517.6, 565.4, 517.1, 566.1, 517.0, 566.1,
+516.8, 566.1, 517.0, 565.3, 517.0, 564.6, 516.7, 557.5, 518.6, 551.0,
+516.5, 550.4, 474.2, 687.1, 474.0, 684.3, 473.9, 684.3, 473.7, 681.5,
+492.4, 628.3, 493.5, 628.7, 513.3, 575.9, 514.3, 573.4, 514.3, 573.5,
+515.2, 571.0, 505.3, 599.1, 505.3, 599.1, 495.3, 627.2, 484.8, 657.2,
+485.9, 657.6, 474.2, 687.1, 450.6, 316.3, 450.9, 313.9, 452.2, 312.4,
+451.2, 311.6, 456.5, 306.3, 452.4, 302.1, 453.6, 292.6, 456.8, 298.7,
+459.4, 299.2, 466.5, 301.3, 472.6, 312.8, 472.6, 312.8, 478.6, 324.2,
+478.7, 323.4, 471.0, 322.1, 463.3, 319.9, 461.5, 319.4, 461.5, 319.4,
+459.7, 318.9, 458.1, 318.4, 458.1, 318.4, 456.6, 318.0, 453.6, 317.2,
+452.2, 318.3, 450.6, 316.3, 193.0, 612.6, 191.5, 619.8, 193.1, 620.6,
+189.9, 626.9, 187.0, 635.3, 187.0, 635.3, 184.0, 643.8, 184.3, 642.6,
+183.1, 642.3, 182.2, 640.8, 182.7, 636.7, 183.7, 636.8, 185.3, 632.9,
+188.4, 624.7, 188.4, 624.7, 191.5, 616.5, 192.3, 614.5, 192.7, 614.6,
+193.0, 612.6, 219.0, 424.9, 221.4, 447.0, 233.1, 461.9, 223.8, 469.2,
+218.1, 495.7, 218.1, 495.7, 212.4, 522.3, 207.3, 474.5, 208.9, 472.1,
+219.0, 424.9, 212.4, 522.3, 209.1, 537.8, 209.1, 537.8, 205.8, 553.2,
+203.9, 543.4, 200.7, 544.0, 195.7, 534.8, 207.3, 489.8, 222.8, 476.9,
+205.2, 441.3, 211.9, 430.8, 211.9, 430.8, 218.5, 420.3, 217.7, 422.0,
+218.8, 422.6, 219.0, 424.9, 208.9, 472.1, 207.3, 474.5, 212.4, 522.3,
+461.7, 734.0, 463.2, 759.7, 463.1, 759.8, 464.7, 785.5, 462.5, 801.0,
+462.5, 801.0, 460.2, 816.6, 455.1, 797.7, 446.6, 800.0, 433.0, 783.4,
+430.7, 774.5, 439.5, 772.2, 446.0, 761.1, 450.1, 753.9, 450.1, 753.9,
+454.2, 746.8, 458.0, 740.4, 463.1, 739.0, 461.7, 734.0, 447.6, 495.3,
+448.0, 501.2, 447.9, 501.2, 448.3, 507.2, 450.3, 533.5, 449.9, 533.5,
+451.5, 559.9, 451.9, 567.7, 451.9, 567.7, 452.4, 575.5, 451.9, 567.7,
+451.9, 567.7, 451.5, 559.9, 449.9, 533.5, 450.3, 533.5, 448.3, 507.2,
+447.9, 501.2, 448.0, 501.2, 447.6, 495.3, 413.5, 651.4, 420.1, 608.0,
+416.2, 607.4, 419.2, 563.4, 419.9, 555.0, 419.9, 555.0, 420.6, 546.5,
+420.6, 543.2, 420.9, 543.2, 421.2, 539.9, 424.7, 497.4, 425.3, 497.4,
+428.3, 454.9, 429.0, 448.0, 429.9, 448.1, 431.6, 441.3, 431.6, 441.3,
+431.6, 441.3, 431.6, 441.3, 436.2, 422.4, 436.2, 422.4, 440.8, 403.5,
+441.3, 401.3, 442.4, 401.0, 441.8, 399.1, 442.2, 404.5, 442.2, 404.5,
+442.5, 409.9, 428.9, 530.8, 431.7, 531.2, 413.5, 651.4, 442.5, 409.9,
+443.4, 424.6, 443.4, 424.6, 444.3, 439.3, 444.3, 445.8, 443.4, 445.8,
+442.5, 452.2, 432.1, 526.1, 432.1, 526.1, 421.8, 600.0, 417.1, 633.6,
+417.8, 633.8, 412.4, 667.3, 413.3, 659.4, 413.0, 659.4, 413.5, 651.4,
+431.7, 531.2, 428.9, 530.8, 442.5, 409.9, 383.3, 722.9, 393.5, 735.4,
+396.2, 749.3, 403.8, 747.8, 409.1, 754.3, 409.1, 754.3, 414.4, 760.8,
+416.7, 763.5, 416.7, 763.5, 418.9, 766.3, 423.1, 771.4, 424.8, 770.6,
+427.3, 776.5, 434.5, 793.1, 432.8, 793.9, 438.3, 811.2, 438.3, 811.3,
+438.3, 811.3, 438.3, 811.3, 438.3, 811.3, 438.3, 811.3, 438.3, 811.2,
+420.6, 782.9, 420.6, 782.9, 403.0, 754.5, 393.1, 738.7, 381.6, 737.4,
+383.3, 722.9, 366.8, 867.4, 358.6, 864.1, 355.0, 857.9, 350.4, 860.7,
+354.5, 820.5, 354.5, 820.5, 358.6, 780.4, 359.1, 775.3, 359.2, 775.3,
+359.7, 770.2, 363.7, 811.1, 362.7, 811.2, 365.7, 852.2, 366.3, 859.8,
+369.6, 865.9, 366.8, 867.4, 377.8, 211.3, 377.6, 210.3, 377.6, 210.3,
+377.5, 209.4, 397.1, 195.9, 394.7, 192.4, 411.9, 175.4, 400.3, 185.7,
+401.1, 186.7, 390.4, 198.0, 389.4, 199.1, 389.4, 199.1, 388.3, 200.2,
+383.0, 205.7, 383.6, 206.3, 377.8, 211.3, 239.8, 662.8, 239.0, 701.7,
+233.3, 701.6, 226.8, 740.4, 226.3, 743.4, 225.6, 743.4, 225.8, 746.3,
+225.1, 709.3, 223.8, 709.3, 221.9, 672.3, 221.9, 670.5, 225.1, 670.6,
+228.3, 668.9, 234.0, 665.8, 239.7, 665.9, 239.8, 662.8, 223.6, 759.5,
+224.7, 752.9, 226.0, 752.9, 225.8, 746.3, 225.6, 743.4, 226.3, 743.4,
+226.8, 740.4, 243.2, 724.1, 244.4, 725.4, 262.0, 710.4, 263.0, 709.5,
+263.0, 709.5, 264.0, 708.7, 312.0, 667.8, 311.7, 667.4, 360.0, 626.8,
+359.6, 627.2, 360.2, 627.9, 359.8, 628.3, 353.5, 635.0, 353.1, 634.7,
+346.4, 641.2, 315.7, 670.8, 315.7, 670.8, 284.9, 700.5, 262.0, 722.6,
+262.0, 722.6, 239.0, 744.7, 237.6, 746.0, 237.6, 746.0, 236.2, 747.4,
+229.9, 753.5, 229.3, 760.1, 223.6, 759.5, 285.2, 852.2, 296.7, 804.1,
+297.5, 803.6, 317.2, 758.2, 316.2, 760.6, 323.3, 763.1, 322.6, 766.3,
+318.0, 785.6, 314.5, 784.8, 306.5, 803.3, 295.8, 827.8, 291.3, 826.7,
+285.2, 852.2, 349.9, 662.3, 350.7, 654.7, 355.3, 654.7, 355.0, 647.4,
+352.0, 670.9, 358.7, 672.9, 351.3, 694.7, 351.0, 696.9, 351.9, 697.8,
+350.7, 699.0, 338.7, 735.0, 345.8, 737.4, 340.8, 775.8, 339.6, 719.2,
+343.7, 718.9, 349.9, 662.3, 340.8, 775.8, 339.9, 783.2, 339.9, 783.2,
+338.9, 790.7, 327.5, 784.7, 330.7, 778.5, 322.6, 766.3, 323.3, 763.1,
+316.2, 760.6, 317.2, 758.2, 319.6, 741.4, 322.8, 741.8, 328.4, 725.4,
+338.4, 696.1, 338.4, 696.1, 348.4, 666.8, 349.1, 664.5, 349.7, 664.6,
+349.9, 662.3, 343.7, 718.9, 339.6, 719.2, 340.8, 775.8, 385.0, 633.5,
+387.8, 636.1, 383.1, 641.1, 381.3, 648.8, 380.1, 653.4, 380.1, 653.4,
+379.0, 658.0, 378.4, 660.7, 376.7, 661.9, 377.7, 663.3, 370.4, 646.5,
+368.6, 647.3, 359.5, 631.2, 359.8, 632.0, 361.1, 631.4, 362.7, 631.5,
+373.8, 632.5, 378.5, 627.5, 385.0, 633.5, 400.7, 531.7, 402.1, 534.9,
+401.5, 535.4, 403.6, 538.0, 403.4, 537.8, 403.4, 537.8, 403.2, 537.7,
+357.2, 510.5, 356.8, 511.0, 310.5, 484.3, 343.2, 510.4, 348.2, 504.2,
+386.0, 524.0, 393.3, 527.9, 394.3, 526.7, 400.7, 531.7, 356.4, 303.0,
+350.0, 293.2, 344.7, 282.9, 343.5, 283.5, 344.3, 276.1, 338.5, 275.2,
+332.8, 267.4, 335.2, 259.1, 340.4, 253.4, 337.6, 250.9, 339.1, 248.9,
+340.9, 248.6, 340.6, 246.9, 340.1, 246.3, 343.2, 243.5, 345.7, 240.1,
+353.6, 266.3, 350.3, 267.3, 355.0, 294.4, 355.7, 298.7, 353.9, 300.6,
+356.4, 303.0, 384.0, 325.9, 390.1, 329.9, 392.4, 326.4, 400.9, 326.8,
+403.1, 330.3, 415.1, 326.1, 415.3, 327.6, 419.6, 334.6, 419.6, 334.6,
+423.8, 341.6, 403.5, 340.5, 401.6, 337.3, 384.0, 325.9, 354.1, 435.3,
+341.6, 425.3, 342.3, 424.3, 329.1, 415.3, 326.5, 412.4, 326.5, 412.4,
+324.0, 409.5, 332.6, 410.0, 335.1, 405.5, 342.0, 397.7, 367.3, 394.6,
+370.0, 392.8, 393.7, 400.8, 390.0, 399.5, 387.8, 405.9, 381.9, 411.1,
+368.0, 423.2, 368.9, 434.1, 354.1, 435.3, 272.8, 437.6, 273.4, 436.3,
+273.4, 436.3, 274.1, 435.0, 268.9, 461.0, 268.4, 460.9, 262.9, 486.8,
+261.9, 491.5, 261.0, 496.3, 261.0, 496.3, 261.0, 496.3, 261.9, 491.5,
+262.9, 486.8, 267.9, 462.2, 267.5, 462.1, 272.8, 437.6, 67.4, 175.0,
+67.4, 174.8, 67.4, 174.8, 67.4, 174.6, 69.5, 163.5, 68.3, 163.3,
+69.2, 152.0, 70.3, 157.7, 73.0, 157.2, 76.7, 162.3, 87.0, 209.4,
+89.9, 208.8, 103.2, 255.3, 115.4, 232.0, 85.9, 216.5, 68.6, 177.8,
+68.0, 176.4, 67.9, 176.4, 67.4, 175.0, 60.2, 159.3, 61.6, 171.9,
+66.0, 173.1, 63.0, 184.6, 63.0, 185.0, 63.2, 185.1, 63.0, 185.5,
+63.0, 185.5, 63.0, 185.5, 63.0, 185.6, 65.5, 192.5, 53.0, 194.9,
+48.4, 206.4, 44.4, 195.3, 38.1, 193.9, 40.3, 184.2, 41.9, 137.6,
+41.9, 137.6, 43.5, 91.0, 30.1, 107.8, 53.0, 124.9, 60.2, 159.3,
+43.5, 91.0, 43.7, 85.4, 43.7, 85.4, 43.9, 79.8, 46.9, 72.5,
+46.3, 72.1, 47.6, 64.1, 49.1, 68.4, 49.1, 68.4, 50.5, 72.6,
+53.3, 116.1, 55.4, 116.0, 60.2, 159.3, 53.0, 124.9, 30.1, 107.8,
+43.5, 91.0, 681.0, 569.7, 678.1, 569.9, 678.1, 569.9, 675.1, 570.2,
+666.1, 555.9, 665.9, 556.0, 656.7, 541.9, 658.6, 545.0, 659.2, 544.7,
+661.6, 547.5, 671.3, 558.6, 673.6, 557.2, 681.0, 569.7, 641.5, 479.0,
+641.5, 479.0, 641.5, 479.0, 641.6, 478.9, 639.0, 466.5, 650.4, 464.2,
+659.2, 449.5, 665.3, 457.3, 683.8, 457.8, 686.6, 453.1, 689.2, 456.4,
+689.2, 456.4, 691.8, 459.8, 668.7, 472.9, 666.6, 469.3, 641.6, 478.9,
+641.5, 479.0, 641.5, 479.0, 641.5, 479.0, 791.8, 137.2, 766.4, 118.0,
+768.4, 102.3, 740.9, 98.7, 740.1, 98.2, 740.1, 98.2, 739.3, 97.6,
+735.9, 98.2, 735.2, 94.5, 731.1, 91.4, 744.5, 94.7, 745.7, 89.9,
+760.4, 88.4, 777.7, 99.6, 772.6, 107.4, 784.9, 126.3, 788.4, 131.7,
+786.9, 134.1, 791.8, 137.2, 796.7, 204.0, 801.9, 215.2, 799.9, 216.7,
+807.2, 226.4, 792.9, 218.3, 792.9, 218.3, 778.7, 210.2, 772.5, 209.7,
+774.3, 201.8, 767.4, 197.3, 758.0, 193.0, 759.9, 188.8, 752.5, 180.3,
+776.1, 185.6, 777.9, 188.2, 796.7, 204.0, 752.5, 180.3, 747.3, 174.3,
+748.6, 172.2, 742.1, 168.4, 741.1, 167.9, 741.3, 167.5, 740.5, 166.5,
+752.1, 153.2, 750.4, 148.0, 765.4, 141.4, 766.1, 141.1, 768.7, 147.1,
+772.0, 152.8, 773.5, 155.3, 773.6, 155.2, 774.9, 157.7, 789.9, 177.8,
+785.8, 180.8, 796.7, 204.0, 777.9, 188.2, 776.1, 185.6, 752.5, 180.3,
+700.8, 121.1, 692.8, 111.8, 692.8, 111.8, 684.7, 102.6, 687.4, 102.5,
+689.7, 98.8, 689.9, 99.1, 714.6, 98.4, 715.3, 102.1, 739.3, 97.6,
+740.1, 98.2, 740.1, 98.2, 740.9, 98.7, 752.8, 100.3, 746.8, 120.3,
+760.7, 133.2, 761.0, 133.7, 760.9, 134.2, 761.4, 134.3, 731.0, 128.2,
+729.0, 132.7, 700.8, 121.1, 761.4, 134.3, 764.2, 135.2, 766.5, 139.8,
+765.4, 141.4, 750.4, 148.0, 752.1, 153.2, 740.5, 166.5, 723.1, 146.6,
+727.5, 138.7, 705.7, 126.7, 702.9, 126.2, 703.3, 123.9, 700.8, 121.1,
+729.0, 132.7, 731.0, 128.2, 761.4, 134.3, 583.1, 158.4, 580.9, 157.7,
+580.9, 157.7, 578.7, 157.1, 592.9, 148.5, 603.3, 151.5, 606.8, 139.6,
+632.0, 152.8, 632.0, 152.8, 657.2, 166.0, 636.3, 182.6, 620.1, 162.6,
+583.1, 158.4, 657.2, 166.0, 673.1, 174.3, 673.1, 174.3, 689.0, 182.7,
+693.0, 183.9, 691.0, 188.6, 695.0, 192.2, 690.8, 194.8, 687.8, 190.0,
+680.7, 187.9, 666.8, 183.7, 666.8, 183.7, 653.0, 179.5, 623.6, 160.4,
+618.0, 168.9, 583.1, 158.4, 620.1, 162.6, 636.3, 182.6, 657.2, 166.0,
+733.6, 362.1, 732.7, 362.5, 732.7, 362.5, 731.8, 362.9, 690.2, 300.2,
+690.1, 300.2, 645.8, 239.4, 637.4, 227.1, 637.8, 226.9, 629.3, 214.7,
+628.1, 213.3, 628.0, 213.3, 626.8, 212.0, 626.8, 212.0, 626.8, 212.0,
+626.8, 212.0, 632.4, 218.1, 632.4, 218.1, 638.0, 224.2, 638.4, 224.6,
+638.4, 224.6, 638.7, 224.9, 645.6, 232.5, 645.6, 232.5, 652.5, 240.0,
+665.2, 253.8, 665.2, 253.8, 677.8, 267.5, 681.5, 271.6, 681.5, 271.6,
+685.2, 275.6, 685.8, 276.2, 685.8, 276.2, 686.3, 276.8, 688.5, 279.2,
+688.5, 279.2, 690.7, 281.6, 707.9, 306.5, 708.9, 305.7, 727.2, 329.8,
+734.6, 343.7, 731.3, 345.8, 733.6, 362.1, 727.2, 329.8, 737.0, 342.8,
+734.4, 346.0, 746.8, 355.7, 740.2, 358.9, 740.2, 358.9, 733.6, 362.1,
+731.3, 345.8, 734.6, 343.7, 727.2, 329.8, 706.4, 330.7, 717.6, 347.6,
+716.2, 348.6, 728.7, 364.4, 725.4, 366.0, 725.4, 366.0, 722.0, 367.6,
+721.7, 367.9, 720.8, 365.9, 719.2, 365.0, 705.9, 360.5, 707.9, 354.5,
+696.7, 344.0, 687.0, 328.8, 685.1, 330.0, 673.6, 315.9, 675.5, 321.6,
+681.7, 319.5, 689.7, 323.2, 698.1, 326.9, 700.6, 324.6, 706.4, 330.7,
+668.8, 149.5, 679.7, 163.4, 677.9, 165.3, 690.7, 177.3, 674.4, 168.6,
+674.4, 168.6, 658.2, 159.9, 637.3, 162.6, 635.2, 146.2, 612.2, 132.4,
+622.3, 122.5, 643.8, 135.2, 668.8, 149.5, 540.0, 203.6, 544.8, 209.8,
+544.8, 209.8, 549.5, 216.0, 545.7, 212.3, 544.0, 214.0, 538.5, 212.0,
+524.1, 208.3, 524.8, 205.7, 511.1, 199.4, 515.0, 201.9, 516.3, 200.1,
+521.4, 200.9, 530.7, 202.2, 532.3, 199.4, 540.0, 203.6, 493.2, 21.2,
+499.3, 14.5, 500.4, 15.2, 505.4, 7.7, 510.5, 23.9, 510.5, 23.9,
+515.6, 40.0, 515.2, 40.4, 496.9, 33.0, 493.2, 21.2, 515.6, 40.0,
+516.0, 41.4, 516.9, 42.3, 516.5, 42.7, 506.3, 53.8, 506.3, 53.8,
+496.1, 64.9, 491.4, 73.5, 480.3, 65.3, 470.6, 73.3, 465.3, 82.3,
+453.8, 73.5, 444.3, 82.0, 462.3, 58.7, 462.3, 58.7, 480.4, 35.4,
+485.7, 27.5, 486.8, 28.3, 493.2, 21.2, 496.9, 33.0, 515.2, 40.4,
+515.6, 40.0, 587.3, -74.6, 589.1, -80.4, 589.5, -86.3, 590.9, -86.2,
+592.6, -88.4, 597.0, -86.2, 597.6, -88.0, 595.3, -80.4, 593.8, -76.3,
+587.3, -74.6, 279.7, 73.4, 281.6, 75.0, 283.3, 74.8, 283.5, 76.5,
+283.8, 77.5, 283.8, 77.5, 284.2, 78.5, 274.2, 128.6, 273.3, 128.7,
+268.0, 179.5, 266.6, 180.8, 266.6, 180.8, 265.1, 182.1, 265.5, 181.5,
+261.8, 178.5, 258.5, 175.0, 257.9, 162.7, 261.1, 162.6, 263.7, 150.1,
+265.7, 140.4, 265.7, 140.4, 267.7, 130.7, 273.7, 102.0, 271.5, 101.4,
+279.7, 73.4, 353.9, 96.6, 354.4, 104.1, 352.6, 104.8, 354.9, 111.6,
+355.4, 111.8, 354.4, 113.6, 355.1, 114.2, 353.0, 126.2, 350.2, 134.3,
+356.7, 139.2, 357.2, 139.2, 356.9, 141.9, 357.1, 144.7, 353.2, 170.7,
+350.9, 171.1, 352.1, 197.2, 352.7, 194.0, 350.3, 193.8, 349.5, 190.1,
+349.1, 188.4, 349.6, 188.2, 349.7, 186.4, 350.0, 180.1, 350.0, 180.1,
+350.3, 173.8, 352.1, 135.2, 351.1, 135.1, 353.9, 96.6, 336.8, 156.0,
+346.6, 170.8, 343.1, 173.1, 349.5, 190.1, 350.3, 193.8, 352.7, 194.0,
+352.1, 197.2, 352.7, 208.9, 355.7, 209.1, 360.7, 220.3, 357.9, 224.1,
+354.1, 225.8, 355.0, 227.9, 354.5, 228.5, 354.5, 229.1, 354.1, 229.1,
+349.0, 223.4, 336.9, 222.5, 333.8, 226.6, 331.8, 220.7, 331.8, 220.7,
+329.9, 214.9, 330.5, 191.8, 332.6, 191.9, 335.3, 168.8, 336.0, 162.4,
+339.5, 160.1, 336.8, 156.0, 197.4, 398.0, 197.4, 397.9, 195.8, 399.4,
+194.2, 400.8, 190.4, 408.1, 186.9, 405.9, 181.0, 412.4, 185.5, 404.4,
+185.5, 404.4, 190.1, 396.4, 191.7, 394.9, 195.3, 395.7, 197.4, 398.0,
+267.3, 336.5, 274.9, 329.8, 275.2, 330.1, 282.5, 323.1, 243.4, 371.5,
+243.4, 371.5, 204.3, 420.0, 173.8, 423.9, 175.8, 445.4, 149.2, 472.6,
+150.9, 467.6, 150.9, 467.6, 152.7, 462.6, 152.8, 462.2, 153.0, 462.3,
+153.1, 461.8, 156.4, 455.6, 157.1, 456.0, 161.0, 450.1, 211.6, 394.2,
+212.2, 394.7, 263.7, 339.6, 265.4, 339.8, 265.5, 338.1, 267.3, 336.5,
+161.0, 450.1, 177.6, 425.5, 180.4, 426.9, 194.2, 400.8, 195.8, 399.4,
+197.4, 397.9, 197.4, 398.0, 230.6, 368.8, 230.6, 368.8, 263.7, 339.6,
+265.4, 339.8, 265.5, 338.1, 267.3, 336.5, 214.3, 393.5, 219.1, 399.0,
+161.0, 450.1, 182.0, 340.9, 181.9, 342.0, 182.1, 342.0, 181.8, 343.0,
+179.0, 352.7, 179.1, 352.8, 176.4, 362.5, 177.8, 378.3, 163.4, 379.5,
+150.4, 396.6, 158.1, 366.7, 165.8, 368.5, 182.0, 340.9, 606.6, 614.7,
+613.0, 605.6, 611.2, 604.3, 615.8, 594.0, 621.3, 581.5, 619.6, 580.4,
+626.8, 569.1, 625.3, 571.4, 628.0, 572.7, 627.2, 575.8, 626.3, 579.7,
+625.3, 579.5, 623.3, 583.1, 615.0, 598.9, 616.8, 600.2, 606.6, 614.7,
+755.2, 696.0, 759.7, 703.1, 759.7, 703.1, 764.3, 710.3, 750.1, 721.0,
+751.8, 723.2, 739.3, 736.1, 743.2, 733.3, 741.4, 730.8, 743.5, 725.6,
+749.3, 710.8, 744.3, 704.0, 755.2, 696.0, 615.8, 594.0, 611.2, 604.3,
+613.0, 605.6, 606.6, 614.7, 598.3, 633.5, 603.5, 638.6, 590.1, 652.2,
+590.7, 651.6, 585.5, 646.4, 580.9, 640.6, 579.6, 639.0, 579.6, 639.0,
+578.3, 637.3, 577.2, 636.0, 576.0, 635.8, 576.1, 634.6, 576.4, 631.8,
+577.6, 632.0, 579.1, 629.3, 579.9, 628.0, 579.9, 628.0, 580.6, 626.7,
+586.2, 616.8, 583.9, 614.2, 591.8, 606.9, 601.4, 597.9, 609.1, 590.4,
+615.8, 594.0, 591.8, 606.9, 587.9, 600.6, 599.4, 593.4, 607.0, 580.0,
+621.3, 554.7, 618.1, 552.2, 635.6, 529.4, 635.9, 529.0, 641.7, 530.6,
+642.5, 533.4, 643.4, 536.7, 640.7, 537.4, 639.0, 541.4, 632.9, 555.2,
+632.9, 555.2, 626.8, 569.1, 619.6, 580.4, 621.3, 581.5, 615.8, 594.0,
+609.1, 590.4, 601.4, 597.9, 591.8, 606.9, 576.4, 460.9, 575.7, 454.1,
+572.0, 449.9, 574.9, 447.3, 576.1, 442.9, 576.8, 438.4, 577.4, 438.4,
+578.4, 438.1, 577.9, 436.5, 578.5, 434.6, 598.0, 464.0, 628.7, 470.0,
+623.1, 489.8, 630.0, 500.6, 631.2, 500.0, 636.9, 511.4, 637.2, 511.8,
+637.6, 512.1, 637.5, 512.3, 637.5, 512.3, 637.5, 512.3, 637.5, 512.3,
+607.0, 486.6, 604.0, 489.4, 576.4, 460.9, 637.5, 512.3, 639.7, 515.7,
+639.7, 515.7, 641.9, 519.1, 649.1, 530.3, 655.8, 530.1, 656.3, 541.6,
+656.1, 537.2, 649.4, 537.5, 642.5, 533.4, 641.7, 530.6, 635.9, 529.0,
+635.6, 529.4, 620.6, 520.5, 620.6, 520.5, 605.6, 511.6, 602.6, 509.9,
+602.6, 509.9, 599.7, 508.2, 590.1, 502.5, 584.7, 505.2, 580.6, 496.9,
+583.0, 479.5, 578.5, 478.9, 576.4, 460.9, 610.9, 469.7, 606.8, 486.0,
+636.9, 511.4, 637.2, 511.8, 637.6, 512.1, 637.5, 512.3, 637.5, 512.3,
+637.5, 512.3, 637.5, 512.3, 573.7, 767.7, 573.8, 767.6, 575.8, 769.6,
+575.5, 770.6, 574.2, 774.0, 573.6, 774.5, 570.5, 776.6, 557.9, 782.0,
+558.4, 783.3, 546.4, 789.9, 553.7, 788.1, 552.8, 784.7, 559.2, 779.4,
+566.5, 773.6, 565.6, 772.1, 573.7, 767.7, 595.9, 745.9, 603.8, 735.1,
+604.5, 735.6, 613.0, 725.3, 621.9, 714.5, 620.4, 712.7, 630.9, 703.8,
+630.8, 703.8, 632.3, 705.6, 633.8, 707.5, 634.9, 708.8, 636.2, 709.4,
+635.9, 710.2, 634.5, 713.3, 633.1, 712.6, 630.4, 715.1, 623.2, 721.6,
+623.2, 721.6, 616.0, 728.0, 609.7, 733.6, 609.7, 733.6, 603.4, 739.3,
+602.5, 740.0, 602.5, 740.0, 601.6, 740.8, 598.8, 743.4, 598.1, 742.9,
+595.9, 745.9, 545.8, 831.4, 545.8, 831.4, 550.9, 851.6, 556.0, 871.7,
+556.0, 871.9, 556.0, 871.9, 556.1, 872.2, 556.7, 874.7, 556.7, 874.7,
+557.4, 877.2, 557.6, 878.3, 557.7, 879.4, 557.9, 879.4, 539.7, 881.0,
+522.2, 884.3, 521.2, 880.5, 516.2, 860.4, 528.4, 835.8, 545.8, 831.4,
+521.2, 880.5, 518.2, 884.3, 506.9, 883.2, 506.1, 880.9, 511.1, 866.3,
+508.0, 865.3, 510.0, 849.6, 521.3, 851.8, 525.4, 830.9, 540.9, 812.3,
+538.9, 813.6, 542.7, 819.2, 544.4, 826.1, 544.5, 826.3, 544.5, 826.3,
+544.5, 826.6, 545.2, 829.0, 546.6, 829.6, 545.8, 831.4, 528.4, 835.8,
+516.2, 860.4, 521.2, 880.5, 501.0, 479.8, 509.2, 464.3, 517.2, 464.4,
+517.4, 448.8, 528.2, 446.9, 528.2, 446.9, 539.0, 445.1, 538.5, 445.1,
+538.5, 445.4, 538.1, 445.8, 529.7, 453.6, 529.7, 453.6, 521.2, 461.3,
+511.1, 470.5, 499.2, 474.1, 501.0, 479.8, 513.3, 575.9, 493.5, 628.7,
+492.4, 628.3, 473.7, 681.5, 473.3, 677.4, 473.3, 677.4, 472.9, 673.2,
+478.0, 656.7, 479.6, 657.2, 486.2, 641.2, 499.8, 608.6, 502.9, 609.6,
+513.3, 575.9, 495.3, 627.2, 497.7, 601.0, 504.3, 601.6, 513.3, 575.9,
+514.3, 573.4, 514.3, 573.5, 515.2, 571.0, 516.1, 568.5, 516.1, 568.5,
+517.0, 566.1, 517.1, 566.1, 517.6, 565.4, 517.5, 564.7, 519.4, 590.9,
+515.0, 592.1, 521.3, 617.1, 514.9, 633.7, 506.3, 648.9, 508.5, 650.2,
+506.8, 653.2, 507.2, 653.4, 506.0, 656.7, 498.3, 643.3, 494.0, 641.4,
+495.3, 627.2, 506.0, 656.7, 495.0, 685.1, 490.1, 684.0, 484.0, 713.4,
+484.7, 720.8, 478.3, 721.1, 478.0, 728.9, 471.0, 709.9, 470.8, 707.1,
+474.2, 687.1, 485.9, 657.6, 484.8, 657.2, 495.3, 627.2, 494.0, 641.4,
+498.3, 643.3, 506.0, 656.7, 445.1, 359.6, 446.0, 352.4, 448.3, 351.9,
+446.9, 345.2, 449.8, 331.0, 448.7, 330.7, 450.6, 316.3, 452.2, 318.3,
+453.6, 317.2, 456.6, 318.0, 457.2, 318.6, 456.1, 319.7, 455.6, 321.4,
+451.7, 335.6, 451.7, 335.6, 447.8, 349.9, 446.4, 354.8, 444.3, 355.2,
+445.1, 359.6, 158.8, 562.8, 158.5, 560.6, 157.7, 560.5, 158.2, 558.4,
+158.5, 556.2, 157.8, 556.1, 157.5, 553.7, 156.4, 553.2, 158.4, 549.0,
+159.2, 544.2, 160.5, 553.3, 159.4, 553.5, 158.8, 562.8, 418.2, 496.4,
+418.2, 496.3, 418.2, 496.3, 418.3, 496.3, 418.3, 496.3, 418.3, 496.3,
+418.3, 496.4, 418.3, 496.4, 418.2, 496.4, 418.2, 496.4, 379.0, 658.0,
+380.1, 653.4, 380.1, 653.4, 381.3, 648.8, 391.3, 646.7, 392.2, 650.9,
+403.1, 653.0, 407.3, 653.8, 411.0, 652.7, 411.6, 654.6, 410.7, 664.7,
+410.7, 664.7, 409.9, 674.8, 395.5, 676.3, 391.6, 669.5, 379.0, 658.0,
+409.9, 674.8, 408.8, 688.1, 411.8, 689.1, 407.6, 701.4, 407.5, 703.4,
+407.5, 703.4, 407.3, 705.4, 406.9, 710.5, 406.9, 710.5, 406.5, 715.6,
+406.4, 715.7, 406.4, 715.7, 406.4, 715.8, 406.3, 717.1, 406.0, 718.3,
+406.2, 718.4, 395.6, 705.4, 385.7, 702.3, 369.0, 705.6, 368.3, 705.3,
+367.7, 704.7, 367.8, 704.1, 372.0, 686.8, 377.1, 669.7, 376.3, 669.4,
+378.0, 667.1, 378.7, 665.6, 377.7, 663.3, 376.7, 661.9, 378.4, 660.7,
+379.0, 658.0, 391.6, 669.5, 395.5, 676.3, 409.9, 674.8, 442.5, 452.2,
+443.4, 445.8, 444.3, 445.8, 444.3, 439.3, 445.1, 452.6, 444.2, 452.7,
+445.8, 465.9, 448.0, 480.4, 446.7, 480.6, 447.6, 495.3, 448.0, 501.2,
+447.9, 501.2, 448.3, 507.2, 450.3, 533.5, 449.9, 533.5, 451.5, 559.9,
+451.9, 567.7, 451.9, 567.7, 452.4, 575.5, 452.6, 578.7, 452.6, 578.7,
+452.8, 581.9, 452.2, 585.4, 451.5, 585.3, 450.2, 588.8, 447.3, 596.8,
+443.2, 597.4, 444.3, 604.8, 439.9, 575.1, 444.0, 574.5, 443.6, 544.2,
+443.0, 498.2, 442.2, 498.2, 442.5, 452.2, 363.4, 734.1, 364.4, 724.0,
+361.6, 722.8, 365.4, 714.0, 365.5, 713.7, 365.5, 713.7, 365.5, 713.5,
+366.7, 708.8, 366.7, 708.8, 367.8, 704.1, 367.7, 704.7, 368.3, 705.3,
+369.0, 705.6, 374.3, 704.6, 376.1, 714.2, 383.3, 722.9, 381.6, 737.4,
+393.1, 738.7, 403.0, 754.5, 402.3, 755.6, 388.1, 746.8, 373.2, 739.2,
+368.3, 736.6, 364.5, 737.8, 363.4, 734.1, 382.3, 243.1, 380.0, 227.2,
+380.0, 227.2, 377.8, 211.3, 383.6, 206.3, 383.0, 205.7, 388.3, 200.2,
+392.4, 214.6, 386.1, 216.4, 383.8, 232.7, 383.0, 237.9, 381.0, 238.5,
+382.3, 243.1, 262.2, 528.4, 258.2, 543.6, 259.6, 544.0, 257.0, 559.6,
+255.0, 571.8, 255.0, 571.8, 252.9, 584.1, 247.6, 616.0, 247.6, 616.0,
+242.3, 647.9, 241.0, 655.3, 243.6, 657.0, 239.8, 662.8, 239.7, 665.9,
+234.0, 665.8, 228.3, 668.9, 240.2, 597.8, 243.9, 598.3, 262.2, 528.4,
+228.3, 668.9, 225.1, 670.6, 221.9, 670.5, 221.9, 672.3, 221.3, 662.2,
+223.9, 661.3, 220.8, 652.1, 226.3, 633.0, 226.4, 633.0, 231.9, 614.0,
+250.7, 549.3, 247.1, 548.0, 269.5, 484.6, 262.2, 505.2, 267.1, 506.8,
+262.2, 528.4, 243.9, 598.3, 240.2, 597.8, 228.3, 668.9, 212.2, 827.7,
+217.9, 793.6, 217.9, 793.6, 223.6, 759.5, 229.3, 760.1, 229.9, 753.5,
+236.2, 747.4, 233.8, 748.3, 235.0, 751.5, 233.8, 755.6, 232.7, 759.2,
+232.7, 759.2, 231.7, 762.7, 221.9, 795.2, 209.5, 826.6, 212.2, 827.7,
+252.9, 584.1, 255.0, 571.8, 255.0, 571.8, 257.0, 559.6, 255.6, 564.2,
+257.2, 564.7, 257.4, 569.9, 257.5, 573.8, 257.5, 573.8, 257.6, 577.7,
+258.6, 606.4, 272.9, 617.1, 259.5, 635.1, 270.6, 620.2, 253.8, 609.7,
+252.9, 584.1, 354.7, 534.6, 362.3, 542.1, 362.3, 542.1, 370.0, 549.5,
+371.9, 552.9, 369.4, 554.3, 368.8, 559.1, 364.9, 589.4, 368.6, 590.3,
+361.0, 619.6, 363.8, 608.6, 360.1, 607.6, 359.2, 595.6, 358.0, 579.6,
+358.0, 579.6, 356.8, 563.5, 356.1, 553.6, 356.1, 553.6, 355.4, 543.6,
+355.0, 539.1, 356.5, 535.4, 354.7, 534.6, 368.8, 559.1, 369.4, 554.3,
+371.9, 552.9, 370.0, 549.5, 373.2, 552.6, 376.3, 552.5, 376.5, 555.8,
+376.5, 556.1, 376.7, 556.1, 377.0, 556.3, 373.0, 558.1, 370.2, 560.5,
+368.8, 559.1, 386.0, 524.0, 348.2, 504.2, 343.2, 510.4, 310.5, 484.3,
+301.3, 479.0, 302.0, 476.9, 292.1, 473.7, 287.7, 470.6, 288.2, 469.9,
+284.3, 466.1, 282.0, 463.9, 282.5, 463.1, 279.8, 461.8, 294.6, 469.4,
+294.1, 470.2, 308.5, 478.6, 314.9, 482.3, 314.9, 482.3, 321.3, 486.1,
+353.7, 505.1, 351.5, 518.3, 386.0, 524.0, 355.0, 294.4, 350.3, 267.3,
+353.6, 266.3, 345.7, 240.1, 349.9, 234.6, 355.0, 230.2, 354.1, 229.1,
+354.5, 229.1, 354.5, 228.5, 355.0, 227.9, 367.7, 256.8, 363.9, 266.8,
+387.9, 282.3, 389.9, 289.5, 392.0, 289.0, 396.0, 295.6, 396.2, 296.0,
+396.1, 296.0, 396.1, 296.5, 375.5, 295.8, 364.6, 305.2, 355.0, 294.4,
+396.1, 296.5, 398.5, 311.6, 393.5, 314.7, 400.9, 326.8, 392.4, 326.4,
+390.1, 329.9, 384.0, 325.9, 377.6, 325.6, 375.1, 328.5, 371.2, 325.2,
+363.8, 314.1, 363.8, 314.1, 356.4, 303.0, 353.9, 300.6, 355.7, 298.7,
+355.0, 294.4, 364.6, 305.2, 375.5, 295.8, 396.1, 296.5, 437.6, 403.3,
+437.5, 403.4, 432.1, 404.9, 429.5, 402.8, 423.1, 391.0, 420.4, 392.5,
+411.3, 382.1, 410.7, 388.7, 420.7, 389.6, 430.0, 397.2, 433.8, 400.3,
+437.8, 400.6, 437.6, 403.3, 325.6, 322.0, 326.6, 319.9, 326.6, 319.9,
+327.5, 317.9, 341.1, 338.4, 353.4, 336.2, 381.6, 341.0, 386.2, 343.5,
+389.5, 348.0, 388.2, 350.8, 383.4, 361.2, 378.8, 359.0, 369.4, 367.2,
+365.1, 371.0, 364.9, 374.9, 360.7, 374.8, 357.9, 374.7, 358.1, 370.8,
+355.4, 366.8, 346.5, 353.4, 346.5, 353.4, 337.7, 340.1, 331.6, 331.0,
+330.1, 331.7, 325.6, 322.0, 420.5, 402.3, 415.5, 395.5, 407.1, 401.5,
+393.7, 400.8, 370.0, 392.8, 367.3, 394.6, 342.0, 397.7, 340.5, 399.4,
+338.5, 397.5, 334.9, 397.3, 334.6, 396.8, 337.2, 395.3, 339.5, 393.3,
+341.5, 391.6, 341.5, 391.6, 343.5, 389.8, 352.1, 382.3, 352.1, 382.3,
+360.7, 374.8, 364.9, 374.9, 365.1, 371.0, 369.4, 367.2, 397.1, 380.0,
+403.3, 378.7, 420.5, 402.3, 369.4, 367.2, 378.8, 359.0, 383.4, 361.2,
+388.2, 350.8, 388.6, 350.6, 390.1, 353.7, 392.0, 356.6, 396.6, 363.6,
+396.6, 363.6, 401.3, 370.6, 410.4, 387.3, 409.9, 388.2, 422.4, 402.4,
+422.1, 402.0, 421.2, 402.8, 420.5, 402.3, 403.3, 378.7, 397.1, 380.0,
+369.4, 367.2, 381.9, 411.1, 387.8, 405.9, 390.0, 399.5, 393.7, 400.8,
+407.1, 401.5, 415.5, 395.5, 420.5, 402.3, 421.2, 402.8, 422.1, 402.0,
+422.4, 402.4, 424.0, 404.3, 428.6, 401.2, 429.5, 402.8, 432.1, 404.9,
+437.5, 403.4, 437.6, 403.3, 439.2, 403.4, 440.7, 403.7, 440.8, 403.5,
+436.2, 422.4, 436.2, 422.4, 431.6, 441.3, 431.6, 441.2, 431.5, 441.2,
+431.3, 441.1, 421.1, 434.9, 421.1, 434.9, 410.9, 428.7, 396.4, 419.9,
+389.8, 423.9, 381.9, 411.1, 226.5, 544.9, 227.1, 537.3, 227.1, 537.3,
+227.6, 529.8, 242.2, 506.7, 239.7, 505.1, 251.8, 480.4, 251.0, 482.0,
+251.2, 482.0, 250.5, 483.7, 242.6, 503.9, 242.6, 503.9, 234.6, 524.2,
+230.6, 534.6, 234.1, 539.0, 226.5, 544.9, 68.6, 177.8, 85.9, 216.5,
+115.4, 232.0, 103.2, 255.3, 104.5, 259.8, 104.5, 259.8, 105.7, 264.3,
+105.7, 264.1, 105.7, 264.1, 105.6, 264.0, 103.7, 259.7, 103.7, 259.7,
+101.9, 255.4, 85.3, 216.6, 82.1, 176.7, 68.6, 177.8, 685.5, 569.3,
+683.3, 569.5, 683.3, 569.5, 681.0, 569.7, 673.6, 557.2, 671.3, 558.6,
+661.6, 547.5, 672.6, 546.6, 674.9, 557.2, 685.5, 569.3, 702.7, 480.0,
+702.5, 483.1, 702.5, 483.1, 702.3, 486.2, 700.5, 484.1, 694.7, 489.0,
+687.0, 491.8, 687.5, 485.4, 693.9, 483.3, 702.7, 480.0, 857.0, 143.8,
+836.9, 149.9, 832.1, 143.9, 816.9, 156.1, 811.6, 152.0, 811.6, 152.0,
+806.2, 148.0, 830.0, 140.7, 841.8, 132.4, 857.0, 143.8, 792.8, 174.5,
+792.8, 174.5, 795.0, 176.8, 797.2, 179.1, 799.7, 181.7, 799.7, 181.7,
+802.1, 184.2, 802.4, 184.5, 802.4, 184.5, 802.7, 184.8, 809.4, 191.8,
+809.4, 191.8, 816.1, 198.8, 816.8, 199.5, 816.8, 199.5, 817.5, 200.3,
+850.9, 235.1, 853.6, 232.9, 884.2, 269.9, 875.7, 265.1, 875.7, 265.1,
+867.2, 260.3, 832.9, 224.5, 835.0, 222.5, 802.7, 184.8, 802.4, 184.5,
+802.4, 184.5, 802.1, 184.2, 799.7, 181.7, 799.7, 181.7, 797.2, 179.1,
+795.0, 176.8, 792.8, 174.5, 792.8, 174.5, 867.2, 260.3, 842.6, 246.4,
+842.6, 246.4, 817.9, 232.4, 799.6, 193.6, 800.5, 192.0, 774.9, 157.7,
+773.6, 155.2, 773.5, 155.3, 772.0, 152.8, 783.0, 163.0, 782.9, 163.3,
+792.8, 174.5, 830.4, 217.0, 845.6, 210.6, 867.2, 260.3, 797.2, 179.1,
+795.0, 176.8, 792.8, 174.5, 792.8, 174.5, 782.9, 163.3, 783.0, 163.0,
+772.0, 152.8, 768.7, 147.1, 766.1, 141.1, 765.4, 141.4, 766.5, 139.8,
+764.2, 135.2, 761.4, 134.3, 760.9, 134.2, 761.0, 133.7, 760.7, 133.2,
+767.4, 139.3, 771.4, 135.0, 782.2, 136.8, 798.9, 152.6, 801.2, 150.2,
+820.2, 163.7, 821.3, 166.9, 809.8, 174.1, 797.2, 179.1, 701.9, 194.3,
+712.7, 197.5, 715.9, 194.0, 723.5, 200.8, 762.4, 221.2, 762.4, 221.2,
+801.3, 241.7, 802.0, 241.9, 799.9, 248.5, 798.5, 255.3, 795.0, 256.8,
+792.7, 251.7, 787.0, 248.0, 786.8, 247.9, 786.8, 247.9, 786.5, 247.7,
+784.3, 246.3, 784.3, 246.3, 782.1, 244.9, 769.7, 237.1, 769.7, 237.1,
+757.4, 229.3, 757.4, 229.3, 757.4, 229.3, 757.4, 229.3, 729.6, 211.8,
+726.8, 215.2, 701.9, 194.3, 626.8, 212.0, 636.0, 225.9, 636.5, 225.5,
+645.8, 239.4, 667.0, 268.4, 665.7, 269.4, 685.6, 299.3, 655.5, 256.1,
+655.9, 255.9, 626.8, 212.0, 635.9, 116.5, 646.2, 125.1, 646.2, 125.1,
+656.5, 133.7, 657.2, 142.1, 662.6, 141.6, 668.8, 149.5, 643.8, 135.2,
+622.3, 122.5, 612.2, 132.4, 593.2, 121.1, 593.2, 121.1, 574.2, 109.7,
+572.8, 107.4, 572.2, 107.5, 569.8, 106.0, 580.0, 103.8, 580.0, 103.8,
+590.2, 101.6, 613.7, 105.4, 614.5, 106.1, 635.9, 116.5, 590.2, 101.6,
+600.3, 99.5, 600.3, 99.5, 610.4, 97.3, 613.6, 104.6, 618.0, 102.6,
+625.6, 107.8, 631.3, 111.2, 630.8, 112.2, 635.9, 116.5, 614.5, 106.1,
+613.7, 105.4, 590.2, 101.6, 499.3, 193.9, 476.5, 183.3, 477.3, 175.2,
+453.6, 172.7, 441.0, 164.6, 441.0, 164.6, 428.4, 156.5, 457.3, 169.0,
+456.3, 171.2, 484.2, 186.0, 491.8, 189.9, 491.5, 190.5, 499.3, 193.9,
+601.4, 22.8, 597.4, 24.3, 593.3, 25.3, 593.4, 25.8, 591.9, 23.2,
+590.0, 21.0, 590.4, 20.7, 590.7, 20.3, 589.6, 19.4, 588.8, 18.1,
+595.3, 19.3, 598.7, 18.3, 601.4, 22.8, 276.3, 70.7, 278.0, 72.0,
+278.0, 72.0, 279.7, 73.4, 271.5, 101.4, 273.7, 102.0, 267.7, 130.7,
+255.6, 120.9, 270.1, 100.3, 276.3, 70.7, 349.7, 186.4, 349.6, 188.2,
+349.1, 188.4, 349.5, 190.1, 343.1, 173.1, 346.6, 170.8, 336.8, 156.0,
+330.5, 139.2, 331.3, 138.9, 324.3, 122.5, 337.7, 154.1, 337.7, 154.2,
+349.7, 186.4, 335.3, 168.8, 332.6, 191.9, 330.5, 191.8, 329.9, 214.9,
+320.4, 186.5, 320.4, 186.5, 310.9, 158.1, 305.7, 151.6, 309.6, 148.5,
+308.3, 138.9, 325.1, 146.3, 330.3, 151.4, 335.3, 168.8, 308.3, 138.9,
+306.7, 127.1, 310.9, 124.6, 305.2, 115.3, 310.1, 106.4, 310.1, 106.4,
+315.0, 97.6, 323.2, 100.7, 319.7, 110.0, 324.3, 122.5, 331.3, 138.9,
+330.5, 139.2, 336.8, 156.0, 339.5, 160.1, 336.0, 162.4, 335.3, 168.8,
+330.3, 151.4, 325.1, 146.3, 308.3, 138.9, 263.7, 336.2, 263.7, 337.9,
+263.6, 339.6, 263.7, 339.6, 230.6, 368.8, 230.6, 368.8, 197.4, 398.0,
+195.3, 395.7, 191.7, 394.9, 190.1, 396.4, 202.0, 375.3, 211.2, 376.4,
+213.9, 354.1, 213.9, 354.1, 214.0, 354.0, 214.0, 353.9, 238.8, 344.9,
+238.4, 343.4, 263.7, 336.2, 214.0, 353.9, 226.4, 331.9, 237.8, 332.4,
+238.9, 309.9, 240.5, 309.0, 240.7, 308.1, 241.0, 306.0, 252.2, 300.0,
+252.2, 300.0, 263.4, 293.9, 259.6, 314.3, 263.6, 315.1, 263.7, 336.2,
+238.4, 343.4, 238.8, 344.9, 214.0, 353.9, 150.0, 380.7, 152.0, 345.3,
+158.2, 344.5, 154.0, 309.9, 154.8, 305.8, 154.8, 305.8, 155.7, 301.6,
+155.8, 301.9, 157.5, 301.0, 159.2, 300.4, 157.2, 333.4, 155.5, 333.2,
+151.7, 366.1, 150.8, 373.4, 150.3, 373.4, 150.0, 380.7, 591.4, 653.9,
+591.6, 653.5, 589.9, 652.7, 590.1, 652.2, 603.5, 638.6, 598.3, 633.5,
+606.6, 614.7, 616.8, 600.2, 615.0, 598.9, 623.3, 583.1, 612.9, 586.0,
+616.4, 598.5, 609.4, 614.0, 600.4, 633.9, 601.3, 634.3, 591.4, 653.9,
+607.0, 580.0, 599.4, 593.4, 587.9, 600.6, 591.8, 606.9, 583.9, 614.2,
+586.2, 616.8, 580.6, 626.7, 575.6, 621.5, 580.0, 612.0, 586.2, 601.1,
+593.2, 588.6, 607.2, 580.2, 607.0, 580.0, 586.2, 601.1, 582.8, 599.4,
+589.3, 586.8, 592.4, 572.5, 593.4, 567.5, 593.4, 567.5, 594.5, 562.6,
+599.8, 538.4, 599.8, 538.4, 605.0, 514.1, 605.3, 512.9, 605.8, 511.8,
+605.6, 511.6, 620.6, 520.5, 620.6, 520.5, 635.6, 529.4, 618.1, 552.2,
+621.3, 554.7, 607.0, 580.0, 607.2, 580.2, 593.2, 588.6, 586.2, 601.1,
+523.8, 737.3, 526.4, 716.5, 526.4, 716.5, 529.0, 695.8, 528.6, 697.6,
+530.3, 697.9, 531.6, 700.1, 538.0, 710.4, 538.1, 710.3, 544.4, 720.7,
+544.4, 720.7, 544.4, 720.7, 544.4, 720.7, 534.1, 729.0, 523.0, 735.9,
+523.8, 737.3, 573.1, 676.7, 567.3, 670.3, 574.9, 663.4, 576.6, 650.0,
+576.6, 649.8, 576.6, 649.8, 576.7, 649.6, 577.5, 643.4, 575.7, 642.6,
+578.3, 637.3, 579.6, 639.0, 579.6, 639.0, 580.9, 640.6, 581.0, 646.3,
+579.7, 646.3, 578.4, 652.1, 575.8, 664.4, 568.2, 671.3, 573.1, 676.7,
+536.3, 636.7, 537.3, 627.8, 537.3, 627.8, 538.4, 619.0, 537.6, 618.0,
+551.4, 612.5, 552.4, 604.6, 552.6, 604.5, 553.8, 606.4, 555.2, 608.1,
+563.2, 618.2, 573.3, 624.9, 571.1, 628.3, 563.9, 639.2, 551.3, 641.0,
+536.3, 636.7, 549.3, 443.5, 552.8, 465.2, 544.2, 472.5, 556.3, 486.9,
+555.7, 487.9, 555.3, 487.8, 555.0, 488.9, 553.7, 495.1, 551.2, 494.6,
+547.5, 500.3, 547.7, 500.0, 547.5, 499.8, 547.5, 499.4, 547.6, 497.4,
+547.6, 497.4, 547.6, 495.4, 547.8, 490.8, 547.8, 490.8, 547.9, 486.2,
+548.0, 483.4, 548.0, 483.4, 548.1, 480.6, 548.7, 462.0, 557.9, 450.1,
+549.3, 443.5, 517.0, 564.6, 517.0, 565.3, 516.8, 566.1, 517.0, 566.1,
+516.1, 568.5, 516.1, 568.5, 515.2, 571.0, 514.3, 573.5, 514.3, 573.4,
+513.3, 575.9, 502.9, 609.6, 499.8, 608.6, 486.2, 641.2, 493.4, 624.6,
+492.9, 624.4, 499.7, 607.6, 508.3, 586.1, 508.0, 586.0, 517.0, 564.6,
+469.6, 385.7, 466.8, 389.5, 464.2, 393.4, 463.9, 393.2, 459.0, 391.3,
+455.0, 392.5, 454.1, 389.4, 452.7, 386.4, 452.7, 386.4, 451.3, 383.3,
+452.5, 381.9, 454.8, 383.8, 458.3, 384.2, 463.9, 385.0, 467.7, 382.6,
+469.6, 385.7, 396.3, 586.8, 397.2, 582.8, 397.3, 582.8, 398.2, 578.9,
+398.4, 578.1, 398.4, 578.1, 398.6, 577.3, 409.8, 571.4, 405.2, 559.0,
+407.6, 540.2, 413.0, 527.4, 419.1, 522.3, 414.3, 512.8, 411.6, 510.8,
+416.2, 504.6, 418.2, 496.4, 418.2, 496.4, 418.3, 496.4, 418.3, 496.4,
+419.0, 502.7, 419.0, 502.7, 419.7, 509.1, 410.4, 547.4, 408.3, 546.9,
+396.9, 584.7, 396.6, 585.7, 396.5, 585.7, 396.3, 586.8, 406.5, 715.6,
+406.9, 710.5, 406.9, 710.5, 407.3, 705.4, 414.6, 682.2, 422.2, 683.1,
+424.1, 659.7, 421.7, 688.2, 416.6, 688.1, 406.5, 715.6, 425.5, 707.4,
+429.7, 691.9, 428.8, 691.6, 432.1, 675.9, 441.2, 632.3, 440.7, 632.2,
+450.2, 588.8, 451.5, 585.3, 452.2, 585.4, 452.8, 581.9, 453.1, 588.3,
+453.1, 588.3, 453.5, 594.6, 451.7, 607.4, 450.4, 607.2, 447.3, 619.8,
+436.4, 663.6, 437.3, 663.9, 425.5, 707.4, 421.8, 600.0, 432.1, 526.1,
+432.1, 526.1, 442.5, 452.2, 442.2, 498.2, 443.0, 498.2, 443.6, 544.2,
+443.5, 549.1, 441.7, 549.1, 439.7, 554.0, 430.8, 577.0, 422.4, 576.8,
+421.8, 600.0, 450.1, 848.6, 452.0, 854.6, 455.4, 855.6, 453.9, 860.5,
+453.3, 865.0, 453.3, 865.0, 452.6, 869.4, 442.1, 862.3, 444.4, 858.9,
+436.1, 848.5, 428.4, 838.7, 428.5, 829.0, 420.7, 828.9, 435.5, 829.1,
+437.5, 836.6, 450.1, 848.6, 365.7, 852.2, 362.7, 811.2, 363.7, 811.1,
+359.7, 770.2, 360.0, 767.1, 360.0, 767.1, 360.3, 764.1, 361.6, 774.6,
+361.0, 774.7, 361.6, 785.4, 363.7, 818.8, 361.5, 819.0, 365.7, 852.2,
+444.9, 882.7, 427.4, 888.3, 425.7, 884.8, 406.6, 883.8, 405.1, 880.8,
+402.4, 882.1, 398.3, 880.4, 394.0, 872.0, 396.6, 870.7, 395.0, 861.0,
+392.2, 844.6, 396.7, 830.6, 389.3, 828.2, 417.3, 837.2, 412.8, 851.2,
+436.3, 874.3, 440.6, 878.5, 442.2, 883.6, 444.9, 882.7, 416.0, 171.3,
+416.1, 171.1, 416.3, 171.1, 416.3, 171.0, 417.8, 183.6, 417.8, 183.6,
+419.4, 196.3, 421.3, 210.6, 421.0, 210.6, 422.5, 225.0, 417.7, 260.8,
+417.2, 261.1, 417.5, 297.2, 417.2, 296.7, 417.2, 296.7, 416.8, 296.1,
+416.0, 242.1, 416.4, 242.1, 416.1, 188.1, 416.0, 179.7, 415.9, 179.7,
+416.0, 171.3, 346.4, 641.2, 353.1, 634.7, 353.5, 635.0, 359.8, 628.3,
+359.0, 628.9, 359.6, 629.7, 359.5, 631.2, 359.1, 633.6, 359.1, 633.6,
+358.8, 636.1, 358.4, 641.9, 355.7, 641.6, 355.0, 647.4, 355.3, 654.7,
+350.7, 654.7, 349.9, 662.3, 349.7, 664.6, 349.1, 664.5, 348.4, 666.8,
+346.5, 658.6, 347.7, 658.4, 347.1, 650.0, 346.8, 645.6, 344.6, 644.3,
+346.4, 641.2, 261.3, 688.3, 264.5, 698.4, 267.0, 702.9, 262.0, 710.4,
+244.4, 725.4, 243.2, 724.1, 226.8, 740.4, 233.3, 701.6, 239.0, 701.7,
+239.8, 662.8, 243.6, 657.0, 241.0, 655.3, 242.3, 647.9, 256.2, 664.4,
+254.6, 667.2, 261.3, 688.3, 242.3, 647.9, 247.6, 616.0, 247.6, 616.0,
+252.9, 584.1, 253.8, 609.7, 270.6, 620.2, 259.5, 635.1, 259.7, 636.7,
+259.6, 636.7, 259.6, 638.3, 260.0, 649.2, 260.0, 649.2, 260.4, 660.1,
+260.4, 662.7, 260.4, 662.7, 260.5, 665.3, 260.8, 672.8, 260.8, 672.8,
+261.0, 680.4, 261.2, 684.4, 259.5, 685.3, 261.3, 688.3, 254.6, 667.2,
+256.2, 664.4, 242.3, 647.9, 306.5, 803.3, 314.5, 784.8, 318.0, 785.6,
+322.6, 766.3, 330.7, 778.5, 327.5, 784.7, 338.9, 790.7, 338.4, 794.6,
+338.4, 794.6, 337.9, 798.5, 323.4, 804.1, 308.4, 807.4, 306.5, 803.3,
+337.9, 798.5, 337.2, 803.9, 337.2, 803.9, 336.5, 809.4, 321.1, 829.8,
+319.0, 828.2, 301.5, 847.1, 290.0, 859.4, 292.5, 867.4, 278.5, 871.8,
+284.4, 870.0, 281.3, 861.8, 285.2, 852.2, 291.3, 826.7, 295.8, 827.8,
+306.5, 803.3, 308.4, 807.4, 323.4, 804.1, 337.9, 798.5, 301.5, 847.1,
+319.0, 828.2, 321.1, 829.8, 336.5, 809.4, 333.6, 832.1, 337.9, 833.6,
+330.6, 854.9, 330.0, 857.6, 330.6, 857.7, 329.9, 860.4, 329.5, 862.2,
+329.5, 862.2, 329.0, 864.1, 314.4, 857.3, 300.6, 853.6, 301.5, 847.1,
+329.0, 864.1, 326.7, 873.5, 320.9, 879.5, 324.4, 882.9, 302.3, 890.3,
+299.7, 883.1, 275.0, 882.2, 275.2, 882.2, 275.2, 881.7, 275.3, 881.2,
+276.9, 876.5, 275.7, 875.5, 278.5, 871.8, 292.5, 867.4, 290.0, 859.4,
+301.5, 847.1, 300.6, 853.6, 314.4, 857.3, 329.0, 864.1, 398.2, 578.9,
+397.3, 582.8, 397.2, 582.8, 396.3, 586.8, 394.8, 593.0, 394.8, 593.0,
+393.3, 599.3, 389.1, 616.4, 395.5, 622.4, 385.0, 633.5, 378.5, 627.5,
+373.8, 632.5, 362.7, 631.5, 369.7, 602.6, 379.2, 604.2, 398.2, 578.9,
+362.7, 631.5, 361.1, 631.4, 359.8, 632.0, 359.5, 631.2, 359.5, 631.2,
+359.5, 631.2, 359.5, 631.2, 359.6, 629.7, 359.0, 628.9, 359.8, 628.3,
+360.2, 627.9, 359.6, 627.2, 360.0, 626.8, 360.5, 623.2, 360.5, 623.2,
+361.0, 619.6, 368.6, 590.3, 364.9, 589.4, 368.8, 559.1, 370.2, 560.5,
+373.0, 558.1, 377.0, 556.3, 387.8, 566.8, 394.5, 579.5, 398.6, 577.3,
+398.4, 578.1, 398.4, 578.1, 398.2, 578.9, 379.2, 604.2, 369.7, 602.6,
+362.7, 631.5, 374.9, 477.0, 387.8, 504.4, 387.8, 504.4, 400.7, 531.7,
+394.3, 526.7, 393.3, 527.9, 386.0, 524.0, 351.5, 518.3, 353.7, 505.1,
+321.3, 486.1, 322.1, 486.6, 322.6, 485.9, 323.8, 485.7, 332.3, 484.2,
+332.3, 484.2, 340.7, 482.8, 347.2, 481.7, 347.2, 481.7, 353.6, 480.6,
+364.3, 478.8, 371.0, 472.7, 374.9, 477.0, 430.0, 397.2, 420.7, 389.6,
+410.7, 388.7, 411.3, 382.1, 406.3, 376.3, 404.8, 377.1, 401.3, 370.6,
+396.6, 363.6, 396.6, 363.6, 392.0, 356.6, 406.4, 368.4, 404.9, 370.3,
+417.7, 384.1, 423.9, 390.6, 422.5, 394.9, 430.0, 397.2, 312.7, 349.7,
+319.1, 335.8, 319.1, 335.8, 325.6, 322.0, 330.1, 331.7, 331.6, 331.0,
+337.7, 340.1, 333.6, 348.9, 314.3, 352.2, 312.7, 349.7, 426.6, 461.9,
+423.9, 473.2, 422.3, 473.1, 421.1, 484.6, 421.1, 486.1, 420.7, 486.1,
+420.4, 487.6, 419.3, 484.4, 417.0, 485.2, 413.7, 482.7, 388.8, 467.8,
+390.8, 464.5, 367.9, 446.3, 367.7, 447.2, 393.4, 453.0, 418.9, 459.8,
+422.7, 460.9, 426.5, 460.5, 426.6, 461.9, 236.0, 594.4, 228.0, 614.6,
+225.6, 614.0, 220.0, 634.9, 220.3, 631.4, 219.5, 628.1, 220.5, 627.8,
+225.4, 586.6, 223.5, 586.4, 226.5, 544.9, 234.1, 539.0, 230.6, 534.6,
+234.6, 524.2, 241.1, 558.2, 240.5, 560.0, 236.0, 594.4, 77.2, 274.3,
+70.8, 259.9, 70.8, 259.9, 64.3, 245.5, 66.4, 226.4, 65.1, 226.2,
+65.9, 206.9, 64.9, 213.5, 67.1, 213.8, 68.2, 220.7, 71.9, 242.5,
+71.9, 242.5, 75.5, 264.2, 76.4, 269.2, 74.8, 270.2, 77.2, 274.3,
+689.5, 513.1, 695.2, 510.7, 698.8, 512.4, 700.8, 508.2, 700.3, 515.6,
+700.3, 515.6, 699.8, 523.1, 697.3, 524.2, 689.2, 517.7, 689.5, 513.1,
+699.8, 523.1, 698.6, 542.0, 694.3, 542.7, 697.3, 560.8, 695.3, 564.7,
+692.5, 565.5, 693.3, 568.6, 689.4, 569.0, 689.4, 569.0, 685.5, 569.3,
+674.9, 557.2, 672.6, 546.6, 661.6, 547.5, 659.2, 544.7, 658.6, 545.0,
+656.7, 541.9, 653.1, 536.2, 653.0, 536.3, 649.4, 530.7, 670.2, 528.0,
+669.4, 521.9, 689.5, 513.1, 689.2, 517.7, 697.3, 524.2, 699.8, 523.1,
+640.6, 486.8, 641.1, 482.9, 641.1, 482.9, 641.5, 479.0, 665.1, 466.5,
+665.8, 463.1, 691.8, 459.8, 696.3, 465.5, 696.3, 465.5, 700.8, 471.3,
+700.6, 474.2, 701.0, 474.9, 702.9, 477.3, 702.8, 478.7, 702.8, 478.7,
+702.7, 480.0, 693.9, 483.3, 687.5, 485.4, 687.0, 491.8, 677.4, 495.4,
+677.4, 495.4, 667.8, 498.9, 653.7, 497.4, 652.1, 495.6, 640.6, 486.8,
+667.8, 498.9, 652.8, 504.4, 652.4, 503.5, 637.8, 510.0, 638.1, 507.7,
+638.4, 507.7, 638.3, 505.4, 635.1, 498.0, 639.5, 496.1, 640.6, 486.8,
+652.1, 495.6, 653.7, 497.4, 667.8, 498.9, 784.9, 126.3, 772.6, 107.4,
+777.7, 99.6, 760.4, 88.4, 767.7, 87.7, 771.2, 83.6, 775.0, 86.9,
+813.2, 104.8, 813.2, 104.8, 851.4, 122.6, 849.9, 116.6, 813.4, 137.1,
+784.9, 126.3, 851.4, 122.6, 854.5, 124.1, 854.9, 123.5, 857.5, 125.5,
+863.1, 129.5, 863.2, 129.3, 868.7, 133.4, 872.0, 135.8, 872.0, 135.8,
+875.3, 138.2, 868.0, 135.7, 866.1, 141.0, 857.0, 143.8, 841.8, 132.4,
+830.0, 140.7, 806.2, 148.0, 800.0, 143.3, 800.7, 141.9, 793.9, 138.7,
+792.8, 138.7, 792.9, 137.9, 791.8, 137.2, 786.9, 134.1, 788.4, 131.7,
+784.9, 126.3, 813.4, 137.1, 849.9, 116.6, 851.4, 122.6, 921.4, 271.7,
+918.0, 273.4, 914.5, 273.9, 914.7, 275.0, 914.9, 275.8, 907.1, 277.0,
+907.2, 278.6, 907.3, 278.8, 905.1, 279.6, 903.1, 280.6, 902.5, 281.0,
+901.6, 279.7, 900.1, 278.9, 910.2, 274.1, 910.6, 274.7, 921.4, 271.7,
+773.0, 328.8, 748.5, 323.3, 748.1, 316.3, 724.0, 317.9, 720.6, 314.2,
+720.6, 314.2, 717.1, 310.4, 741.1, 315.2, 740.5, 318.1, 763.9, 325.8,
+768.5, 327.3, 768.4, 327.9, 773.0, 328.8, 787.0, 248.0, 792.7, 251.7,
+795.0, 256.8, 798.5, 255.3, 796.8, 263.4, 794.1, 271.2, 795.1, 271.6,
+793.4, 271.7, 791.4, 277.9, 792.6, 283.1, 788.8, 283.1, 789.0, 300.4,
+785.4, 317.7, 785.5, 317.1, 784.0, 316.8, 784.0, 315.9, 783.8, 302.9,
+784.5, 302.9, 785.1, 289.9, 786.1, 269.0, 779.8, 266.6, 787.0, 248.0,
+673.5, 315.8, 659.5, 298.6, 659.5, 298.6, 645.4, 281.4, 632.5, 255.7,
+631.1, 256.4, 615.8, 231.9, 605.0, 210.3, 611.0, 203.2, 594.1, 188.7,
+592.9, 180.0, 592.1, 178.0, 585.7, 172.0, 581.2, 168.9, 582.9, 166.5,
+580.1, 161.0, 591.5, 174.3, 591.9, 173.9, 603.8, 186.8, 616.0, 204.4,
+614.0, 205.7, 624.2, 224.7, 638.5, 251.0, 638.5, 251.0, 652.8, 277.4,
+663.2, 296.6, 673.6, 315.7, 673.5, 315.8, 478.7, 141.4, 501.3, 162.4,
+497.6, 169.5, 523.9, 183.4, 524.4, 183.1, 525.3, 184.7, 526.7, 186.0,
+533.2, 191.2, 531.9, 192.8, 537.0, 199.6, 526.3, 193.5, 528.0, 190.6,
+519.0, 181.6, 498.8, 161.5, 503.0, 150.3, 478.7, 141.4, 620.1, -35.4,
+624.7, -11.6, 619.7, -9.4, 629.3, 12.3, 624.8, 14.0, 624.8, 14.0,
+620.2, 15.7, 617.8, 13.9, 620.2, 10.6, 620.2, 5.5, 620.1, -14.9,
+629.9, -28.1, 620.1, -35.4, 250.6, 110.4, 253.5, 96.5, 253.0, 96.4,
+256.4, 82.5, 257.2, 79.3, 257.0, 79.3, 257.9, 76.1, 260.2, 67.8,
+260.2, 67.8, 262.6, 59.6, 263.8, 66.2, 269.4, 65.1, 276.3, 70.7,
+270.1, 100.3, 255.6, 120.9, 267.7, 130.7, 265.7, 140.4, 265.7, 140.4,
+263.7, 150.1, 251.1, 135.4, 252.7, 130.8, 250.6, 110.4, 263.7, 150.1,
+261.1, 162.6, 257.9, 162.7, 258.5, 175.0, 249.7, 165.6, 249.7, 165.6,
+240.9, 156.3, 246.6, 133.6, 245.7, 133.4, 250.6, 110.4, 252.7, 130.8,
+251.1, 135.4, 263.7, 150.1, 326.0, 83.2, 339.5, 82.3, 343.1, 87.8,
+353.0, 81.4, 353.5, 89.0, 353.5, 89.0, 353.9, 96.6, 351.1, 135.1,
+352.1, 135.2, 350.3, 173.8, 322.8, 160.6, 324.7, 128.1, 326.0, 83.2,
+350.3, 173.8, 350.0, 180.1, 350.0, 180.1, 349.7, 186.4, 337.7, 154.2,
+337.7, 154.1, 324.3, 122.5, 319.7, 110.0, 323.2, 100.7, 315.0, 97.6,
+319.0, 90.5, 325.0, 87.7, 323.0, 83.4, 324.5, 83.3, 324.5, 83.3,
+326.0, 83.2, 324.7, 128.1, 322.8, 160.6, 350.3, 173.8, 172.0, 295.9,
+179.3, 293.3, 179.3, 293.3, 186.7, 290.7, 183.3, 295.7, 186.1, 297.6,
+185.4, 304.5, 180.8, 306.1, 171.6, 299.5, 172.0, 295.9, 602.3, 667.7,
+604.0, 664.1, 590.6, 659.9, 591.4, 653.9, 601.3, 634.3, 600.4, 633.9,
+609.4, 614.0, 609.2, 614.5, 609.3, 614.5, 609.3, 615.1, 609.3, 615.2,
+609.3, 615.2, 609.2, 615.2, 605.8, 641.4, 612.9, 644.7, 602.3, 667.7,
+662.7, 698.1, 662.6, 699.1, 661.9, 699.0, 661.0, 700.0, 658.8, 702.5,
+658.8, 702.5, 656.6, 705.1, 654.4, 707.5, 654.4, 707.5, 652.3, 710.0,
+647.9, 714.9, 648.2, 719.6, 643.6, 719.9, 640.3, 720.1, 637.3, 715.8,
+636.4, 710.8, 632.1, 687.1, 631.2, 686.3, 633.1, 662.4, 632.8, 666.0,
+636.4, 666.3, 639.6, 670.2, 647.5, 679.7, 647.5, 679.7, 655.4, 689.2,
+658.3, 692.8, 658.3, 692.8, 661.2, 696.3, 661.9, 697.2, 662.7, 697.2,
+662.7, 698.1, 555.2, 608.1, 553.8, 606.4, 552.6, 604.5, 552.4, 604.6,
+553.2, 598.7, 541.1, 592.1, 541.9, 591.3, 542.6, 585.6, 542.6, 585.6,
+543.2, 580.0, 552.4, 591.6, 549.9, 593.8, 555.2, 608.1, 561.8, 494.2,
+562.8, 490.6, 562.8, 490.6, 563.8, 487.0, 564.1, 489.9, 568.0, 489.5,
+572.1, 491.9, 572.1, 492.7, 568.0, 492.8, 564.0, 493.7, 562.9, 493.9,
+561.8, 493.9, 561.8, 494.2, 544.4, 720.7, 544.4, 720.7, 544.4, 720.7,
+544.4, 720.7, 549.1, 728.1, 549.1, 728.1, 553.7, 735.5, 558.5, 743.3,
+558.5, 743.3, 563.4, 751.1, 568.5, 759.4, 574.8, 760.3, 573.7, 767.7,
+565.6, 772.1, 566.5, 773.6, 559.2, 779.4, 548.5, 769.2, 554.9, 762.5,
+550.7, 745.6, 547.5, 733.2, 547.5, 733.2, 544.4, 720.7, 589.1, 754.2,
+588.6, 757.8, 586.3, 757.5, 583.5, 760.9, 579.5, 765.7, 580.5, 767.1,
+575.5, 770.6, 575.8, 769.6, 573.8, 767.6, 573.7, 767.7, 574.8, 760.3,
+568.5, 759.4, 563.4, 751.1, 563.1, 714.0, 567.5, 713.8, 573.1, 676.7,
+568.2, 671.3, 575.8, 664.4, 578.4, 652.1, 575.3, 653.6, 579.5, 662.6,
+580.6, 673.2, 583.7, 702.7, 583.7, 702.7, 586.8, 732.3, 587.9, 743.2,
+590.3, 743.5, 589.1, 754.2, 531.4, 675.9, 533.8, 656.3, 533.8, 656.3,
+536.3, 636.7, 551.3, 641.0, 563.9, 639.2, 571.1, 628.3, 572.8, 628.1,
+573.1, 630.7, 575.0, 633.2, 575.6, 633.9, 575.6, 633.9, 576.1, 634.6,
+576.0, 635.8, 577.2, 636.0, 578.3, 637.3, 575.7, 642.6, 577.5, 643.4,
+576.7, 649.6, 571.0, 656.4, 568.5, 654.3, 560.3, 659.1, 545.9, 667.5,
+535.0, 679.2, 531.4, 675.9, 630.3, 847.0, 629.2, 849.3, 629.8, 849.8,
+628.1, 851.5, 623.9, 855.9, 624.5, 856.6, 619.8, 860.2, 609.4, 869.5,
+610.7, 874.4, 598.4, 878.2, 579.8, 884.0, 578.1, 879.9, 557.9, 879.4,
+557.7, 879.4, 557.6, 878.3, 557.4, 877.2, 591.6, 861.8, 592.0, 862.9,
+626.7, 848.5, 628.5, 847.7, 630.3, 846.9, 630.3, 847.0, 538.1, 445.8,
+538.5, 445.4, 538.5, 445.1, 539.0, 445.1, 540.4, 444.8, 541.1, 445.4,
+541.9, 444.6, 543.5, 442.4, 545.6, 443.9, 549.3, 443.3, 549.3, 443.3,
+549.3, 443.4, 549.3, 443.5, 557.9, 450.1, 548.7, 462.0, 548.1, 480.6,
+548.3, 478.7, 547.6, 478.7, 547.0, 476.8, 544.5, 467.9, 544.5, 467.9,
+541.9, 459.0, 540.7, 454.7, 540.7, 454.7, 539.5, 450.4, 538.8, 448.1,
+538.4, 448.1, 538.1, 445.8, 499.7, 607.6, 492.9, 624.4, 493.4, 624.6,
+486.2, 641.2, 479.6, 657.2, 478.0, 656.7, 472.9, 673.2, 459.6, 660.6,
+460.3, 644.6, 468.4, 624.5, 473.6, 611.8, 495.6, 603.8, 499.7, 607.6,
+468.4, 624.5, 468.3, 623.1, 468.3, 623.1, 468.2, 621.6, 468.1, 621.0,
+468.2, 621.0, 468.3, 620.3, 466.7, 616.9, 475.7, 614.6, 476.1, 608.4,
+497.1, 588.7, 503.3, 585.9, 508.7, 559.0, 509.0, 559.2, 512.5, 553.3,
+516.3, 547.5, 515.7, 548.6, 516.4, 549.0, 516.5, 550.4, 518.6, 551.0,
+516.7, 557.5, 517.0, 564.6, 508.0, 586.0, 508.3, 586.1, 499.7, 607.6,
+495.6, 603.8, 473.6, 611.8, 468.4, 624.5, 446.4, 372.4, 445.7, 370.9,
+445.1, 370.9, 445.0, 369.4, 444.8, 366.7, 444.8, 366.7, 444.5, 364.1,
+444.1, 362.0, 444.8, 361.9, 445.1, 359.6, 444.3, 355.2, 446.4, 354.8,
+447.8, 349.9, 448.9, 361.0, 448.0, 361.3, 446.4, 372.4, 191.5, 616.5,
+188.4, 624.7, 188.4, 624.7, 185.3, 632.9, 179.2, 628.3, 179.6, 619.8,
+183.2, 610.3, 182.7, 611.6, 191.2, 613.0, 191.5, 616.5, 183.2, 610.3,
+174.4, 552.3, 178.0, 551.8, 172.8, 493.4, 172.9, 493.2, 172.9, 493.2,
+172.9, 493.1, 178.5, 505.2, 179.3, 504.9, 185.8, 516.6, 190.9, 543.6,
+189.3, 545.5, 202.3, 569.3, 197.7, 591.0, 197.7, 591.0, 193.0, 612.6,
+192.7, 614.6, 192.3, 614.5, 191.5, 616.5, 191.2, 613.0, 182.7, 611.6,
+183.2, 610.3, 168.3, 506.7, 170.6, 500.0, 170.6, 500.0, 172.8, 493.4,
+178.0, 551.8, 174.4, 552.3, 183.2, 610.3, 179.6, 619.8, 179.2, 628.3,
+185.3, 632.9, 183.7, 636.8, 182.7, 636.7, 182.2, 640.8, 174.0, 627.6,
+163.2, 624.8, 165.9, 614.5, 165.1, 609.2, 165.1, 609.2, 164.4, 603.8,
+165.5, 555.2, 164.6, 555.1, 168.3, 506.7, 164.4, 603.8, 161.6, 583.3,
+161.6, 583.3, 158.8, 562.8, 159.4, 553.5, 160.5, 553.3, 159.2, 544.2,
+161.2, 532.8, 165.9, 522.6, 163.3, 521.4, 165.8, 514.0, 165.8, 514.0,
+168.3, 506.7, 164.6, 555.1, 165.5, 555.2, 164.4, 603.8, 403.1, 653.0,
+392.2, 650.9, 391.3, 646.7, 381.3, 648.8, 383.1, 641.1, 387.8, 636.1,
+385.0, 633.5, 395.5, 622.4, 389.1, 616.4, 393.3, 599.3, 408.9, 616.2,
+408.9, 628.7, 403.1, 653.0, 406.4, 715.8, 406.4, 715.7, 406.4, 715.7,
+406.5, 715.6, 416.6, 688.1, 421.7, 688.2, 424.1, 659.7, 430.8, 639.9,
+431.3, 640.1, 438.6, 620.5, 441.4, 612.6, 441.4, 612.6, 444.3, 604.8,
+443.2, 597.4, 447.3, 596.8, 450.2, 588.8, 440.7, 632.2, 441.2, 632.3,
+432.1, 675.9, 424.6, 697.5, 419.2, 695.7, 406.5, 715.6, 406.4, 715.7,
+406.4, 715.7, 406.4, 715.8, 432.1, 675.9, 428.8, 691.6, 429.7, 691.9,
+425.5, 707.4, 421.8, 725.3, 421.8, 725.3, 418.1, 743.1, 416.7, 749.7,
+416.7, 749.7, 415.4, 756.3, 414.9, 758.5, 413.6, 760.2, 414.4, 760.8,
+409.1, 754.3, 409.1, 754.3, 403.8, 747.8, 407.7, 747.1, 412.9, 726.6,
+406.2, 718.4, 406.0, 718.3, 406.3, 717.1, 406.4, 715.8, 418.8, 695.5,
+414.0, 683.8, 432.1, 675.9, 458.7, 682.6, 460.2, 708.3, 460.1, 708.3,
+461.7, 734.0, 463.1, 739.0, 458.0, 740.4, 454.2, 746.8, 450.4, 731.2,
+455.4, 730.0, 456.6, 713.1, 457.6, 697.9, 462.2, 696.8, 458.7, 682.6,
+439.7, 554.0, 441.7, 549.1, 443.5, 549.1, 443.6, 544.2, 444.0, 574.5,
+439.9, 575.1, 444.3, 604.8, 441.4, 612.6, 441.4, 612.6, 438.6, 620.5,
+435.6, 587.6, 437.6, 587.1, 439.7, 554.0, 438.6, 620.5, 431.3, 640.1,
+430.8, 639.9, 424.1, 659.7, 422.2, 683.1, 414.6, 682.2, 407.3, 705.4,
+407.5, 703.4, 407.5, 703.4, 407.6, 701.4, 413.1, 685.3, 410.4, 684.4,
+412.4, 667.3, 417.8, 633.8, 417.1, 633.6, 421.8, 600.0, 422.4, 576.8,
+430.8, 577.0, 439.7, 554.0, 437.6, 587.1, 435.6, 587.6, 438.6, 620.5,
+392.3, 792.8, 390.7, 784.7, 386.5, 785.5, 380.8, 778.2, 371.1, 765.9,
+366.9, 767.5, 361.4, 753.6, 362.4, 743.8, 362.4, 743.8, 363.4, 734.1,
+364.5, 737.8, 368.3, 736.6, 373.2, 739.2, 385.7, 764.5, 386.9, 765.2,
+392.3, 792.8, 395.0, 861.0, 396.6, 870.7, 394.0, 872.0, 398.3, 880.4,
+382.6, 873.9, 382.6, 873.9, 366.8, 867.4, 369.6, 865.9, 366.3, 859.8,
+365.7, 852.2, 361.5, 819.0, 363.7, 818.8, 361.6, 785.4, 387.3, 793.1,
+380.1, 822.5, 395.0, 861.0, 361.6, 785.4, 361.0, 774.7, 361.6, 774.6,
+360.3, 764.1, 360.9, 758.8, 360.9, 758.8, 361.4, 753.6, 366.9, 767.5,
+371.1, 765.9, 380.8, 778.2, 389.5, 801.5, 385.1, 803.2, 389.3, 828.2,
+396.7, 830.6, 392.2, 844.6, 395.0, 861.0, 380.1, 822.5, 387.3, 793.1,
+361.6, 785.4, 436.3, 874.3, 412.8, 851.2, 417.3, 837.2, 389.3, 828.2,
+385.1, 803.2, 389.5, 801.5, 380.8, 778.2, 386.5, 785.5, 390.7, 784.7,
+392.3, 792.8, 393.5, 794.3, 393.5, 794.3, 394.7, 795.9, 407.7, 812.4,
+407.7, 812.4, 420.7, 828.9, 428.5, 829.0, 428.4, 838.7, 436.1, 848.5,
+440.1, 860.0, 431.5, 872.2, 436.3, 874.3, 436.1, 848.5, 444.4, 858.9,
+442.1, 862.3, 452.6, 869.4, 451.9, 874.1, 452.4, 874.2, 451.3, 878.7,
+450.8, 880.6, 450.5, 882.6, 450.3, 882.5, 448.4, 883.8, 446.9, 883.9,
+444.9, 882.7, 442.2, 883.6, 440.6, 878.5, 436.3, 874.3, 431.5, 872.2,
+440.1, 860.0, 436.1, 848.5, 383.8, 232.7, 386.1, 216.4, 392.4, 214.6,
+388.3, 200.2, 389.4, 199.1, 389.4, 199.1, 390.4, 198.0, 388.0, 215.4,
+394.0, 221.9, 383.8, 232.7, 284.3, 466.1, 288.2, 469.9, 287.7, 470.6,
+292.1, 473.7, 296.3, 475.1, 295.0, 478.2, 299.2, 480.6, 316.5, 484.7,
+314.1, 495.1, 329.0, 509.6, 330.1, 511.2, 327.3, 513.3, 325.6, 516.9,
+320.7, 527.7, 323.9, 534.9, 315.8, 538.5, 315.8, 538.5, 312.6, 531.3,
+309.5, 524.1, 301.1, 504.9, 301.1, 504.9, 292.8, 485.6, 288.5, 475.9,
+284.9, 476.1, 284.3, 466.1, 358.5, 448.9, 362.0, 453.0, 362.0, 453.0,
+365.6, 457.1, 373.1, 463.9, 370.3, 467.0, 374.9, 477.0, 371.0, 472.7,
+364.3, 478.8, 353.6, 480.6, 349.6, 477.1, 355.1, 470.8, 356.6, 461.0,
+357.2, 457.1, 357.2, 457.1, 357.8, 453.2, 358.1, 451.1, 359.1, 449.2,
+358.5, 448.9, 417.7, 384.1, 404.9, 370.3, 406.4, 368.4, 392.0, 356.6,
+390.1, 353.7, 388.6, 350.6, 388.2, 350.8, 389.5, 348.0, 386.2, 343.5,
+381.6, 341.0, 375.3, 339.9, 376.4, 333.1, 371.2, 325.2, 375.1, 328.5,
+377.6, 325.6, 384.0, 325.9, 401.6, 337.3, 403.5, 340.5, 423.8, 341.6,
+424.2, 342.3, 424.2, 342.3, 424.7, 343.1, 421.8, 363.6, 427.9, 379.8,
+417.7, 384.1, 424.7, 343.1, 432.4, 355.7, 432.0, 356.0, 440.0, 368.4,
+440.9, 383.7, 440.9, 383.7, 441.8, 399.1, 442.4, 401.0, 441.3, 401.3,
+440.8, 403.5, 440.7, 403.7, 439.2, 403.4, 437.6, 403.3, 437.8, 400.6,
+433.8, 400.3, 430.0, 397.2, 422.5, 394.9, 423.9, 390.6, 417.7, 384.1,
+427.9, 379.8, 421.8, 363.6, 424.7, 343.1, 355.4, 366.8, 358.1, 370.8,
+357.9, 374.7, 360.7, 374.8, 352.1, 382.3, 352.1, 382.3, 343.5, 389.8,
+340.0, 384.6, 346.3, 374.7, 355.4, 366.8, 418.9, 459.8, 393.4, 453.0,
+367.7, 447.2, 367.9, 446.3, 366.7, 445.3, 366.7, 445.3, 365.4, 444.3,
+365.4, 444.7, 366.6, 444.6, 367.8, 445.0, 393.3, 452.4, 417.7, 449.6,
+418.9, 459.8, 262.9, 486.8, 261.9, 491.5, 261.0, 496.3, 261.0, 496.3,
+259.6, 503.2, 259.6, 503.2, 258.1, 510.1, 259.7, 503.9, 259.4, 503.9,
+260.7, 497.6, 261.8, 492.2, 261.5, 492.1, 262.9, 486.8, 118.7, 318.3,
+119.2, 321.0, 119.2, 321.0, 119.8, 323.7, 122.1, 325.8, 107.3, 335.3,
+108.8, 344.5, 106.6, 339.6, 106.6, 339.6, 104.4, 334.7, 106.1, 328.2,
+109.4, 329.0, 114.3, 323.3, 116.5, 320.8, 116.7, 318.2, 118.7, 318.3,
+925.0, 270.0, 923.2, 270.9, 923.2, 270.9, 921.4, 271.7, 910.6, 274.7,
+910.2, 274.1, 900.1, 278.9, 892.2, 274.4, 892.2, 274.4, 884.2, 269.9,
+853.6, 232.9, 850.9, 235.1, 817.5, 200.3, 861.1, 193.4, 867.2, 232.5,
+916.9, 264.8, 921.0, 267.4, 922.6, 266.3, 925.0, 270.0, 704.8, 239.4,
+704.8, 239.2, 714.5, 236.3, 722.0, 239.1, 727.1, 241.1, 726.0, 244.0,
+729.9, 248.9, 747.4, 270.5, 766.2, 271.9, 764.8, 292.2, 765.0, 289.6,
+744.5, 291.9, 727.4, 284.4, 723.0, 282.4, 724.6, 278.8, 721.8, 273.1,
+713.3, 256.2, 704.7, 256.2, 704.8, 239.4, 666.3, 239.8, 663.2, 236.4,
+657.8, 242.9, 652.5, 240.0, 645.6, 232.5, 645.6, 232.5, 638.7, 224.9,
+652.4, 224.8, 656.3, 228.9, 666.3, 239.8, 773.6, 303.1, 775.2, 302.3,
+778.8, 309.5, 784.0, 315.9, 784.0, 316.8, 785.5, 317.1, 785.4, 317.7,
+785.1, 318.9, 784.8, 320.1, 784.9, 320.1, 781.7, 321.8, 783.7, 325.5,
+782.6, 330.9, 778.5, 328.6, 777.8, 329.9, 773.0, 328.8, 768.4, 327.9,
+768.5, 327.3, 763.9, 325.8, 764.2, 314.4, 765.2, 307.2, 773.6, 303.1,
+697.2, 208.4, 686.5, 202.6, 682.2, 199.0, 680.7, 187.9, 687.8, 190.0,
+690.8, 194.8, 695.0, 192.2, 697.4, 194.4, 698.4, 193.2, 701.9, 194.3,
+726.8, 215.2, 729.6, 211.8, 757.4, 229.3, 757.5, 228.9, 724.9, 223.3,
+697.2, 208.4, 624.2, 224.7, 614.0, 205.7, 616.0, 204.4, 603.8, 186.8,
+608.6, 192.1, 608.6, 192.1, 613.4, 197.3, 620.3, 210.2, 614.9, 214.5,
+624.2, 224.7, 484.2, 186.0, 456.3, 171.2, 457.3, 169.0, 428.4, 156.5,
+427.8, 156.2, 427.8, 156.2, 427.2, 155.8, 455.7, 170.8, 457.2, 168.6,
+484.2, 186.0, 620.2, 5.5, 620.2, 10.6, 617.8, 13.9, 620.2, 15.7,
+610.8, 19.2, 610.8, 19.2, 601.4, 22.8, 598.7, 18.3, 595.3, 19.3,
+588.8, 18.1, 583.6, 9.6, 583.6, 9.6, 578.5, 1.0, 584.0, -3.9,
+578.1, -10.7, 577.7, -22.4, 577.6, -21.7, 578.8, -21.6, 580.0, -20.8,
+600.1, -7.7, 602.6, -10.4, 620.2, 5.5, 151.7, 366.1, 155.5, 333.2,
+157.2, 333.4, 159.2, 300.4, 164.9, 298.4, 164.9, 298.4, 170.5, 296.4,
+166.4, 331.9, 170.9, 359.3, 151.7, 366.1, 170.5, 296.4, 171.2, 296.2,
+171.2, 296.2, 172.0, 295.9, 171.6, 299.5, 180.8, 306.1, 185.4, 304.5,
+183.7, 322.7, 183.7, 322.7, 182.0, 340.9, 165.8, 368.5, 158.1, 366.7,
+150.4, 396.6, 150.3, 396.6, 150.3, 396.6, 150.3, 396.7, 149.9, 392.5,
+149.9, 392.5, 149.5, 388.3, 149.1, 384.6, 149.8, 384.5, 150.0, 380.7,
+150.3, 373.4, 150.8, 373.4, 151.7, 366.1, 170.9, 359.3, 166.4, 331.9,
+170.5, 296.4, 618.3, 687.8, 619.4, 679.0, 603.6, 678.6, 602.3, 667.7,
+612.9, 644.7, 605.8, 641.4, 609.2, 615.2, 628.7, 639.7, 622.9, 652.7,
+618.3, 687.8, 705.5, 618.5, 711.2, 627.4, 711.2, 627.4, 716.9, 636.3,
+710.2, 655.5, 702.4, 652.8, 687.9, 669.3, 675.3, 683.7, 676.1, 684.5,
+662.7, 698.1, 662.7, 697.2, 661.9, 697.2, 661.2, 696.3, 664.7, 687.9,
+665.7, 688.3, 670.2, 680.4, 674.1, 673.6, 674.1, 673.6, 678.0, 666.8,
+691.7, 642.6, 685.3, 634.3, 705.5, 618.5, 743.5, 725.6, 741.4, 730.8,
+743.2, 733.3, 739.3, 736.1, 735.2, 740.4, 735.2, 740.4, 731.1, 744.7,
+721.4, 738.3, 724.7, 733.4, 718.2, 722.2, 717.3, 720.6, 717.3, 720.6,
+716.3, 718.9, 710.1, 708.1, 710.1, 708.1, 703.9, 697.2, 703.3, 696.1,
+703.6, 695.6, 702.6, 694.9, 712.2, 701.4, 711.9, 701.9, 721.2, 708.8,
+730.6, 715.9, 730.6, 715.9, 739.9, 722.9, 741.7, 724.2, 743.6, 724.3,
+743.5, 725.6, 685.5, 772.8, 679.5, 765.3, 672.3, 759.2, 673.6, 757.7,
+672.1, 756.0, 672.1, 756.0, 670.7, 754.2, 667.7, 750.4, 667.7, 750.4,
+664.7, 746.6, 664.1, 745.8, 664.1, 745.8, 663.5, 745.0, 653.5, 732.4,
+648.2, 734.2, 643.6, 719.9, 648.2, 719.6, 647.9, 714.9, 652.3, 710.0,
+670.8, 731.5, 665.9, 735.7, 679.5, 761.5, 682.5, 767.1, 680.8, 769.9,
+685.5, 772.8, 575.0, 633.2, 573.1, 630.7, 572.8, 628.1, 571.1, 628.3,
+573.3, 624.9, 563.2, 618.2, 555.2, 608.1, 549.9, 593.8, 552.4, 591.6,
+543.2, 580.0, 545.2, 564.5, 545.2, 564.5, 547.1, 549.0, 544.2, 551.1,
+550.9, 560.4, 554.6, 571.8, 564.8, 602.5, 566.0, 602.2, 575.0, 633.2,
+552.2, 531.6, 552.3, 531.5, 551.5, 531.2, 551.5, 531.1, 556.7, 512.6,
+556.7, 512.6, 561.8, 494.2, 561.8, 493.9, 562.9, 493.9, 564.0, 493.7,
+563.0, 500.5, 561.9, 500.3, 559.9, 507.0, 556.0, 519.3, 556.4, 519.4,
+552.2, 531.6, 550.7, 745.6, 554.9, 762.5, 548.5, 769.2, 559.2, 779.4,
+552.8, 784.7, 553.7, 788.1, 546.4, 789.9, 533.1, 797.2, 533.1, 797.2,
+519.9, 804.5, 522.8, 773.9, 526.4, 761.1, 550.7, 745.6, 519.9, 804.5,
+517.5, 805.8, 515.6, 805.4, 515.2, 807.1, 519.5, 772.2, 519.5, 772.2,
+523.8, 737.3, 523.0, 735.9, 534.1, 729.0, 544.4, 720.7, 547.5, 733.2,
+547.5, 733.2, 550.7, 745.6, 526.4, 761.1, 522.8, 773.9, 519.9, 804.5,
+580.6, 673.2, 579.5, 662.6, 575.3, 653.6, 578.4, 652.1, 579.7, 646.3,
+581.0, 646.3, 580.9, 640.6, 585.5, 646.4, 590.7, 651.6, 590.1, 652.2,
+589.9, 652.7, 591.6, 653.5, 591.4, 653.9, 590.6, 659.9, 604.0, 664.1,
+602.3, 667.7, 603.6, 678.6, 619.4, 679.0, 618.3, 687.8, 618.4, 688.0,
+618.4, 688.2, 618.6, 688.3, 602.2, 681.9, 602.3, 681.8, 586.0, 675.3,
+583.3, 674.2, 581.2, 674.9, 580.6, 673.2, 531.6, 700.1, 530.3, 697.9,
+528.6, 697.6, 529.0, 695.8, 529.9, 688.2, 529.6, 688.2, 530.8, 680.6,
+531.2, 678.3, 531.1, 678.3, 531.4, 675.9, 535.0, 679.2, 545.9, 667.5,
+560.3, 659.1, 560.5, 679.5, 547.8, 681.1, 531.6, 700.1, 611.2, 757.1,
+629.3, 783.0, 624.2, 786.6, 637.1, 816.1, 639.1, 820.5, 640.9, 820.5,
+641.0, 824.9, 639.3, 828.4, 639.3, 828.4, 637.6, 831.9, 624.6, 834.2,
+616.6, 837.5, 610.6, 830.4, 603.2, 821.6, 610.7, 815.3, 610.8, 800.2,
+610.9, 794.7, 610.9, 794.7, 610.9, 789.2, 611.0, 784.0, 611.0, 784.0,
+611.0, 778.7, 611.1, 767.9, 616.2, 764.3, 611.2, 757.1, 670.7, 754.2,
+672.1, 756.0, 672.1, 756.0, 673.6, 757.7, 650.1, 785.2, 657.3, 791.3,
+641.0, 824.9, 640.9, 820.5, 639.1, 820.5, 637.1, 816.1, 641.6, 801.5,
+644.6, 802.4, 652.0, 788.7, 661.4, 771.4, 659.6, 770.2, 670.7, 754.2,
+626.7, 848.5, 592.0, 862.9, 591.6, 861.8, 557.4, 877.2, 556.7, 874.7,
+556.7, 874.7, 556.1, 872.2, 590.4, 857.9, 627.4, 851.2, 626.7, 848.5,
+547.0, 476.8, 547.6, 478.7, 548.3, 478.7, 548.1, 480.6, 548.0, 483.4,
+548.0, 483.4, 547.9, 486.2, 546.7, 481.7, 546.9, 481.5, 547.0, 476.8,
+492.2, 356.2, 480.9, 370.9, 480.9, 370.9, 469.6, 385.7, 467.7, 382.6,
+463.9, 385.0, 458.3, 384.2, 462.7, 374.2, 467.7, 376.4, 477.2, 368.6,
+484.7, 362.4, 488.7, 364.1, 492.2, 356.2, 396.9, 584.7, 408.3, 546.9,
+410.4, 547.4, 419.7, 509.1, 420.3, 514.1, 421.1, 514.2, 420.8, 519.2,
+420.7, 532.8, 420.4, 532.8, 420.6, 546.5, 419.9, 555.0, 419.9, 555.0,
+419.2, 563.4, 411.4, 576.1, 397.0, 574.0, 396.9, 584.7, 419.2, 563.4,
+415.4, 609.0, 415.4, 609.0, 411.6, 654.6, 411.0, 652.7, 407.3, 653.8,
+403.1, 653.0, 408.9, 628.7, 408.9, 616.2, 393.3, 599.3, 394.8, 593.0,
+394.8, 593.0, 396.3, 586.8, 396.5, 585.7, 396.6, 585.7, 396.9, 584.7,
+397.0, 574.0, 411.4, 576.1, 419.2, 563.4, 418.1, 743.1, 421.8, 725.3,
+421.8, 725.3, 425.5, 707.4, 433.4, 674.3, 434.0, 674.4, 442.2, 641.3,
+444.8, 630.6, 447.3, 619.8, 447.3, 619.8, 447.3, 619.8, 444.8, 630.6,
+442.2, 641.3, 435.7, 668.8, 435.7, 668.8, 429.2, 696.3, 423.6, 719.7,
+425.6, 720.3, 418.1, 743.1, 394.7, 795.9, 393.5, 794.3, 393.5, 794.3,
+392.3, 792.8, 386.9, 765.2, 385.7, 764.5, 373.2, 739.2, 388.1, 746.8,
+402.3, 755.6, 403.0, 754.5, 420.6, 782.9, 420.6, 782.9, 438.3, 811.2,
+438.9, 808.0, 416.1, 804.5, 394.7, 795.9, 438.3, 811.2, 438.3, 811.3,
+438.3, 811.3, 438.3, 811.3, 444.2, 830.0, 444.2, 830.0, 450.1, 848.6,
+437.5, 836.6, 435.5, 829.1, 420.7, 828.9, 407.7, 812.4, 407.7, 812.4,
+394.7, 795.9, 416.1, 804.5, 438.9, 808.0, 438.3, 811.2, 416.1, 188.1,
+416.4, 242.1, 416.0, 242.1, 416.8, 296.1, 407.0, 281.7, 407.0, 281.7,
+397.3, 267.3, 397.0, 227.8, 431.5, 210.9, 416.1, 188.1, 397.3, 267.3,
+390.0, 256.5, 379.9, 250.3, 382.7, 245.8, 382.5, 244.4, 382.5, 244.4,
+382.3, 243.1, 381.0, 238.5, 383.0, 237.9, 383.8, 232.7, 394.0, 221.9,
+388.0, 215.4, 390.4, 198.0, 401.1, 186.7, 400.3, 185.7, 411.9, 175.4,
+413.9, 173.3, 413.9, 173.3, 416.0, 171.3, 415.9, 179.7, 416.0, 179.7,
+416.1, 188.1, 431.5, 210.9, 397.0, 227.8, 397.3, 267.3, 275.3, 881.2,
+275.2, 881.7, 275.2, 882.2, 275.0, 882.2, 263.9, 882.6, 255.8, 887.0,
+252.7, 881.9, 240.2, 861.3, 244.8, 856.5, 243.7, 830.9, 244.0, 836.8,
+247.3, 836.7, 251.0, 842.4, 255.4, 849.5, 255.4, 849.5, 259.8, 856.5,
+264.9, 864.6, 264.9, 864.6, 270.1, 872.8, 272.7, 877.0, 273.1, 876.8,
+275.3, 881.2, 239.4, 806.4, 234.4, 814.0, 241.5, 818.6, 243.7, 830.9,
+244.8, 856.5, 240.2, 861.3, 252.7, 881.9, 246.6, 891.2, 211.6, 885.1,
+210.9, 881.3, 205.0, 847.4, 218.0, 839.2, 239.4, 806.4, 210.9, 881.3,
+210.8, 881.6, 209.1, 881.3, 209.1, 881.3, 212.1, 865.4, 209.0, 864.8,
+208.8, 848.4, 207.5, 838.4, 210.5, 838.1, 212.2, 827.7, 209.5, 826.6,
+221.9, 795.2, 231.7, 762.7, 223.7, 770.7, 235.1, 782.2, 238.5, 801.7,
+239.0, 804.0, 240.0, 804.4, 239.4, 806.4, 218.0, 839.2, 205.0, 847.4,
+210.9, 881.3, 359.2, 595.6, 360.1, 607.6, 363.8, 608.6, 361.0, 619.6,
+360.5, 623.2, 360.5, 623.2, 360.0, 626.8, 311.7, 667.4, 312.0, 667.8,
+264.0, 708.7, 275.7, 699.7, 273.7, 697.1, 283.5, 685.5, 292.3, 675.0,
+292.3, 675.0, 301.1, 664.5, 313.0, 650.4, 313.0, 650.4, 324.9, 636.3,
+342.0, 615.9, 337.3, 605.7, 359.2, 595.6, 355.4, 543.6, 356.1, 553.6,
+356.1, 553.6, 356.8, 563.5, 339.0, 591.0, 311.6, 612.4, 311.1, 611.9,
+307.1, 608.3, 329.4, 583.6, 347.8, 555.3, 351.6, 549.5, 356.2, 544.4,
+355.4, 543.6, 257.4, 569.9, 257.2, 564.7, 255.6, 564.2, 257.0, 559.6,
+259.6, 544.0, 258.2, 543.6, 262.2, 528.4, 267.1, 506.8, 262.2, 505.2,
+269.5, 484.6, 270.8, 480.4, 270.8, 480.4, 272.0, 476.1, 273.8, 480.1,
+271.2, 481.3, 270.4, 486.5, 263.9, 528.2, 265.0, 528.4, 257.4, 569.9,
+279.0, 460.9, 279.1, 460.5, 278.2, 460.2, 277.5, 459.5, 277.2, 459.3,
+277.0, 459.2, 277.0, 459.0, 283.9, 435.5, 283.9, 435.5, 290.7, 411.9,
+300.0, 420.9, 285.7, 436.7, 279.0, 460.9, 308.0, 359.7, 310.3, 354.7,
+310.3, 354.7, 312.7, 349.7, 314.3, 352.2, 333.6, 348.9, 337.7, 340.1,
+346.5, 353.4, 346.5, 353.4, 355.4, 366.8, 346.3, 374.7, 340.0, 384.6,
+343.5, 389.8, 341.5, 391.6, 341.5, 391.6, 339.5, 393.3, 322.1, 378.5,
+319.9, 378.9, 308.0, 359.7, 339.5, 393.3, 337.2, 395.3, 334.6, 396.8,
+334.9, 397.3, 323.6, 396.7, 316.9, 390.7, 312.2, 396.0, 305.9, 388.8,
+301.7, 380.5, 299.6, 381.6, 301.0, 376.6, 301.0, 376.6, 302.4, 371.7,
+303.9, 365.4, 305.2, 365.7, 308.0, 359.7, 319.9, 378.9, 322.1, 378.5,
+339.5, 393.3, 431.3, 441.1, 431.5, 441.2, 431.6, 441.2, 431.6, 441.3,
+431.6, 441.3, 431.6, 441.3, 431.6, 441.3, 431.5, 441.2, 431.3, 441.1,
+431.3, 441.1, 260.7, 497.6, 259.4, 503.9, 259.7, 503.9, 258.1, 510.1,
+256.8, 515.4, 255.8, 520.7, 255.8, 520.7, 249.4, 547.7, 250.8, 548.1,
+242.9, 574.7, 241.7, 578.5, 241.8, 578.5, 240.7, 582.4, 239.4, 588.6,
+238.4, 588.4, 236.0, 594.4, 240.5, 560.0, 241.1, 558.2, 234.6, 524.2,
+242.6, 503.9, 242.6, 503.9, 250.5, 483.7, 249.5, 484.7, 258.5, 489.8,
+260.7, 497.6, 250.5, 483.7, 251.2, 482.0, 251.0, 482.0, 251.8, 480.4,
+262.3, 459.0, 262.3, 459.0, 272.8, 437.6, 267.5, 462.1, 267.9, 462.2,
+262.9, 486.8, 261.5, 492.1, 261.8, 492.2, 260.7, 497.6, 258.5, 489.8,
+249.5, 484.7, 250.5, 483.7, 114.3, 323.3, 109.4, 329.0, 106.1, 328.2,
+104.4, 334.7, 90.8, 304.5, 90.8, 304.5, 77.2, 274.3, 74.8, 270.2,
+76.4, 269.2, 75.5, 264.2, 92.4, 285.4, 90.4, 286.9, 105.3, 309.6,
+109.8, 316.5, 114.5, 316.6, 114.3, 323.3, 721.8, 273.1, 724.6, 278.8,
+723.0, 282.4, 727.4, 284.4, 727.4, 284.5, 723.5, 283.6, 719.5, 282.8,
+717.0, 282.2, 717.0, 282.2, 714.4, 281.7, 699.8, 278.7, 698.9, 280.9,
+685.2, 275.6, 681.5, 271.6, 681.5, 271.6, 677.8, 267.5, 699.5, 266.0,
+701.2, 266.2, 721.8, 273.1, 677.8, 267.5, 665.2, 253.8, 665.2, 253.8,
+652.5, 240.0, 657.8, 242.9, 663.2, 236.4, 666.3, 239.8, 685.6, 239.6,
+690.8, 230.9, 704.8, 239.4, 704.7, 256.2, 713.3, 256.2, 721.8, 273.1,
+701.2, 266.2, 699.5, 266.0, 677.8, 267.5, 641.5, 196.5, 647.2, 188.0,
+652.8, 179.4, 653.0, 179.5, 666.8, 183.7, 666.8, 183.7, 680.7, 187.9,
+682.2, 199.0, 686.5, 202.6, 697.2, 208.4, 705.9, 219.2, 705.9, 219.2,
+714.6, 230.0, 715.2, 230.7, 715.9, 231.3, 715.8, 231.4, 715.7, 231.6,
+715.0, 231.0, 714.1, 230.6, 677.8, 213.5, 671.3, 221.4, 641.5, 196.5,
+686.3, 276.8, 685.8, 276.2, 685.8, 276.2, 685.2, 275.6, 698.9, 280.9,
+699.8, 278.7, 714.4, 281.7, 706.7, 273.4, 700.2, 279.7, 686.3, 276.8,
+714.6, 230.0, 705.9, 219.2, 705.9, 219.2, 697.2, 208.4, 724.9, 223.3,
+757.5, 228.9, 757.4, 229.3, 757.4, 229.3, 757.4, 229.3, 757.4, 229.3,
+741.4, 229.6, 741.4, 229.6, 725.3, 229.8, 720.0, 229.9, 718.0, 232.5,
+714.6, 230.0, 652.8, 277.4, 638.5, 251.0, 638.5, 251.0, 624.2, 224.7,
+614.9, 214.5, 620.3, 210.2, 613.4, 197.3, 620.0, 204.5, 620.0, 204.5,
+626.6, 211.7, 626.7, 211.8, 626.7, 211.8, 626.8, 212.0, 626.8, 212.0,
+626.8, 212.0, 626.8, 212.0, 655.9, 255.9, 655.5, 256.1, 685.6, 299.3,
+696.0, 315.0, 696.0, 315.0, 706.4, 330.7, 700.6, 324.6, 698.1, 326.9,
+689.7, 323.2, 669.0, 302.6, 669.0, 301.8, 652.8, 277.4, 689.7, 323.2,
+681.7, 319.5, 675.5, 321.6, 673.6, 315.9, 673.6, 315.8, 673.6, 315.8,
+673.5, 315.8, 673.6, 315.7, 663.2, 296.6, 652.8, 277.4, 669.0, 301.8,
+669.0, 302.6, 689.7, 323.2, 521.4, 200.9, 516.3, 200.1, 515.0, 201.9,
+511.1, 199.4, 505.2, 196.6, 505.2, 196.6, 499.3, 193.9, 491.5, 190.5,
+491.8, 189.9, 484.2, 186.0, 456.3, 171.2, 457.3, 169.0, 428.4, 156.5,
+427.8, 156.2, 427.8, 156.2, 427.2, 155.8, 423.8, 153.6, 423.0, 154.3,
+420.4, 151.4, 414.8, 145.9, 415.1, 145.5, 409.3, 140.3, 413.9, 139.4,
+413.9, 139.4, 418.6, 138.4, 425.7, 140.2, 425.1, 142.3, 431.7, 146.3,
+476.5, 173.6, 477.8, 171.7, 521.4, 200.9, 616.4, -54.1, 618.2, -44.7,
+618.2, -44.7, 620.1, -35.4, 629.9, -28.1, 620.1, -14.9, 620.2, 5.5,
+602.6, -10.4, 600.1, -7.7, 580.0, -20.8, 579.0, -36.3, 595.0, -46.3,
+616.4, -54.1, 580.0, -20.8, 578.8, -21.6, 577.6, -21.7, 577.7, -22.4,
+577.3, -31.7, 574.6, -40.2, 577.0, -41.0, 582.2, -57.8, 582.2, -57.8,
+587.3, -74.6, 593.8, -76.3, 595.3, -80.4, 597.6, -88.0, 597.7, -88.2,
+598.1, -88.3, 598.2, -88.1, 605.5, -82.0, 608.1, -83.2, 612.3, -75.3,
+615.4, -75.0, 614.4, -64.7, 616.4, -54.1, 595.0, -46.3, 579.0, -36.3,
+580.0, -20.8, 609.3, 615.1, 609.3, 614.5, 609.2, 614.5, 609.4, 614.0,
+616.4, 598.5, 612.9, 586.0, 623.3, 583.1, 625.3, 579.5, 626.3, 579.7,
+627.2, 575.8, 627.0, 576.2, 627.3, 576.4, 627.3, 576.9, 628.7, 597.0,
+628.7, 597.0, 630.0, 617.0, 631.0, 631.0, 631.0, 631.0, 631.9, 644.9,
+632.5, 653.6, 632.6, 653.6, 633.1, 662.4, 634.6, 686.3, 634.3, 686.3,
+635.9, 710.2, 635.9, 710.5, 636.4, 710.8, 636.4, 710.8, 636.4, 710.8,
+635.9, 710.5, 635.9, 710.2, 636.2, 709.4, 634.9, 708.8, 633.8, 707.5,
+620.9, 661.5, 621.3, 661.4, 609.3, 615.1, 633.8, 707.5, 632.3, 705.6,
+630.8, 703.8, 630.9, 703.8, 624.7, 696.0, 624.7, 696.0, 618.6, 688.3,
+618.4, 688.2, 618.4, 688.0, 618.3, 687.8, 622.9, 652.7, 628.7, 639.7,
+609.2, 615.2, 609.3, 615.2, 609.3, 615.2, 609.3, 615.1, 621.3, 661.4,
+620.9, 661.5, 633.8, 707.5, 696.0, 603.6, 696.3, 604.1, 696.3, 604.2,
+696.7, 604.7, 695.6, 610.5, 701.1, 611.6, 705.5, 618.5, 685.3, 634.3,
+691.7, 642.6, 678.0, 666.8, 683.9, 659.1, 680.8, 656.7, 683.7, 646.7,
+686.2, 637.8, 686.2, 637.8, 688.7, 629.0, 692.4, 616.3, 691.9, 616.1,
+696.0, 603.6, 727.2, 652.4, 737.6, 668.6, 733.2, 676.6, 747.9, 684.8,
+750.0, 690.9, 751.5, 690.4, 755.2, 696.0, 744.3, 704.0, 749.3, 710.8,
+743.5, 725.6, 743.6, 724.3, 741.7, 724.2, 739.9, 722.9, 734.8, 702.4,
+736.2, 702.0, 732.4, 681.1, 729.8, 666.8, 732.9, 653.7, 727.2, 652.4,
+679.5, 761.5, 665.9, 735.7, 670.8, 731.5, 652.3, 710.0, 654.4, 707.5,
+654.4, 707.5, 656.6, 705.1, 664.6, 716.4, 661.9, 718.3, 667.3, 731.5,
+671.8, 742.5, 671.8, 742.5, 676.3, 753.6, 677.2, 755.8, 677.2, 755.8,
+678.1, 758.1, 678.8, 759.8, 678.6, 759.8, 679.5, 761.5, 579.1, 629.3,
+577.6, 632.0, 576.4, 631.8, 576.1, 634.6, 575.6, 633.9, 575.6, 633.9,
+575.0, 633.2, 566.0, 602.2, 564.8, 602.5, 554.6, 571.8, 558.1, 584.8,
+560.0, 584.3, 565.3, 596.8, 572.2, 613.1, 574.3, 612.5, 579.1, 629.3,
+559.9, 507.0, 561.9, 500.3, 563.0, 500.5, 564.0, 493.7, 568.0, 492.8,
+572.1, 492.7, 572.1, 491.9, 576.3, 494.4, 580.8, 495.0, 580.6, 496.9,
+584.7, 505.2, 590.1, 502.5, 599.7, 508.2, 583.8, 515.9, 577.2, 514.0,
+559.9, 507.0, 613.0, 725.3, 604.5, 735.6, 603.8, 735.1, 595.9, 745.9,
+592.5, 750.0, 588.2, 752.9, 589.1, 754.2, 590.3, 743.5, 587.9, 743.2,
+586.8, 732.3, 588.7, 728.1, 593.8, 730.4, 600.8, 728.6, 606.9, 726.9,
+612.1, 728.4, 613.0, 725.3, 576.6, 650.0, 574.9, 663.4, 567.3, 670.3,
+573.1, 676.7, 567.5, 713.8, 563.1, 714.0, 563.4, 751.1, 558.5, 743.3,
+558.5, 743.3, 553.7, 735.5, 559.4, 692.0, 562.7, 692.0, 576.6, 650.0,
+553.7, 735.5, 549.1, 728.1, 549.1, 728.1, 544.4, 720.7, 538.1, 710.3,
+538.0, 710.4, 531.6, 700.1, 547.8, 681.1, 560.5, 679.5, 560.3, 659.1,
+568.5, 654.3, 571.0, 656.4, 576.7, 649.6, 576.6, 649.8, 576.6, 649.8,
+576.6, 650.0, 562.7, 692.0, 559.4, 692.0, 553.7, 735.5, 601.6, 740.8,
+602.5, 740.0, 602.5, 740.0, 603.4, 739.3, 608.2, 747.5, 607.2, 748.1,
+611.1, 756.9, 611.2, 757.0, 611.2, 757.0, 611.2, 757.1, 616.2, 764.3,
+611.1, 767.9, 611.0, 778.7, 611.9, 774.5, 609.9, 774.1, 608.7, 769.4,
+605.2, 755.1, 604.2, 755.3, 601.6, 740.8, 630.4, 715.1, 633.1, 712.6,
+634.5, 713.3, 635.9, 710.2, 635.9, 710.5, 636.4, 710.8, 636.4, 710.8,
+637.3, 715.8, 640.3, 720.1, 643.6, 719.9, 648.2, 734.2, 653.5, 732.4,
+663.5, 745.0, 660.2, 736.0, 655.5, 737.8, 647.5, 730.5, 638.9, 722.8,
+635.8, 724.6, 630.4, 715.1, 556.0, 871.7, 550.9, 851.6, 545.8, 831.4,
+545.8, 831.4, 546.6, 829.6, 545.2, 829.0, 544.5, 826.6, 554.0, 824.7,
+563.2, 824.2, 564.4, 827.7, 569.6, 842.9, 560.9, 845.9, 557.4, 864.1,
+556.7, 867.9, 554.8, 868.6, 556.0, 871.7, 514.8, 533.6, 503.1, 533.1,
+491.9, 530.4, 491.4, 532.6, 486.1, 528.4, 475.4, 529.7, 474.6, 531.9,
+474.7, 530.5, 474.7, 530.5, 474.8, 529.0, 469.2, 522.9, 486.6, 506.8,
+498.4, 484.5, 495.6, 487.0, 501.4, 493.6, 504.5, 502.6, 508.3, 514.0,
+508.3, 514.0, 512.1, 525.5, 513.5, 529.6, 514.9, 533.6, 514.8, 533.6,
+448.4, 376.8, 447.4, 374.6, 447.4, 374.6, 446.4, 372.4, 448.0, 361.3,
+448.9, 361.0, 447.8, 349.9, 451.7, 335.6, 451.7, 335.6, 455.6, 321.4,
+462.3, 334.2, 453.4, 338.8, 451.1, 356.2, 449.7, 366.5, 451.2, 367.0,
+448.4, 376.8, 442.2, 641.3, 444.8, 630.6, 447.3, 619.8, 447.3, 619.8,
+450.4, 607.2, 451.7, 607.4, 453.5, 594.6, 455.3, 625.3, 455.3, 625.3,
+457.1, 655.9, 458.4, 650.7, 444.6, 650.0, 442.2, 641.3, 305.5, 617.8,
+304.9, 615.7, 308.3, 614.8, 311.1, 611.9, 311.6, 612.4, 339.0, 591.0,
+356.8, 563.5, 358.0, 579.6, 358.0, 579.6, 359.2, 595.6, 337.3, 605.7,
+342.0, 615.9, 324.9, 636.3, 323.8, 637.1, 319.9, 631.5, 314.9, 626.8,
+310.2, 622.3, 306.8, 623.1, 305.5, 617.8, 273.1, 632.1, 273.6, 645.9,
+270.9, 655.3, 260.4, 660.1, 260.0, 649.2, 260.0, 649.2, 259.6, 638.3,
+262.0, 633.2, 273.2, 635.0, 273.1, 632.1, 356.6, 461.0, 355.1, 470.8,
+349.6, 477.1, 353.6, 480.6, 347.2, 481.7, 347.2, 481.7, 340.7, 482.8,
+342.5, 471.0, 347.1, 462.7, 356.6, 461.0, 410.9, 428.7, 421.1, 434.9,
+421.1, 434.9, 431.3, 441.1, 431.3, 441.1, 431.5, 441.2, 431.6, 441.3,
+429.9, 448.1, 429.0, 448.0, 428.3, 454.9, 428.0, 458.4, 427.4, 458.4,
+426.6, 461.9, 426.5, 460.5, 422.7, 460.9, 418.9, 459.8, 417.7, 449.6,
+393.3, 452.4, 367.8, 445.0, 367.1, 442.5, 388.9, 430.0, 410.9, 428.7,
+367.8, 445.0, 366.6, 444.6, 365.4, 444.7, 365.4, 444.3, 359.8, 439.8,
+359.8, 439.8, 354.1, 435.3, 368.9, 434.1, 368.0, 423.2, 381.9, 411.1,
+389.8, 423.9, 396.4, 419.9, 410.9, 428.7, 388.9, 430.0, 367.1, 442.5,
+367.8, 445.0, 68.2, 220.7, 67.1, 213.8, 64.9, 213.5, 65.9, 206.9,
+66.4, 193.9, 65.6, 193.9, 66.9, 181.0, 67.2, 178.0, 67.2, 178.0,
+67.4, 175.0, 67.9, 176.4, 68.0, 176.4, 68.6, 177.8, 82.1, 176.7,
+85.3, 216.6, 101.9, 255.4, 102.1, 238.2, 82.5, 239.9, 68.2, 220.7,
+819.3, 199.5, 818.6, 198.6, 817.2, 199.7, 816.1, 198.8, 809.4, 191.8,
+809.4, 191.8, 802.7, 184.8, 805.2, 187.7, 805.6, 187.3, 808.4, 189.9,
+810.7, 191.9, 810.7, 191.9, 813.0, 194.0, 816.1, 196.8, 817.1, 196.1,
+819.3, 199.5, 916.9, 264.8, 867.2, 232.5, 861.1, 193.4, 817.5, 200.3,
+816.8, 199.5, 816.8, 199.5, 816.1, 198.8, 817.2, 199.7, 818.6, 198.6,
+819.3, 199.5, 857.7, 208.5, 857.7, 208.3, 896.1, 217.4, 896.2, 217.4,
+896.3, 217.5, 896.3, 217.7, 906.7, 241.2, 902.2, 261.5, 916.9, 264.8,
+896.3, 217.7, 896.4, 217.7, 896.5, 217.6, 896.6, 217.7, 912.8, 229.1,
+912.7, 229.3, 929.0, 240.6, 934.5, 244.9, 934.5, 244.9, 940.1, 249.1,
+943.0, 254.3, 941.7, 255.7, 941.3, 262.2, 941.3, 262.5, 939.2, 262.7,
+939.3, 263.2, 939.6, 265.2, 925.6, 266.1, 925.5, 269.8, 925.5, 269.9,
+925.2, 269.9, 925.0, 270.0, 922.6, 266.3, 921.0, 267.4, 916.9, 264.8,
+904.8, 242.3, 906.9, 241.2, 896.6, 217.7, 896.5, 217.6, 896.4, 217.7,
+896.3, 217.7, 638.0, 224.2, 633.7, 219.4, 633.7, 219.4, 629.3, 214.7,
+636.9, 207.0, 635.4, 205.6, 641.5, 196.5, 671.3, 221.4, 677.8, 213.5,
+714.1, 230.6, 713.9, 232.2, 675.4, 231.2, 638.0, 224.2, 714.1, 230.6,
+715.0, 231.0, 715.7, 231.6, 715.8, 231.4, 719.2, 235.0, 721.8, 239.3,
+722.0, 239.1, 714.5, 236.3, 704.8, 239.2, 704.8, 239.4, 690.8, 230.9,
+685.6, 239.6, 666.3, 239.8, 656.3, 228.9, 652.4, 224.8, 638.7, 224.9,
+638.4, 224.6, 638.4, 224.6, 638.0, 224.2, 675.4, 231.2, 713.9, 232.2,
+714.1, 230.6, 719.5, 282.8, 723.5, 283.6, 727.4, 284.5, 727.4, 284.4,
+744.5, 291.9, 765.0, 289.6, 764.8, 292.2, 770.3, 294.4, 771.1, 303.5,
+773.3, 302.8, 766.0, 305.3, 763.9, 299.3, 754.4, 295.7, 737.0, 289.2,
+736.7, 290.0, 719.5, 282.8, 725.3, 229.8, 741.4, 229.6, 741.4, 229.6,
+757.4, 229.3, 769.7, 237.1, 769.7, 237.1, 782.1, 244.9, 778.4, 241.6,
+776.7, 243.5, 771.3, 242.0, 748.3, 235.9, 740.9, 244.0, 725.3, 229.8,
+519.0, 181.6, 528.0, 190.6, 526.3, 193.5, 537.0, 199.6, 538.5, 201.6,
+538.5, 201.6, 540.0, 203.6, 532.3, 199.4, 530.7, 202.2, 521.4, 200.9,
+477.8, 171.7, 476.5, 173.6, 431.7, 146.3, 434.6, 169.1, 477.1, 160.4,
+519.0, 181.6, 431.7, 146.3, 425.1, 142.3, 425.7, 140.2, 418.6, 138.4,
+432.6, 135.3, 433.1, 136.8, 446.7, 132.3, 455.3, 131.1, 458.1, 133.7,
+463.7, 128.7, 464.0, 128.4, 464.3, 128.6, 464.8, 128.5, 471.2, 135.4,
+471.8, 134.9, 478.7, 141.4, 503.0, 150.3, 498.8, 161.5, 519.0, 181.6,
+477.1, 160.4, 434.6, 169.1, 431.7, 146.3, 662.2, 550.8, 669.9, 559.1,
+668.4, 560.5, 674.6, 570.2, 678.1, 576.1, 676.7, 578.5, 682.0, 581.7,
+681.3, 582.6, 684.2, 587.1, 685.3, 586.9, 687.4, 596.0, 690.6, 595.2,
+696.0, 603.6, 691.9, 616.1, 692.4, 616.3, 688.7, 629.0, 673.2, 615.5,
+681.1, 606.5, 673.4, 583.9, 669.5, 572.2, 669.5, 572.2, 665.5, 560.5,
+663.8, 555.6, 665.4, 554.2, 662.2, 550.8, 721.2, 708.8, 711.9, 701.9,
+712.2, 701.4, 702.6, 694.9, 693.5, 684.1, 688.8, 682.7, 688.3, 669.9,
+688.6, 678.5, 695.3, 678.2, 702.3, 686.5, 711.7, 697.7, 720.7, 697.3,
+721.2, 708.8, 661.0, 700.0, 661.9, 699.0, 662.6, 699.1, 662.7, 698.1,
+676.1, 684.5, 675.3, 683.7, 687.9, 669.3, 687.9, 669.4, 688.1, 669.6,
+688.3, 669.9, 688.8, 682.7, 693.5, 684.1, 702.6, 694.9, 703.6, 695.6,
+703.3, 696.1, 703.9, 697.2, 692.5, 699.2, 692.3, 698.0, 680.6, 698.7,
+675.1, 699.1, 675.1, 699.1, 669.6, 699.4, 665.3, 699.7, 665.1, 700.8,
+661.0, 700.0, 592.4, 572.5, 589.3, 586.8, 582.8, 599.4, 586.2, 601.1,
+580.0, 612.0, 575.6, 621.5, 580.6, 626.7, 579.9, 628.0, 579.9, 628.0,
+579.1, 629.3, 574.3, 612.5, 572.2, 613.1, 565.3, 596.8, 568.7, 582.3,
+581.8, 570.3, 592.4, 572.5, 565.3, 596.8, 560.0, 584.3, 558.1, 584.8,
+554.6, 571.8, 550.9, 560.4, 544.2, 551.1, 547.1, 549.0, 547.3, 547.2,
+546.7, 546.9, 547.5, 545.3, 549.5, 538.2, 549.5, 538.2, 551.5, 531.1,
+551.5, 531.2, 552.3, 531.5, 552.2, 531.6, 554.8, 533.5, 554.8, 533.5,
+557.4, 535.4, 576.0, 549.0, 579.0, 546.1, 594.5, 562.6, 593.4, 567.5,
+593.4, 567.5, 592.4, 572.5, 581.8, 570.3, 568.7, 582.3, 565.3, 596.8,
+605.0, 514.1, 599.8, 538.4, 599.8, 538.4, 594.5, 562.6, 579.0, 546.1,
+576.0, 549.0, 557.4, 535.4, 560.7, 520.3, 594.6, 506.5, 605.0, 514.1,
+557.4, 535.4, 554.8, 533.5, 554.8, 533.5, 552.2, 531.6, 556.4, 519.4,
+556.0, 519.3, 559.9, 507.0, 577.2, 514.0, 583.8, 515.9, 599.7, 508.2,
+602.6, 509.9, 602.6, 509.9, 605.6, 511.6, 605.8, 511.8, 605.3, 512.9,
+605.0, 514.1, 594.6, 506.5, 560.7, 520.3, 557.4, 535.4, 600.8, 728.6,
+593.8, 730.4, 588.7, 728.1, 586.8, 732.3, 583.7, 702.7, 583.7, 702.7,
+580.6, 673.2, 581.2, 674.9, 583.3, 674.2, 586.0, 675.3, 595.4, 701.2,
+600.4, 701.8, 600.8, 728.6, 586.0, 675.3, 602.3, 681.8, 602.2, 681.9,
+618.6, 688.3, 624.7, 696.0, 624.7, 696.0, 630.9, 703.8, 620.4, 712.7,
+621.9, 714.5, 613.0, 725.3, 612.1, 728.4, 606.9, 726.9, 600.8, 728.6,
+600.4, 701.8, 595.4, 701.2, 586.0, 675.3, 610.8, 800.2, 610.7, 815.3,
+603.2, 821.6, 610.6, 830.4, 610.6, 830.5, 608.9, 830.3, 607.3, 830.2,
+585.8, 828.9, 585.8, 828.9, 564.4, 827.7, 563.2, 824.2, 554.0, 824.7,
+544.5, 826.6, 544.5, 826.3, 544.5, 826.3, 544.4, 826.1, 577.5, 812.9,
+578.6, 798.2, 610.8, 800.2, 611.1, 756.9, 607.2, 748.1, 608.2, 747.5,
+603.4, 739.3, 609.7, 733.6, 609.7, 733.6, 616.0, 728.0, 614.4, 728.3,
+615.2, 732.7, 614.4, 737.3, 614.3, 737.8, 614.3, 737.8, 614.2, 738.3,
+612.7, 747.6, 613.5, 756.7, 611.1, 756.9, 607.3, 830.2, 608.9, 830.3,
+610.6, 830.5, 610.6, 830.4, 616.6, 837.5, 624.6, 834.2, 637.6, 831.9,
+634.0, 839.4, 634.0, 839.4, 630.3, 847.0, 630.3, 846.9, 628.5, 847.7,
+626.7, 848.5, 627.4, 851.2, 590.4, 857.9, 556.1, 872.2, 556.0, 871.9,
+556.0, 871.9, 556.0, 871.7, 554.8, 868.6, 556.7, 867.9, 557.4, 864.1,
+580.8, 845.2, 581.8, 846.3, 607.3, 830.2, 557.4, 864.1, 560.9, 845.9,
+569.6, 842.9, 564.4, 827.7, 585.8, 828.9, 585.8, 828.9, 607.3, 830.2,
+581.8, 846.3, 580.8, 845.2, 557.4, 864.1, 547.5, 499.4, 547.5, 499.8,
+547.7, 500.0, 547.5, 500.3, 536.3, 517.1, 536.3, 517.1, 525.2, 534.0,
+525.1, 533.3, 520.0, 533.8, 514.8, 533.6, 514.9, 533.6, 513.5, 529.6,
+512.1, 525.5, 518.9, 516.3, 521.8, 518.4, 531.4, 511.3, 539.5, 505.4,
+539.3, 505.1, 547.5, 499.4, 451.1, 356.2, 453.4, 338.8, 462.3, 334.2,
+455.6, 321.4, 456.1, 319.7, 457.2, 318.6, 456.6, 318.0, 458.1, 318.4,
+458.1, 318.4, 459.7, 318.9, 457.0, 337.8, 462.6, 349.1, 451.1, 356.2,
+429.2, 696.3, 435.7, 668.8, 435.7, 668.8, 442.2, 641.3, 444.6, 650.0,
+458.4, 650.7, 457.1, 655.9, 457.9, 669.3, 457.9, 669.3, 458.7, 682.6,
+462.2, 696.8, 457.6, 697.9, 456.6, 713.1, 453.4, 715.7, 446.3, 706.8,
+436.1, 700.5, 432.6, 698.4, 429.0, 698.0, 429.2, 696.3, 347.1, 650.0,
+347.7, 658.4, 346.5, 658.6, 348.4, 666.8, 338.4, 696.1, 338.4, 696.1,
+328.4, 725.4, 328.1, 726.3, 328.0, 726.3, 327.5, 727.1, 325.7, 730.5,
+324.9, 730.3, 324.0, 733.9, 334.6, 692.0, 335.4, 692.2, 346.9, 650.6,
+347.0, 650.3, 347.1, 650.3, 347.1, 650.0, 270.1, 872.8, 264.9, 864.6,
+264.9, 864.6, 259.8, 856.5, 259.4, 855.5, 260.7, 854.9, 261.5, 853.3,
+292.7, 793.6, 292.7, 793.6, 324.0, 733.9, 324.9, 730.3, 325.7, 730.5,
+327.5, 727.1, 299.2, 800.1, 306.2, 803.8, 270.1, 872.8, 327.5, 727.1,
+328.0, 726.3, 328.1, 726.3, 328.4, 725.4, 322.8, 741.8, 319.6, 741.4,
+317.2, 758.2, 297.5, 803.6, 296.7, 804.1, 285.2, 852.2, 281.3, 861.8,
+284.4, 870.0, 278.5, 871.8, 275.7, 875.5, 276.9, 876.5, 275.3, 881.2,
+273.1, 876.8, 272.7, 877.0, 270.1, 872.8, 306.2, 803.8, 299.2, 800.1,
+327.5, 727.1, 314.9, 626.8, 319.9, 631.5, 323.8, 637.1, 324.9, 636.3,
+313.0, 650.4, 313.0, 650.4, 301.1, 664.5, 306.3, 660.7, 303.8, 657.3,
+306.4, 650.2, 310.6, 638.5, 306.5, 633.0, 314.9, 626.8, 347.1, 555.7,
+347.3, 561.2, 337.1, 561.5, 327.0, 567.2, 310.5, 576.7, 311.8, 580.6,
+294.0, 586.2, 297.6, 585.1, 296.3, 581.2, 298.6, 576.2, 300.9, 571.2,
+300.9, 571.2, 303.2, 566.1, 309.5, 552.3, 309.5, 552.3, 315.8, 538.5,
+323.9, 534.9, 320.7, 527.7, 325.6, 516.9, 342.1, 525.9, 346.6, 536.0,
+347.1, 555.7, 325.6, 516.9, 327.3, 513.3, 330.1, 511.2, 329.0, 509.6,
+341.8, 522.1, 341.8, 522.1, 354.7, 534.6, 356.5, 535.4, 355.0, 539.1,
+355.4, 543.6, 356.2, 544.4, 351.6, 549.5, 347.8, 555.3, 347.6, 555.6,
+347.1, 555.7, 347.1, 555.7, 346.6, 536.0, 342.1, 525.9, 325.6, 516.9,
+278.9, 619.5, 273.7, 609.2, 282.3, 599.0, 294.0, 586.2, 311.8, 580.6,
+310.5, 576.7, 327.0, 567.2, 330.2, 573.7, 313.3, 582.2, 299.5, 597.1,
+289.2, 608.3, 276.5, 614.7, 278.9, 619.5, 308.5, 478.6, 294.1, 470.2,
+294.6, 469.4, 279.8, 461.8, 279.3, 461.5, 278.9, 461.2, 279.0, 460.9,
+285.7, 436.7, 300.0, 420.9, 290.7, 411.9, 291.4, 409.5, 291.4, 409.5,
+292.1, 407.2, 292.0, 407.2, 292.6, 409.2, 293.0, 411.3, 300.8, 444.9,
+316.2, 449.0, 308.5, 478.6, 105.3, 309.6, 90.4, 286.9, 92.4, 285.4,
+75.5, 264.2, 71.9, 242.5, 71.9, 242.5, 68.2, 220.7, 82.5, 239.9,
+102.1, 238.2, 101.9, 255.4, 103.7, 259.7, 103.7, 259.7, 105.6, 264.0,
+107.0, 286.7, 105.6, 309.6, 105.3, 309.6, 105.6, 264.0, 105.7, 264.1,
+105.7, 264.1, 105.7, 264.3, 108.2, 272.8, 108.8, 272.7, 110.6, 281.3,
+114.6, 299.8, 114.6, 299.8, 118.7, 318.3, 116.7, 318.2, 116.5, 320.8,
+114.3, 323.3, 114.5, 316.6, 109.8, 316.5, 105.3, 309.6, 102.1, 287.5,
+105.6, 287.0, 105.7, 264.3, 105.7, 264.1, 105.7, 264.1, 105.6, 264.0,
+813.0, 194.0, 807.8, 189.4, 807.8, 189.4, 802.7, 184.8, 802.4, 184.5,
+802.4, 184.5, 802.1, 184.2, 805.3, 187.0, 805.3, 187.0, 808.4, 189.9,
+810.7, 191.9, 810.7, 191.9, 813.0, 194.0, 703.6, 295.6, 697.1, 288.6,
+697.1, 288.6, 690.7, 281.6, 688.5, 279.2, 688.5, 279.2, 686.3, 276.8,
+700.2, 279.7, 706.7, 273.4, 714.4, 281.7, 717.0, 282.2, 717.0, 282.2,
+719.5, 282.8, 736.7, 290.0, 737.0, 289.2, 754.4, 295.7, 739.0, 308.1,
+727.8, 301.0, 703.6, 295.6, 754.4, 295.7, 763.9, 299.3, 766.0, 305.3,
+773.3, 302.8, 773.5, 302.8, 773.7, 303.0, 773.6, 303.1, 765.2, 307.2,
+764.2, 314.4, 763.9, 325.8, 740.5, 318.1, 741.1, 315.2, 717.1, 310.4,
+710.4, 303.0, 710.4, 303.0, 703.6, 295.6, 727.8, 301.0, 739.0, 308.1,
+754.4, 295.7, 729.9, 248.9, 726.0, 244.0, 727.1, 241.1, 722.0, 239.1,
+721.8, 239.3, 719.2, 235.0, 715.8, 231.4, 715.9, 231.3, 715.2, 230.7,
+714.6, 230.0, 718.0, 232.5, 720.0, 229.9, 725.3, 229.8, 740.9, 244.0,
+748.3, 235.9, 771.3, 242.0, 765.5, 235.9, 756.5, 244.5, 741.7, 247.0,
+735.8, 247.9, 734.7, 250.8, 729.9, 248.9, 627.3, 576.9, 627.3, 576.4,
+627.0, 576.2, 627.2, 575.8, 628.0, 572.7, 625.3, 571.4, 626.8, 569.1,
+632.9, 555.2, 632.9, 555.2, 639.0, 541.4, 632.2, 549.5, 635.4, 552.2,
+631.9, 562.9, 629.6, 569.9, 629.8, 570.0, 627.3, 576.9, 732.4, 681.1,
+736.2, 702.0, 734.8, 702.4, 739.9, 722.9, 730.6, 715.9, 730.6, 715.9,
+721.2, 708.8, 720.7, 697.3, 711.7, 697.7, 702.3, 686.5, 705.4, 678.9,
+726.0, 674.9, 732.4, 681.1, 702.3, 686.5, 695.3, 678.2, 688.6, 678.5,
+688.3, 669.9, 688.1, 669.6, 687.9, 669.4, 687.9, 669.3, 702.4, 652.8,
+710.2, 655.5, 716.9, 636.3, 722.1, 644.3, 722.1, 644.3, 727.2, 652.4,
+732.9, 653.7, 729.8, 666.8, 732.4, 681.1, 726.0, 674.9, 705.4, 678.9,
+702.3, 686.5, 667.3, 731.5, 661.9, 718.3, 664.6, 716.4, 656.6, 705.1,
+658.8, 702.5, 658.8, 702.5, 661.0, 700.0, 665.1, 700.8, 665.3, 699.7,
+669.6, 699.4, 672.6, 714.6, 674.1, 728.5, 667.3, 731.5, 583.5, 760.9,
+586.3, 757.5, 588.6, 757.8, 589.1, 754.2, 588.2, 752.9, 592.5, 750.0,
+595.9, 745.9, 598.1, 742.9, 598.8, 743.4, 601.6, 740.8, 604.2, 755.3,
+605.2, 755.1, 608.7, 769.4, 605.2, 773.4, 593.4, 768.6, 583.5, 760.9,
+647.5, 730.5, 655.5, 737.8, 660.2, 736.0, 663.5, 745.0, 664.1, 745.8,
+664.1, 745.8, 664.7, 746.6, 662.4, 744.7, 662.5, 744.5, 660.3, 742.5,
+653.9, 736.5, 654.3, 736.0, 647.5, 730.5, 521.2, 461.3, 529.7, 453.6,
+529.7, 453.6, 538.1, 445.8, 538.4, 448.1, 538.8, 448.1, 539.5, 450.4,
+531.8, 457.4, 520.4, 458.7, 521.2, 461.3, 477.2, 368.6, 467.7, 376.4,
+462.7, 374.2, 458.3, 384.2, 454.8, 383.8, 452.5, 381.9, 451.3, 383.3,
+449.8, 380.1, 449.8, 380.1, 448.4, 376.8, 451.2, 367.0, 449.7, 366.5,
+451.1, 356.2, 462.6, 349.1, 457.0, 337.8, 459.7, 318.9, 461.5, 319.4,
+461.5, 319.4, 463.3, 319.9, 471.7, 343.7, 479.1, 344.9, 477.2, 368.6,
+463.3, 319.9, 471.0, 322.1, 478.7, 323.4, 478.6, 324.2, 486.4, 339.0,
+486.4, 339.0, 494.1, 353.7, 494.4, 354.1, 493.2, 355.0, 492.2, 356.2,
+488.7, 364.1, 484.7, 362.4, 477.2, 368.6, 479.1, 344.9, 471.7, 343.7,
+463.3, 319.9, 418.9, 766.3, 416.7, 763.5, 416.7, 763.5, 414.4, 760.8,
+413.6, 760.2, 414.9, 758.5, 415.4, 756.3, 418.5, 760.1, 419.8, 761.8,
+418.9, 766.3, 238.5, 801.7, 235.1, 782.2, 223.7, 770.7, 231.7, 762.7,
+232.7, 759.2, 232.7, 759.2, 233.8, 755.6, 236.8, 761.2, 234.5, 762.4,
+235.2, 769.2, 235.4, 771.3, 235.4, 771.3, 235.6, 773.3, 236.2, 779.1,
+236.2, 779.1, 236.8, 784.9, 237.4, 790.6, 237.4, 790.6, 238.0, 796.2,
+238.3, 799.0, 238.0, 799.0, 238.5, 801.7, 283.5, 685.5, 273.7, 697.1,
+275.7, 699.7, 264.0, 708.7, 263.0, 709.5, 263.0, 709.5, 262.0, 710.4,
+267.0, 702.9, 264.5, 698.4, 261.3, 688.3, 259.5, 685.3, 261.2, 684.4,
+261.0, 680.4, 271.8, 679.0, 283.1, 681.8, 283.5, 685.5, 297.7, 626.0,
+292.4, 638.3, 287.9, 636.3, 278.2, 646.7, 269.3, 656.0, 270.6, 657.7,
+260.5, 665.3, 260.4, 662.7, 260.4, 662.7, 260.4, 660.1, 270.9, 655.3,
+273.6, 645.9, 273.1, 632.1, 276.0, 625.8, 274.8, 624.9, 278.9, 619.5,
+276.5, 614.7, 289.2, 608.3, 299.5, 597.1, 303.2, 598.4, 303.1, 613.5,
+297.7, 626.0, 299.5, 597.1, 313.3, 582.2, 330.2, 573.7, 327.0, 567.2,
+337.1, 561.5, 347.3, 561.2, 347.1, 555.7, 347.1, 555.7, 347.6, 555.6,
+347.8, 555.3, 329.4, 583.6, 307.1, 608.3, 311.1, 611.9, 308.3, 614.8,
+304.9, 615.7, 305.5, 617.8, 301.6, 621.9, 296.9, 623.2, 297.7, 626.0,
+303.1, 613.5, 303.2, 598.4, 299.5, 597.1, 270.4, 486.5, 271.2, 481.3,
+273.8, 480.1, 272.0, 476.1, 274.5, 467.6, 274.5, 467.6, 277.0, 459.0,
+277.0, 459.2, 277.2, 459.3, 277.5, 459.5, 274.2, 473.1, 274.7, 473.3,
+270.4, 486.5, 273.8, 561.0, 276.9, 540.3, 287.9, 535.6, 309.5, 524.1,
+312.6, 531.3, 315.8, 538.5, 315.8, 538.5, 309.5, 552.3, 309.5, 552.3,
+303.2, 566.1, 292.8, 571.7, 273.8, 561.4, 273.8, 561.0, 293.0, 411.3,
+292.6, 409.2, 292.0, 407.2, 292.1, 407.2, 292.3, 406.5, 292.3, 406.5,
+292.5, 405.8, 306.0, 421.3, 313.3, 417.0, 335.5, 422.7, 339.3, 427.0,
+338.6, 427.9, 343.0, 431.2, 352.6, 437.1, 350.7, 440.1, 358.5, 448.9,
+359.1, 449.2, 358.1, 451.1, 357.8, 453.2, 346.9, 448.6, 347.8, 446.7,
+337.7, 440.2, 315.4, 425.7, 314.6, 426.8, 293.0, 411.3, 808.4, 189.9,
+805.3, 187.0, 805.3, 187.0, 802.1, 184.2, 799.7, 181.7, 799.7, 181.7,
+797.2, 179.1, 809.8, 174.1, 821.3, 166.9, 820.2, 163.7, 862.2, 179.9,
+899.8, 209.2, 896.1, 217.4, 893.9, 222.3, 851.7, 205.1, 808.4, 189.9,
+896.1, 217.4, 896.4, 217.5, 896.4, 217.5, 896.6, 217.7, 896.5, 217.6,
+896.4, 217.7, 896.3, 217.7, 857.8, 208.6, 857.3, 210.4, 819.3, 199.5,
+817.1, 196.1, 816.1, 196.8, 813.0, 194.0, 810.7, 191.9, 810.7, 191.9,
+808.4, 189.9, 851.7, 205.1, 893.9, 222.3, 896.1, 217.4, 786.5, 247.7,
+786.8, 247.9, 786.8, 247.9, 787.0, 248.0, 779.8, 266.6, 786.1, 269.0,
+785.1, 289.9, 785.8, 278.9, 785.5, 278.9, 785.9, 267.8, 786.2, 257.8,
+786.0, 257.7, 786.5, 247.7, 676.3, 753.6, 671.8, 742.5, 671.8, 742.5,
+667.3, 731.5, 674.1, 728.5, 672.6, 714.6, 669.6, 699.4, 675.1, 699.1,
+675.1, 699.1, 680.6, 698.7, 684.3, 705.4, 679.9, 707.8, 679.2, 716.9,
+679.2, 717.0, 679.2, 717.0, 679.2, 717.0, 677.7, 735.3, 685.8, 742.0,
+676.3, 753.6, 610.9, 789.2, 610.9, 794.7, 610.9, 794.7, 610.8, 800.2,
+578.6, 798.2, 577.5, 812.9, 544.4, 826.1, 542.7, 819.2, 538.9, 813.6,
+540.9, 812.3, 553.8, 796.7, 553.8, 796.7, 566.7, 781.1, 585.5, 775.0,
+590.8, 780.5, 610.9, 789.2, 566.7, 781.1, 568.6, 778.9, 568.1, 777.6,
+570.5, 776.6, 573.6, 774.5, 574.2, 774.0, 575.5, 770.6, 580.5, 767.1,
+579.5, 765.7, 583.5, 760.9, 593.4, 768.6, 605.2, 773.4, 608.7, 769.4,
+609.9, 774.1, 611.9, 774.5, 611.0, 778.7, 611.0, 784.0, 611.0, 784.0,
+610.9, 789.2, 590.8, 780.5, 585.5, 775.0, 566.7, 781.1, 614.4, 737.3,
+615.2, 732.7, 614.4, 728.3, 616.0, 728.0, 623.2, 721.6, 623.2, 721.6,
+630.4, 715.1, 635.8, 724.6, 638.9, 722.8, 647.5, 730.5, 654.3, 736.0,
+653.9, 736.5, 660.3, 742.5, 638.8, 746.9, 635.9, 744.3, 614.4, 737.3,
+547.6, 495.4, 547.6, 497.4, 547.6, 497.4, 547.5, 499.4, 539.3, 505.1,
+539.5, 505.4, 531.4, 511.3, 537.2, 509.1, 536.2, 506.6, 541.1, 501.8,
+544.4, 498.6, 543.7, 496.9, 547.6, 495.4, 446.0, 761.1, 439.5, 772.2,
+430.7, 774.5, 433.0, 783.4, 430.1, 779.9, 428.0, 780.3, 427.3, 776.5,
+424.8, 770.6, 423.1, 771.4, 418.9, 766.3, 419.8, 761.8, 418.5, 760.1,
+415.4, 756.3, 416.7, 749.7, 416.7, 749.7, 418.1, 743.1, 425.6, 720.3,
+423.6, 719.7, 429.2, 696.3, 429.0, 698.0, 432.6, 698.4, 436.1, 700.5,
+443.7, 730.1, 447.1, 731.0, 446.0, 761.1, 436.1, 700.5, 446.3, 706.8,
+453.4, 715.7, 456.6, 713.1, 455.4, 730.0, 450.4, 731.2, 454.2, 746.8,
+450.1, 753.9, 450.1, 753.9, 446.0, 761.1, 447.1, 731.0, 443.7, 730.1,
+436.1, 700.5, 278.2, 646.7, 287.9, 636.3, 292.4, 638.3, 297.7, 626.0,
+296.9, 623.2, 301.6, 621.9, 305.5, 617.8, 306.8, 623.1, 310.2, 622.3,
+314.9, 626.8, 306.5, 633.0, 310.6, 638.5, 306.4, 650.2, 296.2, 655.7,
+280.3, 652.7, 278.2, 646.7, 306.4, 650.2, 303.8, 657.3, 306.3, 660.7,
+301.1, 664.5, 292.3, 675.0, 292.3, 675.0, 283.5, 685.5, 283.1, 681.8,
+271.8, 679.0, 261.0, 680.4, 260.8, 672.8, 260.8, 672.8, 260.5, 665.3,
+270.6, 657.7, 269.3, 656.0, 278.2, 646.7, 280.3, 652.7, 296.2, 655.7,
+306.4, 650.2, 292.8, 485.6, 301.1, 504.9, 301.1, 504.9, 309.5, 524.1,
+287.9, 535.6, 276.9, 540.3, 273.8, 561.0, 268.3, 566.7, 268.3, 566.7,
+262.7, 572.5, 261.5, 573.7, 260.9, 573.4, 260.4, 574.9, 275.9, 530.0,
+262.6, 516.8, 292.8, 485.6, 260.4, 574.9, 259.7, 576.6, 257.4, 577.3,
+257.6, 577.7, 257.5, 573.8, 257.5, 573.8, 257.4, 569.9, 265.0, 528.4,
+263.9, 528.2, 270.4, 486.5, 274.7, 473.3, 274.2, 473.1, 277.5, 459.5,
+278.2, 460.2, 279.1, 460.5, 279.0, 460.9, 278.9, 461.2, 279.3, 461.5,
+279.8, 461.8, 282.5, 463.1, 282.0, 463.9, 284.3, 466.1, 284.9, 476.1,
+288.5, 475.9, 292.8, 485.6, 262.6, 516.8, 275.9, 530.0, 260.4, 574.9,
+298.6, 576.2, 296.3, 581.2, 297.6, 585.1, 294.0, 586.2, 282.3, 599.0,
+273.7, 609.2, 278.9, 619.5, 274.8, 624.9, 276.0, 625.8, 273.1, 632.1,
+273.2, 635.0, 262.0, 633.2, 259.6, 638.3, 259.6, 636.7, 259.7, 636.7,
+259.5, 635.1, 272.9, 617.1, 258.6, 606.4, 257.6, 577.7, 257.4, 577.3,
+259.7, 576.6, 260.4, 574.9, 260.9, 573.4, 261.5, 573.7, 262.7, 572.5,
+280.7, 573.1, 282.9, 569.3, 298.6, 576.2, 262.7, 572.5, 268.3, 566.7,
+268.3, 566.7, 273.8, 561.0, 273.8, 561.4, 292.8, 571.7, 303.2, 566.1,
+300.9, 571.2, 300.9, 571.2, 298.6, 576.2, 282.9, 569.3, 280.7, 573.1,
+262.7, 572.5, 337.7, 440.2, 347.8, 446.7, 346.9, 448.6, 357.8, 453.2,
+357.2, 457.1, 357.2, 457.1, 356.6, 461.0, 347.1, 462.7, 342.5, 471.0,
+340.7, 482.8, 332.3, 484.2, 332.3, 484.2, 323.8, 485.7, 322.2, 463.5,
+322.7, 454.5, 337.7, 440.2, 323.8, 485.7, 322.6, 485.9, 322.1, 486.6,
+321.3, 486.1, 314.9, 482.3, 314.9, 482.3, 308.5, 478.6, 316.2, 449.0,
+300.8, 444.9, 293.0, 411.3, 314.6, 426.8, 315.4, 425.7, 337.7, 440.2,
+322.7, 454.5, 322.2, 463.5, 323.8, 485.7, 785.9, 267.8, 785.5, 278.9,
+785.8, 278.9, 785.1, 289.9, 784.5, 302.9, 783.8, 302.9, 784.0, 315.9,
+778.8, 309.5, 775.2, 302.3, 773.6, 303.1, 773.7, 303.0, 773.5, 302.8,
+773.3, 302.8, 771.1, 303.5, 770.3, 294.4, 764.8, 292.2, 766.2, 271.9,
+747.4, 270.5, 729.9, 248.9, 734.7, 250.8, 735.8, 247.9, 741.7, 247.0,
+764.7, 254.7, 769.5, 251.6, 785.9, 267.8, 741.7, 247.0, 756.5, 244.5,
+765.5, 235.9, 771.3, 242.0, 776.7, 243.5, 778.4, 241.6, 782.1, 244.9,
+784.3, 246.3, 784.3, 246.3, 786.5, 247.7, 786.0, 257.7, 786.2, 257.8,
+785.9, 267.8, 769.5, 251.6, 764.7, 254.7, 741.7, 247.0, 630.0, 617.0,
+628.7, 597.0, 628.7, 597.0, 627.3, 576.9, 629.8, 570.0, 629.6, 569.9,
+631.9, 562.9, 633.7, 589.8, 638.1, 592.3, 630.0, 617.0, 673.4, 583.9,
+681.1, 606.5, 673.2, 615.5, 688.7, 629.0, 686.2, 637.8, 686.2, 637.8,
+683.7, 646.7, 673.6, 617.0, 665.6, 611.6, 673.4, 583.9, 678.1, 758.1,
+677.2, 755.8, 677.2, 755.8, 676.3, 753.6, 685.8, 742.0, 677.7, 735.3,
+679.2, 717.0, 670.4, 723.5, 678.7, 734.6, 678.3, 752.1, 678.2, 755.1,
+679.6, 757.0, 678.1, 758.1, 614.2, 738.3, 614.3, 737.8, 614.3, 737.8,
+614.4, 737.3, 635.9, 744.3, 638.8, 746.9, 660.3, 742.5, 662.5, 744.5,
+662.4, 744.7, 664.7, 746.6, 667.7, 750.4, 667.7, 750.4, 670.7, 754.2,
+659.6, 770.2, 661.4, 771.4, 652.0, 788.7, 627.9, 781.9, 632.9, 763.7,
+614.2, 738.3, 652.0, 788.7, 644.6, 802.4, 641.6, 801.5, 637.1, 816.1,
+624.2, 786.6, 629.3, 783.0, 611.2, 757.1, 611.2, 757.0, 611.2, 757.0,
+611.1, 756.9, 613.5, 756.7, 612.7, 747.6, 614.2, 738.3, 632.9, 763.7,
+627.9, 781.9, 652.0, 788.7, 541.1, 501.8, 536.2, 506.6, 537.2, 509.1,
+531.4, 511.3, 521.8, 518.4, 518.9, 516.3, 512.1, 525.5, 508.3, 514.0,
+508.3, 514.0, 504.5, 502.6, 509.2, 496.3, 517.1, 502.3, 529.8, 502.0,
+535.4, 501.9, 540.9, 501.0, 541.1, 501.8, 235.2, 769.2, 234.5, 762.4,
+236.8, 761.2, 233.8, 755.6, 235.0, 751.5, 233.8, 748.3, 236.2, 747.4,
+237.6, 746.0, 237.6, 746.0, 239.0, 744.7, 238.4, 757.0, 240.3, 758.5,
+235.2, 769.2, 238.0, 796.2, 237.4, 790.6, 237.4, 790.6, 236.8, 784.9,
+241.5, 774.8, 244.1, 776.0, 251.5, 767.1, 255.0, 762.8, 255.0, 762.8,
+258.5, 758.5, 296.1, 712.6, 296.1, 712.7, 333.7, 666.8, 334.2, 666.2,
+334.6, 665.6, 334.6, 665.6, 334.6, 665.6, 334.2, 666.2, 333.7, 666.8,
+306.0, 704.2, 306.0, 704.2, 278.3, 741.7, 270.2, 752.7, 270.2, 752.7,
+262.0, 763.8, 250.0, 780.0, 253.0, 783.6, 238.0, 796.2, 660.5, 548.2,
+660.2, 549.1, 661.6, 549.4, 662.2, 550.8, 665.4, 554.2, 663.8, 555.6,
+665.5, 560.5, 664.0, 575.9, 661.9, 575.7, 658.3, 591.0, 652.1, 617.1,
+652.1, 617.1, 646.0, 643.2, 642.8, 656.7, 646.9, 659.5, 639.6, 670.2,
+636.4, 666.3, 632.8, 666.0, 633.1, 662.4, 632.6, 653.6, 632.5, 653.6,
+631.9, 644.9, 643.7, 595.9, 645.0, 596.2, 660.5, 548.2, 631.9, 644.9,
+631.0, 631.0, 631.0, 631.0, 630.0, 617.0, 638.1, 592.3, 633.7, 589.8,
+631.9, 562.9, 635.4, 552.2, 632.2, 549.5, 639.0, 541.4, 640.7, 537.4,
+643.4, 536.7, 642.5, 533.4, 649.4, 537.5, 656.1, 537.2, 656.3, 541.6,
+659.1, 543.9, 661.1, 545.5, 660.5, 548.2, 645.0, 596.2, 643.7, 595.9,
+631.9, 644.9, 655.4, 689.2, 647.5, 679.7, 647.5, 679.7, 639.6, 670.2,
+646.9, 659.5, 642.8, 656.7, 646.0, 643.2, 659.2, 659.2, 660.3, 668.5,
+655.4, 689.2, 679.2, 716.9, 679.9, 707.8, 684.3, 705.4, 680.6, 698.7,
+692.3, 698.0, 692.5, 699.2, 703.9, 697.2, 710.1, 708.1, 710.1, 708.1,
+716.3, 718.9, 705.5, 727.6, 697.8, 717.9, 679.2, 716.9, 679.2, 717.0,
+679.2, 717.0, 679.2, 717.0, 679.2, 717.0, 679.2, 717.0, 679.2, 716.9,
+679.2, 717.0, 679.2, 717.0, 679.2, 717.0, 679.2, 717.0, 679.2, 717.0,
+679.2, 716.9, 541.9, 459.0, 544.5, 467.9, 544.5, 467.9, 547.0, 476.8,
+546.9, 481.5, 546.7, 481.7, 547.9, 486.2, 547.8, 490.8, 547.8, 490.8,
+547.6, 495.4, 543.7, 496.9, 544.4, 498.6, 541.1, 501.8, 540.9, 501.0,
+535.4, 501.9, 529.8, 502.0, 530.2, 480.4, 530.0, 476.5, 541.9, 459.0,
+529.8, 502.0, 517.1, 502.3, 509.2, 496.3, 504.5, 502.6, 501.4, 493.6,
+495.6, 487.0, 498.4, 484.5, 499.7, 482.2, 499.7, 482.2, 501.0, 479.8,
+499.2, 474.1, 511.1, 470.5, 521.2, 461.3, 520.4, 458.7, 531.8, 457.4,
+539.5, 450.4, 540.7, 454.7, 540.7, 454.7, 541.9, 459.0, 530.0, 476.5,
+530.2, 480.4, 529.8, 502.0, 251.5, 767.1, 244.1, 776.0, 241.5, 774.8,
+236.8, 784.9, 236.2, 779.1, 236.2, 779.1, 235.6, 773.3, 240.3, 767.5,
+251.7, 769.3, 251.5, 767.1, 658.3, 591.0, 661.9, 575.7, 664.0, 575.9,
+665.5, 560.5, 669.5, 572.2, 669.5, 572.2, 673.4, 583.9, 665.6, 611.6,
+673.6, 617.0, 683.7, 646.7, 680.8, 656.7, 683.9, 659.1, 678.0, 666.8,
+674.1, 673.6, 674.1, 673.6, 670.2, 680.4, 659.0, 637.1, 660.1, 635.9,
+658.3, 591.0, 670.2, 680.4, 665.7, 688.3, 664.7, 687.9, 661.2, 696.3,
+658.3, 692.8, 658.3, 692.8, 655.4, 689.2, 660.3, 668.5, 659.2, 659.2,
+646.0, 643.2, 652.1, 617.1, 652.1, 617.1, 658.3, 591.0, 660.1, 635.9,
+659.0, 637.1, 670.2, 680.4, 713.4, 763.0, 709.0, 767.6, 709.6, 768.3,
+704.6, 772.1, 704.0, 772.6, 704.1, 772.7, 703.6, 773.3, 698.9, 778.5,
+698.7, 778.3, 693.8, 783.4, 694.9, 781.9, 689.7, 778.1, 685.5, 772.8,
+680.8, 769.9, 682.5, 767.1, 679.5, 761.5, 678.6, 759.8, 678.8, 759.8,
+678.1, 758.1, 679.6, 757.0, 678.2, 755.1, 678.3, 752.1, 696.3, 754.7,
+699.7, 752.5, 713.4, 763.0, 284.9, 700.5, 315.7, 670.8, 315.7, 670.8,
+346.4, 641.2, 344.6, 644.3, 346.8, 645.6, 347.1, 650.0, 347.1, 650.3,
+347.0, 650.3, 346.9, 650.6, 345.3, 652.8, 345.2, 652.7, 343.5, 654.8,
+339.0, 660.2, 339.0, 660.2, 334.6, 665.6, 296.6, 712.0, 305.8, 725.3,
+258.5, 758.5, 281.0, 742.7, 266.3, 725.4, 284.9, 700.5, 258.5, 758.5,
+255.0, 762.8, 255.0, 762.8, 251.5, 767.1, 251.7, 769.3, 240.3, 767.5,
+235.6, 773.3, 235.4, 771.3, 235.4, 771.3, 235.2, 769.2, 240.3, 758.5,
+238.4, 757.0, 239.0, 744.7, 262.0, 722.6, 262.0, 722.6, 284.9, 700.5,
+266.3, 725.4, 281.0, 742.7, 258.5, 758.5, 262.0, 763.8, 270.2, 752.7,
+270.2, 752.7, 278.3, 741.7, 282.8, 773.8, 273.3, 775.1, 268.2, 808.5,
+264.9, 830.4, 264.9, 830.4, 261.6, 852.3, 261.6, 852.8, 261.7, 852.9,
+261.5, 853.3, 260.7, 854.9, 259.4, 855.5, 259.8, 856.5, 255.4, 849.5,
+255.4, 849.5, 251.0, 842.4, 251.9, 803.0, 251.7, 801.8, 262.0, 763.8,
+251.0, 842.4, 247.3, 836.7, 244.0, 836.8, 243.7, 830.9, 241.5, 818.6,
+234.4, 814.0, 239.4, 806.4, 240.0, 804.4, 239.0, 804.0, 238.5, 801.7,
+238.0, 799.0, 238.3, 799.0, 238.0, 796.2, 253.0, 783.6, 250.0, 780.0,
+262.0, 763.8, 251.7, 801.8, 251.9, 803.0, 251.0, 842.4, 719.8, 756.4,
+716.6, 759.7, 716.6, 759.7, 713.4, 763.0, 699.7, 752.5, 696.3, 754.7,
+678.3, 752.1, 678.7, 734.6, 670.4, 723.5, 679.2, 717.0, 679.2, 717.0,
+679.2, 717.0, 679.2, 716.9, 697.8, 717.9, 705.5, 727.6, 716.3, 718.9,
+717.3, 720.6, 717.3, 720.6, 718.2, 722.2, 719.8, 739.2, 721.7, 739.6,
+719.8, 756.4, 718.2, 722.2, 724.7, 733.4, 721.4, 738.3, 731.1, 744.7,
+725.4, 750.5, 725.4, 750.5, 719.8, 756.4, 721.7, 739.6, 719.8, 739.2,
+718.2, 722.2, 333.7, 666.8, 334.2, 666.2, 334.6, 665.6, 334.6, 665.6,
+339.0, 660.2, 339.0, 660.2, 343.5, 654.8, 342.0, 665.7, 338.4, 665.2,
+333.3, 675.6, 324.0, 694.6, 315.7, 694.2, 314.7, 713.7, 315.9, 689.8,
+324.0, 690.2, 333.7, 666.8, 314.7, 713.7, 292.5, 761.6, 305.7, 779.6,
+268.2, 808.5, 273.3, 775.1, 282.8, 773.8, 278.3, 741.7, 306.0, 704.2,
+306.0, 704.2, 333.7, 666.8, 324.0, 690.2, 315.9, 689.8, 314.7, 713.7,
+333.3, 675.6, 338.4, 665.2, 342.0, 665.7, 343.5, 654.8, 345.2, 652.7,
+345.3, 652.8, 346.9, 650.6, 335.4, 692.2, 334.6, 692.0, 324.0, 733.9,
+298.0, 795.3, 292.6, 793.0, 261.6, 852.3, 261.6, 852.8, 261.7, 852.9,
+261.5, 853.3, 261.7, 852.9, 261.6, 852.8, 261.6, 852.3, 297.4, 763.9,
+296.8, 763.7, 333.3, 675.6, 261.6, 852.3, 264.9, 830.4, 264.9, 830.4,
+268.2, 808.5, 305.7, 779.6, 292.5, 761.6, 314.7, 713.7, 315.7, 694.2,
+324.0, 694.6, 333.3, 675.6, 296.8, 763.7, 297.4, 763.9, 261.6, 852.3
+};
diff --git a/perf/micro/paint-with-alpha.c b/perf/micro/paint-with-alpha.c
new file mode 100644
index 000000000..047e35c43
--- /dev/null
+++ b/perf/micro/paint-with-alpha.c
@@ -0,0 +1,59 @@
+/*
+ * Copyright © 2006 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+#include "cairo-perf.h"
+
+static cairo_time_t
+do_paint_with_alpha (cairo_t *cr, int width, int height, int loops)
+{
+ cairo_perf_timer_start ();
+
+ while (loops--)
+ cairo_paint_with_alpha (cr, 0.5);
+
+ cairo_perf_timer_stop ();
+
+ return cairo_perf_timer_elapsed ();
+}
+
+static double
+count_paint_with_alpha (cairo_t *cr, int width, int height)
+{
+ return width * height / 1e6; /* Mpix/s */
+}
+
+cairo_bool_t
+paint_with_alpha_enabled (cairo_perf_t *perf)
+{
+ return cairo_perf_can_run (perf, "paint-with-alpha", NULL);
+}
+
+void
+paint_with_alpha (cairo_perf_t *perf, cairo_t *cr, int width, int height)
+{
+ cairo_perf_cover_sources_and_operators (perf, "paint-with-alpha",
+ do_paint_with_alpha,
+ count_paint_with_alpha);
+}
diff --git a/perf/micro/paint.c b/perf/micro/paint.c
new file mode 100644
index 000000000..2a59a45e0
--- /dev/null
+++ b/perf/micro/paint.c
@@ -0,0 +1,57 @@
+/*
+ * Copyright © 2006 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+#include "cairo-perf.h"
+
+static cairo_time_t
+do_paint (cairo_t *cr, int width, int height, int loops)
+{
+ cairo_perf_timer_start ();
+
+ while (loops--)
+ cairo_paint (cr);
+
+ cairo_perf_timer_stop ();
+
+ return cairo_perf_timer_elapsed ();
+}
+
+static double
+count_paint (cairo_t *cr, int width, int height)
+{
+ return width * height / 1e6; /* Mpix/s */
+}
+
+cairo_bool_t
+paint_enabled (cairo_perf_t *perf)
+{
+ return cairo_perf_can_run (perf, "paint", NULL);
+}
+
+void
+paint (cairo_perf_t *perf, cairo_t *cr, int width, int height)
+{
+ cairo_perf_cover_sources_and_operators (perf, "paint", do_paint, count_paint);
+}
diff --git a/perf/micro/pattern_create_radial.c b/perf/micro/pattern_create_radial.c
new file mode 100644
index 000000000..3915efb9a
--- /dev/null
+++ b/perf/micro/pattern_create_radial.c
@@ -0,0 +1,106 @@
+/*
+ * Copyright © 2006 Dan Amelang
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * the authors not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. The authors make no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Dan Amelang <dan@amelang.net>
+ *
+ * This test was originally created to test _cairo_fixed_from_double.
+ * cairo_pattern_create_radial was selected as the entry point into
+ * cairo as it makes several calls to _cairo_fixed_from_double and
+ * presents a somewhat realistic use-case (although the RADIALS_COUNT
+ * isn't very realistic).
+ */
+#include "cairo-perf.h"
+#include <time.h>
+
+#define RADIALS_COUNT (10000)
+
+static struct
+{
+ double cx0;
+ double cy0;
+ double radius0;
+ double cx1;
+ double cy1;
+ double radius1;
+} radials[RADIALS_COUNT];
+
+static double
+generate_double_in_range (double min, double max)
+{
+ double d;
+
+ d = rand () / (double) RAND_MAX;
+ d *= max - min;
+ d += min;
+
+ return d;
+}
+
+static cairo_time_t
+do_pattern_create_radial (cairo_t *cr, int width, int height, int loops)
+{
+ cairo_perf_timer_start ();
+
+ while (loops--) {
+ cairo_pattern_t *pattern;
+ int i;
+
+ for (i = 0; i < RADIALS_COUNT; i++) {
+ pattern =
+ cairo_pattern_create_radial (radials[i].cx0, radials[i].cy0,
+ radials[i].radius0,
+ radials[i].cx1, radials[i].cy1,
+ radials[i].radius1);
+ cairo_pattern_destroy (pattern);
+ }
+ }
+
+ cairo_perf_timer_stop ();
+
+ return cairo_perf_timer_elapsed ();
+}
+
+cairo_bool_t
+pattern_create_radial_enabled (cairo_perf_t *perf)
+{
+ return cairo_perf_can_run (perf, "pattern-create-radial", NULL);
+}
+
+void
+pattern_create_radial (cairo_perf_t *perf, cairo_t *cr, int width, int height)
+{
+ int i;
+
+ srand (time (0));
+ for (i = 0; i < RADIALS_COUNT; i++)
+ {
+ radials[i].cx0 = generate_double_in_range (-50000.0, 50000.0);
+ radials[i].cy0 = generate_double_in_range (-50000.0, 50000.0);
+ radials[i].radius0 = generate_double_in_range (0.0, 1000.0);
+ radials[i].cx1 = generate_double_in_range (-50000.0, 50000.0);
+ radials[i].cy1 = generate_double_in_range (-50000.0, 50000.0);
+ radials[i].radius1 = generate_double_in_range (0.0, 1000.0);
+ }
+
+ cairo_perf_run (perf, "pattern-create-radial",
+ do_pattern_create_radial, NULL);
+}
diff --git a/perf/micro/pixel.c b/perf/micro/pixel.c
new file mode 100644
index 000000000..b600b5170
--- /dev/null
+++ b/perf/micro/pixel.c
@@ -0,0 +1,237 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+/* Measure the overhead in setting a single pixel */
+
+#include "cairo-perf.h"
+
+#include <pixman.h>
+
+static cairo_time_t
+pixel_direct (cairo_t *cr, int width, int height, int loops)
+{
+ cairo_surface_t *surface, *image;
+ uint32_t *data;
+ int stride, bpp;
+
+ surface = cairo_get_target (cr);
+ image = cairo_surface_map_to_image (surface, NULL);
+ data = (uint32_t *) cairo_image_surface_get_data (image);
+ stride = cairo_image_surface_get_stride (image) / sizeof (uint32_t);
+
+ switch (cairo_image_surface_get_format (image)) {
+ default:
+ case CAIRO_FORMAT_INVALID:
+ case CAIRO_FORMAT_A1: bpp = 0; break;
+ case CAIRO_FORMAT_A8: bpp = 8; break;
+ case CAIRO_FORMAT_RGB16_565: bpp = 16; break;
+ case CAIRO_FORMAT_RGB24:
+ case CAIRO_FORMAT_RGB30:
+ case CAIRO_FORMAT_ARGB32: bpp = 32; break;
+ }
+
+ cairo_perf_timer_start ();
+
+ while (loops--)
+ pixman_fill (data, stride, bpp, 0, 0, 1, 1, -1);
+
+ cairo_perf_timer_stop ();
+
+ cairo_surface_unmap_image (surface, image);
+
+ return cairo_perf_timer_elapsed ();
+}
+
+static cairo_time_t
+pixel_paint (cairo_t *cr, int width, int height, int loops)
+{
+ cairo_perf_timer_start ();
+
+ while (loops--)
+ cairo_paint (cr);
+
+ cairo_perf_timer_stop ();
+
+ return cairo_perf_timer_elapsed ();
+}
+
+static cairo_time_t
+pixel_mask (cairo_t *cr, int width, int height, int loops)
+{
+ cairo_surface_t *mask;
+ cairo_t *cr2;
+
+ mask = cairo_surface_create_similar (cairo_get_target (cr),
+ CAIRO_CONTENT_ALPHA,
+ 1, 1);
+ cr2 = cairo_create (mask);
+ cairo_set_source_rgb (cr2, 1,1,1);
+ cairo_paint (cr2);
+ cairo_destroy (cr2);
+
+ cairo_perf_timer_start ();
+
+ while (loops--)
+ cairo_mask_surface (cr, mask, 0, 0);
+
+ cairo_perf_timer_stop ();
+
+ cairo_surface_destroy (mask);
+
+ return cairo_perf_timer_elapsed ();
+}
+
+static cairo_time_t
+pixel_rectangle (cairo_t *cr, int width, int height, int loops)
+{
+ cairo_new_path (cr);
+ cairo_rectangle (cr, 0, 0, 1, 1);
+
+ cairo_perf_timer_start ();
+
+ while (loops--)
+ cairo_fill_preserve (cr);
+
+ cairo_perf_timer_stop ();
+
+ cairo_new_path (cr);
+ return cairo_perf_timer_elapsed ();
+}
+
+static cairo_time_t
+pixel_subrectangle (cairo_t *cr, int width, int height, int loops)
+{
+ cairo_new_path (cr);
+ cairo_rectangle (cr, 0.1, 0.1, .8, .8);
+
+ cairo_perf_timer_start ();
+
+ while (loops--)
+ cairo_fill_preserve (cr);
+
+ cairo_perf_timer_stop ();
+
+ cairo_new_path (cr);
+ return cairo_perf_timer_elapsed ();
+}
+
+static cairo_time_t
+pixel_triangle (cairo_t *cr, int width, int height, int loops)
+{
+ cairo_new_path (cr);
+ cairo_move_to (cr, 0, 0);
+ cairo_line_to (cr, 1, 1);
+ cairo_line_to (cr, 0, 1);
+
+ cairo_perf_timer_start ();
+
+ while (loops--)
+ cairo_fill_preserve (cr);
+
+ cairo_perf_timer_stop ();
+
+ cairo_new_path (cr);
+ return cairo_perf_timer_elapsed ();
+}
+
+static cairo_time_t
+pixel_circle (cairo_t *cr, int width, int height, int loops)
+{
+ cairo_new_path (cr);
+ cairo_arc (cr, 0.5, 0.5, 0.5, 0, 2 * M_PI);
+
+ cairo_perf_timer_start ();
+
+ while (loops--)
+ cairo_fill_preserve (cr);
+
+ cairo_perf_timer_stop ();
+
+ cairo_new_path (cr);
+ return cairo_perf_timer_elapsed ();
+}
+
+static cairo_time_t
+pixel_stroke (cairo_t *cr, int width, int height, int loops)
+{
+ cairo_set_line_width (cr, 1.);
+ cairo_new_path (cr);
+ cairo_move_to (cr, 0, 0.5);
+ cairo_line_to (cr, 1, 0.5);
+
+ cairo_perf_timer_start ();
+
+ while (loops--)
+ cairo_stroke_preserve (cr);
+
+ cairo_perf_timer_stop ();
+
+ cairo_new_path (cr);
+ return cairo_perf_timer_elapsed ();
+}
+
+cairo_bool_t
+pixel_enabled (cairo_perf_t *perf)
+{
+ return cairo_perf_can_run (perf, "pixel", NULL);
+}
+
+void
+pixel (cairo_perf_t *perf, cairo_t *cr, int width, int height)
+{
+ cairo_set_source_rgb (cr, 1., 1., 1.);
+
+ cairo_perf_run (perf, "pixel-direct", pixel_direct, NULL);
+ cairo_perf_run (perf, "pixel-paint", pixel_paint, NULL);
+ cairo_perf_run (perf, "pixel-mask", pixel_mask, NULL);
+ cairo_perf_run (perf, "pixel-rectangle", pixel_rectangle, NULL);
+ cairo_perf_run (perf, "pixel-subrectangle", pixel_subrectangle, NULL);
+ cairo_perf_run (perf, "pixel-triangle", pixel_triangle, NULL);
+ cairo_perf_run (perf, "pixel-circle", pixel_circle, NULL);
+ cairo_perf_run (perf, "pixel-stroke", pixel_stroke, NULL);
+}
+
+cairo_bool_t
+a1_pixel_enabled (cairo_perf_t *perf)
+{
+ return cairo_perf_can_run (perf, "a1-pixel", NULL);
+}
+
+void
+a1_pixel (cairo_perf_t *perf, cairo_t *cr, int width, int height)
+{
+ cairo_set_source_rgb (cr, 1., 1., 1.);
+ cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE);
+
+ cairo_perf_run (perf, "a1-pixel-direct", pixel_direct, NULL);
+ cairo_perf_run (perf, "a1-pixel-paint", pixel_paint, NULL);
+ cairo_perf_run (perf, "a1-pixel-mask", pixel_mask, NULL);
+ cairo_perf_run (perf, "a1-pixel-rectangle", pixel_rectangle, NULL);
+ cairo_perf_run (perf, "a1-pixel-subrectangle", pixel_subrectangle, NULL);
+ cairo_perf_run (perf, "a1-pixel-triangle", pixel_triangle, NULL);
+ cairo_perf_run (perf, "a1-pixel-circle", pixel_circle, NULL);
+ cairo_perf_run (perf, "a1-pixel-stroke", pixel_stroke, NULL);
+}
diff --git a/perf/micro/pythagoras-tree.c b/perf/micro/pythagoras-tree.c
new file mode 100644
index 000000000..9d3ca1155
--- /dev/null
+++ b/perf/micro/pythagoras-tree.c
@@ -0,0 +1,95 @@
+/*
+ * Copyright © 2007 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Chris Wilson not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Chris Wilson makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-perf.h"
+#define _USE_MATH_DEFINES /* for M_SQRT2 on win32 */
+#include <math.h>
+
+static void
+add_rectangle (cairo_t *cr, double size)
+{
+ double x, y;
+
+ if (size < 1)
+ return;
+
+ cairo_get_current_point (cr, &x, &y);
+
+ cairo_rel_move_to (cr, -size/2., -size/2.);
+ cairo_rel_line_to (cr, size, 0);
+ cairo_rel_line_to (cr, 0, size);
+ cairo_rel_line_to (cr, -size, 0);
+ cairo_close_path (cr);
+
+ cairo_save (cr);
+ cairo_translate (cr, -size/2., size);
+ cairo_move_to (cr, x, y);
+ cairo_rotate (cr, M_PI/4);
+ add_rectangle (cr, size / M_SQRT2);
+ cairo_restore (cr);
+
+ cairo_save (cr);
+ cairo_translate (cr, size/2., size);
+ cairo_move_to (cr, x, y);
+ cairo_rotate (cr, -M_PI/4);
+ add_rectangle (cr, size / M_SQRT2);
+ cairo_restore (cr);
+}
+
+static cairo_time_t
+do_pythagoras_tree (cairo_t *cr, int width, int height, int loops)
+{
+ double size = 128;
+
+ cairo_perf_timer_start ();
+
+ while (loops--) {
+ cairo_save (cr);
+ cairo_translate (cr, 0, height);
+ cairo_scale (cr, 1, -1);
+
+ cairo_move_to (cr, width/2, size/2);
+ add_rectangle (cr, size);
+ cairo_set_source_rgb (cr, 0., 0., 0.);
+ cairo_fill (cr);
+ cairo_restore (cr);
+ }
+
+ cairo_perf_timer_stop ();
+
+ return cairo_perf_timer_elapsed ();
+}
+
+cairo_bool_t
+pythagoras_tree_enabled (cairo_perf_t *perf)
+{
+ return cairo_perf_can_run (perf, "pythagoras-tree", NULL);
+}
+
+void
+pythagoras_tree (cairo_perf_t *perf, cairo_t *cr, int width, int height)
+{
+ cairo_perf_run (perf, "pythagoras-tree", do_pythagoras_tree, NULL);
+}
diff --git a/perf/micro/rectangles.c b/perf/micro/rectangles.c
new file mode 100644
index 000000000..9228a4efa
--- /dev/null
+++ b/perf/micro/rectangles.c
@@ -0,0 +1,121 @@
+/*
+ * Copyright © 2006 Dan Amelang
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * the authors not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. The authors make no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Dan Amelang <dan@amelang.net>
+ */
+#include "cairo-perf.h"
+
+#if 0
+#define MODE cairo_perf_run
+#else
+#define MODE cairo_perf_cover_sources_and_operators
+#endif
+
+#define RECTANGLE_COUNT (1000)
+
+static struct {
+ double x;
+ double y;
+ double width;
+ double height;
+} rects[RECTANGLE_COUNT];
+
+static cairo_time_t
+do_rectangles (cairo_t *cr, int width, int height, int loops)
+{
+ int i;
+
+ cairo_perf_timer_start ();
+
+ while (loops--) {
+ for (i = 0; i < RECTANGLE_COUNT; i++) {
+ cairo_rectangle (cr, rects[i].x, rects[i].y,
+ rects[i].width, rects[i].height);
+ cairo_fill (cr);
+ }
+ }
+
+ cairo_perf_timer_stop ();
+
+ return cairo_perf_timer_elapsed ();
+}
+
+static cairo_time_t
+do_rectangles_once (cairo_t *cr, int width, int height, int loops)
+{
+ int i;
+
+ cairo_perf_timer_start ();
+
+ while (loops--) {
+ for (i = 0; i < RECTANGLE_COUNT; i++) {
+ cairo_rectangle (cr, rects[i].x, rects[i].y,
+ rects[i].width, rects[i].height);
+ }
+
+ cairo_fill (cr);
+ }
+
+ cairo_perf_timer_stop ();
+
+ return cairo_perf_timer_elapsed ();
+}
+
+static cairo_time_t
+do_rectangle (cairo_t *cr, int width, int height, int loops)
+{
+ cairo_perf_timer_start ();
+
+ while (loops--) {
+ cairo_rectangle (cr, 0, 0, width, height);
+ cairo_fill (cr);
+ }
+
+ cairo_perf_timer_stop ();
+
+ return cairo_perf_timer_elapsed ();
+}
+
+cairo_bool_t
+rectangles_enabled (cairo_perf_t *perf)
+{
+ return cairo_perf_can_run (perf, "rectangles", NULL);
+}
+
+void
+rectangles (cairo_perf_t *perf, cairo_t *cr, int width, int height)
+{
+ int i;
+
+ srand (8478232);
+ for (i = 0; i < RECTANGLE_COUNT; i++)
+ {
+ rects[i].x = rand () % width;
+ rects[i].y = rand () % height;
+ rects[i].width = (rand () % (width / 10)) + 1;
+ rects[i].height = (rand () % (height / 10)) + 1;
+ }
+
+ MODE (perf, "one-rectangle", do_rectangle, NULL);
+ MODE (perf, "rectangles", do_rectangles, NULL);
+ MODE (perf, "rectangles-once", do_rectangles_once, NULL);
+}
diff --git a/perf/micro/rounded-rectangles.c b/perf/micro/rounded-rectangles.c
new file mode 100644
index 000000000..1e432dd1f
--- /dev/null
+++ b/perf/micro/rounded-rectangles.c
@@ -0,0 +1,144 @@
+/*
+ * Copyright © 2005 Owen Taylor
+ * Copyright © 2007 Dan Amelang
+ * Copyright © 2007 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * the authors not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. The authors make no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+/* This perf case is derived from the bug report
+ * Gradient on 'rounded rectangle' MUCH slower than normal rectangle
+ * https://bugs.freedesktop.org/show_bug.cgi?id=4263.
+ */
+
+#include "cairo-perf.h"
+
+#define RECTANGLE_COUNT (1000)
+
+#if 0
+#define MODE cairo_perf_run
+#else
+#define MODE cairo_perf_cover_sources_and_operators
+#endif
+
+static struct
+{
+ double x;
+ double y;
+ double width;
+ double height;
+} rects[RECTANGLE_COUNT];
+
+static void
+rounded_rectangle (cairo_t *cr,
+ double x, double y, double w, double h,
+ double radius)
+{
+ cairo_move_to (cr, x+radius, y);
+ cairo_arc (cr, x+w-radius, y+radius, radius, M_PI + M_PI / 2, M_PI * 2 );
+ cairo_arc (cr, x+w-radius, y+h-radius, radius, 0, M_PI / 2 );
+ cairo_arc (cr, x+radius, y+h-radius, radius, M_PI/2, M_PI );
+ cairo_arc (cr, x+radius, y+radius, radius, M_PI, 270 * M_PI / 180);
+}
+
+static cairo_time_t
+do_rectangle (cairo_t *cr, int width, int height, int loops)
+{
+ cairo_perf_timer_start ();
+
+ while (loops--) {
+ rounded_rectangle (cr, 0, 0, width, height, 3.0);
+ cairo_fill (cr);
+ }
+
+ cairo_perf_timer_stop ();
+
+ return cairo_perf_timer_elapsed ();
+}
+
+static cairo_time_t
+do_rectangles (cairo_t *cr, int width, int height, int loops)
+{
+ int i;
+
+ cairo_perf_timer_start ();
+
+ while (loops--) {
+ for (i = 0; i < RECTANGLE_COUNT; i++) {
+ rounded_rectangle (cr,
+ rects[i].x, rects[i].y,
+ rects[i].width, rects[i].height,
+ 3.0);
+ cairo_fill (cr);
+ }
+ }
+
+ cairo_perf_timer_stop ();
+
+ return cairo_perf_timer_elapsed ();
+}
+
+static cairo_time_t
+do_rectangles_once (cairo_t *cr, int width, int height, int loops)
+{
+ int i;
+
+ cairo_perf_timer_start ();
+
+ while (loops--) {
+ for (i = 0; i < RECTANGLE_COUNT; i++) {
+ rounded_rectangle (cr,
+ rects[i].x, rects[i].y,
+ rects[i].width, rects[i].height,
+ 3.0);
+ }
+ cairo_fill (cr);
+ }
+
+ cairo_perf_timer_stop ();
+
+ return cairo_perf_timer_elapsed ();
+}
+
+cairo_bool_t
+rounded_rectangles_enabled (cairo_perf_t *perf)
+{
+ return cairo_perf_can_run (perf, "rounded-rectangles", NULL);
+}
+
+void
+rounded_rectangles (cairo_perf_t *perf, cairo_t *cr, int width, int height)
+{
+ int i;
+
+ srand (8478232);
+ for (i = 0; i < RECTANGLE_COUNT; i++) {
+ rects[i].x = rand () % width;
+ rects[i].y = rand () % height;
+ rects[i].width = (rand () % (width / 10)) + 1;
+ rects[i].height = (rand () % (height / 10)) + 1;
+ }
+
+ MODE (perf, "one-rounded-rectangle", do_rectangle, NULL);
+ MODE (perf, "rounded-rectangles", do_rectangles, NULL);
+ MODE (perf, "rounded-rectangles-once", do_rectangles_once, NULL);
+}
diff --git a/perf/micro/sierpinski.c b/perf/micro/sierpinski.c
new file mode 100644
index 000000000..c6f5fadc2
--- /dev/null
+++ b/perf/micro/sierpinski.c
@@ -0,0 +1,94 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-perf.h"
+
+static const double m_1_sqrt_3 = 0.577359269;
+
+static void
+T (cairo_t *cr, int size)
+{
+ cairo_move_to (cr, 0, 0);
+ cairo_line_to (cr, size, 0);
+ cairo_line_to (cr, size/2, size*m_1_sqrt_3);
+
+ size /= 2;
+ if (size >= 4) {
+ T (cr, size);
+ cairo_save (cr); {
+ cairo_translate (cr, size, 0);
+ T (cr, size);
+ } cairo_restore (cr);
+ cairo_save (cr); {
+ cairo_translate (cr, size/2, size*m_1_sqrt_3);
+ T (cr, size);
+ } cairo_restore (cr);
+ }
+}
+
+static cairo_time_t
+draw (cairo_t *cr, int width, int height, int loops)
+{
+ int t_height = height/2;
+ int t_width = t_height / m_1_sqrt_3;
+
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ cairo_set_line_width (cr, 1.);
+
+ cairo_perf_timer_start ();
+
+ while (loops--) {
+ cairo_save (cr);
+ T (cr, t_width);
+
+ cairo_translate (cr, 0, height);
+ cairo_scale (cr, 1, -1);
+
+ T (cr, t_width);
+
+ cairo_stroke (cr);
+ cairo_restore (cr);
+ }
+
+ cairo_perf_timer_stop ();
+
+ return cairo_perf_timer_elapsed ();
+}
+
+cairo_bool_t
+sierpinski_enabled (cairo_perf_t *perf)
+{
+ return cairo_perf_can_run (perf, "sierpinski", NULL);
+}
+
+void
+sierpinski (cairo_perf_t *perf, cairo_t *cr, int width, int height)
+{
+ cairo_perf_run (perf, "sierpinski", draw, NULL);
+}
diff --git a/perf/micro/spiral.c b/perf/micro/spiral.c
new file mode 100644
index 000000000..5db62b0d7
--- /dev/null
+++ b/perf/micro/spiral.c
@@ -0,0 +1,352 @@
+/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
+/* cairo - a vector graphics library with display and print output
+ *
+ * Copyright (c) 2008 M Joonas Pihlaja
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include "cairo-perf.h"
+#include <assert.h>
+
+#define MAX_SEGMENTS 2560
+
+typedef enum {
+ PIXALIGN, /* pixel aligned path */
+ NONALIGN /* unaligned path. */
+} align_t;
+
+typedef enum {
+ RECTCLOSE, /* keeps the path rectilinear */
+ DIAGCLOSE /* forces a diagonal */
+} close_t;
+
+static cairo_time_t
+draw_spiral (cairo_t *cr,
+ cairo_fill_rule_t fill_rule,
+ align_t align,
+ close_t close,
+ int width, int height, int loops)
+{
+ int i;
+ int n=0;
+ double x[MAX_SEGMENTS];
+ double y[MAX_SEGMENTS];
+ int step = 3;
+ int side = width < height ? width : height;
+
+ assert(5*(side/step/2+1)+2 < MAX_SEGMENTS);
+
+#define L(x_,y_) (x[n] = (x_), y[n] = (y_), n++)
+#define M(x_,y_) L(x_,y_)
+#define v(t) L(x[n-1], y[n-1] + (t))
+#define h(t) L(x[n-1] + (t), y[n-1])
+
+ switch (align) {
+ case PIXALIGN: M(0,0); break;
+ case NONALIGN: M(0.1415926, 0.7182818); break;
+ }
+
+ while (side >= step && side >= 0) {
+ v(side);
+ h(side);
+ v(-side);
+ h(-side+step);
+ v(step);
+ side -= 2*step;
+ }
+
+ switch (close) {
+ case RECTCLOSE: L(x[n-1],y[0]); break;
+ case DIAGCLOSE: L(x[0],y[0]); break;
+ }
+
+ assert(n < MAX_SEGMENTS);
+
+ cairo_save (cr);
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ cairo_paint (cr);
+
+ cairo_translate (cr, 1, 1);
+ cairo_set_fill_rule (cr, fill_rule);
+ cairo_set_source_rgb (cr, 1, 0, 0);
+
+ cairo_new_path (cr);
+ cairo_move_to (cr, x[0], y[0]);
+ for (i = 1; i < n; i++) {
+ cairo_line_to (cr, x[i], y[i]);
+ }
+ cairo_close_path (cr);
+
+ cairo_perf_timer_start ();
+ while (loops--)
+ cairo_fill_preserve (cr);
+ cairo_perf_timer_stop ();
+
+ cairo_restore (cr);
+
+ return cairo_perf_timer_elapsed ();
+}
+
+static cairo_time_t
+draw_spiral_box (cairo_t *cr,
+ cairo_fill_rule_t fill_rule,
+ align_t align,
+ int width, int height, int loops)
+{
+ const int step = 3;
+ int side = (width < height ? width : height) - 2;
+
+ cairo_save (cr);
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ cairo_paint (cr);
+
+ cairo_set_source_rgb (cr, 1, 0, 0);
+ cairo_set_fill_rule (cr, fill_rule);
+ cairo_translate (cr, 1, 1);
+ if (align == NONALIGN)
+ cairo_translate (cr, 0.1415926, 0.7182818);
+
+ cairo_new_path (cr);
+ while (side >= step) {
+ cairo_rectangle (cr, 0, 0, side, side);
+ cairo_translate (cr, step, step);
+ side -= 2*step;
+ }
+
+ cairo_perf_timer_start ();
+ while (loops--)
+ cairo_fill_preserve (cr);
+ cairo_perf_timer_stop ();
+
+ cairo_restore (cr);
+
+ return cairo_perf_timer_elapsed ();
+}
+
+static cairo_time_t
+draw_spiral_stroke (cairo_t *cr,
+ align_t align,
+ int width, int height, int loops)
+{
+ const int step = 3;
+ int side = width < height ? width : height;
+
+ cairo_save (cr);
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ cairo_paint (cr);
+
+ cairo_translate (cr, 1, 1);
+ cairo_set_source_rgb (cr, 1, 0, 0);
+ cairo_set_line_width (cr, 4.);
+ cairo_set_line_join (cr, CAIRO_LINE_JOIN_MITER);
+ cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT);
+
+ cairo_new_path (cr);
+ switch (align) {
+ case PIXALIGN: cairo_move_to (cr, 0,0); break;
+ case NONALIGN: cairo_move_to (cr, 0.1415926, 0.7182818); break;
+ }
+ while (side >= step) {
+ cairo_rel_line_to (cr, 0, side);
+ side -= step;
+ if (side <= 0)
+ break;
+
+ cairo_rel_line_to (cr, side, 0);
+ side -= step;
+ if (side <= 0)
+ break;
+
+ cairo_rel_line_to (cr, 0, -side);
+ side -= step;
+ if (side <= 0)
+ break;
+
+ cairo_rel_line_to (cr, -side, 0);
+ side -= step;
+ if (side <= 0)
+ break;
+ }
+
+ cairo_perf_timer_start ();
+ while (loops--)
+ cairo_stroke_preserve (cr);
+ cairo_perf_timer_stop ();
+
+ cairo_restore (cr);
+
+ return cairo_perf_timer_elapsed ();
+}
+
+static cairo_time_t
+draw_spiral_eo_pa_re (cairo_t *cr, int width, int height, int loops)
+{
+ return draw_spiral (cr,
+ CAIRO_FILL_RULE_EVEN_ODD,
+ PIXALIGN,
+ RECTCLOSE,
+ width, height, loops);
+}
+
+static cairo_time_t
+draw_spiral_nz_pa_re (cairo_t *cr, int width, int height, int loops)
+{
+ return draw_spiral (cr,
+ CAIRO_FILL_RULE_WINDING,
+ PIXALIGN,
+ RECTCLOSE,
+ width, height, loops);
+}
+
+static cairo_time_t
+draw_spiral_eo_na_re (cairo_t *cr, int width, int height, int loops)
+{
+ return draw_spiral (cr,
+ CAIRO_FILL_RULE_EVEN_ODD,
+ NONALIGN,
+ RECTCLOSE,
+ width, height, loops);
+}
+
+static cairo_time_t
+draw_spiral_nz_na_re (cairo_t *cr, int width, int height, int loops)
+{
+ return draw_spiral (cr,
+ CAIRO_FILL_RULE_WINDING,
+ NONALIGN,
+ RECTCLOSE,
+ width, height, loops);
+}
+
+static cairo_time_t
+draw_spiral_eo_pa_di (cairo_t *cr, int width, int height, int loops)
+{
+ return draw_spiral (cr,
+ CAIRO_FILL_RULE_EVEN_ODD,
+ PIXALIGN,
+ DIAGCLOSE,
+ width, height, loops);
+}
+
+static cairo_time_t
+draw_spiral_nz_pa_di (cairo_t *cr, int width, int height, int loops)
+{
+ return draw_spiral (cr,
+ CAIRO_FILL_RULE_WINDING,
+ PIXALIGN,
+ DIAGCLOSE,
+ width, height, loops);
+}
+
+static cairo_time_t
+draw_spiral_eo_na_di (cairo_t *cr, int width, int height, int loops)
+{
+ return draw_spiral (cr,
+ CAIRO_FILL_RULE_EVEN_ODD,
+ NONALIGN,
+ DIAGCLOSE,
+ width, height, loops);
+}
+
+static cairo_time_t
+draw_spiral_nz_na_di (cairo_t *cr, int width, int height, int loops)
+{
+ return draw_spiral (cr,
+ CAIRO_FILL_RULE_WINDING,
+ NONALIGN,
+ DIAGCLOSE,
+ width, height, loops);
+}
+
+static cairo_time_t
+draw_spiral_nz_pa_box (cairo_t *cr, int width, int height, int loops)
+{
+ return draw_spiral_box (cr,
+ CAIRO_FILL_RULE_WINDING, PIXALIGN,
+ width, height, loops);
+}
+
+static cairo_time_t
+draw_spiral_nz_na_box (cairo_t *cr, int width, int height, int loops)
+{
+ return draw_spiral_box (cr,
+ CAIRO_FILL_RULE_WINDING, NONALIGN,
+ width, height, loops);
+}
+
+
+static cairo_time_t
+draw_spiral_eo_pa_box (cairo_t *cr, int width, int height, int loops)
+{
+ return draw_spiral_box (cr,
+ CAIRO_FILL_RULE_EVEN_ODD, PIXALIGN,
+ width, height, loops);
+}
+
+static cairo_time_t
+draw_spiral_eo_na_box (cairo_t *cr, int width, int height, int loops)
+{
+ return draw_spiral_box (cr,
+ CAIRO_FILL_RULE_EVEN_ODD, NONALIGN,
+ width, height, loops);
+}
+
+static cairo_time_t
+draw_spiral_stroke_pa (cairo_t *cr, int width, int height, int loops)
+{
+ return draw_spiral_stroke (cr,
+ PIXALIGN,
+ width, height, loops);
+}
+
+static cairo_time_t
+draw_spiral_stroke_na (cairo_t *cr, int width, int height, int loops)
+{
+ return draw_spiral_stroke (cr,
+ NONALIGN,
+ width, height, loops);
+}
+
+cairo_bool_t
+spiral_enabled (cairo_perf_t *perf)
+{
+ return cairo_perf_can_run (perf, "spiral", NULL);
+}
+
+void
+spiral (cairo_perf_t *perf, cairo_t *cr, int width, int height)
+{
+ cairo_perf_run (perf, "spiral-box-nonalign-evenodd-fill", draw_spiral_eo_na_box, NULL);
+ cairo_perf_run (perf, "spiral-box-nonalign-nonzero-fill", draw_spiral_nz_na_box, NULL);
+ cairo_perf_run (perf, "spiral-box-pixalign-evenodd-fill", draw_spiral_eo_pa_box, NULL);
+ cairo_perf_run (perf, "spiral-box-pixalign-nonzero-fill", draw_spiral_nz_pa_box, NULL);
+ cairo_perf_run (perf, "spiral-diag-nonalign-evenodd-fill", draw_spiral_eo_na_di, NULL);
+ cairo_perf_run (perf, "spiral-diag-nonalign-nonzero-fill", draw_spiral_nz_na_di, NULL);
+ cairo_perf_run (perf, "spiral-diag-pixalign-evenodd-fill", draw_spiral_eo_pa_di, NULL);
+ cairo_perf_run (perf, "spiral-diag-pixalign-nonzero-fill", draw_spiral_nz_pa_di, NULL);
+ cairo_perf_run (perf, "spiral-rect-nonalign-evenodd-fill", draw_spiral_eo_na_re, NULL);
+ cairo_perf_run (perf, "spiral-rect-nonalign-nonzero-fill", draw_spiral_nz_na_re, NULL);
+ cairo_perf_run (perf, "spiral-rect-pixalign-evenodd-fill", draw_spiral_eo_pa_re, NULL);
+ cairo_perf_run (perf, "spiral-rect-pixalign-nonzero-fill", draw_spiral_nz_pa_re, NULL);
+ cairo_perf_run (perf, "spiral-nonalign-stroke", draw_spiral_stroke_na, NULL);
+ cairo_perf_run (perf, "spiral-pixalign-stroke", draw_spiral_stroke_pa, NULL);
+}
diff --git a/perf/micro/stroke.c b/perf/micro/stroke.c
new file mode 100644
index 000000000..4b2954770
--- /dev/null
+++ b/perf/micro/stroke.c
@@ -0,0 +1,100 @@
+/*
+ * Copyright © 2006 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+#include "cairo-perf.h"
+
+static cairo_time_t
+do_stroke (cairo_t *cr, int width, int height, int loops)
+{
+ cairo_arc (cr,
+ width/2.0, height/2.0,
+ width/3.0,
+ 0, 2 * M_PI);
+ cairo_close_path (cr);
+
+ cairo_set_line_width (cr, width/5.0);
+
+ cairo_perf_timer_start ();
+
+ while (loops--)
+ cairo_stroke_preserve (cr);
+
+ cairo_perf_timer_stop ();
+
+ cairo_new_path (cr);
+
+ return cairo_perf_timer_elapsed ();
+}
+
+static void
+rounded_rectangle (cairo_t *cr,
+ double x, double y, double w, double h,
+ double radius)
+{
+ cairo_move_to (cr, x+radius, y);
+ cairo_arc (cr, x+w-radius, y+radius, radius, M_PI + M_PI / 2, M_PI * 2 );
+ cairo_arc (cr, x+w-radius, y+h-radius, radius, 0, M_PI / 2 );
+ cairo_arc (cr, x+radius, y+h-radius, radius, M_PI/2, M_PI );
+ cairo_arc (cr, x+radius, y+radius, radius, M_PI, 270 * M_PI / 180);
+}
+
+static cairo_time_t
+do_strokes (cairo_t *cr, int width, int height, int loops)
+{
+ /* a pair of overlapping rectangles */
+ rounded_rectangle (cr,
+ 2, 2, width/2. + 10, height/2. + 10,
+ 10);
+ rounded_rectangle (cr,
+ width/2. - 10, height/2. - 10,
+ width/2. - 2, height/2. - 2,
+ 10);
+
+ cairo_set_line_width (cr, 2.);
+
+ cairo_perf_timer_start ();
+
+ while (loops--)
+ cairo_stroke_preserve (cr);
+
+ cairo_perf_timer_stop ();
+
+ cairo_new_path (cr);
+
+ return cairo_perf_timer_elapsed ();
+}
+
+cairo_bool_t
+stroke_enabled (cairo_perf_t *perf)
+{
+ return cairo_perf_can_run (perf, "stroke", NULL);
+}
+
+void
+stroke (cairo_perf_t *perf, cairo_t *cr, int width, int height)
+{
+ cairo_perf_cover_sources_and_operators (perf, "stroke", do_stroke, NULL);
+ cairo_perf_cover_sources_and_operators (perf, "strokes", do_strokes, NULL);
+}
diff --git a/perf/micro/subimage_copy.c b/perf/micro/subimage_copy.c
new file mode 100644
index 000000000..e749c062f
--- /dev/null
+++ b/perf/micro/subimage_copy.c
@@ -0,0 +1,80 @@
+/*
+ * Copyright © 2006 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+#include "cairo-perf.h"
+
+/* This case exposes a performance bug found by Christopher "Monty"
+ * Montgomery in that copying a tiny portion of an image surface to an
+ * X surface causes the entire image surface to be copied to an
+ * intermediate surface.
+ *
+ * If the performance bug is fixed, then the time this test takes
+ * should be independent of the source and destination surface sizes.
+ */
+
+static cairo_time_t
+do_subimage_copy (cairo_t *cr, int width, int height, int loops)
+{
+ cairo_rectangle (cr, 2, 2, 4, 4);
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+
+ cairo_perf_timer_start ();
+
+ while (loops--)
+ cairo_fill_preserve (cr);
+
+ cairo_perf_timer_stop ();
+
+ cairo_new_path (cr);
+
+ return cairo_perf_timer_elapsed ();
+}
+
+cairo_bool_t
+subimage_copy_enabled (cairo_perf_t *perf)
+{
+ return cairo_perf_can_run (perf, "subimage-copy", NULL);
+}
+
+void
+subimage_copy (cairo_perf_t *perf, cairo_t *cr, int width, int height)
+{
+ cairo_surface_t *image;
+ cairo_t *cr2;
+
+ cairo_set_source_rgb (cr, 0, 0, 1); /* blue */
+ cairo_paint (cr);
+
+ image = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
+ cr2 = cairo_create (image);
+ cairo_set_source_rgb (cr2, 1, 0, 0); /* red */
+ cairo_paint (cr2);
+ cairo_destroy (cr2);
+
+ cairo_set_source_surface (cr, image, 0, 0);
+ cairo_surface_destroy (image);
+
+ cairo_perf_run (perf, "subimage-copy", do_subimage_copy, NULL);
+}
diff --git a/perf/micro/tessellate.c b/perf/micro/tessellate.c
new file mode 100644
index 000000000..b6277fe63
--- /dev/null
+++ b/perf/micro/tessellate.c
@@ -0,0 +1,181 @@
+/*
+ * Copyright © 2006 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+#include "cairo-perf.h"
+
+typedef struct {
+ double x;
+ double y;
+} point_t;
+
+point_t points[300] = {
+ {39.4383,84.0188}, {79.844,78.3099}, {19.7551,91.1647}, {76.823,33.5223}, {55.397,27.7775},
+ {62.8871,47.7397}, {51.3401,36.4784}, {91.6195,95.223}, {71.7297,63.5712}, {60.6969,14.1603},
+ {24.2887,1.63006}, {80.4177,13.7232}, {40.0944,15.6679}, {10.8809,12.979}, {21.8257,99.8925},
+ {83.9112,51.2932}, {29.6032,61.264}, {52.4287,63.7552}, {97.2775,49.3583}, {77.1358,29.2517},
+ {76.9914,52.6745}, {89.1529,40.0229}, {35.2458,28.3315}, {91.9026,80.7725}, {94.9327,6.97553},
+ {8.60558,52.5995}, {66.3227,19.2214}, {34.8893,89.0233}, {2.0023,6.41713}, {6.30958,45.7702},
+ {97.0634,23.828}, {85.092,90.2208}, {53.976,26.6666}, {76.0249,37.5207}, {66.7724,51.2535},
+ {3.92803,53.1606}, {93.1835,43.7638}, {72.0952,93.081}, {73.8534,28.4293}, {35.4049,63.9979},
+ {16.5974,68.7861}, {88.0075,44.0105}, {33.0337,82.9201}, {89.3372,22.8968}, {68.667,35.036},
+ {58.864,95.6468}, {85.8676,65.7304}, {92.397,43.956}, {81.4767,39.8437}, {91.0972,68.4219},
+
+ {21.5825,48.2491}, {92.0128,95.0252}, {88.1062,14.766}, {43.1953,64.1081}, {28.1059,61.9596},
+ {30.7458,78.6002}, {22.6107,44.7034}, {27.6235,18.7533}, {41.6501,55.6444}, {90.6804,16.9607},
+ {12.6075,10.3171}, {76.0475,49.5444}, {93.5004,98.4752}, {38.3188,68.4445}, {36.8664,74.9771},
+ {23.2262,29.416}, {24.4413,58.4489}, {73.2149,15.239}, {79.347,12.5475}, {74.5071,16.4102},
+ {95.0104,7.45298}, {52.1563,5.25293}, {24.0062,17.6211}, {73.2654,79.7798}, {96.7405,65.6564},
+ {75.9735,63.9458}, {13.4902,9.34805}, {7.82321,52.021}, {20.4655,6.99064}, {81.9677,46.142},
+ {75.5581,57.3319}, {15.7807,5.19388}, {20.4329,99.9994}, {12.5468,88.9956}, {5.40576,99.7799},
+ {7.23288,87.054}, {92.3069,0.416161}, {18.0372,59.3892}, {39.169,16.3131}, {81.9695,91.3027},
+ {55.2485,35.9095}, {45.2576,57.943}, {9.96401,68.7387}, {75.7294,53.0808}, {99.2228,30.4295},
+ {87.7614,57.6971}, {62.891,74.7809}, {74.7803,3.54209}, {92.5377,83.3239}, {83.1038,87.3271},
+
+ {74.3811,97.9434}, {98.3596,90.3366}, {49.7259,66.688}, {83.0012,16.3968}, {7.69947,88.8949},
+ {24.8044,64.9707}, {22.9137,62.948}, {31.6867,70.062}, {23.1428,32.8777}, {63.3072,7.4161},
+ {65.1132,22.3656}, {97.1466,51.0686}, {54.6107,28.0042}, {11.3281,71.9269}, {59.254,47.1483},
+ {45.0918,94.4318}, {84.7684,33.6351}, {0.323146,43.4513}, {59.8481,34.4943}, {23.3892,83.3243},
+ {48.295,67.5476}, {30.4956,48.1936}, {18.2556,71.2087}, {4.08643,62.1823}, {69.5984,41.3984},
+ {63.764,67.3936}, {18.4622,34.7116}, {62.7158,60.9106}, {32.8374,73.0729}, {20.2213,74.0438},
+ {68.4757,92.0914}, {25.7265,65.313}, {8.76436,53.2441}, {87.7384,26.0497}, {9.37402,68.6125},
+ {36.1601,11.1276}, {59.3211,57.6691}, {28.8778,66.6557}, {28.8379,77.5767}, {18.9751,32.9642},
+ {0.357857,98.4363}, {33.1479,82.7391}, {43.6497,18.8201}, {91.893,95.8637}, {69.9075,76.4871},
+ {68.5786,12.1143}, {77.4273,38.3832}, {91.6273,94.3051}, {20.3548,86.1917}, {54.8042,79.3657},
+
+ {90.4932,29.7288}, {87.3979,90.9643}, {57.62,49.8144}, {27.3911,16.2757}, {49.2399,86.4579},
+ {84.8942,46.3662}, {29.1053,49.5977}, {68.4178,18.0421}, {13.9058,72.755}, {49.2422,60.3109},
+ {72.4252,83.8134}, {22.1966,17.8208}, {12.1259,49.8525}, {36.0443,13.8238}, {93.1895,32.4807},
+ {62.2095,90.8485}, {81.8128,83.6828}, {33.4972,49.6074}, {65.8831,39.4327}, {25.8906,60.8883},
+ {7.2545,15.123}, {64.7207,10.7848}, {28.827,36.3598}, {9.11486,33.1386}, {93.4495,42.7328},
+ {26.5461,58.357}, {76.1778,65.8747}, {15.7272,48.7427}, {62.5665,88.3037}, {20.7844,51.7715},
+ {42.6199,55.7561}, {39.4388,82.9939}, {32.6013,24.4327}, {63.8654,72.936}, {33.8243,98.4845},
+ {13.6075,89.756}, {0.540855,41.0788}, {77.4386,78.3282}, {11.4668,29.3678}, {72.1006,86.5535},
+ {44.9105,4.91625}, {70.7909,98.6467}, {47.3894,21.0883}, {9.39195,86.5181}, {38.2896,9.95593},
+ {65.712,30.1763}, {13.1702,80.9095}, {5.34223,5.15083}, {78.0868,45.7716}, {44.256,69.2076},
+
+ {58.9637,11.9111}, {52.9899,57.8635}, {36.1917,59.5045}, {88.8723,30.4285}, {16.982,47.6585},
+ {52.5747,60.9729}, {59.6196,61.8925}, {82.9808,23.3656}, {9.88374,7.00902}, {16.965,92.3728},
+ {22.5491,48.1733}, {29.0829,82.6769}, {87.8278,35.7193}, {81.4909,34.4251}, {3.63274,65.9146},
+ {77.8257,25.7469}, {83.6104,62.5964}, {22.1009,30.8157}, {61.2442,19.8021}, {67.4605,10.9733},
+ {71.9462,78.2262}, {40.1188,20.0352}, {43.4009,31.5658}, {38.5748,23.0996}, {15.4724,53.2846},
+ {1.45793,55.5398}, {38.2167,38.0215}, {73.7408,30.5408}, {64.9659,26.0445}, {91.9591,55.2316},
+ {80.9785,68.5986}, {31.195,69.7848}, {0.600477,64.5889}, {84.391,53.296}, {64.2693,61.8447},
+ {40.0709,51.8515}, {71.8867,36.2154}, {67.7812,80.1897}, {3.28927,15.2876}, {68.5722,6.35606},
+ {61.8958,18.7616}, {56.7831,70.0301}, {0.570914,0.112548}, {26.157,30.5239}, {85.7555,65.5368},
+ {34.1354,18.1161}, {87.9009,66.7341}, {31.323,65.3305}, {18.6265,88.5014}, {50.3461,15.7139},
+
+ {67.5654,82.8957}, {19.1112,90.417}, {70.6067,39.4521}, {54.7397,86.8924}, {93.2485,73.8959},
+ {92.6576,23.3119}, {93.342,55.1443}, {55.2568,49.4407}, {79.9646,93.9129}, {59.4497,81.4139},
+ {99.53,65.7201}, {32.4541,93.5852}, {58.9157,87.4309}, {75.9324,63.7771}, {79.491,77.5421},
+ {60.4379,26.2785}, {16.6955,47.0564}, {86.5086,79.549}, {66.4414,87.3021}, {61.1981,41.2483},
+ {64.5601,59.6899}, {14.8342,53.8557}, {3.29634,57.9022}, {51.8151,70.091}, {51.5049,83.2609},
+ {48.981,11.2648}, {4.84997,51.0349}, {38.4658,81.4351}, {45.2122,63.7656}, {41.3078,14.3982},
+ {40.6767,24.7033}, {71.7597,1.74566}, {81.2947,57.3721}, {44.6743,58.2682}, {99.5165,47.7361},
+ {7.42604,5.87232}, {59.728,64.0766}, {21.9788,22.2602}, {92.3513,63.0243}, {46.2852,73.7939},
+ {85.0586,43.8562}, {94.8911,95.2662}, {76.7014,89.9086}, {53.6742,33.3569}, {47.7551,21.9136},
+ {46.6169,94.982}, {96.7277,88.4318}, {45.8039,18.3765}, {76.6448,78.0224}, {25.7585,90.4782}
+};
+
+static cairo_time_t
+do_tessellate (cairo_t *cr, int num_points, int loops)
+{
+ int i;
+
+ for (i=0; i < num_points; i++)
+ cairo_line_to (cr, points[i].x, points[i].y);
+
+ cairo_perf_timer_start ();
+
+ /* We'd like to measure just tessellation without
+ * rasterization. For now, we can do that with cairo_in_fill. But
+ * we'll have to be careful since cairo_in_fill might eventually
+ * be optimized to have an implementation that doesn't necessarily
+ * include tessellation. */
+ while (loops--)
+ cairo_in_fill (cr, 50, 50);
+
+ cairo_perf_timer_stop ();
+
+ cairo_new_path (cr);
+
+ return cairo_perf_timer_elapsed ();
+}
+
+static cairo_time_t
+tessellate_16 (cairo_t *cr, int width, int height, int loops)
+{
+ return do_tessellate (cr, 16, loops);
+}
+
+static cairo_time_t
+tessellate_64 (cairo_t *cr, int width, int height, int loops)
+{
+ return do_tessellate (cr, 64, loops);
+}
+
+static cairo_time_t
+tessellate_256 (cairo_t *cr, int width, int height, int loops)
+{
+ return do_tessellate (cr, 256, loops);
+}
+
+cairo_bool_t
+tessellate_enabled (cairo_perf_t *perf)
+{
+ return cairo_perf_can_run (perf, "tessellate", NULL);
+}
+
+void
+tessellate (cairo_perf_t *perf, cairo_t *cr, int width, int height)
+{
+ cairo_perf_run (perf, "tessellate-16", tessellate_16, NULL);
+ cairo_perf_run (perf, "tessellate-64", tessellate_64, NULL);
+ cairo_perf_run (perf, "tessellate-256", tessellate_256, NULL);
+}
+
+#if 0
+double
+rand_within (double range)
+{
+ return range * (rand() / (RAND_MAX + 1.0));
+}
+
+int
+main (void)
+{
+#define SIZE 100
+ int i;
+
+ printf ("point_t points[] = {\n");
+
+ for (i=0; i < 1000; i++) {
+ printf (" {%g,%g},", rand_within (SIZE), rand_within (SIZE));
+ if (i % 5 == 4)
+ printf ("\n");
+ }
+
+ printf ("};\n");
+}
+#endif
diff --git a/perf/micro/text.c b/perf/micro/text.c
new file mode 100644
index 000000000..cdb319936
--- /dev/null
+++ b/perf/micro/text.c
@@ -0,0 +1,69 @@
+/*
+ * Copyright © 2006 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+#include "cairo-perf.h"
+
+static cairo_time_t
+do_text (cairo_t *cr, int width, int height, int loops)
+{
+ const char text[] = "the jay, pig, fox, zebra and my wolves quack";
+ int len = strlen (text);
+ double x, y;
+ int i = 0, j = 0;
+
+ cairo_set_font_size (cr, 9);
+
+ cairo_perf_timer_start ();
+
+ while (loops--) {
+ do {
+ cairo_move_to (cr, 0, j++ * 10);
+ cairo_show_text (cr, text + i);
+ cairo_get_current_point (cr, &x, &y);
+ while (x < width && cairo_status (cr) == CAIRO_STATUS_SUCCESS) {
+ cairo_show_text (cr, text);
+ cairo_get_current_point (cr, &x, &y);
+ }
+ if (++i >= len)
+ i = 0;
+ } while (y < height && cairo_status (cr) == CAIRO_STATUS_SUCCESS);
+ }
+
+ cairo_perf_timer_stop ();
+
+ return cairo_perf_timer_elapsed ();
+}
+
+cairo_bool_t
+text_enabled (cairo_perf_t *perf)
+{
+ return cairo_perf_can_run (perf, "text", NULL);
+}
+
+void
+text (cairo_perf_t *perf, cairo_t *cr, int width, int height)
+{
+ cairo_perf_cover_sources_and_operators (perf, "text", do_text, NULL);
+}
diff --git a/perf/micro/tiger.c b/perf/micro/tiger.c
new file mode 100644
index 000000000..9e7a9419a
--- /dev/null
+++ b/perf/micro/tiger.c
@@ -0,0 +1,115 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.o.uk>
+ */
+
+#include "cairo-perf.h"
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include "../../test/tiger.inc"
+
+static cairo_time_t
+do_tiger (cairo_t *cr, int width, int height, int loops)
+{
+ unsigned int i;
+
+ cairo_perf_timer_start ();
+
+ while (loops--) {
+ cairo_identity_matrix (cr);
+
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_set_source_rgba (cr, 0.1, 0.2, 0.3, 1.0);
+ cairo_paint (cr);
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+
+ cairo_translate (cr, width/2, height/2);
+ cairo_scale (cr, .85 * width/500, .85 * height/500);
+
+ for (i = 0; i < sizeof (tiger_commands)/sizeof(tiger_commands[0]);i++) {
+ const struct command *cmd = &tiger_commands[i];
+ switch (cmd->type) {
+ case 'm':
+ cairo_move_to (cr, cmd->x0, cmd->y0);
+ break;
+ case 'l':
+ cairo_line_to (cr, cmd->x0, cmd->y0);
+ break;
+ case 'c':
+ cairo_curve_to (cr,
+ cmd->x0, cmd->y0,
+ cmd->x1, cmd->y1,
+ cmd->x2, cmd->y2);
+ break;
+ case 'f':
+ cairo_set_source_rgba (cr,
+ cmd->x0, cmd->y0, cmd->x1, cmd->y1);
+ cairo_fill (cr);
+ break;
+ }
+ }
+ }
+
+ cairo_perf_timer_stop ();
+
+ return cairo_perf_timer_elapsed ();
+}
+
+static cairo_time_t
+do_mono_tiger (cairo_t *cr, int width, int height, int loops)
+{
+ cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE);
+ return do_tiger (cr, width, height, loops);
+}
+
+static cairo_time_t
+do_fast_tiger (cairo_t *cr, int width, int height, int loops)
+{
+ cairo_set_antialias (cr, CAIRO_ANTIALIAS_FAST);
+ return do_tiger (cr, width, height, loops);
+}
+
+static cairo_time_t
+do_best_tiger (cairo_t *cr, int width, int height, int loops)
+{
+ cairo_set_antialias (cr, CAIRO_ANTIALIAS_BEST);
+ return do_tiger (cr, width, height, loops);
+}
+
+cairo_bool_t
+tiger_enabled (cairo_perf_t *perf)
+{
+ return cairo_perf_can_run (perf, "tiger", NULL);
+}
+
+void
+tiger (cairo_perf_t *perf, cairo_t *cr, int width, int height)
+{
+ cairo_perf_run (perf, "tiger-mono", do_mono_tiger, NULL);
+ cairo_perf_run (perf, "tiger-fast", do_fast_tiger, NULL);
+ cairo_perf_run (perf, "tiger-best", do_best_tiger, NULL);
+}
diff --git a/perf/micro/twin.c b/perf/micro/twin.c
new file mode 100644
index 000000000..99433bd65
--- /dev/null
+++ b/perf/micro/twin.c
@@ -0,0 +1,59 @@
+#define WIDTH 1350
+#define HEIGHT 900
+
+#include "cairo-perf.h"
+
+static cairo_time_t
+do_twin (cairo_t *cr,
+ int width,
+ int height,
+ int loops)
+{
+ int i, j, h;
+ unsigned char s[2] = {0, 0};
+
+ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */
+ cairo_paint (cr);
+ cairo_set_source_rgb (cr, 0, 0, 0);
+
+ cairo_select_font_face (cr,
+ "@cairo:",
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_NORMAL);
+
+ cairo_perf_timer_start ();
+
+ while (loops--) {
+ h = 2;
+ for (i = 8; i < 48; i >= 24 ? i+=3 : i++) {
+ cairo_set_font_size (cr, i);
+ for (j = 33; j < 128; j++) {
+ if (j == 33 || (j == 80 && i > 24)) {
+ h += i + 2;
+ cairo_move_to (cr, 10, h);
+ }
+ s[0] = j;
+ cairo_text_path (cr, (const char *) s);
+ }
+ }
+ cairo_fill (cr);
+ }
+
+ cairo_perf_timer_stop ();
+ return cairo_perf_timer_elapsed ();
+}
+
+cairo_bool_t
+twin_enabled (cairo_perf_t *perf)
+{
+ return cairo_perf_can_run (perf, "twin", NULL);
+}
+
+void
+twin (cairo_perf_t *perf,
+ cairo_t *cr,
+ int width,
+ int height)
+{
+ cairo_perf_run (perf, "twin", do_twin, NULL);
+}
diff --git a/perf/micro/unaligned-clip.c b/perf/micro/unaligned-clip.c
new file mode 100644
index 000000000..41e327f1e
--- /dev/null
+++ b/perf/micro/unaligned-clip.c
@@ -0,0 +1,73 @@
+/*
+ * Copyright © 2006 Jeff Muizelaar <jeff@infidigm.net>
+ * Copyright © 2006 Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors: Jeff Muizelaar <jeff@infidigm.net>
+ * Carl Worth <cworth@cworth.org>
+ */
+
+#include "cairo-perf.h"
+
+static cairo_time_t
+do_unaligned_clip (cairo_t *cr, int width, int height, int loops)
+{
+ cairo_perf_timer_start ();
+
+ while (loops--) {
+ cairo_save (cr);
+
+ /* First a triangular clip that obviously isn't along device-pixel
+ * boundaries. */
+ cairo_move_to (cr, 50, 50);
+ cairo_line_to (cr, 50, 90);
+ cairo_line_to (cr, 90, 90);
+ cairo_close_path (cr);
+ cairo_clip (cr);
+
+ /* Then a rectangular clip that would be but for the non-integer
+ * scaling. */
+ cairo_scale (cr, 1.1, 1.1);
+ cairo_rectangle (cr, 55, 55, 35, 35);
+ cairo_clip (cr);
+
+ /* And paint something to force the clip to be evaluated. */
+ cairo_paint (cr);
+
+ cairo_restore (cr);
+ }
+ cairo_perf_timer_stop ();
+
+ return cairo_perf_timer_elapsed ();
+}
+
+cairo_bool_t
+unaligned_clip_enabled (cairo_perf_t *perf)
+{
+ return cairo_perf_can_run (perf, "unaligned-clip", NULL);
+}
+
+void
+unaligned_clip (cairo_perf_t *perf, cairo_t *cr, int width, int height)
+{
+ cairo_perf_run (perf, "unaligned-clip", do_unaligned_clip, NULL);
+}
diff --git a/perf/micro/wave.c b/perf/micro/wave.c
new file mode 100644
index 000000000..f6e6f74a3
--- /dev/null
+++ b/perf/micro/wave.c
@@ -0,0 +1,115 @@
+/*
+ * Copyright 2011 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Benjamin Otte <otte@redhat.com>
+ */
+
+#include "cairo-perf.h"
+
+static cairo_surface_t *
+generate_random_waveform(cairo_t *target, int width, int height)
+{
+ cairo_surface_t *surface;
+ cairo_t *cr;
+ int i, r;
+
+ srand (0xdeadbeef);
+
+ surface = cairo_surface_create_similar (cairo_get_target (target),
+ CAIRO_CONTENT_ALPHA,
+ width, height);
+ cr = cairo_create (surface);
+
+ r = height / 2;
+
+ for (i = 0; i < width; i++)
+ {
+ r += rand () % (height / 4) - (height / 8);
+ if (r < 0)
+ r = 0;
+ else if (r > height)
+ r = height;
+ cairo_rectangle (cr, i, (height - r) / 2, 1, r);
+ }
+ cairo_fill (cr);
+ cairo_destroy (cr);
+
+ return surface;
+}
+
+static cairo_time_t
+do_wave (cairo_t *cr, int width, int height, int loops)
+{
+ cairo_surface_t *wave;
+ cairo_pattern_t *mask;
+
+ wave = generate_random_waveform (cr, width, height);
+
+ cairo_perf_timer_start ();
+
+ while (loops--) {
+ /* paint outline (and contents) */
+ cairo_set_source_rgb (cr, 1, 0, 0);
+ cairo_mask_surface (cr, wave, 0, 0);
+
+ /* overdraw inline */
+ /* first, create a mask */
+ cairo_push_group_with_content (cr, CAIRO_CONTENT_ALPHA);
+ cairo_set_source_surface (cr, wave, 0, 0);
+ cairo_paint (cr);
+ cairo_set_operator (cr, CAIRO_OPERATOR_IN);
+ cairo_set_source_surface (cr, wave, 1, 0);
+ cairo_paint (cr);
+ cairo_set_source_surface (cr, wave, -1, 0);
+ cairo_paint (cr);
+ cairo_set_source_surface (cr, wave, 0, 1);
+ cairo_paint (cr);
+ cairo_set_source_surface (cr, wave, 0, -1);
+ cairo_paint (cr);
+ mask = cairo_pop_group (cr);
+
+ /* second, paint the mask */
+ cairo_set_source_rgb (cr, 0, 1, 0);
+ cairo_mask (cr, mask);
+
+ cairo_pattern_destroy (mask);
+ }
+
+ cairo_perf_timer_stop ();
+
+ cairo_surface_destroy (wave);
+
+ return cairo_perf_timer_elapsed ();
+}
+
+cairo_bool_t
+wave_enabled (cairo_perf_t *perf)
+{
+ return cairo_perf_can_run (perf, "wave", NULL);
+}
+
+void
+wave (cairo_perf_t *perf, cairo_t *cr, int width, int height)
+{
+ cairo_perf_run (perf, "wave", do_wave, NULL);
+}
diff --git a/perf/micro/wide-fills.c b/perf/micro/wide-fills.c
new file mode 100644
index 000000000..0747e6e67
--- /dev/null
+++ b/perf/micro/wide-fills.c
@@ -0,0 +1,187 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+
+/* This is a variant on wide strokes where we precompute
+ * a simplified stroke-to-path.
+ * When we have a real stroke-to-path, it would useful to compare the cost
+ * of stroking vs filling the "identical" paths.
+ */
+
+#include "cairo-perf.h"
+
+static uint32_t state;
+
+static double
+uniform_random (double minval, double maxval)
+{
+ static uint32_t const poly = 0x9a795537U;
+ uint32_t n = 32;
+ while (n-->0)
+ state = 2*state < state ? (2*state ^ poly) : 2*state;
+ return minval + state * (maxval - minval) / 4294967296.0;
+}
+
+static cairo_time_t
+do_wide_fills_ha (cairo_t *cr, int width, int height, int loops)
+{
+ int count;
+
+ state = 0xc0ffee;
+ for (count = 0; count < 1000; count++) {
+ double y = floor (uniform_random (0, height));
+ double x = floor (uniform_random (0, width));
+ cairo_rectangle (cr, x, y, ceil (uniform_random (0, width)) - x, 5);
+ }
+
+ cairo_perf_timer_start ();
+
+ while (loops--)
+ cairo_fill_preserve (cr);
+
+ cairo_perf_timer_stop ();
+
+ cairo_new_path (cr);
+
+ return cairo_perf_timer_elapsed ();
+}
+
+static cairo_time_t
+do_wide_fills_h (cairo_t *cr, int width, int height, int loops)
+{
+ int count;
+
+ state = 0xc0ffee;
+ for (count = 0; count < 1000; count++) {
+ double y = uniform_random (0, height);
+ double x = uniform_random (0, width);
+ cairo_rectangle (cr, x, y, uniform_random (0, width) - x, 5);
+ }
+
+ cairo_perf_timer_start ();
+
+ while (loops--)
+ cairo_fill_preserve (cr);
+
+ cairo_perf_timer_stop ();
+
+ cairo_new_path (cr);
+
+ return cairo_perf_timer_elapsed ();
+}
+
+static cairo_time_t
+do_wide_fills_va (cairo_t *cr, int width, int height, int loops)
+{
+ int count;
+
+ state = 0xc0ffee;
+ for (count = 0; count < 1000; count++) {
+ double x = floor (uniform_random (0, width));
+ double y = floor (uniform_random (0, height));
+ cairo_rectangle (cr, x, y, 5, ceil (uniform_random (0, height) - y));
+ }
+
+ cairo_perf_timer_start ();
+
+ while (loops--)
+ cairo_fill_preserve (cr);
+
+ cairo_perf_timer_stop ();
+
+ cairo_new_path (cr);
+
+ return cairo_perf_timer_elapsed ();
+}
+
+static cairo_time_t
+do_wide_fills_v (cairo_t *cr, int width, int height, int loops)
+{
+ int count;
+
+ state = 0xc0ffee;
+ for (count = 0; count < 1000; count++) {
+ double x = uniform_random (0, width);
+ double y = uniform_random (0, height);
+ cairo_rectangle (cr, x, y, 5, uniform_random (0, height) - y);
+ }
+
+ cairo_perf_timer_start ();
+
+ while (loops--)
+ cairo_fill_preserve (cr);
+
+ cairo_perf_timer_stop ();
+
+ cairo_new_path (cr);
+
+ return cairo_perf_timer_elapsed ();
+}
+
+static cairo_time_t
+do_wide_fills (cairo_t *cr, int width, int height, int loops)
+{
+ int count;
+
+ /* lots and lots of overlapping stroke-like fills */
+ state = 0xc0ffee;
+ for (count = 0; count < 1000; count++) {
+ cairo_save (cr);
+ cairo_translate (cr,
+ uniform_random (0, width),
+ uniform_random (0, height));
+ cairo_rotate (cr, uniform_random (-M_PI,M_PI));
+ cairo_rectangle (cr, 0, 0, uniform_random (0, width), 5);
+ cairo_restore (cr);
+ }
+
+ cairo_perf_timer_start ();
+
+ while (loops--)
+ cairo_fill_preserve (cr);
+
+ cairo_perf_timer_stop ();
+
+ cairo_new_path (cr);
+
+ return cairo_perf_timer_elapsed ();
+}
+
+cairo_bool_t
+wide_fills_enabled (cairo_perf_t *perf)
+{
+ return cairo_perf_can_run (perf, "wide-fills", NULL);
+}
+
+void
+wide_fills (cairo_perf_t *perf, cairo_t *cr, int width, int height)
+{
+ cairo_perf_run (perf, "wide-fills-halign", do_wide_fills_ha, NULL);
+ cairo_perf_run (perf, "wide-fills-valign", do_wide_fills_va, NULL);
+ cairo_perf_run (perf, "wide-fills-horizontal", do_wide_fills_h, NULL);
+ cairo_perf_run (perf, "wide-fills-vertical", do_wide_fills_v, NULL);
+ cairo_perf_run (perf, "wide-fills-random", do_wide_fills, NULL);
+}
diff --git a/perf/micro/wide-strokes.c b/perf/micro/wide-strokes.c
new file mode 100644
index 000000000..141309148
--- /dev/null
+++ b/perf/micro/wide-strokes.c
@@ -0,0 +1,188 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-perf.h"
+
+static uint32_t state;
+
+static double
+uniform_random (double minval, double maxval)
+{
+ static uint32_t const poly = 0x9a795537U;
+ uint32_t n = 32;
+ while (n-->0)
+ state = 2*state < state ? (2*state ^ poly) : 2*state;
+ return minval + state * (maxval - minval) / 4294967296.0;
+}
+
+static cairo_time_t
+do_wide_strokes_ha (cairo_t *cr, int width, int height, int loops)
+{
+ int count;
+
+ state = 0xc0ffee;
+ for (count = 0; count < 1000; count++) {
+ double h = floor (uniform_random (0, height));
+ cairo_move_to (cr, floor (uniform_random (0, width)), h);
+ cairo_line_to (cr, ceil (uniform_random (0, width)), h);
+ }
+
+ cairo_set_line_width (cr, 5.);
+
+ cairo_perf_timer_start ();
+
+ while (loops--)
+ cairo_stroke_preserve (cr);
+
+ cairo_perf_timer_stop ();
+
+ cairo_new_path (cr);
+
+ return cairo_perf_timer_elapsed ();
+}
+
+static cairo_time_t
+do_wide_strokes_h (cairo_t *cr, int width, int height, int loops)
+{
+ int count;
+
+ state = 0xc0ffee;
+ for (count = 0; count < 1000; count++) {
+ double h = uniform_random (0, height);
+ cairo_move_to (cr, uniform_random (0, width), h);
+ cairo_line_to (cr, uniform_random (0, width), h);
+ }
+
+ cairo_set_line_width (cr, 5.);
+
+ cairo_perf_timer_start ();
+
+ while (loops--)
+ cairo_stroke_preserve (cr);
+
+ cairo_perf_timer_stop ();
+
+ cairo_new_path (cr);
+
+ return cairo_perf_timer_elapsed ();
+}
+
+static cairo_time_t
+do_wide_strokes_va (cairo_t *cr, int width, int height, int loops)
+{
+ int count;
+
+ state = 0xc0ffee;
+ for (count = 0; count < 1000; count++) {
+ double v = floor (uniform_random (0, width));
+ cairo_move_to (cr, v, floor (uniform_random (0, height)));
+ cairo_line_to (cr, v, ceil (uniform_random (0, height)));
+ }
+
+ cairo_set_line_width (cr, 5.);
+
+ cairo_perf_timer_start ();
+
+ while (loops--)
+ cairo_stroke_preserve (cr);
+
+ cairo_perf_timer_stop ();
+
+ cairo_new_path (cr);
+
+ return cairo_perf_timer_elapsed ();
+}
+
+static cairo_time_t
+do_wide_strokes_v (cairo_t *cr, int width, int height, int loops)
+{
+ int count;
+
+ state = 0xc0ffee;
+ for (count = 0; count < 1000; count++) {
+ double v = uniform_random (0, width);
+ cairo_move_to (cr, v, uniform_random (0, height));
+ cairo_line_to (cr, v, uniform_random (0, height));
+ }
+
+ cairo_set_line_width (cr, 5.);
+
+ cairo_perf_timer_start ();
+
+ while (loops--)
+ cairo_stroke_preserve (cr);
+
+ cairo_perf_timer_stop ();
+
+ cairo_new_path (cr);
+
+ return cairo_perf_timer_elapsed ();
+}
+
+static cairo_time_t
+do_wide_strokes (cairo_t *cr, int width, int height, int loops)
+{
+ int count;
+
+ /* lots and lots of overlapping strokes */
+ state = 0xc0ffee;
+ for (count = 0; count < 1000; count++) {
+ cairo_line_to (cr,
+ uniform_random (0, width),
+ uniform_random (0, height));
+ }
+
+ cairo_set_line_width (cr, 5.);
+
+ cairo_perf_timer_start ();
+
+ while (loops--)
+ cairo_stroke_preserve (cr);
+
+ cairo_perf_timer_stop ();
+
+ cairo_new_path (cr);
+
+ return cairo_perf_timer_elapsed ();
+}
+
+cairo_bool_t
+wide_strokes_enabled (cairo_perf_t *perf)
+{
+ return cairo_perf_can_run (perf, "wide-strokes", NULL);
+}
+
+void
+wide_strokes (cairo_perf_t *perf, cairo_t *cr, int width, int height)
+{
+ cairo_set_source_rgb (cr, 1., 1., 1.);
+
+ cairo_perf_run (perf, "wide-strokes-halign", do_wide_strokes_ha, NULL);
+ cairo_perf_run (perf, "wide-strokes-valign", do_wide_strokes_va, NULL);
+ cairo_perf_run (perf, "wide-strokes-horizontal", do_wide_strokes_h, NULL);
+ cairo_perf_run (perf, "wide-strokes-vertical", do_wide_strokes_v, NULL);
+ cairo_perf_run (perf, "wide-strokes-random", do_wide_strokes, NULL);
+}
diff --git a/perf/micro/world-map.c b/perf/micro/world-map.c
new file mode 100644
index 000000000..ff22eebf3
--- /dev/null
+++ b/perf/micro/world-map.c
@@ -0,0 +1,149 @@
+/*
+ * Copyright © 2006 Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+#include "cairo-perf.h"
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+typedef enum {
+ WM_NEW_PATH,
+ WM_MOVE_TO,
+ WM_LINE_TO,
+ WM_HLINE_TO,
+ WM_VLINE_TO,
+ WM_REL_LINE_TO,
+ WM_END
+} wm_type_t;
+
+typedef struct _wm_element {
+ wm_type_t type;
+ double x;
+ double y;
+} wm_element_t;
+
+#include "world-map.h"
+
+enum {
+ STROKE = 1,
+ FILL = 2,
+};
+
+static cairo_time_t
+do_world_map (cairo_t *cr, int width, int height, int loops, int mode)
+{
+ const wm_element_t *e;
+ double cx, cy;
+
+ cairo_set_line_width (cr, 0.2);
+
+ cairo_perf_timer_start ();
+
+ while (loops--) {
+ cairo_set_source_rgb (cr, .68, .85, .90); /* lightblue */
+ cairo_rectangle (cr, 0, 0, 800, 400);
+ cairo_fill (cr);
+
+ e = &countries[0];
+ while (1) {
+ switch (e->type) {
+ case WM_NEW_PATH:
+ case WM_END:
+ if (mode & FILL) {
+ cairo_set_source_rgb (cr, .75, .75, .75); /* silver */
+ cairo_fill_preserve (cr);
+ }
+ if (mode & STROKE) {
+ cairo_set_source_rgb (cr, .50, .50, .50); /* gray */
+ cairo_stroke (cr);
+ }
+ cairo_new_path (cr);
+ cairo_move_to (cr, e->x, e->y);
+ break;
+ case WM_MOVE_TO:
+ cairo_close_path (cr);
+ cairo_move_to (cr, e->x, e->y);
+ break;
+ case WM_LINE_TO:
+ cairo_line_to (cr, e->x, e->y);
+ break;
+ case WM_HLINE_TO:
+ cairo_get_current_point (cr, &cx, &cy);
+ cairo_line_to (cr, e->x, cy);
+ break;
+ case WM_VLINE_TO:
+ cairo_get_current_point (cr, &cx, &cy);
+ cairo_line_to (cr, cx, e->y);
+ break;
+ case WM_REL_LINE_TO:
+ cairo_rel_line_to (cr, e->x, e->y);
+ break;
+ }
+ if (e->type == WM_END)
+ break;
+ e++;
+ }
+
+ cairo_new_path (cr);
+ }
+
+ cairo_perf_timer_stop ();
+
+ return cairo_perf_timer_elapsed ();
+}
+
+static cairo_time_t
+do_world_map_stroke (cairo_t *cr, int width, int height, int loops)
+{
+ return do_world_map (cr, width, height, loops, STROKE);
+}
+
+static cairo_time_t
+do_world_map_fill (cairo_t *cr, int width, int height, int loops)
+{
+ return do_world_map (cr, width, height, loops, FILL);
+}
+
+static cairo_time_t
+do_world_map_both (cairo_t *cr, int width, int height, int loops)
+{
+ return do_world_map (cr, width, height, loops, FILL | STROKE);
+}
+
+cairo_bool_t
+world_map_enabled (cairo_perf_t *perf)
+{
+ return cairo_perf_can_run (perf, "world-map", NULL);
+}
+
+void
+world_map (cairo_perf_t *perf, cairo_t *cr, int width, int height)
+{
+ cairo_perf_run (perf, "world-map-stroke", do_world_map_stroke, NULL);
+ cairo_perf_run (perf, "world-map-fill", do_world_map_fill, NULL);
+ cairo_perf_run (perf, "world-map", do_world_map_both, NULL);
+}
diff --git a/perf/micro/world-map.h b/perf/micro/world-map.h
new file mode 100644
index 000000000..af58b80f1
--- /dev/null
+++ b/perf/micro/world-map.h
@@ -0,0 +1,196 @@
+/* The data for this test case was provided by Gary Nicholson
+ * <gary@imapping.co.nz> who originally created an interactive SVG map
+ * of the world as can be seen here:
+ *
+ * http://www.wherearewe.co.nz/svg.html
+ *
+ * The data is used here by permission from Gary given on 2006-11-08:
+ *
+ * Thanks for asking, I don't need any attribution if you are
+ * only using the vectors and not the entire map with
+ * interactivity etc. So feel free to do what you wish with
+ * the data.
+ */
+
+#define N(x,y) { WM_NEW_PATH, x, y }
+#define M(x,y) { WM_MOVE_TO, x, y }
+#define L(x,y) { WM_LINE_TO, x, y }
+#define H(x,y) { WM_HLINE_TO, x, y }
+#define V(x,y) { WM_VLINE_TO, x, y }
+#define l(x,y) { WM_REL_LINE_TO, x, y }
+#define E(x,y) { WM_END, x, y }
+
+static const wm_element_t countries[] = {
+N(413.519,90.071),l(.136,-.348),l(-.31,-.204),l(-.017,-.327),l(.213,-.322),l(.245,-.147),l(.142,-.08),l(.225,.072),l(.062,.301),l(.41,.312),l(.466,.096),l(-.044,.288),l(-.248,.144),l(.074,.353),l(-.145,-.063),l(-.568,-.011),l(-.642,-.063),
+N(421.683,94.397),l(.193,.336),l(-.266,.274),l(.214,.288),l(-.09,.192),l(.622,.062),l(.008,.144),l(.55,.242),l(.579,-.332),l(.215,.117),l(-.029,.171),l(-.126,.309),l(.112,.212),l(-.038,.192),l(-.315,-.051),l(-.176,-.162),l(-.283,.091),l(-.081,.273),l(.244,.131),l(-.228,.415),l(-.244,-.333),l(-.469,.05),l(-.071,.122),l(-.216,.03),l(-.23,-.142),l(-.143,-.354),l(-.371,.081),l(.019,.333),l(-.425,.384),l(-.018,.535),l(-.285,.151),l(-.385,-.312),l(.098,-.182),l(-.311,-.071),l(-.534,-.363),l(-.016,-.415),l(-.777,.404),l(.103,.212),l(-.349,.432),l(-.275,.16),l(-.629,-.168),l(-.627,.204),l(-.599,-.062),l(-.102,-.424),l(-.312,-.806),l(-.616,.147),l(-.854,.668),l(-.369,-.111),l(.238,-.226),l(.013,-.322),l(-.08,-.137),l(.089,-.294),l(.718,-.418),l(-.038,-.315),l(.575,-.24),l(.012,-.076),l(.528,-.494),l(.173,-.035),l(-.116,-.089),l(-.153,-.028),l(.221,-.302),l(.446,.007),l(-.005,.096),l(.473,.007),l(.385,-.309),l(.271,.089),l(.272,-.117),l(.271,.096),l(.567,-.158),l(.278,.11),l(.354,-.021),l(-.179,-.199),l(.709,-.199),l(.017,.151),l(.199,-.014),l(.149,.089),l(.852,.007),l(.664,.261),
+N(421.394,104.558),l(.104,.175),l(.04,.256),l(-.06,.475),l(.118,.054),l(.062,.333),l(-.076,.795),l(-.211,.327),l(-.118,.724),l(-.292,.501),l(-.298,-.043),l(-.057,-.196),l(-.41,-.076),l(-.227,-.152),l(.284,-.207),l(-.07,-.076),l(-.437,-.098),l(.257,-.332),l(-.11,-.071),l(-.291,.071),l(-.053,-.147),l(.115,-.022),l(.175,-.158),l(-.094,-.153),l(-.257,-.082),l(.015,-.164),l(.247,-.12),l(-.284,-.218),l(.241,-.284),l(.6,-.305),l(.27,-.022),l(.04,-.125),l(.292,-.043),l(.195,.104),l(.096,-.142),l(-.022,-.344),l(.072,-.224),l(.143,-.011),M(396.323,103.853),l(.375,-.122),l(.411,-.365),l(.549,-2.299),l(.397,-.091),l(-.21,-.29),l(-.226,.259),l(.125,-1.144),l(.223,-.826),l(.115,.153),l(.496,.306),l(.191,.382),l(.191,.229),l(-.281,-.673),l(-.63,-.582),l(-.242,-.233),l(.024,-.249),l(.359,-.477),l(-.202,-.375),l(-.2,-.274),l(-.326,-.216),l(-.685,-.1),l(-.515,-.571),l(-.416,-.323),l(.278,-.426),l(-.233,-.181),l(-.343,-.131),l(-.511,-.142),l(-.184,-.173),l(.247,-.376),l(-.329,-.173),l(-.509,.179),l(-.489,-.249),l(-.824,-.251),l(-.619,-.181),l(-.325,.014),l(-.215,-.25),l(-.91,.167),l(-.059,-.25),l(-.265,-.125),l(-.367,-.042),l(-.056,-.104),l(.861,-.083),l(-.085,-.229),l(-.526,-.104),l(.442,-.104),l(.086,-.205),l(-.275,.017),l(-.263,-.021),l(-.417,.083),l(.04,-.438),l(.303,.012),l(.305,-.146),l(.526,-.088),l(.562,-.174),l(.215,.188),l(.18,-.167),l(.474,.063),l(.112,-.26),l(.272,-.059),l(.764,-.078),l(.393,.366),l(.275,.26),l(.342,.083),l(.652,-.271),l(.317,.167),l(.276,-.127),l(.457,-.124),l(.029,.23),l(.591,-.065),l(.3,-.103),l(-.265,-.188),l(-.028,-.251),l(.056,-.345),l(-.037,-.428),l(-.131,.021),l(-.562,-.682),l(-.11,-.407),l(.927,.126),l(.607,-.105),l(-.084,.397),l(.248,.419),l(.342,-.146),l(1.241,.104),l(.501,.146),l(.079,-.014),l(.525,-.093),l(.662,-.27),l(-.534,-.124),l(.055,-.204),l(.166,-.175),l(.753,-.322),l(.756,-.181),l(.902,-.215),l(.314,-.235),l(.302,-.264),l(-.053,-.775),l(.135,-.542),l(.521,-.25),l(.46,-.16),l(.916,-.092),l(.177,-.096),l(.208,.447),l(.311,.335),l(.266,.127),l(.141,-.071),l(.41,-.208),l(.153,.17),l(.202,.458),l(.194,.133),l(.518,-.012),l(.159,.301),l(.259,-.012),l(.576,.048),l(.375,.168),l(-.159,.241),l(.091,.175),l(-.072,.198),l(.285,.122),l(.406,-.075),l(.446,-.035),l(.193,-.313),l(.245,-.072),l(-.119,.373),l(.146,.18),l(-.039,.228),l(.529,.048),l(.341,.192),l(.371,.204),l(.127,.228),l(.694,-.174),l(.079,.114),l(.642,.063),l(.568,.011),l(.145,.063),l(.428,.319),l(.337,.277),l(.395,-.055),l(.045,.145),l(.689,-.062),l(.072,-.048),l(.233,.007),l(.095,.186),l(.456,.09),l(.479,-.014),l(.605,.193),l(-.954,.806),l(-.054,.213),l(-.054,.358),l(-.321,.372),l(-.075,.295),l(.091,.076),l(-.216,.701),l(.135,.233),l(-.385,.309),l(-.473,-.007),l(.005,-.096),L(415.96,94.5),l(-.221,.302),l(.153,.028),l(.116,.089),l(-.173,.035),l(-.528,.494),l(-.012,.076),l(-.575,.24),l(.038,.315),l(-.718,.418),l(-.089,.294),l(.08,.137),l(-.013,.322),l(-.238,.226),l(.369,.111),l(.854,-.668),l(.616,-.147),l(.312,.806),l(.102,.424),l(-.624,.301),l(.532,.344),l(.025,.292),l(.43,.192),l(-.199,.272),l(-.541,.353),l(-.183,-.111),l(-.437,.186),l(.352,.358),l(.616,.191),l(.135,.331),l(-.175,.01),l(-.315,.371),l(.193,.442),l(.754,.391),l(.849,-.07),l(.062,.281),l(-.146,.469),l(-.346,.23),l(-.221,.215),l(-.833,.488),l(-.889,.659),l(-.427,.087),l(-.318,.043),l(-.798,.159),l(-.405,-.028),l(-.471,-.156),l(-.851,-.499),l(-.315,-.085),l(-.354,.029),l(-.231,.072),l(-.511,-.056),l(-.752,-.313),l(-.602,.044),l(-.731,.345),l(-.357,.258),l(-.555,.559),l(-.147,.386),l(.099,.514),l(.091,.379),l(-.334,-.091),l(-.75,.137),l(-.039,.136),l(-.485,-.015),l(-.427,-.197),l(-.395,.167),l(-.261,-.015),l(-.036,-.152),l(-.335,-.091),l(-.206,.03),l(-.374,.076),l(-.187,-.076),l(-.035,-.289),l(-.091,-.213),l(-1.252,-.304),l(-.355,0),l(.017,.319),l(-.542,-.015),l(-.337,.061),l(-.037,-.122),l(-.767,.03),l(-.084,-.114),l(-.028,-.038),l(-.431,-.152),l(-.131,.076),l(-.262,-.03),l(-.056,.076),l(-.507,-.395),l(-.15,.061),l(-1.088,-.334),l(-.112,.106),l(-.15,-.03),l(-.094,-.106),l(.205,-.243),l(-.058,-.122),l(-.469,.03),l(-.472,-.243),
+N(681.312,116.395),l(.235,-.171),l(.283,-.256),l(.633,-.738),l(.315,-.157),l(.595,.011),l(.579,.068),l(.511,.096),l(.309,-.115),l(.571,-.678),l(.682,.621),l(1.178,1.611),l(.329,.495),l(.269,.664),l(.002,.75),l(-.034,.947),l(-.129,.637),l(.143,.113),l(.5,-.043),l(-.121,.41),l(-.282,.523),l(-.5,.75),l(-.316,.312),l(-.243,.043),l(-.567,-.211),l(-.256,.1),l(-.607,.58),l(-.431,-.083),l(-.289,-.225),l(-.544,.1),l(-.526,.199),l(-1.188,.835),l(-.462,.043),l(-.46,.312),l(-.055,-.564),l(-.056,-.324),l(-.163,-.705),l(-.137,-.395),l(.167,-.453),l(.499,-.468),l(0,-.353),l(.226,-.425),l(-.044,-.141),l(-.378,-.311),l(-.095,-.296),l(.015,-.467),l(-.087,-.339),l(-.289,-.126),l(-.603,-.084),l(.654,-.411),l(.303,-.114),l(.654,.268),l(.254,-.241),l(-.029,-.283),l(-.764,-.89),l(-.113,-.311),l(-.137,-.105),
+N(475.646,121.847),l(-.018,.175),l(.338,.391),l(-.295,-.009),l(-.132,.108),l(-.104,-.059),l(-.327,-.021),l(-.121,.33),l(-.783,.257),l(-.384,.046),l(-.099,.053),l(0,.21),l(-.217,.006),l(-.072,-.192),l(-.402,.023),l(-.547,-.146),l(-.191,-.087),l(0,-.21),l(-.161,-.105),l(-.122,-.403),l(.082,-.035),l(.12,.1),l(.147,-.006),l(.405,-.304),l(.253,-.006),l(.328,.092),l(.077,-.086),l(.088,-.286),l(-.053,-.175),l(.627,.093),l(.658,.027),l(.367,-.056),l(.818,-.233),l(.689,-.304),l(.535,-.158),l(-.475,.295),l(-.436,.231),l(-.596,.444),
+N(704.404,117.274),l(.197,-.099),l(1.108,-.271),l(.057,.354),l(-.481,.284),l(-.232,.241),l(-.068,.453),l(.139,.367),l(.291,.056),l(.221,-.114),l(.418,-.354),l(.24,-.085),l(1.656,-.697),l(.389,-.213),l(.46,-.326),l(.349,-.638),l(.76,-.412),l(.347,-.327),l(.191,-.269),l(.142,-.51),l(.538,-.582),l(-.01,-.142),l(.344,-.567),l(.159,-.468),l(.139,-.609),l(-.043,-.467),l(-.33,-.198),l(-.128,-.24),l(.234,-.213),l(.166,-.284),l(-.155,-1.023),l(.544,-.343),l(.176,-.242),l(.327,-.328),l(.192,0),l(.21,.355),l(.199,.227),l(.303,-.058),l(.799,-.257),l(-.169,-.526),l(-.311,-.028),l(-.36,-.312),l(.694,-.415),l(.441,.156),l(.336,.227),l(.025,.199),l(-.016,.868),l(.058,.611),l(.22,.127),l(.243,.312),l(.717,1.432),l(.001,.496),l(-.246,.709),l(-.709,.766),l(-.226,.439),l(.064,.368),l(-.15,.071),l(-.737,.285),l(-.161,.113),l(-.164,.199),l(-.174,.453),l(.02,.396),l(.094,.254),l(.131,.792),l(-.04,.693),l(-.686,.751),l(-.242,.736),l(.02,.707),l(.198,.296),l(.422,.353),l(-.617,.298),l(-.193,.127),l(-.166,.17),l(-.174,.834),l(-1.081,.439),l(-.094,-.282),l(.294,-.665),l(.184,-.523),l(-.198,-.126),l(-.514,.241),l(-.578,.623),l(-.476,.001),l(-.346,.312),l(-.066,.748),l(-.354,.269),l(-.188,-.028),l(-.066,-.155),l(.003,-.606),l(-.149,-.155),l(-.211,.042),l(-.309,.156),l(-.344,.311),l(-.325,.523),l(-.866,-.055),l(-.505,.057),l(-.631,.1),l(-.458,-.549),l(-.685,-.323),l(-.26,.254),l(-.067,.184),l(-.177,.353),l(.037,.056),l(.417,.197),l(.416,.323),l(-.293,.198),l(-.829,.129),l(-.433,.241),l(-.463,.622),l(-.522,.847),l(-.688,-.365),l(-.565,-.21),l(-.285,-.197),l(-.014,-.169),l(-.194,-.818),l(.099,-.155),l(.495,-.325),l(.179,-.269),l(-.067,-.282),l(-.18,-.042),l(-.601,.17),l(-.341,-.028),l(-.789,-.167),l(-.475,.128),l(-.427,.227),l(-.437,.184),l(-.269,-.098),l(-.256,-.027),l(-1.647,.398),l(-.814,.298),l(-.21,-.31),l(-.452,-.042),l(-.413,.438),l(-.006,.635),l(-.756,-.238),l(-.579,-.055),l(-1.1,.073),l(-.267,-.14),l(.072,-.339),l(.179,-.283),l(.483,.013),l(.499,-.114),l(.751,-.467),l(2.201,-1.953),l(.28,-.015),l(.427,-.128),l(.056,.424),l(.495,-.128),l(1.278,-.257),l(.933,-.058),l(1.183,-.172),l(.892,-.256),l(.068,.452),l(.377,.268),l(.167,-.085),l(.654,-.199),l(.446,-.34),l(-.003,-.353),l(.114,-.467),l(.465,-.51),l(.698,-.581),l(.371,-.453),l(-.062,-1.117),l(.182,-.213),M(695.464,127.756),l(-.292,-.197),l(-.223,-.268),l(-.101,-.381),l(-.177,-.395),l(-.492,-.535),l(.731,-.382),l(.287,-.269),l(.456,-.593),l(.409,.253),l(.615,-.015),l(.483,-.185),l(.311,-.339),l(.451,-.311),l(.454,-.029),l(.316,.169),l(.862,.224),l(.153,.254),l(-.1,.127),l(-.102,.423),l(-.292,.24),l(-.864,.876),l(-.181,-.211),l(-.424,-.295),l(-.467,-.042),l(-.612,.213),l(-.193,.184),l(-.245,.495),l(-.165,.508),l(-.153,.212),l(-.448,.269),M(691.12,131.448),l(-.366,-.042),l(-.056,-.141),l(.268,-.537),l(.128,-.593),l(-.334,-.112),l(-.239,.198),l(-.155,.466),l(-.381,.452),l(-.326,-.211),l(-.059,-.211),l(.322,-.466),l(.032,-.296),l(-.356,-.917),l(.169,-.113),l(.687,-.58),l(.083,-.141),l(.034,-.466),l(-.532,-.789),l(-.333,-.042),l(-.162,.269),l(-.419,.495),l(-.249,-.112),l(-.23,-.508),l(-.376,-.267),l(-.261,-.366),l(.41,-.325),l(.733,.083),l(.706,-.171),l(.315,-.466),l(.241,-.283),l(.484,-.058),l(.478,.056),l(.249,.38),l(.27,.168),l(.43,.084),l(.628,-.213),l(.225,.395),l(-.569,.438),l(.405,.239),l(.443,.437),l(.079,.254),l(-.596,.58),l(-.242,.41),l(-.104,.367),l(-.085,.621),l(-.109,.649),l(-.242,.353),l(-.194,.099),l(-.165,.071),l(-.197,.184),l(-.479,.678),M(711.938,108.369),l(-.222,-.241),l(-.077,-.271),l(.325,-.642),l(-.055,-.342),l(-.549,-.198),l(-.168,-.171),l(-.146,-.812),l(.583,-.386),l(.522,-.172),l(.646,-.373),l(.037,-.356),l(-.318,-.285),l(.277,-.3),l(.224,-.015),l(.661,.427),l(.373,.085),l(.532,-.201),l(-.004,-1.186),l(.455,-.187),l(.45,-.244),l(.074,-.743),l(.007,-.844),l(-.398,-.758),l(-.098,-.473),l(.166,-.216),l(.618,-.346),l(.063,.072),l(.507,.43),l(.904,.816),l(1.07,.842),l(1.083,.684),l(.627,.285),l(.528,.17),l(1.02,.198),l(.282,.042),l(.304,-.086),l(.866,-.66),l(.461,-.144),l(.002,.1),l(-.308,.358),l(-.335,.558),l(.198,.414),l(.469,.599),l(.197,.356),l(-.561,.272),l(-.447,.244),l(-.534,.158),l(-.365,.015),l(-.488,-.199),l(-.453,.015),l(-.363,.144),l(-.345,.229),l(-.754,.786),l(-.396,.5),l(-.26,.599),l(-.4,-.07),l(-.425,-.241),l(-2.031,-.965),l(-.461,-.085),l(-.72,.044),l(-1.038,.587),l(-.153,-.299),l(-.372,-.356),l(-.339,.029),l(-.266,.115),l(-.439,.272),l(.049,.299),l(1.16,.497),l(.56,.298),l(.302,.27),l(-.391,.214),l(-.303,.029),l(-.305,-.128),l(-.261,.043),l(-.324,.314),l(-.388,.471),l(-.347,.114),
+N(597.917,139.685),l(1.251,-1.545),l(.609,-.539),l(.348,-.239),l(.149,-.103),l(.417,-.016),l(.309,.294),l(.479,.208),l(1.659,.047),l(.371,.041),l(.312,.209),l(.329,.619),l(-.07,.156),l(.042,.24),l(.326,.294),l(.313,.069),l(.258,.238),l(.017,.282),l(-.217,.58),l(-.624,.06),l(-1.036,.062),l(-1.238,-.063),l(-.335,-.125),l(-.301,-.055),l(-.531,.313),l(-.544,.074),l(-.085,-.021),l(-.869,-.214),l(-.559,-.081),l(-.637,-.18),l(-.235,-.493),l(.092,-.113),
+N(362.764,152.723),l(.072,-.625),l(.395,-.876),l(.52,-.552),l(.488,-.566),l(.244,-.509),l(1.175,-2.559),l(.238,-.241),l(1.404,-1.175),l(.345,-.495),l(.051,-.918),l(.305,-1.088),l(.651,-1.075),l(.399,-.34),l(.404,-.198),l(.838,-.51),l(.361,-.495),l(.334,-.777),l(.428,-.851),l(1.635,-.04),l(2.511,0),l(2.677,-.001),l(1.718,.004),l(1.42,-.008),l(.027,.876),l(-.03,1.752),l(.002,.65),l(-.104,.396),l(-.56,-.011),l(-6.005,-.022),l(-.557,.074),l(-.047,.509),l(-.07,2.261),l(-.099,2.6),l(-.144,.128),l(-.809,.287),l(-.726,.315),l(-.575,.427),l(-.249,.383),l(-.01,.707),l(.164,1.539),l(.051,1.102),l(-.212,-.027),l(-.732,.033),l(-2.396,-.014),l(-5.055,-.056),l(-.474,-.013),
+N(514.551,145.841),l(-.374,.027),l(-.336,-.083),l(-.008,-.615),l(-.153,-.437),l(-.108,-.791),l(.187,-.607),l(.188,-.11),l(-.059,-.187),l(.177,-.607),l(.33,-.269),l(.312,.083),l(.069,.315),l(.26,.093),l(.063,.199),l(.116,.326),l(-.106,.42),l(.031,.708),l(.118,.254),l(-.104,.381),l(-.327,.467),l(-.275,.433),
+N(514.177,145.868),l(.374,-.027),l(.008,.288),l(.361,.14),l(.153,.128),l(.186,-.093),l(-.046,.443),l(.397,.001),l(.402,.127),l(.687,-.093),l(.103,-.21),l(.183,-.058),l(.218,.117),l(.424,-.042),l(.595,.112),l(.224,-.035),l(.079,-.105),l(1.358,.222),l(.732,-.14),l(-.022,-.292),l(.225,.175),l(.375,-.016),l(.157,-.099),l(.312,-.422),l(.232,-.073),l(.267,-.495),l(.131,-.297),l(.711,-.637),l(.813,-.889),l(.163,.105),l(.229,-.178),l(.85,-.708),l(.313,-.433),l(.15,.161),l(-.248,.42),l(-.107,.299),l(-.004,.176),l(.099,.064),l(.121,-.024),l(.454,.042),l(.09,.324),l(.001,.508),l(-.003,.358),l(-.49,.034),l(-.401,-.083),l(-.107,.396),l(.073,1.326),l(-.199,.34),l(-.536,.596),l(.003,.946),l(.024,2.075),l(.063,.183),l(-.152,.057),l(-.584,.469),l(-.839,-.108),l(-3.387,-.446),l(-3.362,-.375),l(-.261,-.902),l(-.548,-1.154),l(-1.043,-2.198),
+N(668.627,151.365),l(-.102,-.056),l(-.107,-.325),l(-.922,-1.212),l(-.332,-.987),l(-.03,-.438),l(.156,-.749),l(.546,-.792),l(1.312,-1.852),l(.259,-.184),l(.425,-.128),l(.229,-.184),l(.358,-.227),l(.228,.127),l(.554,.394),l(-.334,.424),l(-.084,.142),l(.023,.31),l(-.067,.622),l(-.203,.296),l(-.182,.354),l(-.065,.692),l(-.1,.494),l(-.317,.805),l(-.473,.707),l(-.417,.833),l(-.014,.353),l(-.114,.438),l(-.228,.142),
+N(389.765,144.543),l(.1,.084),l(.895,.531),l(2.054,1.344),l(.811,.575),l(3.283,2.241),l(1.924,1.26),l(1.292,.824),l(.397,.253),l(2.472,1.469),l(.181,.253),l(-.096,.396),l(.082,.183),l(.393,.28),l(1.111,1.039),l(.229,.027),l(.47,-.314),l(.588,.562),l(.375,.167),l(.748,.024),l(.309,.111),l(.277,.352),l(.099,.522),l(-.161,.679),l(.146,.564),l(2.176,-.408),l(.064,1.017),l(.034,2.203),l(.001,.96),l(-.08,.89),l(-.145,.919),l(-.434,1.246),l(-.596,.794),l(-.339,.271),l(-.29,.129),l(-2.533,.085),l(-1.808,.124),l(-.209,.072),l(-.562,.427),l(-.579,.272),l(-.678,-.053),l(-.581,-.081),l(-1.062,-.173),l(-.36,-.059),l(-.356,-.125),l(-.37,.073),l(-1.22,.713),l(-.947,.458),l(-.304,.228),l(-.314,.793),l(-.274,-.027),l(-.324,-.182),l(-.518,-.209),l(-.272,.101),l(-.638,.625),l(-.492,.667),l(-.393,.822),l(-.174,.227),l(-.45,.102),l(-.551,-.364),l(-.293,-.281),l(-.273,.058),l(-.397,.384),l(-.355,1.217),l(-.292,1.047),l(-.317,.369),l(-.543,.271),l(-.448,.158),l(-.257,.016),l(-.141,.255),l(.058,.749),l(-.133,.876),l(-.261,.92),l(-.172,.326),l(-.046,.156),l(-.08,.043),l(-.159,.1),l(-.604,.399),l(-.352,.059),l(-.148,-.239),l(-.117,-.381),l(-.004,-.297),l(-.147,-.211),l(-.257,-.041),l(-.239,.114),l(-.571,.483),l(-.362,.469),l(-.35,.228),l(-.455,-.436),l(-.566,-.321),l(-.352,.059),l(-.522,.54),l(-.559,-.901),l(-.194,-1.143),l(-.349,-.718),l(-.474,-.478),l(-.265,-.451),l(-.271,-.832),l(-.022,-.339),l(-.246,-.281),l(-.323,-.055),l(-.684,.428),l(-.3,.327),l(-.43,.243),l(-.565,-.152),l(-.356,-.153),l(-.338,-.026),l(-.475,.413),l(-.252,.256),l(-.536,-.265),l(-.882,-.715),l(-.18,-.183),l(-.113,-.028),l(.062,-.142),l(.004,-.565),l(-.082,-.833),l(-.265,-.337),l(-.554,-.322),l(-.181,-.197),l(-.22,-.479),l(-.144,-.663),l(-.251,-1.1),l(.057,-.339),l(.506,-.399),l(.332,-.284),l(.018,-.607),l(.181,-.552),l(.252,-.256),l(.402,-.073),l(.261,.111),l(.568,.83),l(.214,.168),l(.454,.082),l(.107,-.269),l(-.055,-.296),l(.06,-.212),l(.535,.124),l(.713,.137),l(.485,.054),l(.387,-.031),l(.945,-.344),l(1.953,-.026),l(6.457,-.01),l(.379,-1.613),l(-.724,-.787),l(-.186,-1.468),l(-.202,-2.386),l(-.325,-2.753),l(-.178,-1.736),l(-.19,-1.468),l(-.908,-7.962),l(-.049,-.776),l(3.231,-.089),l(.523,-.13),
+N(525.37,142.384),l(.312,-.429),l(.155,-.17),l(.084,.833),l(-.423,.707),l(-.118,.156),l(-.121,.024),l(-.099,-.064),l(.004,-.176),l(.107,-.299),l(.248,-.42),l(-.15,-.161),M(525.923,144.712),l(0,.22),l(.456,.762),l(.408,.465),l(.782,.634),l(.677,.394),l(1.008,.52),l(.392,.154),l(.277,.014),l(.576,-.029),l(.364,.112),l(.873,.973),l(.518,.648),l(.46,.422),l(.81,.365),l(.025,.212),l(-.67,1.06),l(-.615,.721),l(-.883,.807),l(-.776,1.541),l(-.242,.142),l(-.562,-.083),l(-.235,-.084),l(-.252,.071),l(-.278,.509),l(-.062,1.115),l(.001,.791),l(.134,.621),l(-.403,.142),l(-1.046,.073),l(-.627,.27),l(-.367,.283),l(-.29,.495),l(-.131,.551),l(-.204,.283),l(-.444,.255),l(-.544,.1),l(-.292,0),l(-.386,-.042),l(-.326,.029),l(-.382,.283),l(-.22,.297),l(-.125,.508),l(.003,.353),l(-.091,.311),l(-.631,.396),l(-.344,.043),l(-.776,-.21),l(-.717,.058),l(-.896,.27),l(-.768,.298),l(-.283,.099),l(-.416,.145),l(-.241,-.306),l(-.483,-.689),l(.006,-.296),l(-.127,-.253),l(-.933,-1.364),l(-.604,-.971),l(-.226,-.634),l(-.092,-.663),l(1.691,-.815),l(2.35,-1.213),l(5.346,-2.982),l(-.155,-1.453),l(-.581,-.914),l(-.063,-.183),l(-.024,-2.075),l(-.003,-.946),l(.536,-.596),l(.199,-.34),l(-.073,-1.326),l(.107,-.396),l(.401,.083),l(.49,-.034),
+N(405.733,173.04),l(-.568,-.971),l(-.562,-.025),l(-.37,.044),l(-.516,-.181),l(-.97,-.757),l(-.114,-.226),l(.335,-.439),l(-.018,-.212),l(-.179,-.268),l(-.502,-.42),l(-.389,-.266),l(-.422,-.492),l(-.426,-.93),l(-.019,-.396),l(.173,-.665),l(.581,.081),l(.678,.053),l(.579,-.272),l(.562,-.427),l(.209,-.072),l(1.808,-.124),l(2.533,-.085),l(.29,-.129),l(.339,-.271),l(.596,-.794),l(.434,-1.246),l(.145,-.919),l(.08,-.89),l(-.001,-.96),l(-.034,-2.203),l(-.064,-1.017),l(1.672,-.321),l(1.82,-.364),l(3.084,-2.617),l(.834,-.655),l(2.308,-1.454),l(1.607,-.956),l(4.012,-2.241),l(1.632,-.843),l(.265,-.186),l(.832,.137),l(1.646,.442),l(1.008,.333),l(.258,.182),l(1.192,.911),l(.231,-.157),l(1.519,-.729),l(.364,2.145),l(.169,1.298),l(.42,1.028),l(.554,.802),l(.703,.604),l(-.388,.722),l(-.265,.99),l(-.168,1.088),l(-.084,.989),l(.022,.537),l(-.062,.707),l(-.019,1.045),l(-.034,1.088),l(-.056,.466),l(-2.43,2.613),l(-.591,.78),l(-.87,1.333),l(-.572,.794),l(-.007,.678),l(.123,.719),l(.014,.269),l(-.951,.034),l(-.437,.2),l(-.453,.299),l(-.761,.697),l(-.259,.058),l(-.609,-.208),l(-.724,-.193),l(-.884,-.221),l(-.531,-.04),l(-.709,.047),l(-.628,.103),l(-.774,.287),l(-.403,.327),l(-.629,.399),l(-.273,.059),l(-.934,.005),l(-.965,-.277),l(-1.173,-.742),l(-.354,-.083),l(-.467,.116),l(-1.337,.544),l(-.37,.002),l(-.209,-.098),l(-1.095,-1.223),l(-.821,-.277),l(-1.111,-.121),l(-1.174,.108),l(-1.064,.188),l(-.676,.4),l(-.687,1.614),l(-.353,.482),l(-.158,.849),l(-.092,.961),l(-.902,-.503),l(-.727,-.589),l(-.339,-.28),l(-.321,.073),l(-.577,.3),
+N(431.763,171.063),l(-.351,-.407),l(-.575,-.52),l(-.173,-.394),l(-.014,-.269),l(-.123,-.719),l(.007,-.678),l(.572,-.794),l(.87,-1.333),l(.591,-.78),l(2.43,-2.613),l(.056,-.466),l(.034,-1.088),l(.019,-1.045),l(.062,-.707),l(-.022,-.537),l(.084,-.989),l(.168,-1.088),l(.265,-.99),l(.388,-.722),l(-.703,-.604),l(-.554,-.802),l(-.42,-1.028),l(-.169,-1.298),l(-.364,-2.145),l(1.818,-.858),l(.41,-.059),l(5.231,2.554),l(4.941,2.372),l(5.577,2.792),l(1.981,.963),l(-.02,1.045),l(-.016,.946),l(-.036,.636),l(.085,2.5),l(-.038,.749),l(.036,1.002),l(.031,1.229),l(-.04,.283),l(-.839,-.009),l(-1.245,.05),l(-.229,.143),l(-.417,1.245),l(-.583,.809),l(-.122,.438),l(.131,.677),l(-.149,.212),l(-.718,.428),l(-.053,.24),l(.342,.662),l(-.087,.34),l(-.542,.596),l(-.316,.609),l(.219,.352),l(.517,-.088),l(.338,.012),l(.141,.225),l(.221,1.228),l(.137,.522),l(.155,.295),l(.444,.407),l(.266,.465),l(.026,.367),l(-.15,.425),l(-.559,-.208),l(-.321,-.012),l(-.322,.086),l(-.939,.613),l(-.372,.228),l(-.165,.382),l(-.005,.41),l(-.196,.284),l(-2.649,2.275),l(-.386,.087),l(-2.181,.055),l(-.434,.059),l(-.209,.199),l(-.117,.806),l(-.646,1.176),l(-.258,.143),l(-.368,.031),l(-.881,-.009),l(-.818,.273),l(-.754,.386),l(-.466,.271),l(-.224,.03),l(-.225,-.069),l(-.494,-.661),l(-1.363,.686),l(-.449,.158),l(-.24,-.027),l(-.096,-.084),l(-.208,-.183),l(-.382,-1.057),l(-.638,-1.07),l(-1.343,-1.179),l(-1.088,-1.067),l(.323,-.539),l(.29,-.312),l(.24,-.1),l(.481,.082),l(1.187,.191),l(.674,-.032),l(.225,-.143),l(-.047,-.127),l(-.208,-.21),l(-.381,-.633),l(-.205,-.578),l(-.169,-1.228),l(.134,-.651),l(-.119,-1.2),l(-.395,-.887),l(-.923,-1.238),l(-.208,-.083),l(-.627,-.109),
+N(627.173,150.012),l(.483,-.229),l(.515,-.13),l(.341,.012),l(.597,.392),l(.325,.097),l(.584,-.413),l(.332,-.115),l(1.595,-.052),l(.807,-.117),l(.341,-.157),l(.696,-.554),l(.521,-.328),l(.298,-.101),l(.623,.575),l(.771,.235),l(.66,.053),l(.777,-.047),l(.237,.21),l(.056,.38),l(-.472,.75),l(.096,.521),l(.273,.365),l(.943,.615),l(.621,.166),l(.909,.107),l(.197,.143),l(-.19,.132),l(-.826,.482),l(.106,.465),l(-.203,.212),l(-1.261,-.054),l(-.136,.198),l(.057,.395),l(-.283,.382),l(-.585,.792),l(-.221,.142),l(-.533,.241),l(-.171,.127),l(-.27,.396),l(-.303,.932),l(-.388,.975),l(.268,.225),l(.469,.563),l(1.112,1.071),l(.023,.24),l(.042,.522),l(.087,.254),l(.42,.493),l(1.096,.83),l(1.282,1.296),l(.26,.197),l(.636,.069),l(.313,.38),l(.282,1.016),l(.302,.578),l(.638,.605),l(.293,.663),l(.341,1.382),l(.524,2.809),l(-.295,.438),l(-.235,.495),l(.05,.819),l(-.095,.41),l(.056,.664),l(-.027,.099),l(-.364,.551),l(-.447,.439),l(-.254,.127),l(-.509,.1),l(-.419,.17),l(-.501,.354),l(-.591,.622),l(-.579,.354),l(-.325,.043),l(-.512,-.197),l(-.404,-.31),l(-.179,-.141),l(-.153,.424),l(.051,.494),l(.048,.353),l(-.205,.721),l(-.388,.424),l(-.326,.071),l(-.235,-.07),l(-.246,.481),l(-.427,.326),l(-.523,.142),l(-.417,.213),l(-.459,.565),l(-.196,.269),l(-.406,.297),l(-.264,.099),l(-.365,-.042),l(.078,-.861),l(.1,-1.313),l(.151,-.494),l(.215,-.283),l(-.02,-.353),l(-.475,-.437),l(-.749,-.238),l(-.091,-.066),l(.3,-.289),l(.646,-.229),l(.915,-.528),l(.599,-.229),l(.497,.011),l(.688,.194),l(.17,-.27),l(-.03,-.197),l(-.568,-.435),l(-.216,-.422),l(.234,-.425),l(.99,-.571),l(.521,-.229),l(.932,-.443),l(.599,-.187),l(.385,-.285),l(.217,-.509),l(-.054,-1.073),l(.05,-.424),l(.076,-.367),l(-.455,-1.014),l(-.029,-.663),l(.215,-.905),l(.155,-.918),l(-.064,-.578),l(-.214,-.437),l(-.529,-.477),l(-.072,-.282),l(.226,-.439),l(-.136,-.395),l(-.358,-.308),l(-.685,-.391),l(-.471,-.52),l(-.57,-.914),l(-1.683,-2.121),l(-.698,-.772),l(-.637,-.646),l(-.632,-.476),l(-1.234,-.741),l(-.162,-.098),l(-.043,-.494),l(.277,-.369),l(.311,-.101),l(.476,.068),l(.287,-.058),l(.261,-.185),l(.255,-.326),l(-.009,-.508),l(-.87,-.968),l(-.434,-.675),l(-.262,-.083),l(-.39,.171),l(-.509,.483),l(-.287,.058),l(-.47,-.195),l(-.607,-.434),l(-.334,-.689),l(-.338,-.929),l(-.543,-.604),l(-.613,-.575),l(-.45,-.745),
+N(217.961,150.385),l(.304,-.043),l(.84,-.27),l(-.17,-.254),l(-.312,-.112),l(-.369,-.056),l(-.651,.016),l(-.497,-.042),l(-.645,.157),l(-1.193,.92),l(-.371,.029),l(-.653,.001),l(-.211,.113),l(-.189,.452),l(-.396,.284),l(-.32,.043),l(-.786,.086),l(.259,-.325),l(.473,-.312),l(-.128,-.593),l(.282,-.382),l(.114,-.099),l(1.258,-.61),l(1.625,-.47),l(1.164,-.087),l(.842,-.157),l(.825,.041),l(.566,-.044),l(.73,.168),l(.848,.083),l(.603,.197),l(.557,.112),l(.477,.013),l(.499,.268),l(.573,.536),l(.382,.253),l(.581,.168),l(.768,.111),l(1.229,.351),l(1.02,.492),l(.453,.31),l(.374,.55),l(.33,.141),l(.479,.041),l(1.704,.519),l(1.018,.167),l(.327,.239),l(-.344,.58),l(.233,.155),l(.559,.042),l(.756,-.072),l(.495,.168),l(.507,.38),l(.591,.281),l(.381,.296),l(-.233,.085),l(-.981,.087),l(-1.15,.398),l(-.626,.058),l(-1.054,-.209),l(-.9,-.041),l(-.934,.186),l(-.943,.115),l(-.484,.029),l(-.449,-.07),l(.353,-.382),l(.728,-.623),l(.173,-.396),L(229,154.204),l(-.181,-.127),l(-.622,-.14),l(-.7,.001),l(-.603,-.112),l(-.651,-.338),l(-.141,-.748),l(-.258,-.536),l(-.218,-.155),l(-.396,-.027),l(-1.005,.044),l(-.836,-.139),l(-.621,-.225),l(-.956,-.493),l(-.739,-.238),l(-.615,-.069),l(-1.154,-.068),l(-.489,-.098),l(-.855,-.352),
+N(634.036,168.444),l(.808,-.64),l(.121,-.438),l(-.002,-.945),l(-.157,-.507),l(-.419,-.703),l(-.979,-1.279),l(-.255,-.464),l(-.107,-.366),l(-.058,-1.524),l(-.435,-.632),l(-.688,-.659),l(-.285,-.535),l(-.052,-.282),l(-.266,-.153),l(-.893,-.192),l(-.403,-.012),l(-.286,.453),l(-.2,.538),l(-.543,.257),l(-.223,.072),l(-.59,-.265),l(-.835,-.348),l(-.346,.03),l(-1.173,1.178),l(-.37,.411),l(-.481,-.138),l(-.145,-.324),l(.027,-.494),l(.117,-.438),l(.528,-1.569),l(.085,-.41),l(-.249,-1.311),l(-.045,-.113),l(-.414,.045),l(-.489,.2),l(-.423,.003),l(-.186,-.154),l(-.066,-.367),l(.106,-.805),l(-.01,-.423),l(-.118,-.168),l(-.295,-.182),l(-.541,-.166),l(.193,-.185),l(.582,-.455),l(.442,-.581),l(.53,-.61),l(.502,-.355),l(.178,.196),l(.321,.21),l(.769,.08),l(.266,-.213),l(.109,-.339),l(-.119,-.521),l(-.228,-.366),l(-.138,-.592),l(.043,-.325),l(.24,-.241),l(.679,-.314),l(.45,.745),l(.613,.575),l(.543,.604),l(.338,.929),l(.334,.689),l(.607,.434),l(.47,.195),l(.287,-.058),l(.509,-.483),l(.39,-.171),l(.262,.083),l(.434,.675),l(.87,.968),l(.009,.508),l(-.255,.326),l(-.261,.185),l(-.287,.058),l(-.476,-.068),l(-.311,.101),l(-.277,.369),l(.043,.494),l(.162,.098),l(1.234,.741),l(.632,.476),l(.637,.646),l(.698,.772),l(1.683,2.121),l(.57,.914),l(.471,.52),l(.685,.391),l(.358,.308),l(.136,.395),l(-.226,.439),l(.072,.282),l(.529,.477),l(.214,.437),l(.064,.578),l(-.155,.918),l(-.209,.114),l(-.975,.429),l(-.3,.072),l(-.373,-.351),l(-.444,-.181),l(-.476,.186),l(-.392,.285),l(.107,.296),l(.187,.182),l(.103,.211),l(-.095,.24),l(-.248,.058),l(-.469,-.251),l(-.341,-.111),l(-.736,-.165),l(-.533,-.251),
+N(60.074,72.607),l(-.099,.228),l(-.491,.472),l(-.395,.183),l(-.462,.062),L(58,73.461),l(-.961,-.362),l(-.153,-.197),l(.169,-.289),l(.54,-.274),l(.341,-.32),l(.716,.364),l(.3,.091),l(.465,-.26),l(.215,-.213),l(.064,-.366),l(.485,-.047),l(1.107,.135),l(.536,.334),l(.133,.213),l(-.756,.062),l(-.429,0),l(-.59,.184),l(-.11,.092),M(40.092,77.571),l(-.729,-.029),l(-.097,-.24),l(.011,-.3),l(.802,-.243),l(.326,-.211),l(.593,-.423),l(.448,-.137),l(.646,-.077),l(1.427,.253),l(.711,.24),l(-.079,.211),l(-.303,.046),l(-.754,-.074),l(-.496,.031),l(-1.077,.183),l(-.269,.226),l(-1.161,.543),M(38.426,77.979),l(-.515,-.209),l(-.139,-.285),l(.381,-.227),l(.674,.27),l(.093,.195),l(-.122,.15),l(-.372,.105),M(37.896,78.449),l(-.256,.084),l(-.558,.151),l(-1.109,-.058),l(-.387,.135),l(-.398,.434),l(-.31,.15),l(-.854,-.207),l(-.135,-.224),l(.497,-.359),l(.5,-.315),l(.955,-.166),l(.863,-.346),l(.39,.089),l(.461,.224),l(.341,.409),M(29.628,81.29),l(-.168,-.594),l(-.324,-.476),l(.839,-.136),l(.424,.088),l(.436,.238),l(-.244,.268),l(-.26,.06),l(-.073,.297),l(-.22,.09),l(-.412,.164),M(27.543,81.591),l(-.39,.031),l(-.741,.165),l(-.311,-.133),l(-.088,-.178),l(.104,-.119),l(.336,-.268),l(.294,-.09),l(.584,.222),l(.212,.371),M(54.394,157.986),l(-.559,-.356),l(-.044,-.884),l(-.243,-.677),l(.482,-.402),l(-.035,-.2),l(-.156,-.26),l(.052,-.149),l(.173,-.046),l(.354,.158),l(.652,.279),l(.593,.425),l(-.015,.275),l(.238,.046),l(.12,.287),l(.306,.149),l(-.062,.161),L(56,156.933),l(-.172,.204),l(-.766,.195),l(-.374,.23),l(-.295,.425),M(23.015,59.92),l(-1.613,-.646),l(-.75,-.205),l(-.792,-.062),l(-.9,.065),l(-.291,-.095),l(-.431,-.222),l(.179,-.287),l(.516,-.049),l(1.135,.221),l(.579,-.001),l(.543,-.081),l(.538,-.001),l(.828,.285),l(1.725,.362),l(.429,.237),l(.046,.111),l(-.569,-.03),l(-.646,.033),l(-.527,.365),M(99.855,70.993),l(.467,.929),l(-.071,.167),l(-.879,-.272),l(-.621,-.075),l(.067,.441),l(-.056,.228),l(-.935,-.607),L(97.03,71.41),l(.396,-.458),l(.263,-.153),l(.612,-.078),l(.784,.38),l(.771,-.108),M(100.975,73.606),l(.128,.272),l(-.086,.273),l(-.318,.483),l(-.559,-.815),l(-.597,-.909),l(-.04,-.228),l(.095,-.213),l(.407,.029),l(.568,.197),l(.402,.91),M(106.858,78.207),l(-1.872,-1.166),l(-.566,-.555),l(.01,-.467),l(-.559,-.843),l(.071,-.106),l(.456,.06),l(.274,.256),l(1.165,.48),l(.086,.196),l(-.059,.136),l(-.149,.226),l(.296,.436),l(.839,.374),l(.007,.974),M(140.191,127.819),l(-.043,-.094),l(-.198,-.36),l(-.049,-.067),l(-.032,.042),l(-.028,.05),l(-.04,-.092),l(.002,-.664),l(-.331,-.604),l(-.472,-.451),l(-.661,-.451),l(-.512,-.197),l(-.114,-.052),l(-.145,.034),l(.002,.092),l(-.088,.025),l(-.1,-.042),l(-.146,-.143),l(.076,-.076),l(-.073,-.202),l(-.228,-.252),l(-.283,-.025),l(-.312,.084),l(-.932,-.336),l(-.286,-.328),l(-.428,-.244),l(-.383,.042),l(-.932,-.16),l(-.721,.051),l(-.12,-.185),l(-.234,-.067),l(-.046,-.177),l(.094,-.117),l(-.157,-.504),l(.133,-.464),l(-.227,-.096),l(-.127,.008),l(-.249,-.134),l(0,-.101),l(.075,-.093),l(-.029,-.219),l(-.347,-.185),l(-.254,-.286),l(-.415,-.219),l(-.391,-.623),l(-.202,-.076),l(-.203,-.311),l(-.409,-.219),l(-.156,-.529),l(-.002,-.227),l(.178,.007),l(.147,-.164),l(.029,-.326),l(-.208,-.251),l(-.192,-.045),l(-.22,.037),l(-.303,-.126),l(-.535,-.514),l(.078,-.21),l(-.091,-.312),l(-.129,-.067),l(-.044,-.463),l(.058,-.152),l(.119,-.025),l(.099,.067),l(.073,.076),l(-.086,.101),l(.153,.202),l(.285,.126),l(.116,.118),l(.203,.017),l(-.385,-.564),l(-.183,-.144),l(-.021,-.236),l(-.184,-.109),l(-.051,-.344),l(-.13,.006),l(-.011,.144),l(.048,.446),l(-.093,.017),l(-.293,-.194),l(-.119,.042),l(-.516,-.404),l(-.136,-.363),l(-.377,-.514),l(-.531,-.379),l(-.624,-.583),l(-.123,-.142),l(.114,-.101),l(-.327,-.751),l(.161,-.43),l(-.254,-.479),l(-.22,-.355),l(-.738,-.782),l(-.104,-.299),l(.099,-.627),l(.252,-.628),l(.166,-.357),l(.059,-.856),l(-.215,-.785),l(-.692,-1.486),l(-.153,-.916),l(.096,-.287),l(.231,-.244),l(.402,-.201),l(.365,-.717),l(-.365,-.573),l(-.066,-.33),l(.424,-1.593),l(.153,-.575),l(.061,-.634),l(.091,-.778),l(.019,-.179),l(-.153,-.16),l(.08,-.231),l(-.103,-.167),l(.157,-.077),l(-.03,-.186),l(-.046,-.186),l(-.031,-.103),l(-.004,-.058),l(.322,.096),l(.209,-.019),l(.062,-.097),l(-.211,.006),l(-.614,-.122),l(.062,-.707),l(-.103,-.328),l(.017,-.277),l(.587,-.225),l(-.345,-.019),l(-.16,-.142),l(-.129,0),l(-.053,.045),l(.042,.116),l(-.12,.052),l(-.133,-.979),l(-.927,-1.463),l(-.017,-.465),l(.129,-.131),l(.544,.086),l(.632,.217),l(.785,.114),l(.641,.028),l(.546,-.044),l(.415,.086),l(.547,.318),l(.039,.435),l(-.42,.407),l(-.413,.347),l(.532,.146),l(.184,.188),l(.251,.169),l(.029,-.228),l(.161,-.232),l(.393,-.305),l(.21,-.581),l(.102,-.465),l(-.064,-.421),l(-.356,-.958),l(-.158,-.305),l(-.655,-.516),l(.194,.013),l(2.579,.001),l(1.335,.022),l(4.588,-.025),l(3.938,.008),l(2.87,-.001),l(1.687,.006),l(5.117,-.028),l(.74,.011),l(4.13,.021),l(1.089,-.035),l(3.821,.023),l(.875,-.005),l(3.617,-.004),l(4.84,.018),l(.601,-.003),l(2.935,.014),l(2.131,-.012),l(2.781,.029),l(2.915,-.016),l(2.105,.003),l(1.348,-.007),l(2.798,.029),l(2.687,-.029),l(.68,.003),l(-.387,-.588),l(-.131,-.347),l(.501,-.036),l(.896,.748),l(.279,.371),l(.468,.46),l(.833,.451),l(.518,-.076),l(1.425,.208),l(.02,.185),l(.271,-.012),l(.338,.48),l(.16,-.247),l(.502,.013),l(.241,.271),l(.469,.086),l(.064,.185),l(.506,.098),l(.573,-.141),l(.219,-.06),l(.412,-.191),l(.373,-.075),l(.028,.282),l(.197,.116),l(.855,-.083),l(.474,.041),l(.156,.115),l(.196,.144),l(.542,-.049),l(.707,.074),l(1.469,-.592),l(.805,-.189),l(.797,.227),l(.977,.386),l(3.975,1.576),l(2.15,1.061),l(.101,.429),l(.46,.465),l(.628,-.024),l(.178,.135),l(.184,.294),l(.916,.181),l(.307,.235),l(-.11,.318),l(.26,.33),l(2.529,1.05),l(.876,3.16),l(.054,.545),l(-.028,.746),l(-.377,.576),l(-.294,.544),l(-.264,.433),l(-.414,.294),l(-.707,.525),l(-.044,.218),l(.012,.33),l(.371,.427),l(.497,.169),l(.573,.068),l(.524,-.117),l(.925,-.506),l(.939,-.478),l(.88,-.262),l(.919,-.062),l(.944,-.163),l(1.464,-.452),l(.875,-.427),l(-.047,-.362),l(-.16,-.471),l(-.018,-.319),l(.162,-.375),l(.47,-.203),l(.93,-.091),l(1.123,.01),l(1.305,.138),l(1.156,-.197),l(.44,-.275),l(.163,-.512),l(.146,-.434),l(.545,-.164),l(1.754,-.814),l(.534,-.305),l(.968,-.523),l(1.76,-.009),l(2.508,.029),l(1.855,.004),l(1.093,.095),l(.174,-.375),l(.363,-.435),l(.402,-.06),l(1.161,.124),l(1.139,-1.45),l(1.139,-2.22),l(.514,-.626),l(.632,-.526),l(.273,.085),l(.505,.36),l(.381,.085),l(.41,-.176),l(.771,.025),l(.488,.288),l(.174,.274),l(.31,2.819),l(-.077,.229),l(.606,.231),l(.224,0),l(.042,.154),l(-.143,.069),l(.02,.256),l(-.192,.077),l(.16,.291),l(.188,-.153),l(.349,.495),l(-.268,.281),l(.299,-.04),l(.171,.093),l(-.511,.374),l(-.509,.093),l(-.297,-.12),l(-.013,.253),l(-.138,.067),l(-.077,-.107),l(-.231,-.08),l(-.277,.133),l(-.101,.28),l(-.171,-.013),l(-.15,.16),l(-.175,-.347),l(-.746,.28),l(-.204,-.093),l(.12,.413),l(-.666,-.213),l(.199,-.48),l(-.149,-.04),l(-.364,.52),l(-.332,.56),l(-.342,.333),l(-.324,-.227),l(-.249,.439),l(-.346,-.08),l(.122,-.307),l(-.325,.253),l(.165,.16),l(-.326,.293),l(-.318,-.133),l(.105,-.226),l(-.654,.253),l(.065,.359),l(-.264,.04),l(-.161,.373),l(-.352,.106),l(-.333,.679),l(-.404,.505),l(.173,.146),l(.068,.212),l(.168,.053),l(.083,-.08),l(.169,.013),l(-.122,.146),l(-.547,.106),l(.053,.093),l(-.392,.292),l(-.068,.159),l(.337,.027),l(.282,.093),l(.599,.704),l(.055,.398),l(.399,.106),l(.691,-.239),l(-.022,-.186),l(-.14,-.027),l(-.254,-.279),l(-.097,-.04),l(-.009,-.066),l(.196,0),l(.23,.133),l(.218,.358),l(.031,.425),l(-1.599,.292),l(-.032,-.385),l(-.124,-.066),l(-.109,.226),l(-.164,.04),l(-.03,.093),l(-.105,-.106),l(-.159,.266),l(-.164,.04),l(-.294,.04),l(-.045,-.332),l(.198,-.332),l(-.443,.119),l(-.154,-.146),l(-.082,.252),l(-.087,.664),l(-1.429,.132),l(-1.694,.159),l(-1.182,.345),l(-.787,.358),l(-.097,.212),l(-.32,.053),l(-.144,.172),l(-.032,-.04),l(.308,-.756),l(.024,-.106),l(-.071,.027),l(-.41,.994),l(-.079,-.08),l(-.406,.292),l(.218,.318),l(.553,.093),l(-.46,1.515),l(-.302,.429),l(-.259,-.092),l(.043,.251),l(-.062,.185),l(-.237,.145),l(-.462,.501),l(-.292,.304),l(-.167,.026),l(-.075,-.119),l(.177,-.31),l(-.113,-.178),l(-.43,.013),l(-.447,-.343),l(-.148,-.053),l(-.329,-.541),l(.315,-.257),l(.151,-.245),l(-.271,.119),l(-.362,.37),l(.489,.845),l(.033,.356),l(.387,.581),l(.28,.066),l(.104,.765),l(-.101,.238),l(-.151,.23),l(-.125,-.013),l(-.487,.666),l(-.396,.798),l(.034,.053),l(-.13,.132),l(-.107,-.125),l(-.374,.725),l(.026,.125),l(-.226,.04),l(-.137,-.263),l(.342,-.864),l(.195,-.29),l(.247,-.119),l(.061,-.237),l(-.093,-.059),l(-.374,.119),l(.226,-.383),l(-.218,.04),l(-.176,-.093),l(.012,-.191),l(.242,-.04),l(-.077,-.33),l(-.439,.296),l(-.241,-.204),l(-.157,.053),l(-.23,-.396),l(.355,-.171),l(.357,-.053),l(-.005,-.06),l(-.604,-.316),l(-.092,.165),l(-.072,0),l(.107,-.323),l(.089,-.02),l(.21,.159),l(.131,-.06),l(-.098,-.224),l(-.353,-.066),l(-.065,-.112),l(.096,-.112),l(.336,.02),l(.193,-.284),l(-.281,.046),l(-.158,-.059),l(.241,-.37),l(.652,-.152),l(-.328,-.06),l(.146,-.409),l(-.28,.093),l(-.096,.132),l(.11,.079),l(-.315,.191),l(-.035,-.224),l(-.093,.053),l(.051,.224),l(-.081,.086),l(-.051,-.158),l(-.097,-.066),l(-.103,.416),l(-.447,-.079),l(.402,.501),l(-.294,.666),l(.07,.237),l(.272,.488),l(-.055,.139),l(-.466,-.317),l(-.1,-.211),l(.026,.205),l(.174,.218),l(.421,.237),l(.132,.508),l(-.631,-.402),l(-.354,-.007),l(-.118,-.283),l(-.155,-.053),l(.066,.25),l(-.541,-.323),l(-.33,.04),l(.015,-.29),l(.427,-.323),l(-.428,.079),l(-.19,.468),l(.204,.231),l(.457,.046),l(.202,.25),l(.954,.297),l(-.047,.092),l(.554,.165),l(.158,.132),l(-.22,.468),l(-.227,.06),l(-1.042,-.804),l(.708,.811),l(.626,.171),l(-.248,.092),l(.323,.079),l(-.045,.079),l(.061,.06),l(-.034,.25),l(-.312,-.191),l(-.071,.073),l(.104,.211),l(-.216,.02),l(-.656,-.56),l(-.023,.026),l(.419,.475),l(.309,.158),l(.182,-.026),l(.191,.21),l(.018,.31),l(-.298,.059),l(-.492,-.534),l(-.474,-.198),l(-.199,.16),l(.046,.044),l(.44,.145),l(.488,.382),l(-.047,.237),l(.442,-.033),l(.031,-.119),l(.748,.119),l(.151,.382),l(.406,1.212),l(.448,.803),l(-.14,-.092),l(-.262,-.349),l(-.059,-.132),l(-.359,-1.172),l(-.147,-.277),l(-.056,.31),l(.135,0),l(.034,.198),l(-.292,-.066),l(.173,.283),l(.144,.099),l(.228,.58),l(-.144,-.053),l(-.211,-.382),l(.002,.224),l(-.52,-.303),l(-.06,.059),l(.266,.303),l(-.247,.119),l(-.526,-.204),l(.225,.204),l(-.375,.211),l(-.173,-.02),l(-.251,-.21),l(-.024,-.217),l(.083,-.158),l(-.081,-.053),l(-.091,.204),l(.044,.23),l(.116,.211),l(-.107,.158),l(.894,.02),l(.571,-.145),l(.125,.165),l(-.113,.191),l(-.072,.369),l(.14,.066),l(.092,-.257),l(.135,-.369),l(.18,-.105),l(.266,.31),l(.047,.296),l(-.166,.25),l(-.163,-.013),l(-.063,-.099),l(-.316,.474),l(-.254,.197),l(-.483,-.053),l(-.203,-.065),l(-.147,-.066),l(-.136,-.245),l(-.151,.014),l(.141,.244),l(-.075,.013),l(-.538,-.125),l(-.436,-.151),l(.162,.185),l(.269,.026),l(.833,.335),l(-.034,.119),l(-.396,.145),l(.247,.007),l(-.19,.25),l(-.281,.138),l(-.149,0),l(-.481,-.375),l(.242,.395),l(.43,.164),l(.302,-.171),l(.292,.026),l(.11,-.204),l(.04,.178),l(.217,.04),l(.048,.079),l(-.428,.322),l(-.013,.085),l(-.261,.072),l(-1.498,.214),l(-.865,.895),l(-.487,.609),l(-.13,.127),l(-.935,.143),l(-.528,.128),l(-.617,.241),l(-.678,.539),l(-.225,.424),l(-.096,.354),l(-.819,.694),l(-.693,.383),l(-.429,.199),l(-.797,.086),l(-.35,.58),l(-.177,.198),l(-.809,1.125),l(-.273,.781),l(-.459,1.249),l(.236,1.455),l(.387,.925),l(.456,.873),l(.934,1.562),l(.352,1.746),l(.486,1.194),l(-.075,.092),l(.287,.276),l(.123,.333),l(.062,.827),l(-.301,1.536),l(-.064,.278),l(-.31,.415),l(.108,.424),l(-.02,.252),l(-.393,.551),l(-.017,-.092),l(.129,-.241),l(-.025,-.138),l(-.256,.035),l(-.38,.137),l(-.291,-.126),l(-.509,.138),l(-.12,-.329),l(.014,-.233),l(-.567,-1.068),l(-.764,-.138),l(-.204,-.352),l(-.113,-.819),l(-.423,-.229),l(-.144,-.702),l(-.373,.093),l(-.608,-1.08),l(-.375,-.482),l(.296,0),l(.375,-.438),l(.048,-.226),l(-.167,-.226),l(-.471,.407),l(-.277,-.208),l(.126,-.573),l(.147,-.758),l(.158,-1.043),l(-.293,-.452),l(-.258,-.169),l(-.496,-.126),l(-.832,-.987),l(-.875,-.804),l(-.528,-.168),l(-.43,.072),l(-.536,.298),l(-.456,.354),l(-1.202,.299),l(-.273,-.213),l(-.131,-.62),l(-.253,-.254),l(-.264,-.113),l(-.752,-.069),l(-.516,-.296),l(-.22,-.233),l(-.504,.138),l(-1.052,.115),l(-.653,-.184),l(-.047,.298),l(-.64,.099),l(-.183,0),l(-.578,-.926),l(-.238,.781),l(-.447,-.135),l(-.65,.001),l(-1.328,-.04),l(-.672,.439),l(-.39,.055),l(-1,-.459),l(-.096,.009),l(-.142,.014),l(-.362,.528),l(.201,.229),l(.303,0),l(.211,0),l(.537,-.207),l(.406,.092),l(.676,.482),l(-.68,.373),l(.02,.254),l(.263,.353),l(.593,.146),l(.229,.217),l(.35,.334),l(-.533,.136),l(-.503,-.084),l(-.276,-.419),l(-.79,-.271),l(-.224,-.211),l(-.265,-.056),l(-.013,.02),l(-.209,.32),l(.209,.154),l(.248,.183),l(-.248,.179),l(-.069,.05),l(-.447,-.459),l(-.476,.192),l(-.287,.291),l(-1.025,-.472),l(-.419,-.494),l(-1.16,-.642),l(-.615,.066),l(.554,.393),l(-.307,.187),l(-1.17,-.083),l(-.886,-.252),l(-.896,-.168),l(-1.547,.173),l(-.632,.328),l(-.392,-.015),l(-.433,-.031),l(-.135,-.49),l(-.333,.057),l(-.112,.184),l(.474,.731),l(-.877,.64),l(-.808,.577),l(-.915,.317),l(-.419,.043),l(-.414,-.056),l(-.728,-.111),l(-.126,.198),l(.437,.437),l(-.239,.396),l(-.327,.199),l(-.631,.114),l(-.737,.27),l(-.268,.17),l(.558,.352),l(.111,.169),l(-.659,.694),l(-.154,.297),l(-.012,.848),l(.144,.636),l(.271,.762),l(.425,.903),l(-.347,-.119),l(-.816,-.377),l(-.296,.001),l(-.416,.116),l(-.264,-.069),l(-1.029,-.56),l(-.921,-.32),l(-.375,-.365),l(-.336,-.592),l(-.332,-.932),l(-.078,-.467),l(-.268,-.253),l(-.657,-.576),l(-.845,-1.042),l(-.744,-1.227),l(-.663,-1.029),l(-.363,-.366),l(-.412,-.252),l(-.783,-.321),l(-.475,-.082),l(-.643,.018),l(-.468,.201),l(-.576,.541),l(-.418,.413),l(-.283,.37),l(-.416,.158),l(-.501,-.011),l(-.337,-.069),l(-1.104,-.503),l(-1.092,-.659),l(-.445,-.549),l(-.318,-.847),l(-.284,-.678),l(-.179,-.226),l(-.708,-.491),l(-.837,-.519),l(-.766,-.632),l(-.631,-.662),l(-.209,-.112),l(-1.892,-.046),l(-1.858,-.003),l(-.096,.892),l(-.213,.101),l(-1.867,.011),l(-.966,-.037),l(-1.544,-.02),l(-1.662,-.019),l(-.338,-.055),l(-3.516,-1.112),l(-2.811,-.933),l(-1.186,-.39),l(-.267,-.154),l(-.316,-.31),l(-2.381,.084),l(-2.367,.155),l(-.34,.017),M(49.818,152.776),l(-.122,.086),l(-.279,.03),l(-.111,-.131),l(-.177,-.005),l(-.324,.051),l(-.304,-.39),l(-.071,-.263),l(.339,-.01),l(.299,-.253),l(.188,.218),l(.106,.294),l(.223,.096),l(.233,.279),M(52.785,154.312),l(-.155,-.081),l(-.085,-.356),l(-.461,-.321),l(.095,-.229),l(.143,-.058),l(.366,.209),l(.344,.055),l(.616,.356),l(-.005,.172),l(-.294,.184),l(-.563,.069),M(111.683,77.224),l(-.138,.415),l(-.45,.067),l(-.324,.113),l(-.295,.247),l(-.321,-.137),l(-.185,-.21),l(.087,-.443),l(.086,-.443),l(-.438,-.675),l(-.463,-.319),l(-.199,-.271),l(-1.281,.055),l(-.437,.098),l(-.153,.161),l(-.496,.097),l(-.019,-.193),l(-.034,-.432),l(.212,-.272),l(.184,-.212),l(-.378,-.347),l(-.641,-.438),l(-.693,-.696),l(-.723,-.317),l(-.453,-.136),l(.132,-.35),l(-.569,-.592),l(-.099,-.213),l(.371,-.229),l(-.068,-.122),l(-.301,-.152),l(-.445,-.076),l(-.392,-.274),l(-.237,-.259),l(-.57,-.305),l(-1,-.411),l(-.479,-.765),l(-.217,-.583),l(-.367,-.399),l(-.357,.016),l(-.101,.814),l(.42,.873),l(.104,.306),l(-.047,.153),l(-.701,-.136),l(-.272,-.076),l(-.511,-.504),l(-.4,-.459),l(-.537,.139),l(-1.219,-.228),l(1.263,.718),l(.032,.214),l(-1.62,.171),l(-1.093,-.35),l(-1.388,-.948),l(-.543,-.292),l(-.664,-.043),l(-.079,0),l(-.933,-.213),l(-1.3,-.536),l(.928,-.248),l(.135,-.169),L(90.8,67.129),l(-.384,-.153),l(-.792,.156),l(-.454,.14),l(-.656,.017),l(-1.058,-.06),l(-1.068,-.245),l(.027,-.247),l(-.148,-.186),l(-.325,-.108),l(-.359,.016),l(-.47,.202),l(-1.036,.049),l(-1.465,-.122),L(80.46,66.64),l(-.786,-.091),l(-.248,-.108),l(-.651,-.387),l(-.427,-.527),l(-.301,.218),l(-.788,.157),l(-.89,-.293),l(-.234,-.326),l(-.417,-.139),l(-.872,-.248),l(-1.538,-.23),l(-.817,-.248),l(-.671,-.342),l(-.553,.235),l(-.675,.079),l(.06,.437),l(-.193,.062),l(-.389,.25),l(-.249,.405),l(1.119,.293),l(.174,.294),l(-.096,.388),l(-.428,.449),l(-.458,.001),l(-.804,-.214),l(-.586,-.061),l(-.568,.094),l(-.978,.603),l(-1.066,.217),l(-.936,.448),l(-1.035,.448),l(-1.095,.109),l(.178,-.308),l(.063,-.123),l(.72,-.401),l(-.093,-.385),l(-.655,-.523),l(.004,-.108),L(64.1,66.19),l(.411,-.482),l(.157,-.42),l(.736,-.312),l(.87,-.235),l(1.165,-.018),l(1.085,.123),l(.239,-.156),l(-1.239,-.466),l(-.971,-.389),l(-1.043,.049),l(-.226,.219),l(-.449,.095),l(-.573,.438),l(-.865,.375),l(-1.019,.282),L(61.553,65.9),l(-.406,.094),l(-.298,.14),l(.131,.325),l(-.177,.526),l(-.563,.34),l(-.564,.078),L(59,67.544),l(-.592,.278),l(-.681,.601),l(-.035,.292),l(.38,.168),l(.36,.03),l(.667,.106),l(.465,.229),l(-.075,.184),l(-.43,.338),l(-.625,.2),l(-.557,.277),l(-.423,.398),l(-.544,.383),l(-.675,.093),l(-1.434,.308),l(-.678,.397),l(-1.036,.337),l(-.7,.367),l(.52,.5),l(-.1,.167),l(-1.106,.412),l(-.897,.153),l(-.778,.168),L(49.51,74.19),l(-1.214,.456),L(48.1,74.828),l(-.274,.394),l(-.753,.439),l(-1.193,.229),l(-1.234,.184),l(-.973,-.345),l(.001,-.181),l(.332,-.348),l(.763,-.273),l(.306,-.212),l(.445,-.364),l(1.171,-.441),l(1.403,.073),l(-.12,-.212),l(.02,-.516),l(.47,-.304),l(.725,-.291),l(.754,-.366),l(.266,-.214),l(.002,-.731),l(.246,-.749),l(.693,-.49),l(.194,-.398),l(.034,-.412),l(-.633,.122),l(-1.251,.186),l(-.676,-.029),l(-.5,-.597),l(-.266,.062),l(-.613,.216),l(-.136,.23),l(.239,.352),l(.021,.352),l(-.169,.046),L(47,70.115),l(-.567,-.32),l(-.487,-.397),l(-.509,-.291),l(-.56,-.03),l(-.812,-.106),l(-.91,.094),l(.028,.138),l(-.644,.338),l(-1.175,.14),l(-.649,-.09),l(-.064,-.123),l(-.082,-.107),l(-.125,-1.028),l(.3,-.508),l(-.142,-.431),l(-.864,-1.002),l(-1.43,.437),l(-.738,.078),l(-.406,.202),l(-1.091,.094),l(-.4,-.23),l(-.394,-.355),l(-.466,-.325),l(-1.007,-.463),l(-.179,-.28),l(.292,-.171),l(.337,-.437),l(.704,.139),l(1.312,.309),l(.69,.03),l(.238,-.234),l(-.375,-.482),l(-.458,-.264),l(-.363,0),l(-.541,.22),l(-.528,-.015),l(-1.342,-.513),l(-.623,-.186),l(-.197,.016),l(-.858,-.029),l(-.024,-.078),l(-.623,-.985),l(.79,-.19),l(.071,-.456),l(.495,-.221),l(.102,-.299),l(.227,-.347),l(.893,-.491),l(.337,-.38),l(.386,-.301),l(.527,-.476),l(.39,-.175),l(.719,.109),l(.98,.268),l(.485,.094),l(.752,-.144),l(.427,-.254),l(.675,-.429),l(1.252,-.257),l(.774,-.033),l(.955,-.049),l(.354,-.175),l(.187,-.478),l(-.259,-.669),l(-.814,-.686),l(.026,-.096),l(.927,-.034),l(.343,-.256),l(-.25,-.384),l(-.497,-.256),l(-.367,-.08),l(-1.88,.389),L(39.33,56.53),l(-.534,.289),l(-.496,.065),l(-1.907,-.333),l(-.848,-.031),L(34.8,56.49),l(-1.27,.162),l(-1.265,-.029),l(-1.349,-.174),l(-.53,-.207),l(-.183,-.788),l(.144,-.146),l(.636,-.033),l(1.008,-.002),l(.446,-.179),l(-1.057,-.241),l(-1.912,-.304),L(28.13,54.31),l(-1.285,-.208),l(.219,-.114),l(.781,-.262),l(1.568,-.214),l(1.325,-.328),l(.958,-.214),l(1.058,-.361),l(.953,-.23),l(1.399,-.281),l(1.513,.128),l(-.158,.523),l(.023,.277),l(1.051,.161),l(1.359,.095),l(1.074,-.019),l(.657,-.099),l(.784,-.246),l(.55,-.295),l(.262,-.083),l(.752,.064),l(.751,.113),l(1.021,-.051),l(.2,-.327),l(.007,-.18),l(-.689,-.064),l(-1.946,-.292),l(-1.283,-.047),l(-.312,-.755),l(-1.473,-.162),l(-.96,-.031),l(-1.573,-.096),l(-.194,-.511),l(-.484,-.312),l(-1.042,-.461),l(-.512,-.148),l(-2.66,-.659),l(-2.008,-.545),l(.317,-.167),l(.812,-.402),l(.086,-.485),l(2.136,-.054),l(.99,-.069),l(1.829,-.288),l(.784,-.354),l(.452,-.623),l(.788,-.575),l(.616,-.525),l(.818,-.41),l(.742,-.224),l(1.066,-.104),l(1.133,-.241),l(1.047,-.036),l(1.804,.065),l(.146,-.188),l(-.156,-.205),L(44.47,42.83),l(.018,-.206),l(1.936,-.089),l(1.143,.032),l(.974,-.054),l(1.344,-.14),l(1.098,-.416),l(.918,-.417),l(.957,-.019),l(.282,.051),l(.675,.241),l(.156,.172),l(-.383,.139),l(.017,.344),l(1.049,.136),l(.424,.034),l(.536,-.293),l(.297,-.208),l(1.419,.187),l(1.534,.049),l(1.062,.049),l(.715,.033),l(.711,.257),l(.359,.274),l(.783,.358),l(.494,.085),l(.421,-.086),l(1.292,.117),l(1.124,.015),l(1.556,-.054),l(1.449,-.088),l(1.213,.1),l(1.377,.254),l(.883,.118),l(3.424,.13),l(1.279,.168),l(.743,.169),l(2.027,-.038),l(2.339,-.141),l(1.123,.236),l(2.441,.791),l(1.206,.301),l(.227,.008),l(.102,.483),l(-.003,2.855),l(.039,2.259),l(.052,2.335),l(.129,2.796),l(-.026,2.183),l(-.043,4.334),l(.026,2.167),l(.089,1.046),l(.196,.279),l(.84,.074),l(2.424,-.122),l(.739,.059),l(.332,.388),l(.173,.387),l(.348,.292),l(2.162,1.318),l(.945,.673),l(.238,-.325),l(.848,-.205),l(1.225,-.67),l(.731,-.498),l(.495,-.126),l(.832,.073),l(.316,.199),l(.371,.492),l(.35,.322),l(2.048,1.175),l(.814,.58),l(1.769,1.768),l(1.67,1.882),l(.512,.393),l(.189,.029),l(.98,.314),l(2.025,.763),l(.402,.255),l(-.163,.788),l(.393,.777),
+N(643.755,159.873),l(-1.092,-.52),l(-.637,-.337),l(-.203,-1.284),l(.036,-.282),l(.24,-.241),l(.42,-.241),l(.721,-.623),l(.493,.056),l(.049,-.17),l(.24,-.396),l(.239,.028),l(.573,.225),l(.321,-.312),l(.439,-.001),l(.798,-.171),l(.596,.69),l(-.163,.17),l(-.443,.354),l(-.412,.538),l(-.285,.734),l(.14,.296),l(-.22,.311),l(-.292,.085),l(-1.026,.383),l(-.532,.707),M(627.173,150.012),l(-.679,.314),l(-.24,.241),l(-.043,.325),l(.138,.592),l(.228,.366),l(.119,.521),l(-.109,.339),l(-.266,.213),l(-.769,-.08),l(-.321,-.21),l(-.178,-.196),l(-.153,-.239),l(-.111,-.38),l(-.628,.413),l(-.647,.159),l(-.246,-.083),l(-.378,-.266),l(-.341,-.746),l(-.291,-.379),l(-.481,.045),l(-.507,.003),l(-.228,-.098),l(-.117,-.352),l(.729,-1.584),l(-.033,-.268),l(-.521,-.096),l(-.554,.074),l(-.202,-.324),l(-.277,-1.762),l(-.156,-.126),l(-.479,.017),l(-.771,.089),l(-.819,.442),l(-.312,.086),l(-.216,-.069),l(0,-.268),l(.224,-.58),l(-.163,-.705),l(-.075,-.465),l(.617,-.85),l(.191,-.198),l(.487,-.271),l(.611,-.525),l(.429,-.722),l(.353,-.862),l(-.02,-.875),l(-.195,-1.649),l(-.146,-.14),l(-.504,.031),l(-.287,-.041),l(-.217,-.309),l(-.243,-.901),l(-.397,-.435),l(-.504,-.279),l(-.277,.044),l(-.306,.34),l(-.001,.127),l(-.624,-.081),l(-.73,-.179),l(-.657,-.081),l(-.3,-.055),l(-.102,-.056),l(.138,-.269),l(.354,-.454),l(-.046,-.38),l(-.716,-.715),l(-.455,-.392),l(-1.377,.84),l(-.377,.044),l(-.975,-.319),l(-.286,-.167),l(-.355,.087),l(-.546,.299),l(-1.105,.726),l(-.829,.258),l(-.543,.37),l(-1.123,1.107),l(-.397,.27),l(-.714,.216),l(-.784,.033),l(-.189,.1),l(-.329,-.619),l(-.312,-.209),l(-.371,-.041),l(-1.659,-.047),L(601,137.538),l(-.309,-.294),l(-.417,.016),l(-.149,.103),l(-.348,.239),l(-.609,.539),l(-1.251,1.545),l(-.212,-.662),l(.052,-.861),l(-.139,-.183),l(-.231,-.069),l(-.471,.102),l(-.345,.129),l(-.655,-.159),l(-.339,.281),l(-.341,-.116),l(-.849,.066),l(-.319,-.364),l(-.63,-.281),l(-.407,0),l(-.08,.331),l(-.271,.083),l(-.685,-.38),l(.01,.364),l(-.237,.099),l(-.141,-.463),l(-.54,-.496),l(-.365,.066),l(-.935,-.066),l(-.014,-.265),l(.175,-.396),l(-.326,-.017),l(-.333,.248),l(-1.451,-.893),l(.069,-.281),l(-.178,-.38),l(-.289,-.166),l(-.71,.116),l(-.158,.166),l(-.657,-.794),l(-.454,-.281),l(-.15,.132),l(-.472,-.215),l(-.726,-.595),l(-.867,-.264),l(-.132,-.612),l(-1.079,-.199),l(-.186,.182),l(-.275,-.066),l(-.134,.513),l(-.276,.314),l(-.299,-.05),l(-.24,-.43),l(-.859,-.596),l(-.154,.066),l(-.756,-.248),l(.116,-.364),l(-1.078,-.579),l(-.363,.116),l(-.772,-.843),l(-.383,-.248),l(-.477,.314),l(-.198,-.066),l(-.099,-.43),l(.215,-.215),l(-.272,-.364),l(.104,-.446),l(-.579,-.595),l(-.157,-.694),l(.785,-.198),l(.033,.364),l(.337,.264),l(.368,-.049),l(.376,-.281),l(.578,-.364),l(-.367,-.694),l(.104,-.414),l(-.68,-.099),l(-.044,-.182),l(-.092,-.078),l(-.718,-.096),l(-.294,-.221),l(-.037,-.552),l(-.073,-.589),l(.184,-.184),l(.331,-.221),l(-.221,-.258),l(-.441,-.405),l(-.81,-.11),l(-.221,-.515),l(-.441,-1.03),l(0,-.515),l(-.502,.152),l(-.147,-.126),l(-.305,-.111),l(-1.337,-.104),l(-.565,-.436),l(-.178,-.09),l(-.104,-.199),l(-.239,0),l(-.52,.196),l(-.252,-.281),l(-.198,-.218),l(-.301,-.07),l(.312,-.516),l(-.007,-.501),l(-.213,-.247),l(-.373,-.323),l(-.625,.009),l(-.282,.128),l(-.004,-.456),l(-.554,-.117),l(-.296,-.047),l(-.281,.21),l(-.105,-.112),l(-.313,-.14),l(-.048,-.088),l(-.236,-.012),l(-.01,-.269),l(.574,.059),l(.192,-.145),l(.354,-.136),l(.08,-.249),l(.181,-.185),l(-.2,-.163),l(.152,-.36),l(-.245,-.237),l(.126,-.428),l(-.049,-.123),l(-.152,-.012),l(-.028,-.246),l(.009,-.284),l(-.295,-.494),l(-.273,-.154),l(-.692,-.039),l(-.22,-.06),l(-.229,.162),l(-.463,.045),l(-.325,-.394),l(-.077,-.305),l(.207,-.223),l(-.023,-1.031),l(.011,-.069),l(.139,-.739),l(.129,-.213),l(.274,-.186),l(1.422,-.704),l(1.737,-.734),l(.359,-.03),l(.06,.071),l(.183,.567),l(.344,.055),l(.507,-.145),l(.885,-.132),l(.268,-.243),l(.463,-.784),l(.467,-.472),l(.238,-.03),l(1.248,.235),l(.459,-.017),l(.478,-.102),l(.646,-.345),l(.638,-.701),l(.405,-.301),l(.445,-.145),l(1.338,-.349),l(.97,-.219),l(.325,-.187),l(.051,-.157),l(-.031,-.194),l(-.139,-.86),l(.02,-.399),l(.32,-.401),l(.705,-.546),l(.222,-.33),l(-.119,-.47),l(-.29,-.441),l(-.345,-.627),l(-.03,-1.357),l(-.483,-.141),l(-.366,.06),l(-.232,-.185),l(.068,-.215),l(.215,-.302),l(.393,-.188),l(1.799,-.254),l(1.082,-.207),l(.35,-.06),l(.5,.184),l(1.133,.238),l(.394,-.074),l(.231,-.145),l(.156,-.245),l(-.126,-.286),l(-.622,-.514),l(.137,-.418),l(.286,-.605),l(.438,-.794),l(.516,-1.141),l(.427,-.507),l(1.096,.254),l(.721,.141),l(.594,.141),l(1.402,.079),l(.718,-.062),l(.417,-.103),l(.444,-.392),l(.157,-.39),l(-.213,-.707),l(-.097,-.75),l(.34,-.581),l(.428,-.277),l(1.199,-.093),l(.289,-.06),l(.306,-.219),l(.035,-.478),l(.011,-.275),l(.279,-.262),l(.542,-.148),l(.551,-.034),l(.228,-.014),l(.569,-.003),l(.244,-.074),l(.062,.145),l(.131,.405),l(.24,.563),l(.371,.433),l(1.301,.745),l(.834,.415),l(.614,.069),l(.731,.167),l(.633,.144),l(.354,.143),l(.568,.618),l(1.07,1.451),l(.401,.66),l(-.215,.447),l(-.237,.75),l(-.214,.389),l(-.369,.347),l(-.035,.129),l(.105,.43),l(.233,.229),l(.724,.312),l(1.062,.181),l(1.505,.021),l(.995,.038),l(.668,.083),l(.998,.224),l(.632,.268),l(1.645,.806),l(.839,.31),l(.744,.096),l(.105,.542),l(1.571,2.161),l(.467,.439),l(.444,.254),l(1.979,.018),l(1.241,.207),l(.802,.109),l(1.165,.022),l(2.861,-.059),l(.937,.023),l(1.164,.022),l(1.69,.119),l(.521,.168),l(.815,.551),l(1.006,.365),l(1.599,.433),l(.929,.123),l(.663,-.061),l(.61,.067),l(.253,.297),l(.433,.197),l(.481,-.017),l(.686,-.289),l(1.44,-.534),l(.303,-.101),l(.736,-.274),l(.816,-.289),l(1.204,-.349),l(1.339,-.007),l(1.514,-.065),l(.987,.08),l(.651,-.061),l(1.941,-.737),l(.265,-.172),l(1.111,-1.046),l(.67,-.389),l(1.265,-.292),l(.326,-.259),l(.123,-.271),l(-.188,-.228),l(-.599,-.411),l(-.389,-.569),l(-.003,-.343),l(.214,-.401),l(.539,-.589),l(.457,-.231),l(.316,-.073),l(.718,.154),l(.668,.382),l(.592,.125),l(.982,-.005),l(.744,-.047),l(.742,-.433),l(1.192,-.91),l(.224,.013),l(.438,.012),l(.624,.054),l(.896,-.134),l(.638,-.248),l(.347,-.188),l(.241,-.216),l(.312,-.82),l(.363,-.333),l(.47,-.204),l(.464,-.045),l(.483,.127),l(.353,-.189),l(.831,-.278),l(.539,-.146),l(.937,-.221),l(.854,-.033),l(.432,.099),l(1.074,.008),l(.464,.127),l(.414,-.218),l(.107,-.217),l(-.048,-.273),l(-.599,-.501),l(-.879,-.99),l(-.797,-.5),l(-.538,-.199),l(-.928,-.212),l(-.438,.002),l(-1.191,.786),l(-.292,-.07),l(-.431,-.416),l(-.317,-.085),l(-.576,.018),l(-.754,.062),l(-.929,.395),l(-.342,.045),l(-.051,-.029),l(-.269,-.836),l(.381,-.58),l(1.224,-1.959),l(.687,-1.207),l(.295,-.31),l(.046,.018),l(.452,.172),l(1.126,.574),l(.343,-.016),l(.438,-.089),l(2.44,-.752),l(.779,-.339),l(.123,-.233),l(-.056,-.306),l(-.35,-.348),l(-.062,-.146),l(.103,-.249),l(.422,-.426),l(.416,-.543),l(.667,-.779),l(.599,-.545),l(1.371,-.608),l(.167,-.794),l(-.107,-.249),l(-.465,-.306),l(-.558,-.026),l(-.822,.078),l(.119,-.25),l(.375,-.282),l(1.193,-.787),l(.478,-.165),l(.602,-.136),l(1.854,-.143),l(.836,-.123),l(1.203,-.109),l(.917,-.049),l(1.148,.215),l(1.037,.481),l(.683,.188),l(1.386,-.125),l(.539,.026),l(.763,.467),l(.742,.952),l(1.087,2.384),l(.94,1.588),l(.927,1.903),l(.436,.389),l(.507,.2),l(1.247,.341),l(1.523,.253),l(2.659,.839),l(.205,.144),l(.297,.866),l(.44,1.283),l(.261,.446),l(.68,-.033),l(.649,-.018),l(1.657,-.052),l(.604,-.22),l(.953,-.308),l(1.357,-.31),l(1.181,-.208),l(.902,-.034),l(.246,.114),l(.064,.259),l(.116,.389),l(.017,.504),l(-.566,.407),l(-.66,.393),l(-.291,.707),l(-.278,.893),l(-.538,1.066),l(-.627,1.08),l(-.329,.432),l(-.551,.69),l(-.47,.347),l(-.547,-.098),l(-.679,-.225),l(-.685,-.24),l(-.396,-.041),l(-1.664,.982),l(-.048,.557),l(.332,.897),l(.062,.656),l(-.006,.613),l(-.025,.385),l(-.097,.128),l(.112,.299),l(-.156,.329),l(-.511,.43),l(-1.252,.462),l(-.111,.058),l(-.579,-.68),l(-.247,.001),l(-.253,.129),l(-.383,.358),l(-.23,.713),l(-.955,.532),l(-.62,.259),l(-.538,.017),l(-.452,-.054),l(-.333,-.126),l(-.392,.059),l(-.273,.243),l(-.025,.342),l(.508,.765),l(.046,.113),l(-.527,.159),l(-.975,.048),l(-.508,-.153),l(-.493,-.253),l(-.273,-.396),l(-.448,.017),l(-.386,.13),l(-.686,1.027),l(-.636,.543),l(-1.032,.545),l(-1.533,.604),l(-.52,.329),l(-.415,.442),l(-.379,.528),l(-.066,-.092),l(-.417,.171),l(-1.222,.13),l(-.728,.171),l(-2.248,.925),l(-.632,.37),l(-.566,.469),l(-.604,.271),l(-.336,.015),l(.13,-.255),l(.862,-.682),l(.33,-.354),l(-.47,-.113),l(-.37,.072),l(-.153,-.297),l(.058,-.156),l(.953,-.781),l(.269,-.384),l(.55,-.413),l(.159,-.2),l(-.057,-.298),l(-.73,-.553),l(-.727,-.283),l(-.131,-.014),l(-.628,.03),l(-.166,.015),l(-.494,.371),l(-1.146,1.183),l(-.355,.157),l(-.643,.086),l(-.613,.243),l(-.36,.199),L(665.49,112),l(-.136,.411),l(-.131,.255),l(-.251,.255),l(-.437,.128),l(-.493,-.013),l(-.326,.27),l(-.307,.114),l(-.455,-.565),l(-.355,-.014),l(-.349,.128),l(-.396,.638),l(-.301,.694),l(.088,.34),l(.245,.368),l(.558,.268),l(.8,.268),l(1.21,-.045),l(.29,.254),l(-.019,.538),l(-.123,.581),l(.057,.538),l(.261,.283),l(.733,.069),l(.698,-.157),l(.76,-.525),l(.509,-.497),l(.552,-.228),l(.534,-.128),l(.287,.07),l(.895,.621),l(.543,.197),l(1.023,-.087),l(.361,.027),l(.471,.141),l(.274,0),l(-.248,.708),l(-.057,.552),l(-.612,-.197),l(-.297,-.084),l(-.525,.058),l(-1.677,.555),l(-.707,.44),l(-.072,.735),l(-.522,.157),l(-.146,-.113),l(-.017,-.269),l(-.127,-.084),l(-.501,.114),l(.138,.466),l(-.152,.368),l(-.485,.496),l(-1.397,1.119),l(-.126,.226),l(.039,.55),l(.62,.225),l(.712,.492),l(.785,.521),l(.391,.535),l(.424,1.241),l(.668,.647),l(.175,.437),l(-.13,.677),l(.172,.183),l(.694,.295),l(.399,.592),l(.562,.253),l(.272,.268),l(.087,.31),l(-.049,.155),l(-.789,.369),l(.088,.07),l(.425,.31),l(.314,.79),l(-.019,.296),l(-.141,.184),l(-.534,.043),l(-.651,.213),l(-.948,.552),l(-.849,.213),l(-.629,.297),l(.72,.21),l(.378,.056),l(.944,-.425),l(.488,-.058),l(.162,.056),l(.524,.592),l(.387,.168),l(.456,.027),l(.009,.155),l(-.231,.311),l(-.382,.227),l(-.304,.241),l(.11,.155),l(.326,-.029),l(.202,.084),l(-.184,.325),l(-.298,.749),l(-.192,.649),l(.028,.353),l(-.22,.452),l(-.209,.127),l(-.35,-.338),l(-.146,.142),l(-.569,.763),l(-.401,.622),l(-.215,.622),l(-.127,.296),l(-.595,.425),l(-.251,.438),l(-.254,.184),l(-.569,.029),l(-.382,.227),l(.279,.719),l(-.264,.508),l(.076,.593),l(-.093,.269),l(-.207,.269),l(-.532,.199),l(-.161,.282),l(-.174,.396),l(-.294,.636),l(-.626,.354),l(-.412,.495),l(-.492,-.14),l(-.443,-.069),l(-.142,.113),l(-.145,.198),l(.118,.833),l(-.213,.142),l(-.772,.651),l(-.356,.127),l(-.628,.171),l(-.563,.467),l(-.571,.213),l(-.107,.113),l(-.008,.48),l(-.133,.156),l(-.568,.058),l(-.5,.114),l(-.341,.438),l(-.364,-.126),l(-.52,-.168),l(-.274,.057),l(-.315,.326),l(-.435,.198),l(-.643,.1),l(-.047,-.465),l(-.52,.057),l(-.699,.213),l(-.32,.198),l(-.285,-.042),l(-.401,-.493),l(-.163,-.155),l(-.191,.283),l(.095,.169),l(-.045,.212),l(-.047,.691),l(-.209,.297),l(-.416,.114),l(-.501,-.182),l(-.123,.282),l(-.001,.24),l(-.146,.155),l(-.615,.058),l(-.366,.114),l(-.596,.043),l(-.463,-.211),l(-.217,.1),l(-.439,.48),l(-.227,.071),l(-.774,-.041),l(-.747,.227),l(-.406,.326),l(-.451,-.027),l(-.277,-.084),l(-.011,.057),l(-.069,.353),l(-.29,.396),l(.011,.113),l(.48,.634),l(.269,.126),l(.043,.198),l(-.36,.269),l(-.763,.157),l(-.481,-.719),l(-.241,-.691),l(.012,-.395),l(.396,-.777),l(-.015,-.169),l(-.587,-.253),l(-.226,.071),l(-.206,.297),l(-.454,.072),l(-.676,-.21),l(-.574,-.733),l(-.196,.085),l(-.017,.169),l(-.159,.396),l(-.27,.128),l(-.332,-.056),l(-.481,.043),l(-.055,.038),l(-.197,-.143),l(-.909,-.107),l(-.621,-.166),l(-.943,-.615),l(-.273,-.365),l(-.096,-.521),l(.472,-.75),l(-.056,-.38),l(-.237,-.21),l(-.777,.047),l(-.66,-.053),l(-.771,-.235),l(-.623,-.575),l(-.298,.101),l(-.521,.328),l(-.696,.554),l(-.341,.157),l(-.807,.117),l(-1.595,.052),l(-.332,.115),l(-.584,.413),l(-.325,-.097),l(-.597,-.392),l(-.341,-.012),l(-.515,.13),l(-.483,.229),
+N(241.073,156.152),l(.017,.52),l(.098,1.215),l(.012,.212),l(-.379,.455),l(-.011,.17),l(.485,1.358),l(-.669,-.577),l(-.445,-.056),l(-.761,.143),l(-.877,-.012),l(-.666,-.14),l(-.574,-.056),l(-.474,.1),l(-.378,.354),l(-.135,-.042),l(-.993,-.549),l(-.171,-.325),l(.04,-.198),l(.269,-.184),l(1.051,.097),l(.631,.111),l(1.125,.167),l(.654,.041),l(.61,-.185),l(.386,-.156),l(-.198,-.155),l(-.692,-.464),l(-.136,-.296),l(.184,-.707),l(-.202,-.296),l(-.394,-.154),l(-.913,-.14),l(-.305,-.211),l(.04,-.184),l(.119,-.085),l(.344,-.1),l(.724,-.058),l(.781,.125),l(1.081,.294),l(.576,.056),l(.147,-.089),
+N(241.295,160.082),l(-.485,-1.358),l(.011,-.17),l(.379,-.455),l(-.012,-.212),l(-.098,-1.215),l(-.017,-.52),l(.503,-.279),l(.393,.14),l(.342,0),l(.384,-.17),l(.369,-.043),l(.14,.198),l(.177,.112),l(1,.309),l(.657,-.072),l(.213,.395),l(.335,.338),l(.528,.324),l(.335,.084),l(.643,.21),l(.916,.45),l(.399,.352),l(.231,.311),l(-.191,.17),l(-.144,.297),l(-.314,.368),l(-.238,-.098),l(-.476,-.592),l(-.378,-.042),l(-.788,.058),l(-.288,-.098),l(-.373,0),l(-.329,.1),l(-.763,.539),l(-.396,-.056),l(-.319,-.494),l(-.166,-.028),l(-.155,.057),l(-.658,.326),l(-.344,.778),l(-.41,.65),l(-.289,-.112),l(-.325,-.551),
+N(668.053,167.796),l(-.131,-.099),l(-.74,-.732),l(-.444,-1.255),l(.037,-.424),l(.054,-.706),l(-.292,-.465),l(.18,-.382),l(.978,.704),l(.202,-.424),l(.023,-.41),l(-.101,-.438),l(-.026,-.579),l(.145,-.438),l(.025,-.664),l(.082,-.861),l(.074,-.636),l(.38,-.862),l(.188,-.127),l(.337,-.142),l(.523,.055),l(1.21,.52),l(.576,.042),l(.188,-.212),l(.277,-.17),l(.199,.141),l(.018,.396),l(-.266,.438),l(-.045,.48),l(.14,.79),l(.541,.394),l(.182,.325),l(-.427,1.271),l(-.31,.467),l(-.834,.608),l(-.555,.312),l(-.082,.099),l(.003,.268),l(-.078,.565),l(-.28,.424),l(.127,.211),l(.35,.733),l(.345,1.101),l(.26,.62),l(.093,.028),l(.451,.324),l(.296,.07),l(.161,-.325),l(.485,-.537),l(.197,-.029),l(.418,.112),l(.226,.211),l(.179,.635),l(.286,.353),l(.326,.084),l(.505,-.58),l(.621,.267),l(.141,.028),l(.078,.127),l(-.168,.156),l(-.378,.156),l(-.208,.212),l(.936,1.226),l(-.315,.184),l(-.568,-.196),l(-.404,-.098),l(-.094,-.48),l(-.229,-.31),l(-.599,-.535),l(-.753,-.577),l(-.258,0),l(-.099,.226),l(.371,.776),l(-.218,.283),l(-.727,-.775),l(-.982,-.548),l(-.309,.015),l(-.344,.142),l(-.182,.255),l(-.14,.071),l(-.395,.057),l(-.322,-.225),l(-.591,-.366),l(-.195,-.423),l(.64,-.608),l(.323,.211),l(.358,.084),l(.4,-.199),l(-.151,-.169),l(-.713,-.295),l(-.422,-.395),l(-.522,-.168),l(-.239,.607),M(669.676,172.974),l(-.452,-.366),l(-.349,-.408),l(-.051,-.226),l(-.364,-1.114),l(-.459,-.521),l(.685,-.058),l(.868,.012),l(.314,.169),l(.274,.451),l(.028,.861),l(-.097,.48),l(-.214,.283),l(-.185,.438),M(679.073,175.368),l(-.562,-.267),l(-.178,-.254),l(-.237,-.169),l(-.064,-.127),l(.139,-.339),l(-.091,-.423),l(-.55,-.352),l(-.662,-.479),l(-.147,-.466),l(.513,-.1),l(1.017,-.143),l(.371,.112),l(.283,.409),l(.069,.818),l(.123,.805),l(.257,.79),l(-.112,.127),l(-.167,.057),M(671.406,176.824),l(.022,-.353),l(.186,-1.342),l(.061,-1.172),l(.482,.395),l(.576,.281),l(.366,.028),l(.634,-.185),l(.027,.438),l(-.079,.396),l(-.24,.269),l(-.184,.198),l(-.908,.651),l(-.943,.397),M(664.721,177.812),l(-.366,-.027),l(.127,-.297),l(.202,-.099),l(.314,-.396),l(.265,-.523),l(.082,-.607),l(.138,-.509),l(.326,-.184),l(.14,.183),l(-.16,.283),l(.276,.55),l(.212,.564),l(-.108,.113),l(-.664,.354),l(-.406,.368),l(-.377,.227),M(673.781,179.981),l(-.385,-.366),l(-.828,-.591),l(-.206,-.38),l(.099,-.368),l(.565,-.213),l(.22,-.269),l(.487,-1.822),l(.438,-.185),l(.271,.028),l(.113,.126),l(.049,.282),l(-.373,.905),l(-.089,.226),l(-.315,1.413),l(.165,.296),l(.214,.465),l(-.213,.41),l(-.212,.043),M(661.179,181.308),l(-.317,-.042),l(.215,-.48),l(.343,-.467),l(.35,-.34),l(.592,-.354),l(.636,-.496),l(.933,-1.089),l(.11,.55),l(-.118,.424),l(-.267,.297),l(-.24,.184),l(-.516,.213),l(-.172,.127),l(-.244,.622),l(-.327,.269),l(-.591,.171),l(-.386,.41),M(680.678,185.402),l(-.201,-.098),l(-.098,-.438),l(-.361,-.748),l(-.297,-.112),l(-.381,.608),l(-.361,.82),l(.246,.38),l(.166,.395),l(.148,.677),l(-.158,.495),l(-.383,.509),l(-.305,-.253),l(-.176,-.268),l(.201,-.41),l(-.076,-.325),l(-.363,-.07),l(-.361,.665),l(-.173,-.056),l(-1.114,-.619),l(-.557,-.549),l(-.206,-.508),l(-.037,-.635),l(.466,-.905),l(-.108,-.479),l(-.466,-.409),l(-.778,-.295),l(-.292,.043),l(-.062,.17),l(-.129,.226),l(-.5,.255),l(-.661,.058),l(-.027,-.494),l(-.174,-.24),l(-.399,.199),l(-.504,.961),l(-.525,.863),l(-.219,-.084),l(-.119,-.127),l(-.034,-.197),l(.054,-.311),l(.359,-.749),l(.185,-.537),l(.263,-.283),l(.383,-.184),l(.564,-.044),l(.219,-.127),l(.134,-.466),l(.205,-.156),l(.549,-.241),l(.777,-.101),l(.292,.353),l(.102,.72),l(.317,-.156),l(.485,-.058),l(.207,-.184),l(.207,-.565),l(.358,-.255),l(.479,.21),l(.186,.084),l(.158,-1.087),l(.29,-.015),l(.264,.465),l(.315,-.481),l(.205,-.142),l(.392,.098),l(.133,-.227),l(-.048,-.706),l(-.172,-.564),l(.146,-.353),l(.413,.549),l(.711,.803),l(.229,.48),l(.083,.324),l(-.336,.735),l(.237,.226),l(.537,-.1),l(.076,.423),l(-.114,.424),l(.056,.692),l(.207,.437),l(-.002,.438),l(-.111,.424),l(-.283,.579),l(-.332,.622),
+N(251.898,160.229),l(-.547,-.112),l(-.073,-.212),l(.051,-.551),l(-.109,-.24),l(.11,-.17),l(.235,-.071),l(.543,.069),l(.404,-.015),l(1.505,.11),l(.393,.168),l(.113,.141),l(-.188,.354),l(-.07,.099),l(-.283,.227),l(-.335,.043),l(-.739,-.083),l(-.657,.072),l(-.354,.17),
+N(228.82,160.519),l(-.299,-.056),l(-.693,-.224),l(-.229,-.268),l(-.47,-.366),l(-.465,-.084),l(-.142,-.211),l(.53,-.284),l(.704,-.072),l(1.364,.251),l(.97,.351),l(.651,.267),l(.279,.282),l(-.04,.198),l(-.332,.071),l(-.751,-.295),l(-.543,.058),l(-.227,.255),l(-.308,.128),
+N(400.72,175.499),l(-.595,-.119),l(-.161,-.032),l(-.976,.458),l(-1.429,-.006),l(-.867,-.037),l(-2.119,.041),l(-.271,.157),l(-.125,.34),l(.261,1.934),l(.02,.41),l(-.191,.17),l(-.63,-.434),l(-.644,-.166),l(-.769,.075),l(-.608,.159),l(-.446,.257),l(-.368,.115),l(-.354,-.083),l(-.452,-.223),l(-.52,-.562),l(-.15,-.465),l(-.308,-.252),l(-.545,.003),l(-.259,-.168),l(.08,-.043),l(.046,-.156),l(.172,-.326),l(.261,-.92),l(.133,-.876),l(-.058,-.749),l(.141,-.255),l(.257,-.016),l(.448,-.158),l(.543,-.271),l(.317,-.369),l(.292,-1.047),l(.355,-1.217),l(.397,-.384),l(.273,-.058),l(.293,.281),l(.551,.364),l(.45,-.102),l(.174,-.227),l(.393,-.822),l(.492,-.667),l(.638,-.625),l(.272,-.101),l(.518,.209),l(.324,.182),l(.274,.027),l(.314,-.793),l(.304,-.228),l(.947,-.458),l(1.22,-.713),l(.37,-.073),l(.356,.125),l(.36,.059),l(1.062,.173),l(-.173,.665),l(.019,.396),l(.426,.93),l(.422,.492),l(.389,.266),l(.502,.42),l(.179,.268),l(.018,.212),l(-.335,.439),l(.114,.226),l(.97,.757),l(.516,.181),l(.37,-.044),l(.562,.025),l(.568,.971),l(.131,.367),l(-.237,.764),l(-.415,.468),l(-.337,.158),l(-.739,-.095),l(-.418,.045),l(-.415,.271),l(-.366,.553),l(-.24,.157),l(-.062,.142),l(-.29,-.041),l(-.611,-.166),l(-1.013,-.163),
+N(209.823,175.47),l(-.388,-.645),l(-.932,-.888),l(-1.003,-1.085),l(-.837,-.817),l(-.723,-.464),l(-.196,-.183),l(-.023,-.226),l(.625,-.03),l(1.001,-.125),l(.29,-.143),l(.293,-.412),l(.005,-.961),l(.882,-.034),l(.513,-.583),l(.725,.42),l(1.207,-.997),l(.503,-.794),l(.294,-.242),l(.259,.013),l(.328,.182),l(.463,.097),l(.248,-.086),l(.424,-.229),l(1.425,-.486),l(.23,.519),l(.038,.339),l(-.057,.509),l(-.214,.707),l(-.543,.806),l(-.1,.749),l(.042,.904),l(-.245,1.13),l(-.188,.735),l(-.101,1.385),l(.031,.55),l(.184,.466),l(.188,.363),l(-.281,.274),l(-.767,-.149),l(-.241,-.46),l(-.285,.077),l(-.394,-.107),l(-.603,.25),l(-1.651,-.599),l(-.43,.271),
+N(634.036,168.444),l(.533,.251),l(.736,.165),l(.341,.111),l(.469,.251),l(.248,-.058),l(.095,-.24),l(-.103,-.211),l(-.187,-.182),l(-.107,-.296),l(.392,-.285),l(.476,-.186),l(.444,.181),l(.373,.351),l(.3,-.072),l(.975,-.429),l(.209,-.114),l(-.215,.905),l(.029,.663),l(.455,1.014),l(-.076,.367),l(-.05,.424),l(.054,1.073),l(-.217,.509),l(-.385,.285),l(-.599,.187),l(-.932,.443),l(-.521,.229),l(-.99,.571),l(-.234,.425),l(.216,.422),l(.568,.435),l(.03,.197),l(-.17,.27),l(-.688,-.194),l(-.497,-.011),l(-.599,.229),l(-.915,.528),l(-.646,.229),l(-.3,.289),l(-.256,-.188),l(-.248,-.268),l(-.35,-.042),l(-.382,.142),l(-.205,-.042),l(-.293,.043),l(-.183,-.113),l(.142,-.311),l(.182,-.226),l(-.04,-.254),l(-.283,-.395),l(-.277,.043),l(-.462,.298),l(-.339,.015),l(-.171,-1.044),l(-.649,-1.488),l(.146,-.176),l(-.16,-.479),l(-.487,-.717),l(-.219,-.648),l(-.026,-.635),l(.076,-.382),l(.146,-.297),l(.92,-1.233),l(.521,-.441),l(.383,-.101),l(1.172,-.091),l(.798,.066),l(.558,-.074),l(.575,.039),l(.599,.109),l(.301,.167),
+N(214.474,175.913),l(.821,.884),l(.385,.623),l(.314,.322),l(.225,.046),l(.465,.645),l(.441,.352),l(-.014,.006),l(-.074,.123),l(-.478,-.184),l(-.219,.205),l(-.014,.321),l(0,.58),l(.507,.307),l(-.396,.368),l(.125,.532),l(-.374,.369),l(.243,.184),l(-.204,.609),l(.003,-.466),l(-.296,-.307),l(.01,-.568),l(-.377,-.148),l(-.238,-.102),l(-.111,.082),l(.325,.41),l(.084,.225),l(-.113,.062),l(-.726,-.299),l(-.13,-.282),l(.251,-.339),l(.04,-.382),l(-.182,-.338),l(-.486,-.324),l(-.695,-.287),l(-.079,-.144),l(-.689,-.103),l(-.316,-.327),l(.007,-.421),l(-.146,-.255),l(-.249,-.098),l(-.576,-.353),l(-.416,-.266),l(.225,.512),l(.086,.222),l(.422,.044),l(.181,.266),l(-.544,.573),l(-.144,-.262),l(-.356,-.282),l(-.561,-.211),l(-.323,-.239),l(-.147,-.24),l(-.104,-.494),l(.128,-.421),l(.332,-.225),l(-.008,-.389),l(-.554,-.225),l(.363,-.123),l(-.057,-.227),l(-.238,.017),l(.43,-.271),l(1.651,.599),l(.603,-.25),l(.394,.107),l(.285,-.077),l(.241,.46),l(.767,.149),l(.281,-.274),
+N(436.304,195.359),l(-.209,-.451),l(-.194,-.804),l(-.498,-.802),l(-1.217,-1.236),l(-.112,-.324),l(-.064,-.791),l(-.432,-.605),l(-.4,-.661),l(-.207,-.592),l(-.273,-1.185),l(-.112,-.776),l(.064,-.424),l(.144,-.198),l(.528,-.399),l(.4,-.511),l(.866,-1.743),l(.354,-.327),l(.208,-.114),l(.096,.084),l(.24,.027),l(.449,-.158),l(1.363,-.686),l(.494,.661),l(.225,.069),l(.224,-.03),l(.466,-.271),l(.754,-.386),l(.818,-.273),l(.881,.009),l(.368,-.031),l(.258,-.143),l(.646,-1.176),l(.117,-.806),l(.209,-.199),l(.434,-.059),l(2.181,-.055),l(.386,-.087),l(2.649,-2.275),l(.196,-.284),l(.005,-.41),l(.165,-.382),l(.372,-.228),l(.939,-.613),l(.322,-.086),l(.321,.012),l(.559,.208),l(1.342,1.673),l(.347,.549),l(.122,.536),l(-.416,1.472),l(.01,.664),l(.158,.211),l(.802,-.019),l(.272,-.001),l(.207,.126),l(.252,.493),l(.223,.225),l(.797,.447),l(.799,.235),l(.351,.196),l(.223,.267),l(-.148,.481),l(.173,.395),l(.445,.351),l(.558,.378),l(.717,.434),l(.207,.168),l(.206,.366),l(.059,.72),l(.285,.436),l(.367,.224),l(.814,.165),l(.558,.477),l(.157,.352),l(-.083,.679),l(.031,.07),l(-.496,.145),l(-.962,.344),l(-.319,-.026),l(-.287,-.167),l(-.687,-.264),l(-1.15,-.361),l(-.4,.13),l(-.082,.551),l(-.13,.241),l(-.256,.058),l(-.399,-.026),l(-.862,-.207),l(-.593,.102),l(-.93,.373),l(-.93,.486),l(-.271,.016),l(-.559,-.35),l(-.383,-.153),l(-.353,.186),l(-.677,1.36),l(-.176,.157),l(-.591,-.067),l(-1.934,-.511),l(-1.422,-.189),l(-.512,-.322),l(-.159,-.239),l(-.334,-.394),l(-.75,-.518),l(-.432,-.167),l(-.479,.06),l(-.529,.3),l(-.353,.341),l(-.785,.979),l(-.097,.297),l(.096,.452),l(-.017,.353),l(-.063,.594),l(-.16,.058),l(-.751,.287),l(-.895,-.093),l(-.624,-.138),l(-.367,-.054),l(-.975,.175),l(-.479,.102),l(-.255,.228),l(-.222,1.287),l(-.158,.523),l(-.365,.497),l(-.303,.312),
+N(371.324,180.419),l(1.088,-1.235),l(.643,-.866),l(.238,-.157),l(.594,.039),l(1.137,-.148),l(.466,.04),l(.42,.224),l(.456,.421),l(.475,.619),l(.252,.761),l(.165,1.369),l(.26,.656),l(-.259,.502),l(-1.184,1.151),l(-.63,.724),l(-.285,.256),l(-.061,.103),l(-.631,-.523),l(-.661,-.408),l(-.483,-.196),l(-.033,-.141),l(.061,-.297),l(-.05,-.184),l(-.531,-.21),l(-.792,-.549),l(-.389,-.366),l(-.375,-.465),l(.494,-.241),l(.174,-.227),l(-.034,-.155),l(-.484,-.211),l(-.065,-.113),l(.022,-.173),
+N(579.606,186.906),l(-.493,-.083),l(-.265,-.197),l(-.21,-.353),l(-.246,-.621),l(-.361,-1.256),l(-.034,-.649),l(.005,-.763),l(-.02,-.904),l(-.24,-.696),l(.188,-.513),l(-.298,-.35),l(.068,-.28),l(.423,.023),l(.349,-.43),l(.053,-.367),l(.226,-.369),l(-.152,-.537),l(.529,.48),l(.699,.38),l(.234,.395),l(.549,.776),l(.175,.324),l(-.099,.339),l(.024,.141),l(.592,.338),l(.266,.733),l(.798,1.368),l(.136,.508),l(-.193,.735),l(-.397,.679),l(-.369,.396),l(-.514,.425),l(-.78,.284),l(-.642,.043),
+N(217.111,178.792),l(.52,.307),l(.195,.512),l(.02,.374),l(.363,.155),l(.628,.024),l(.244,-.205),l(.398,.43),l(.726,.082),l(.458,-.083),l(1.348,-.751),l(.514,-.046),l(1.387,-.921),l(.373,.144),l(.742,.069),l(.071,.156),l(.789,-.017),l(.767,.21),l(.666,.38),l(.644,.563),l(.406,.666),l(.084,.327),l(.228,.149),l(.509,1.038),l(-.322,.062),l(-.094,.43),l(-.584,.409),l(-.085,-.307),l(-.19,-.082),l(.045,.45),l(-.228,.082),l(-.256,.753),l(-.378,-.825),l(-.441,-.762),l(-.137,-.452),l(.179,-.24),l(.22,-.085),l(.786,.125),l(-.336,-.193),l(-.125,-.164),l(-.096,-.471),l(-.309,.307),l(-.439,.041),l(-.244,-.378),l(-.031,-.269),l(-.193,-.282),l(-.132,.151),l(-.226,-.287),l(-.11,.102),l(-.132,-.266),l(-.456,-.192),l(-.562,-.013),l(-.499,.241),l(-.382,.108),l(-.07,.359),l(.081,.234),l(-.529,.318),l(-.374,.184),l(-.335,.029),l(-.345,.41),l(.049,.296),l(.316,.297),l(.464,.43),l(.178,.386),l(-.011,.146),l(-.281,.081),l(-.243,-.042),l(-.431,.391),l(-.568,.105),l(-.339,-.042),l(-.189,-.146),l(.108,-.164),l(-.349,-.833),l(-.244,-.353),l(-.177,.674),l(-.812,-.409),l(-.227,-.757),l(-.207,.041),l(-.96,-.123),l(-.434,-.266),l(-.599,0),l(-.314,.113),l(-.361,.495),l(.204,-.609),l(-.243,-.184),l(.374,-.369),l(-.125,-.532),l(.396,-.368),l(-.507,-.307),l(0,-.58),l(.014,-.321),l(.219,-.205),l(.478,.184),l(.074,-.123),
+N(266.015,188.956),l(-.503,-.647),l(-.732,-.745),l(-.324,-.521),l(.071,-.212),l(.395,-.539),l(-.008,-.58),l(.061,-.452),l(1.032,-.19),l(.41,-.144),l(.308,-.299),l(-.141,-.282),l(-.62,-.604),l(-.074,-.212),l(.101,-.255),l(1.655,-1.239),l(.061,-.41),l(-.095,-.296),l(.072,.049),l(.496,.338),l(.856,.521),l(.695,.521),l(.587,.663),l(.128,.409),l(-.036,.734),l(.148,.945),l(.298,-.593),l(.22,-.099),l(.6,.182),l(.101,.127),l(.507,.295),l(.708,.549),l(.401,.493),l(.374,.649),l(-.015,.339),l(-.142,.496),l(-.082,.862),l(-.183,.27),l(-1.131,.091),l(-.169,.17),l(.078,.777),l(-.095,.467),l(-.328,.694),l(.571,.831),l(.532,.675),l(.561,.067),l(.185,.295),l(.246,.832),l(.49,1.127),l(.332,.563),l(-.06,.212),l(-.943,-.022),l(-.934,.429),l(-1,.331),l(-.505,.314),l(-.694,.513),l(-.686,.075),l(-.613,-.392),l(-1.103,-.897),l(-.15,-.296),l(-.008,-.396),l(.072,-.354),l(-.167,-.31),l(-.281,-.394),l(-.156,-.465),l(.213,-.962),l(.547,-1.416),l(.179,-.368),l(-.435,-.958),l(-.533,-.138),l(-.304,.001),l(.452,-1.09),l(-.04,-.212),l(-.26,-.111),l(-.516,-.124),l(-.302,.058),l(-.375,.257),
+N(377.518,182.142),l(.193,-.376),l(.252,-.242),l(.367,-.143),l(.528,-.046),l(.338,.097),l(.165,.366),l(.22,.846),l(.009,.65),l(-.044,.283),l(.277,.323),l(.404,.322),l(.321,.026),l(.756,-.922),l(.143,-.086),l(.337,.097),l(.339,.224),l(-.062,.17),l(.119,.55),l(-.059,.438),l(-.501,.865),l(.05,.183),l(.194,.183),l(.369,.097),l(.592,-.032),l(1.264,1.334),l(.131,.282),l(-.059,.452),l(-.247,.849),l(-.105,.565),l(-.041,.919),l(-1.513,-.643),l(-1.221,-.619),l(-1.012,-.562),l(-.403,-.423),l(-1.129,-1.113),l(-1.111,-.76),l(-.723,-.337),l(-.901,-.535),l(-.66,-.548),l(.061,-.103),l(.285,-.256),l(.63,-.724),l(1.184,-1.151),l(.259,-.502),
+N(429.505,210.684),l(.484,.336),l(.177,.013),l(.443,-.271),l(.327,-.581),l(1.495,-.532),l(.054,.424),l(.042,.664),l(.147,.211),l(.57,-.328),l(.554,-.399),l(.931,-.811),l(.364,-.229),l(1.025,-.938),l(.086,-.706),l(-.122,-.72),l(.074,-.396),l(.193,-1.159),l(.343,-.751),l(.47,-.836),l(.41,-.454),l(.809,-.599),l(.525,-.229),l(.459,-.427),l(.139,-.523),l(.169,-.708),l(.115,-.61),l(.254,-1.342),l(.196,-2.021),l(.156,-.764),l(.094,-.551),l(.349,-.821),l(.558,-.837),l(.398,-1.203),l(.031,-.156),l(-.128,-.197),l(.16,-.058),l(.063,-.594),l(.017,-.353),l(-.096,-.452),l(.097,-.297),l(.785,-.979),l(.353,-.341),l(.529,-.3),l(.479,-.06),l(.432,.167),l(.75,.518),l(.334,.394),l(.159,.239),l(.512,.322),l(1.422,.189),l(1.934,.511),l(.591,.067),l(.176,-.157),l(.677,-1.36),l(.353,-.186),l(.383,.153),l(.559,.35),l(.271,-.016),l(.93,-.486),l(.93,-.373),l(.593,-.102),l(.862,.207),l(.399,.026),l(.256,-.058),l(.13,-.241),l(.082,-.551),l(.4,-.13),l(1.15,.361),l(.687,.264),l(.287,.167),l(.319,.026),l(.962,-.344),l(.496,-.145),l(.143,.239),l(.795,.772),l(.348,.493),l(.525,.477),l(.366,.195),l(.352,-.016),l(.258,-.242),l(.529,-.37),l(.384,.012),l(.684,.631),l(.16,-.1),l(.436,-.582),l(.258,-.157),l(.207,.083),l(1.032,.926),l(1.288,1.32),l(.063,.028),l(.159,.183),l(-.018,.424),l(-.26,1.88),l(.128,.253),l(.191,.027),l(.479,.04),l(.271,.182),l(.111,.31),l(-.191,.453),l(-1.195,1.066),l(-1.241,.996),l(-.255,.284),l(-.395,.681),l(-.217,1.02),l(-.107,.507),l(.021,.593),l(-.025,.734),l(.057,.748),l(-.076,.27),l(-.188,.298),l(-.426,.412),l(-.301,.171),l(-.269,.256),l(-.122,.425),l(-.49,1.358),l(.197,.338),l(.689,.999),l(.087,.381),l(-.04,.438),l(.014,.636),l(.237,.634),l(.017,1.329),l(-.064,.762),l(.425,1.439),l(-.102,.848),l(.122,.693),l(.486,.631),l(.936,.898),l(.428,.78),l(.689,1.804),l(-.563,.068),l(-3.015,.499),l(-.347,.214),l(-.154,.198),l(-.797,1.276),l(-.029,.622),l(.372,2.088),l(-.377,1.175),l(-.3,1.02),l(.043,.296),l(.456,.605),l(.837,.843),l(.445,.279),l(.515,.012),l(.448,-.455),l(.362,-.186),l(.136,.183),l(.032,.791),l(.028,1.427),l(-.041,.551),l(-.371,-.012),l(-1.355,-.091),l(-.348,-.21),l(-.381,-.647),l(-.561,-.731),l(-.416,-.351),l(-.477,-.252),l(-.895,-.263),l(-.38,-.28),l(-.728,-1.423),l(-.212,.354),l(-.522,.682),l(-.366,.087),l(-.325,-.111),l(-.922,-.164),l(-.925,-.249),l(-.489,-.194),l(-.58,-1.014),l(-.175,.071),l(-1.146,.289),l(-.195,-.056),l(-.172,-.352),l(-.365,-.379),l(-.678,-.096),l(-1.24,-.147),l(-.991,.146),l(-.859,.26),l(-.61,.004),l(-.199,-.197),l(-.007,-.254),l(.198,-.905),l(.003,-.466),l(-.306,-.62),l(-.844,-.998),l(-.117,-.211),l(-.021,-.212),l(.296,-1.033),l(.07,-1.06),l(-.109,-.607),l(-.303,-.605),l(.057,-.354),l(.177,-.693),l(-.052,-.183),l(-.322,-.098),l(-1.231,.093),l(-.88,.019),l(-.212,-.168),l(.055,-.48),l(-.181,-.225),l(-2.016,.082),l(-.112,.001),l(-.089,.354),l(.027,.593),l(-.286,.892),l(-.184,.411),l(-.993,.006),l(-.899,-.122),l(-1.021,.246),l(-.88,.034),l(-.292,-.168),l(-.64,-.787),l(-.597,-1.07),l(-.537,-1.409),l(-.059,-.579),l(-.121,-.521),l(-.082,-.127),l(-.321,-.111),l(-.385,-.012),l(-1.104,-.008),l(-.88,.034),l(-.624,.003),l(-1.312,-.048),l(-.945,-.052),l(-.783,.02),l(-.432,.03),l(-.318,.101),l(-.896,.062),l(-.699,.314),l(-.56,.06),l(-.112,-.013),l(-.322,-.922),l(.012,-.053),l(.74,-.3),l(-.017,-.085),l(.1,-.89),l(.094,-.143),l(.317,-.199),l(.583,-.568),
+N(468.568,202.653),l(1.277,-.05),l(4.659,0),l(1.448,-.033),l(4.663,2.568),l(3.553,1.984),l(.137,.381),l(-.116,.552),l(.07,.239),l(2.427,1.752),l(1.067,.807),l(-.237,.427),l(-.419,1.329),l(-.137,1.017),l(.109,.551),l(.665,.987),l(.768,.577),l(-.024,.282),l(-.263,.354),l(-.371,1.046),l(.037,.17),l(.306,.041),l(.118,.226),l(-.172,.692),l(-.019,.946),l(.411,1.793),l(.18,.564),l(.401,.465),l(.823,.55),l(.396,.268),l(.177,.228),l(-1.157,.836),l(-.515,.342),l(-1.218,.402),l(-1.243,.559),l(-.448,.031),l(-.646,-.42),l(-.276,-.083),l(-.21,.326),l(-.543,.766),l(-.396,.144),l(-.42,-.054),l(-.964,.006),l(-.963,.02),l(-.512,-.294),l(-.323,-.394),l(-.229,-.083),l(-.123,.128),l(-.643,.356),l(-.526,.088),l(-1.019,-.149),l(-.898,-.018),l(-.196,-.559),l(-.135,-.766),l(-.053,-.584),l(-.135,-.946),l(-.448,-.841),l(-.663,-.538),l(-1.014,-.107),l(-.223,.016),l(-.385,-.407),l(-.732,-.349),l(-1.574,-.57),l(-1.269,-.6),l(-.729,-.265),l(-.263,-.21),l(-.703,-.641),l(-.689,-1.804),l(-.428,-.78),l(-.936,-.898),l(-.486,-.631),l(-.122,-.693),l(.102,-.848),l(-.425,-1.439),l(.064,-.762),l(1.252,-.348),l(.388,-.539),l(.645,-1.204),l(.687,-.853),l(.346,-.271),l(.044,-.212),l(-.148,-.239),l(-.273,-.125),l(-.401,-.068),l(-.211,-.211),l(.158,-.976),l(.304,-.016),l(.396,-.158),l(.142,-.17),l(.104,-.481),l(-.167,-.493),l(-.364,-.888),l(-.121,-.748),
+N(464.786,206.235),l(-.197,-.338),l(.49,-1.358),l(.122,-.425),l(.269,-.256),l(.301,-.171),l(.426,-.412),l(.064,.042),l(.546,.223),l(.431,-.045),l(.458,-.427),l(.554,-.398),l(.319,-.017),l(.121,.748),l(.364,.888),l(.167,.493),l(-.104,.481),l(-.142,.17),l(-.396,.158),l(-.304,.016),l(-.559,.031),l(-.508,.159),l(-.391,.567),l(-.158,.085),l(-.396,.13),l(-.789,-.32),l(-.688,-.024),
+N(465.79,210.652),l(-.017,-1.329),l(-.237,-.634),l(-.014,-.636),l(.04,-.438),l(-.087,-.381),l(-.689,-.999),l(.688,.024),l(.789,.32),l(.396,-.13),l(.158,-.085),l(.391,-.567),l(.508,-.159),l(.559,-.031),l(-.158,.976),l(.211,.211),l(.401,.068),l(.273,.125),l(.148,.239),l(-.044,.212),l(-.346,.271),l(-.687,.853),l(-.645,1.204),l(-.388,.539),l(-1.252,.348),
+N(427.243,211.207),l(.536,-.414),l(.68,-.513),l(.351,-.13),l(.695,.533),l(-.583,.568),l(-.317,.199),l(-.094,.143),l(-.1,.89),l(.017,.085),l(-.74,.3),l(.143,-.625),l(-.082,-.24),l(-.505,-.796),M(427.998,213.843),l(.112,.013),l(.56,-.06),l(.699,-.314),l(.896,-.062),l(.318,-.101),l(.432,-.03),l(.783,-.02),l(.945,.052),l(1.312,.048),l(.624,-.003),l(.88,-.034),l(1.104,.008),l(.385,.012),l(.321,.111),l(.082,.127),l(.121,.521),l(.059,.579),l(.537,1.409),l(.597,1.07),l(.64,.787),l(.292,.168),l(.88,-.034),l(1.021,-.246),l(.899,.122),l(.993,-.006),l(.184,-.411),l(.286,-.892),l(-.027,-.593),l(.089,-.354),l(.112,-.001),l(2.016,-.082),l(.181,.225),l(-.055,.48),l(.212,.168),l(.88,-.019),l(1.231,-.093),l(.322,.098),l(.052,.183),l(-.177,.693),l(-.057,.354),l(.303,.605),l(.109,.607),l(-.07,1.06),l(-.296,1.033),l(.021,.212),l(.117,.211),l(.844,.998),l(.306,.62),l(-.003,.466),l(-.198,.905),l(.007,.254),l(.199,.197),l(.61,-.004),l(.859,-.26),l(.991,-.146),l(1.24,.147),l(-.214,1.344),l(.195,1.059),l(.269,.323),l(.089,.254),l(-.132,.368),l(-.436,.44),l(-.124,.594),l(-.125,.086),l(-.517,-.04),l(-3.408,.091),l(-.051,.877),l(.015,1.342),l(-.024,3.249),l(.017,.848),l(.023,.594),l(.099,.438),l(.308,.394),l(.471,.436),l(1.354,1.391),l(.611,.632),l(-.93,.218),l(-1.96,.379),l(-1.044,.203),l(-.717,-.08),l(-1.164,.063),l(-.408,-.083),l(-.349,-.21),l(-2.024,.026),l(-.697,-.024),l(-.622,-.151),l(-.401,-.322),l(-.305,-.366),l(-.408,-.096),l(-.989,-.023),l(-2.59,.016),l(-1.636,-.019),l(-.631,-.011),l(-1.296,-.006),l(-2.201,.013),l(-.636,-.151),l(-.463,-.309),l(-.45,-.478),l(-.294,-.083),l(-.499,.088),l(-.591,.286),l(-.778,.513),l(-.758,-.462),l(-.352,.144),l(-.248,.197),l(.048,-1.809),l(-.017,-.805),l(-.029,-.649),l(.397,-.34),l(.221,-.269),l(.26,-.707),l(.163,-.734),l(.184,-1.398),l(.239,-.976),l(.321,-.918),l(.584,-.665),l(.183,-.565),l(.268,-.354),l(.64,-.228),l(.268,-.325),l(.423,-.679),l(.364,-1.201),l(.053,-.664),l(-.046,-.848),l(-.191,-.959),l(-.201,-.536),l(-.492,-.705),l(-.476,-.776),l(-.268,-.775),l(.139,-.495),l(.476,-.382),l(.158,-.156),l(.107,-.424),l(-.006,-.479),l(-.199,-.579),l(-.489,-.69),l(-.441,-.733),l(-.203,-1.031),l(-.181,-.423),l(-.276,-.366),l(-.666,-.974),l(-.072,-.15),
+N(452.198,239.34),l(-.611,-.632),l(-1.354,-1.391),l(-.471,-.436),l(-.308,-.394),l(-.099,-.438),l(-.023,-.594),l(-.017,-.848),l(.024,-3.249),l(-.015,-1.342),l(.051,-.877),l(3.408,-.091),l(.517,.04),l(.125,-.086),l(.124,-.594),l(.436,-.44),l(.132,-.368),l(-.089,-.254),l(-.269,-.323),l(-.195,-1.059),l(.214,-1.344),l(.678,.096),l(.365,.379),l(.172,.352),l(.195,.056),l(1.146,-.289),l(.175,-.071),l(.58,1.014),l(.489,.194),l(.925,.249),l(.922,.164),l(.325,.111),l(.366,-.087),l(.522,-.682),l(.212,-.354),l(.728,1.423),l(.38,.28),l(.895,.263),l(.477,.252),l(.416,.351),l(.561,.731),l(.381,.647),l(.348,.21),l(1.355,.091),l(.371,.012),l(.041,-.551),l(-.028,-1.427),l(-.032,-.791),l(-.136,-.183),l(-.362,.186),l(-.448,.455),l(-.515,-.012),l(-.445,-.279),l(-.837,-.843),l(-.456,-.605),l(-.043,-.296),l(.3,-1.02),l(.377,-1.175),l(-.372,-2.088),l(.029,-.622),l(.797,-1.276),l(.154,-.198),l(.347,-.214),l(3.015,-.499),l(.563,-.068),l(.703,.641),l(.263,.21),l(.729,.265),l(1.269,.6),l(1.574,.57),l(.732,.349),l(.385,.407),l(.559,.887),l(.434,.859),l(.013,.324),l(-.183,.27),l(-.709,.344),l(-.011,.127),l(.04,.594),l(-.091,1.682),l(.08,.353),l(.216,.168),l(.511,.266),l(.072,.197),l(-.197,.241),l(-.472,.258),l(-.792,.259),l(-.146,.34),l(-.094,.764),l(-.3,.807),l(.2,.479),l(.261,.408),l(.394,.125),l(-1.264,.53),l(-1.696,.575),l(-.932,.4),l(-2.165,.578),l(-.187,.128),l(-.009,.495),l(.152,.465),l(.087,.438),l(-.505,-.096),l(-.999,.049),l(-.794,.259),l(-.636,.54),l(-.312,.539),l(-.019,.579),l(-.168,.199),l(-.285,.114),l(-.999,.062),l(-.621,.202),l(-.306,.341),l(-.777,.937),l(-.562,.738),l(-.825,.951),l(-.354,.045),l(-.803,-.165),l(-.421,-.309),l(-.334,.129),l(-.521,.286),l(-.404,.017),l(-.594,-.209),l(-.264,-.097),l(-.154,-.169),l(-.163,-.027),l(-.187,-.154),l(-.456,-.393),l(-.294,-.055),l(-1.089,-.093),l(-.086,-.099),l(-.165,-.056),l(-1.845,.364),
+N(477.231,225.874),l(-.224,1.184),l(-.107,.48),l(.252,.917),l(.177,1.017),l(.149,.408),l(.238,.268),l(.803,.588),l(1.189,1.166),l(.454,.661),l(.14,.48),l(-.155,2.346),l(-.04,.41),l(-.214,.213),l(-.432,.073),l(-.322,.017),l(-.229,.213),l(-.076,.622),l(.08,.509),l(.029,.479),l(-.096,.283),l(-.185,-.111),l(-.562,-.463),l(-.763,-1.112),l(-.484,-.548),l(-.234,-.423),l(.036,-.212),l(.499,-.61),l(.116,-.227),l(.025,-.693),l(-.1,-.96),l(-.22,-.479),l(-.261,-.056),l(-.674,.061),l(-.702,.132),l(-.27,-.211),l(-.343,-.407),l(-.382,-.549),l(-.195,-.041),l(-.394,-.125),l(-.261,-.408),l(-.2,-.479),l(.3,-.807),l(.094,-.764),l(.146,-.34),l(.792,-.259),l(.472,-.258),l(.197,-.241),l(-.072,-.197),l(-.511,-.266),l(-.216,-.168),l(-.08,-.353),l(.091,-1.682),l(-.04,-.594),l(.011,-.127),l(.709,-.344),l(.183,-.27),l(-.013,-.324),l(-.434,-.859),l(-.559,-.887),l(.223,-.016),l(1.014,.107),l(.663,.538),l(.448,.841),l(.135,.946),l(.053,.584),l(.135,.766),l(.196,.559),
+N(245.934,224.314),l(.939,.136),l(1.122,.304),l(.355,-.03),l(.946,-.824),l(.336,.026),l(.48,.025),l(.415,-.243),l(1.471,-1.109),l(.874,-.485),l(.36,-.158),l(.934,-.076),l(1.283,.021),l(.045,.748),l(-.079,.621),l(-.064,.622),l(.036,.818),l(.141,.635),l(.335,.591),l(.813,.928),l(1.1,.939),l(.316,.097),l(.787,.023),l(.355,-.03),l(.676,.25),l(.688,.307),l(.75,.603),l(.3,.098),l(.882,.037),l(.096,.014),l(.385,.774),l(.398,.308),l(.22,.084),l(1.148,-.077),l(.636,.123),l(.537,.166),l(.403,.237),l(.085,.169),l(-.038,.565),l(.203,1.029),l(.03,.706),l(.138,2.032),l(.249,.944),l(.153,.112),l(.967,.036),l(.5,.012),l(1.615,.019),l(.693,.024),l(.042,.296),l(-.261,.835),l(.067,.563),l(.436,.407),l(.73,.362),l(.316,.479),l(.307,.774),l(.022,.494),l(-.185,1.173),l(-.238,.834),l(-.38,.765),l(-.421,.666),l(-.089,-.084),l(-1.952,-.991),l(-.352,-.054),l(-.928,.02),l(-.843,-.01),l(-.126,.128),l(-1.076,.204),l(-1.104,.162),l(-.784,.202),l(-.33,.044),l(-.332,.383),l(-.698,1.105),l(-.278,.341),l(-.133,.509),l(.016,.635),l(-.385,1.188),l(-.395,1.104),l(-.149,.325),l(-.592,-.109),l(-1.33,-.077),l(-.686,.004),l(-1.034,1.784),l(-.416,-1.084),l(-.341,-.309),l(-.37,-.195),l(-.531,-.067),l(-.527,.045),l(-.901,.034),l(-.615,-.194),l(-.193,-.169),l(-.322,-.181),l(-.292,.27),l(-2.026,2.087),l(-1.047,.006),l(-.272,-.182),l(-.397,-2.144),l(-.278,-.973),l(-.212,-.563),l(-.769,-1.11),l(-.249,-.676),l(.04,-.354),l(.437,-1.555),l(-.017,-.282),l(-.761,-.744),l(-.25,-.521),l(-.193,-1.213),l(-.304,-.647),l(-.555,-.745),l(-.152,-.253),l(-.018,-.142),l(-.132,-.295),l(-.049,-.48),l(.12,-.227),l(.723,-.61),l(.285,-.439),l(-.015,-.522),l(-.604,-1.168),l(-.022,-.48),l(.159,-.34),l(.21,-.368),l(-.347,-.845),l(.102,-.452),l(.532,-.582),l(.221,-.34),l(.156,-.34),l(-.236,-.902),l(-.057,-.522),l(.143,-.848),l(.15,-.523),l(.437,-.736),l(-.08,-.24),l(-.922,-1.646),l(-1.109,-1.843),
+N(473.575,260.04),l(-1.331,.011),l(-.192,.058),l(-.068,-.382),l(-.261,-.889),l(.071,-.495),l(-.075,-.296),l(-.095,-.324),l(.03,-.806),l(.057,-1.301),l(-.072,-.763),l(-.147,-.678),l(-.33,-.944),l(-.441,-.689),l(-.181,-.946),l(-.295,-1.199),l(-.159,-.183),l(.448,-.384),l(.396,-.412),l(1.68,-1.706),l(.114,-.227),l(-.09,-.367),l(.075,-.834),l(.229,-.481),l(.736,-.683),l(.205,-.341),l(.168,-.41),l(-.594,-.845),l(-.118,-.805),l(-.113,-.494),l(.128,-.283),l(.448,-.596),l(.201,-.411),l(-.132,-.805),l(-.086,-1.144),l(-.031,-.791),l(-.178,-.818),l(-.441,-.379),l(-.515,-.224),l(-1.167,-.347),l(-1.042,-.445),l(-.658,-.223),l(-1.438,-.006),l(-.137,-.14),l(-.025,-.495),l(-.011,-.212),l(-.087,-.438),l(-.152,-.465),l(.009,-.495),l(.187,-.128),l(2.165,-.578),l(.932,-.4),l(1.696,-.575),l(1.264,-.53),l(.195,.041),l(.382,.549),l(.343,.407),l(.27,.211),l(.702,-.132),l(.674,-.061),l(.261,.056),l(.22,.479),l(.1,.96),l(-.025,.693),l(-.116,.227),l(-.499,.61),l(-.036,.212),l(.234,.423),l(.484,.548),l(.763,1.112),l(.562,.463),l(.185,.111),l(.096,-.283),l(-.029,-.479),l(-.08,-.509),l(.076,-.622),l(.229,-.213),l(.322,-.017),l(.432,-.073),l(.214,-.213),l(.04,-.41),l(.155,-2.346),l(-.14,-.48),l(-.454,-.661),l(-1.189,-1.166),l(-.803,-.588),l(-.238,-.268),l(-.149,-.408),l(-.177,-1.017),l(-.252,-.917),l(.107,-.48),l(.224,-1.184),l(.898,.018),l(1.019,.149),l(.526,-.088),l(.643,-.356),l(.123,-.128),l(.229,.083),l(.323,.394),l(.512,.294),l(.963,-.02),l(.964,-.006),l(.42,.054),l(.396,-.144),l(.543,-.766),l(.21,-.326),l(.276,.083),l(.646,.42),l(.448,-.031),l(1.243,-.559),l(1.218,-.402),l(.515,-.342),l(1.157,-.836),l(.128,.167),l(.212,.479),l(-.185,.579),l(-.302,.453),l(-.198,.255),l(.181,.451),l(.129,.72),l(-.012,.466),l(.182,1.115),l(-.101,.58),l(-.258,.325),l(.374,.705),l(.154,.494),l(-.006,1.115),l(-.004,.819),l(.043,.184),l(.185,.127),l(.327,.084),l(.015,.269),l(-.165,.494),l(-.563,.58),l(.184,.381),l(-.08,.283),l(-.418,.565),l(-.802,.906),l(-.512,.622),l(-.72,.651),l(-1.36,.751),l(-1.48,.653),l(-.73,.228),l(-1.308,.582),l(-.852,.637),l(-1.286,1.443),l(-.886,.85),l(-1.193,.878),l(-1.181,.836),l(-.268,.128),l(-.035,.96),l(-.083,.495),l(.058,.127),l(.719,.535),l(.188,.381),l(-.166,.452),l(-.085,.184),l(.461,1.511),l(.071,.564),l(.06,.155),l(.246,.014),l(.171,-.128),l(.141,-.085),l(.043,.607),l(-.234,2.218),l(-.284,.82),l(.325,.196),l(.152,.057),l(-.025,.325),l(-.157,.311),l(-.516,.566),l(-.699,.538),l(-.664,.34),l(-1.266,.412),l(-.796,.312),l(-.688,.228),l(-.895,.524),l(-.652,.665),l(-.337,.51),l(.292,.338),l(.589,.338),l(.045,.325),l(-.149,1.022),
+N(499.85,236.166),l(.544,-.071),l(.622,-.369),l(.18,.028),l(.346,.098),l(.269,-.085),l(.396,-.368),l(.911,-.143),l(.311,.281),l(.305,-.028),l(.101,-.185),l(-.171,-.366),l(.771,-.539),l(.423,-.198),l(.322,.226),l(.389,-.213),l(-.308,-.494),l(.207,-.282),l(.505,-.425),l(.229,.296),l(.229,.056),l(.558,-.594),l(-.158,-.197),l(-.253,-.409),l(.094,-.297),l(.243,.014),l(.27,-.071),l(.172,-.34),l(-.297,-.875),l(.06,-.339),l(.255,-.043),l(.117,.07),l(.253,.438),l(.28,.099),l(.2,-.41),l(.692,-.524),l(.235,-.367),l(.134,-.452),l(.168,-.692),l(-.133,-.354),l(.003,-.226),l(.537,-.468),l(.356,.324),l(.455,.648),l(.612,.281),l(.141,.198),l(.213,.847),l(.294,1.821),l(.093,.663),l(.231,.791),l(.391,.733),l(.163,.466),l(-.038,.367),l(-.069,.155),l(-.058,.099),l(-.537,.807),l(-.22,-.127),l(-.189,-.366),l(-.555,-.748),l(-.297,.143),l(-.05,.424),l(.193,.875),l(.396,.521),l(.079,.396),l(-.307,.636),l(-.746,1.005),l(-.045,.452),l(.041,.89),l(-.18,.946),l(-.709,2.12),l(-.825,2.572),l(-1.254,3.788),l(-1.324,4.48),l(-.518,1.568),l(-.188,.255),l(-.508,.637),l(-.2,.113),l(-1.369,.102),l(-.999,.327),l(-.474,.468),l(-.813,.086),l(-.363,-.465),l(-.196,-.142),l(-.546,-.182),l(-.37,.071),l(-.269,-.057),l(-.863,-.718),l(-.104,-.24),l(-.02,-.565),l(-.104,-.239),l(-.46,-.366),l(-.124,-.282),l(.001,-.721),l(.345,-1.088),l(-.094,-.325),l(-.287,-.479),l(-.62,-.931),l(-.189,-.494),l(.075,-.664),l(.391,-1.37),l(.228,-.213),l(.474,-.185),l(.768,-1.371),l(.686,-1.174),l(.104,-.325),l(.151,-1.103),l(-.11,-.353),l(-.278,-.226),l(-.354,-.366),l(.066,-.184),l(.252,-.509),l(-.521,-.861),l(-.117,-.677),l(-.069,-.494),l(-.231,-.721),l(.024,-.112),l(.517,-.693),l(.362,-.594),l(.163,-.438),l(.007,-1.073),l(.484,-.016),
+N(468.138,234.908),l(.011,.212),l(.025,.495),l(.137,.14),l(1.438,.006),l(.658,.223),l(1.042,.445),l(1.167,.347),l(.515,.224),l(.441,.379),l(.178,.818),l(.031,.791),l(.086,1.144),l(.132,.805),l(-.201,.411),l(-.448,.596),l(-.128,.283),l(.113,.494),l(.118,.805),l(.594,.845),l(-.168,.41),l(-.205,.341),l(-.736,.683),l(-.229,.481),l(-.075,.834),l(.09,.367),l(-.114,.227),l(-1.68,1.706),l(-.396,.412),l(-.448,.384),l(-.342,-.225),l(-.547,-.124),l(-.442,-.025),l(-.529,.145),l(-.31,.016),l(-.99,-.403),l(-.597,-.139),l(-.72,-.023),l(-.067,-.042),l(-.186,-.098),l(-.306,-.451),l(-.479,-.35),l(-.549,-.167),l(-.938,-.136),l(-.352,-.153),l(-.524,-.873),l(-.163,-.564),l(.032,-.565),l(-.127,-.239),l(-.78,.019),l(-.201,-.098),l(-.109,-.211),l(.051,-.537),l(-.106,-.169),l(-.552,-.266),l(-.533,-.223),l(-.57,-.321),l(-.563,-.491),l(-.377,-.662),l(-.246,-.96),l(-.469,-.604),l(-.43,-.478),l(-.267,-.451),l(.103,-.227),l(.594,.209),l(.404,-.017),l(.521,-.286),l(.334,-.129),l(.421,.309),l(.803,.165),l(.354,-.045),l(.825,-.951),l(.562,-.738),l(.777,-.937),l(.306,-.341),l(.621,-.202),l(.999,-.062),l(.285,-.114),l(.168,-.199),l(.019,-.579),l(.312,-.539),l(.636,-.54),l(.794,-.259),l(.999,-.049),l(.505,.096),
+N(444.673,255.519),l(-.006,3.434),l(.031,1.894),l(.025,2.246),l(-.057,.205),l(-.454,.318),l(-.545,.302),l(-.581,.498),l(-.427,.034),l(-.581,-.166),l(-.745,-.042),l(-.892,.048),l(-.517,-.039),l(-.296,-.212),l(-.055,-.528),l(-.042,-.345),l(-.193,-.222),l(-.637,-.348),l(-.329,-.127),l(-.335,.116),l(-.109,.217),l(-.317,.416),l(-.584,.27),l(-.152,.068),l(-.458,-.491),l(-1.041,-1.001),l(-.458,-.606),l(-.359,-1.03),l(-.345,-.72),l(-.136,-.493),l(.12,-.269),l(.053,-.34),l(-.458,-.719),l(-.231,-.861),l(.148,-.861),l(-.002,-.48),l(-.537,-1.326),l(-.496,-2.244),l(.772,-.02),l(.04,-.678),l(-.077,-.749),l(-.456,-.006),l(.016,-.06),l(-.099,-.522),l(-.26,-.508),l(-1.018,-1.283),l(-.343,-.55),l(-1.102,-2.158),l(-.841,-1.623),l(-.9,-1.509),l(-.988,-1.269),l(-.511,-1.044),l(-.122,-.396),l(-.045,-.551),l(.015,-.578),l(.248,-.197),l(.352,-.144),l(.758,.462),l(.778,-.513),l(.591,-.286),l(.499,-.088),l(.294,.083),l(.45,.478),l(.463,.309),l(.636,.151),l(2.201,-.013),l(1.296,.006),l(.631,.011),l(1.636,.019),l(2.59,-.016),l(.989,.023),l(.408,.096),l(.305,.366),l(.401,.322),l(.622,.151),l(.697,.024),l(2.024,-.026),l(.349,.21),l(.408,.083),l(1.164,-.063),l(.717,.08),l(1.044,-.203),l(1.96,-.379),l(.93,-.218),l(1.845,-.364),l(.165,.056),l(.086,.099),l(1.089,.093),l(.294,.055),l(.456,.393),l(-.811,.315),l(-.891,.02),l(-.284,.143),l(-.993,.938),l(-.209,.029),l(-.62,-.773),l(-1.048,.134),l(-2.962,.47),l(-1.183,.021),l(.005,1.215),l(-.007,1.286),l(-.025,.876),l(-.043,1.201),l(.002,3.561),l(-.586,.046),l(-1.564,.052),l(-.146,.028),l(-.106,2.657),l(-.009,1.201),l(.013,1.624),l(.007,.806),
+N(248.453,316.576),l(-.306,.101),l(-.892,-.087),l(-.538,-.293),l(-.236,-.015),l(-.311,.163),l(-.418,.398),l(-.498,.192),l(-1.156,.091),l(-.349,.09),l(-.358,.207),l(-.267,.621),l(-.114,.341),l(.06,.532),l(-.163,.622),l(-.104,.148),l(-.453,.031),l(-.534,.104),l(-.956,-.413),l(.667,-.639),l(.326,-.444),l(.582,-.4),l(.025,-.147),l(-.372,-.177),l(-.273,-.117),l(-1.353,.534),l(-1.01,-.013),l(-.545,.163),l(-.202,-.339),l(.128,-.192),l(.959,-.268),l(.266,.028),l(.792,-.208),l(.441,-.118),l(-.605,-.162),l(-.582,.002),l(-.77,.001),l(-.014,-.413),l(.265,-.31),l(-.007,-.191),l(-.446,-.073),l(-.356,-.44),l(-.66,.384),l(-.669,-.175),l(.292,-.53),l(.041,-.177),l(-.378,.045),l(-.361,.147),l(-.416,-.396),l(-.215,-.117),l(.413,-.279),l(.114,-.177),l(-.091,-.278),l(-.053,-.073),l(-.351,.03),l(-.773,-.424),l(-.135,-.059),l(.844,-.192),l(.253,-.161),l(.1,-.294),l(.396,-.366),l(.049,-.234),l(-.641,.06),l(-.257,.104),l(-.312,-.073),l(-.256,-.672),l(.573,-.395),l(-.565,-.378),l(-.12,-.421),l(.757,-.452),l(-.14,-.421),l(-.686,.422),l(-.091,-1.523),l(.399,-.596),l(-.185,-.825),l(.013,-.218),l(.593,.014),l(.41,.245),l(.711,.071),l(.171,-.246),l(.002,-.159),l(-.896,-.447),l(-.867,.146),l(-.317,-.173),l(-.536,.059),l(-.017,-.231),l(.339,-.333),l(.025,-.246),l(-.067,-.087),l(.186,-.202),l(.536,.014),l(.229,-.377),l(.01,-.216),l(-.722,-.389),l(-.354,-.129),l(-.886,.045),l(-.332,-.101),l(-.024,-.49),l(-.939,.16),l(-.115,-.101),l(.122,-.145),l(1.032,-.521),l(.251,-.116),l(.4,-.404),l(.266,-.389),l(.833,-.06),l(.268,.201),l(.059,.346),l(-.648,.202),l(-.323,.274),l(.11,.505),l(.117,.058),l(.191,-.102),l(.268,-.39),l(.183,-.087),l(.242,.101),l(-.037,.317),l(.057,.504),l(.886,-.996),l(.161,-.678),l(.056,-.647),l(.237,-.375),l(.079,-.058),l(.631,-.217),l(-.201,-.071),l(-.438,-.143),l(-.056,-.158),l(.101,-.273),l(.246,-.072),l(.571,-.245),l(.599,-.431),l(.271,-.459),l(-.061,-.229),l(-.394,-.157),l(-.662,-.399),l(-.053,-.372),l(.139,-.243),l(.105,-.458),l(-.06,-.828),l(.366,-.33),l(.676,-.272),l(-.431,-.585),l(-.053,-.784),l(.133,-.158),l(.554,-.157),l(.054,-.314),l(-.116,-.285),l(-.317,-.085),l(-.272,-.198),l(.233,-.329),l(.087,-.313),l(-.401,-.185),l(-.274,-.014),l(-.161,.101),l(-.476,.414),l(-.548,.058),l(-.087,.001),l(-.289,-.199),l(-.16,-.484),l(-.399,-.726),l(-.133,-.697),l(.188,-.911),l(.137,-.413),l(.722,-.739),l(.535,-.767),l(-.006,-.326),l(-.544,-1.757),l(.001,-.608),l(.088,-.567),l(-.076,-.438),l(-.528,-.891),l(-.04,-.298),l(.236,-.198),l(.499,.098),l(.182,-.085),l(.2,-.142),l(.097,-.143),l(.41,-1.288),l(.252,-.481),l(.304,-.935),l(.18,-.65),l(.664,-.808),l(.363,-.722),l(.201,-.636),l(.252,-.946),l(.311,-.691),l(.187,-.128),l(.273,-.382),l(.013,-.296),l(-.312,-.847),l(.082,-.184),l(.455,-.452),l(.206,-.339),l(.028,-.24),l(-.093,-.226),l(-.166,-.805),l(-.292,-2.088),l(-.098,-.86),l(.031,-.565),l(.412,-.565),l(.37,-.537),l(.207,-.564),l(.007,-.734),l(-.339,-.521),l(-.098,-.409),l(.295,-.96),l(.218,-.941),l(.127,-.556),l(.461,-.594),l(.171,-.918),l(.243,-.975),l(.126,-.805),l(.082,-.565),l(-.063,-1.087),l(.422,-.664),l(.211,-.494),l(-.221,-.932),l(-.048,-.833),l(.148,-.24),l(-.022,-.917),l(.229,-.607),l(-.124,-.297),l(-.365,-.084),l(.06,-.324),l(-.046,-.396),l(.223,-.198),l(.402,-.198),l(.137,-.424),l(-.008,-.819),l(.093,-.593),l(.182,-.918),l(-.004,-2.344),l(-.172,-2.074),l(-.042,-1.539),l(-.194,-.974),l(-.15,-.387),l(.852,-.275),l(.259,-.298),l(.228,-.933),l(.15,-.199),l(.586,-.187),l(.152,.253),l(.555,.745),l(.304,.647),l(.193,1.213),l(.25,.521),l(.761,.744),l(.017,.282),l(-.437,1.555),l(-.04,.354),l(.249,.676),l(.769,1.11),l(.212,.563),l(.278,.973),l(.397,2.144),l(.272,.182),l(1.047,-.006),l(.107,.056),l(.212,.14),l(.161,.154),l(-.093,.636),l(-.541,1.457),l(-.36,.256),l(-1.346,.53),l(-.819,.372),l(-.204,.312),l(.25,.817),l(-.421,.722),l(-.007,.579),l(.113,.437),l(.34,.449),l(.03,.226),l(-.273,.369),l(-.161,.382),l(.114,.507),l(.53,.477),l(.011,.227),l(-.152,.311),l(-.333,.017),l(-.791,.089),l(-.329,.835),l(-.464,.835),l(-.608,.694),l(-.282,.439),l(-.823,1.839),l(.167,1.466),l(.054,.762),l(-.124,.185),l(-.492,.271),l(-.292,.34),l(-.388,1.201),l(-.156,.961),l(.285,.633),l(.408,1.154),l(.784,2.816),l(.055,.69),l(-.075,.41),l(-1.083,1.854),l(-.319,.595),l(.088,.409),l(.189,1.06),l(-.078,.325),l(-1.334,1.11),l(-.231,.312),l(-.142,1.075),l(.014,1.16),l(.249,1.103),l(.437,.932),l(-.202,.143),l(-.951,.529),l(-.126,.17),l(-.053,.312),l(-.511,2.427),l(-.316,.541),l(-.1,.37),l(.123,1.835),l(.231,.867),l(.012,.427),l(-.596,.317),l(-.172,.172),l(-.106,.271),l(.094,1.226),l(.125,.128),l(.555,.111),l(.088,.655),l(-.191,1.458),l(.252,.585),l(.26,.185),l(.789,.11),l(.302,.17),l(-.007,.186),l(-.245,.202),l(-.322,.13),l(-.726,.033),l(-.757,.146),l(.176,.171),l(.586,.298),l(.552,.385),l(.017,.216),l(-.767,.794),l(-.059,1.094),l(.158,1.035),l(-.216,.896),l(-.212,.434),l(-.226,.262),l(-.598,.161),l(-.28,.219),l(-.249,.781),l(.446,.648),l(-.069,.188),l(-.296,1.218),l(-.307,.263),l(-1.729,1.01),l(-.271,.292),l(-.037,.45),l(.28,1.309),l(.508,1.123),l(.218,.043),l(.961,-.283),l(.654,-.121),l(.187,.248),l(.231,2.285),l(.778,.568),l(.669,.041),l(1.41,-.052),l(2.827,.132),l(.841,.217),l(1.385,.36),l(.286,.039),M(236.642,296.773),l(-.394,-.113),l(-.43,-.028),l(-.21,-.171),l(-.133,-.229),l(.21,-.457),l(.15,-.657),l(-.087,-.514),l(.011,-.414),l(.364,-.728),l(.817,-.116),l(.36,.327),l(.044,.328),l(-.688,.443),l(-.146,.229),l(.493,.771),l(-.194,1.058),l(-.167,.271),M(238.177,317.937),l(-.445,-.177),l(.083,-.842),l(-.849,.075),l(-.073,-.368),l(.218,-.354),l(.823,.102),l(.508,-.207),l(.205,.103),l(.054,.812),l(-.267,.34),l(-.257,.518),M(247.801,322.062),l(-1.033,.102),l(-.467,-.118),l(-.55,-.237),l(-.42,.001),l(-.481,.104),l(-.935,.226),l(-.496,.03),l(.125,-.343),l(.202,-.312),l(-.104,-.312),l(.906,-.15),l(1.434,.058),l(.433,.323),l(.706,-.007),l(-.622,-.689),l(-.307,-.163),l(-.56,-.117),l(-.178,-.089),l(-.188,.03),l(-.338,-.341),l(-.229,-.4),l(1.611,-.581),l(-.044,-.296),l(-.165,-.147),l(-1.819,.285),l(-.292,-.222),l(.263,-.474),l(.146,-.163),l(1.074,-.52),l(.868,-.637),l(.414,.28),l(1.153,.062),l(-.008,1.144),l(-.098,3.675),
+N(456.133,239.67),l(.187,.154),l(.163,.027),l(.154,.169),l(.264,.097),l(-.103,.227),l(.267,.451),l(.43,.478),l(.469,.604),l(.246,.96),l(.377,.662),l(.563,.491),l(.57,.321),l(.533,.223),l(.552,.266),l(.106,.169),l(-.051,.537),l(.109,.211),l(.201,.098),l(.78,-.019),l(.127,.239),l(-.032,.565),l(.163,.564),l(.524,.873),l(.352,.153),l(.938,.136),l(.549,.167),l(.479,.35),l(.306,.451),l(.186,.098),l(-.317,.411),l(-.388,.327),l(-.507,.243),l(-.747,.075),l(-.304,.115),l(-.7,.823),l(-.586,.583),l(-.362,.229),l(-.747,.357),l(-.388,.355),l(-.107,.636),l(-.222,.666),l(-.247,.241),l(-.634,.357),l(-.98,.33),l(-.249,.214),l(-.217,.708),l(-.345,.963),l(-.288,.354),l(-.237,.129),l(-.584,.116),l(-.43,-.026),l(-.473,.06),l(-.511,-.011),l(-.819,-.193),l(-.744,-.32),l(-.979,-.645),l(-.545,-.039),l(-.333,.186),l(-.084,.24),l(-.585,1.134),l(-.382,.469),l(-.651,.625),l(-.632,.428),l(-.8,.372),l(-.823,.033),l(-.854,.047),l(-.368,-.097),l(-.11,-.183),l(.003,-.48),l(.243,-.609),l(.166,-.538),l(-.21,-.762),l(-.547,-.943),l(-.716,-.787),l(-.528,-.067),l(-.007,-.806),l(-.013,-1.624),l(.009,-1.201),l(.106,-2.657),l(.146,-.028),l(1.564,-.052),l(.586,-.046),l(-.002,-3.561),l(.043,-1.201),l(.025,-.876),l(.007,-1.286),l(-.005,-1.215),l(1.183,-.021),l(2.962,-.47),l(1.048,-.134),l(.62,.773),l(.209,-.029),l(.993,-.938),l(.284,-.143),l(.891,-.02),l(.811,-.315),
+N(279.288,257.295),l(.02,.239),l(-.544,1.57),l(-.375,.468),l(-1.007,.74),l(-.301,.27),l(-.352,.51),l(-.609,-.363),l(-.35,-.097),l(-.235,.029),l(-.387,.172),l(-.745,.131),l(-.71,.005),l(-.564,-.096),l(-.992,-.333),l(-.607,-.025),l(-1.187,.332),l(-.19,-.056),l(.064,-.212),l(.425,-.426),l(.486,-.398),l(.11,-.198),l(-.21,-.619),l(.048,-.227),l(.625,-.851),l(.617,-1.203),l(.018,-.268),l(-.939,-.503),l(-.65,-.18),l(-1.448,-.697),l(-1.632,-1.106),l(-.671,-.307),l(-1.173,-.204),l(-.498,-.237),l(-.835,-.588),l(-.576,-.562),l(-1.271,-1.376),l(-.782,-.913),l(-.225,-.337),l(-.19,-.056),l(.149,-.325),l(.395,-1.104),l(.385,-1.188),l(-.016,-.635),l(.133,-.509),l(.278,-.341),l(.698,-1.105),l(.332,-.383),l(.33,-.044),l(.784,-.202),l(1.104,-.162),l(1.076,-.204),l(.126,-.128),l(.843,.01),l(.928,-.02),l(.352,.054),l(1.952,.991),l(.089,.084),l(.253,.408),l(.084,.663),l(.521,.872),l(.104,.959),l(-.132,.862),l(-.086,.721),l(-.006,.72),l(.372,.04),l(.818,.15),l(.925,.221),l(.346,-.03),l(.709,-.413),l(.115,-.001),l(.724,.278),l(.843,.404),l(.121,.437),l(.487,2.524),l(.254,.563),l(.224,.055),l(1.29,-.445),l(.234,.112),l(.491,.336),l(.019,.141),l(-.321,.75),l(-.298,.835),l(-.222,.819),l(-.027,.777),l(.063,.423),
+N(444.673,255.519),l(.528,.067),l(.716,.787),l(.547,.943),l(.21,.762),l(-.166,.538),l(-.243,.609),l(-.003,.48),l(.11,.183),l(.368,.097),l(.854,-.047),l(.823,-.033),l(.8,-.372),l(.632,-.428),l(.651,-.625),l(.382,-.469),l(.585,-1.134),l(.084,-.24),l(.333,-.186),l(.545,.039),l(.979,.645),l(.744,.32),l(.819,.193),l(.511,.011),l(.473,-.06),l(.43,.026),l(.584,-.116),l(.237,-.129),l(.288,-.354),l(.345,-.963),l(.217,-.708),l(.249,-.214),l(.98,-.33),l(.634,-.357),l(.247,-.241),l(.222,-.666),l(.107,-.636),l(.388,-.355),l(.747,-.357),l(.362,-.229),l(.586,-.583),l(.7,-.823),l(.304,-.115),l(.747,-.075),l(.507,-.243),l(.388,-.327),l(.317,-.411),l(.067,.042),l(.72,.023),l(.597,.139),l(.99,.403),l(.31,-.016),l(.529,-.145),l(.442,.025),l(.547,.124),l(.342,.225),l(.159,.183),l(.295,1.199),l(.181,.946),l(.441,.689),l(.33,.944),l(.147,.678),l(.072,.763),l(-.057,1.301),l(-.03,.806),l(.095,.324),l(-1.449,-.585),l(-.279,.199),l(-.657,.979),l(-.28,.567),l(-.005,.325),l(.39,.676),l(.307,.465),l(.458,.322),l(.671,.109),l(.595,-.004),l(.076,-.594),l(.064,-.198),l(.312,-.186),l(.131,-.015),l(.192,-.058),l(1.331,-.011),l(-.182,1.195),l(-.352,.849),l(-.182,.184),l(-.404,.1),l(-.093,.24),l(.199,.536),l(-.104,.467),l(-.248,.354),l(-.569,.453),l(-.923,.581),l(-.591,.75),l(-1.383,1.98),l(-.631,.834),l(-1.242,1.373),l(-1.193,1.062),l(-.829,.863),l(-1.434,1.034),l(-1.379,1.091),l(-.552,.382),l(-.989,.638),l(-.676,.298),l(-.782,.101),l(-.98,-.012),l(-.549,.071),l(-.132,.354),l(.013,.127),l(-.109,.085),l(-.449,-.098),l(-.553,-.126),l(-.303,.015),l(-.25,.198),l(-.272,.312),l(-.226,.113),l(-.36,-.056),l(-.768,-.408),l(-.759,-.168),l(-.542,-.013),l(-.31,.113),l(-.38,.27),l(-.482,-.099),l(-.645,-.21),l(-.295,.1),l(-.638,.043),l(-.589,.214),l(-.729,.538),l(-.72,.086),l(-.44,-.013),l(-.667,-.084),l(-.738,.072),l(-.575,.199),l(-.827,.82),l(-1.251,-.576),l(-.092,-.509),l(-.218,-.183),l(-.479,-.056),l(-.28,.085),l(-.257,-.479),l(-.343,-.056),l(-.149,.255),l(-.035,.197),l(-.312,-.112),l(-.119,-.226),l(.267,-.495),l(.103,-.424),l(-.857,-1.354),l(-.323,-.282),l(-.134,-.226),l(.173,-.17),l(.636,-.044),l(.172,-.424),l(.06,-.819),l(-.163,-.663),l(-.186,-.522),l(-.61,-1.143),l(-.75,-1.029),l(-.472,-.903),l(-.612,-1.383),l(-.646,-1.467),l(-.573,-.818),l(-.436,-.467),l(.152,-.068),l(.584,-.27),l(.317,-.416),l(.109,-.217),l(.335,-.116),l(.329,.127),l(.637,.348),l(.193,.222),l(.042,.345),l(.055,.528),l(.296,.212),l(.517,.039),l(.892,-.048),l(.745,.042),l(.581,.166),l(.427,-.034),l(.581,-.498),l(.545,-.302),l(.454,-.318),l(.057,-.205),l(-.025,-2.246),l(-.031,-1.894),l(.006,-3.434),M(462.462,268.501),l(.412,-.044),l(.194,-.553),l(.633,-.343),l(1.035,-.303),l(.263,-.199),l(.582,-1.007),l(.268,-.326),l(.143,-.241),l(-.104,-.226),l(-.967,-.744),l(-.33,-.337),l(-.422,-.266),l(-.308,.086),l(-.995,.359),l(-.65,.329),l(-.513,.567),l(-.275,.44),l(-.691,.611),l(.12,.409),l(.582,.858),l(.285,.366),l(.739,.561),M(432.955,250.661),l(.456,.006),l(.077,.749),l(-.04,.678),l(-.772,.02),l(-.078,-.354),l(-.028,-.396),l(.285,-.297),l(.101,-.406),
+N(471.719,258.047),l(.075,.296),l(-.071,.495),l(.261,.889),l(.068,.382),l(-.131,.015),l(-.312,.186),l(-.064,.198),l(-.076,.594),l(-.595,.004),l(-.671,-.109),l(-.458,-.322),l(-.307,-.465),l(-.39,-.676),l(.005,-.325),l(.28,-.567),l(.657,-.979),l(.279,-.199),l(1.449,.585),
+N(462.462,268.501),l(-.739,-.561),l(-.285,-.366),l(-.582,-.858),l(-.12,-.409),l(.691,-.611),l(.275,-.44),l(.513,-.567),l(.65,-.329),l(.995,-.359),l(.308,-.086),l(.422,.266),l(.33,.337),l(.967,.744),l(.104,.226),l(-.143,.241),l(-.268,.326),l(-.582,1.007),l(-.263,.199),l(-1.035,.303),l(-.633,.343),l(-.194,.553),l(-.412,.044),
+N(790.15,283.022),l(.738,.197),l(.008,-.227),l(-.242,-.524),l(.052,-.284),l(.233,.014),l(.389,.17),l(.37,.751),l(.277,.964),l(.48,.17),l(1.753,.691),l(.506,.113),l(.37,-.072),l(.699,-.483),l(.885,-.343),l(.4,.027),l(.329,.17),l(.066,.454),l(-.022,.198),l(-.402,1.236),l(-.283,.072),l(-.761,.058),l(-.035,.683),l(-.124,.156),l(-.424,.029),l(-.746,.016),l(-.432,.2),l(-.271,.284),l(.041,.384),l(.254,.525),l(-.002,.213),l(-.151,.199),l(-.646,.515),l(-.898,1.129),l(-.847,1.058),l(-.756,.587),l(-.68,.316),l(-.337,-.171),l(-.47,-.313),l(-.237,-.328),l(.056,-.314),l(.288,-.386),l(.307,-.671),l(.398,-.5),l(-.031,-.343),l(-.271,-.128),l(-.761,-.582),l(-.421,-.185),l(-.593,-.184),l(-.98,-.452),l(-.306,-.256),l(-.11,-.17),l(.081,-.128),l(.419,-.157),l(1.389,-.685),l(.209,-.512),l(-.078,-.695),l(.087,-.312),l(.396,-.441),l(.032,-.383),l(-.482,-.837),l(.081,-.567),l(-.156,-.311),l(-.479,-.655),l(-.574,-.678),l(.102,-.164),l(-.145,-.304),l(-.291,-.351),l(-.336,-.188),l(-.29,-.163),l(.117,.233),l(.497,.515),l(.049,.141),l(-.169,0),l(-.211,-.281),l(-.525,-.631),l(-.622,-.771),l(-.518,-.561),l(.001,-.117),l(-.268,-.257),l(.04,-.141),l(.013,-.14),l(-.048,-.188),l(-.197,-.396),l(-.379,-.42),l(-.347,-.257),l(.163,-.046),l(.205,.093),l(.358,-.047),l(.131,-.093),l(.084,.28),l(-.149,.187),l(.186,.303),l(.177,.21),l(.167,.116),l(.228,.164),l(.041,-.141),l(.269,.023),l(.519,.257),l(.42,.117),l(.274,.07),l(.128,.257),l(-.011,.141),l(.185,.023),l(.146,-.188),l(.185,.023),l(-.022,.164),l(.227,.351),l(.249,.187),l(.233,.28),l(-.18,.023),l(-.076,.164),l(.093,.163),l(-.242,-.023),l(-.175,-.047),l(.143,.117),l(.251,.188),l(.23,.233),l(.352,.28),l(.063,.234),l(.019,.21),l(-.261,-.047),l(.096,.164),l(.239,.351),l(.256,.188),l(-.292,.023),l(-.226,0),l(-.205,-.047),l(-.006,.141),l(.306,.14),l(.324,.164),l(-.09,.211),l(.205,.046),l(.265,-.023),l(.226,0),l(.223,.141),l(-.114,.07),l(-.031,.141),l(.025,.141),l(.136,.06),M(782.939,297.694),l(-.088,.158),l(-.558,.13),l(-.309,.288),l(-.322,.101),l(-.246,.244),l(-.692,-.242),l(-.16,.086),l(.15,.216),l(.429,.415),l(-.141,.173),l(.02,.259),l(-.064,.431),l(-.218,-.071),l(-.976,-.099),l(.418,.229),l(.449,.244),l(-.278,.49),l(-.427,.896),l(-.212,.549),l(-.418,.318),l(-.673,.349),l(-.171,.246),l(-.259,.145),l(-.581,.233),l(-.593,.406),l(-.398,.015),l(-1.156,-.258),l(-.628,.112),l(-.585,-.442),l(-.812,-.158),l(-.373,-.066),l(-.162,-.308),l(-.467,-.098),l(-.24,.142),l(-.062,.168),l(-.78,.095),l(-.214,-.166),l(-.515,-.095),l(-.146,-.286),l(.432,-.089),l(-.223,-.216),l(.328,-.116),l(.322,-.001),l(-.452,-.482),l(.82,.266),l(-.464,-.576),l(.121,-.145),l(.946,.156),l(.082,-.13),l(-.141,-.173),l(-.201,-.216),l(-.06,-.288),l(.283,-.303),l(.569,-.246),l(.328,-.374),l(.561,-.375),l(.102,-.302),l(.998,-.575),l(1.106,-.275),l(.713,-.331),l(.544,-.36),l(.377,-.101),l(.685,-.575),l(.066,-.272),l(.48,-.302),l(.373,-.015),l(.787,-.331),l(.664,-.402),l(.126,-.215),l(-.008,-.172),l(.266,-.144),l(.448,-.302),l(-.109,-.501),l(.076,-.214),l(.166,-.44),l(.306,.048),l(.066,-.152),l(.58,-.259),l(.444,-.272),l(.137,-.285),l(.131,-1.187),l(.512,-.647),l(.372,.047),l(.365,.165),l(.032,.259),l(.337,.06),l(.187,.186),l(.231,.799),l(.312,.242),l(.973,-.645),l(.426,-.029),l(.367,.113),l(.222,.5),l(-.197,.399),l(.299,.429),l(.066,.271),l(-.611,.659),l(-.261,.401),l(-.476,.358),l(-.868,.746),l(-.578,.359),l(-.295,.13),l(-.236,.258),l(-.389,.159),l(-.271,.258),l(.416,.407),l(.428,.047),l(.421,.289),l(-.276,.113),l(-.484,.07),l(-.503,-.296),l(-.488,.131),l(-.352,.158),
+N(247.899,318.387),l(.008,-1.144),l(.821,.289),l(.06,.206),l(-.354,.312),l(-.534,.337),M(248.453,316.576),l(-.286,-.039),l(-1.385,-.36),l(-.841,-.217),l(-2.827,-.132),l(-1.41,.052),l(-.669,-.041),l(-.778,-.568),l(-.231,-2.285),l(-.187,-.248),l(-.654,.121),l(-.961,.283),l(-.218,-.043),l(-.508,-1.123),l(-.28,-1.309),l(.037,-.45),l(.271,-.292),l(1.729,-1.01),l(.307,-.263),l(.296,-1.218),l(.069,-.188),l(-.446,-.648),l(.249,-.781),l(.28,-.219),l(.598,-.161),l(.226,-.262),l(.212,-.434),l(.216,-.896),l(-.158,-1.035),l(.059,-1.094),l(.767,-.794),l(-.017,-.216),l(-.552,-.385),l(-.586,-.298),l(-.176,-.171),l(.757,-.146),l(.726,-.033),l(.322,-.13),l(.245,-.202),l(.007,-.186),l(-.302,-.17),l(-.789,-.11),l(-.26,-.185),l(-.252,-.585),l(.191,-1.458),l(-.088,-.655),l(-.555,-.111),l(-.125,-.128),l(-.094,-1.226),l(.106,-.271),l(.172,-.172),l(.596,-.317),l(-.012,-.427),l(-.231,-.867),l(-.123,-1.835),l(.1,-.37),l(.316,-.541),l(.511,-2.427),l(.053,-.312),l(.126,-.17),l(.951,-.529),l(.202,-.143),l(-.437,-.932),l(-.249,-1.103),l(-.014,-1.16),l(.142,-1.075),l(.231,-.312),l(1.334,-1.11),l(.078,-.325),l(-.189,-1.06),l(-.088,-.409),l(.319,-.595),l(1.083,-1.854),l(.075,-.41),l(-.055,-.69),l(-.784,-2.816),l(-.408,-1.154),l(-.285,-.633),l(.156,-.961),l(.388,-1.201),l(.292,-.34),l(.492,-.271),l(.124,-.185),l(-.054,-.762),l(-.167,-1.466),l(.823,-1.839),l(.282,-.439),l(.608,-.694),l(.464,-.835),l(.329,-.835),l(.791,-.089),l(.333,-.017),l(.152,-.311),l(-.011,-.227),l(-.53,-.477),l(-.114,-.507),l(.161,-.382),l(.273,-.369),l(-.03,-.226),l(-.34,-.449),l(-.113,-.437),l(.007,-.579),l(.421,-.722),l(-.25,-.817),l(.204,-.312),l(.819,-.372),l(1.346,-.53),l(.36,-.256),l(.541,-1.457),l(.093,-.636),l(-.161,-.154),l(-.212,-.14),l(-.107,-.056),l(2.026,-2.087),l(.292,-.27),l(.322,.181),l(.193,.169),l(.615,.194),l(.901,-.034),l(.527,-.045),l(.531,.067),l(.37,.195),l(.341,.309),l(.416,1.084),l(1.034,-1.784),l(.686,-.004),l(1.33,.077),l(.592,.109),l(.19,.056),l(.225,.337),l(.782,.913),l(1.271,1.376),l(.576,.562),l(.835,.588),l(.498,.237),l(1.173,.204),l(.671,.307),l(1.632,1.106),l(1.448,.697),l(.65,.18),l(.939,.503),l(-.018,.268),l(-.617,1.203),l(-.625,.851),l(-.048,.227),l(.21,.619),l(-.11,.198),l(-.486,.398),l(-.425,.426),l(-.064,.212),l(.19,.056),l(1.187,-.332),l(.607,.025),l(.992,.333),l(.564,.096),l(.71,-.005),l(.745,-.131),l(.387,-.172),l(.235,-.029),l(.35,.097),l(.609,.363),l(.352,-.51),l(.301,-.27),l(1.007,-.74),l(.375,-.468),l(.544,-1.57),l(-.02,-.239),l(.957,-.161),l(.462,-.017),l(.206,.196),l(.517,1.154),l(-.094,1.638),l(-.161,.467),l(-.521,.313),l(-1.754,.744),l(-.348,.242),l(-1.633,1.448),l(-1.435,1.363),l(-1.805,1.816),l(-.833,.88),l(-.214,.27),l(-.443,.524),l(-.065,.452),l(-.595,2.359),l(-.103,.522),l(.049,.847),l(.168,.986),l(-.118,.325),l(-.48,.524),l(-.24,.495),l(-.011,.522),l(.194,.577),l(-.054,.338),l(-.162,.273),l(-.26,.325),l(.015,.226),l(.924,.831),l(.68,.281),l(.715,.281),l(.283,.169),l(.281,.325),l(-.025,.325),l(-.362,.523),l(-.043,.396),l(.105,.339),l(.174,.269),l(.466,.325),l(.522,.168),l(.109,.113),l(.226,.892),l(-.308,.481),l(-.75,.937),l(-.729,.766),l(-.313,.737),l(-.368,.284),l(-.832,.342),l(-1.04,.342),l(-1.92,.401),l(-1.795,.188),l(-1.361,.116),l(-.945,.044),l(-1.175,-.11),l(-.934,-.226),l(-.128,.199),l(.036,.808),l(.322,.312),l(.308,.184),l(-.09,.298),l(-.381,.624),l(-.345,.498),l(-.069,.385),l(.392,.682),l(.066,.285),l(-.208,.214),l(-.105,.057),l(-1.251,.473),l(-1.137,.116),l(-.814,-.069),l(-.967,-.34),l(-1.47,-.396),l(-.246,.057),l(-.23,.271),l(.041,.598),l(.429,.684),l(.037,.398),l(-.242,.643),l(.092,.385),l(.773,.54),l(.796,.084),l(.369,-.2),l(-.387,-.398),l(.872,-.188),l(.383,-.043),l(.234,1.041),l(.052,.3),l(-.144,.157),l(-.299,.101),l(-.448,.072),l(-.261,-.157),l(-.104,-.299),l(-.115,-.071),l(-1.046,.073),l(-.67,.201),l(-.212,.101),l(.151,.214),l(.591,.07),l(.47,.113),l(.452,.113),l(.06,.028),l(-.864,.388),l(-.776,.287),l(-.577,.602),l(.003,.414),l(.161,.787),l(-.081,.258),l(-.815,.817),l(.022,.215),l(.423,.371),l(-.491,.116),l(-1.194,.088),l(-.48,.087),l(-.632,.246),l(-.619,.389),l(-.56,.548),l(-.549,.821),l(-.052,.389),l(.061,.375),l(.312,.591),l(.48,.446),l(.98,.633),l(.657,.244),l(.97,.143),l(.362,.086),l(.14,.274),l(-.151,.796),l(-.128,.348),l(-.342,.464),l(-.189,.145),l(-1.08,.524),l(-1.541,.814),l(-.712,.698),l(-.179,.276),l(-.093,.45),l(.111,.523),l(-.169,.451),l(-.239,.32),l(-.97,.454),l(-.969,.25),l(-.421,.221),l(-.323,.396),l(-.226,.791),l(-.054,.514),l(.2,.777),l(.547,.896),l(.699,.779),l(.235,.339),l(-.101,.032),M(247.899,318.387),l(.18,.182),l(.148,.073),l(.607,-.075),l(.344,.133),l(.648,.725),l(.908,.665),l(.993,.756),l(.525,.222),l(.73,.37),l(.246,.074),l(.42,-.001),l(.483,.163),l(1.283,.027),l(.142,-.016),l(-.006,.224),l(-.19,.209),l(-.492,.06),l(-1.198,.092),l(-.777,.196),l(-.364,0),l(-1.179,-.355),l(-.753,-.088),l(-1.15,-.027),l(-.814,-.014),l(-.831,.081),l(.098,-3.675),
+N(346.758,54.457),l(.127,-.162),l(.42,-.179),l(.894,.015),l(.674,-.098),l(-.354,-.227),l(-.405,-.34),l(.317,-.342),l(.277,0),l(.956,.42),l(.67,.048),l(.3,-.163),l(-.191,-.26),l(-.625,-.373),l(.366,-.245),l(1.037,.226),l(.957,.08),l(.746,.275),l(.446,.551),l(-.119,.405),l(-.441,.292),l(.922,.806),l(.553,-.356),l(.352,-.13),l(.63,-.114),l(.49,-.179),l(.061,-.21),l(-.169,-.778),l(.542,-.245),l(.501,.454),l(.426,.307),l(.489,.209),l(.215,.016),l(.185,-.13),l(-.264,-.454),l(.243,-.163),l(.27,-.033),l(.817,-.164),l(.683,.438),l(.536,.242),l(.542,.063),l(.05,-.178),l(-.358,-.535),l(1.006,.145),l(1.439,.079),l(.787,-.115),l(.427,-.229),l(-.021,-.716),l(1.167,.08),l(.635,.471),l(1.118,.323),l(.683,.015),l(.273,.243),l(-.252,.552),l(.786,.29),l(1.674,.159),l(.127,.145),l(.143,.548),l(-.07,.387),l(-.152,.256),l(-.152,.256),l(-.443,.129),l(-.815,.018),l(-.195,.096),l(-.04,.431),l(-.515,.463),l(-.497,.16),l(-.568,-.031),l(-.422,-.159),l(-.817,.495),l(-.539,.144),l(-1.46,.463),l(-.853,.113),l(-.726,.001),l(-.771,.097),l(-.784,.587),l(-.473,.127),l(-1.078,.097),l(-.709,-.03),l(-1.316,-.171),l(-.608,-.142),l(-1.283,-.489),l(-1.058,-.093),l(-.443,.064),l(-1.041,-.014),l(-1.834,-.124),l(-.297,-.206),l(.434,-.191),l(1.127,-.352),l(.701,-.59),l(-.818,-.015),l(-.51,-.126),l(-.428,-.398),l(-.253,-.095),l(-.358,.081),l(-1.564,.115),l(-.557,.033),l(-.37,-.223),l(.141,-.192),l(.388,-.129),l(.669,-.097),l(.794,-.017),l(.729,-.114),l(1.049,-.098),l(.376,-.194),l(.178,-.322),l(-.144,-.258),l(-.358,-.177),l(-.426,-.015),l(-.478,-.145),l(-1.005,-.047),l(-.821,.099),l(-.424,.162),l(-.676,.082),l(-1.041,-.272),l(-.16,-.21),
+N(462.829,67.958),l(.145,.053),l(.16,.131),l(-.043,.174),l(-.175,.044),l(-.189,0),l(-.116,0),l(-.088,.043),l(-.058,.131),l(-.175,.277),l(-.219,.204),l(-.319,.131),l(-.204,.131),l(-.088,.16),l(.029,.16),l(.131,.437),l(.073,.189),l(.029,.16),l(-.175,.131),l(0,.175),l(.175,.233),l(.203,.087),l(.088,.073),l(0,.073),l(.015,.087),l(.043,.146),l(.175,.043),l(.059,.059),l(-.175,.073),l(-.262,.043),l(-.16,.058),l(-.059,.102),l(-.087,.116),l(-.131,0),L(461.402,72),l(-.015,.087),l(-.116,.058),l(.081,.106),l(-.125,.025),l(-.087,-.015),l(-.306,-.043),l(-.16,-.058),l(-.175,-.073),l(-.204,-.044),l(-.131,.102),l(-.204,-.029),l(-.131,.044),l(-.16,.087),l(-.146,.014),l(-.146,-.087),l(-.116,-.029),l(-.175,0),l(-.204,-.117),l(-.116,-.174),l(-.203,-.117),l(-.146,-.043),l(-.072,-.117),l(-.189,0),l(-.247,-.043),l(-.204,-.117),l(-.029,0),l(-.276,-.014),l(-.102,-.102),l(-.248,-.043),l(-.116,-.102),l(-.189,-.087),l(0,.073),l(-.116,.087),l(-.131,-.058),l(-.015,-.073),l(-.087,-.029),l(-.103,0),l(-.276,.117),l(-.102,.029),l(-.131,.015),l(-.219,.015),l(-.146,.043),l(-.262,.029),l(-.276,.087),l(-.116,.102),l(-.087,0),l(.156,-.19),l(-.003,-.351),l(.183,-.238),l(-.368,-.21),l(-.605,.437),l(-.334,-.251),l(-.527,-.038),l(.043,-.942),l(-.396,.188),l(-.336,-.415),l(.158,-.202),l(-.209,-.254),l(.265,-.074),l(-.092,-.252),l(.344,-.042),l(1.026,-.084),l(-.006,-.132),l(.561,-.108),l(.133,-.188),l(.436,.101),l(.074,-.113),l(.317,.05),l(.083,-.215),l(1.104,.193),l(.446,-.294),l(.091,.165),l(.514,-.089),l(1.383,.029),l(1.152,.167),l(.305,.12),l(.592,-.045),l(.971,.09),l(.426,-.108),l(.271,-.24),l(-.006,-.009),
+N(461.353,72.251),l(.37,-.004),l(-.015,.116),l(0,.117),l(.232,.073),l(.204,.087),l(.087,.073),l(.204,.058),l(-.015,.087),l(-.029,.116),l(-.015,.087),l(-.102,.073),l(-.087,.015),l(-.103,.029),l(.131,.087),l(-.072,.131),l(.029,.117),l(-.073,.087),l(-.102,.073),l(-.044,.102),l(.204,-.059),l(.146,-.015),l(.131,.073),l(.087,.014),l(.073,.044),l(-.059,.087),l(-.043,.073),l(.116,.102),l(.131,.058),l(.029,.16),l(.146,.102),l(.16,.043),l(-.059,.087),l(.131,.117),l(-.015,.189),l(.088,.233),l(-.044,.087),l(-.015,.117),l(-.061,.042),l(-.241,.044),l(-.24,.051),l(-.12,.12),l(-.223,.034),l(-.137,.154),l(-.137,.085),l(-.069,.103),l(-.068,.206),l(-.188,.035),l(-.239,-.035),l(-.24,-.034),l(-.325,-.034),l(-.359,0),l(-.172,.068),l(-.103,.137),l(-.223,.085),l(-.154,0),l(-.103,-.017),l(-.086,.052),l(-.377,-.035),l(-.273,-.068),l(-.154,-.171),l(-.138,-.154),l(-.325,-.137),l(-.497,-.223),l(-.342,-.24),l(-.377,-.034),l(-.583,-.035),l(-.325,-.12),l(-.291,-.188),l(-.086,-.257),l(-.188,.017),l(-.171,.068),l(-.36,.171),l(-.394,.017),l(-.24,0),l(-.273,.085),l(-.24,-.085),l(-.309,-.103),l(-.6,-.017),l(-.291,.069),l(-.359,-.069),l(-.291,-.051),l(-.154,.034),l(-.274,.069),l(-.103,-.052),l(-.12,-.137),l(-.154,0),l(-.257,.068),l(-.188,0),l(-.754,-.017),l(-.445,-.085),l(-.754,.171),l(-.599,.154),l(-.429,.103),l(-.257,.137),l(-.052,.188),l(-.526,.026),l(-.065,-.059),l(.073,-.837),l(.035,-.302),l(.127,-.167),l(.672,-.379),l(.034,-.717),l(.267,-.162),l(.267,-.273),l(.217,-.203),l(.296,-.026),l(1.056,-.199),l(.166,-.046),l(.162,-.066),l(.29,0),l(.049,.237),l(.657,.388),l(.422,.162),l(.23,.473),l(.091,.15),l(.441,.196),l(.785,.059),l(.868,-.244),l(.24,-.122),l(.178,-.288),l(-.052,-.394),l(-.193,-.869),l(.198,-.243),l(.045,-.055),l(.087,0),l(.116,-.102),l(.276,-.087),l(.262,-.029),l(.146,-.043),l(.219,-.015),l(.131,-.015),l(.102,-.029),l(.276,-.117),l(.103,0),l(.087,.029),l(.015,.073),l(.131,.058),l(.116,-.087),l(0,-.073),l(.189,.087),l(.116,.102),l(.248,.043),l(.102,.102),l(.276,.014),l(.029,0),l(.204,.117),l(.247,.043),l(.189,0),l(.072,.117),l(.146,.043),l(.203,.117),l(.116,.174),l(.204,.117),l(.175,0),l(.116,.029),l(.146,.087),l(.146,-.014),l(.16,-.087),l(.131,-.044),l(.204,.029),l(.131,-.102),l(.204,.044),l(.175,.073),l(.16,.058),l(.306,.043),l(.087,.015),l(.125,-.025),
+N(451.02,79.165),l(-.029,-.038),l(-.034,-.137),l(-.018,-.171),l(.068,-.206),l(.068,-.154),l(.224,-.12),l(-.052,-.12),l(-.018,-.137),l(-.171,-.069),l(-.188,-.034),l(-.103,-.103),l(-.086,-.137),l(-.223,.017),l(-.257,0),l(-.445,0),l(-.223,.051),l(-.086,-.103),l(-.514,-.068),l(-.257,-.069),l(-.223,-.12),l(-.24,0),l(-.086,-.052),l(-.051,-.154),l(-.12,.034),l(-.353,.096),l(-.043,-.077),l(.128,-.012),l(.034,-.183),l(-.439,-.646),l(-.008,-.14),l(-.042,-.727),l(-.112,-.102),l(.526,-.026),l(.052,-.188),l(.257,-.137),l(.429,-.103),l(.599,-.154),l(.754,-.171),l(.445,.085),l(.754,.017),l(.188,0),l(.257,-.068),l(.154,0),l(.12,.137),l(.103,.052),l(.274,-.069),l(.154,-.034),l(.291,.051),l(.359,.069),l(.291,-.069),l(.6,.017),l(.309,.103),l(.24,.085),l(.273,-.085),l(.24,0),l(.394,-.017),l(.36,-.171),l(.171,-.068),l(.188,-.017),l(.086,.257),l(.291,.188),l(.325,.12),l(.583,.035),l(.377,.034),l(.342,.24),l(.497,.223),l(.325,.137),l(.138,.154),l(.154,.171),l(.273,.068),l(.377,.035),l(-.017,.171),l(-.086,.154),l(-.034,.12),l(-.12,.137),l(-.086,.137),l(.343,.034),l(.274,.052),l(.085,.051),l(-.119,.051),l(-.086,0),l(-.103,.154),l(-.018,.154),l(-.171,.017),l(-.12,-.086),l(-.12,.051),l(-.239,-.034),l(-.154,.034),l(-.086,.154),l(-.103,.154),l(-.257,.068),l(-.429,0),l(-.137,.137),l(-.12,.12),l(-.034,.154),l(-.086,.171),l(.103,.171),l(-.068,.137),l(-.239,.154),l(0,.137),l(-.068,.085),l(-.069,.137),l(.172,.034),l(.205,0),l(.138,.206),l(-.086,.188),l(-.274,.017),l(-.223,-.068),l(0,-.154),l(-.034,-.085),l(-.086,-.069),l(-.171,.051),l(-.12,.086),l(-.291,-.034),l(-.068,.137),l(-.24,.12),l(-.154,0),l(-.188,-.034),l(-.273,.103),l(.086,.171),l(-.069,.12),l(-.171,.034),l(-.137,-.034),l(-.206,.051),l(-.377,.154),l(-.291,0),l(-.068,-.103),l(-.12,-.051),l(-.239,.051),l(-.377,.017),l(-.24,.034),l(-.291,-.034),l(-.154,.034),l(-.093,-.035),l(-.09,-.171),l(-.016,-.029),l(-.099,-.186),l(-.284,-.487),l(-.679,-.243),l(-.04,-.014),l(-.641,.021),
+N(452.867,80.273),l(.093,.035),l(.154,-.034),l(.291,.034),l(.24,-.034),l(.377,-.017),l(.239,-.051),l(.12,.051),l(.068,.103),l(.291,0),l(.377,-.154),l(.206,-.051),l(.137,.034),l(.171,-.034),l(.069,-.12),l(-.086,-.171),l(.273,-.103),l(.188,.034),l(.154,0),l(.24,-.12),l(.068,-.137),l(.291,.034),l(.12,-.086),l(.171,-.051),l(.086,.069),l(.034,.085),l(0,.154),l(.223,.068),l(.274,-.017),l(.086,-.188),l(-.138,-.206),l(-.205,0),l(-.172,-.034),l(.069,-.137),l(.068,-.085),l(0,-.137),l(.239,-.154),l(.068,-.137),l(-.103,-.171),l(.086,-.171),l(.034,-.154),l(.12,-.12),l(.137,-.137),l(.429,0),l(.257,-.068),l(.103,-.154),l(.086,-.154),l(.154,-.034),l(.239,.034),l(.12,-.051),l(.12,.086),l(.171,-.017),l(.018,-.154),l(.103,-.154),l(.086,0),l(.119,-.051),l(-.085,-.051),l(-.274,-.052),l(-.343,-.034),l(.086,-.137),l(.12,-.137),l(.034,-.12),l(.086,-.154),l(.017,-.171),l(.086,-.052),l(.103,.017),l(.154,0),l(.223,-.085),l(.103,-.137),l(.172,-.068),l(.359,0),l(.325,.034),l(.24,.034),l(.239,.035),l(.188,-.035),l(.068,-.206),l(.069,-.103),l(.137,-.085),l(.137,-.154),l(.223,-.034),l(.12,-.12),l(.24,-.051),l(.241,-.044),l(.165,.147),l(.229,.066),l(.197,-.131),l(.181,.016),l(.312,.033),l(.132,.148),l(.082,.148),l(.197,-.033),l(.214,-.065),l(.361,-.049),l(.312,.049),l(.296,.065),l(.147,.017),l(0,.115),l(-.164,.099),l(-.017,.099),l(.065,.148),l(.164,.148),l(.197,0),l(.214,-.197),l(.279,-.016),l(.165,0),l(.147,-.099),l(.23,-.083),l(.131,.049),l(.099,.049),l(.247,-.049),l(.542,.115),l(.132,.131),l(.279,.099),l(.099,.099),l(.147,.099),l(.165,.033),l(.147,-.033),l(.049,.115),l(-.065,.115),l(0,.083),l(-.033,.164),l(-.131,.165),l(.197,.247),l(.147,.099),l(.05,.164),l(-.066,.131),l(-.114,0),l(0,.083),l(-.115,.082),l(-.099,.049),l(-.033,.165),l(-.049,.147),l(.345,.049),l(.132,.181),l(.082,.115),l(.181,-.049),l(.132,.033),l(-.099,.115),l(-.066,.131),l(.017,.099),l(.214,.017),l(.164,.263),l(.115,.23),l(.443,.213),l(.23,.066),l(.279,.082),l(.164,.099),l(.066,.148),l(-.099,.197),l(-.066,.181),l(.182,.066),l(.361,-.066),l(.378,.066),l(.361,.099),l(.263,.066),l(-.032,.065),l(-.066,.049),l(-.082,.017),l(.099,.181),l(.296,.148),l(.279,.066),l(.033,.131),l(-.065,.164),l(-.296,0),l(-.148,.083),l(-.049,.065),l(-.444,.247),l(-.525,.099),l(-.51,-.016),l(-.197,-.132),l(-.328,-.049),l(-.362,.017),l(-.131,.165),l(-.099,.131),l(.017,.164),l(.279,.263),l(.296,.164),l(0,.165),l(-.132,.066),l(.099,.148),l(.147,.131),l(-.082,.099),l(.033,.164),l(.033,.23),l(-.033,.099),l(.164,.082),l(.082,.115),l(.165,.066),l(.002,.142),l(-.519,-.005),l(-.522,.056),l(-.112,.131),l(-.205,-.056),l(-.187,-.037),l(-.336,.075),l(-.057,.13),l(-.111,.112),l(-.317,.187),l(-.188,.261),l(-.261,.224),l(-.057,.206),l(.243,.205),l(.056,.149),l(-.131,.206),l(-.261,-.019),l(-.149,-.056),l(-.149,-.206),l(-.112,-.056),l(-.187,-.075),l(-.224,-.037),l(-.225,.037),l(-.242,.075),l(-.299,.019),l(-.149,-.131),l(-.224,.075),l(-.188,.093),l(-.316,.056),l(-.188,-.056),l(-.037,-.205),l(-.112,-.131),l(-.168,-.131),l(-.13,.038),l(-.131,.075),l(-.168,0),l(-.299,.149),l(-.131,.149),l(-.168,0),l(-.094,-.187),l(-.13,-.075),l(-.206,0),l(-.224,.112),l(-.131,-.187),l(-.224,-.093),l(-.131,.112),l(-.354,.056),l(-.262,-.112),l(-.112,0),l(-.019,.205),l(-.168,.093),l(-.093,-.056),l(.056,-.224),l(-.243,-.038),l(-.187,-.056),l(-.541,.112),l(0,-.149),l(-.187,0),l(.019,-.224),l(-.28,-.037),l(-.242,.075),l(-.523,-.112),l(-.578,-.056),l(-.075,-.056),l(-.522,0),l(-.205,-.168),l(-.262,.019),l(-.522,-.093),l(-.467,.075),l(-.485,0),l(-.354,-.056),l(-.355,.056),l(-.354,.056),l(-.485,-.038),l(-.485,.019),l(-.205,.187),l(-.037,.168),l(-.374,.168),l(-.373,.206),l(-.112,-.112),l(-.261,0),l(-.374,-.019),l(-.037,.131),l(0,.045),l(-.126,-.137),l(.315,-.752),l(-.013,-.25),l(-.218,-.146),l(-.149,-.176),l(-.421,-.146),l(-.289,-.012),l(.128,-.292),l(.291,-.328),l(.571,-.244),l(.44,-.03),l(.263,-.208),l(.023,-.236),l(-.172,-.502),l(-.615,-1.5),l(-.16,-.302),
+N(400.125,81.146),l(.633,.305),l(.208,.207),l(.208,.37),l(-.038,.193),l(-.545,.563),l(.714,.176),l(.396,-.311),l(.527,-.119),l(.602,.028),l(.807,.176),l(.467,.354),l(.235,.752),l(-.077,.221),l(-.322,.414),l(-1.068,.473),l(-.767,.561),l(-.96,.237),l(1.223,.167),l(.501,.043),l(.354,-.104),l(.39,.117),l(-.066,.516),l(-.997,.308),l(.005,.199),l(-.479,-.084),l(-1.068,.443),l(-.879,-.142),l(-.293,-.048),l(-1.119,.211),l(-.587,-.211),l(-.598,.112),l(-1.584,.141),l(.137,.295),l(-.907,-.168),l(-.264,.168),l(-.911,-.337),l(-.334,.143),l(-.913,.089),l(-.093,.569),l(-.337,.316),l(-.37,.042),l(-.272,-.252),l(-.53,-.172),l(-.135,.151),l(-.527,-.077),l(-.948,.324),l(-.701,.552),l(-.326,-.231),l(-.775,-.147),l(1.2,-.472),l(.492,-.476),l(.447,-.097),l(.468,-.388),l(.118,-.485),l(.242,.063),l(.367,-.211),l(-.008,-.274),l(1.013,-.105),l(.76,.119),l(.927,.007),l(.073,-.338),l(.308,-.142),l(.321,-.556),l(-.939,.394),l(-.725,.016),l(-1.467,-.482),l(-1.866,-.055),l(-.399,-.191),l(-.156,-.162),l(.417,-.325),l(.983,-.194),l(.721,-.237),l(.38,-.384),l(.066,-.827),l(-.119,-.192),l(-.713,.046),l(-.34,-.044),l(.288,-.355),l(.387,-.223),l(.802,-.253),l(1.394,-.062),l(.922,-.076),l(-.316,-.548),l(.172,-.683),l(.253,-.461),l(-.045,-.312),l(-.834,.061),l(-.484,-.296),l(-.2,-.312),l(.309,-.507),l(.617,-.433),l(-.347,-.104),l(-.596,-.088),l(-.735,.3),l(-.476,.061),l(-.753,-.222),l(-.088,.194),l(-.222,.194),l(-.672,-.103),l(-.464,-.133),l(.1,-.343),l(.348,-.36),l(.604,-.706),l(-.293,-.134),l(-.305,-.39),l(.028,-.24),l(.304,-.106),l(.3,-.196),l(-.194,-.496),l(-.306,.076),l(-.636,.453),l(-.442,.031),l(-.526,.287),l(-.14,-.421),l(.302,-.527),l(.438,-.559),l(.065,-.257),l(-.417,-.195),l(-.196,-.045),l(-.218,.302),l(-.394,.257),l(-.493,-.165),l(.299,-.575),l(.54,-.455),l(.09,-.136),l(-.225,-.575),l(.366,-.092),l(.225,-.197),l(-.672,-.515),l(.432,-.351),l(.752,.151),l(.387,-.092),l(-.645,-.759),l(.975,-.169),l(-.457,-.502),l(.416,-.382),l(.924,.365),l(.824,-.093),l(.686,-.139),l(.867,-.047),l(.612,.014),l(.303,.259),l(-.307,.29),l(-1.726,.704),l(-.46,.274),l(-.218,.441),l(.222,.182),l(.784,.029),l(.877,-.078),l(.685,-.001),l(.53,.075),l(1.563,-.064),l(.458,.378),l(-.363,.425),l(-.212,.323),l(.098,.112),l(-.565,.66),l(-.226,.111),l(-.339,.437),l(-.696,.261),l(-.382,.038),l(.451,.186),l(.508,.167),l(-.116,.015),l(-.272,.19),l(-.61,.052),l(-.275,.196),l(-1.337,-.025),l(.404,.223),l(.302,0),l(.492,.093),l(.432,-.006),l(.519,-.223),l(.413,-.025),l(.449,.161),l(.656,.164),l(.673,.566),l(.496,.228),l(.118,.165),l(-.067,.238),l(.312,.78),l(.371,.536),l(.438,.189),l(.714,.107),l(.59,.549),l(.688,.593),l(.135,.52),l(-.188,.49),l(.257,.124),M(387.915,77.13),l(-.128,-.325),l(.149,-.335),l(.38,-.089),l(.079,.501),l(-.307,.251),l(-.173,-.003),M(386.786,80.184),l(-.178,-.272),l(-.967,.072),l(.123,-.256),l(-.364,-.15),l(-.26,-.257),l(-.335,-.107),l(-.253,.364),l(-.751,.257),l(-.778,-.192),l(-.401,-.278),l(-.101,-.278),l(.86,-.278),l(-.483,-.257),l(.817,-.107),l(.385,-.484),l(-.029,-.235),l(.449,-.09),l(.508,-.15),l(.781,-.077),l(.424,.044),l(.389,.104),l(.362,-.046),l(.218,.149),l(.519,.791),l(.047,.179),l(-.081,.298),l(.308,.446),l(-.155,.328),l(-.402,.328),l(-.354,.12),l(-.299,.038),
+N(578.943,106.217),l(-.41,-.375),l(-.466,-.098),l(-.663,0),l(-.196,-.27),l(-.27,-.147),l(-.147,-.344),l(-.564,.049),l(-.981,-.246),l(-.662,.074),l(-1.35,-.024),l(-.662,-.098),l(-.712,-.221),l(-.785,.147),l(-.761,0),l(-.858,.024),l(-.441,.27),l(-.54,-.098),l(-.908,-.196),l(-.735,-.246),l(-.761,-.27),l(-.589,-.074),l(-.688,.123),l(-.466,.368),l(-.245,.736),l(.024,.442),l(-.344,-.123),l(-.81,-.123),l(-.688,-.196),l(-.883,-.245),l(-.883,-.147),l(-.663,.098),l(-.736,.123),l(-.318,.368),l(-.393,.442),l(.044,.273),l(-.322,.031),l(-.377,.377),l(-.283,-.126),l(-.22,.063),l(-.346,.283),l(-.534,.471),l(-.755,.189),l(-.943,.377),l(-.282,.188),l(-.221,.472),l(-.439,.188),l(-.504,.44),l(.157,.409),l(-.125,.188),l(-.66,0),l(-.44,-.346),l(.062,-.283),l(-.062,-.283),l(-.44,-.314),l(-.346,0),l(-1.006,.094),l(-.691,.032),l(-.503,-.063),l(-.346,-1.069),l(-.221,-.817),l(-1.006,0),l(-.031,-.754),l(.188,-.409),l(.031,-1.038),l(-.66,.314),l(-.66,-1.006),l(-.597,-.22),l(-.724,-.723),l(-1.1,.409),l(-2.767,-.188),l(-2.578,.346),l(-2.012,-1.666),l(-5.722,-2.986),l(-5.658,1.289),l(-.056,8.174),l(-.158,-.014),l(-.341,.106),l(-.489,.043),l(-.447,-.255),l(-.638,-.703),l(-.256,-.511),l(-.617,-.383),l(-.681,-.383),l(-.512,-.234),l(-.979,.085),l(-1.277,.298),l(-.937,.532),l(-.529,.453),l(.092,-.399),l(-.06,-.18),l(-.12,-.12),l(.14,-.26),l(.2,-.2),l(.14,-.32),l(.04,-.3),l(.18,-.2),l(-.159,-.24),l(-.4,-.16),l(-.459,.06),l(-.18,-.16),l(-.3,.06),l(-.2,.04),l(-.199,-.18),l(-.221,-.32),l(-.319,-.28),l(-.34,0),l(-.359,.02),l(0,-.2),l(.08,-.28),l(-.2,-.379),l(-.239,-.12),l(-.2,-.24),l(-.399,-.799),l(-.08,-.28),l(-.56,-.12),l(-.699,-.08),l(-.14,-.16),l(.02,-.439),l(.16,-.12),l(.3,-.06),l(.399,.02),l(.34,.02),l(.479,.14),l(.539,.18),l(.18,-.08),l(.36,-.08),l(-.2,-.16),l(-.26,-.12),l(-.399,-.2),l(-.2,-.24),l(.26,-.36),l(.28,-.04),l(.08,-.26),l(.18,-.299),l(.12,-.14),l(.26,.04),l(.319,-.08),l(.16,-.1),l(.339,.12),l(.24,0),l(1.119,-.04),l(.999,.14),l(.499,.02),l(-.159,-.08),l(-.34,-.2),l(-.479,-.12),l(-.021,-.3),l(.2,-.2),l(.279,-.22),l(.221,-.28),l(.119,-.52),l(.12,-.28),l(-.16,-.24),l(-.14,-.16),l(.1,-.2),l(.26,-.2),l(-.119,-.12),l(-.101,-.3),l(-.359,-.12),l(-.359,-.04),l(-.68,-.1),l(-.2,.16),l(-.199,.08),l(-.52,.08),l(-.46,-.12),l(-.319,-.26),l(-.26,-.06),l(-.68,-.12),l(-.56,.06),l(-.659,.319),l(-.42,.02),l(-.799,.5),l(-.72,.28),l(-.499,.06),l(-.42,-.02),l(-.279,.24),l(-.213,.18),l(-.616,-.19),l(-.857,-.377),l(-.068,-.308),l(.343,-.103),l(.309,.103),l(.445,.103),l(.138,-.103),l(-.96,-1.131),l(-.343,-.514),l(-.479,-.206),l(-.515,-.445),l(-.514,-.034),l(-.343,.034),l(-.583,-.206),l(-.103,.343),l(-.514,-.514),l(.068,-.309),l(-.138,-.377),l(-1.37,-.343),l(.65,-1.165),l(.446,-.274),l(.239,-.206),l(-.239,-.274),l(-.343,-.171),l(.205,-1.303),l(.823,-.137),l(.343,-.549),l(.103,-.308),l(.411,-.069),l(.514,.24),l(.48,.548),l(.514,.411),l(.651,0),l(.411,-.24),l(.068,-.446),l(-.171,-.411),l(-.068,-.445),l(.479,-.206),l(.891,-.411),l(.172,-.24),l(.309,-.309),l(.514,-.171),l(.549,-.068),l(.788,-.377),l(.548,-.343),l(.515,-.309),l(.651,.069),l(.479,0),l(.309,.274),l(.651,-.137),l(.273,-.137),l(.617,-.24),l(.411,.069),l(.411,.514),l(.788,.035),l(.617,-.069),l(.96,.171),l(0,.343),l(.582,.206),l(.789,.343),l(.411,.274),l(.068,.583),l(.274,.137),l(.239,-.274),l(-.205,-.48),l(-.034,-.24),l(.72,.068),l(.582,.548),l(.686,.137),l(.411,.24),l(.686,-.171),l(.274,-.274),l(.377,-.343),l(.514,-.377),l(.823,.068),l(.65,.035),l(.651,.411),l(.617,-.068),l(.137,-.412),l(1.062,-.103),l(.754,.103),l(.274,.548),l(.926,.309),l(.754,.137),l(.411,.171),l(.651,-.343),l(.171,-.309),l(.24,0),l(.343,.343),l(.959,.034),l(1.577,-.411),l(.137,-.309),l(.138,-.686),l(-.24,-.24),l(-1.165,-.171),l(-.274,-.308),l(-.651,-.069),l(-.377,-.137),l(.068,-.171),l(-.377,-.137),l(-.239,0),l(-.164,-.274),l(.467,-.067),l(.735,-.368),l(.588,-.147),l(.331,-.294),l(-.441,-.478),l(-.146,-.257),l(.662,-.515),l(.698,-.184),l(1.103,.147),l(.515,-.073),l(.11,-.257),l(-.956,-.294),l(-1.065,-.11),l(0,-.331),l(.294,-.074),l(-.294,-.221),l(-.074,-.441),l(.185,-.515),l(.33,-.074),l(1.066,.147),l(.515,0),l(.772,0),l(.368,-.184),l(1.396,-.405),l(1.029,-.037),l(.735,-.11),l(1.545,-.11),l(.588,-.073),l(.331,.073),l(.221,-.331),l(.625,-.331),l(1.177,-.037),l(2.021,-.405),l(1.876,-.073),l(.625,-.074),l(.367,-.368),V(0,77.39),l(.515,-.037),l(.589,-.184),l(.11,-.221),l(.735,-.037),l(.919,.147),l(.515,.11),l(.772,.257),l(.625,-.11),l(.882,-.037),l(.368,.404),l(-.037,.331),l(.147,.221),l(.515,.22),l(-.11,.331),l(-.147,.257),l(.073,.331),l(-.33,.037),l(.184,.257),l(.478,.074),l(.295,-.147),l(.44,.11),l(.368,-.147),l(.367,.074),l(.331,-.221),l(.294,.11),l(.295,.368),l(.367,.221),l(.147,-.147),l(.184,-.147),l(.478,.037),l(.405,.294),l(.478,.11),l(.441,-.221),l(.367,0),l(-.146,.294),l(-.441,.184),l(-.331,.441),l(.331,.184),l(.441,-.11),l(.771,-.073),l(.441,.037),l(.552,.184),l(.294,-.294),l(.772,-.441),l(1.103,-.257),l(.956,-.515),l(.772,-.221),l(.515,-.22),l(.809,-.074),l(0,.441),l(-.515,.11),l(-.11,.368),l(1.104,.588),l(.809,.294),l(1.287,.772),l(1.066,1.029),l(1.69,2.133),l(.846,.882),l(1.104,1.434),l(.515,-.257),l(.331,-.257),l(.367,-.515),l(.92,0),l(.367,.331),l(0,.368),l(.478,0),l(.258,.257),l(.184,.184),l(.589,0),l(.992,0),l(.993,-.221),l(.771,-.221),l(.993,-.037),l(.698,.441),l(.772,.588),l(.331,.625),l(.956,.147),l(.588,.552),l(.662,.699),l(.882,.073),l(.993,.074),l(.478,-.368),l(.625,-.184),l(-.073,.331),l(.441,.331),l(.294,.478),l(.589,0),l(.064,.145),l(-.551,.034),l(-.542,.148),l(-.279,.262),l(-.011,.275),l(-.035,.478),l(-.306,.219),l(-.289,.06),l(-1.199,.093),l(-.428,.277),l(-.34,.581),l(.097,.75),l(.213,.707),l(-.157,.39),l(-.444,.392),l(-.417,.103),l(-.718,.062),l(-1.402,-.079),l(-.594,-.141),l(-.721,-.141),l(-1.096,-.254),l(-.427,.507),l(-.516,1.141),L(584.2,97.43),l(-.286,.605),l(-.137,.418),l(.622,.514),l(.126,.286),l(-.156,.245),l(-.231,.145),l(-.394,.074),l(-1.133,-.238),l(-.5,-.184),l(-.35,.06),l(-1.082,.207),l(-1.799,.254),l(-.393,.188),l(-.215,.302),l(-.068,.215),l(.232,.185),l(.366,-.06),l(.483,.141),l(.03,1.357),l(.345,.627),l(.29,.441),l(.119,.47),l(-.222,.33),l(-.705,.546),l(-.32,.401),l(-.02,.399),l(.139,.86),
+N(386.786,80.184),l(-.304,.038),l(-.223,.09),l(.241,.252),l(.361,.771),l(.287,1.213),l(-.061,.281),l(-.359,.341),l(-.242,.414),l(-.145,.473),l(-.185,.044),l(-.284,-.058),l(-.616,.031),l(-.15,.212),l(-.913,.042),l(-.84,.132),l(-.247,.144),l(-.661,.286),l(-.903,.498),l(-.628,.035),l(-.879,.283),l(-1.28,.084),l(.053,-.378),l(-.089,-.441),l(-.848,.1),l(-.171,-.487),l(.734,-.254),l(-1.186,-.021),l(.062,-.233),l(1.286,.027),l(.198,-.104),l(.039,-.222),l(.107,-.31),l(.515,-.134),l(.692,-.031),l(.13,-.281),l(-1.07,.099),l(.387,-.437),l(-.187,-.159),l(.481,-.468),l(.694,-.011),l(.163,-.089),l(-.174,-.311),l(-.348,.177),l(-.309,-.131),l(-.319,.03),l(-.391,-.177),l(-.414,.001),l(-.182,.106),L(378,81.478),l(.309,-.306),l(-.29,-.142),l(.759,-.126),l(-.139,-.301),l(.391,-.235),l(-.481,-.214),l(-.59,.128),L(378,79.792),l(.38,-.268),l(.215,-.16),l(.928,.187),l(.336,-.075),l(.527,.038),l(1.102,.123),l(-.214,-.358),L(382.132,79),l(.198,-.321),l(-1.373,0),l(.154,-.15),l(.569,-.107),l(.061,-.29),l(.291,-.479),l(.505,-.181),l(.804,-.169),l(.22,.302),l(.354,.149),l(.156,-.031),l(.029,.235),l(-.385,.484),l(-.817,.107),l(.483,.257),l(-.86,.278),l(.101,.278),l(.401,.278),l(.778,.192),l(.751,-.257),l(.253,-.364),l(.335,.107),l(.26,.257),l(.364,.15),l(-.123,.256),l(.967,-.072),l(.178,.272),
+N(452.998,85.535),V(0,85.49),l(.037,-.131),l(.374,.019),l(.261,0),l(.112,.112),l(.373,-.206),l(.374,-.168),l(.037,-.168),l(.205,-.187),l(.485,-.019),l(.485,.038),l(.354,-.056),l(.355,-.056),l(.354,.056),l(.485,0),l(.467,-.075),l(.522,.093),l(.262,-.019),l(.205,.168),l(.522,0),l(.075,.056),l(.578,.056),l(.523,.112),l(.242,-.075),l(.28,.037),l(-.019,.224),l(.187,0),l(0,.149),l(.541,-.112),l(.187,.056),l(.243,.038),l(-.056,.224),l(.093,.056),l(.168,-.093),l(.019,-.205),l(.112,0),l(.262,.112),l(.354,-.056),l(.131,-.112),l(.224,.093),l(.131,.187),l(.224,-.112),l(.206,0),l(.13,.075),l(.094,.187),l(.168,0),l(.131,-.149),l(.299,-.149),l(.168,0),l(.131,-.075),l(.13,-.038),l(.168,.131),l(.112,.131),l(.037,.205),l(.188,.056),l(.316,-.056),l(.188,-.093),l(.224,-.075),l(.149,.131),l(.299,-.019),l(.242,-.075),l(.225,-.037),l(.224,.037),l(.187,.075),l(.112,.056),l(.149,.206),l(.149,.056),l(.261,.019),l(.131,-.206),l(-.056,-.149),l(-.243,-.205),l(.057,-.206),l(.261,-.224),l(.188,-.261),l(.317,-.187),l(.111,-.112),l(.057,-.13),l(.336,-.075),l(.187,.037),l(.205,.056),l(.112,-.131),l(.522,-.056),l(.519,.005),l(.357,.089),l(.469,.022),l(.313,-.156),l(.179,-.291),l(.134,-.268),l(.536,.246),l(.536,-.022),l(.67,-.223),l(.692,.112),l(.514,-.134),l(.201,.268),l(.312,.134),l(.246,.335),l(.134,.201),l(.246,.156),l(.312,.156),l(0,.268),l(-.312,-.022),l(-.312,.134),l(.134,.291),l(.111,.357),l(.269,.29),l(.647,0),l(.156,.112),l(.514,-.067),l(.38,.022),l(0,.312),l(.402,0),l(0,.357),l(.224,.268),l(.089,.246),l(-.089,.179),l(.089,.224),l(.179,.089),l(.291,.29),l(.268,-.179),l(.47,-.067),l(.268,.067),l(.469,.291),l(.201,-.067),l(.179,.022),l(.179,.156),l(.425,-.112),l(.312,-.112),l(.269,0),l(.536,-.134),l(.357,-.067),l(.111,.156),l(.268,.179),l(0,.134),l(.201,.179),l(.022,.134),l(.402,.044),l(.179,.179),l(.224,.112),l(.29,-.134),l(.045,-.157),l(.224,-.067),l(.29,.268),l(.425,.067),l(.469,.112),l(.268,.112),l(.357,-.067),l(.201,.179),l(.291,.089),l(.469,.022),l(.111,.224),l(.357,.156),l(.269,0),l(.134,-.044),l(.201,-.089),l(.156,.089),l(-.089,.111),l(-.022,.179),l(.111,.089),l(.09,.179),l(-.045,.224),l(-.201,.089),l(-.156,.067),l(-.357,.201),l(-.312,.044),l(.223,.246),l(.269,.089),l(.29,.044),l(-.134,.156),l(-.312,0),l(-.246,0),l(-.045,.179),l(-.044,.224),l(.156,.067),l(.179,.067),l(.044,.134),l(.045,.179),l(.09,.201),l(.066,.067),l(-.156,.491),l(-.156,.291),l(0,.156),l(-.335,.134),l(-.805,-.157),l(-.736,.045),l(-.269,0),l(-.022,.179),l(-.223,.179),l(-.38,.134),l(-.357,.022),l(-.224,.089),l(-.09,.514),l(0,.224),l(-.021,.112),l(-.012,.126),l(-.779,.104),l(-.971,.06),l(-.511,.405),l(-.729,.189),l(-1.135,.075),l(-1.119,.248),l(-.502,.318),l(-.463,.059),l(-.453,-.316),l(-.369,.621),l(-.31,.188),l(-.477,.044),l(-.438,-.057),l(-.959,.031),l(-.5,.16),l(.641,.287),l(1.957,1.004),l(.053,.172),l(-.093,.188),l(.163,.244),l(.562,.042),l(.511,-.13),l(.675,-.146),l(1.052,.013),l(.439,.114),l(-.235,.259),l(-.106,.245),l(-.228,.144),l(-.578,.116),l(-.31,.029),l(-.591,-.157),l(-.473,.044),l(-.71,.489),l(-1.007,.045),l(-.538,.188),l(-.527,.488),l(-.269,.101),l(-.786,-.07),l(-.588,-.171),l(.364,-.746),l(-.096,-.416),l(-.264,-.287),l(-.854,-.286),l(-.193,-.014),l(-.629,.016),l(-.151,.043),l(-.16,-.187),l(.887,-.505),l(.644,-.261),l(.772,-.188),l(.221,-.116),l(-.246,-.46),l(-.435,-.071),l(-.799,.044),l(-1.015,.045),l(-.698,-.1),l(-.195,-.101),l(-.418,-.432),l(.584,-.405),l(-.528,-.605),l(-.378,.361),l(-.541,.001),l(-1.001,.146),l(-.565,.131),l(-.694,.722),l(-1.003,.867),l(-.754,.203),l(-.223,.044),l(-.287,.504),l(.079,.158),l(.178,.093),l(-.706,-.131),l(-.665,.261),l(-.457,0),l(-.033,.189),l(-.609,-.047),l(-.398,-.166),l(-.119,-.249),l(-.15,.02),l(.055,-.077),l(.102,-.025),l(.126,.013),l(.113,.013),l(.189,0),l(.088,-.114),l(0,-.088),l(-.063,-.113),l(.025,-.113),l(.126,-.063),l(.051,-.063),l(.075,-.013),l(.089,-.025),l(.088,-.063),l(.089,-.088),l(.024,-.126),l(-.013,-.114),l(.14,-.013),l(.29,-.063),l(.075,-.076),l(-.025,-.088),l(-.062,-.088),l(.126,-.114),l(.037,-.063),l(-.012,-.088),l(-.114,-.113),l(.051,-.101),l(-.088,-.151),l(-.063,-.101),l(.202,-.151),l(.239,-.025),l(.126,-.088),l(.113,.025),l(.013,.088),l(-.013,.214),l(.063,.013),l(.113,0),V(0,96.92),l(-.013,-.063),l(.101,.038),l(.063,.051),l(.025,-.076),l(.075,-.038),l(.139,-.012),l(0,.075),l(.089,.063),l(.075,0),l(.126,.164),l(.076,-.076),l(.075,-.076),l(.013,-.05),l(.101,-.025),l(.177,0),l(-.037,.189),l(.176,.025),l(.038,-.038),l(.038,-.038),l(.139,.013),l(.227,0),l(.038,-.025),l(.075,-.076),l(-.126,-.013),l(-.164,-.126),l(-.101,-.051),l(-.075,-.05),l(.013,-.038),l(.101,-.063),l(-.025,-.113),l(.038,-.101),l(-.013,-.126),l(-.051,-.139),l(-.101,-.063),l(-.177,-.076),l(-.075,0),l(-.151,-.126),l(-.151,-.063),l(-.151,-.038),l(.051,-.151),l(.037,-.088),l(-.037,-.051),l(-.127,.038),l(-.062,-.114),l(.113,-.038),l(-.013,-.189),l(.089,-.075),l(-.025,-.101),l(-.038,-.088),l(-.113,0),l(-.102,.05),l(-.088,.051),l(-.113,-.088),l(-.089,-.101),l(-.188,-.101),l(-.139,-.025),l(-.102,-.139),l(-.05,-.139),l(.177,-.139),l(0,-.189),l(.024,-.114),l(.051,-.05),l(-.126,-.063),l(.164,-.151),l(-.113,-.025),l(-.076,-.063),l(-.062,-.126),l(-.14,-.013),l(-.062,.101),l(-.126,-.025),l(-.215,-.025),l(-.126,-.189),l(-.05,-.189),l(-.417,-.075),l(-.277,.012),l(-.062,.051),l(-.076,.101),l(-.062,-.05),l(0,-.076),l(-.089,-.025),l(-.101,.038),l(.038,-.05),l(.088,-.101),l(-.025,-.063),l(-.113,0),l(-.177,.038),l(-.126,-.025),l(-.101,.013),l(-.076,-.076),l(-.05,-.063),l(-.101,-.063),l(-.151,-.013),l(-.139,-.05),l(-.14,-.126),l(-.214,-.088),l(-.038,-.013),l(-.126,.025),l(-.05,.025),l(-.114,-.051),l(-.088,-.025),l(-.139,.025),l(-.177,.051),l(-.177,-.025),l(-.062,.038),l(-.126,.114),l(-.202,0),l(-.265,-.038),l(-.126,.051),l(-.315,-.114),l(-.088,.101),l(.012,.113),l(-.126,0),l(-.075,-.063),l(-.126,.114),l(-.06,.052),l(-.634,.08),l(-.151,.311),l(-.278,.178),l(-1.992,.191),l(-.186,.215),l(-.243,.119),l(-.339,.06),l(-.188,-.227),l(-.327,.004),l(-.025,-.231),l(-.363,.045),l(-1.115,-.066),l(-.958,-.193),l(-.241,.107),l(-.787,-.121),l(-.136,.085),l(-.678,-.387),l(-.554,-.2),l(-.668,-.301),l(-.166,.015),l(1.047,-1.471),l(.653,.018),l(-.349,-.383),l(-.044,-.552),l(.082,-.306),l(1.509,-1.218),l(.599,-.398),l(.286,-.181),l(.429,-.013),l(.255,-.24),l(.009,-.314),l(-.328,-.302),l(.085,-.133),l(.298,-.048),l(-.316,-.193),l(-.816,-.835),l(.074,-.242),l(-.161,-.175),
+N(660.044,89.132),l(-.295,.31),l(-.687,1.207),l(-1.224,1.959),l(-.381,.58),l(.269,.836),l(.051,.029),l(.342,-.045),l(.929,-.395),l(.754,-.062),l(.576,-.018),l(.317,.085),l(.431,.416),l(.292,.07),l(1.191,-.786),l(.438,-.002),l(.928,.212),l(.538,.199),l(.797,.5),l(.879,.99),l(.599,.501),l(.048,.273),l(-.107,.217),l(-.414,.218),l(-.464,-.127),l(-1.074,-.008),l(-.432,-.099),l(-.854,.033),l(-.937,.221),l(-.539,.146),l(-.831,.278),l(-.353,.189),l(-.483,-.127),l(-.464,.045),l(-.47,.204),l(-.363,.333),l(-.312,.82),l(-.241,.216),l(-.347,.188),l(-.638,.248),l(-.896,.134),l(-.624,-.054),l(-.438,-.012),l(-.224,-.013),l(-1.192,.91),l(-.742,.433),l(-.744,.047),l(-.982,.005),l(-.592,-.125),l(-.668,-.382),l(-.718,-.154),l(-.316,.073),l(-.457,.231),l(-.539,.589),l(-.214,.401),l(.003,.343),l(.389,.569),l(.599,.411),l(.188,.228),l(-.123,.271),l(-.326,.259),l(-1.265,.292),l(-.67,.389),l(-1.111,1.046),l(-.265,.172),l(-1.941,.737),l(-.651,.061),l(-.987,-.08),l(-1.514,.065),l(-1.339,.007),l(-1.204,.349),l(-.816,.289),l(-.736,.274),l(-.303,.101),l(-1.44,.534),l(-.686,.289),l(-.481,.017),l(-.433,-.197),l(-.253,-.297),l(-.61,-.067),l(-.663,.061),l(-.929,-.123),l(-1.599,-.433),l(-1.006,-.365),l(-.815,-.551),l(-.521,-.168),l(-1.69,-.119),l(-1.164,-.022),l(-.937,-.023),l(-2.861,.059),l(-1.165,-.022),l(-.802,-.109),l(-1.241,-.207),l(-1.979,-.018),l(-.444,-.254),l(-.467,-.439),l(-1.571,-2.161),l(-.105,-.542),l(-.744,-.096),l(-.839,-.31),l(-1.645,-.806),l(-.632,-.268),l(-.998,-.224),l(-.668,-.083),l(-.995,-.038),l(-1.505,-.021),l(-1.062,-.181),l(-.724,-.312),l(-.233,-.229),l(-.105,-.43),l(.035,-.129),l(.369,-.347),l(.214,-.389),l(.237,-.75),l(.215,-.447),l(-.401,-.66),l(-1.07,-1.451),l(-.568,-.618),l(-.354,-.143),l(-.633,-.144),l(-.731,-.167),l(-.614,-.069),l(-.834,-.415),l(-1.301,-.745),l(-.371,-.433),l(-.24,-.563),l(-.131,-.405),l(-.062,-.145),l(.154,-.044),l(.799,-.425),l(.599,-.207),l(1.387,-.08),l(.603,-.148),l(.727,-.381),l(.017,-.012),l(.971,-.692),l(.787,-.398),l(1.143,-.341),l(1.512,-.476),l(.84,-.18),l(.953,.097),l(.932,.156),l(1.842,.122),l(.831,.083),l(.694,.755),l(.393,.406),l(.699,.113),l(1.458,-.008),l(.719,.083),l(.85,-.004),l(.875,.068),l(.312,.114),l(.576,.186),l(.562,-.018),l(.755,-.28),l(.31,-.162),l(.744,-.572),l(.163,-.526),l(-.116,-.204),l(-.396,-.304),l(-.409,-.86),l(.098,-.293),l(.905,-.839),l(1.269,-.96),l(.84,.201),l(1.028,.098),l(1.036,.185),l(1.748,.328),l(.702,.231),l(.989,.317),l(.767,.143),l(.145,.204),l(.004,.541),l(.182,.481),l(.408,.451),l(.421,.333),l(1.643,.531),l(.673,.113),l(2.48,-.538),l(.796,-.077),l(1.172,.037),l(1.423,.022),l(.769,.229),l(1.333,.75),l(.623,.331),l(1.132,.313),l(.812,.373),l(1.318,.254),l(.905,.241),l(.984,.082),l(.739,.039),l(1.602,-.11),l(1.018,-.063),l(.532,-.075),l(.867,-.106),l(1.147,-.136),l(.526,-.163),l(.604,-.264),l(.447,-.394),l(.755,-.498),l(1.165,-.487),l(.333,-.002),l(.609,-.047),l(.74,.156),l(.751,.506),l(.34,.129),l(.86,.169),l(1.228,-.297),l(.622,-.018),l(.431,.168),
+N(406.183,86.551),l(1.051,-.494),l(.485,-.089),l(.574,.087),l(.465,-.016),l(.209,-.147),l(.477,.098),l(.407,.042),l(.52,-.034),l(-.025,-.157),l(.307,.012),l(.307,0),l(.267,-.182),l(.313,.242),l(.173,-.121),l(.228,.061),l(.292,.375),l(.535,-.109),l(.754,.375),l(-.11,.423),l(-.172,.097),l(.001,.338),l(.672,-.024),l(.344,.177),l(.282,.365),l(.038,.468),l(-.422,.376),l(-.225,-.072),l(-.142,.08),l(-.245,.147),l(-.213,.322),l(.017,.327),l(.31,.204),l(-.136,.348),l(-.079,-.114),l(-.694,.174),l(-.127,-.228),l(-.371,-.204),l(-.341,-.192),l(-.529,-.048),l(.039,-.228),l(-.146,-.18),l(.119,-.373),l(-.245,.072),l(-.193,.313),l(-.446,.035),l(-.406,.075),l(-.285,-.122),l(.072,-.198),l(-.091,-.175),l(.159,-.241),l(-.375,-.168),l(-.576,-.048),l(-.259,.012),l(-.159,-.301),l(-.518,.012),l(-.194,-.133),l(-.202,-.458),l(-.153,-.17),l(-.41,.208),l(-.141,.071),l(-.266,-.127),l(-.311,-.335),l(-.208,-.447),
+N(438.22,91.952),l(.039,-.044),l(.065,-.105),l(.014,-.131),l(.092,-.066),l(.146,-.119),l(.026,-.04),l(.171,-.053),l(.093,-.026),l(.092,.053),l(.132,.053),l(.158,0),l(.065,-.026),l(.093,0),l(.065,.026),l(.065,.026),l(.093,-.026),l(.145,-.04),l(.132,0),l(.118,-.053),l(.079,-.053),l(.066,-.026),l(.105,-.026),l(.039,0),l(.053,-.079),l(.04,-.092),l(.079,-.079),l(.092,.026),l(.105,-.04),l(.145,-.066),l(.053,-.105),l(.053,-.079),l(.026,-.132),l(.026,-.092),l(.053,-.092),l(.118,-.013),l(.105,-.013),l(.132,-.079),l(.119,-.053),l(.118,-.092),l(.053,-.079),l(.132,-.066),l(.065,-.04),L(442,89.998),l(.145,.013),l(.105,.026),l(.066,-.04),l(.065,-.066),l(.071,.012),l(.285,.041),l(.03,.228),l(.43,-.048),l(.183,-.24),l(.193,.016),l(.062,-.112),l(.261,-.024),l(.194,.24),l(.073,.169),l(.331,-.025),l(.066,.18),l(-.026,.083),l(.003,.204),l(.389,-.083),l(.18,.12),l(.149,-.135),l(.104,-.177),l(.558,-.204),l(.168,.056),l(.483,-.046),l(.46,.254),l(.373,-.18),l(.073,-.137),l(.508,.041),l(.561,-.076),l(.129,.13),l(.703,.186),l(.104,.216),l(.424,.101),l(.831,.33),l(-1.047,1.471),l(-.629,.076),l(-.437,-.143),l(-.534,-.359),l(-1.062,.035),l(-.717,.047),l(-1.024,.759),L(444.857,93),l(-.59,-.072),l(-.499,.061),l(-.761,.134),l(-.255,.001),l(-.334,.568),l(-1.651,-.036),l(-.414,-.027),l(-.617,-.17),l(-.399,-.172),l(-.245,.146),l(-.761,-.547),l(-.155,-.26),l(.097,-.581),l(-.053,-.093),
+N(442.391,98.111),l(-.589,.203),l(-.433,.031),l(-.668,.047),l(-.58,-.098),l(-1.116,-.671),l(-1.412,-.612),l(-.215,-.197),l(-.364,-.333),l(-.304,-.59),l(.346,-.299),l(.154,-.294),l(-.204,-.188),l(.04,-.375),l(.409,-.062),l(.157,-.206),l(-.136,-.196),l(-.452,-.063),l(.223,-.197),l(.325,0),l(.164,.134),l(.701,-.054),l(.019,-.367),l(.636,-.291),l(.245,-.146),l(.399,.172),l(.617,.17),l(.414,.027),l(1.651,.036),l(.334,-.568),l(.255,-.001),l(.761,-.134),l(.499,-.061),l(.59,.072),l(.427,-.063),l(1.024,-.759),l(.717,-.047),l(1.062,-.035),l(.534,.359),l(.437,.143),l(.629,-.076),l(.166,-.015),l(.668,.301),l(.554,.2),l(.678,.387),l(-.45,.338),l(-1.125,.267),l(-.581,.408),l(-.968,1.451),l(-.63,.84),l(-.753,.567),l(-.361,.16),l(-.724,.047),l(-.264,.103),l(-.176,-.002),l(-.907,-.067),l(-.889,.077),l(-1.535,.529),
+N(459.717,92.836),l(.06,-.052),l(.126,-.114),l(.075,.063),l(.126,0),l(-.012,-.113),l(.088,-.101),l(.315,.114),l(.126,-.051),l(.265,.038),l(.202,0),l(.126,-.114),l(.062,-.038),l(.177,.025),l(.177,-.051),l(.139,-.025),l(.088,.025),l(.114,.051),l(.05,-.025),l(.126,-.025),l(.038,.013),l(.214,.088),l(.14,.126),l(.139,.05),l(.151,.013),l(.101,.063),l(.05,.063),l(.076,.076),l(.101,-.013),l(.126,.025),l(.177,-.038),l(.113,0),l(.025,.063),l(-.088,.101),l(-.038,.05),l(.101,-.038),l(.089,.025),l(0,.076),l(.062,.05),l(.076,-.101),l(.062,-.051),l(.277,-.012),l(.417,.075),l(.05,.189),l(.126,.189),l(.215,.025),l(.126,.025),l(.062,-.101),l(.14,.013),l(.062,.126),l(.076,.063),l(.113,.025),l(-.164,.151),l(.126,.063),l(-.051,.05),l(-.024,.114),l(0,.189),l(-.177,.139),l(.05,.139),l(.102,.139),l(.139,.025),l(.188,.101),l(.089,.101),l(.113,.088),l(.088,-.051),l(.102,-.05),l(.113,0),l(.038,.088),l(.025,.101),l(-.089,.075),l(.013,.189),l(-.113,.038),l(.062,.114),l(.127,-.038),l(.037,.051),l(-.037,.088),l(-.051,.151),l(.151,.038),l(.151,.063),l(.151,.126),l(.075,0),l(.177,.076),l(.101,.063),l(.051,.139),l(.013,.126),l(-.038,.101),l(.025,.113),l(-.101,.063),l(-.013,.038),l(.075,.05),l(.101,.051),l(.164,.126),l(.126,.013),l(-.075,.076),l(-.038,.025),l(-.227,0),l(-.139,-.013),l(-.038,.038),l(-.038,.038),l(-.176,-.025),l(.037,-.189),l(-.177,0),l(-.101,.025),l(-.013,.05),l(-.075,.076),l(-.076,.076),l(-.126,-.164),l(-.075,0),l(-.089,-.063),l(0,-.075),l(-.139,.012),l(-.075,.038),l(-.025,.076),l(-.063,-.051),l(-.101,-.038),l(.013,.063),l(0,.088),l(-.113,0),l(-.063,-.013),l(.013,-.214),l(-.013,-.088),l(-.113,-.025),l(-.126,.088),l(-.239,.025),l(-.202,.151),l(.063,.101),l(.088,.151),l(-.051,.101),l(.114,.113),l(.012,.088),l(-.037,.063),l(-.126,.114),l(.062,.088),l(.025,.088),l(-.075,.076),l(-.29,.063),l(-.14,.013),l(.013,.114),l(-.024,.126),l(-.089,.088),l(-.088,.063),l(-.089,.025),l(-.075,.013),l(-.051,.063),l(-.126,.063),l(-.025,.113),l(.063,.113),l(0,.088),l(-.088,.114),l(-.189,0),l(-.113,-.013),l(-.126,-.013),l(-.102,.025),l(-.055,.077),l(-.03,.004),l(-.062,-.237),l(-.218,-.106),l(.16,-.071),l(-.021,-.267),l(-.104,-.561),l(.323,-.978),l(.027,-.404),l(-.353,-.856),l(-.604,-.286),l(-1.037,-1.119),L(460.567,93),l(-.626,-.191),l(-.225,.028),
+N(445.722,97.573),l(.176,.002),l(.264,-.103),l(.724,-.047),l(.361,-.16),l(.753,-.567),l(.63,-.84),l(.968,-1.451),l(.581,-.408),l(1.125,-.267),l(.45,-.338),l(.136,-.085),l(.787,.121),l(.241,-.107),l(.958,.193),l(1.115,.066),l(.363,-.045),l(.025,.231),l(.327,-.004),l(.188,.227),l(.339,-.06),l(.243,-.119),l(.186,-.215),l(1.992,-.191),l(.278,-.178),l(.151,-.311),l(.634,-.08),l(.225,-.028),L(460.567,93),l(.767,1.17),l(1.037,1.119),l(.604,.286),l(.353,.856),l(-.027,.404),l(-.323,.978),l(.104,.561),l(.021,.267),l(-.16,.071),l(.218,.106),l(.062,.237),l(.03,-.004),l(.15,-.02),l(.119,.249),l(.398,.166),l(.609,.047),l(.033,-.189),l(.457,0),l(.665,-.261),l(.706,.131),l(.149,.079),l(.062,.259),l(-.293,.446),l(-.27,.316),l(-.436,.044),l(-.382,.043),l(-.382,.245),l(-.515,.617),l(-.252,.645),l(-.096,.787),l(-.044,.223),l(-.671,-.12),l(-1.346,-.336),l(-.514,-.226),l(-.295,-.042),l(-.671,-.369),l(-.562,-.04),l(-.618,.218),l(-1.904,.771),l(-.38,.059),l(-1.385,-.35),l(-.3,-.013),l(-.69,.261),l(-.34,.031),l(-1.151,-.395),l(-.506,-.002),l(-.771,.189),l(-.266,.023),l(-.048,-.189),l(.234,-.318),l(-.352,-.106),l(-.392,-.204),l(-.418,-.186),l(-.146,-.33),l(.32,-.201),l(.351,.012),l(-.114,-.13),l(-.625,-.248),l(-.253,.13),l(-.215,.283),l(-.147,.118),l(-.414,-.239),l(-.194,-.139),l(-.594,-.059),l(-.02,-.189),l(-.234,0),l(-.245,-.036),l(-.052,-.165),l(.178,-.094),l(.271,-.071),l(-.239,-.083),l(-.183,-.059),l(.124,-.146),l(.19,-.127),l(-.069,-.142),l(-.306,-.118),l(-.555,-.141),l(-.712,-.471),l(.058,-.088),l(-.104,-.119),l(.075,-.356),l(-.202,-.036),l(-.19,-.237),l(-.569,-.178),l(-.054,-.309),
+N(420.177,113.472),l(-.274,-.042),l(-.253,-.155),l(-.367,-.325),l(-.096,-.213),l(.202,-.738),l(.097,-.681),l(-.046,-.583),l(-.133,-.569),l(-.503,-.44),l(-.094,-.271),l(.181,-.157),l(.366,-.015),l(.801,-.001),l(.339,-.172),l(.861,-.543),l(.633,.625),l(.451,.754),l(-.014,.271),l(-.204,.285),l(-.145,.484),l(.149,.894),l(-.11,.525),l(-.377,.695),l(-.405,-.198),l(-.52,.03),l(-.143,.1),l(-.149,.27),l(-.248,.17),M(433.783,118.446),l(-.712,-.084),l(-.902,-.607),l(-.772,-.239),l(-1.904,-.817),l(-.833,-.126),l(-.232,-.127),l(-.173,-.283),l(.139,-.34),l(.328,-.34),l(.264,-.1),l(.629,.112),l(.569,-.341),l(.68,.424),l(.403,.141),l(.722,-.016),l(1.403,-.187),l(1.38,-.329),l(.148,.085),l(.043,.127),l(-.112,.127),l(-.536,.823),l(-.153,.497),l(.009,.382),l(.411,.509),l(-.179,.128),l(-.43,.567),l(-.188,.015),M(431.244,98.829),l(-.281,-.329),l(-.242,-.027),l(-.281,.196),l(-.156,-.125),l(-.47,-.071),l(-.114,.32),l(-.458,.054),l(-1.001,.364),l(.078,-.151),l(-.452,.133),l(-.063,.249),l(-.157,.044),l(-.01,.125),l(.303,.08),l(.021,.302),l(.193,.119),l(.253,.236),l(-.104,.213),l(-.449,.254),l(.016,.272),l(.143,.554),l(.783,.814),l(2.008,.889),l(.29,.357),l(.134,.558),l(.274,.557),l(.395,.585),l(.694,.57),l(.254,.274),l(.446,.195),l(.041,.21),l(.408,.167),l(1.17,.255),l(1.254,-.105),l(.388,.141),l(.024,.212),l(-.465,.247),l(-.258,.294),l(.262,.213),l(.954,.283),l(1.168,.411),l(.829,.366),l(1.589,.739),l(.058,.185),l(.719,.458),l(.31,.475),l(-.198,.435),l(-.152,.337),l(-.455,-.281),l(-.318,-.167),l(-.109,-.486),l(-.263,-.17),l(-.512,-.099),l(-.483,-.009),l(-.439,-.236),l(.086,-.217),l(-.353,-.065),l(-.301,.098),l(-.232,.262),l(-.259,.399),l(-.273,.208),l(.043,.271),l(-.197,.303),l(-.007,.298),l(.76,.342),l(.611,.271),l(-.093,.314),l(.03,.432),l(.133,.142),l(-.191,.238),l(-.659,-.024),l(-.41,.219),l(-.202,.228),l(.11,.595),l(-.536,.303),l(-.617,.866),l(-.595,.048),l(-.167,-.071),l(-.184,-.14),l(-.002,-.508),l(.364,-.141),l(.317,-.542),l(-.236,-.184),l(.361,-.249),l(.361,.074),l(.133,-.17),l(-.077,-.34),l(-.211,-.181),l(-.206,-.924),l(-.367,-.516),l(-.15,-.607),l(-.201,-.352),l(-.334,.058),l(-.187,.171),l(-.899,-.496),l(-.286,-.065),l(.208,-.291),l(-.092,-.398),l(-.461,-.34),l(-.909,.247),l(.034,-.109),l(.322,-.194),l(-.276,-.27),l(-.29,-.003),l(-.42,.19),l(-.242,-.512),l(-.198,-.207),l(-.124,-.228),l(-.663,-.241),l(-.505,-.027),l(-.654,-.127),l(-.745,-.355),l(-.548,-.441),l(-.959,-.612),l(-1.036,-.826),l(-.872,-.384),l(-.805,-.67),l(-.566,-.856),l(-.434,-1.043),l(-.347,-.443),l(-.505,-.457),l(-.483,-.243),l(-1.188,-.341),l(-.579,-.142),l(-.5,.044),l(-1.078,.647),l(-.46,.359),l(-.646,.173),l(-.303,.043),l(.146,-.469),l(-.062,-.281),l(-.849,.07),l(-.754,-.391),l(-.193,-.442),l(.315,-.371),l(.175,-.01),l(-.135,-.331),l(-.616,-.191),l(-.352,-.358),l(.437,-.186),l(.183,.111),l(.541,-.353),l(.199,-.272),l(-.43,-.192),l(-.025,-.292),l(-.532,-.344),l(.624,-.301),l(.599,.062),l(.627,-.204),l(.629,.168),l(.275,-.16),l(.349,-.432),l(-.103,-.212),l(.777,-.404),l(.016,.415),l(.534,.363),l(.311,.071),l(-.098,.182),l(.385,.312),l(.285,-.151),l(.018,-.535),l(.425,-.384),l(-.019,-.333),l(.371,-.081),l(.143,.354),l(.23,.142),l(.216,-.03),l(.071,-.122),l(.469,-.05),l(.244,.333),l(.228,-.415),l(-.244,-.131),l(.081,-.273),l(.283,-.091),l(.176,.162),l(.315,.051),l(.038,-.192),l(-.112,-.212),l(.126,-.309),l(.631,.171),l(.597,.034),l(.329,-.411),l(.366,-.096),l(.183,.083),l(.445,-.11),l(.301,.103),l(.856,-.227),l(.023,.363),l(.318,.096),l(.32,.391),l(1.311,.247),l(.894,.082),l(.478,.112),l(.116,.199),l(-.614,.303),l(.098,.151),l(.297,.002),l(.187,.185),l(-.367,.285),l(.336,.089),l(-.127,.361),l(.36,.11),l(.284,.198),l(-.056,.214),
+N(430.73,96.731),l(1.04,.065),l(.179,.107),l(.612,-.009),l(.287,.152),l(.646,-.5),l(.566,-.107),l(.85,.08),l(.298,-.196),l(.89,.116),l(-.082,-.393),l(.693,-.157),l(.304,.59),l(.364,.333),l(-.035,-.009),l(-.1,-.073),l(-.145,-.036),l(-.172,0),l(-.145,.009),l(-.055,.063),l(0,.072),l(.019,.09),l(.009,.082),l(-.063,.009),l(-.136,-.009),l(-.108,-.036),l(-.091,.063),l(-.045,.082),l(-.081,.063),l(-.082,.045),l(-.081,.009),l(-.163,.036),l(-.117,.036),l(-.108,.036),l(-.055,.045),l(-.153,-.009),l(-.127,.072),l(-.063,.054),l(-.018,.082),l(.036,.072),l(.081,.054),l(.063,.055),l(.045,.045),l(.019,.063),l(.018,.09),l(-.036,.108),l(-.018,.063),l(-.046,.1),l(-.108,0),l(-.081,-.009),l(-.091,.027),l(-.108,.009),l(-.117,.054),l(-.091,.018),l(-.081,.027),l(-.1,.045),l(-.055,.063),l(-.036,.027),l(.055,.018),l(.063,.009),l(.026,.027),l(.037,.072),l(-.046,.063),l(-.027,.009),l(-.081,.027),l(-.009,.045),l(.045,.081),l(0,.072),l(.045,.1),l(-.054,.072),l(-.063,-.018),l(-.1,.045),l(-.117,.018),l(-.127,-.036),l(-.063,-.027),l(-.1,-.063),l(-.099,0),l(-.063,-.027),l(-.118,-.045),l(-.018,.045),l(-.027,.045),l(-.1,.027),l(-.136,0),l(-.054,-.045),l(-.072,-.063),l(-.127,-.018),l(-.019,-.09),l(-.026,-.018),l(-.063,-.054),l(-.055,-.027),l(-.018,-.054),l(-.01,-.054),l(-.036,-.009),l(-.063,.018),l(-.036,.054),l(-.009,.027),l(-.054,.063),l(-.019,.018),l(-.018,.081),l(-.063,.045),l(-.046,.018),l(-.062,.054),l(-.036,.009),l(-.254,0),l(-.108,-.027),l(-.108,.027),l(-.145,.009),l(-.1,-.009),l(-.1,-.036),l(-.045,-.019),l(-.055,0),l(0,.037),l(0,.036),l(-.045,.027),l(-.045,.018),l(-.136,-.009),l(-.027,-.036),l(-.108,.018),l(-.019,.018),l(-.136,.018),l(-.063,.018),l(-.126,.018),l(-.272,-.063),l(.428,-.077),l(.113,-.16),l(.056,-.214),l(-.284,-.198),l(-.36,-.11),l(.127,-.361),l(-.336,-.089),l(.367,-.285),l(-.187,-.185),l(-.297,-.002),l(-.098,-.151),l(.614,-.303),l(-.116,-.199),
+N(439.573,104.709),l(-1.051,-.672),l(-.185,-.222),l(-.783,-.149),l(-.203,-.159),l(-.403,-.115),l(-.683,.177),l(-.326,-.486),l(-1.112,-.627),l(-.584,-.678),l(.277,.007),l(.608,.016),l(-.583,-.221),l(-.659,-.469),l(-.183,-.407),l(.086,-.452),l(-.289,-.336),l(-.646,-.418),l(-.378,-.126),l(-.258,.579),l(-.142,.116),l(.03,.15),l(-.284,.106),l(-.154,.248),l(-.213,.053),l(-.496,-.647),l(-.063,-.286),l(-.259,-.612),l(.065,-.012),l(.272,.063),l(.126,-.018),l(.063,-.018),l(.136,-.018),l(.019,-.018),l(.108,-.018),l(.027,.036),l(.136,.009),l(.045,-.018),l(.045,-.027),l(0,-.036),l(0,-.037),l(.055,0),l(.045,.019),l(.1,.036),l(.1,.009),l(.145,-.009),l(.108,-.027),l(.108,.027),l(.254,0),l(.036,-.009),l(.062,-.054),l(.046,-.018),l(.063,-.045),l(.018,-.081),l(.019,-.018),l(.054,-.063),l(.009,-.027),l(.036,-.054),l(.063,-.018),l(.036,.009),l(.01,.054),l(.018,.054),l(.055,.027),l(.063,.054),l(.026,.018),l(.019,.09),l(.127,.018),l(.072,.063),l(.054,.045),l(.136,0),l(.1,-.027),l(.027,-.045),l(.018,-.045),l(.118,.045),l(.063,.027),l(.099,0),l(.1,.063),l(.063,.027),l(.127,.036),l(.117,-.018),l(.1,-.045),l(.063,.018),l(.054,-.072),l(-.045,-.1),l(0,-.072),l(-.045,-.081),l(.009,-.045),l(.081,-.027),l(.027,-.009),l(.046,-.063),l(-.037,-.072),l(-.026,-.027),l(-.063,-.009),l(-.055,-.018),l(.036,-.027),l(.055,-.063),l(.1,-.045),l(.081,-.027),l(.091,-.018),l(.117,-.054),l(.108,-.009),l(.091,-.027),l(.081,.009),l(.108,0),l(.046,-.1),l(.018,-.063),l(.036,-.108),l(-.018,-.09),l(-.019,-.063),l(-.045,-.045),l(-.063,-.055),l(-.081,-.054),l(-.036,-.072),l(.018,-.082),l(.063,-.054),l(.127,-.072),l(.153,.009),l(.055,-.045),l(.108,-.036),l(.117,-.036),l(.163,-.036),l(.081,-.009),l(.082,-.045),l(.081,-.063),l(.045,-.082),l(.091,-.063),l(.108,.036),l(.136,.009),l(.063,-.009),l(-.009,-.082),l(-.019,-.09),l(0,-.072),l(.055,-.063),l(.145,-.009),l(.172,0),l(.145,.036),l(.1,.073),l(.035,.009),l(.215,.197),l(1.412,.612),l(1.116,.671),l(.58,.098),l(.668,-.047),l(.433,-.031),l(.589,-.203),l(.201,.142),l(.056,.089),l(.022,.112),l(-.022,.078),l(.045,.044),l(.011,.067),l(-.078,.056),l(-.011,.146),l(.078,.067),l(.145,-.034),l(.101,.034),l(.045,.089),l(-.078,.011),l(-.056,-.022),l(-.022,.078),l(.033,.1),l(-.045,.034),l(-.044,.022),l(.066,.111),l(.168,-.022),l(.033,.078),l(.123,.1),l(.122,0),l(.101,0),l(.09,.078),l(.122,.011),l(.134,0),l(.012,.078),l(-.033,.056),l(-.135,-.011),l(-.089,-.034),l(-.067,.022),l(-.078,-.011),l(-.066,-.045),l(-.056,-.011),l(-.045,.011),l(.033,.067),l(-.101,.089),l(-.078,0),l(0,.156),l(.045,.067),l(-.033,.078),l(.022,.078),l(.011,.078),l(-.089,.033),l(-.09,-.033),l(-.056,.067),l(.078,.089),l(-.078,.011),l(-.189,.022),l(-.201,-.022),l(-.145,-.123),l(.056,-.101),l(-.045,-.089),l(-.123,-.011),l(-.022,-.112),l(-.145,-.056),l(-.146,-.045),l(-.101,.089),l(-.1,-.011),l(-.156,-.078),l(-.067,-.022),l(-.146,0),l(-.156,-.045),l(-.111,.067),l(-.134,.045),l(-.134,-.045),l(-.111,-.067),l(-.112,0),l(-.122,.089),l(-.168,.078),l(-.156,-.067),l(-.268,-.089),l(-.179,.011),l(-.156,.011),l(-.189,-.056),l(-.168,-.011),l(-.156,-.089),l(-.089,.078),l(-.111,.022),l(-.057,-.056),l(-.234,-.078),l(-.156,-.056),l(-.134,-.045),l(-.089,-.011),l(-.134,.123),l(-.112,-.011),l(-.223,-.022),l(-.168,-.033),l(-.212,.022),l(-.101,.111),l(-.145,.145),l(-.123,.201),l(-.201,-.022),l(-.256,-.134),l(-.156,-.19),l(-.101,-.111),l(-.312,-.034),l(-.123,.044),l(-.089,.179),l(-.045,.167),l(.045,.134),l(0,.078),l(.033,.212),l(-.123,.067),l(.022,.089),l(.134,.078),l(.09,.089),l(.122,.034),l(.101,.033),l(.179,.179),l(.146,.234),l(.089,.134),l(.022,.123),l(.156,.111),l(-.078,.056),l(-.012,.1),l(.022,.146),l(.168,-.011),l(.089,.111),l(.056,.123),l(.112,.111),l(.167,.045),l(.167,.033),l(.369,.357),l(.021,.167),l(.078,.044),l(.213,.078),l(.379,.357),l(.224,.123),l(.223,.067),l(.101,.056),l(0,.112),l(.078,.279),l(.201,.078),l(.189,.167),l(.146,.112),l(.245,.123),l(.067,.212),l(-.284,.083),M(439.792,104.833),l(.132,-.118),l(.134,.011),l(.123,.034),l(.045,.078),l(.066,.089),l(.146,.089),l(.179,.078),l(.212,.011),l(.312,.257),l(.045,.067),l(.134,-.033),l(.123,.022),l(.089,.034),l(.062,.063),l(.005,.004),l(-.022,.089),l(.033,.078),l(.082,.072),l(.029,.092),l(-.002,.1),l(-.589,-.367),l(-.549,-.371),l(-.789,-.378),
+N(451.009,101.725),l(-.328,.346),l(-.383,.374),l(-.18,.302),l(.056,.271),l(1.326,1.122),l(.028,.2),l(-.302,.302),l(-.762,.333),l(-.246,.301),l(-.008,.514),l(-.013,.208),l(-.058,-.017),l(-.072,.029),l(-.16,.022),l(-.145,.021),l(-.116,.022),l(-.058,.015),l(-.102,-.051),l(-.087,.043),l(-.088,.021),l(-.102,-.043),l(-.064,-.021),l(-.131,.116),l(-.087,.08),l(-.152,-.015),l(-.196,-.007),l(-.064,.007),l(-.175,-.043),l(-.152,.087),l(-.151,.102),l(-.109,.058),l(.059,.072),l(-.029,.058),l(-.116,0),l(-.094,-.109),l(-.131,-.058),l(-.087,-.073),l(-.08,.065),l(-.116,.058),l(-.246,.058),l(-.225,.058),l(-.088,.058),l(-.058,.167),l(.029,.13),l(-.029,.072),l(-.072,.087),l(-.188,0),l(-.14,-.049),l(-.018,-.109),l(-.733,-.866),l(-.382,-.369),l(-.058,-.004),l(.109,-.286),l(0,-.067),l(-.078,-.067),l(-.101,0),l(-.056,-.056),l(.022,-.089),l(.111,-.033),l(.146,.011),l(.167,.033),l(.057,-.033),l(.021,-.067),l(.09,-.044),l(.134,-.022),l(.089,-.011),l(-.011,-.089),l(-.101,-.101),l(-.167,-.067),l(-.134,-.045),l(-.057,-.044),l(-.111,.022),l(-.078,-.045),l(-.033,-.067),l(-.123,-.101),l(-.078,-.1),l(-.066,-.022),l(-.067,.044),l(-.078,-.011),l(-.101,-.056),l(-.279,-.078),l(-.078,-.022),l(-.056,-.033),l(-.167,-.134),l(-.101,-.146),l(-.111,-.111),l(-.168,-.078),l(-.156,-.101),l(-.223,-.056),l(0,-.101),l(.179,-.101),l(.089,-.111),l(.078,-.011),l(.067,.034),l(.078,.044),l(.1,.022),l(.045,-.022),l(.012,-.134),l(.011,-.19),l(-.134,-.145),l(-.179,-.19),l(-.212,-.134),l(-.101,-.145),l(.101,.022),l(.101,.011),l(.145,.056),l(.224,.044),l(.134,-.078),l(.089,-.056),l(.067,-.078),l(-.089,-.044),l(-.135,-.022),l(-.089,-.089),l(-.123,-.078),l(-.156,-.089),l(-.033,-.101),l(-.045,-.1),l(-.212,.011),l(-.167,-.056),l(-.078,-.1),l(-.022,-.134),l(.078,-.067),l(0,-.089),l(-.033,-.1),l(.056,-.056),l(.066,-.078),l(.156,-.156),l(.156,-.223),l(.034,-.167),l(.056,-.1),l(-.022,-.067),l(-.123,-.022),l(-.179,-.011),l(-.156,0),l(-.212,.112),l(-.078,-.089),l(.056,-.067),l(.09,.033),l(.089,-.033),l(-.011,-.078),l(-.022,-.078),l(.033,-.078),l(-.045,-.067),l(0,-.156),l(.078,0),l(.101,-.089),l(-.033,-.067),l(.045,-.011),l(.056,.011),l(.066,.045),l(.078,.011),l(.067,-.022),l(.089,.034),l(.135,.011),l(.033,-.056),l(-.012,-.078),l(-.134,0),l(-.122,-.011),l(-.09,-.078),l(-.101,0),l(-.122,0),l(-.123,-.1),l(-.033,-.078),l(-.168,.022),l(-.066,-.111),l(.044,-.022),l(.045,-.034),l(-.033,-.1),l(.022,-.078),l(.056,.022),l(.078,-.011),l(-.045,-.089),l(-.101,-.034),l(-.145,.034),l(-.078,-.067),l(.011,-.146),l(.078,-.056),l(-.011,-.067),l(-.045,-.044),l(.022,-.078),l(-.022,-.112),l(-.056,-.089),l(-.201,-.142),l(1.535,-.529),l(.889,-.077),l(.907,.067),l(.054,.309),l(.569,.178),l(.19,.237),l(.202,.036),l(-.075,.356),l(.104,.119),l(-.058,.088),l(.712,.471),l(.555,.141),l(.306,.118),l(.069,.142),l(-.19,.127),l(-.124,.146),l(.183,.059),l(.239,.083),l(-.271,.071),l(-.178,.094),l(.052,.165),l(.245,.036),l(.234,0),l(.02,.189),l(.594,.059),l(.194,.139),l(.414,.239),l(.147,-.118),l(.215,-.283),l(.253,-.13),l(.625,.248),l(.114,.13),l(-.351,-.012),l(-.32,.201),l(.146,.33),l(.418,.186),
+N(551.198,117.997),l(-.351,-.48),l(-.236,-.126),l(-1.217,-.05),l(-.646,-.011),l(-.096,-.016),l(.091,-.726),l(-.062,-.503),l(.157,-.251),l(.062,-.22),l(-.503,-.094),l(-.534,-.283),l(-.566,-.189),l(-.471,.063),l(-.378,-.251),l(-1.132,-.597),l(-.565,-.22),l(-.943,-.597),l(-.314,.063),l(-1.006,-.503),l(-.377,-.44),l(-1.194,-.597),l(-1.384,-.975),l(0,-.283),l(-.188,-.44),l(-.283,-.188),l(-.408,-.597),l(-.126,-.566),l(-.22,-.377),l(-.881,-.251),l(-.188,.157),l(-.439,.063),l(-.535,-.126),l(-.439,.032),l(-.503,.094),l(-.314,-.157),l(-.691,-.314),l(.094,-.22),l(.157,-.188),l(-.188,-.22),l(.031,-.188),l(.188,-.157),l(-.439,-.283),l(0,-.22),l(-.032,-.22),l(-.251,-.22),l(-.534,-.094),l(-.692,-.095),l(-.22,-.314),l(-.346,-.032),l(-.629,-.377),l(-.472,-.095),l(-.188,.063),l(-.565,.157),l(.251,.251),l(.188,.377),l(-.597,-.283),l(-.283,0),l(-.126,.126),l(-.22,.346),l(-.283,.126),l(-.629,0),l(-.503,.251),l(-.503,.409),l(-.062,.628),l(.314,.409),l(-.126,.314),l(-1.383,.032),l(-1.03,-.063),l(.056,-8.174),l(5.658,-1.289),l(5.722,2.986),l(2.012,1.666),l(2.578,-.346),l(2.767,.188),l(1.1,-.409),l(.724,.723),l(.597,.22),l(.66,1.006),l(.66,-.314),l(-.031,1.038),l(-.188,.409),l(.031,.754),l(1.006,0),l(.221,.817),l(.346,1.069),l(.503,.063),l(.691,-.032),l(1.006,-.094),l(.346,0),l(.44,.314),l(.062,.283),l(-.062,.283),l(.44,.346),l(.66,0),l(.125,-.188),l(-.157,-.409),l(.504,-.44),l(.439,-.188),l(.221,-.472),l(.282,-.188),l(.943,-.377),l(.755,-.189),l(.534,-.471),l(.346,-.283),l(.22,-.063),l(.283,.126),l(.377,-.377),l(.322,-.031),l(.349,-.126),l(.441,.246),l(-.368,.172),l(-.368,.171),l(-.221,.049),l(-.073,.196),l(-.295,.049),l(-.294,.172),l(-.196,.147),l(-.441,.295),l(-.172,.098),l(-.024,.123),l(.294,.049),l(.295,.074),l(.146,.123),l(.418,-.147),l(.098,.221),l(.172,.221),l(.368,.27),l(.589,0),l(.393,0),l(.049,-.393),l(.221,.049),l(.196,-.196),l(.024,-.245),l(.196,.098),l(.196,.172),l(.172,.294),l(.049,.147),l(.393,.024),l(.147,-.024),l(.073,.246),l(.025,.098),l(.343,-.025),l(.319,.147),l(.245,.196),l(.516,.074),l(.466,.024),l(.172,.123),l(-.49,.221),l(-.197,.147),l(-.221,.147),l(-.49,-.024),l(-.245,-.049),l(.049,.171),l(0,.147),l(-.319,0),l(-.172,.049),l(-.343,.196),l(-.221,.196),l(-.271,.049),l(-.221,.196),l(-.245,-.147),l(-.319,-.098),l(-.294,-.098),l(-.221,.025),l(-.246,.073),l(-.318,-.073),l(-.042,.098),l(-.345,-.005),l(-.409,.031),l(-.188,-.283),l(-.251,-.063),l(-.126,-.188),l(.251,-.126),l(.409,-.346),l(.188,-.22),l(-.252,-.251),l(-.439,-.377),l(-.221,.251),l(-.471,.346),l(-.692,.188),l(-.22,.157),l(-.252,-.22),l(-.22,-.157),l(-.346,0),l(.031,.22),l(-.283,.314),l(.189,.314),l(-.032,.346),l(-.062,.126),l(-.472,-.095),l(-.565,.095),l(-.503,.094),l(.251,.125),l(.534,-.031),l(.126,.094),l(-.251,.063),l(-.188,.063),l(-.032,.346),l(-.188,0),l(-.251,.157),l(-.063,.409),l(-.282,.188),l(-1.069,-.094),l(-.629,-.126),l(-.472,.283),l(-.125,.471),l(.251,.283),l(.346,.188),l(.157,.157),l(.44,.032),l(.346,0),l(.126,.22),l(-.126,.22),l(-.031,.472),l(.126,.409),l(.471,.314),l(.126,.283),l(-.157,.22),l(-.503,.346),l(-.283,.503),l(-.377,.377),l(.063,.377),l(-.375,.843),
+N(439.792,104.833),l(-.113,-.054),l(-.105,-.07),l(.284,-.083),l(-.067,-.212),l(-.245,-.123),l(-.146,-.112),l(-.189,-.167),l(-.201,-.078),l(-.078,-.279),l(0,-.112),l(-.101,-.056),l(-.223,-.067),l(-.224,-.123),l(-.379,-.357),l(-.213,-.078),l(-.078,-.044),l(-.021,-.167),l(-.369,-.357),l(-.167,-.033),l(-.167,-.045),l(-.112,-.111),l(-.056,-.123),l(-.089,-.111),l(-.168,.011),l(-.022,-.146),l(.012,-.1),l(.078,-.056),l(-.156,-.111),l(-.022,-.123),l(-.089,-.134),l(-.146,-.234),l(-.179,-.179),l(-.101,-.033),l(-.122,-.034),l(-.09,-.089),l(-.134,-.078),l(-.022,-.089),l(.123,-.067),l(-.033,-.212),l(0,-.078),l(-.045,-.134),l(.045,-.167),l(.089,-.179),l(.123,-.044),l(.312,.034),l(.101,.111),l(.156,.19),l(.256,.134),l(.201,.022),l(.123,-.201),l(.145,-.145),l(.101,-.111),l(.212,-.022),l(.168,.033),l(.223,.022),l(.112,.011),l(.134,-.123),l(.089,.011),l(.134,.045),l(.156,.056),l(.234,.078),l(.057,.056),l(.111,-.022),l(.089,-.078),l(.156,.089),l(.168,.011),l(.189,.056),l(.156,-.011),l(.179,-.011),l(.268,.089),l(.156,.067),l(.168,-.078),l(.122,-.089),l(.112,0),l(.111,.067),l(.134,.045),l(.134,-.045),l(.111,-.067),l(.156,.045),l(.146,0),l(.067,.022),l(.156,.078),l(.1,.011),l(.101,-.089),l(.146,.045),l(.145,.056),l(.022,.112),l(.123,.011),l(.045,.089),l(-.056,.101),l(.145,.123),l(.201,.022),l(.189,-.022),l(.078,-.011),l(.212,-.112),l(.156,0),l(.179,.011),l(.123,.022),l(.022,.067),l(-.056,.1),l(-.034,.167),l(-.156,.223),l(-.156,.156),l(-.066,.078),l(-.056,.056),l(.033,.1),l(0,.089),l(-.078,.067),l(.022,.134),l(.078,.1),l(.167,.056),l(.212,-.011),l(.045,.1),l(.033,.101),l(.156,.089),l(.123,.078),l(.089,.089),l(.135,.022),l(.089,.044),l(-.067,.078),l(-.089,.056),l(-.134,.078),l(-.224,-.044),l(-.145,-.056),l(-.101,-.011),l(-.101,-.022),l(.101,.145),l(.212,.134),l(.179,.19),l(.134,.145),l(-.011,.19),l(-.012,.134),l(-.045,.022),l(-.1,-.022),l(-.078,-.044),l(-.067,-.034),l(-.078,.011),l(-.089,.111),l(-.179,.101),l(-.056,-.033),l(-.156,.056),l(-.112,-.022),l(-.066,-.044),l(-.112,.033),l(-.078,.056),l(.012,.078),l(.089,.1),l(.123,.167),l(.056,.101),l(-.056,.101),l(-.111,0),l(-.09,-.056),l(-.056,-.089),l(-.056,-.044),l(-.123,-.011),l(-.122,.056),l(-.168,.078),l(-.045,.101),l(-.044,.089),l(-.112,.101),l(.034,.089),l(.011,.1),L(442,104.458),l(-.134,.011),l(-.111,.022),l(-.101,.089),l(-.012,.134),l(.012,.112),l(.011,.145),l(.012,.044),l(.066,.112),l(.078,.089),l(.045,.101),l(-.09,.089),l(-.183,.108),l(-.062,-.063),l(-.089,-.034),l(-.123,-.022),l(-.134,.033),l(-.045,-.067),l(-.312,-.257),l(-.212,-.011),l(-.179,-.078),l(-.146,-.089),l(-.066,-.089),l(-.045,-.078),l(-.123,-.034),l(-.134,-.011),l(-.132,.118),
+N(450.198,105.998),l(.013,-.208),l(.008,-.514),l(.246,-.301),l(.762,-.333),l(.302,-.302),l(-.028,-.2),l(-1.326,-1.122),l(-.056,-.271),l(.18,-.302),l(.383,-.374),l(.328,-.346),l(.392,.204),l(.352,.106),l(-.234,.318),l(.048,.189),l(.266,-.023),l(.771,-.189),l(.506,.002),l(1.151,.395),l(.34,-.031),l(.69,-.261),l(.3,.013),l(1.385,.35),l(.38,-.059),l(1.904,-.771),l(.618,-.218),l(.562,.04),l(.671,.369),l(.295,.042),l(.514,.226),l(1.346,.336),l(.671,.12),l(-.066,.335),l(-.077,.258),l(-.261,.086),l(-.313,-.028),l(-.339,.129),l(-.327,.73),l(-.039,.586),l(-.075,.143),l(-.404,.115),l(-.338,.372),l(-.017,.257),l(.252,-.036),l(.255,.224),l(.033,.154),l(.391,.375),l(.01,.223),l(-1.333,-.005),l(-.527,-.111),l(-.497,.045),l(-.629,.374),l(-.498,.445),l(-.363,-.026),l(-.344,.216),l(.097,.327),l(-.086,.257),l(-1.117,.277),l(-.388,.031),l(-.619,-.21),l(-1.473,-.505),l(-.584,.06),l(-.799,.261),l(-1.855,.195),l(-.09,.029),l(-.047,-.199),l(.104,-.3),l(.006,-.499),l(-.225,-.469),l(-.358,-.383),l(-.666,-.296),l(-.134,-.213),l(.007,-.106),
+N(381.009,107),l(-.121,-.278),l(.138,-.4),l(.343,-.5),l(-.358,-.471),l(-.304,-.428),l(-.514,-.07),l(-.164,-.1),l(-.053,-.329),l(.163,-.243),l(.409,-.272),l(.365,-.101),l(.563,-.03),l(.634,-.03),l(.133,-.172),l(.068,-.415),l(.535,-.273),l(.763,.042),l(1.078,.37),l(.763,.07),l(.756,-.087),l(.577,-.173),l(.508,-.144),l(.354,-.001),l(.629,.285),l(.694,.156),l(.939,.084),l(1.538,.04),l(.583,.027),l(.957,.141),l(.491,-.158),l(.419,-.229),l(.531,.027),l(.891,.47),l(.67,-.016),l(.335,.062),l(.472,.243),l(.469,-.03),l(.058,.122),l(-.205,.243),l(.094,.106),l(.15,.03),l(.112,-.106),l(1.088,.334),l(.15,-.061),l(.507,.395),l(.056,-.076),l(.262,.03),l(.131,-.076),l(.431,.152),l(.028,.038),l(.084,.114),l(.767,-.03),l(.037,.122),l(.337,-.061),l(.542,.015),l(-.017,-.319),l(.355,0),l(1.252,.304),l(.091,.213),l(.035,.289),l(.187,.076),l(.374,-.076),l(.206,-.03),l(.335,.091),l(.036,.152),l(.261,.015),l(.395,-.167),l(.427,.197),l(.485,.015),l(.039,-.136),l(.75,-.137),l(.334,.091),l(-.001,.088),l(-.001,.463),l(.156,.1),l(-.062,.485),l(-1.112,.528),l(-.95,.385),l(-.267,.328),l(-1.046,.198),l(-.664,.116),l(-.96,.301),l(-.323,.326),l(-.053,.2),l(.261,.128),l(-.088,.157),l(-.628,.143),l(-.594,.783),l(-.886,.787),l(-.096,.192),l(-.18,.361),l(-.245,.45),l(.353,.827),l(.072,.111),l(.084,.13),l(.648,.295),l(.103,.185),l(-.621,.327),l(-.215,.105),l(-.515,.252),l(-.286,.479),l(-.224,.085),l(-.461,.926),l(.155,.322),l(-.257,.099),l(-.992,.049),l(-.581,.242),l(-.425,.327),l(-.274,.757),l(-.663,.496),l(-.258,-.213),l(-.599,.028),l(-.305,.27),l(-.342,0),l(-.121,-.113),l(-3.282,.042),l(-.69,.524),l(-1.021,.17),l(-.35,.382),l(-.028,.283),l(-.083,.085),l(-.073,-.212),l(-.068,-.014),l(.005,.241),l(-.389,.127),l(-.421,-.142),l(-.788,-.467),l(-.224,-.382),l(.036,-.262),l(-.345,-.113),l(-.125,-.213),l(.175,-.163),l(-.468,-.51),l(-.702,-.284),L(385,117.498),l(-.484,-.135),l(-.586,.039),l(.008,-.018),l(.304,-.951),l(.242,-.37),l(.884,-.643),l(-.408,-.31),l(-.812,-.123),l(.17,-.455),l(.506,-.655),l(.347,-.371),l(-.163,-.198),l(-.455,-.551),l(-.488,-.494),l(.288,-.129),l(.482,-.045),l(.458,-.229),l(.043,-.199),l(-.057,-.938),l(.132,-.983),l(-.072,-.456),l(.051,-.442),l(.084,-.072),l(1.234,-.506),l(.288,-.216),l(-.062,-.242),l(-.842,-.495),l(-.15,-.242),l(-.272,-.227),l(-.335,-.055),l(-.531,.26),L(382.981,107),l(-.531,-.439),l(-.55,.188),L(381.009,107),
+N(489.685,103.693),l(.112,-.309),l(.26,-.166),l(.284,.047),l(.07,.047),l(.402,.023),l(.449,.023),l(.283,.095),l(.284,.142),l(.188,.094),l(.189,.047),l(.331,0),l(.213,0),l(.212,.166),l(.261,.095),l(.307,.071),l(.355,.047),l(.307,0),l(.426,-.095),l(.544,0),l(.401,.166),l(.189,0),l(.283,-.047),l(.354,.166),l(.095,.142),l(.284,.213),l(.52,.118),l(.354,.071),l(.236,.118),l(.308,.119),l(-.142,.118),l(-.048,.118),l(.261,.118),l(.212,.071),l(.261,-.118),l(.283,0),l(.166,-.166),l(.094,-.095),l(.213,-.071),l(.354,0),l(.261,.071),l(.188,.142),l(.142,-.166),l(.095,-.071),l(.118,0),l(.236,.118),l(.143,.094),l(.212,0),l(.189,.118),l(.213,.166),l(.378,0),l(.354,.024),l(.118,.142),l(-.118,.189),l(-.118,.307),l(.354,.284),l(.284,.166),l(.26,.094),l(.284,.047),l(.236,-.023),l(.236,.071),l(.126,.189),l(-.268,.189),l(-.143,.142),l(-.095,.071),l(.143,.26),l(.213,.307),l(.614,.166),l(.118,.213),l(-.095,.331),l(-.236,.095),l(-.236,.047),l(-.26,-.189),l(-.143,-.071),l(-.188,-.023),l(-.284,.047),l(-.638,-.189),l(-.189,-.213),l(-.331,-.189),l(-.473,-.024),l(-.236,0),l(-.418,.308),l(-.291,.094),l(-.378,.047),l(-.591,.095),l(-.592,-.047),l(-.401,.118),l(-.426,.023),l(-.308,.095),l(-.307,-.024),l(-.377,.108),l(-.031,-.028),l(-1.326,-1.018),l(-.41,-.041),l(-.761,.36),l(-.226,.072),l(-.491,-.068),l(-1.212,-.082),l(.083,-.065),l(.322,-.585),l(.032,-.143),l(-.064,-.728),l(-.331,-1.084),l(-.206,-.399),l(-.639,-.513),l(-.341,-.128),l(-.916,-.155),l(-.679,-.271),l(-.341,-.243),
+N(443.617,107.095),l(-.065,-.035),l(-.435,-.156),l(-.017,-.15),l(-.501,-.485),l(-.848,-.3),l(-.033,-.021),l(.002,-.1),l(-.029,-.092),l(-.082,-.072),l(-.033,-.078),l(.022,-.089),l(-.005,-.004),l(.183,-.108),l(.09,-.089),l(-.045,-.101),l(-.078,-.089),l(-.066,-.112),l(-.012,-.044),l(-.011,-.145),l(-.012,-.112),l(.012,-.134),l(.101,-.089),l(.111,-.022),l(.134,-.011),l(.056,-.056),l(-.011,-.1),l(-.034,-.089),l(.112,-.101),l(.044,-.089),l(.045,-.101),l(.168,-.078),l(.122,-.056),l(.123,.011),l(.056,.044),l(.056,.089),l(.09,.056),l(.111,0),l(.056,-.101),l(-.056,-.101),l(-.123,-.167),l(-.089,-.1),l(-.012,-.078),l(.078,-.056),l(.112,-.033),l(.066,.044),l(.112,.022),l(.156,-.056),l(.056,.033),l(0,.101),l(.223,.056),l(.156,.101),l(.168,.078),l(.111,.111),l(.101,.146),l(.167,.134),l(.056,.033),l(.078,.022),l(.279,.078),l(.101,.056),l(.078,.011),l(.067,-.044),l(.066,.022),l(.078,.1),l(.123,.101),l(.033,.067),l(.078,.045),l(.111,-.022),l(.057,.044),l(.134,.045),l(.167,.067),l(.101,.101),l(.011,.089),l(-.089,.011),l(-.134,.022),l(-.09,.044),l(-.021,.067),l(-.057,.033),l(-.167,-.033),l(-.146,-.011),l(-.111,.033),l(-.022,.089),l(.056,.056),l(.101,0),l(.078,.067),l(0,.067),l(-.109,.286),l(-.361,-.022),l(-.727,-.11),l(-.273,.273),l(-.279,.515),l(.133,.427),l(-.002,.342),
+N(558.52,110.652),l(.042,-.098),l(.318,.073),l(.246,-.073),l(.221,-.025),l(.294,.098),l(.319,.098),l(.245,.147),l(.221,-.196),l(.271,-.049),l(.221,-.196),l(.343,-.196),l(.172,-.049),l(.319,0),l(0,-.147),l(-.049,-.171),l(.245,.049),l(.49,.024),l(.221,-.147),l(.197,-.147),l(.49,-.221),l(-.172,-.123),l(-.466,-.024),l(-.516,-.074),l(-.245,-.196),l(-.319,-.147),l(-.343,.025),l(-.025,-.098),l(-.073,-.246),l(-.147,.024),l(-.393,-.024),l(-.049,-.147),l(-.172,-.294),l(-.196,-.172),l(-.196,-.098),l(-.024,.245),l(-.196,.196),l(-.221,-.049),l(-.049,.393),l(-.393,0),l(-.589,0),l(-.368,-.27),l(-.172,-.221),l(-.098,-.221),l(-.418,.147),l(-.146,-.123),l(-.295,-.074),l(-.294,-.049),l(.024,-.123),l(.172,-.098),l(.441,-.295),l(.196,-.147),l(.294,-.172),l(.295,-.049),l(.073,-.196),l(.221,-.049),l(.368,-.171),l(.368,-.172),l(-.441,-.246),l(-.349,.126),l(-.044,-.273),l(.393,-.442),l(.318,-.368),l(.736,-.123),l(.663,-.098),l(.883,.147),l(.883,.245),l(.688,.196),l(.81,.123),l(.344,.123),l(-.024,-.442),l(.245,-.736),l(.466,-.368),l(.688,-.123),l(.589,.074),l(.761,.27),l(.735,.246),l(.908,.196),l(.54,.098),l(.441,-.27),l(.858,-.024),l(.761,0),l(.785,-.147),l(.712,.221),l(.662,.098),l(1.35,.024),l(.662,-.074),l(.981,.246),l(.564,-.049),l(.147,.344),l(.27,.147),l(.196,.27),l(.663,0),l(.466,.098),l(.41,.375),l(.031,.194),l(-.051,.157),l(-.325,.187),l(-.97,.219),l(-1.338,.349),l(-.445,.145),l(-.405,.301),l(-.638,.701),l(-.646,.345),l(-.478,.102),l(-.459,.017),l(-1.248,-.235),l(-.238,.03),l(-.467,.472),l(-.463,.784),l(-.268,.243),l(-.885,.132),l(-.507,.145),l(-.344,-.055),l(-.183,-.567),l(-.06,-.071),l(-.359,.03),l(-1.737,.734),l(-1.422,.704),l(-.274,.186),l(-.129,.213),l(-.139,.739),l(-.196,-.073),l(-.344,.098),l(-.344,.171),l(-.539,0),l(-.663,-.073),l(-.834,.221),l(-.172,.147),l(-.196,0),l(-.172,-.319),l(-.368,.024),l(-.318,.172),l(-.074,-.221),l(-.049,-.172),l(-.122,.024),l(-.319,-.123),l(-.049,-.147),l(-.221,-.024),l(-.442,.123),l(-.343,.049),l(.024,.221),l(-.295,.049),l(-.393,-.074),l(-.073,-.196),l(-.147,-.123),l(-.368,-.098),l(-.49,.147),l(-.196,-.073),l(-.688,.024),l(-.564,0),l(-.589,.024),l(-.122,-.098),l(-.049,-.147),l(-.099,-.27),l(.099,-.245),l(.196,-.196),l(.098,.221),l(.196,-.074),l(-.049,-.196),l(.098,-.27),l(.123,0),l(.981,-.196),l(.515,.147),l(.516,.196),l(.099,.172),l(.196,0),l(.024,-.246),l(.441,-.196),l(.302,-.147),
+N(685.343,114.455),l(-.571,.678),l(-.309,.115),l(-.511,-.096),l(-.579,-.068),l(-.595,-.011),l(-.315,.157),l(-.633,.738),l(-.283,.256),l(-.235,.171),l(-.268,-.206),l(-.35,.34),l(-.319,.199),l(-.373,-.608),l(-.398,-.112),l(-.649,.78),l(-.195,-.382),l(-.232,-.254),l(-.683,-.367),l(-.169,-.453),l(.095,-.312),l(.429,-.411),l(.754,-.229),l(.056,-.269),l(-.591,-.282),l(.407,-.879),l(.189,-.34),l(-.199,-.269),l(-.632,-.296),l(-.139,0),l(-.381,.029),l(-.312,.143),l(-.234,-.07),l(-.52,-.368),l(-.167,-.233),l(.379,-.528),l(.415,-.442),l(.52,-.329),l(1.533,-.604),l(1.032,-.545),l(.636,-.543),l(.686,-1.027),l(.386,-.13),l(.448,-.017),l(.273,.396),l(.493,.253),l(.508,.153),l(.975,-.048),l(.527,-.159),l(-.046,-.113),l(-.508,-.765),l(.025,-.342),l(.273,-.243),l(.392,-.059),l(.333,.126),l(.452,.054),l(.538,-.017),l(.62,-.259),l(.955,-.532),l(.23,-.713),l(.383,-.358),l(.253,-.129),l(.247,-.001),l(.579,.68),l(.298,.439),l(.167,.393),l(-1.356,.923),l(-.408,.457),l(-.112,.414),l(.09,.427),l(-.154,.456),l(-.187,.868),l(-.668,.115),l(-.36,.229),l(-.497,.385),l(-.766,.641),l(-.468,.214),l(-.678,.03),l(-.577,.199),l(-.265,.228),l(-.248,.312),l(-.364,.893),l(.284,.326),l(1.225,.847),l(.419,.354),
+N(536.625,121.017),l(-.078,-.028),l(-.15,-.692),l(-.01,-.565),l(-.038,-.848),l(-.185,-.211),l(-.787,.075),l(-.696,-.01),l(-.655,-.506),l(-1.803,-1.362),l(-.597,-.336),l(-.66,-.167),l(-.5,-.054),l(-.788,-.066),l(-.822,-.335),l(-.708,-.251),l(-.402,-.437),l(-1.055,-.107),l(-.519,-.054),l(-.343,.129),l(-.517,.343),l(-.333,.03),l(-.78,-.038),l(-.609,.032),l(-.413,.144),l(-.476,.328),l(-.621,.654),l(-.466,.3),l(-.562,.13),l(-.441,-.025),l(-.066,-.376),l(-.128,-.681),l(-.106,-.447),l(.128,-.298),l(0,-.383),l(0,-.532),l(.106,-.191),l(.106,-.298),l(.085,-.234),l(-.085,-.212),l(-.256,-.128),l(-.319,-.191),l(-.213,-.255),l(-.042,-.149),l(-.171,0),l(-.191,-.042),l(-.361,-.106),l(-.191,.192),l(-.086,-.234),l(.086,-.106),l(.148,-.255),l(.128,.106),l(.383,-.042),l(.426,.085),l(.128,.021),l(.043,-.128),l(-.319,-.213),l(-.256,-.021),l(-.085,-.277),l(.17,-.255),l(.213,-.191),l(-.404,-.042),l(-.319,.085),l(-.383,0),l(-.319,-.085),l(-.128,.149),l(-.17,-.255),l(-.149,-.298),l(0,-.34),l(-.042,-.298),l(.17,-.213),l(.106,-.319),l(.043,-.255),l(.105,-.277),l(.086,-.234),l(.213,.34),l(.063,.128),l(.17,.17),l(.405,-.085),l(.383,.128),l(.106,-.149),l(-.021,-.149),l(.106,0),l(.148,.021),l(.064,.319),l(.106,.191),l(.298,-.021),l(.298,-.063),l(.256,-.106),l(.233,.085),l(.192,.064),l(.085,-.128),l(-.149,-.191),l(-.042,-.213),l(.191,-.042),l(.106,.149),l(.233,.085),l(.256,-.085),l(.213,-.064),l(.021,-.234),l(-.171,-.341),l(-.34,-.234),l(-.532,-.319),l(-.426,-.213),l(-.063,-.319),l(-.043,-.34),l(-.213,-.17),l(0,-.213),l(0,-.213),l(-.085,-.127),l(-.554,-.064),l(-.617,.085),l(-.426,.021),l(-.446,.127),l(-.192,.277),l(-.085,.298),l(.128,.192),l(-.063,.276),l(-.086,.405),l(.064,.234),l(.021,.298),l(-.256,-.553),l(-.361,-.319),l(.042,-.17),l(-.063,-.191),l(-.274,-.143),l(.529,-.453),l(.937,-.532),l(1.277,-.298),l(.979,-.085),l(.512,.234),l(.681,.383),l(.617,.383),l(.256,.511),l(.638,.703),l(.447,.255),l(.489,-.043),l(.341,-.106),l(.158,.014),l(1.03,.063),l(1.383,-.032),l(.126,-.314),l(-.314,-.409),l(.062,-.628),l(.503,-.409),l(.503,-.251),l(.629,0),l(.283,-.126),l(.22,-.346),l(.126,-.126),l(.283,0),l(.597,.283),l(-.188,-.377),l(-.251,-.251),l(.565,-.157),l(.188,-.063),l(.472,.095),l(.629,.377),l(.346,.032),l(.22,.314),l(.692,.095),l(.534,.094),l(.251,.22),l(.032,.22),l(0,.22),l(.439,.283),l(-.188,.157),l(-.031,.188),l(.188,.22),l(-.157,.188),l(-.094,.22),l(.691,.314),l(.314,.157),l(.503,-.094),l(.439,-.032),l(.535,.126),l(.439,-.063),l(.188,-.157),l(.881,.251),l(.22,.377),l(.126,.566),l(.408,.597),l(.283,.188),l(.188,.44),l(0,.283),l(1.384,.975),l(1.194,.597),l(.377,.44),l(1.006,.503),l(.314,-.063),l(.943,.597),l(.565,.22),l(1.132,.597),l(.378,.251),l(.471,-.063),l(.566,.189),l(.534,.283),l(.503,.094),l(-.062,.22),l(-.157,.251),l(.062,.503),l(-.091,.726),l(-1.454,-.244),l(-.565,-.294),l(-.445,.356),l(-.417,.2),l(-1.135,.205),l(-.432,.809),l(-.203,.991),l(-.103,.128),l(-.508,.243),l(-1.985,.689),l(-.568,.159),l(-.119,.199),l(-.001,.466),l(-.22,.199),l(-.636,.3),l(-.534,.031),l(-.573,-.082),l(-.999,-.348),l(-.937,-.193),l(-.193,-.112),
+N(445.294,112.196),l(-.07,-.115),l(-.138,-.469),l(-.5,-.452),l(-.966,-.541),l(.024,-.141),l(.23,.062),l(.023,-.237),l(-.345,-.414),l(.418,-.616),l(-.182,-.22),l(.188,-.563),l(-.251,-.282),l(.182,-.396),l(.268,-.079),l(-.027,-.45),l(-.331,-.081),l(-.2,-.107),l(.002,-.342),l(-.133,-.427),l(.279,-.515),l(.273,-.273),l(.727,.11),l(.361,.022),l(.058,.004),l(.382,.369),l(.733,.866),l(.018,.109),l(.035,.218),l(-.132,.429),l(.074,.641),l(.298,.668),l(.722,.608),l(-.09,.029),l(-.449,.842),l(-.402,.386),l(-.496,.472),l(-.583,.884),
+N(451.512,108.463),l(-.507,.16),l(-.532,.245),l(-.622,-.054),l(-.361,-.041),l(-.365,.159),l(-.395,.429),l(-.606,.146),l(-.809,.076),l(-.722,-.608),l(-.298,-.668),l(-.074,-.641),l(.132,-.429),l(-.035,-.218),l(.14,.049),l(.188,0),l(.072,-.087),l(.029,-.072),l(-.029,-.13),l(.058,-.167),l(.088,-.058),l(.225,-.058),l(.246,-.058),l(.116,-.058),l(.08,-.065),l(.087,.073),l(.131,.058),l(.094,.109),l(.116,0),l(.029,-.058),l(-.059,-.072),l(.109,-.058),l(.151,-.102),l(.152,-.087),l(.175,.043),l(.064,-.007),l(.196,.007),l(.152,.015),l(.087,-.08),l(.131,-.116),l(.064,.021),l(.102,.043),l(.088,-.021),l(.087,-.043),l(.102,.051),l(.058,-.015),l(.116,-.022),l(.145,-.021),l(.16,-.022),l(.072,-.029),l(.058,.017),l(-.007,.106),l(.134,.213),l(.666,.296),l(.358,.383),l(.225,.469),l(-.006,.499),l(-.104,.3),l(.047,.199),
+N(383.93,117.402),l(-.249,.101),l(-.517,.291),l(-.439,.052),l(-.548,-.178),l(-.58,0),l(-.28,-.073),l(-.719,.292),l(-.058,-.177),l(.389,-1.012),l(-.021,-.856),l(-.182,-.115),l(.244,-.542),l(-.054,-.397),l(.13,-.114),l(-.144,-.141),l(-.375,.085),l(-.476,.097),l(-.108,-.449),l(.48,-.052),l(.283,-.22),l(-.042,-.17),l(-.178,-.226),l(-.3,.417),l(-.413,.136),l(-.357,-.042),l(-.059,-.188),l(.198,-.397),l(.138,-.616),l(-.039,-.303),l(.258,-.114),l(.403,-.503),l(.45,-1.098),l(-.12,-.115),l(.612,-1.783),l(-.35,-.924),l(-.007,-.42),l(-.146,-.378),l(.255,-.271),l(.891,-.251),l(.55,-.188),l(.531,.439),l(1.822,.047),l(.531,-.26),l(.335,.055),l(.272,.227),l(.15,.242),l(.842,.495),l(.062,.242),l(-.288,.216),l(-1.234,.506),l(-.084,.072),l(-.051,.442),l(.072,.456),l(-.132,.983),l(.057,.938),l(-.043,.199),l(-.458,.229),l(-.482,.045),l(-.288,.129),l(.488,.494),l(.455,.551),l(.163,.198),l(-.347,.371),l(-.506,.655),l(-.17,.455),l(.812,.123),l(.408,.31),l(-.884,.643),l(-.242,.37),l(-.304,.951),l(-.008,.018),
+N(500.121,117.572),l(-.407,-.016),l(-.433,.388),l(-.164,.126),l(-.318,-.105),l(-.102,-.269),l(.03,-.259),l(-.274,-.151),l(-.366,-.082),l(-.244,.234),l(-.343,-.023),l(-.811,-.153),l(-.364,.032),l(-.304,-.16),l(-.437,.094),l(-.266,.143),l(-.23,.043),l(-.064,-.245),l(-.207,-.023),l(-.24,.292),l(-.693,.304),l(-1.185,.224),l(-.711,-.039),l(-.747,-.123),l(-.439,.073),l(-1.498,.673),l(-.567,.13),l(-1.104,.176),l(-.556,-.153),l(-1.532,-.444),l(-.278,.03),l(-.929,.373),l(-.746,.075),l(-.575,-.025),l(-.777,-.166),l(-.222,.001),l(-.142,-.035),l(-.055,.319),l(.102,.452),l(.243,.423),l(-.627,.127),l(-.156,.374),l(-.2,.169),l(-.171,-.041),l(-.114,.127),l(-.39,-.125),l(-.311,.001),l(-.245,-.459),l(-.119,-.093),l(.097,-.175),l(.242,-.197),l(.617,-.403),l(.021,-.175),l(-.049,-.134),l(-.279,-.28),l(-.146,-.053),l(-.487,.368),l(-.23,.041),l(-.137,.064),l(.092,.041),l(-.118,.216),l(-.172,.023),l(-.063,-.047),l(-.076,.088),l(-.297,.058),l(-.332,-.222),l(-.447,-.198),l(-.461,-.157),l(-.395,.046),l(-.849,.548),l(-.337,.286),l(.006,.204),l(-.141,.046),l(-.122,.07),l(-.005,.082),l(-.179,-.169),l(-.604,.206),l(-.689,.185),l(-.594,-.013),l(-.587,-.07),l(-.678,-.267),l(-.963,-.819),l(-1.181,-.479),l(-1.034,-.182),l(-.692,.072),l(-.119,.255),l(-.097,.609),l(-.053,.411),l(-.173,.156),l(-.256,0),l(-.253,-.155),l(-1.12,.243),l(-.423,-.027),l(-.386,-.183),l(-.657,-1.159),l(-.42,.354),l(-.764,-.451),l(-.451,.057),l(-.562,.412),l(-.227,-.382),l(.066,-.127),l(.242,-.17),l(-.116,-.17),l(-.989,-.012),l(-.545,-.013),l(-.088,-.269),l(.571,-.199),l(-.074,-.241),l(-.284,-.198),l(-.454,-.07),l(-.084,-.297),l(.041,-.34),l(.087,-.284),l(-.089,-.255),l(-.396,-.126),l(-.627,-.353),l(-.371,.086),l(-.265,-.084),l(-.004,-.255),l(.171,-.501),l(.131,.059),l(.478,.311),l(.567,-.271),l(-.396,-.283),l(.021,-.124),l(-.296,-.128),l(.03,-.128),l(.571,-.159),l(.152,-.113),l(-.068,-.142),l(-.149,-.088),l(-.337,-.035),l(.01,-.187),l(.18,-.07),l(-.163,-.164),l(-.198,-.117),l(-.009,-.152),l(-.227,-.012),l(.263,-.181),l(.296,-.275),l(.161,-.035),l(.07,-.16),l(-.341,-.042),l(-.573,.12),l(-.905,.164),l(-.166,-.035),l(.046,-.33),l(.127,-.125),l(-.003,-.199),l(-.029,-.286),l(.13,-.264),l(.299,.012),l(.184,-.41),l(.175,-.023),l(.63,-.422),l(.514,.012),l(.133,-.129),l(.479,-.047),l(.128,.211),l(.268,.102),l(.169,.028),l(.529,.022),l(.147,-.129),l(-.067,-.129),l(-.269,-.129),l(.286,-.094),l(.324,.036),l(.117,.082),l(-.219,.223),l(.213,-.026),l(1.053,-.073),l(.619,.042),l(.379,.046),l(.279,.047),l(.155,-.176),l(-.086,-.094),l(-.468,-.035),l(-.212,-.118),l(.275,-.212),l(1.386,-.151),l(.417,-.012),l(.377,-.117),l(-.442,-.012),l(-.592,.023),l(-.215,0),l(-.068,-.146),l(-.611,-.382),l(.325,-.528),l(.926,.14),l(1.244,.048),l(.264,-.117),l(1.086,.321),l(1.051,-.031),l(.414,-.243),l(-.041,-.27),l(.624,-.244),l(.455,-.214),l(1.218,-.573),l(.598,-.215),l(1.039,-.23),l(.889,-.073),l(.758,.07),l(.905,.126),l(.798,.041),l(.753,-.372),l(.216,.527),l(.416,.298),l(.278,.099),l(.592,.013),l(.622,-.144),l(.453,.74),l(.492,.255),l(.574,-.172),l(.391,.056),l(.968,.582),l(1.265,.04),l(1.094,.197),l(.749,-.001),l(1.084,-.272),l(.514,-.044),l(.651,.141),l(.764,.098),l(.787,-.016),l(.554,-.144),l(1.518,-.573),l(.424,-.335),l(1.212,.082),l(.491,.068),l(.226,-.072),l(.761,-.36),l(.41,.041),l(1.326,1.018),l(.031,.028),l(.795,.722),l(.026,.199),l(-.421,.813),l(.033,.412),l(.284,.211),l(1.413,.12),l(.492,.451),l(-.072,.211),l(-.409,-.023),l(-.231,.141),l(-.009,.433),l(-.584,.267),l(-.039,.27),l(.264,.67),l(-.122,.375),l(.224,.492),l(.09,.117),l(.106,-.105),l(.288,.203),l(.039,.207),l(-.229,.281),l(-.287,.535),l(-.06,.128),l(.213,.14),l(.424,.111),l(-.145,.245),l(.099,.421),l(.42,.374),l(.275,.035),l(.023,.308),M(462.617,106.804),l(.241,.211),l(-.019,.287),l(.115,.285),l(.077,.071),l(.593,.355),l(.819,.241),l(.605,.155),l(.152,.121),L(464.943,109),l(-.304,.166),l(-.515,-.072),l(-.94,-.246),l(-.326,.07),l(-.209,.152),l(-1.019,-.012),l(-.357,.384),l(-.109,.273),l(-.833,.316),l(-.612,.282),l(-.222,.258),l(-.307,.152),l(-.268,.293),l(-.255,.082),l(.164,-.258),l(.019,-.141),l(-.062,-.176),l(.584,-.293),l(.22,-.141),l(-.226,-.191),l(-.082,.015),l(-.653,-.056),l(-.229,-.148),l(.326,-.546),l(.387,-.558),l(.678,-.631),l(-.127,-.227),l(-.427,-.197),l(-.105,0),l(.498,-.445),l(.629,-.374),l(.497,-.045),l(.527,.111),l(1.333,.005),
+N(509.077,114.955),l(-.72,-.317),l(-.268,.016),l(-.356,-.433),l(-.374,-.105),l(-.13,-.363),l(.532,-.27),l(.095,-.222),l(-.43,-.176),l(-.027,-.188),l(.63,-.129),l(.094,-.155),l(-.061,-.113),l(-.487,-.21),l(-.351,-.281),l(-.306,-.166),l(-.456,.234),l(-1.058,.492),l(-.374,.445),l(-.642,.188),l(-.254,.255),l(-.014,-.027),l(.094,-.118),l(-.094,-.213),l(-.189,-.071),l(.26,-.095),l(.166,-.047),l(-.261,-.189),l(-.236,-.236),l(.236,-.118),l(.095,-.189),l(-.283,-.047),l(-.354,-.024),l(-.284,-.118),l(-.213,-.212),l(-.236,-.024),l(-.26,-.354),l(-.283,-.142),l(-.048,-.094),l(.166,0),l(.378,0),l(.165,-.236),l(0,-.236),l(-.213,-.024),l(-.188,-.142),l(-.544,-.331),l(-.283,-.354),l(.047,-.284),l(.402,-.142),l(-.119,-.236),l(-.212,-.166),l(-.426,-.071),l(-.284,-.095),l(.071,-.094),l(.071,-.118),l(-.284,-.095),l(-.087,-.212),l(.418,-.308),l(.236,0),l(.473,.024),l(.331,.189),l(.189,.213),l(.638,.189),l(.284,-.047),l(.188,.023),l(.143,.071),l(.26,.189),l(.236,-.047),l(.236,-.095),l(.095,-.331),l(-.118,-.213),l(-.614,-.166),l(-.213,-.307),l(-.143,-.26),l(.095,-.071),l(.143,-.142),l(.268,-.189),l(.229,-.023),l(.023,.166),l(.213,-.047),l(.189,0),l(.142,.189),l(.473,.284),l(.095,.118),l(.118,0),l(.283,.284),l(0,.308),l(.591,.094),l(.449,.142),l(.379,-.047),l(.165,-.213),l(.308,-.331),l(.283,-.094),l(.496,-.284),l(.292,-.449),l(.465,.331),l(.236,.378),l(.26,.189),l(.284,.307),l(.095,.52),l(.142,.236),l(.283,.26),l(.284,.165),l(0,.166),l(.449,.236),l(.473,-.047),l(.378,.071),l(.284,.166),l(.236,.189),l(.095,.189),l(0,.142),l(-.355,-.142),l(-.401,-.047),l(-.213,0),l(-.26,.047),l(-.142,.118),l(-.402,.071),l(-.213,.142),l(-.047,.189),l(-.023,.473),l(-.118,.26),l(-.095,.236),l(-.095,.378),l(.213,.236),l(-.023,.189),l(-.237,-.071),l(-.094,.095),l(-.071,.331),l(-.071,.26),l(-.118,-.047),l(-.094,-.236),l(-.143,-.095),l(-.165,.095),l(-.047,.307),l(.07,.166),l(-.118,.118),l(-.118,.095),l(.095,.26),l(-.363,.91),M(499.844,111.738),l(.709,.061),l(.142,-.047),l(.26,-.071),l(.236,.236),l(.071,.166),l(.378,.142),l(.213,.071),l(.308,-.118),l(.52,0),l(-.071,.213),l(.024,.236),l(.118,.023),l(.331,.166),l(-.071,.236),l(.421,.763),l(-.009,.001),l(-.253,-.133),l(-.416,.038),l(-.512,-.025),l(-.421,-.125),l(-.335,-.211),l(-.294,-.402),l(-.551,-.223),l(-.281,-.417),l(-.265,-.381),l(-.252,-.197),
+N(455.452,122.442),l(.049,-.209),l(-.057,-.128),l(-.812,-.256),l(-.691,-.006),l(-.506,-.116),l(-.484,.017),l(-.121,-.046),l(-.103,-.093),l(.139,-.56),l(.315,-.005),l(-.005,-.088),l(-.009,-.122),l(.069,-.07),l(.083,.157),l(.021,.146),l(.303,.021),l(.172,.055),l(.184,-.076),l(-.014,-.082),l(.108,-.029),l(.157,.105),l(-.037,.093),l(-.099,.006),l(-.04,.053),l(.088,.023),l(.144,.035),l(.094,.046),l(.021,.128),l(.353,.041),l(.846,-.122),l(.509,.016),l(.035,.13),l(.192,.035),l(.608,.064),l(.307,.051),l(.358,-.121),l(.09,.05),l(-.101,.312),l(.163,.11),l(.105,0),l(.325,-.169),l(.286,-.058),l(.078,.052),l(.154,-.07),l(.232,-.146),l(-.083,.187),l(.015,.186),l(-.183,.268),l(-.582,-.046),l(-.349,.081),l(-.335,-.017),l(-1.994,.169),M(445.294,112.196),l(.583,-.884),l(.496,-.472),l(.402,-.386),l(.449,-.842),l(.09,-.029),l(.809,-.076),l(.606,-.146),l(.395,-.429),l(.365,-.159),l(.361,.041),l(.622,.054),l(.532,-.245),l(.507,-.16),l(.09,-.029),l(1.855,-.195),l(.799,-.261),l(.584,-.06),l(1.473,.505),l(.619,.21),l(.388,-.031),l(1.117,-.277),l(.086,-.257),l(-.097,-.327),l(.344,-.216),l(.363,.026),l(.105,0),l(.427,.197),l(.127,.227),l(-.678,.631),l(-.387,.558),l(-.326,.546),l(-.062,-.407),l(-.794,-.056),l(-.743,-.041),l(-.566,-.125),l(-.062,-.144),l(-.459,.186),l(-.248,.123),l(-.403,.012),l(-.031,-.247),l(-.335,.029),l(-.301,.314),l(-.431,.186),l(-.31,.03),l(-.306,-.159),l(-.252,.07),l(-.004,.133),l(.169,.185),l(.169,.34),l(.308,.059),l(.826,.609),l(-.166,.07),l(-.369,-.258),l(-.015,-.105),l(-.276,-.082),l(-.331,-.105),l(-.116,.099),l(-.211,.007),l(.069,.129),l(-.016,.129),l(.338,.164),l(.145,-.012),l(.114,.234),l(-.03,.129),l(-.245,.023),l(-.445,-.457),l(-.341,-.141),l(-.207,-.059),l(-.128,-.012),l(.003,.094),l(-.075,.035),l(.138,.164),l(.102,.105),l(.154,.141),l(.193,.059),l(.153,.035),l(.103,.094),l(-.093,.058),l(-.494,-.046),l(-.253,-.035),l(.035,-.176),l(-.137,-.293),l(-.164,-.188),l(-.401,-.108),l(-.472,-.373),l(.258,-.118),l(.025,-.136),l(-.053,-.122),l(-.182,-.035),l(-.153,.199),l(-.465,.176),l(.245,.224),l(-.25,.371),l(-.05,.249),l(.13,.121),l(.065,.172),l(.311,.338),l(.133,.036),l(.131,.479),l(.579,.421),l(.359,.467),l(-.172,.14),l(-.237,.082),l(.106,-.187),l(-.121,-.187),l(-.142,-.128),l(-.139,-.035),l(-.151,-.047),l(-.29,.175),l(.102,.188),l(.153,.081),l(.08,.316),l(-.193,.187),l(-.652,.141),l(.248,.046),l(.27,.14),l(.391,.058),l(.188,.222),l(.257,-.012),l(.155,.012),l(.048,.126),l(.367,.269),l(.306,.014),l(.138,.292),l(.282,.012),l(.27,0),l(.348,.303),l(.015,.128),l(-.193,.082),l(.238,.782),l(-.153,.175),l(-.185,0),l(-.226,-.385),l(-.222,-.047),l(-.207,-.278),l(-.101,-.142),l(-.17,0),l(-.496,.14),l(-.479,.105),l(-.184,.128),l(.315,.093),l(.013,.188),l(.007,.291),l(.229,.117),l(.153,-.026),l(.225,-.079),l(-.021,.198),l(.235,.175),l(-.519,.093),l(.002,.117),l(-.169,.062),l(-.309,-.086),l(.121,-.21),l(-.186,-.086),l(-.508,-.056),l(-.158,-.092),l(-.008,.206),l(.194,.453),l(.193,.17),l(-.045,.163),l(.209,.204),l(.213,.96),l(-.688,-.31),l(-.331,.071),l(-.298,.439),l(-.442,-.735),l(-.46,-.367),l(-.452,.44),l(-.428,-.353),l(-.127,-.297),l(.212,-.425),l(-.028,-.241),l(-.215,-.269),l(-.491,-.424),l(-.167,-.226),l(.017,-.17),l(.471,-.61),l(.609,.098),l(.425,-.298),l(.202,.042),l(1.668,.663),l(.337,-.1),l(.483,-.355),l(-.266,-.049),l(-.27,-.056),l(-1.204,-.493),l(-1.127,-.083),l(-.367,.058),l(-.66,.058),l(-.427,.143),l(-.89,-1.118),l(.269,-.1),l(.253,.056),l(.218,-.114),l(.122,-.185),l(-.339,-.24),l(-.235,.114),l(-.496,-.042),l(-1.035,-.721),l(-.199,-.325),
+N(504.136,113.458),l(-.327,.328),l(-.377,.03),l(-.421,-.763),l(.071,-.236),l(-.331,-.166),l(-.118,-.023),l(-.024,-.236),l(.071,-.213),l(-.52,0),l(-.308,.118),l(-.213,-.071),l(-.378,-.142),l(-.071,-.166),l(-.236,-.236),l(-.26,.071),l(-.142,.047),l(-.709,-.061),l(-.492,-.451),l(-1.413,-.12),l(-.284,-.211),l(-.033,-.412),l(.421,-.813),l(-.026,-.199),l(-.795,-.722),l(.377,-.108),l(.307,.024),l(.308,-.095),l(.426,-.023),l(.401,-.118),l(.592,.047),l(.591,-.095),l(.378,-.047),l(.291,-.094),l(.087,.212),l(.284,.095),l(-.071,.118),l(-.071,.094),l(.284,.095),l(.426,.071),l(.212,.166),l(.119,.236),l(-.402,.142),l(-.047,.284),l(.283,.354),l(.544,.331),l(.188,.142),l(.213,.024),l(0,.236),l(-.165,.236),l(-.378,0),l(-.166,0),l(.048,.094),l(.283,.142),l(.26,.354),l(.236,.024),l(.213,.212),l(.284,.118),l(.354,.024),l(.283,.047),l(-.095,.189),l(-.236,.118),l(.236,.236),l(.261,.189),l(-.166,.047),l(-.26,.095),l(.189,.071),l(.094,.213),l(-.094,.118),l(.014,.027),
+N(566.651,117.4),l(-.565,-.153),l(-.496,-.054),l(-.264,-.151),l(-.564,.227),l(-.974,.147),l(-.137,-.059),l(.129,-.176),l(-.198,-.077),l(-.678,.03),l(-.739,.315),l(-.592,.486),l(-.589,.064),l(-.745,.495),l(-.351,.03),l(-.368,-.026),l(-.128,-.084),l(-.164,-.409),l(-.199,-.521),l(.185,-.444),l(.099,-.775),l(.029,-.255),l(-.17,-.187),l(-.484,.093),l(.156,-.597),l(-.576,-.45),l(-.153,-.056),l(-.384,.016),l(-.286,.162),l(-.134,.363),l(-.435,.428),l(-.049,.425),l(.006,.255),l(-.208,.228),l(-.442,.158),l(-.133,-.013),l(-.587,-.152),l(-.292,.058),l(-.073,.185),l(.007,.311),l(-.3,.313),l(-.21,.128),l(-.381,.016),l(-.63,-.237),l(-.325,.001),l(-.581,.286),l(-.58,.343),l(-.485,.144),l(-.245,-.041),l(-.129,-.141),l(-.04,-.055),l(.375,-.843),l(-.063,-.377),l(.377,-.377),l(.283,-.503),l(.503,-.346),l(.157,-.22),l(-.126,-.283),l(-.471,-.314),l(-.126,-.409),l(.031,-.472),l(.126,-.22),l(-.126,-.22),l(-.346,0),l(-.44,-.032),l(-.157,-.157),l(-.346,-.188),l(-.251,-.283),l(.125,-.471),l(.472,-.283),l(.629,.126),l(1.069,.094),l(.282,-.188),l(.063,-.409),l(.251,-.157),l(.188,0),l(.032,-.346),l(.188,-.063),l(.251,-.063),l(-.126,-.094),l(-.534,.031),l(-.251,-.125),l(.503,-.094),l(.565,-.095),l(.472,.095),l(.062,-.126),l(.032,-.346),l(-.189,-.314),l(.283,-.314),l(-.031,-.22),l(.346,0),l(.22,.157),l(.252,.22),l(.22,-.157),l(.692,-.188),l(.471,-.346),l(.221,-.251),l(.439,.377),l(.252,.251),l(-.188,.22),l(-.409,.346),l(-.251,.126),l(.126,.188),l(.251,.063),l(.188,.283),l(.409,-.031),l(.345,.005),l(-.302,.147),l(-.441,.196),l(-.024,.246),l(-.196,0),l(-.099,-.172),l(-.516,-.196),l(-.515,-.147),l(-.981,.196),l(-.123,0),l(-.098,.27),l(.049,.196),l(-.196,.074),l(-.098,-.221),l(-.196,.196),l(-.099,.245),l(.099,.27),l(.049,.147),l(.122,.098),l(.589,-.024),l(.564,0),l(.688,-.024),l(.196,.073),l(.49,-.147),l(.368,.098),l(.147,.123),l(.073,.196),l(.393,.074),l(.295,-.049),l(-.024,-.221),l(.343,-.049),l(.442,-.123),l(.221,.024),l(.049,.147),l(.319,.123),l(.122,-.024),l(.049,.172),l(.074,.221),l(.318,-.172),l(.368,-.024),l(.172,.319),l(.196,0),l(.172,-.147),l(.834,-.221),l(.663,.073),l(.539,0),l(.344,-.171),l(.344,-.098),l(.196,.073),l(-.011,.069),l(.023,1.031),l(-.207,.223),l(.077,.305),l(.325,.394),l(.463,-.045),l(.229,-.162),l(.22,.06),l(.692,.039),l(.273,.154),l(.295,.494),l(-.009,.284),l(.028,.246),l(.152,.012),l(.049,.123),l(-.126,.428),l(.245,.237),l(-.152,.36),l(.2,.163),l(-.181,.185),l(-.08,.249),l(-.354,.136),
+N(500.121,117.572),l(-.023,-.308),l(-.275,-.035),l(-.42,-.374),l(-.099,-.421),l(.145,-.245),l(-.424,-.111),l(-.213,-.14),l(.06,-.128),l(.287,-.535),l(.229,-.281),l(-.039,-.207),l(-.288,-.203),l(-.106,.105),l(-.09,-.117),l(-.224,-.492),l(.122,-.375),l(-.264,-.67),l(.039,-.27),l(.584,-.267),l(.009,-.433),l(.231,-.141),l(.409,.023),l(.072,-.211),l(.252,.197),l(.265,.381),l(.281,.417),l(.551,.223),l(.294,.402),l(.335,.211),l(.421,.125),l(.512,.025),l(.416,-.038),l(.253,.133),l(.009,-.001),l(.377,-.03),l(.327,-.328),l(.254,-.255),l(.642,-.188),l(.374,-.445),l(1.058,-.492),l(.456,-.234),l(.306,.166),l(.351,.281),l(.487,.21),l(.061,.113),l(-.094,.155),l(-.63,.129),l(.027,.188),l(.43,.176),l(-.095,.222),l(-.532,.27),l(.13,.363),l(.374,.105),l(.356,.433),l(.268,-.016),l(.72,.317),l(.015,.007),l(-.05,.707),l(-.143,.581),l(.205,.48),l(.494,.252),l(.925,.235),l(.827,.052),l(.424,.097),l(.162,.282),l(.312,.451),l(.687,.463),l(1.902,.513),l(.841,.052),l(.438,-.059),l(1.354,-.262),l(1.192,-.148),l(1.469,-.079),l(.41,-.229),l(.185,-.354),l(-.131,-.905),l(.015,0),l(.441,.025),l(.562,-.13),l(.466,-.3),l(.621,-.654),l(.476,-.328),l(.413,-.144),l(.609,-.032),l(.78,.038),l(.333,-.03),l(.517,-.343),l(.343,-.129),l(.519,.054),l(1.055,.107),l(.402,.437),l(.708,.251),l(.822,.335),l(.788,.066),l(.5,.054),l(.66,.167),l(.597,.336),l(1.803,1.362),l(.655,.506),l(.696,.01),l(.787,-.075),l(.185,.211),l(.038,.848),l(.01,.565),l(.15,.692),l(.078,.028),l(-.145,.241),l(-.084,.339),l(-.246,.807),l(-.49,1.272),l(-.222,.297),l(-.596,.384),l(-.016,.141),l(.119,.663),l(.096,.098),l(.738,.235),l(.026,.183),l(-.661,.935),l(-.034,.155),l(.254,1.085),l(.167,1.283),l(.143,.775),l(.191,.21),l(.209,.041),l(1.198,.275),l(.401,.167),l(.144,.366),l(.046,.437),l(-.425,.553),l(-.853,.795),l(-.853,1.034),l(.802,1.083),l(.71,1.068),l(.353,.464),l(.695,.391),l(1.144,.388),l(.409,.224),l(.168,.38),l(.111,1.34),l(.185,.394),l(.652,.053),l(.186,.281),l(-.036,.974),l(-.188,.255),l(-.209,.072),l(-1,.077),l(-.697,.258),l(-.794,.47),l(-.285,.383),l(-.31,.792),l(-.049,.354),l(-.182,.954),l(-.502,.028),l(-1.079,-.153),l(-.236,-.197),l(-.605,-.253),l(-.403,-.056),l(-1.43,.003),l(-.783,-.041),l(-.602,.072),l(-.475,-.38),l(-.163,-.126),l(-.835,-.026),l(-.576,.001),l(-.465,.014),l(-.212,-.239),l(-.756,-.125),l(-.305,-.183),l(-.162,-.014),l(-.021,-.5),l(-.295,-.128),l(-.103,-.514),l(-.292,-.349),l(-.013,-.639),l(-.309,-.493),l(-.237,.012),l(-.035,-.181),l(-.526,-.126),l(-.807,-.013),l(-.374,.017),l(-.209,.222),l(-.329,.018),l(-.517,.075),l(-.188,.364),l(-.538,.138),l(-.383,.443),l(-.368,.283),l(-.253,.043),l(-1.292,-.689),l(-.958,-.104),l(-.562,-.359),l(-1.088,-.317),l(-.247,-.301),l(-.324,-.282),l(-.497,-.592),l(-.997,-.436),l(-.584,-.083),l(-.194,-.028),l(-.58,-.465),l(-.596,-1.058),l(-.635,-1.114),l(-.209,-.268),l(.005,-.593),l(-.767,-.761),l(-.506,-.719),l(-.921,.143),l(-.46,-.042),l(-.13,-.126),l(-.291,-.056),l(-.191,-.268),l(-.029,-.565),l(-.448,.1),l(-.166,.099),l(-.32,.678),l(-.195,.184),l(-.355,.012),l(-.014,-.12),l(-.351,-.224),l(-.686,-.546),l(.064,-.212),l(-.007,-.395),l(-.164,-.465),l(-.215,-.013),l(-.551,.003),l(-.034,-.325),l(.055,-.579),l(.197,-.622),l(.014,-.508),l(-.112,-.239),l(-.29,-.28),l(-.774,-.603),l(-.436,-.209),l(-1.242,-.925),l(-.533,-.025),l(-.321,.115),L(503,127.106),l(.033,-.819),l(-1.02,-.954),l(-.312,-.351),l(-.002,-.184),l(.133,-.875),l(.235,-.763),l(1.142,-.98),l(-.422,-.761),l(.013,-.254),l(.468,-.596),l(-1.067,-.107),l(-.761,-.208),l(-.065,-.198),l(-.563,-1.086),l(-.69,-1.397),
+N(535.734,133.791),l(.853,-1.034),l(.853,-.795),l(.425,-.553),l(-.046,-.437),l(-.144,-.366),l(-.401,-.167),l(-1.198,-.275),l(-.209,-.041),l(-.191,-.21),l(-.143,-.775),l(-.167,-1.283),l(-.254,-1.085),l(.034,-.155),l(.661,-.935),l(-.026,-.183),l(-.738,-.235),l(-.096,-.098),l(-.119,-.663),l(.016,-.141),l(.596,-.384),l(.222,-.297),l(.49,-1.272),l(.246,-.807),l(.084,-.339),l(.145,-.241),l(.193,.112),l(.937,.193),l(.999,.348),l(.573,.082),l(.534,-.031),l(.636,-.3),l(.22,-.199),l(.001,-.466),l(.119,-.199),l(.568,-.159),l(1.985,-.689),l(.508,-.243),l(.103,-.128),l(.203,-.991),l(.432,-.809),l(1.135,-.205),l(.417,-.2),l(.445,-.356),l(.565,.294),l(1.454,.244),l(.096,.016),l(.646,.011),l(1.217,.05),l(.236,.126),l(.351,.48),l(.04,.055),l(.129,.141),l(.245,.041),l(.485,-.144),l(.58,-.343),l(.581,-.286),l(.325,-.001),l(.63,.237),l(.381,-.016),l(.21,-.128),l(.3,-.313),l(-.007,-.311),l(.073,-.185),l(.292,-.058),l(.587,.152),l(.133,.013),l(.442,-.158),l(.208,-.228),l(-.006,-.255),l(.049,-.425),l(.435,-.428),l(.134,-.363),l(.286,-.162),l(.384,-.016),l(.153,.056),l(.576,.45),l(-.156,.597),l(.484,-.093),l(.17,.187),l(-.029,.255),l(-.099,.775),l(-.185,.444),l(.199,.521),l(.164,.409),l(.128,.084),l(.368,.026),l(.351,-.03),l(.745,-.495),l(.589,-.064),l(.592,-.486),l(.739,-.315),l(.678,-.03),l(.198,.077),l(-.129,.176),l(.137,.059),l(.974,-.147),l(.564,-.227),l(.264,.151),l(.496,.054),l(.565,.153),l(-.192,.145),l(-.574,-.059),l(.01,.269),l(.236,.012),l(.048,.088),l(-.148,.142),l(-.358,.004),l(-.455,.297),l(-.332,-.005),l(-.338,.179),l(-.647,-.144),l(-1.345,.012),l(-1.148,.152),l(-.53,.292),l(-.272,.19),l(-.559,.395),l(-.246,-.023),l(-.258,.214),l(-.464,.413),l(.01,.32),l(.411,.271),l(.01,.336),l(.232,.171),l(-.119,.483),l(.198,.477),l(-.324,.426),l(-.524,.355),l(-.4,.341),l(-.13,.283),l(.223,.478),l(.033,.31),l(-.289,.255),l(-.513,.215),l(-.698,-.039),l(-.997,-.122),l(-.355,.129),l(.35,.336),l(.365,.407),l(.129,.281),l(.088,.437),l(-.199,.255),l(-.315,.115),l(-.513,.031),l(-.416,.115),l(-.292,.228),l(-.224,.424),l(-.288,.834),l(-.139,1.214),l(-.021,.084),l(-.34,.383),l(-.237,.086),l(-1.001,-.375),l(-.562,-.025),l(-.559,.243),l(-.362,.271),l(-.321,.693),l(-.254,.086),l(-.516,-.082),l(-.644,-.039),l(-.283,.072),l(-.597,.441),l(-.412,.369),l(-.188,.34),l(-.232,.876),l(-.099,.903),l(-.069,.184),l(-.247,.156),l(-1.066,.274),l(-1.183,.19),l(-.964,.175),l(-1.234,.12),l(-1.005,-.135),l(-.349,.002),l(-1.187,.218),l(-.742,-.024),l(-.541,-.039),l(-.854,-.235),l(-1.069,-.248),l(-.63,-.194),l(-.887,-.32),
+N(486.696,126.295),l(5.257,-2.711),l(.589,-2.701),l(-.024,-.467),l(-.187,-.508),l(.009,-.255),l(.23,-.355),l(.31,-.214),l(.866,-.174),l(.457,-.371),l(.944,-.883),l(-.059,-.24),l(.23,-.043),l(.266,-.143),l(.437,-.094),l(.304,.16),l(.364,-.032),l(.811,.153),l(.343,.023),l(.244,-.234),l(.366,.082),l(.274,.151),l(-.03,.259),l(.102,.269),l(.318,.105),l(.164,-.126),l(.433,-.388),l(.407,.016),l(.69,1.397),l(.563,1.086),l(.065,.198),l(.761,.208),l(1.067,.107),l(-.468,.596),l(-.013,.254),l(.422,.761),l(-1.142,.98),l(-.235,.763),l(-.133,.875),l(.002,.184),l(.312,.351),l(1.02,.954),L(503,127.106),l(.075,.155),l(.321,-.115),l(.533,.025),l(1.242,.925),l(.436,.209),l(.774,.603),l(.29,.28),l(.112,.239),l(-.014,.508),l(-.197,.622),l(-.055,.579),l(.034,.325),l(.551,-.003),l(.215,.013),l(.164,.465),l(.007,.395),l(-.064,.212),l(.686,.546),l(.351,.224),l(.014,.12),l(-.096,.003),l(-.664,.101),l(-.408,-.056),l(-.157,.057),l(-.103,.127),l(-1.271,.044),l(-.518,.13),l(-.343,.693),l(-.463,.609),l(-.521,.568),l(-4.048,-.132),l(-1.557,-.697),l(-.812,-.277),l(-.118,-.253),l(-.047,-.818),l(.118,-.396),l(-.135,-.366),l(-.973,.048),l(-.141,-.07),l(-.399,-.633),l(-.258,-.196),l(-2.44,-1.101),l(-1.14,-.473),l(-2.034,-.934),l(-.757,-.222),l(-1.129,-.459),l(-.093,-.056),l(-.093,-.056),l(-.311,-.69),l(-.87,-1.632),
+N(479.916,127.377),l(-.082,-.085),l(.047,-.122),l(-.021,-.183),l(-.201,-.128),l(-.183,-.346),l(.398,-.209),l(.041,-.099),l(.526,-.396),l(-.048,-.058),l(-.223,-.099),l(.077,-.151),l(.298,-.25),l(.599,-.006),l(-.14,-.146),l(-.035,-.046),l(.078,-.111),l(.177,-.163),l(.169,-.116),l(.299,-.239),l(-.068,-.058),l(.023,-.163),l(-.09,-.047),l(-.031,-.221),l(-.241,-.157),l(-.222,-.058),l(.204,-.204),l(-.125,-.052),l(-.053,-.116),l(-.12,.058),l(-.335,.052),l(-.388,-.023),l(-.225,-.564),l(.129,-.593),l(.072,-.064),l(-.1,-.507),l(-.42,-.326),l(.126,-.093),l(.036,-.152),l(.117,-.128),l(-.093,-.222),l(.107,-.012),l(.259,-.32),l(-.061,-.112),l(.311,-.001),l(.39,.125),l(.114,-.127),l(.171,.041),l(.2,-.169),l(.156,-.374),l(.627,-.127),l(-.243,-.423),l(-.102,-.452),l(.055,-.319),l(.142,.035),l(.222,-.001),l(.777,.166),l(.575,.025),l(.746,-.075),l(.929,-.373),l(.278,-.03),l(1.532,.444),l(.556,.153),l(1.104,-.176),l(.567,-.13),l(1.498,-.673),l(.439,-.073),l(.747,.123),l(.711,.039),l(1.185,-.224),l(.693,-.304),l(.24,-.292),l(.207,.023),l(.064,.245),l(.059,.24),l(-.944,.883),l(-.457,.371),l(-.866,.174),l(-.31,.214),l(-.23,.355),l(-.009,.255),l(.187,.508),l(.024,.467),l(-.589,2.701),l(-5.257,2.711),l(-.161,.071),l(-2.96,1.541),l(-1.139,.656),l(-.253,.016),l(-.365,-.167),l(-1.902,-1.034),
+N(426.068,126.434),l(-.093,.981),l(.064,.564),l(-.093,.269),l(-.802,.428),l(-.579,.314),l(-1.473,1.138),l(-.126,.354),l(.274,.973),l(-.147,.537),l(-.155,.227),l(-.864,.598),l(-.22,.143),l(-.564,-1.536),l(-.699,-2.242),l(-.323,-.464),l(-.363,-.252),l(-.432,-.181),l(-.484,-.831),l(-.225,-.465),l(-.363,-.28),l(-.452,-.097),l(-.336,-.774),l(-.301,-.888),l(.112,-.509),l(1,-.853),l(.414,-.355),l(.163,-.411),l(.048,-.537),l(-.052,-.594),l(-.026,-.892),l(-.012,-1.429),l(.114,-.439),l(.685,-.627),l(.012,-.184),l(.508,-.185),l(.633,-.455),l(.591,-.228),l(.703,-.016),l(.643,.183),l(.247,.212),l(.059,.241),l(.25,.538),l(.27,.084),l(.417,-.171),l(.584,-.44),l(.401,-.17),l(.034,.354),l(-.265,.567),l(-.638,.511),l(-.275,.468),l(.005,.283),l(.202,.438),l(.508,.466),l(.351,.127),l(.303,.848),l(-.094,.212),l(-.541,.764),l(-.59,.34),l(-1.017,.92),l(-.216,.339),l(.287,.451),l(.587,.55),l(.528,.295),l(.284,.056),l(.396,-.227),l(.316,.084),l(.244,.635),l(.582,.239),
+N(381.402,139.704),l(-.027,-.876),l(.069,-2.006),l(.037,-.382),l(.686,-.314),l(1.512,-.998),l(.963,-.542),l(1.265,.078),l(.397,-.059),l(.181,-.693),l(.864,-.033),l(.777,-.174),l(.527,-.229),l(.524,-.356),l(.484,-.652),l(1.109,-.332),l(1.52,-.701),l(.129,-.227),l(-.296,-.62),l(-.025,-.396),l(.079,-.227),l(.265,-.114),l(1.186,-.12),l(.381,-.186),l(.309,-.553),l(1.022,.022),l(.67,-.018),l(1.826,.004),l(.34,-1.033),l(-.07,-.211),l(-.507,-.322),L(397,126.646),l(-.158,-.465),l(.016,-1.271),l(.022,-.833),l(-.165,-.889),l(-.189,-.211),l(-.563,-.279),l(-.259,-.508),l(.351,0),l(.66,-.143),l(.541,-.256),l(.369,-.566),l(.405,-.312),l(.509,-.086),l(.407,-.157),l(.679,-.27),l(.324,.226),l(.176,.017),l(.249,.024),l(.238,-.142),l(.407,-.51),l(.613,-.426),l(.682,-.355),l(.614,-.171),l(1.16,-.116),l(1.587,-.06),l(.513,-.072),l(.634,-.312),l(.578,.211),l(.564,-.072),l(.585,-.313),l(.343,-.1),l(.939,.012),l(.513,-.015),l(.307,.056),l(.221,.042),l(.322,.113),l(.816,.168),l(.529,-.015),l(.772,-.171),l(.705,-.2),l(.612,-.554),l(.994,.508),l(.339,.099),l(.312,-.143),l(.314,-.241),l(.228,-.156),l(.528,.042),l(.388,.197),l(.162,.269),l(.269,.126),l(.516,-.086),l(1.093,-.158),l(-.012,.184),l(-.685,.627),l(-.114,.439),l(.012,1.429),l(.026,.892),l(.052,.594),l(-.048,.537),l(-.163,.411),l(-.414,.355),l(-1,.853),l(-.112,.509),l(.301,.888),l(.336,.774),l(.452,.097),l(.363,.28),l(.225,.465),l(.484,.831),l(.432,.181),l(.363,.252),l(.323,.464),l(.699,2.242),l(.564,1.536),l(-.204,.156),l(-.241,.383),l(.88,1.605),l(.147,.833),l(.052,.691),l(-.1,.862),l(.101,.748),l(-.16,.622),l(-.158,.495),l(.457,1.156),l(-.061,.664),l(-.086,.17),l(-.666,.47),l(-.249,.128),l(-.152,.283),l(1.272,1.702),l(.249,.917),l(.562,.873),l(.244,.154),l(.544,-.201),l(.702,.165),l(1.028,.347),l(.178,.168),l(.86,1.506),l(.098,.07),l(-.265,.186),l(-1.632,.843),l(-4.012,2.241),l(-1.607,.956),l(-2.308,1.454),l(-.834,.655),l(-3.084,2.617),l(-1.82,.364),l(-1.672,.321),l(-2.176,.408),l(-.146,-.564),l(.161,-.679),l(-.099,-.522),l(-.277,-.352),l(-.309,-.111),l(-.748,-.024),l(-.375,-.167),l(-.588,-.562),l(-.47,.314),l(-.229,-.027),l(-1.111,-1.039),l(-.393,-.28),l(-.082,-.183),l(.096,-.396),l(-.181,-.253),l(-2.472,-1.469),l(-.397,-.253),l(-1.292,-.824),l(-1.924,-1.26),l(-3.283,-2.241),l(-.811,-.575),l(-2.054,-1.344),l(-.895,-.531),l(-.1,-.084),l(-1.414,-.91),l(-4.12,-2.42),l(-2.829,-1.509),
+N(395.704,122.189),l(.259,.508),l(.563,.279),l(.189,.211),l(.165,.889),l(-.022,.833),l(-.016,1.271),l(.158,.465),l(.598,.788),l(.507,.322),l(.07,.211),l(-.34,1.033),l(-1.826,-.004),l(-.67,.018),l(-1.022,-.022),l(-.309,.553),l(-.381,.186),l(-1.186,.12),l(-.265,.114),l(-.079,.227),l(.025,.396),l(.296,.62),l(-.129,.227),l(-1.52,.701),l(-1.109,.332),l(-.484,.652),l(-.524,.356),l(-.527,.229),l(-.777,.174),l(-.864,.033),l(-.181,.693),l(-.397,.059),l(-1.265,-.078),l(-.963,.542),l(-1.512,.998),l(-.686,.314),l(-.037,.382),l(-.069,2.006),l(-1.42,.008),l(-1.718,-.004),l(-2.677,.001),l(-2.511,0),l(-1.635,.04),l(.141,-.28),l(.431,-.411),l(.427,-.085),l(1.296,-.285),l(1.143,-.455),l(.453,-.312),l(1.147,-.85),l(1.149,-.878),l(1.043,-1.104),l(.46,-.693),l(.133,-.509),l(-.05,-.494),l(-.427,-.776),l(-.09,-.678),l(.099,-.508),l(.396,-.636),l(.706,-.863),l(.211,-.65),l(-.063,-.367),l(.071,-.353),l(1.285,-1.203),l(.724,-.481),l(.916,-.327),l(1.266,-.469),l(.73,-.397),l(.558,-.552),l(.537,-.736),l(.466,-.905),l(.829,-1.925),l(.269,-.128),l(.54,-.171),l(.19,.127),l(.684,.848),l(.138,.099),l(1.148,.507),l(.661,-.001),l(.595,.042),l(1.304,-.074),l(.522,-.228),l(.437,-.27),l(.398,.551),l(.256,.099),l(.798,.097),l(.361,0),
+N(480.248,123.437),l(.388,.023),l(.335,-.052),l(.12,-.058),l(.053,.116),l(.125,.052),l(-.204,.204),l(.222,.058),l(.241,.157),l(.031,.221),l(.09,.047),l(-.023,.163),l(.068,.058),l(-.299,.239),l(-.169,.116),l(-.177,.163),l(-.078,.111),l(.035,.046),l(.14,.146),l(-.599,.006),l(-.298,.25),l(-.077,.151),l(.223,.099),l(.048,.058),l(-.526,.396),l(-.041,.099),l(-.398,.209),l(-.07,-.023),l(-.088,.041),l(-.067,.193),l(-.009,.167),l(-.355,.07),l(-.07,-.099),l(-.151,-.022),l(-.372,.051),l(.26,-.291),l(.097,-.361),l(.169,-.227),l(.328,-.681),l(-.017,-.232),l(.181,0),l(.138,-.192),l(.072,-.32),l(.018,-.32),l(.409,-.431),l(.232,-.07),l(.116,-.174),l(-.048,-.157),
+N(184.444,142.729),l(-.367,.82),l(-.518,.821),l(-.186,.763),l(-.179,1.159),l(.017,1.851),l(-.133,1.187),l(-.016,1.13),l(.564,1.737),l(.275,.805),l(.624,.945),l(.76,.903),l(.191,.452),l(.481,.521),l(.529,.974),l(.729,1.228),l(.375,.296),l(.677,.069),l(.436,-.015),l(.577,.154),l(.593,.451),l(.503,.508),l(.773,.069),l(1.016,-.242),l(1.55,-.456),l(1.396,-.3),l(.803,-.157),l(-.02,.542),l(.838,.223),l(.264,-.286),l(.293,-.199),l(-.104,-.247),l(-.393,-.175),l(1.073,-.62),l(.633,-.62),l(.086,-.827),l(.498,-.429),l(-.094,-.477),l(.092,-1.145),l(.254,-.699),l(.625,-.334),l(.164,-.043),l(.757,-.198),l(.701,-.1),l(1.088,-.229),l(1.016,-.37),l(.594,-.058),l(.499,.056),l(1.139,.181),l(.502,-.194),l(.378,.093),l(.62,.507),l(.047,.297),l(-.079,.424),l(-.298,.382),l(-.541,.496),l(-.433,.425),l(-.317,.445),l(-.02,.7),l(-.254,.297),l(-.188,.354),l(.155,.155),l(.337,-.138),l(-.101,.652),l(-.262,1.196),L(205.356,159),l(-.062,.24),l(-.34,-.534),l(-.167,-.452),l(-.072,-.155),l(-.386,.34),l(-.02,.549),l(-.437,.016),l(-.178,.447),l(-.599,.857),l(-.386,-.27),l(-.278,.095),l(.025,.329),l(-2.332,-.006),l(-1.792,-.005),l(-.04,1.24),l(-.999,.032),l(.396,.223),l(.495,.541),l(.624,.231),l(.359,.69),l(.532,.223),l(-.211,.683),l(-1.762,-.007),l(-1.06,.007),l(-1.076,1.812),l(.305,.397),l(-.207,.238),l(.054,.553),l(.044,.454),l(-.704,-.555),l(-.952,-.888),l(-.956,-.761),l(-1.069,-.859),l(-.534,-.352),l(-.053,-.071),l(-.639,-.252),l(-1.048,-.21),l(-.657,.044),l(-.817,.397),l(-1.1,.567),l(-.756,.256),l(-.931,-.069),l(-.724,-.21),l(-.48,-.197),l(-1.305,-.195),l(-.588,-.267),l(-.644,-.422),l(-.935,-.521),l(-.785,-.267),l(-1.711,-.392),l(-.963,-.365),l(-.722,-.366),l(-1.074,-.436),l(-.592,-.352),l(-1.123,-1),l(-.207,-.07),l(-.606,.058),l(-.689,-.14),l(-1.835,-.575),l(-.565,-.536),l(-.503,-.634),l(-.495,-.395),l(-1.049,-.577),l(-.619,-.267),l(-.5,-.494),l(-.742,-.987),l(-.363,-.55),l(-.038,-.113),l(.15,-.155),l(.504,-.086),l(.18,-.17),l(.047,-.184),l(-.331,-.367),l(.457,-.679),l(.041,-.381),l(-.172,-.466),l(-.744,-.959),l(.121,-.297),l(.146,-.17),l(-.07,-.268),l(-.665,-.62),l(-1.495,-1.777),l(-.546,-.493),l(-.963,-1.058),l(-.474,-.522),l(-.815,-.578),l(-.322,-.197),l(-.158,-.268),l(-.058,-.48),l(-.144,-.183),l(-.329,-.197),l(-.609,-.197),l(-.408,-.31),l(-.366,-.522),l(-.271,-.028),l(-.414,.114),l(-.238,-.155),l(-.163,-.367),l(-.005,-.325),l(.459,-.736),l(-.126,-.339),l(-.751,-.62),l(-.439,.255),l(-.375,-.621),l(-.118,-.353),l(-.359,-.211),l(-.61,-.168),l(-.319,-.296),l(-.125,-.254),l(.05,-.381),l(.084,-.269),l(-.185,-.226),l(-.561,-.21),l(-.46,-.098),l(-.46,-.253),l(-.935,-.86),l(-.478,-.706),l(-.281,-.551),l(-.646,-.832),l(-.736,-1.073),l(-.184,-.423),l(-.38,-.678),l(-.242,-.338),l(-.152,-.452),l(.042,-.509),l(.032,-.311),l(-.56,-.239),l(-.795,-.196),l(-.06,-.452),l(-.128,-.155),l(-.458,-.183),l(-.289,.326),l(-.251,.043),l(-1.43,-.647),l(-.285,1.004),l(-.045,.438),l(.033,.084),l(.265,.339),l(.264,.296),l(.028,1.046),l(.088,.509),l(.51,.677),l(.143,.169),l(.643,.267),l(.601,.536),l(.525,.663),l(.602,1.214),l(.44,.282),l(.328,.042),l(.237,.169),l(.325,1.398),l(.102,.169),l(.246,.155),l(.497,.056),l(.133,.056),l(.215,.438),l(.161,.65),l(.445,.79),l(.49,-.071),l(.223,-.142),l(.245,.452),l(.344,1.469),l(.531,1.059),l(.649,1.2),l(.069,.593),l(-.014,.522),l(.26,.353),l(.378,.154),l(.389,-.17),l(.234,-.198),l(.588,.804),l(.258,.579),l(.464,.253),l(.281,.014),l(.133,.311),l(-.196,.537),l(-.136,.127),l(-.691,.595),l(-.254,-.042),l(-.251,-.409),l(-.24,-.734),l(-.617,-.578),l(-.625,-.309),l(-.516,-.479),l(-.834,-.507),l(-1.143,-.986),l(-.416,-.451),l(-.162,-.269),l(.216,-.989),l(-.035,-.254),l(-.488,-1.002),l(-.238,-.381),l(-.327,-.282),l(-.44,-.098),l(-.5,-.31),l(-.675,-.677),l(-.305,.142),l(-.363,-.056),l(-1.262,-.746),l(-.722,-.31),l(-.896,-.973),l(-.139,-.127),l(-.246,-.254),l(.679,.15),l(.599,.013),l(.588,-.284),l(.244,-.326),l(.093,-.636),l(-.01,-.184),l(-.458,-.635),l(-.466,-.452),l(-1.1,-.888),l(-.986,-.493),l(-.402,-.338),l(-.203,-.522),l(-.272,-.649),l(-.091,-.155),l(-.447,-.126),l(-.15,-.353),l(-.026,-.594),l(-.203,-.395),l(-.623,-.734),l(-.434,-.706),l(-.003,-.254),l(.212,-.382),l(-.777,-.62),l(-.254,-.325),l(-.22,-.485),l(.34,-.017),l(2.367,-.155),l(2.381,-.084),l(.316,.31),l(.267,.154),l(1.186,.39),l(2.811,.933),l(3.516,1.112),l(.338,.055),l(1.662,.019),l(1.544,.02),l(.966,.037),l(1.867,-.011),l(.213,-.101),l(.096,-.892),l(1.858,.003),l(1.892,.046),l(.209,.112),l(.631,.662),l(.766,.632),l(.837,.519),l(.708,.491),l(.179,.226),l(.284,.678),l(.318,.847),l(.445,.549),l(1.092,.659),l(1.104,.503),l(.337,.069),l(.501,.011),l(.416,-.158),l(.283,-.37),l(.418,-.413),l(.576,-.541),l(.468,-.201),l(.643,-.018),l(.475,.082),l(.783,.321),l(.412,.252),l(.363,.366),l(.663,1.029),l(.744,1.227),l(.845,1.042),l(.657,.576),l(.268,.253),l(.078,.467),l(.332,.932),l(.336,.592),l(.375,.365),l(.921,.32),l(1.029,.56),l(.264,.069),l(.416,-.116),l(.296,-.001),l(.816,.377),l(.347,.119),
+N(507.047,133.665),l(.055,.197),l(.134,.691),l(-.336,-.028),l(-.513,.513),l(.421,.194),l(.418,-.206),l(.306,.021),l(.698,1.84),l(-.644,.044),l(-1.07,-.05),l(-.185,-.239),l(-.334,-.619),l(-.408,-.054),l(-1.657,-.259),l(.521,-.568),l(.463,-.609),l(.343,-.693),l(.518,-.13),l(1.271,-.044),
+N(606.155,150.953),l(.595,.152),l(.255,.14),l(.25,-.129),l(.273,-.368),l(.015,-.678),l(-.152,-.93),l(.228,-.185),l(.401,-.144),l(.191,-.354),l(-.146,-1.594),l(.133,-.283),l(.811,.32),l(.391,.11),l(.309,.013),l(.17,-.128),l(1.148,-2.25),l(0,-.324),l(-.192,-.408),l(.045,-.212),l(.938,-1.134),l(.136,-.382),l(-.057,-.761),l(.197,-.354),l(1.446,-.883),l(.719,-.512),l(.312,-.129),l(.558,.082),l(.853,.221),l(.295,-.058),l(-.184,-.718),l(.072,-.283),l(.596,-.582),l(.112,-.24),l(.018,-.508),l(.001,-.127),l(.306,-.34),l(.277,-.044),l(.504,.279),l(.397,.435),l(.243,.901),l(.217,.309),l(.287,.041),l(.504,-.031),l(.146,.14),l(.195,1.649),l(.02,.875),l(-.353,.862),l(-.429,.722),l(-.611,.525),l(-.487,.271),l(-.191,.198),l(-.617,.85),l(.075,.465),l(.163,.705),l(-.224,.58),l(0,.268),l(.216,.069),l(.312,-.086),l(.819,-.442),l(.771,-.089),l(.479,-.017),l(.156,.126),l(.277,1.762),l(.202,.324),l(.554,-.074),l(.521,.096),l(.033,.268),l(-.729,1.584),l(.117,.352),l(.228,.098),l(.507,-.003),l(.481,-.045),l(.291,.379),l(.341,.746),l(.378,.266),l(.246,.083),l(.647,-.159),l(.628,-.413),l(.111,.38),l(.153,.239),l(-.502,.355),l(-.53,.61),l(-.442,.581),l(-.582,.455),l(-.193,.185),l(-.08,.085),l(-.158,.071),l(-.645,.06),l(-.436,.172),l(-.528,.342),l(-.394,.595),l(-1.078,.316),l(-.62,.018),l(-.474,-.082),l(-.362,.411),l(-.143,.368),l(-.036,.819),l(-.114,.509),l(.064,.409),l(-.086,.24),l(-.163,.001),l(-.588,.131),l(.739,.884),l(.069,.183),l(.112,.875),l(.254,.14),l(1.091,.953),l(.148,.324),l(.646,1.041),l(.163,.338),l(-.194,.241),l(-.451,.229),l(-.128,.226),l(.231,1.185),l(-.171,.198),l(-.812,.428),l(.178,.38),l(.6,1.436),l(.54,.477),l(.606,.604),l(.203,.479),l(.088,.663),l(-.086,.636),l(.006,.254),l(.488,1.183),l(.586,1.225),l(-.077,.297),l(-1.011,1.559),l(-1.01,1.7),l(-.098,.374),l(-.359,-.181),l(-.075,-.805),l(.461,-.665),l(.174,-.495),l(.122,-.777),l(.287,-.466),l(-.512,-.027),l(-.104,-.084),l(-.004,-.282),l(.195,-.509),l(-.177,-1.524),l(-.246,-.832),l(-.639,-1.185),l(-.488,-1.312),l(-.347,-.846),l(-.179,-.875),l(-.174,-1.736),l(-.117,-.677),l(-.034,-.564),l(-.051,-.212),l(-.344,-.084),l(-.148,-.098),l(-.304,-.917),l(-.516,-.677),l(-.226,-.225),l(-.247,.029),l(-.081,.988),l(-.158,.424),l(-.43,.41),l(-.59,.284),l(-1.089,.511),l(-.359,.622),l(-.298,.297),l(-.196,.142),l(-.237,-.282),l(-.007,-.438),l(-.212,.015),l(-.338,.354),l(-.321,-.013),l(-.166,-.211),l(.147,-.495),l(-.001,-.113),l(-.621,.171),l(-.276,.127),l(-.247,.283),l(-.355,-.126),l(-.002,-.466),l(.553,-1.54),l(.162,-.791),l(.001,-.889),l(-.101,-1.059),l(-.384,-.973),l(-.431,-1.072),l(-.196,-.296),l(-.281,.537),l(-.32,-.126),l(-.526,-.366),l(.482,-.17),l(.312,-.015),l(-.149,-.479),l(-.054,-.268),l(-.684,-.775),l(-.182,-.183),l(-.19,-.028),l(-.407,.1),l(-.38,-.267),l(.086,-.438),l(-.026,-.141),l(-.209,-.112),l(-.365,.043),l(-.577,-.465),l(-.504,-.606),l(-.117,-.244),l(.252,-.341),l(.801,-.527),l(-.194,-1.607),
+N(605.297,153.429),l(-.126,-.264),l(-.269,-.55),l(-.223,-1.213),l(-.611,-1.41),l(-.357,-.395),l(-.73,.354),l(-.393,0),l(-.034,-.084),l(-.242,-.211),l(-.356,-.592),l(-.124,-.042),l(-.152,.127),l(-.026,.537),l(.374,.79),l(-.006,.424),l(-.143,.169),l(-.455,.086),l(-.235,.537),l(-.261,.1),l(-.255,-.437),l(-.311,-.395),l(-.073,-.057),l(-.163,.669),l(-.28,.249),l(-.203,.043),l(-.271,-.536),l(-.495,.636),l(-.359,-.265),l(-.147,-.532),l(-.402,-1.775),l(-.325,-1.409),l(-.352,-.45),l(-.04,-.254),l(.505,-.765),l(.029,-.269),l(-.193,-.21),l(-1.042,-.431),l(-.339,-.323),l(.548,-.61),l(.4,-.299),l(.502,-.13),l(.382,-.101),l(.047,-.155),l(-.126,-.112),l(-1.224,-.938),l(-.494,-.237),l(-.083,-.155),l(.124,-.283),l(.555,-.525),l(.234,-.171),l(1.252,.303),l(.339,.266),l(.372,.266),l(.489,-.06),l(.417,.054),l(.129,.324),l(.053,.479),l(.079,.719),l(.095,.099),l(.537,.109),l(.547,.053),l(.916,-.062),l(.559,-.003),l(2.473,.198),l(.111,.098),l(.057,.127),l(-.012,.79),l(-.159,.34),l(-.938,.767),l(-.498,.13),l(-.651,.356),l(-.131,.283),l(.009,.522),l(.001,.381),l(.23,.281),l(.249,.267),l(.529,.448),l(.224,-.354),l(.395,-1.159),l(.281,-.115),l(.4,-.044),l(.064,.578),l(.627,2.479),l(.037,.466),l(.194,1.607),l(-.801,.527),l(-.252,.341),
+N(627.408,186.411),l(-.086,.337),l(-.495,.35),l(-.11,.575),l(-.644,.089),l(-.05,-.478),l(-.309,-.163),l(-.279,.28),l(-.244,.394),l(-.204,-.083),l(-.118,-.239),l(.213,-.398),l(-.041,-.21),l(-.055,-.226),l(-.261,-.238),l(-.447,-.119),l(-.106,-.466),l(-.571,.013),l(-.448,.17),l(.013,-.104),l(.128,-.297),l(-.15,-.183),l(-.411,.212),l(-.301,-.07),l(-.38,-.38),l(-.116,-.508),l(.064,-.282),l(-.151,-.438),l(-.229,-.169),l(-.388,.043),l(-.39,-.719),l(-.209,-.508),l(-.3,-.324),l(-.311,-.155),l(-.456,-.395),l(-.343,.1),l(-.218,.142),l(-.216,-.381),l(-.04,-.607),l(.163,-.749),l(.559,-1.738),l(.29,-.848),l(-.087,-.044),l(.098,-.374),l(1.01,-1.7),l(1.011,-1.559),l(.077,-.297),l(-.586,-1.225),l(-.488,-1.183),l(-.006,-.254),l(.086,-.636),l(-.088,-.663),l(-.203,-.479),l(-.606,-.604),l(-.54,-.477),l(-.6,-1.436),l(-.178,-.38),l(.812,-.428),l(.171,-.198),l(-.231,-1.185),l(.128,-.226),l(.451,-.229),l(.194,-.241),l(-.163,-.338),l(-.646,-1.041),l(-.148,-.324),l(-1.091,-.953),l(-.254,-.14),l(-.112,-.875),l(-.069,-.183),l(-.739,-.884),l(.588,-.131),l(.163,-.001),l(.086,-.24),l(-.064,-.409),l(.114,-.509),l(.036,-.819),l(.143,-.368),l(.362,-.411),l(.474,.082),l(.62,-.018),l(1.078,-.316),l(.394,-.595),l(.528,-.342),l(.436,-.172),l(.645,-.06),l(.158,-.071),l(.08,-.085),l(.541,.166),l(.295,.182),l(.118,.168),l(.01,.423),l(-.106,.805),l(.066,.367),l(.186,.154),l(.423,-.003),l(.489,-.2),l(.414,-.045),l(.045,.113),l(.249,1.311),l(-.085,.41),l(-.528,1.569),l(-.117,.438),l(-.027,.494),l(.145,.324),l(.481,.138),l(.37,-.411),l(1.173,-1.178),l(.346,-.03),l(.835,.348),l(.59,.265),l(.223,-.072),l(.543,-.257),l(.2,-.538),l(.286,-.453),l(.403,.012),l(.893,.192),l(.266,.153),l(.052,.282),l(.285,.535),l(.688,.659),l(.435,.632),l(.058,1.524),l(.107,.366),l(.255,.464),l(.979,1.279),l(.419,.703),l(.157,.507),l(.002,.945),l(-.121,.438),l(-.808,.64),l(-.301,-.167),l(-.599,-.109),l(-.575,-.039),l(-.558,.074),l(-.798,-.066),l(-1.172,.091),l(-.383,.101),l(-.521,.441),l(-.92,1.233),l(-.146,.297),l(-.076,.382),l(.026,.635),l(.219,.648),l(.487,.717),l(.16,.479),l(-.146,.176),l(-.026,-.063),l(-.286,-.183),l(-.458,-.084),l(-.9,-.887),l(-.434,-.154),l(-.304,-.014),l(-.572,.227),l(-.391,-.112),l(-.29,-.141),l(-.337,-.014),l(0,-.282),l(.19,-1.243),l(-.107,-.184),l(-.719,-.055),l(-.248,-.084),l(-.521,.043),l(-.443,.212),l(-.244,.297),l(.207,.593),l(-.103,.339),l(-.318,.707),l(.083,.579),l(.054,.41),l(-.293,.664),l(-.583,1.187),l(-.7,1.682),l(-.255,1.314),l(.104,1.171),l(.172,.296),l(.229,.169),l(.55,-.072),l(.396,-.142),l(.252,.07),l(.135,.353),l(.009,.325),l(-.08,.466),l(.141,.282),l(.178,.211),l(.271,-.094),l(.17,.46),l(.209,.974),l(-.032,.254),l(.127,.737),l(.434,.871),l(.167,.155),l(.801,.281),l(.539,.112),l(.467,-.058),l(.294,.197),l(.266,.612),l(.664,.544),l(.212,.145),
+N(204.31,158.989),l(-.175,.412),l(.612,-.173),l(.026,.429),l(-.419,1.241),l(.178,.269),l(-.237,.795),l(.189,.318),l(-.092,.397),l(-.358,.875),l(-.3,.35),l(-.36,.032),l(-.054,.286),l(-.388,.238),l(0,.286),l(-.69,.016),l(.215,-4.297),l(-.025,-.329),l(.278,-.095),l(.386,.27),l(.599,-.857),l(.178,-.447),l(.437,-.016),
+N(200.276,169.481),l(-.151,-.056),l(-.928,-.342),l(-.614,.032),l(-.766,-.032),l(-.608,-.239),l(-.909,-.656),l(-.513,-.419),l(-.044,-.454),l(-.054,-.553),l(.207,-.238),l(-.305,-.397),l(1.076,-1.812),l(1.06,-.007),l(1.762,.007),l(.211,-.683),l(-.532,-.223),l(-.359,-.69),l(-.624,-.231),l(-.495,-.541),l(-.396,-.223),l(.999,-.032),l(.04,-1.24),l(1.792,.005),l(2.332,.006),l(-.215,4.297),l(.69,-.016),l(.303,.095),l(.311,.302),l(.14,-.191),l(-.066,-.381),l(.336,.157),l(.458,.367),l(-1.507,1.208),l(-.499,.238),l(-.177,.493),l(.162,.604),l(-.438,.302),l(-.467,.048),l(-.043,.254),l(.164,.159),l(-.351,.111),l(-.184,.302),l(-.22,-.016),l(-.565,.461),l(-.012,.223),
+N(204.413,165.093),l(.312,-.03),l(.612,-.27),l(.639,-.058),l(.743,.126),l(.478,.069),l(1.443,.04),l(.699,-.228),l(.379,-.199),l(.567,.267),l(.788,-.03),l(.763,-.101),l(.63,-.001),l(.5,.126),l(.564,.253),l(-.038,.353),l(-.102,.226),l(.228,.282),l(.787,.238),l(.557,.069),l(.244,.524),l(-1.425,.486),l(-.424,.229),l(-.248,.086),l(-.463,-.097),l(-.328,-.182),l(-.259,-.013),l(-.294,.242),l(-.503,.794),l(-1.207,.997),l(-.725,-.42),l(-.513,.583),l(-.882,.034),l(-.005,.961),l(-.293,.412),l(-.29,.143),l(-1.001,.125),l(-.311,-.661),l(-.025,-.085),l(-.478,-.3),l(.085,-.731),l(-.128,-.175),l(-.272,0),l(-.541,-.276),l(-.433,.34),l(-.365,-.016),l(-.066,-.271),l(-.565,-.35),l(-.409,-.08),l(-.208,-.418),l(-.677,-.17),l(.438,-.302),l(-.162,-.604),l(.177,-.493),l(.499,-.238),l(1.507,-1.208),
+N(205.532,170.085),l(.035,.076),l(-.203,.057),l(.01,.265),l(-.237,.334),l(-.68,-.046),l(-.853,-.139),l(-1.697,-.505),l(-1.305,-.435),l(-.325,-.21),l(.012,-.223),l(.565,-.461),l(.22,.016),l(.184,-.302),l(.351,-.111),l(-.164,-.159),l(.043,-.254),l(.467,-.048),l(.677,.17),l(.208,.418),l(.409,.08),l(.565,.35),l(.066,.271),l(.365,.016),l(.433,-.34),l(.541,.276),l(.272,0),l(.128,.175),l(-.085,.731),
+N(242.38,173.617),l(-.128,-.105),l(-.84,.171),l(-.534,.156),l(-.414,.2),l(-.056,.288),l(.048,.497),l(-.129,.396),l(-.227,-.027),l(-.381,.059),l(-.99,1.758),l(-.172,.722),l(-.241,.722),l(-.709,1.191),l(.402,.025),l(.234,-.1),l(.384,-.017),l(.31,.606),l(.855,1.45),l(.103,.395),l(-.226,1.132),l(.099,.353),l(.401,.309),l(.429,.548),l(.397,.252),l(.496,-.017),l(1.163,-.12),l(1.167,-.05),l(.521,.181),l(.64,.321),l(.188,.253),l(.847,.998),l(.554,.576),l(.144,0),l(.522,-.13),l(.76,-.174),l(1.99,-.224),l(.644,.081),l(-.409,.525),l(-.085,1.004),l(-.379,.511),l(-.147,.326),l(.026,.254),l(.035,.438),l(.048,.367),l(.162,.804),l(.447,.789),l(.256,.437),l(.486,.647),l(.121,.282),l(-.731,.612),l(-.479,.526),l(.51,.491),l(.797,1.182),l(-.52,.286),l(-.834,.57),l(-.412,.158),l(-.463,.017),l(-2.812,-.082),l(-.64,-.024),l(-.042,.325),l(-.013,1.031),l(.178,.154),l(.896,.122),l(.177,.084),l(.293,.408),l(.052,.367),l(-.384,-.04),l(-.417,-.11),l(-.687,.032),l(-.493,.187),l(-.111,.085),l(-.001,1.071),l(0,.554),l(.192,.197),l(.688,.363),l(.192,.183),l(-.031,.777),l(.399,.562),l(.031,.212),l(-.326,1.428),l(-.706,4.411),l(-.073,.382),l(-.133,.198),l(-.156,-.14),l(-.575,-.703),l(-.237,-.126),l(-.161,.058),l(-.448,.031),l(1.155,-1.956),l(.035,-.198),l(-.127,-.069),l(-1.299,-.84),l(-.509,-.209),l(-.708,.442),l(-.397,-.182),l(-.523,-.421),l(-.452,.427),l(-.337,.157),l(-.496,.031),l(-1.038,-.008),l(-.573,-.152),l(-.092,-.281),l(.004,-.396),l(-.173,-.296),l(-.479,-.039),l(-.366,-.14),l(-.078,-.282),l(-.251,-.761),l(-.988,-.672),l(-.526,-.364),l(-.208,-.62),l(-.208,-.324),l(-.513,-.435),l(-.897,-.418),l(-.927,-.107),l(-.081,-.112),l(-.269,-.162),l(-.197,-.118),l(-.709,-.631),l(-.128,-.056),l(-.89,.401),l(-.67,.061),l(-.977,-.277),l(-.355,-.309),l(-.166,-.493),l(-.227,-.225),l(-1.432,-.656),l(-1.496,-.803),l(.033,-.068),l(-.117,-.311),l(-.181,-.282),l(.108,-.212),l(.509,-.114),l(.465,.112),l(.186,-.325),l(-.348,-.564),l(.086,-.424),l(.314,-.227),l(.878,-.058),l(.193,.042),l(.41,-.227),l(.445,-.679),l(.45,-.961),l(.651,-1.061),l(-.122,-.268),l(-.56,-.408),l(-.071,-.184),l(.306,-.721),l(.089,-.523),l(-.149,-.861),l(-.371,-.86),l(.085,-.254),l(.49,-.143),l(.135,-.212),l(-.088,-.198),l(-.565,-.479),l(-.042,-.226),l(.103,-.198),l(.242,-.326),l(.036,-.254),l(-.173,-.282),l(-.739,-.719),l(-.364,-.396),l(.256,-.753),l(.228,-.082),l(-.045,-.45),l(.19,.082),l(.085,.307),l(.584,-.409),l(.094,-.43),l(.322,-.062),l(-.509,-1.038),l(-.228,-.149),l(-.084,-.327),l(.142,.075),l(.42,.338),l(.397,.507),l(.22,.508),l(.235,.197),l(.199,-.17),l(.147,-.241),l(-.332,-.776),l(.02,-.212),l(.176,-.297),l(.445,-.34),l(.399,-.297),l(.501,-.736),l(.327,-.156),l(.684,-.101),l(.217,-.382),l(-.104,-.381),l(.174,-.777),l(.067,-.65),l(.207,-.48),l(.498,-.439),l(.429,-.283),l(.592,-.242),l(.113,0),l(.374,.206),l(.22,.443),l(.281,-.34),l(.031,-.438),l(.199,-.551),l(.22,-.071),l(.267,.126),l(.855,.041),l(.562,-.001),l(.623,-.27),l(.237,-.254),l(.476,-.298),l(.848,-.256),l(.435,-.396),l(.278,-.551),l(.333,-.255),l(.469,-.17),l(.58,.013),l(.526,.338),l(.155,.126),l(.155,.339),l(-.285,.332),
+N(408.6,174.04),l(-.062,.777),l(.164,.762),l(.388,.718),l(-.316,.962),l(-.19,.566),l(-.223,.298),l(-.656,.414),l(-.095,.34),l(.116,.592),l(-.078,.368),l(-.433,.13),l(-.257,.03),l(-.237,.397),l(.002,.381),l(.003,.48),l(-.012,.876),l(-.09,.989),l(.217,1.439),l(-.121,1.188),l(.006,.234),l(-.333,.015),l(-1.232,.144),l(-.669,.052),l(-.106,-.205),l(-.295,-1.072),l(.188,-.708),l(.026,-.833),l(-.036,-.537),l(-.135,-.974),l(-.006,-.862),l(-.035,-.522),l(.013,-.579),l(-.442,-1.311),l(-.164,-.691),l(-.403,-.323),l(-.468,-.294),l(-.18,-.395),l(.141,-.594),l(.046,-.424),l(.062,-.142),l(.24,-.157),l(.366,-.553),l(.415,-.271),l(.418,-.045),l(.739,.095),l(.337,-.158),l(.415,-.468),l(.237,-.764),l(-.131,-.367),l(.577,-.3),l(.321,-.073),l(.339,.28),l(.727,.589),l(.902,.503),
+N(394.266,178.814),l(.191,-.17),l(-.02,-.41),l(-.261,-1.934),l(.125,-.34),l(.271,-.157),l(2.119,-.041),l(.867,.037),l(1.429,.006),l(.976,-.458),l(.161,.032),l(.595,.119),l(-.25,.849),l(.05,.254),l(.633,.915),l(.244,.451),l(-.188,.721),l(.02,.396),l(.265,1.114),l(.181,.592),l(.503,.788),l(.032,.155),l(-.286,.242),l(-.174,.382),l(.01,1.314),l(-.011,.72),l(.021,.551),l(.18,.479),l(.468,.577),l(.752,.608),l(-.503,.682),l(-.304,.099),l(-.593,-.013),l(-.992,.144),l(-.463,.185),l(-.188,.098),l(-.898,.469),l(-1.263,.398),l(-.942,.412),l(-.958,.567),l(-.578,-.324),l(-.945,-.436),l(-.074,-.124),l(-.066,-.741),l(-.554,-1.155),l(-.263,-.747),l(-.103,-.706),l(.327,-1.005),l(.437,-1.274),l(.521,-.851),l(.203,-.595),l(-.334,-1.438),l(-.189,-1.285),l(-.178,-.154),
+N(400.72,175.499),l(1.013,.163),l(.611,.166),l(.29,.041),l(-.046,.424),l(-.141,.594),l(.18,.395),l(.468,.294),l(.403,.323),l(.164,.691),l(.442,1.311),l(-.013,.579),l(.035,.522),l(.006,.862),l(.135,.974),l(.036,.537),l(-.026,.833),l(-.188,.708),l(.295,1.072),l(.106,.205),l(-.452,.035),l(-.479,.128),l(-.368,.212),l(-.023,.04),l(-.752,-.608),l(-.468,-.577),l(-.18,-.479),l(-.021,-.551),l(.011,-.72),l(-.01,-1.314),l(.174,-.382),l(.286,-.242),l(-.032,-.155),l(-.503,-.788),l(-.181,-.592),l(-.265,-1.114),l(-.02,-.396),l(.188,-.721),l(-.244,-.451),l(-.633,-.915),l(-.05,-.254),l(.25,-.849),
+N(383.772,190.418),l(.041,-.919),l(.105,-.565),l(.247,-.849),l(.059,-.452),l(-.131,-.282),l(-1.264,-1.334),l(-.592,.032),l(-.369,-.097),l(-.194,-.183),l(-.05,-.183),l(.501,-.865),l(.059,-.438),l(-.119,-.55),l(.062,-.17),l(.047,-.099),l(.602,-.554),l(.188,-.354),l(-.179,-.21),l(-.296,-.549),l(.03,-.127),l(.158,-.199),l(.304,-.03),l(.548,.223),l(.304,.012),l(.19,-.143),l(-.051,-.226),l(-.648,-.561),l(-.309,-.351),l(.332,-.37),l(.125,-.283),l(-.197,-.31),l(-.695,-.405),l(-.214,-.409),l(.264,-.623),l(.379,-.397),l(.522,-.54),l(.352,-.059),l(.566,.321),l(.455,.436),l(.35,-.228),l(.362,-.469),l(.571,-.483),l(.239,-.114),l(.257,.041),l(.147,.211),l(.004,.297),l(.117,.381),l(.148,.239),l(.352,-.059),l(.604,-.399),l(.159,-.1),l(.259,.168),l(.545,-.003),l(.308,.252),l(.15,.465),l(.52,.562),l(.452,.223),l(.354,.083),l(.368,-.115),l(.446,-.257),l(.608,-.159),l(.769,-.075),l(.644,.166),l(.63,.434),l(.178,.154),l(.189,1.285),l(.334,1.438),l(-.203,.595),l(-.521,.851),l(-.437,1.274),l(-.327,1.005),l(.103,.706),l(.263,.747),l(.554,1.155),l(.066,.741),l(-.119,-.201),l(-.289,-.197),l(-.208,.015),l(-.143,.24),l(-.096,.042),l(-.48,-.027),l(-.705,-.167),l(-.608,-.083),l(-2.352,.062),l(-1.279,.243),l(-.575,.199),l(-1.07,.369),l(-1.739,.781),l(-.701,.425),l(-.256,-.013),l(-.075,-.032),
+N(627.408,186.411),l(.035,.024),l(.523,.098),l(1.061,1.198),l(.693,.916),l(.506,.762),l(.081,.579),l(-.023,.805),l(-.134,.862),l(.07,1.073),l(-.07,.636),l(.097,.494),l(.196,.381),l(.53,.493),l(.338,.536),l(.705,1.608),l(.062,.127),l(-.366,-.069),l(-.895,-.055),l(-.401,.142),l(-.175,-.07),l(-.521,-.437),l(-.885,-.605),l(-.6,-.337),l(-1.231,-.675),l(-1.02,-.732),l(-.217,-.254),l(-.16,-.988),l(-.438,-.691),l(-.895,-.817),l(-.195,-.663),l(.039,-.494),l(.03,-.283),l(-.107,-.409),l(-.399,-.634),l(-.347,-1.849),l(-.188,-.72),l(.043,-.362),l(.448,-.17),l(.571,-.013),l(.106,.466),l(.447,.119),l(.261,.238),l(.055,.226),l(.041,.21),l(-.213,.398),l(.118,.239),l(.204,.083),l(.244,-.394),l(.279,-.28),l(.309,.163),l(.05,.478),l(.644,-.089),l(.11,-.575),l(.495,-.35),l(.086,-.337),M(643.95,196.042),l(.081,.044),l(.375,.408),l(.397,.141),l(.861,.083),l(.413,.168),l(.761,.436),l(.335,.042),l(.337,-.1),l(-.503,-.535),l(.169,-.551),l(.365,-.608),l(.528,-1.258),l(.584,-.27),l(1.481,-.342),l(1.018,-.299),l(.428,-.326),l(.524,-1.021),l(.523,-.323),l(.87,-1.117),l(.22,-.212),l(.244,-.147),l(.112,-.068),l(.084,.126),l(.062,.37),l(.234,-.012),l(.111,.259),l(.309,.271),l(.383,-.271),l(1.234,-.42),l(-.025,-.086),l(-.197,-.197),l(.013,-.247),l(.024,-.111),l(-.148,-.444),l(-.11,-.174),l(.167,-.042),l(.188,.143),l(.085,-.016),l(.449,-.084),l(.161,-.283),l(-.036,-.24),l(-.478,-.366),l(.197,-.396),l(.436,-.071),l(.511,.041),l(.154,-.605),l(.408,-.313),l(.284,-.48),l(.531,-.58),l(.498,-1.032),l(.075,-.17),l(.322,.465),l(.33,.098),l(.315,-.424),l(.305,.494),l(.351,.282),l(.402,.211),l(.075,.338),l(-.182,.354),l(-.234,.452),l(.037,.198),l(.631,-.128),l(.472,-.128),l(.115,.226),l(-.349,.495),l(.742,-.1),l(.357,-.085),l(.269,.056),l(1.035,.662),l(.345,.14),l(.1,.24),l(-.158,.269),l(-.201,.155),l(-.44,.143),l(-.594,.029),l(-.683,-.083),l(-.355,.311),l(.096,.254),l(.888,.69),l(-.161,.311),l(-.458,.199),l(-.646,.1),l(-.518,.114),l(-.067,.15),l(-.182,-.09),l(-.753,-.292),l(-.446,-.04),l(-.624,.018),l(-.651,-.081),l(-.748,-.081),l(-.464,.017),l(-.247,.157),l(-.381,.638),l(-.119,.565),l(.106,.988),l(-.22,.383),l(-.646,.244),l(-.218,.34),l(.076,.748),l(-.928,1.785),l(-.387,.299),l(-.864,.175),l(-.465,.172),l(-.467,.356),l(-.287,.03),l(-.559,-.152),l(-.524,-.223),l(-.557,-.251),l(-.431,-.11),l(-.479,.074),l(-.531,.441),l(-.403,.525),l(-.528,.342),l(-.399,.172),l(-.543,-.11),l(-.526,-.223),l(-.255,.001),l(-.928,.416),l(-.446,-.28),l(-.304,-.083),l(-1,-.983),l(-.253,-.295),l(-.288,-.792),
+N(274.556,195.884),l(.06,-.212),l(-.332,-.563),l(-.49,-1.127),l(-.246,-.832),l(-.185,-.295),l(-.561,-.067),l(-.532,-.675),l(-.571,-.831),l(.328,-.694),l(.095,-.467),l(-.078,-.777),l(.169,-.17),l(1.131,-.091),l(.183,-.27),l(.082,-.862),l(.142,-.496),l(.015,-.339),l(.326,-.312),l(.382,-.057),l(1.392,.463),l(.465,.042),l(.083,-.41),l(.141,-.085),l(.337,.027),l(.833,.012),l(.863,-.03),l(.723,.069),l(.63,.182),l(.999,.427),l(-.647,.876),l(-.391,.751),l(-.137,.594),l(.094,.381),l(.134,.635),l(.086,.664),l(.521,.844),l(.029,.438),l(-.424,1.472),l(-.489,.963),l(-1.05,-.488),l(-.319,.001),l(-.534,.385),l(-.398,.059),l(-.418,-.139),l(-.642,-.124),l(-.172,.156),l(-.2,.326),l(.611,1.014),l(-.528,-.054),l(-1.108,-.276),l(-.4,-.04),
+N(285.859,190.719),l(.015,.422),l(-1.102,1.646),l(-.427,.765),l(-.439,.992),l(-.464,.681),l(-.299,.214),l(-.56,-.025),l(-1.11,-.389),l(-.882,.613),l(-.225,-.069),l(-.649,-.505),l(.489,-.963),l(.424,-1.472),l(-.029,-.438),l(-.521,-.844),l(-.086,-.664),l(-.134,-.635),l(-.094,-.381),l(.137,-.594),l(.391,-.751),l(.647,-.876),l(.218,.093),l(1.033,.294),l(.55,.196),l(.799,.549),l(1.264,1.084),l(.545,.564),l(.317,.465),l(.193,.028),
+N(429.505,210.684),l(-.695,-.533),l(-.351,.13),l(-.68,.513),l(-.536,.414),l(-.112,-.177),l(-.392,-.86),l(-1.381,-1.344),l(.184,-.295),l(.413,-.229),l(.803,.307),l(.343,-.681),l(-.052,-.296),l(-.274,-.253),l(-.39,-.521),l(-.116,-.366),l(.058,-.495),l(.127,-.1),l(.909,-.146),l(.604,-.243),l(.125,-.213),l(.167,-.807),l(.174,-.185),l(.239,-.029),l(.193,.14),l(.341,.479),l(.405,.521),l(.386,.195),l(.287,-.016),l(.188,-.228),l(.362,-.482),l(.29,.253),l(.167,.578),l(.146,.112),l(.304,.068),l(.255,-.114),l(.184,-.68),l(.243,-1.089),l(.131,-1.229),l(.229,-1.047),l(-.114,-.338),l(-.161,-.127),l(-.384,-.082),l(-.528,-.208),l(-.242,-.31),l(-.132,-.437),l(.008,-.109),l(.021,-.3),l(.157,-.284),l(.492,-.398),l(.556,-.441),l(.094,-.354),l(-.389,-.902),l(-.369,-.322),l(-.592,-.067),l(-.939,.5),l(-.463,-.025),l(-.146,-.253),l(-.068,-.734),l(.077,-.679),l(.396,-.468),l(.56,.109),l(.863,.023),l(.878,-.076),l(.271,.055),l(.479,.04),l(.56,.124),l(.576,.194),l(.864,.334),l(.863,.292),l(.271,-.086),l(-.1,-.861),l(.159,-.185),l(.303,-.312),l(.365,-.497),l(.158,-.523),l(.222,-1.287),l(.255,-.228),l(.479,-.102),l(.975,-.175),l(.367,.054),l(.624,.138),l(.895,.093),l(.751,-.287),l(.128,.197),l(-.031,.156),l(-.398,1.203),l(-.558,.837),l(-.349,.821),l(-.094,.551),l(-.156,.764),l(-.196,2.021),l(-.254,1.342),l(-.115,.61),l(-.169,.708),l(-.139,.523),l(-.459,.427),l(-.525,.229),l(-.809,.599),l(-.41,.454),l(-.47,.836),l(-.343,.751),l(-.193,1.159),l(-.074,.396),l(.122,.72),l(-.086,.706),l(-1.025,.938),l(-.364,.229),l(-.931,.811),l(-.554,.399),l(-.57,.328),l(-.147,-.211),l(-.042,-.664),l(-.054,-.424),l(-1.495,.532),l(-.327,.581),l(-.443,.271),l(-.177,-.013),l(-.484,-.336),
+N(425.506,195.522),l(.045,-.495),l(.88,.093),l(1.773,.088),l(.831,.038),l(1.022,.149),l(-.396,.468),l(-.077,.679),l(.068,.734),l(.146,.253),l(.463,.025),l(.939,-.5),l(.592,.067),l(.369,.322),l(.389,.902),l(-.094,.354),l(-.556,.441),l(-.492,.398),l(-.157,.284),l(-.021,.3),l(-.008,.109),l(.132,.437),l(.242,.31),l(.528,.208),l(.384,.082),l(.161,.127),l(.114,.338),l(-.229,1.047),l(-.131,1.229),l(-.243,1.089),l(-.184,.68),l(-.255,.114),l(-.304,-.068),l(-.146,-.112),l(-.167,-.578),l(-.29,-.253),l(-.362,.482),l(-.188,.228),l(-.287,.016),l(-.386,-.195),l(-.405,-.521),l(-.341,-.479),l(-.193,-.14),l(-.239,.029),l(-.174,.185),l(-.167,.807),l(-.125,.213),l(-.604,.243),l(-.909,.146),l(-.127,.1),l(-.058,.495),l(.116,.366),l(.39,.521),l(.274,.253),l(.052,.296),l(-.343,.681),l(-.803,-.307),l(-.413,.229),l(-.184,.295),l(-.038,-.037),l(-.563,-.493),l(-.532,-.55),l(-.259,-.466),l(-1.318,-1.169),l(.286,-.312),l(-.369,-.281),l(-.528,-.056),l(-.918,-1.438),l(.382,-.297),l(.111,-.1),l(-.321,-.395),l(-.464,-.14),l(-.29,-.564),l(-.369,-.451),l(.319,-.17),l(.541,-.411),l(.223,-.396),l(.291,-.976),l(.089,-.295),l(.415,.07),l(.495,.013),l(-.064,-.211),l(-.56,-.352),l(-.561,-.451),l(.208,-.042),l(.271,-.128),l(.142,-.617),l(.83,-.043),l(.927,.008),l(1.245,.021),l(.575,-.032),l(-.001,-.155),l(-.02,-.551),l(-.026,-1.836),
+N(422.536,195.513),l(1.005,-.007),l(1.965,.017),l(.026,1.836),l(.02,.551),l(.001,.155),l(-.575,.032),l(-1.245,-.021),l(-.927,-.008),l(-.83,.043),l(.033,-.146),l(-.049,-.297),l(-.144,-.084),l(-.416,-.098),l(.287,-.467),l(.447,-.523),l(.335,-.58),l(.066,-.403),M(419.636,193.273),l(-.484,-.049),l(-.049,-.218),l(.049,-.291),l(.242,-.097),l(.024,-.146),l(0,-.291),l(.17,-.097),l(.169,-.121),l(.219,.048),l(.218,.048),l(.097,.194),l(-.193,.169),l(-.146,.243),l(-.17,.339),l(-.146,.267),
+N(222.291,207.801),l(.188,-.126),l(.264,-.312),l(.585,-1.061),l(.038,-.269),l(-.209,-.733),l(.058,-.391),l(-.478,.617),l(-.732,.623),l(-.333,-.098),l(-.601,-.324),l(-.408,-.408),l(.389,-.283),l(.1,-.24),l(-.167,-.579),l(.005,-.438),l(.133,-.466),l(-.109,-.282),l(-.362,-.649),l(.193,-.17),l(.48,-.198),l(.721,-.454),l(-.319,-.395),l(0,-.226),l(.175,-.354),l(.497,-.462),l(.157,-.146),l(.14,-.848),l(-.116,-.452),l(-.082,-.184),l(.11,-.226),l(.686,-.101),l(.891,-.341),l(.396,-.241),l(.474,-.382),l(.09,-.186),l(1.496,.803),l(1.432,.656),l(.227,.225),l(.166,.493),l(.355,.309),l(.977,.277),l(.67,-.061),l(.89,-.401),l(.128,.056),l(.709,.631),l(.197,.118),l(.269,.162),l(.081,.112),l(.387,.76),l(.321,.789),l(-.08,.255),l(-.352,.384),l(-.547,1.147),l(-.533,.779),l(-.71,.725),l(-1.001,.755),l(-.336,.087),l(-1.028,.303),l(-.901,.358),l(-.809,.499),l(-.59,.653),l(-.284,.51),l(-.987,2.506),l(-.267,.312),l(-.242,.072),l(-.398,-.068),l(-.398,-.491),l(-.191,-.479),l(-.312,-.252),l(-.815,.005),l(-.444,-.11),l(-.105,-.197),l(-.097,-.494),l(.233,-.34),l(.029,-.495),l(.005,-.569),
+N(245.934,224.314),l(1.109,1.843),l(.922,1.646),l(.08,.24),l(-.437,.736),l(-.15,.523),l(-.143,.848),l(.057,.522),l(.236,.902),l(-.156,.34),l(-.221,.34),l(-.532,.582),l(-.102,.452),l(.347,.845),l(-.21,.368),l(-.159,.34),l(.022,.48),l(.604,1.168),l(.015,.522),l(-.285,.439),l(-.723,.61),l(-.12,.227),l(.049,.48),l(.132,.295),l(.018,.142),l(-.586,.187),l(-.15,.199),l(-.228,.933),l(-.259,.298),l(-.852,.275),l(-.201,-.517),l(-.289,-.31),l(-1.422,-.618),l(-.313,-.239),l(-.233,-.678),l(-.315,-.38),l(-.559,-.225),l(-.504,-.281),l(-.489,-.254),l(-.616,-.309),l(-.873,-.464),l(-.673,-.366),l(-.866,-.379),l(-.838,-.337),l(-1.271,-.845),l(-1.354,-.985),l(-1.232,-1.099),l(-.594,-.705),l(-.42,-.677),l(.008,-.438),l(0,-.903),l(-.269,-.606),l(-.781,-1.043),l(-1.389,-2.778),l(-.285,-.268),l(-.467,-.211),l(-.074,-.085),l(.055,-.536),l(-.02,-.396),l(-.149,-.396),l(-1.208,-2.199),l(-.997,-1.961),l(-.688,-1.27),l(-1.365,-1.917),l(-.272,-.353),l(-.598,-.973),l(-.462,-.423),l(-.75,-.437),l(-.914,-.365),l(-.61,-.365),l(.119,-.17),l(.181,-.113),l(.609,-.029),l(.144,-.41),l(-.118,-.282),l(-.592,-.874),l(-.353,-.437),l(-.258,-.72),l(.01,-.24),l(.244,-.523),l(.582,-.622),l(1.02,-.878),l(.47,-.198),l(.317,-.214),l(-.005,.569),l(-.029,.495),l(-.233,.34),l(.097,.494),l(.105,.197),l(.444,.11),l(.815,-.005),l(.312,.252),l(.191,.479),l(.398,.491),l(.398,.068),l(.242,-.072),l(.267,-.312),l(.987,-2.506),l(.284,-.51),l(.59,-.653),l(.809,-.499),l(.901,-.358),l(1.028,-.303),l(.336,-.087),l(1.001,-.755),l(.71,-.725),l(.533,-.779),l(.547,-1.147),l(.352,-.384),l(.08,-.255),l(-.321,-.789),l(-.387,-.76),l(.927,.107),l(.897,.418),l(.513,.435),l(.208,.324),l(.208,.62),l(.526,.364),l(.988,.672),l(.251,.761),l(.078,.282),l(.366,.14),l(.479,.039),l(.173,.296),l(-.004,.396),l(.092,.281),l(.573,.152),l(1.038,.008),l(.496,-.031),l(.337,-.157),l(.452,-.427),l(.523,.421),l(.397,.182),l(.708,-.442),l(.509,.209),l(1.299,.84),l(.127,.069),l(-.035,.198),l(-1.155,1.956),l(.448,-.031),l(.161,-.058),l(.237,.126),l(.575,.703),l(.156,.14),l(.136,.324),l(-.341,.186),l(-.793,-.235),l(-.493,-.096),l(-.322,.072),l(-.604,.441),l(-.371,.115),l(-.669,-.066),l(-1.895,.773),l(-.701,.442),l(-.372,.172),l(-.599,1.415),l(-.319,.511),l(-.021,.155),l(.277,.86),l(.012,.112),l(-.625,.498),l(-.62,.328),l(-.349,.342),l(-.247,.622),l(.106,.564),l(.619,.957),l(1.333,2.166),l(.106,.127),l(-.247,.495),l(-.208,.312),l(1.085,.12),l(.415,.04),l(.312,.182),l(.241,.323),l(.096,.663),l(1.843,.032),l(.762,-.499),l(.648,-.484),l(.326,-.114),l(-.059,1.511),l(-.098,1.173),l(.108,.353),l(.317,.337),l(.285,.068),l(.358,-.072),l(.786,-.259),l(.42,-.045),
+N(279.288,257.295),l(-.063,-.423),l(.027,-.777),l(.222,-.819),l(.298,-.835),l(.321,-.75),l(-.019,-.141),l(-.491,-.336),l(-.234,-.112),l(-1.29,.445),l(-.224,-.055),l(-.254,-.563),l(-.487,-2.524),l(-.121,-.437),l(-.843,-.404),l(-.724,-.278),l(-.115,.001),l(-.709,.413),l(-.346,.03),l(-.925,-.221),l(-.818,-.15),l(-.372,-.04),l(.006,-.72),l(.086,-.721),l(.132,-.862),l(-.104,-.959),l(-.521,-.872),l(-.084,-.663),l(-.253,-.408),l(.421,-.666),l(.38,-.765),l(.238,-.834),l(.185,-1.173),l(-.022,-.494),l(-.307,-.774),l(-.316,-.479),l(-.73,-.362),l(-.436,-.407),l(-.067,-.563),l(.261,-.835),l(-.042,-.296),l(-.693,-.024),l(-1.615,-.019),l(-.5,-.012),l(-.967,-.036),l(-.153,-.112),l(-.249,-.944),l(-.138,-2.032),l(-.03,-.706),l(-.203,-1.029),l(.038,-.565),l(-.085,-.169),l(-.403,-.237),l(-.537,-.166),l(-.636,-.123),l(-1.148,.077),l(-.22,-.084),l(-.398,-.308),l(-.385,-.774),l(-.096,-.014),l(-.882,-.037),l(-.3,-.098),l(-.75,-.603),l(-.688,-.307),l(-.676,-.25),l(-.355,.03),l(-.787,-.023),l(-.316,-.097),l(-1.1,-.939),l(-.813,-.928),l(-.335,-.591),l(-.141,-.635),l(-.036,-.818),l(.064,-.622),l(.079,-.621),l(-.045,-.748),l(-1.283,-.021),l(-.934,.076),l(-.36,.158),l(-.874,.485),l(-1.471,1.109),l(-.415,.243),l(-.48,-.025),l(-.336,-.026),l(-.946,.824),l(-.355,.03),l(-1.122,-.304),l(-.939,-.136),l(-.42,.045),l(-.786,.259),l(-.358,.072),l(-.285,-.068),l(-.317,-.337),l(-.108,-.353),l(.098,-1.173),l(.059,-1.511),l(-.326,.114),l(-.648,.484),l(-.762,.499),l(-1.843,-.032),l(-.096,-.663),l(-.241,-.323),l(-.312,-.182),l(-.415,-.04),l(-1.085,-.12),l(.208,-.312),l(.247,-.495),l(-.106,-.127),l(-1.333,-2.166),l(-.619,-.957),l(-.106,-.564),l(.247,-.622),l(.349,-.342),l(.62,-.328),l(.625,-.498),l(-.012,-.112),l(-.277,-.86),l(.021,-.155),l(.319,-.511),l(.599,-1.415),l(.372,-.172),l(.701,-.442),l(1.895,-.773),l(.669,.066),l(.371,-.115),l(.604,-.441),l(.322,-.072),l(.493,.096),l(.793,.235),l(.341,-.186),l(-.136,-.324),l(.133,-.198),l(.073,-.382),l(.706,-4.411),l(.326,-1.428),l(-.031,-.212),l(-.399,-.562),l(.031,-.777),l(-.192,-.183),l(-.688,-.363),l(-.192,-.197),l(0,-.554),l(.001,-1.071),l(.111,-.085),l(.493,-.187),l(.687,-.032),l(.417,.11),l(.384,.04),l(-.052,-.367),l(-.293,-.408),l(-.177,-.084),l(-.896,-.122),l(-.178,-.154),l(.013,-1.031),l(.042,-.325),l(.64,.024),l(2.812,.082),l(.463,-.017),l(.412,-.158),l(.834,-.57),l(.52,-.286),l(.148,.168),l(.138,.437),l(.161,.861),l(.088,.452),l(.199,.437),l(.432,.054),l(.694,.546),l(.482,.223),l(.414,-.073),l(.757,-.697),l(.083,.183),l(.186,.776),l(.271,-.016),l(.645,-.739),l(.74,-.654),l(.554,-.286),l(.652,-.173),l(.235,-.213),l(.259,-.666),l(.203,-.199),l(.652,-.131),l(.569,-.272),l(.265,-.27),l(-.15,-.253),l(-.434,-.125),l(-.96,-.051),l(-.166,-.239),l(-.079,-.55),l(-.302,-1.524),l(-.391,-.69),l(-.616,-.688),l(.041,-.184),l(.159,-.029),l(.309,.125),l(.896,.461),l(.385,.04),l(1.149,-.035),l(.344,.224),l(.628,.618),l(.348,-.115),l(.232,-1.117),l(.284,-.115),l(.465,.054),l(.557,-.074),l(.807,-.23),l(1.74,-.9),l(.592,-.385),l(.163,-.326),l(-.103,-.169),l(.375,-.257),l(.302,-.058),l(.516,.124),l(.26,.111),l(.04,.212),l(-.452,1.09),l(.304,-.001),l(.533,.138),l(.435,.958),l(-.179,.368),l(-.547,1.416),l(-.213,.962),l(.156,.465),l(.281,.394),l(.167,.31),l(-.072,.354),l(.008,.396),l(.15,.296),l(1.103,.897),l(.613,.392),l(.686,-.075),l(.694,-.513),l(.505,-.314),l(1,-.331),l(.934,-.429),l(.943,.022),l(.4,.04),l(1.108,.276),l(.528,.054),l(-.611,-1.014),l(.2,-.326),l(.172,-.156),l(.642,.124),l(.418,.139),l(.398,-.059),l(.534,-.385),l(.319,-.001),l(1.05,.488),l(.649,.505),l(.225,.069),l(.882,-.613),l(1.11,.389),l(.56,.025),l(.299,-.214),l(.464,-.681),l(.439,-.992),l(.427,-.765),l(1.102,-1.646),l(-.015,-.422),l(.409,-.241),l(.276,.141),l(.235,.423),l(.164,.791),l(.414,1.34),l(.108,.607),l(.472,1.383),l(.296,.55),l(.324,.324),l(.978,.21),l(.196,.338),l(.038,.551),l(-.045,.254),l(-.524,.354),l(-.933,1.414),l(-.238,.325),l(-.51,.411),l(-.41,.231),l(-.244,.138),l(-.798,.778),l(-.544,.947),l(-.419,1.018),l(-.402,.453),l(.271,.112),l(.512,-.072),l(.497,-.198),l(1.202,-.709),l(.112,-.028),l(.299,.889),l(.442,.818),l(.255,.112),l(.287,.07),l(1.135,-.031),l(.592,-.058),l(.737,-.298),l(-.277,.679),l(-.017,.584),l(.448,-.557),l(1.254,-1.006),l(.289,-.156),l(.306,-.382),l(.499,-.933),l(.272,-.396),l(.256,-.099),l(1.006,-.003),l(.352,-.198),l(.175,0),l(.687,.549),l(.654,.267),l(.32,-.028),l(.814,.28),l(1.069,.45),l(.334,.281),l(.269,.593),l(.08,.028),l(.176,-.015),l(.402,-.354),l(.319,.042),l(.302,.254),l(.538,.789),l(.205,.396),l(-.13,.254),l(-.308,.41),l(-.116,.424),l(.091,.466),l(.171,.396),l(.825,-.821),l(.369,-.156),l(.609,-.156),l(.995,-.454),l(.224,-.028),l(.367,.069),l(.764,.38),l(.907,.436),l(.462,.098),l(1.117,.167),l(1.118,.083),l(.464,-.058),l(.48,-.029),l(.577,-.171),l(.416,-.016),l(1.131,.351),l(.731,.408),l(.762,.479),l(.586,.437),l(1.595,1.395),l(.742,.662),l(.821,.605),l(.41,.338),l(.477,.196),l(.734,.168),l(1.247,.097),l(.912,.04),l(.445,.197),l(.265,.465),l(.087,.607),l(.592,2.004),l(.268,1.143),l(.062,.988),l(-.076,.579),l(-.179,.904),l(-.243,.848),l(-.559,1.301),l(-.518,.849),l(-1.347,1.175),l(-1.388,1.288),l(-.44,.198),l(-.354,.043),l(-.39,.637),l(-.094,.396),l(-.012,.353),l(-.504,1.074),l(-.6,.976),l(-.8,1.104),l(-.266,.212),l(-.194,.015),l(-.079,-.423),l(-.278,-.296),l(-.367,-.084),l(-.064,.79),l(-.538,1.64),l(-.049,.734),l(-.077,.607),l(.318,2.738),l(.078,.988),l(-.577,2.543),l(-.039,.663),l(.14,.649),l(.043,.085),l(-.759,.495),l(-.404,.51),l(-.261,.791),l(-.04,.367),l(.245,1.468),l(-.106,.367),l(-.214,.283),l(-.676,.608),l(-.752,1.498),l(-1.01,1.4),l(-.201,.537),l(-.055,.311),l(.144,.945),l(-1.203,.37),l(-.544,.283),l(-.355,.368),l(-.084,.466),l(.021,.367),l(-.401,.114),l(-.864,-.041),l(-.979,.172),l(-.654,.001),l(-.764,-.055),l(-.465,-.112),l(-.922,.072),l(-.736,.002),l(-.214,.607),l(-.295,.198),l(-.795,.312),l(-.481,.453),l(-.21,.354),l(-.747,-.267),l(-.35,.071),l(-.563,.255),l(-1.864,1.232),l(-.528,.396),l(-.725,.383),l(-.616,.438),l(-.532,.679),l(-.486,.241),l(-.567,.072),l(-.278,-.014),l(.006,.24),l(.336,.225),l(.12,.536),l(-.111,.537),l(-.099,.282),l(-.282,.156),l(-.084,.155),l(.384,.648),l(.036,1.186),l(.05,1.045),l(-.057,.311),l(-.11,.594),l(-.198,.621),l(-.464,.735),l(-.566,.495),l(-.788,.524),l(-.866,1.046),l(-.208,.396),l(-.476,1.145),l(-.499,.933),l(-.75,1.004),l(-.69,.623),l(-.801,.78),l(.321,-.808),l(.436,-.594),l(.629,-.566),l(.605,-1.158),l(-.06,-.254),l(-.356,.142),l(-.397,-.014),l(-.633,-.21),l(-.075,.155),l(.002,.297),l(-.401,1.215),l(-.349,.48),l(-.661,.438),l(-.317,.283),l(-.225,.424),l(-.013,.354),l(-.448,1.709),l(-.481,.763),l(-.787,.934),l(-1.076,.979),l(-.101,-.313),l(-.258,-.746),l(.103,-.269),l(.634,-.766),l(.017,-.269),l(-.333,-.379),l(-.163,-.027),l(-.131,-.197),l(-.853,-1.109),l(-.474,-.435),l(-.999,-.587),l(-.55,-.194),l(-.617,-.194),l(-.432,-.576),l(-.365,-.393),l(-.693,.427),l(-.27,.016),l(-.232,-.38),l(-.59,-.814),l(-.379,-.407),l(-.47,-.364),l(-.266,-.098),l(-.25,.101),l(-1.042,.246),l(-.55,.003),l(.214,-.27),l(.833,-.88),l(1.805,-1.816),l(1.435,-1.363),l(1.633,-1.448),l(.348,-.242),l(1.754,-.744),l(.521,-.313),l(.161,-.467),l(.094,-1.638),l(-.517,-1.154),l(-.206,-.196),l(-.462,.017),l(-.957,.161),M(288.966,203.943),l(-.558,-.125),l(-.301,-.536),l(-.078,-.382),l(.16,-.197),l(-.094,-.636),l(.048,-.381),l(.208,-1.018),l(.176,-.099),l(.479,-.058),l(.879,.097),l(1.007,.11),l(.479,-.199),l(.368,.028),l(.479,.168),l(.479,.083),l(.319,.155),l(-.335,.538),l(-.193,.946),l(-.257,.494),l(-.289,.312),l(-.561,.326),l(-.464,.171),l(-.527,.015),l(-.783,.016),l(-.641,.171),
+N(732.92,214.323),l(-.164,-.24),l(-.225,-.197),l(-.379,-.126),l(-.416,.198),l(-.399,-.38),l(-.287,-.184),l(-.659,-.238),l(-.243,-.239),l(.156,-.255),l(.29,.027),l(.731,-.058),l(.538,.126),l(.743,.083),l(.523,-.058),l(.258,-.185),l(.232,-.509),l(.056,.099),l(.351,.395),l(.286,.184),l(.241,.014),l(.961,-.2),l(.366,-.227),l(.361,-.722),l(.241,-.212),l(.653,-.029),l(.263,-.128),l(.04,-.282),l(-.064,-.565),l(-.043,-.536),l(.495,.196),l(.404,.056),l(.324,-.354),l(.318,.578),l(.077,.353),l(-.196,.495),l(-.099,.184),l(-.509,.044),l(-.159,.226),l(.061,.17),l(.437,.479),l(-.308,.354),l(-.264,.113),l(-.742,-.083),l(-.416,.001),l(-.091,.269),l(-.408,.495),l(-.275,.156),l(-.973,.426),l(-.484,.143),l(-.798,.029),l(-.807,.115),M(713.795,220.696),l(.031,-3.438),l(-.046,-.805),l(-.431,-1.368),l(.44,-.822),l(-.169,-7.966),l(2.581,.802),l(.85,.337),l(1.04,.295),l(1.254,.378),l(.848,.507),l(.613,.323),l(.597,.084),l(.38,-.058),l(.26,.508),l(.274,.254),l(.635,.352),l(.687,.395),l(.779,.718),l(-.3,.947),l(.033,.226),l(.305,.226),l(.665,.111),l(1.887,.787),l(.354,.027),l(.72,.183),l(.181,.254),l(.413,.535),l(.211,.579),l(-.166,.113),l(-1.114,.073),l(-.563,.156),l(-.098,.155),l(.047,.339),l(.589,.987),l(.5,.521),l(1.464,1),l(.218,.847),l(.725,1.044),l(.288,.141),l(.304,-.015),l(.712,-.086),l(.338,.013),l(.087,.198),l(-.354,.551),l(.218,.212),l(.401,.141),l(.423,.041),l(.63,.168),l(.096,.127),l(-.031,.142),l(-.648,.213),l(.287,.24),l(1.064,.28),l(.538,.295),l(.235,.763),l(-.064,.226),l(-1.094,-.012),l(-.215,-.154),l(-.146,-.466),l(-.126,-.099),l(-1.011,-.111),l(-1.063,-.266),l(-.644,-.126),l(-.752,.016),l(-.774,-.026),l(-.573,-.211),l(-.494,-.352),l(-.223,-.522),l(-.24,-.268),l(-.726,-.31),l(-.472,-.338),l(-.135,-.197),l(-1.089,-1.608),l(-.613,-.817),l(-.454,-.056),l(-1.524,-.336),l(-.671,-.31),l(-.55,-.055),l(-.415,.185),l(-.394,.071),l(-.78,-.45),l(.282,.762),l(-.027,.212),l(-.249,.071),l(-.382,-.126),l(-.311,.1),l(.296,.395),l(-.116,.113),l(-1.037,.045),l(-1.125,-.182),l(-.478,.029),l(.237,.127),l(.24,.154),l(.642,.169),l(.662,.352),l(.404,.338),l(.219,.395),l(-.411,.199),l(-.739,.425),l(-.458,.213),l(-.668,-.097),l(-1.801,-.039),l(-1.219,-.092),
+N(726.605,297.247),l(-.479,-.229),l(-1.179,-.471),l(-.543,-.371),l(-.508,-.715),l(-.477,-.558),l(-.216,-.414),l(.264,-.044),l(.169,.1),l(.421,.171),l(.129,-.143),l(-.209,-.387),l(-.703,-.699),l(-.617,-.713),l(-.149,-.257),l(-.375,-.956),l(-.008,-.67),l(.177,-.044),l(1.004,.312),l(1.476,.354),l(1.089,.369),l(.797,-.03),l(.463,-.144),l(.382,-.115),l(.373,-.058),l(.684,.027),l(.306,-.301),l(.716,-.244),l(.475,.385),l(-.009,.1),l(.128,.8),l(-.009,.686),l(-.751,1.503),l(-.124,.758),l(-.245,.315),l(-.943,.26),l(-.553,.388),l(-.49,.689),l(-.189,.272),l(-.274,.072),M(716.883,224.344),l(.682,.394),l(.233,.509),l(.047,.649),l(.118,.678),l(.256,.197),l(.42,.013),l(.102,.24),l(-.45,.919),l(.715,.338),l(.175,.282),l(.147,.593),l(.08,1.3),l(.144,.621),l(.456,1.157),l(.293,.268),l(.422,.014),l(.328,-.312),l(.384,-.185),l(.32,.663),l(.363,.127),l(.563,.408),l(.385,.154),l(.144,.155),l(.002,.41),l(.083,.96),l(.275,.776),l(-.046,1.06),l(.279,.24),l(.93,1.325),l(.276,.706),l(.055,.777),l(-.209,.876),l(.403,.649),l(.275,.833),l(.204,.353),l(1.395,.803),l(.285,.154),l(.744,.111),l(.402,.649),l(.843,.535),l(.483,.169),l(1.141,.068),l(.117,.197),L(731,245.42),l(-.273,.565),l(.309,.424),l(.879,.479),l(.22,.564),l(.469,1.342),l(.211,.748),l(.112,.396),l(.252,.311),l(.771,.352),l(-.021,-.127),l(-.141,-.777),l(.913,.507),l(.567,.154),l(.184,.127),l(.136,.296),l(.106,1.752),l(.884,.762),l(.573,.323),l(.604,.154),l(.287,.296),l(.244,.579),l(.229,.424),l(.545,.168),l(.176,.297),l(.007,.269),l(.19,.536),l(.106,.113),l(.506,.126),l(.156,.112),l(.162,.354),l(.366,1.327),l(.026,.876),l(.013,.862),l(-.132,.41),l(-.181,.325),l(.778,1.271),l(.223,.48),l(.181,.833),l(.034,.749),l(-.293,.708),l(-.353,1.668),l(-.585,1.755),l(.137,.791),l(-.065,.806),l(-.306,.778),l(-.661,.977),l(-.203,.665),l(-.598,.821),l(-.45,.185),l(-.465,.1),l(-.423,.468),l(-.466,.68),l(-.328,1.527),l(-.477,.638),l(-.34,.495),l(.014,.65),l(-.208,.539),l(-.331,.312),l(-.601,.341),l(-.27,.326),l(-.3,1.021),l(-.169,1.049),l(-.079,.937),l(.021,.666),l(-.283,.64),l(-.322,.354),l(-.463,.3),l(-.754,.101),l(-1.158,.087),l(-.82,.03),l(-.527,.157),l(-.516,.299),l(-1.529,.94),l(-.443,.129),l(-.214,.284),l(-.346,.071),l(-.528,.059),l(-.286,-.014),l(.295,.368),l(.209,.27),l(-1.315,-.665),l(-.885,-.353),l(.003,-.469),l(-.073,-.156),l(-.56,-.467),l(-.628,-.368),l(-.421,-.014),l(-.485,.172),l(-.335,.242),l(.748,.467),l(-.97,.243),l(-.929,.428),l(-.953,.442),l(-.222,.028),l(-.604,-.226),l(-.886,-.438),l(-.67,-.226),l(-1.086,-.311),l(-.51,-.041),l(-.239,.156),l(-.044,.113),l(-.716,-.169),l(-.751,-.353),l(-.522,-.298),l(-.896,-.82),l(-.526,-.34),l(-.422,-.879),l(.09,-1.035),l(-.082,-.411),l(-.184,-.495),l(-.664,-.736),l(-.141,-.523),l(-.029,-.425),l(-.534,-.014),l(-.786,.398),l(-.597,.114),l(-.34,.058),l(-.178,-.07),l(-.167,-.17),l(.517,-.454),l(.233,-.567),l(.073,-.821),l(-.253,-.324),l(-.536,-.593),l(-.247,-.353),l(-.485,.735),l(-.443,1.431),l(-.19,.113),l(-.796,.002),l(-.199,.156),l(-.196,.015),l(-.255,.028),l(.198,-.396),l(.081,-.396),l(.079,-.1),l(.634,.041),l(.242,-.142),l(.126,-.255),l(-.105,-1.004),l(.454,-.835),l(.328,-.453),l(.091,-.396),l(.018,-.409),l(.151,-.128),l(.245,-.015),l(.218,-.354),l(-.052,-.227),l(-.323,-.494),l(-.338,-.494),l(-.107,.707),l(-.288,.255),l(-.518,.299),l(-.311,.467),l(-.086,.155),l(-.189,.467),l(-.281,.326),l(-.747,.242),l(-.735,.481),l(-.653,.567),l(-.36,.693),l(-.514,.808),l(-.41,-.339),l(-.38,-1.328),l(-.263,-.579),l(-.19,-.325),l(-.688,-.79),l(-.297,-.734),l(-.176,-.212),l(-.704,.072),l(-.235,-.099),l(-.139,-.24),l(-.085,-.269),l(.334,-.34),l(-.047,-.297),l(-.346,-.395),l(-.543,-.494),l(-.266,-.098),l(-.83,.157),l(-.486,-.07),l(-.95,-.549),l(-.274,-.014),l(-.438,.17),l(-.433,-.027),l(-.421,-.183),l(-.662,-.521),l(-.921,-.437),l(-.218,.001),l(-.723,.213),l(-1.282,.088),l(-.669,.001),l(-1.764,.061),l(-.611,.129),l(-.656,.213),l(-.989,.44),l(-.972,.256),l(-1.039,.257),l(-1.503,.088),l(-.794,-.013),l(-.383,.044),l(-.927,.284),l(-.993,.469),l(-.773,.397),l(-.538,.143),l(-.431,.085),l(-.361,.199),l(-.615,.693),l(-.774,1.02),l(-.588,.284),l(-.766,-.013),l(-.547,-.013),l(-.927,.143),l(-.4,.185),l(-.663,-.395),l(-.294,-.084),l(-.734,.016),l(-1.572,.173),l(-.938,.157),l(-.459,-.041),l(-.672,.044),l(-.398,.227),l(-.583,.793),l(-.344,.128),l(-.958,-.125),l(-.158,.057),l(-.57,.708),l(-.465,.368),l(-.919,.271),l(-.586,.086),l(-1.516,-.082),l(-.638,-.055),l(-.688,-.197),l(-.633,-.366),l(-.778,-.677),l(-.74,-.353),l(-.374,-.041),l(-.151,-.07),l(-.19,-1.229),l(.055,-.255),l(.489,.112),l(.45,-.086),l(.332,-.425),l(.197,-.467),l(.267,-1.357),l(-.043,-1.215),l(-.156,-.622),l(-.258,-.593),l(-1.117,-1.906),l(-.208,-.635),l(-.144,-.834),l(.027,-.989),l(-.16,-.692),l(-.467,-1.072),l(-.663,-.945),l(-.603,-.734),l(-.214,-.254),l(.128,-.904),l(-.215,-.536),l(-.733,-1.115),l(-.972,-1.018),l(-.273,-.583),l(.126,-.233),l(.188,.187),l(.152,.443),l(.183,.163),l(.235,.35),l(.327,.188),l(.354,.023),l(-.348,-1.144),l(-.437,-.396),l(-.226,-.326),l(.08,-.304),l(.748,.84),l(.495,.979),l(.477,.065),l(-.099,-.555),l(.289,-.039),l(.004,-.564),l(-.282,-.48),l(-1.03,-1.368),l(-.354,-.691),l(-.119,-.579),l(-.038,-.734),l(.355,-.595),l(.323,-.523),l(.21,-.664),l(-.083,-1.031),l(-.254,-.635),l(.033,-.368),l(.438,-.692),l(.109,-.325),l(.064,-.156),l(.271,.649),l(.011,.424),l(.105,.184),l(.35,.027),l(.171,-.113),l(.187,-.565),l(.141,-.48),l(.765,-.468),l(1.22,-.624),l(.484,-.326),l(.676,-.581),l(.585,-.467),l(.632,-.327),l(.79,-.114),l(.697,-.016),l(.7,-.002),l(.431,-.043),l(.352,-.185),l(.474,-.453),l(.494,-.128),l(.929,-.072),l(.279,-.143),l(.291,-.551),l(.158,-.1),l(.444,.027),l(.877,.224),l(.626,-.043),l(.911,-.299),l(1.084,-.469),l(.359,-.213),l(.716,-.665),l(.427,-.58),l(.29,-.622),l(.132,-.297),l(.41,-.369),l(.968,-.651),l(.079,-.17),l(-.067,-.409),l(-.242,-.805),l(-.016,-.495),l(1.063,-1.118),l(.387,-.692),l(.291,.169),l(.341,.437),l(.619,1.355),l(.262,.253),l(.177,-.579),l(.021,-.466),l(.436,.238),l(.272,.07),l(.189,-.607),l(-.06,-.142),l(-.563,-.238),l(-.175,-.24),l(.007,-.565),l(.044,-.112),l(.897,.04),l(.661,.253),l(.642,-.029),l(.334,-.029),l(.289,.074),l(-.699,-.455),l(-.431,-.141),l(.128,-.537),l(-.07,-.296),l(.135,-.509),l(.422,-.354),l(.165,-.07),l(.732,.394),l(.202,-.043),l(-.112,-.452),l(.11,-.48),l(.146,-.367),l(-.041,-.522),l(.358,-.171),l(.4,-.113),l(.813,.04),l(.529,-1.088),l(.371,-.298),l(.35,.169),l(.268,.451),l(.265,-.552),l(.222,-.227),l(.197,-.48),l(.695,.62),l(.513,.084),l(.293,.211),l(.331,.536),l(.632,.592),l(.122,.706),l(-.072,.594),l(.181,.197),l(.256,-.283),l(.462,-.679),l(.155,-.128),l(1.16,.082),l(.479,.155),l(.637,.492),l(.332,.141),l(.156,-.48),l(.302,-.297),l(.022,-.24),l(-.266,-.324),l(-.601,-.395),l(-.079,-.184),l(.008,-.24),l(.145,-.099),l(.604,-.538),l(.007,-.452),l(.191,-.213),l(.518,-.283),l(.268,-.241),l(.151,-.269),l(-.094,-.184),l(.003,-.296),l(.512,-.863),l(.121,-.057),l(.317,-.029),l(.397,-.029),l(.248,-.17),l(-.205,-.409),l(.377,-.396),l(.344,-.071),l(.793,.366),l(.616,-.072),l(1.291,-.088),l(.512,-.128),l(.232,-.17),l(.04,-.057),l(-.077,-.197),l(-.2,-.734),l(-.248,-.282),l(-.471,-.268),l(-.374,.086),l(-.244,-.141),l(.035,-.212),l(.367,-.143),l(.396,-.043),l(.617,.521),l(.255,.099),l(.34,-.1),l(.364,.31),l(.676,.465),l(.36,.154),l(1.297,.294),l(.591,.084),l(.413,-.143),l(.372,.014),l(.396,.606),l(.419,.112),l(.141,-.029),l(.562,-.438),l(.454,.027),l(.652,.38),l(.331,.479),l(.46,-.143),l(.122,-.791),l(.181,-.085),l(.455,.465),l(.337,.099),l(.152,.154),l(-.436,.411),l(-.126,.424),l(-.176,.212),l(-.011,.438),l(-.12,.255),l(-.513,.015),l(-.51,.228),l(-.396,.34),l(-.004,.551),l(.301,.353),l(-.187,.692),l(-.381,.58),l(-.559,.481),l(-.155,.48),l(.063,.17),l(.469,.437),l(1.038,.619),l(.81,.677),l(.508,.606),l(.246,.099),l(.349,-.114),l(.264,.027),l(.782,.352),l(.742,.465),l(.434,.451),l(.679,.535),l(.335,.127),l(.442,.027),l(.784,.182),l(.25,.184),l(.218,.621),l(.167,.169),l(.507,.31),l(.76,.423),l(.537,.154),l(.422,-.072),l(.414,-.17),l(.603,-.199),l(.208,-.156),l(.736,-1.344),l(.403,-1.131),l(.194,-1.314),l(.259,-.721),l(.43,-.679),l(-.131,-.424),l(-.409,-.621),l(.022,-.311),l(.236,-.637),l(.187,-.48),l(-.164,-.282),l(-.183,-.395),l(.088,-.692),l(.104,-1.004),l(.225,-.297),l(.329,-.156),l(.158,-.311),l(-.534,-.521),l(.033,-.198),l(.576,-.947),l(.312,-.934),l(.072,-.833),l(.191,-.241),l(.279,-.297),
+N(270.934,276.123),l(.054,-.338),l(-.194,-.577),l(.011,-.522),l(.24,-.495),l(.48,-.524),l(.118,-.325),l(-.168,-.986),l(-.049,-.847),l(.103,-.522),l(.595,-2.359),l(.065,-.452),l(.443,-.524),l(.55,-.003),l(1.042,-.246),l(.25,-.101),l(.266,.098),l(.47,.364),l(.379,.407),l(.59,.814),l(.232,.38),l(.27,-.016),l(.693,-.427),l(.365,.393),l(.432,.576),l(.617,.194),l(.55,.194),l(.999,.587),l(.474,.435),l(.853,1.109),l(.131,.197),l(.163,.027),l(.333,.379),l(-.017,.269),l(-.634,.766),l(-.103,.269),l(.258,.746),l(.101,.313),l(-.059,.053),l(-.803,1.103),l(-.625,.552),l(-.775,.454),l(-.441,.156),l(-.818,.1),l(-.874,-.337),l(-.551,.044),l(-.551,.114),l(-.64,.283),l(-.38,-.042),l(-.846,-.676),l(-.637,-.252),l(-.76,-.154),l(-.469,.128),l(-.507,.072),l(-.327,-.127),l(-.548,-.563),l(-.354,-.159),
+N(418.763,73.869),l(.391,-.499),l(.389,-.262),l(.283,.081),l(.663,-.062),l(.762,-.075),l(.324,-.137),l(.891,-.787),l(.979,-.2),l(.224,.025),l(.198,-.219),l(.175,.032),l(-.349,.531),l(.11,.106),l(.026,.481),l(-.288,.156),l(-.17,.368),l(-1.675,.069),l(-.376,-.106),l(-.428,.031),l(-.14,-.062),l(-.239,.081),l(-.275,.031),l(-.153,.417),l(-.249,.218),l(-.353,.118),l(-.08,.112),l(-.229,-.155),l(-.411,-.292),M(421.68,78.002),l(-1.839,.129),l(-.116,-.016),l(.064,-.404),l(-.19,-.638),l(-.174,.015),l(-.36,-.293),l(-.233,.184),l(-.398,-.172),l(.2,-.355),l(.434,-.293),l(-.007,-.181),l(-.445,-.541),l(.018,-.256),l(.131,-.498),l(.279,-.106),l(.318,.15),l(.495,.12),l(.43,-.574),l(.299,-.091),l(.296,.437),l(.391,-.046),l(.022,-.528),l(.107,-.363),l(1.032,-.017),l(.848,.089),l(.03,.544),l(.187,.301),l(1.138,.058),l(.14,.166),l(-.307,.604),l(-.565,.142),l(-.119,-.261),l(-.331,.031),l(-.263,.136),l(.121,.278),l(-.184,.414),l(-.312,.077),l(-.069,.244),l(-.635,.035),l(.157,.229),l(-.291,.094),l(-.191,.24),l(-.061,.285),l(.003,.21),l(-.215,.338),l(.166,.084),M(427.177,77.967),l(-.139,-.149),l(-.312,-.344),l(-.405,.031),l(-.665,-.059),l(-.123,-.329),l(-.285,-.66),l(.433,-.091),l(.603,-.467),l(.356,.495),l(.521,.179),l(.2,-.271),l(.078,-.586),l(.333,-.046),l(.459,.044),l(.056,.571),l(-.134,.36),l(-.144,.09),l(-.413,.286),l(.603,.299),l(-.285,.166),l(-.499,.39),l(-.238,.09),
+N(417.259,94.301),l(-.135,-.233),l(.216,-.701),l(-.091,-.076),l(.075,-.295),l(.321,-.372),l(.054,-.358),l(.054,-.213),l(.954,-.806),l(-.605,-.193),l(-.479,.014),l(-.456,-.09),l(-.095,-.186),l(-.233,-.007),l(-.072,.048),l(-.689,.062),l(-.045,-.145),l(-.395,.055),l(-.337,-.277),l(-.428,-.319),l(-.074,-.353),l(.248,-.144),l(.044,-.288),l(-.466,-.096),l(-.41,-.312),l(-.062,-.301),l(.422,-.376),l(-.038,-.468),l(-.282,-.365),l(-.344,-.177),l(.165,-.278),l(-.143,-.217),l(-.182,-.037),l(.08,-.097),l(.235,-.133),l(.236,-.133),l(-.193,-.121),l(.201,-.275),l(.095,-.148),l(-.152,-.292),l(-.082,-.265),l(-.376,-.182),l(.07,-.182),l(.341,-.078),l(.175,-.092),l(.378,.134),l(.664,-.151),l(.32,-.152),l(.128,-.376),l(.412,-.207),l(.003,-.328),l(-.16,-.17),l(-.188,.061),l(-.44,-.134),l(.029,-.184),l(.113,-.181),l(.571,.036),l(.084,-.401),l(.345,-.361),l(-.151,-.438),l(.066,-.147),l(-.465,-.192),l(.126,-.43),l(.285,-.181),l(.371,-.028),l(1.12,-.062),l(.293,-.012),l(.095,.16),l(.195,.271),l(-.155,.158),l(.324,.113),l(.148,-.068),l(.042,-.192),l(-.159,-.204),l(.259,.012),l(.437,.169),l(-.163,-.362),l(.247,-.419),l(.687,.113),l(.614,-.091),l(-.596,-.17),l(-.084,-.227),l(.282,-.102),l(-.252,-.114),l(-.12,-.147),l(.166,-.08),l(.068,-.136),l(-.675,.08),l(-.06,-.182),l(.664,-.125),l(.218,-.193),l(-.464,-.42),l(-.324,-.341),l(.045,-.28),l(.116,.016),l(1.839,-.129),l(.254,.13),l(.565,.341),l(.271,.297),l(-.02,.228),l(-.252,.175),l(.445,-.05),l(.171,.216),l(.157,-.078),l(.283,.021),l(.235,.156),l(.45,.073),l(.866,-.121),l(.077,.208),l(-.07,.149),l(-.057,.125),l(-.665,.295),l(.316,.193),l(.649,-.136),l(.113,.182),l(.457,-.006),l(.349,-.391),l(1.059,-.136),l(.602,-.234),l(.757,-.266),l(.249,.113),l(.396,-.17),l(.184,.182),l(.085,.159),l(.634,.29),l(.182,.074),l(.526,-.12),l(.156,.12),l(.059,.34),l(.036,.227),l(.154,.102),l(.354,.125),l(.372,-.022),l(.028,.13),l(.201,.025),l(.319,.835),l(-.219,.52),l(-.391,.147),l(-.051,.328),l(.391,.102),l(.683,.429),l(-.217,.395),l(.094,.18),l(.312,.146),l(-.021,.304),l(.131,.102),l(-.118,.292),l(-.214,.124),l(-.007,.191),l(.325,.27),l(-.114,.258),l(.468,.188),l(.281,.485),l(-.435,.698),l(-.142,.115),l(-.344,-.072),l(-.031,-.278),l(-.308,-.121),l(-.436,.072),l(.282,.218),l(-.254,.084),l(-.284,.097),l(-.524,.048),l(-.124,.169),l(-.735,.024),l(-.112,.217),l(-.176,-.072),l(-.358,.061),l(-.097,.229),l(-.382,.012),l(-.078,.181),l(-.442,0),l(-.422,.201),l(-.293,-.033),l(-.26,.181),l(-.243,.168),l(.037,.056),l(.258,.378),l(.413,.098),l(-.155,.25),l(-.08,.406),l(.159,.085),l(.036,.233),l(.244,.173),l(.478,.265),l(.188,-.072),l(.573,.515),l(.431,.17),l(.184,.201),l(.219,-.084),l(.165,.18),l(.207,.036),l(.447,.633),l(-.682,.26),l(-.437,-.151),l(-.132,.027),l(-.039,.337),l(-.162,.172),l(-.968,.295),l(-.364,.227),l(.538,.571),l(-.197,.295),l(.334,.014),l(.056,.158),l(-.098,.343),l(-.082,.055),l(-.441,-.178),l(.049,-.165),l(-.146,-.117),l(-.564,.062),l(-.195,-.138),l(-.433,.035),l(-.092,.178),l(-1.25,.035),l(-.125,.171),l(-.319,.014),l(-.044,.13),L(425.4,94.7),l(-.594,.021),l(-.059,-.144),l(-.093,-.145),l(-.493,-.089),l(-.262,.055),l(-.237,-.041),l(.032,.274),l(-.452,.343),l(-.215,0),l(.078,-.195),l(-.26,-.039),l(.011,-.165),l(-.194,-.048),l(-.104,-.137),l(-.249,-.007),l(-.096,-.11),l(-.164,.137),l(-.368,-.014),l(-.664,-.261),l(-.852,-.007),l(-.149,-.089),l(-.199,.014),l(-.017,-.151),l(-.709,.199),l(.179,.199),l(-.354,.021),l(-.278,-.11),l(-.567,.158),l(-.271,-.096),l(-.272,.117),l(-.271,-.089),M(432.012,80.473),l(-.171,-.038),l(-.088,-.049),l(-.447,.08),l(-.111,-.264),l(.002,-.213),l(.647,.281),l(.168,.203),
+N(450.734,91.05),l(-.831,-.33),l(-.424,-.101),l(-.104,-.216),l(-.703,-.186),l(-.129,-.13),l(-.561,.076),l(-.508,-.041),l(-.073,.137),l(-.373,.18),l(-.46,-.254),l(-.483,.046),l(-.168,-.056),l(-.558,.204),l(-.104,.177),l(-.149,.135),l(-.18,-.12),l(-.389,.083),l(-.003,-.204),l(.026,-.083),l(-.066,-.18),l(-.331,.025),l(-.073,-.169),l(-.194,-.24),l(-.261,.024),l(-.062,.112),l(-.193,-.016),l(-.183,.24),l(-.43,.048),l(-.03,-.228),l(-.285,-.041),l(-.105,-.331),l(-.382,-.096),l(-.188,-.208),l(.02,-.249),l(-.802,-.132),l(-.311,-.181),l(-.368,.161),l(-.293,-.013),l(-.013,-.221),l(.001,-.253),l(-.329,.084),l(.181,-.283),l(-.709,.005),l(-.258,-.121),l(-.509,-.193),l(-.286,-.024),l(-.003,.145),l(.282,.302),l(-.41,.12),l(-.22,.187),l(-.318,-.072),l(-.296,-.38),l(-.55,-.247),l(.224,-.211),l(.208,-.024),l(.099,-.121),l(-.199,-.181),l(-.257,-.024),l(-.061,.066),l(-.466,.066),l(.005,-.169),l(-.278,.037),l(-.132,-.181),l(-.568,-.054),l(-.201,-.025),l(-.363,-.163),l(-.093,-.26),l(-.211,-.091),l(-.361,.018),l(-.063,.084),l(.062,.073),l(-.024,.151),l(-.375,0),l(.435,-.698),l(-.281,-.485),l(-.468,-.188),l(.114,-.258),l(-.325,-.27),l(.007,-.191),l(.214,-.124),l(.118,-.292),l(-.131,-.102),l(.021,-.304),l(-.312,-.146),l(-.094,-.18),l(.217,-.395),l(-.683,-.429),l(-.391,-.102),l(.051,-.328),l(.391,-.147),l(.219,-.52),l(-.319,-.835),l(.34,.043),l(.23,.125),l(-.093,-.193),l(.156,-.153),l(-.019,-.147),l(-.166,-.13),l(-.021,-.129),l(-.012,-.075),l(.93,-.154),l(.431,-.051),l(.516,-.152),l(1.304,-.128),l(.48,-.158),l(.797,-.479),l(1.117,-.298),l(1.515,-.303),l(1.382,-.086),l(1.067,.417),l(-.882,-.294),l(-.054,.147),l(.256,.172),l(.132,.466),l(.355,.135),l(.648,.061),l(.645,-.11),l(1.063,-.409),l(.054,.004),l(-.978,.417),l(-.19,.11),l(-.004,.123),l(.218,.012),l(.286,-.123),l(.613,-.208),l(.543,-.253),l(.842,.006),l(2.246,.115),l(2.96,-.101),l(.641,-.021),l(.04,.014),l(.679,.243),l(.284,.487),l(.099,.186),l(.016,.029),l(.09,.171),l(.16,.302),l(.615,1.5),l(.172,.502),l(-.023,.236),l(-.263,.208),l(-.44,.03),l(-.571,.244),l(-.291,.328),l(-.128,.292),l(.289,.012),l(.421,.146),l(.149,.176),l(.218,.146),l(.013,.25),l(-.315,.752),l(.126,.137),l(.161,.175),l(-.074,.242),l(.816,.835),l(.316,.193),l(-.298,.048),l(-.085,.133),l(.328,.302),l(-.009,.314),l(-.255,.24),l(-.429,.013),l(-.286,.181),l(-.599,.398),l(-1.509,1.218),l(-.082,.306),l(.044,.552),l(.349,.383),l(-.653,-.018),M(431.844,80.27),l(.232,.024),l(.069,.208),l(-.134,-.029),l(-.168,-.203),M(432.739,80.361),l(-.03,.129),l(-.278,-.024),l(-.191,.03),l(-.046,-.208),l(.174,-.012),l(.266,0),l(.106,.085),
+N(416.488,81.945),l(.151,.438),l(-.345,.361),l(-.084,.401),l(-.571,-.036),l(-.113,.181),l(-.029,.184),l(.44,.134),l(.188,-.061),l(.16,.17),l(-.003,.328),l(-.412,.207),l(-.128,.376),l(-.32,.152),l(-.664,.151),l(-.378,-.134),l(-.175,.092),l(-.341,.078),l(-.07,.182),l(.376,.182),l(.082,.265),l(.152,.292),l(-.095,.148),l(-.201,.275),l(.193,.121),l(-.236,.133),l(-.235,.133),l(-.08,.097),l(.182,.037),l(.143,.217),l(-.165,.278),l(-.672,.024),l(-.001,-.338),l(.172,-.097),l(.11,-.423),l(-.754,-.375),l(-.535,.109),l(-.292,-.375),l(-.228,-.061),l(-.173,.121),l(-.313,-.242),l(-.267,.182),l(-.307,0),l(-.307,-.012),l(.025,.157),l(-.52,.034),l(-.407,-.042),l(-.477,-.098),l(-.07,-.162),l(-.496,-.264),l(.795,-.472),l(.858,-.621),l(.273,-.354),l(.563,-1.167),l(.173,-.104),l(.644,-.12),l(.367,.251),l(.136,.268),l(-.28,.203),l(-.228,-.056),l(.066,.496),l(-.191,.124),l(1.163,.225),l(.225,-.236),l(.406,-.113),l(.134,-.417),l(-.458,-.022),l(-.123,-.124),l(-.02,-.203),l(.236,-.158),l(-.171,-.023),l(-.558,-.067),l(.072,-.328),l(-.034,-.13),l(-.023,-.034),l(.128,-.283),l(.572,-.198),l(.709,-.238),l(.654,.03),l(1.089,-.151),l(.245,.275),l(.329,.045),l(.076,.181),l(.259,0),
+N(431.57,91.965),l(-.447,-.633),l(-.207,-.036),l(-.165,-.18),l(-.219,.084),L(430.349,91),l(-.431,-.17),l(-.573,-.515),l(-.188,.072),l(-.478,-.265),l(-.244,-.173),l(-.036,-.233),l(-.159,-.085),l(.08,-.406),l(.155,-.25),l(-.413,-.098),l(-.258,-.378),l(-.037,-.056),l(.243,-.168),l(.26,-.181),l(.293,.033),l(.422,-.201),l(.442,0),l(.078,-.181),l(.382,-.012),l(.097,-.229),l(.358,-.061),l(.176,.072),l(.112,-.217),l(.735,-.024),l(.124,-.169),l(.524,-.048),l(.284,-.097),l(.254,-.084),l(-.282,-.218),l(.436,-.072),l(.308,.121),l(.031,.278),l(.344,.072),l(.142,-.115),l(.375,0),l(.024,-.151),l(-.062,-.073),l(.063,-.084),l(.361,-.018),l(.211,.091),l(.093,.26),l(.363,.163),l(.201,.025),l(.568,.054),l(.132,.181),l(.278,-.037),l(-.005,.169),l(.466,-.066),l(.061,-.066),l(.257,.024),l(.199,.181),l(-.099,.121),l(-.208,.024),l(-.224,.211),l(.55,.247),l(.296,.38),l(.318,.072),l(.22,-.187),l(.41,-.12),l(-.282,-.302),l(.003,-.145),l(.286,.024),l(.509,.193),l(.258,.121),l(.709,-.005),l(-.181,.283),l(.329,-.084),l(-.001,.253),l(.013,.221),l(.293,.013),l(.368,-.161),l(.311,.181),l(.802,.132),l(-.02,.249),l(.188,.208),l(.382,.096),l(.105,.331),l(-.071,-.012),l(-.065,.066),l(-.066,.04),l(-.105,-.026),L(442,89.998),l(-.119,.013),l(-.065,.04),l(-.132,.066),l(-.053,.079),l(-.118,.092),l(-.119,.053),l(-.132,.079),l(-.105,.013),l(-.118,.013),l(-.053,.092),l(-.026,.092),l(-.026,.132),l(-.053,.079),l(-.053,.105),l(-.145,.066),l(-.105,.04),l(-.092,-.026),l(-.079,.079),l(-.04,.092),l(-.053,.079),l(-.039,0),l(-.105,.026),l(-.066,.026),l(-.079,.053),l(-.118,.053),l(-.132,0),l(-.145,.04),l(-.093,.026),l(-.065,-.026),l(-.065,-.026),l(-.093,0),l(-.065,.026),l(-.158,0),l(-.132,-.053),l(-.092,-.053),l(-.093,.026),l(-.171,.053),l(-.026,.04),l(-.146,.119),l(-.092,.066),l(-.014,.131),l(-.065,.105),l(-.039,.044),l(-.055,-.095),l(-.545,-.2),l(-1.332,.181),l(-1.019,-.227),l(-1.374,-.341),l(-.746,.773),l(-.598,.163),l(-.483,-.099),l(-.354,-.129),l(-.145,-.014),
+N(421.683,94.397),l(.368,.014),l(.164,-.137),l(.096,.11),l(.249,.007),l(.104,.137),l(.194,.048),l(-.011,.165),l(.26,.039),l(-.078,.195),l(.215,0),l(.452,-.343),l(-.032,-.274),l(.237,.041),l(.262,-.055),l(.493,.089),l(.093,.145),l(.059,.144),L(425.4,94.7),l(.377,-.103),l(.044,-.13),l(.319,-.014),l(.125,-.171),l(1.25,-.035),l(.092,-.178),l(.433,-.035),l(.195,.138),l(.564,-.062),l(.146,.117),l(-.049,.165),l(.441,.178),l(.082,-.055),l(.098,-.343),l(-.056,-.158),l(-.334,-.014),l(.197,-.295),l(-.538,-.571),l(.364,-.227),l(.968,-.295),l(.162,-.172),l(.039,-.337),l(.132,-.027),l(.437,.151),l(.682,-.26),l(.145,.014),l(.354,.129),l(.483,.099),l(.598,-.163),l(.746,-.773),l(1.374,.341),l(1.019,.227),l(1.332,-.181),l(.545,.2),l(.055,.095),l(.053,.093),l(-.097,.581),l(.155,.26),l(.761,.547),l(-.636,.291),l(-.019,.367),l(-.701,.054),l(-.164,-.134),l(-.325,0),l(-.223,.197),l(.452,.063),l(.136,.196),l(-.157,.206),l(-.409,.062),l(-.04,.375),l(.204,.188),l(-.154,.294),l(-.346,.299),l(-.693,.157),l(.082,.393),l(-.89,-.116),l(-.298,.196),l(-.85,-.08),l(-.566,.107),l(-.646,.5),l(-.287,-.152),l(-.612,.009),l(-.179,-.107),l(-1.04,-.065),l(-.478,-.112),l(-.894,-.082),l(-1.311,-.247),l(-.32,-.391),l(-.318,-.096),l(-.023,-.363),l(-.856,.227),l(-.301,-.103),l(-.445,.11),l(-.183,-.083),l(-.366,.096),l(-.329,.411),l(-.597,-.034),l(-.631,-.171),l(.029,-.171),l(-.215,-.117),l(-.579,.332),l(-.55,-.242),l(-.008,-.144),l(-.622,-.062),l(.09,-.192),l(-.214,-.288),l(.266,-.274),l(-.193,-.336),
+N(431.763,171.063),l(-.067,.354),l(.091,.72),l(.108,.508),l(.225,.168),l(.562,.11),l(.144,.183),l(.077,.353),l(-.089,1.116),l(-.146,.227),l(-.274,.171),l(-.885,.217),l(-.291,.256),l(-.664,1.275),l(-.503,1.203),l(-.243,1.004),l(-.354,.129),l(-.369,.03),l(-.129,.354),l(-.146,1.229),l(-.192,.312),l(-.385,.045),l(-.257,.284),l(-.417,.836),l(-.944,2.223),l(-.304,.624),l(-.352,.496),l(-.368,.355),l(-.239,.114),l(-.145,-.056),l(-.722,-.97),l(-.145,-.14),l(-1.104,-.05),l(-.272,.03),l(-1.31,1.265),l(-.941,.839),l(-.495,.526),l(.02,.974),l(-.189,.552),l(-.376,.686),l(-.188,-.119),l(-.224,-.042),l(-.176,-.127),l(-.145,.212),l(.144,.296),l(-.063,.127),l(-.353,.198),l(-.56,.03),l(-.977,.101),l(-.607,-.267),l(-.288,.043),l(-.271,.368),l(-.177,.113),l(-.432,-.07),l(-1.247,-.011),l(-.528,-.225),l(-.543,-.451),l(-.416,-.72),l(-.192,-.649),l(.048,-.254),l(.208,-.254),l(-.144,-.296),l(-.513,-.069),l(-.128,-.254),l(-.464,-.55),l(-.561,-.465),l(-.608,-.253),l(-.641,-.253),l(-.272,-.31),l(-.513,.072),l(-.24,.297),l(-.336,.071),l(-.881,.044),l(-.659,.03),l(-.006,-.234),l(.121,-1.188),l(-.217,-1.439),l(.09,-.989),l(.012,-.876),l(-.003,-.48),l(-.002,-.381),l(.237,-.397),l(.257,-.03),l(.433,-.13),l(.078,-.368),l(-.116,-.592),l(.095,-.34),l(.656,-.414),l(.223,-.298),l(.19,-.566),l(.316,-.962),l(-.388,-.718),l(-.164,-.762),l(.062,-.777),l(.092,-.961),l(.158,-.849),l(.353,-.482),l(.687,-1.614),l(.676,-.4),l(1.064,-.188),l(1.174,-.108),l(1.111,.121),l(.821,.277),l(1.095,1.223),l(.209,.098),l(.37,-.002),l(1.337,-.544),l(.467,-.116),l(.354,.083),l(1.173,.742),l(.965,.277),l(.934,-.005),l(.273,-.059),l(.629,-.399),l(.403,-.327),l(.774,-.287),l(.628,-.103),l(.709,-.047),l(.531,.04),l(.884,.221),l(.724,.193),l(.609,.208),l(.259,-.058),l(.761,-.697),l(.453,-.299),l(.437,-.2),l(.951,-.034),l(.173,.394),l(.575,.52),l(.351,.407),
+N(425.506,195.522),l(-1.965,-.017),l(-1.005,.007),l(.029,-.176),l(-.208,-.536),l(.271,-.989),l(-.159,-.72),l(-.191,-.522),l(-.399,-.649),l(.433,-.396),l(-.287,-.367),l(-.24,-.056),l(-.576,.058),l(-.559,-.268),l(-.176,-.324),l(-.063,-.537),l(-.111,-.211),l(-.527,-.14),l(-.101,-.064),l(.376,-.686),l(.189,-.552),l(-.02,-.974),l(.495,-.526),l(.941,-.839),l(1.31,-1.265),l(.272,-.03),l(1.104,.05),l(.145,.14),l(.722,.97),l(.145,.056),l(.239,-.114),l(.368,-.355),l(.352,-.496),l(.304,-.624),l(.944,-2.223),l(.417,-.836),l(.257,-.284),l(.385,-.045),l(.192,-.312),l(.146,-1.229),l(.129,-.354),l(.369,-.03),l(.354,-.129),l(.243,-1.004),l(.503,-1.203),l(.664,-1.275),l(.291,-.256),l(.885,-.217),l(.274,-.171),l(.146,-.227),l(.089,-1.116),l(-.077,-.353),l(-.144,-.183),l(-.562,-.11),l(-.225,-.168),l(-.108,-.508),l(-.091,-.72),l(.067,-.354),l(.627,.109),l(.208,.083),l(.923,1.238),l(.395,.887),l(.119,1.2),l(-.134,.651),l(.169,1.228),l(.205,.578),l(.381,.633),l(.208,.21),l(.047,.127),l(-.225,.143),l(-.674,.032),l(-1.187,-.191),l(-.481,-.082),l(-.24,.1),l(-.29,.312),l(-.323,.539),l(1.088,1.067),l(1.343,1.179),l(.638,1.07),l(.382,1.057),l(.208,.183),l(-.208,.114),l(-.354,.327),l(-.866,1.743),l(-.4,.511),l(-.528,.399),l(-.144,.198),l(-.064,.424),l(.112,.776),l(.273,1.185),l(.207,.592),l(.4,.661),l(.432,.605),l(.064,.791),l(.112,.324),l(1.217,1.236),l(.498,.802),l(.194,.804),l(.209,.451),l(-.159,.185),l(.1,.861),l(-.271,.086),l(-.863,-.292),l(-.864,-.334),l(-.576,-.194),l(-.56,-.124),l(-.479,-.04),l(-.271,-.055),l(-.878,.076),l(-.863,-.023),l(-.56,-.109),l(-1.022,-.149),l(-.831,-.038),l(-1.773,-.088),l(-.88,-.093),l(-.045,.495),
+N(551.793,147.278),l(-.788,-.111),l(-.458,-.253),l(-.379,-.367),l(-.248,-1.101),l(-.112,-.141),l(-.342,-.141),l(-.662,-.083),l(-.105,-.07),l(-.014,-.268),l(.116,-.466),l(-.178,-.451),l(-.418,-.38),l(-.294,-.013),l(-1.181,.412),l(-1.229,.087),l(-.81,.143),l(-.947,.073),l(-.415,-.083),l(-.263,-.226),l(-.135,-.197),l(-.909,.143),l(-.548,.382),l(-.856,.016),l(-1.264,-.011),l(-.691,.128),l(-.723,.115),l(-.541,.03),l(.182,-.954),l(.049,-.354),l(.31,-.792),l(.285,-.383),l(.794,-.47),l(.697,-.258),l(1,-.077),l(.209,-.072),l(.188,-.255),l(.036,-.974),l(-.186,-.281),l(-.652,-.053),l(-.185,-.394),l(-.111,-1.34),l(-.168,-.38),l(-.409,-.224),l(-1.144,-.388),l(-.695,-.391),l(-.353,-.464),l(-.71,-1.068),l(-.802,-1.083),l(.887,.32),l(.63,.194),l(1.069,.248),l(.854,.235),l(.541,.039),l(.742,.024),l(1.187,-.218),l(.349,-.002),l(1.005,.135),l(1.234,-.12),l(.964,-.175),l(1.183,-.19),l(1.066,-.274),l(.247,-.156),l(.069,-.184),l(.099,-.903),l(.232,-.876),l(.188,-.34),l(.412,-.369),l(.597,-.441),l(.283,-.072),l(.644,.039),l(.516,.082),l(.254,-.086),l(.321,-.693),l(.362,-.271),l(.559,-.243),l(.562,.025),l(1.001,.375),l(.237,-.086),l(.34,-.383),l(.021,-.084),l(.139,-1.214),l(.288,-.834),l(.224,-.424),l(.292,-.228),l(.416,-.115),l(.513,-.031),l(.315,-.115),l(.199,-.255),l(-.088,-.437),l(-.129,-.281),L(556.193,125),l(-.35,-.336),l(.355,-.129),l(.997,.122),l(.698,.039),l(.513,-.215),l(.289,-.255),l(-.033,-.31),l(-.223,-.478),l(.13,-.283),l(.4,-.341),l(.524,-.355),l(.324,-.426),l(-.198,-.477),l(.119,-.483),l(-.232,-.171),l(-.01,-.336),l(-.411,-.271),l(-.01,-.32),l(.464,-.413),l(.258,-.214),l(.246,.023),l(.559,-.395),l(.272,-.19),l(.53,-.292),l(1.148,-.152),l(1.345,-.012),l(.647,.144),l(.338,-.179),l(.332,.005),l(.455,-.297),l(.358,-.004),l(.148,-.142),l(.313,.14),l(.105,.112),l(.281,-.21),l(.296,.047),l(.554,.117),l(.004,.456),l(.282,-.128),l(.625,-.009),l(.373,.323),l(.213,.247),l(.007,.501),l(-.312,.516),l(.301,.07),l(.198,.218),l(.252,.281),l(.52,-.196),l(.239,0),l(.104,.199),l(.178,.09),l(.565,.436),l(1.337,.104),l(.305,.111),l(.147,.126),l(-.207,.084),l(-.688,.37),l(-.411,.232),l(-.155,.43),l(-.071,.479),l(-.234,.116),l(-.125,-.179),l(-.621,-.102),l(-.438,.132),l(-.271,.298),l(-.262,-.116),l(-.557,.265),l(-.928,-.149),l(-.568,-.138),l(-1.708,-.325),l(-.894,.265),l(-.38,.611),l(.09,.166),l(.336,0),l(.047,.314),l(-.202,.149),l(.101,.199),l(.598,-.017),l(-.002,.347),l(-.384,.099),l(-.139,.413),l(.389,.232),l(-.116,.479),l(-.215,.132),l(.089,.248),l(.606,.298),l(-.003,.532),l(.782,-.003),l(-.039,.43),l(.188,.248),l(.702,-.05),l(.668,.377),l(.012,.211),l(-.2,.255),l(-.504,.2),l(-.643,.196),l(-.517,.248),l(.032,.366),l(.188,.377),l(-.237,.977),l(-1.512,1.503),l(.261,.38),l(-.358,.281),l(-.609,.133),l(-.353,.467),l(-.509,1.216),l(-.478,.547),l(-1.193,.496),l(-.177,.364),l(-.277,.481),l(-.563,.61),l(-.076,.38),l(-.71,.259),l(-.734,-.011),l(-.895,.314),l(-.361,-.094),l(-.158,-.518),l(-.207,-.132),l(-.404,.083),l(-.535,.463),l(-.144,.446),l(-.979,.893),l(-.186,.543),l(-.079,.269),l(.116,.38),l(.541,.163),l(.504,.085),l(.425,.014),l(-.114,.689),l(-.154,.735),l(.412,.411),l(.33,.099),l(.537,-.099),l(.112,.441),l(.216,.507),l(.654,1.333),l(-.232,.149),l(.241,.463),l(-.317,.066),l(-.15,.248),l(-.55,.083),l(-.145,-.335),l(-.183,-.062),l(-.78,.215),l(-.2,.331),l(-.735,-.099),l(-.229,-.149),l(-.835,-.021),l(-.835,-.009),l(-.259,-.052),l(.015,.728),l(-.866,.017),l(-.296,.431),l(-.37,.036),
+N(606.155,150.953),l(-.037,-.466),l(-.627,-2.479),l(-.064,-.578),l(-.4,.044),l(-.281,.115),l(-.395,1.159),l(-.224,.354),l(-.529,-.448),l(-.249,-.267),l(-.23,-.281),l(-.001,-.381),l(-.009,-.522),l(.131,-.283),l(.651,-.356),l(.498,-.13),l(.938,-.767),l(.159,-.34),l(.012,-.79),l(-.057,-.127),l(-.111,-.098),l(-2.473,-.198),l(-.559,.003),l(-.916,.062),l(-.547,-.053),l(-.537,-.109),l(-.095,-.099),l(-.079,-.719),l(-.053,-.479),l(-.129,-.324),l(-.417,-.054),l(-.489,.06),l(-.372,-.266),l(-.339,-.266),l(-1.252,-.303),l(-.234,.171),l(-.555,.525),l(-.124,.283),l(.083,.155),l(.494,.237),l(1.224,.938),l(.126,.112),l(-.047,.155),l(-.382,.101),l(-.502,.13),l(-.4,.299),l(-.548,.61),l(.339,.323),l(1.042,.431),l(.193,.21),l(-.029,.269),l(-.505,.765),l(.04,.254),l(.352,.45),l(.325,1.409),l(.402,1.775),l(.147,.532),l(-.172,.322),l(.068,.183),l(-.321,.071),l(-.35,-.056),l(-.148,-.706),l(-.198,-.084),l(-.253,.354),l(-.171,.354),l(-.172,.057),l(-.115,-.099),l(-.28,-.592),l(-.152,-.169),l(-.412,.537),l(-.504,.298),l(-.992,.397),l(-.571,.213),l(-.264,.226),l(-.05,.113),l(.106,.579),l(.183,.409),l(-.336,.495),l(-.305,.332),l(-.013,.257),l(-.548,.415),l(-.593,.467),l(-.467,.185),l(-.432,.057),l(-.746,.206),l(-.591,.362),l(-.459,.58),l(-.551,.552),l(-.88,1.061),l(-.611,.552),l(-.673,.276),l(-.675,.829),l(-.676,.467),l(-.728,.368),l(-.452,.241),l(-.427,.312),l(-.192,.509),l(-.073,.466),l(-.341,.41),l(-.649,.298),l(-.428,.058),l(-.506,-.098),l(-.258,.269),l(-.366,.887),l(-.277,.23),l(-.505,-.253),l(-.614,.142),l(-.354,.283),l(-.304,.565),l(-.165,.48),l(-.005,.508),l(.166,1.539),l(.018,.805),l(-.208,.495),l(.227,.324),l(.315,.423),l(-.015,.508),l(-.199,.607),l(-.669,1.611),l(-.341,.834),l(-.13,.636),l(.047,.649),l(.21,1.764),l(-.081,.24),l(-.643,.001),l(-.433,-.013),l(-.186,.142),l(-.334,.961),l(-.324,.594),l(.025,.127),l(.493,.352),l(-.805,.327),l(-.306,.015),l(-.77,.284),l(-.295,.41),l(-.101,.692),l(-.157,.255),l(-.367,.283),l(-.526,.255),l(-.099,.057),l(-.066,.042),l(-.231,.156),l(-.145,0),l(-.174,-.056),l(-1.417,-1.451),l(-.092,-.395),l(-.276,-.522),l(-.34,-1.397),l(-.689,-1.792),l(-.94,-1.933),l(-.979,-1.508),l(-.554,-1.722),l(-.507,-1.792),l(-.738,-1.636),l(-.82,-1.42),l(-.424,-.737),l(-.598,-1.439),l(-.363,-1.157),l(-.767,-3.274),l(-.469,-2.695),l(-.157,-1.566),l(-.051,-.24),l(.232,-.565),l(.546,-.834),l(.007,-.311),l(-.404,-.281),l(-.367,-.437),l(-.113,-.635),l(-.108,-.917),l(.065,-.622),l(-.837,.03),l(-.19,.212),l(-.235,.424),l(.009,.183),l(.276,.254),l(.074,.183),l(-.073,.438),l(-.301,.438),l(-.503,.368),l(-.812,.369),l(-.504,.114),l(-.617,.255),l(-.377,.015),l(-.861,-.281),l(-.572,-.38),l(-1.018,-1),l(-1.391,-1.268),l(-.516,-.705),l(.267,-.043),l(1.062,.125),l(.615,-.086),l(.443,-.142),l(.461,-.283),l(.521,-.608),l(-.067,-.24),l(-.156,.071),l(-.587,.114),l(-.847,-.026),l(-.607,-.112),l(-.632,-.132),l(-.5,-.218),l(-.203,-.07),l(-.929,-.661),l(-.668,-.775),l(-.057,-.197),l(.37,-.036),l(.296,-.431),l(.866,-.017),l(-.015,-.728),l(.259,.052),l(.835,.009),l(.835,.021),l(.229,.149),l(.735,.099),l(.2,-.331),l(.78,-.215),l(.183,.062),l(.145,.335),l(.55,-.083),l(.15,-.248),l(.317,-.066),l(-.241,-.463),l(.232,-.149),l(-.654,-1.333),l(-.216,-.507),l(-.112,-.441),L(557,143.058),l(-.33,-.099),l(-.412,-.411),l(.154,-.735),l(.114,-.689),l(-.425,-.014),l(-.504,-.085),l(-.541,-.163),l(-.116,-.38),l(.079,-.269),l(.186,-.543),l(.979,-.893),l(.144,-.446),l(.535,-.463),l(.404,-.083),l(.207,.132),l(.158,.518),l(.361,.094),l(.895,-.314),l(.734,.011),l(.71,-.259),l(.076,-.38),l(.563,-.61),l(.277,-.481),l(.177,-.364),l(1.193,-.496),l(.478,-.547),l(.509,-1.216),l(.353,-.467),l(.609,-.133),l(.358,-.281),l(-.261,-.38),l(1.512,-1.503),l(.237,-.977),l(-.188,-.377),l(-.032,-.366),l(.517,-.248),l(.643,-.196),l(.504,-.2),l(.2,-.255),l(-.012,-.211),l(-.668,-.377),l(-.702,.05),l(-.188,-.248),l(.039,-.43),l(-.782,.003),l(.003,-.532),l(-.606,-.298),l(-.089,-.248),l(.215,-.132),l(.116,-.479),l(-.389,-.232),l(.139,-.413),l(.384,-.099),l(.002,-.347),l(-.598,.017),l(-.101,-.199),l(.202,-.149),l(-.047,-.314),l(-.336,0),l(-.09,-.166),l(.38,-.611),l(.894,-.265),l(1.708,.325),l(.568,.138),l(.928,.149),l(.557,-.265),l(.262,.116),l(.271,-.298),l(.438,-.132),l(.621,.102),l(.125,.179),l(.234,-.116),l(.071,-.479),l(.155,-.43),l(.411,-.232),l(.688,-.37),l(.207,-.084),l(.502,-.152),l(0,.515),l(.441,1.03),l(.221,.515),l(.81,.11),l(.441,.405),l(.221,.258),l(-.331,.221),l(-.184,.184),l(.073,.589),l(.037,.552),l(.294,.221),l(.718,.096),l(.092,.078),l(.044,.182),l(.68,.099),l(-.104,.414),l(.367,.694),l(-.578,.364),l(-.376,.281),l(-.368,.049),l(-.337,-.264),l(-.033,-.364),l(-.785,.198),l(.157,.694),l(.579,.595),l(-.104,.446),l(.272,.364),l(-.215,.215),l(.099,.43),l(.198,.066),l(.477,-.314),l(.383,.248),l(.772,.843),l(.363,-.116),l(1.078,.579),l(-.116,.364),l(.756,.248),l(.154,-.066),l(.859,.596),l(-1.07,.909),l(-.281,.116),l(.008,.364),l(-.221,.265),l(.04,.396),l(-.309,.397),l(-.218,.43),l(.039,.248),l(.63,.38),l(.466,-.083),l(.665,.479),l(.704,.149),l(.305,.529),l(1.242,.678),l(.231,-.166),l(1.027,.595),l(.538,-.066),l(.182,.397),l(.835,.166),l(.304,.198),l(.15,-.066),l(.087,-.215),l(.503,0),l(.482,.265),l(.582,-.347),l(.494,.298),l(.643,.066),l(.142,.231),l(-.101,.446),l(.663,.149),l(.286,.281),l(.618,.265),l(.584,-.281),l(.313,.066),l(-.034,.331),l(.312,.248),l(.379,-.231),l(.721,.148),l(.847,.364),l(.606,-.297),l(.268,.364),l(.399,.116),l(.357,-.132),l(.271,.083),l(.687,-.132),l(.336,.05),l(.311,-.694),l(-.429,-.827),l(.07,-.876),l(.318,-.761),l(-.037,-.022),l(.345,-.129),l(.471,-.102),l(.231,.069),l(.139,.183),l(-.052,.861),l(.212,.662),l(-.092,.113),l(.235,.493),l(.637,.18),l(.559,.081),l(.869,.214),l(.085,.021),l(.544,-.074),l(.531,-.313),l(.301,.055),l(.335,.125),l(1.238,.063),l(1.036,-.062),l(.624,-.06),l(.217,-.58),l(-.017,-.282),l(-.258,-.238),l(-.313,-.069),l(-.326,-.294),l(-.042,-.24),l(.07,-.156),l(.189,-.1),l(.784,-.033),l(.714,-.216),l(.397,-.27),l(1.123,-1.107),l(.543,-.37),l(.829,-.258),l(1.105,-.726),l(.546,-.299),l(.355,-.087),l(.286,.167),l(.975,.319),l(.377,-.044),l(1.377,-.84),l(.455,.392),l(.716,.715),l(.046,.38),l(-.354,.454),l(-.138,.269),l(.102,.056),l(.3,.055),l(.657,.081),l(.73,.179),l(.624,.081),l(-.018,.508),l(-.112,.24),l(-.596,.582),l(-.072,.283),l(.184,.718),l(-.295,.058),l(-.853,-.221),l(-.558,-.082),l(-.312,.129),l(-.719,.512),l(-1.446,.883),l(-.197,.354),l(.057,.761),l(-.136,.382),l(-.938,1.134),l(-.045,.212),l(.192,.408),l(0,.324),l(-1.148,2.25),l(-.17,.128),l(-.309,-.013),l(-.391,-.11),l(-.811,-.32),l(-.133,.283),l(.146,1.594),l(-.191,.354),l(-.401,.144),l(-.228,.185),l(.152,.93),l(-.015,.678),l(-.273,.368),l(-.25,.129),l(-.255,-.14),l(-.595,-.152),
+N(478.516,135.173),l(.052,-.292),l(-.049,-.169),l(-.197,-.107),l(.107,-.175),l(.292,-.919),l(-.015,-.818),l(.517,-1.09),l(.3,-.891),l(-.004,-.409),l(.133,-.283),l(.07,-.749),l(.033,-.847),l(.062,-.174),l(.026,-.278),l(-.065,-.411),l(.037,-.119),l(.102,-.063),l(1.902,1.034),l(.365,.167),l(.253,-.016),l(1.139,-.656),l(2.96,-1.541),l(.161,-.071),l(.87,1.632),l(.311,.69),l(.093,.056),l(-.46,.44),l(-.257,.171),l(-.97,.26),l(-2.586,.622),l(-.646,.229),l(1.146,1.32),l(.698,.885),l(-.765,.724),l(-.456,.37),l(-.24,.072),l(-1.249,.332),l(-.462,.61),l(-.975,.782),l(-2.079,-.299),l(-.154,-.017),
+N(456.028,151.46),l(-.021,1.003),l(.033,3.078),l(-.088,.17),l(-1.561,-.019),l(-.52,-.011),l(-.073,1.13),l(-1.981,-.963),l(-5.577,-2.792),l(-4.941,-2.372),l(-5.231,-2.554),l(-.41,.059),l(-1.818,.858),l(-1.519,.729),l(-.231,.157),l(-1.192,-.911),l(-.258,-.182),l(-1.008,-.333),l(-1.646,-.442),l(-.832,-.137),l(-.098,-.07),l(-.86,-1.506),l(-.178,-.168),l(-1.028,-.347),l(-.702,-.165),l(-.544,.201),l(-.244,-.154),l(-.562,-.873),l(-.249,-.917),l(-1.272,-1.702),l(.152,-.283),l(.249,-.128),l(.666,-.47),l(.086,-.17),l(.061,-.664),l(-.457,-1.156),l(.158,-.495),l(.16,-.622),l(-.101,-.748),l(.1,-.862),l(-.052,-.691),l(-.147,-.833),l(-.88,-1.605),l(.241,-.383),l(.204,-.156),l(.22,-.143),l(.864,-.598),l(.155,-.227),l(.147,-.537),l(-.274,-.973),l(.126,-.354),l(1.473,-1.138),l(.579,-.314),l(.802,-.428),l(.093,-.269),l(-.064,-.564),l(.093,-.981),l(1.436,.59),l(.995,.309),l(.521,.013),l(.863,-.129),l(.604,.027),l(1.552,.223),l(.614,.479),l(.794,.224),l(.486,-.001),l(.342,.197),l(.173,.226),l(.26,.819),l(.39,.564),l(.688,.591),l(.378,.126),l(.678,.14),l(1.031,.083),l(.447,.07),l(.973,.224),l(.639,.224),l(.552,.281),l(1.289,.788),l(.84,.464),l(.465,.013),l(.441,-.128),l(.758,-.411),l(.706,-.623),l(.3,-.523),l(0,-.254),l(-.276,-.621),l(-.112,-.579),l(.044,-.41),l(.237,-.537),l(.661,-.58),l(.333,-.198),l(.554,-.241),l(.644,-.298),l(1.376,-.413),l(1.205,.054),l(.728,.154),l(.844,.365),l(.188,.169),l(.043,.508),l(.281,.253),l(.301,.014),l(.945,.125),l(.712,.309),l(.45,.027),l(1.286,.04),l(.302,.197),l(.068,.381),l(.276,.296),l(-.099,.208),l(-.369,.228),l(-.21,.34),l(.354,1.283),l(-.231,.425),l(-.322,.553),l(-.056,.311),l(.185,.945),l(.388,.916),l(.042,.367),l(-.015,.988),l(-.019,3.869),l(-.016,1.468),l(-.008,2.048),l(-.001,.692),l(.045,2.81),l(-.021,1.342),l(.011,2.612),
+N(478.212,134.714),l(-.834,-1.746),l(-.796,-1.944),l(-.124,-.289),l(.109,-.066),l(.679,-.851),l(.219,-.438),l(.183,-.507),l(.171,-.566),l(.188,-.822),l(.116,.018),l(.137,-.093),l(.006,-.204),l(.028,-.315),l(.372,-.051),l(.151,.022),l(.07,.099),l(.355,-.07),l(.009,-.167),l(.067,-.193),l(.088,-.041),l(.07,.023),l(.183,.346),l(.201,.128),l(.021,.183),l(-.047,.122),l(.082,.085),l(-.102,.063),l(-.037,.119),l(.065,.411),l(-.026,.278),l(-.062,.174),l(-.033,.847),l(-.07,.749),l(-.133,.283),l(.004,.409),l(-.3,.891),l(-.517,1.09),l(.015,.818),l(-.292,.919),l(-.107,.175),l(-.067,.068),l(-.042,.042),
+N(495.751,163.817),l(-.03,-.184),l(-.112,-.537),l(-.508,-.945),l(-.73,-.987),l(-.438,-.493),l(-.846,-.69),l(-.51,-.875),l(-.814,-1.876),l(-.474,-.889),l(-.28,-.409),l(-.794,-.507),l(-1.271,-.689),l(-.527,-.634),l(-.8,-1.17),l(-.081,-.96),l(-.061,-.776),l(-.002,-.89),l(-.104,-.381),l(-.312,-.663),l(-.944,-1.65),l(-.357,-.494),l(-.758,-.62),l(-.459,-.225),l(-.499,-.126),l(-.308,-.282),l(-.483,-.578),l(.149,-.692),l(-.111,-.437),l(-.474,-.818),l(-.747,-1.072),l(-.793,-.902),l(-1.069,-1.494),l(-.525,-.931),l(-.352,-.479),l(-.722,-.761),l(-.524,-.056),l(-.248,0),l(.077,-.296),l(.193,-.283),l(.311,-1.314),l(.104,-.583),l(.154,.017),l(2.079,.299),l(.975,-.782),l(.462,-.61),l(1.249,-.332),l(.24,-.072),l(.456,-.37),l(.765,-.724),l(-.698,-.885),l(-1.146,-1.32),l(.646,-.229),l(2.586,-.622),l(.97,-.26),l(.257,-.171),l(.46,-.44),l(.093,.056),l(1.129,.459),l(.757,.222),l(2.034,.934),l(1.14,.473),l(2.44,1.101),l(.258,.196),l(.399,.633),l(.141,.07),l(.973,-.048),l(.135,.366),l(-.118,.396),l(.047,.818),l(.118,.253),l(.812,.277),l(1.557,.697),l(4.048,.132),l(1.657,.259),l(.408,.054),l(.334,.619),l(.185,.239),l(1.07,.05),l(.644,-.044),l(.043,.121),l(.277,.648),l(.365,.494),l(.178,.663),l(.052,.113),l(.615,-.029),l(.248,.126),l(-.204,.237),l(.194,.187),l(.184,.282),l(.234,.067),l(.234,.27),l(.886,.168),l(.423,.437),l(-.07,.28),l(-.235,.035),l(-.111,.25),l(.316,.381),l(-.188,.593),l(-.122,.198),l(.165,.268),l(.302,.666),l(.149,-.117),l(.372,.282),l(.105,.616),l(.422,.696),l(-.028,.423),l(.222,.268),l(.16,.197),l(.287,.084),l(.136,-.007),l(.336,.083),l(1.043,2.198),l(.548,1.154),l(.261,.902),l(3.362,.375),l(3.387,.446),l(.839,.108),l(.584,-.469),l(.152,-.057),l(.581,.914),l(.155,1.453),l(-5.346,2.982),l(-2.35,1.213),l(-1.691,.815),l(-.169,.085),l(-1.148,.346),l(-3.097,1.035),l(-4.618,1.566),l(-.484,.229),l(-.041,.127),l(-.383,.397),l(-1.907,2.271),l(-2.042,2.667),l(-1.302,-2.703),l(-1.211,-2.45),l(-.452,-.012),l(-.715,.047),l(-.446,-.125),l(-.671,-.151),l(-.216,.1),l(-.174,.185),l(-.11,.495),l(.041,.678),l(-.113,.565),l(-.692,.563),
+N(476.458,130.735),l(.124,.289),l(.796,1.944),l(.834,1.746),l(-.38,.381),l(-.479,1.145),l(-.334,1.413),l(-.171,.593),l(-.18,.156),l(-.407,-.07),l(-.448,-.521),l(-.782,-.676),l(-.386,-.494),l(-.338,-.988),l(-.521,-.45),l(-.289,-.621),l(-.17,-.479),l(-.198,-.353),l(-.466,.17),l(-.267,.523),l(.604,1.34),l(.131,.381),l(.634,.86),l(.933,1.042),l(.473,1.199),l(.526,.973),l(.277,.818),l(.391,.465),l(.912,1.735),l(1.072,1.904),l(.428,.705),l(.586,.549),l(.451,.352),l(.151,.183),l(-.241,.17),l(-.285,.1),l(-.043,.155),l(.238,1.087),l(.252,.467),l(.127,.238),l(.812,.591),l(.397,.168),l(.406,.521),l(.416,.38),l(.311,.56),l(-10.382,-.006),l(-2.138,-.001),l(-2.774,.002),l(-2.513,.015),l(-2.268,-.029),l(-1.664,.01),l(-1.241,.007),l(-1.614,-.019),l(-.914,.005),l(-.819,.089),l(-.011,-2.612),l(.021,-1.342),l(-.045,-2.81),l(.001,-.692),l(.008,-2.048),l(.016,-1.468),l(.019,-3.869),l(.015,-.988),l(-.042,-.367),l(-.388,-.916),l(-.185,-.945),l(.056,-.311),l(.322,-.553),l(.231,-.425),l(-.354,-1.283),l(.21,-.34),l(.369,-.228),l(.099,-.208),l(.337,.168),l(.553,-.015),l(.628,-.1),l(.786,-.001),l(1.513,.293),l(.587,.115),l(.779,.122),l(.721,.154),l(.348,.409),l(.4,0),l(.928,.083),l(.998,.394),l(.628,.069),l(.245,-.127),l(.72,-.538),l(.925,-.397),l(.837,-.186),l(.78,-.27),l(.375,-.072),l(.346,.056),l(.535,-.001),l(.723,.126),l(.202,.465),l(.596,.366),l(.518,-.156),l(.64,.267),l(.382,.027),l(.561,-.401),l(.241,.179),l(.277,.056),l(.674,.13),l(.338,-.062),l(.46,-.165),l(.51,-.308),
+N(580.625,132.873),l(.24,.43),l(.299,.05),l(.276,-.314),l(.134,-.513),l(.275,.066),l(.186,-.182),l(1.079,.199),l(.132,.612),l(.867,.264),l(.726,.595),l(.472,.215),l(.15,-.132),l(.454,.281),l(.657,.794),l(.158,-.166),l(.71,-.116),l(.289,.166),l(.178,.38),l(-.069,.281),l(1.451,.893),l(.333,-.248),l(.326,.017),l(-.175,.396),l(.014,.265),l(.935,.066),l(.365,-.066),l(.54,.496),l(.141,.463),l(.237,-.099),l(-.01,-.364),l(.685,.38),l(.271,-.083),l(.08,-.331),l(.407,0),l(.63,.281),l(.319,.364),l(.849,-.066),l(.341,.116),l(.339,-.281),l(.655,.159),l(.037,.022),l(-.318,.761),l(-.07,.876),l(.429,.827),l(-.311,.694),l(-.336,-.05),l(-.687,.132),l(-.271,-.083),l(-.357,.132),l(-.399,-.116),l(-.268,-.364),l(-.606,.297),l(-.847,-.364),l(-.721,-.148),l(-.379,.231),l(-.312,-.248),l(.034,-.331),l(-.313,-.066),l(-.584,.281),l(-.618,-.265),l(-.286,-.281),l(-.663,-.149),l(.101,-.446),l(-.142,-.231),l(-.643,-.066),l(-.494,-.298),l(-.582,.347),l(-.482,-.265),l(-.503,0),l(-.087,.215),l(-.15,.066),l(-.304,-.198),l(-.835,-.166),l(-.182,-.397),l(-.538,.066),l(-1.027,-.595),l(-.231,.166),l(-1.242,-.678),l(-.305,-.529),l(-.704,-.149),l(-.665,-.479),l(-.466,.083),l(-.63,-.38),l(-.039,-.248),l(.218,-.43),l(.309,-.397),l(-.04,-.396),l(.221,-.265),l(-.008,-.364),l(.281,-.116),l(1.07,-.909),
+N(374.125,167.166),l(-1.41,-.924),l(-.661,-.604),l(-.537,-.788),l(-.292,-.662),l(-.15,-.183),l(-.312,-.154),l(-.567,-.053),l(-.655,-.307),l(-.695,-.561),l(-.604,-.194),l(-.567,-.025),l(-1.209,.12),l(-1.821,.194),l(-.523,.417),l(.06,-.502),l(.563,-1.301),l(.188,-.819),l(.13,-1.13),l(-.162,-1.101),l(-.3,-.791),l(-.624,-.747),l(.267,-.283),l(.182,-.424),l(.067,-.975),l(-.065,-.537),l(-.174,-.353),l(-.808,-.817),l(-.297,-.112),l(-.393,.438),l(-.055,-.197),l(-.013,-.381),l(.08,-.689),l(.474,.013),l(5.055,.056),l(2.396,.014),l(.732,-.033),l(.212,.027),l(-.051,-1.102),l(-.164,-1.539),l(.01,-.707),l(.249,-.383),l(.575,-.427),l(.726,-.315),l(.809,-.287),l(.144,-.128),l(.099,-2.6),l(.07,-2.261),l(.047,-.509),l(.557,-.074),l(6.005,.022),l(.56,.011),l(.104,-.396),l(-.002,-.65),l(.03,-1.752),l(2.829,1.509),l(4.12,2.42),l(1.414,.91),l(-.523,.13),l(-3.231,.089),l(.049,.776),l(.908,7.962),l(.19,1.468),l(.178,1.736),l(.325,2.753),l(.202,2.386),l(.186,1.468),l(.724,.787),l(-.379,1.613),l(-6.457,.01),l(-1.953,.026),l(-.945,.344),l(-.387,.031),l(-.485,-.054),l(-.713,-.137),l(-.535,-.124),l(-.06,.212),l(.055,.296),l(-.107,.269),l(-.454,-.082),l(-.214,-.168),l(-.568,-.83),l(-.261,-.111),l(-.402,.073),l(-.252,.256),l(-.181,.552),l(-.018,.607),l(-.332,.284),
+N(476.114,191.139),l(-.563,.54),l(-.626,.314),l(-.367,.016),l(-.303,-.196),l(-.303,-.097),l(-.88,.132),l(-.881,.33),l(-.911,.048),l(-.942,-.234),l(-.495,-.011),l(-.464,.087),l(-.496,.229),l(-1.288,-1.32),l(-1.032,-.926),l(-.207,-.083),l(-.258,.157),l(-.436,.582),l(-.16,.1),l(-.684,-.631),l(-.384,-.012),l(-.529,.37),l(-.258,.242),l(-.352,.016),l(-.366,-.195),l(-.525,-.477),l(-.348,-.493),l(-.795,-.772),l(-.143,-.239),l(-.031,-.07),l(.083,-.679),l(-.157,-.352),l(-.558,-.477),l(-.814,-.165),l(-.367,-.224),l(-.285,-.436),l(-.059,-.72),l(-.206,-.366),l(-.207,-.168),l(-.717,-.434),l(-.558,-.378),l(-.445,-.351),l(-.173,-.395),l(.148,-.481),l(-.223,-.267),l(-.351,-.196),l(-.799,-.235),l(-.797,-.447),l(-.223,-.225),l(-.252,-.493),l(-.207,-.126),l(-.272,.001),l(-.802,.019),l(-.158,-.211),l(-.01,-.664),l(.416,-1.472),l(-.122,-.536),l(-.347,-.549),l(-1.342,-1.673),l(.15,-.425),l(-.026,-.367),l(-.266,-.465),l(-.444,-.407),l(-.155,-.295),l(-.137,-.522),l(-.221,-1.228),l(-.141,-.225),l(-.338,-.012),l(-.517,.088),l(-.219,-.352),l(.316,-.609),l(.542,-.596),l(.087,-.34),l(-.342,-.662),l(.053,-.24),l(.718,-.428),l(.149,-.212),l(-.131,-.677),l(.122,-.438),l(.583,-.809),l(.417,-1.245),l(.229,-.143),l(1.245,-.05),l(.839,.009),l(.04,-.283),l(-.031,-1.229),l(-.036,-1.002),l(.038,-.749),l(-.085,-2.5),l(.036,-.636),l(.016,-.946),l(.02,-1.045),l(.073,-1.13),l(.52,.011),l(1.561,.019),l(.088,-.17),l(-.033,-3.078),l(.021,-1.003),l(.819,-.089),l(.914,-.005),l(1.614,.019),l(1.241,-.007),l(1.664,-.01),l(2.268,.029),l(2.513,-.015),l(2.774,-.002),l(2.138,.001),l(10.382,.006),l(.229,.414),l(.499,1.115),l(.281,3.501),l(.319,1.637),l(.182,.211),l(.625,.394),l(.595,.366),l(.617,.507),l(.491,.197),l(.254,.223),l(-.238,.199),l(-.277,.327),l(-.306,.566),l(-.369,.242),l(-.511,.172),l(-.427,.116),l(-.153,.142),l(-.235,.496),l(-.348,.171),l(-.73,.033),l(-.204,.552),l(-.038,.452),l(-.202,.862),l(-.242,.722),l(-.541,1.302),l(-.068,.495),l(.092,.903),l(-.013,.679),l(-.001,.083),l(-.148,.947),l(-.398,1.231),l(-.214,1.061),l(-1.04,.331),l(-.414,.37),l(-.693,1.134),l(-.154,.34),l(-.191,1.088),l(-.141,1.074),l(-.197,.185),l(-.274,.044),l(-.431,-.096),l(-.259,.072),l(-.163,.114),l(-.187,1.103),l(-.115,.933),l(-.2,1.272),l(.039,.522),l(-.229,1.159),l(-.469,.299),l(-.288,-.012),l(-.928,-.122),l(-.321,.03),l(-.188,.806),l(-.054,.466),l(.094,.141),l(.479,.11),l(.734,.123),l(.334,.167),l(.805,.913),l(1.06,1.067),l(.751,1.464),l(.345,.732),l(.348,.421),l(.462,.28),l(.415,.097),l(.269,.309),l(.117,.988),l(-.034,.17),l(-.018,.141),l(-.079,-.028),l(-.464,.017),l(-1.009,.133),l(-.832,.005),l(-.671,-.052),l(-.291,.327),l(-.678,.795),
+N(518.402,163.079),l(-.282,.097),l(-.538,.27),l(-.656,.566),l(-.265,.297),l(-.166,.508),l(-.062,.41),l(-.41,.326),l(-1.418,.652),l(-2.27,.641),l(-1.285,.412),l(-.843,.312),l(-.356,.297),l(-.473,.622),l(-.436,.269),l(-.506,.114),l(-.593,-.069),l(-.521,.072),l(-.83,.439),l(-.65,.396),l(-.956,.397),l(-.752,.199),l(-1.16,.003),l(-.562,-.013),l(-.297,.128),l(-.386,.312),l(-.272,.297),l(-.45,.312),l(-.511,.241),l(-.389,.043),l(-.239,-.042),l(-.535,.411),l(-.839,.058),l(-.494,-.112),l(-.623,-.437),l(-.17,-.155),l(-.317,-.437),l(-.084,-.254),l(.18,-.721),l(-.081,-.635),l(-.312,-.507),l(-.341,-1.171),l(-.572,-1.919),l(-.072,-.438),l(.268,-.707),l(-.124,-.748),l(.692,-.563),l(.113,-.565),l(-.041,-.678),l(.11,-.495),l(.174,-.185),l(.216,-.1),l(.671,.151),l(.446,.125),l(.715,-.047),l(.452,.012),l(1.211,2.45),l(1.302,2.703),l(2.042,-2.667),l(1.907,-2.271),l(.383,-.397),l(.041,-.127),l(.484,-.229),l(4.618,-1.566),l(3.097,-1.035),l(1.148,-.346),l(.169,-.085),l(.092,.663),l(.226,.634),l(.604,.971),l(.933,1.364),l(.127,.253),l(-.006,.296),l(.483,.689),l(.241,.306),
+N(494.64,172.627),l(-.261,-.166),l(-.476,-.633),l(-.475,-.159),l(-.437,-.911),l(-1.267,-.792),l(-.277,-.594),l(-.673,-.673),l(-.594,-.119),l(-.871,-.554),l(-.555,.079),l(-.158,-.158),l(-.237,.04),l(-.277,-.198),l(-.356,.159),l(-.476,.079),l(-.277,-.436),l(-.158,.237),l(-.436,.198),l(-.792,.079),l(-.554,-.594),l(-.238,0),l(-.396,-.317),l(-.832,1.663),l(-.436,-.871),l(-.475,.079),l(-.277,.356),l(-.396,-.08),l(-.349,.041),l(.013,-.679),l(-.092,-.903),l(.068,-.495),l(.541,-1.302),l(.242,-.722),l(.202,-.862),l(.038,-.452),l(.204,-.552),l(.73,-.033),l(.348,-.171),l(.235,-.496),l(.153,-.142),l(.427,-.116),l(.511,-.172),l(.369,-.242),l(.306,-.566),l(.277,-.327),l(.238,-.199),l(.098,.129),l(.718,2.102),l(.442,1.623),l(.689,1.919),l(.618,.832),l(.205,-.212),l(-.072,-.479),l(.093,-.226),l(.31,.253),l(.4,.677),l(.384,.395),l(.534,-.043),l(.242,.014),l(1.338,1.282),l(.809,.916),l(.124,.099),l(.706,.055),l(.618,.874),l(.021,.24),l(-.025,.198),l(.118,.212),l(.507,.182),l(.915,.869),l(-.075,.094),l(-.529,.78),l(-.331,-.182),l(-.396,-.125),l(-.214,.114),l(-.055,.085),
+N(370.147,172.035),l(-2.301,-.043),l(-1.045,.006),l(-.505,.384),l(-.51,.187),l(-.74,-.024),l(-.819,.047),l(-.463,.139),l(-.009,-.003),l(-.278,-.226),l(-.169,-.409),l(.104,-.424),l(-.095,-.55),l(-.018,-.198),l(.001,-.046),l(1.695,.014),l(0,-.434),l(.155,0),l(.341,-.016),l(.186,-.077),l(.248,.062),l(.294,-.046),l(.124,-.093),l(.016,-.263),l(.077,-.078),l(.14,-.016),l(.155,.155),l(.232,.124),l(.356,.108),l(.046,.108),l(.139,.047),l(.217,-.031),l(.263,.108),l(.186,.17),l(.434,0),l(.186,-.108),l(.263,-.108),l(.279,0),l(.108,-.124),l(.016,-.124),l(-.155,-.217),l(-.202,-.077),l(-.201,.031),l(-.294,.093),l(-.108,.093),l(-.248,.062),l(-.279,-.186),l(-.031,-.186),l(-.186,-.108),l(-.17,-.015),l(-.186,.124),l(-.139,-.108),l(-.108,-.217),l(-.155,-.108),l(-.201,.031),l(-.17,-.062),l(-.387,.17),l(-.108,-.108),l(-.155,.046),l(-.202,.124),l(-.093,.294),l(-1.664,0),l(-.007,-.067),l(-.028,-.269),l(-.377,-.268),l(-.068,-.155),l(-.057,-.367),l(-.386,-.635),l(-.399,-.494),l(-.379,-.31),l(-.472,-.183),l(.54,-.34),l(.723,-.75),l(.588,-1.004),l(.334,-.82),l(.099,-.826),l(.523,-.417),l(1.821,-.194),l(1.209,-.12),l(.567,.025),l(.604,.194),l(.695,.561),l(.655,.307),l(.567,.053),l(.312,.154),l(.15,.183),l(.292,.662),l(.537,.788),l(.661,.604),l(1.41,.924),l(-.506,.399),l(-.057,.339),l(.251,1.1),l(.144,.663),l(.22,.479),l(.181,.197),l(.554,.322),l(.265,.337),l(.082,.833),l(-.004,.565),l(-.062,.142),l(-.146,-.042),l(-.963,.091),l(-.658,.074),l(-.725,-.081),l(-.503,-.209),l(-.795,-.32),l(-1.255,-.021),
+N(495.973,175.881),l(-.363,.807),l(.083,.409),l(.428,.732),l(.587,.844),l(.732,.801),l(.596,.547),l(.634,.321),l(.54,.209),l(4.26,1.443),l(1.447,.472),l(1.875,-.04),l(.236,.154),l(-4.087,4.205),l(-1.562,1.69),l(-.813,.909),l(-.8,.004),l(-1.693,-.046),l(-.626,.088),l(-.562,.215),l(-.388,.214),l(-.502,.497),l(-.294,.426),l(-.337,.115),l(-1.216,.078),l(-.305,.101),l(-.453,.511),l(-1.103,-.106),l(-.461,-.181),l(-.46,-.336),l(-.271,-.098),l(-.852,.358),l(-.675,.343),l(-.258,.199),l(-.71,.753),l(-.16,.114),l(-.847,-.094),l(-.67,-.193),l(-1.373,-.133),l(-.335,-.041),l(-2.353,-1.525),l(-.604,-.293),l(-.749,-.193),l(-1.054,-.149),l(-.319,-.069),l(.018,-.141),l(.034,-.17),l(-.117,-.988),l(-.269,-.309),l(-.415,-.097),l(-.462,-.28),l(-.348,-.421),l(-.345,-.732),l(-.751,-1.464),l(-1.06,-1.067),l(-.805,-.913),l(-.334,-.167),l(-.734,-.123),l(-.479,-.11),l(-.094,-.141),l(.054,-.466),l(.188,-.806),l(.321,-.03),l(.928,.122),l(.288,.012),l(.469,-.299),l(.229,-1.159),l(-.039,-.522),l(.2,-1.272),l(.115,-.933),l(.187,-1.103),l(.163,-.114),l(.259,-.072),l(.431,.096),l(.274,-.044),l(.197,-.185),l(.141,-1.074),l(.191,-1.088),l(.154,-.34),l(.693,-1.134),l(.414,-.37),l(1.04,-.331),l(.214,-1.061),l(.398,-1.231),l(.148,-.947),l(.001,-.083),l(.349,-.041),l(.396,.08),l(.277,-.356),l(.475,-.079),l(.436,.871),l(.832,-1.663),l(.396,.317),l(.238,0),l(.554,.594),l(.792,-.079),l(.436,-.198),l(.158,-.237),l(.277,.436),l(.476,-.079),l(.356,-.159),l(.277,.198),l(.237,-.04),l(.158,.158),l(.555,-.079),l(.871,.554),l(.594,.119),l(.673,.673),l(.277,.594),l(1.267,.792),l(.437,.911),l(.475,.159),l(.476,.633),l(.261,.166),l(-.594,.921),l(-.488,.61),l(-.105,.254),l(-.029,.396),l(.202,1.157),l(.5,-.074),l(.892,-.246),l(.4,.04),l(.556,.195),
+N(364.011,169.929),l(1.664,0),l(.093,-.294),l(.202,-.124),l(.155,-.046),l(.108,.108),l(.387,-.17),l(.17,.062),l(.201,-.031),l(.155,.108),l(.108,.217),l(.139,.108),l(.186,-.124),l(.17,.015),l(.186,.108),l(.031,.186),l(.279,.186),l(.248,-.062),l(.108,-.093),l(.294,-.093),l(.201,-.031),l(.202,.077),l(.155,.217),l(-.016,.124),l(-.108,.124),l(-.279,0),l(-.263,.108),l(-.186,.108),l(-.434,0),l(-.186,-.17),l(-.263,-.108),l(-.217,.031),l(-.139,-.047),l(-.046,-.108),l(-.356,-.108),l(-.232,-.124),l(-.155,-.155),l(-.14,.016),l(-.077,.078),l(-.016,.263),l(-.124,.093),l(-.294,.046),l(-.248,-.062),l(-.186,.077),l(-.341,.016),l(-.155,0),l(0,.434),l(-1.695,-.014),l(.019,-.477),l(.173,-.198),l(.434,-.058),l(.093,-.155),l(-.006,-.059),
+N(495.973,175.881),l(-.556,-.195),l(-.4,-.04),l(-.892,.246),l(-.5,.074),l(-.202,-1.157),l(.029,-.396),l(.105,-.254),l(.488,-.61),l(.594,-.921),l(.055,-.085),l(.214,-.114),l(.396,.125),l(.331,.182),l(.529,-.78),l(.075,-.094),l(.627,.596),l(.285,.465),l(.036,.282),l(-.118,.113),l(-.361,.185),l(-.438,.1),l(-.56,.312),l(-.566,.467),l(.253,.127),l(.645,-.058),l(.321,.013),l(.434,.124),l(-.114,.26),l(-.37,.468),l(-.34,.567),
+N(363.763,172.732),l(.463,-.139),l(.819,-.047),l(.74,.024),l(.51,-.187),l(.505,-.384),l(1.045,-.006),l(2.301,.043),l(-.111,.792),l(.115,.847),l(-.186,.312),l(-.333,.186),l(-.513,.031),l(-.401,.017),l(-.381,.186),l(-.789,.64),l(-.321,.372),l(-.047,-.126),l(-.192,0),l(-.501,-.14),l(-.165,-.254),l(.121,-.41),l(.33,-.438),l(.253,-.212),l(-.131,-.141),l(-.372,-.112),l(-.498,.015),l(-.415,.17),l(-.161,0),l(-.616,-.281),l(-.36,-.296),l(-.069,-.24),l(-.323,-.084),l(-.316,-.137),
+N(383.005,177.596),l(-.379,.397),l(-.264,.623),l(.214,.409),l(.695,.405),l(.197,.31),l(-.125,.283),l(-.332,.37),l(.309,.351),l(.648,.561),l(.051,.226),l(-.19,.143),l(-.304,-.012),l(-.548,-.223),l(-.304,.03),l(-.158,.199),l(-.03,.127),l(.296,.549),l(.179,.21),l(-.188,.354),l(-.602,.554),l(-.047,.099),l(-.339,-.224),l(-.337,-.097),l(-.143,.086),l(-.756,.922),l(-.321,-.026),l(-.404,-.322),l(-.277,-.323),l(.044,-.283),l(-.009,-.65),l(-.22,-.846),l(-.165,-.366),l(-.338,-.097),l(-.528,.046),l(-.367,.143),l(-.252,.242),l(-.193,.376),l(-.26,-.656),l(-.165,-1.369),l(-.252,-.761),l(-.475,-.619),l(-.456,-.421),l(-.42,-.224),l(-.466,-.04),l(-1.137,.148),l(-.594,-.039),l(-.238,.157),l(-.643,.866),l(-1.088,1.235),l(.051,-.392),l(-.312,-.55),l(-.764,-.775),l(-.122,-.649),l(-.84,-.366),l(-.908,-.563),l(-.277,-.296),l(.09,-.396),l(-.053,-.311),l(-.547,-.041),l(-.323,-.098),l(-.115,-.155),l(.059,-.311),l(-.038,-.1),l(.321,-.372),l(.789,-.64),l(.381,-.186),l(.401,-.017),l(.513,-.031),l(.333,-.186),l(.186,-.312),l(-.115,-.847),l(.111,-.792),l(1.255,.021),l(.795,.32),l(.503,.209),l(.725,.081),l(.658,-.074),l(.963,-.091),l(.146,.042),l(.113,.028),l(.18,.183),l(.882,.715),l(.536,.265),l(.252,-.256),l(.475,-.413),l(.338,.026),l(.356,.153),l(.565,.152),l(.43,-.243),l(.3,-.327),l(.684,-.428),l(.323,.055),l(.246,.281),l(.022,.339),l(.271,.832),l(.265,.451),l(.474,.478),l(.349,.718),l(.194,1.143),l(.559,.901),
+N(266.015,188.956),l(.103,.169),l(-.163,.326),l(-.592,.385),l(-1.74,.9),l(-.807,.23),l(-.557,.074),l(-.465,-.054),l(-.284,.115),l(-.232,1.117),l(-.348,.115),l(-.628,-.618),l(-.344,-.224),l(-1.149,.035),l(-.385,-.04),l(-.896,-.461),l(-.309,-.125),l(-.159,.029),l(-.041,.184),l(.616,.688),l(.391,.69),l(.302,1.524),l(.079,.55),l(.166,.239),l(.96,.051),l(.434,.125),l(.15,.253),l(-.265,.27),l(-.569,.272),l(-.652,.131),l(-.203,.199),l(-.259,.666),l(-.235,.213),l(-.652,.173),l(-.554,.286),l(-.74,.654),l(-.645,.739),l(-.271,.016),l(-.186,-.776),l(-.083,-.183),l(-.757,.697),l(-.414,.073),l(-.482,-.223),l(-.694,-.546),l(-.432,-.054),l(-.199,-.437),l(-.088,-.452),l(-.161,-.861),l(-.138,-.437),l(-.148,-.168),l(-.797,-1.182),l(-.51,-.491),l(.479,-.526),l(.731,-.612),l(-.121,-.282),l(-.486,-.647),l(-.256,-.437),l(-.447,-.789),l(-.162,-.804),l(-.048,-.367),l(-.035,-.438),l(-.026,-.254),l(.147,-.326),l(.379,-.511),l(.085,-1.004),l(.409,-.525),l(-.644,-.081),l(-1.99,.224),l(-.76,.174),l(-.522,.13),l(-.144,0),l(-.554,-.576),l(-.847,-.998),l(-.188,-.253),l(-.64,-.321),l(-.521,-.181),l(-1.167,.05),l(-1.163,.12),l(-.496,.017),l(-.397,-.252),l(-.429,-.548),l(-.401,-.309),l(-.099,-.353),l(.226,-1.132),l(-.103,-.395),l(-.855,-1.45),l(-.31,-.606),l(-.384,.017),l(-.234,.1),l(-.402,-.025),l(.709,-1.191),l(.241,-.722),l(.172,-.722),l(.99,-1.758),l(.381,-.059),l(.227,.027),l(.129,-.396),l(-.048,-.497),l(.056,-.288),l(.414,-.2),l(.534,-.156),l(.84,-.171),l(.128,.105),l(-.9,.151),l(-.731,.312),l(-.145,.212),l(.19,.607),l(.142,.407),l(.224,.126),l(-.043,.145),l(.153,.579),l(-.135,.367),l(-.327,.364),l(-.348,.824),l(-.137,.368),l(.253,.479),l(.288,.253),l(.25,.72),l(.341,.353),l(.523,-.114),l(.184,-.156),l(.419,-.255),l(.12,-.142),l(.066,-.523),l(-.167,-.649),l(-.21,-.282),l(-.438,-.804),l(-.136,-.135),l(-.118,-.395),l(-.247,-.18),l(.239,-.099),l(.095,-.251),l(-.204,-.144),l(1,-.379),l(1.085,-.327),l(.998,-.272),l(.086,-.225),l(.69,-.086),l(.143,-.008),l(-.042,-.157),l(-.055,-.198),l(-.125,-.036),l(-.039,-.108),l(-.128,-.072),l(-.226,.071),l(-.156,.027),l(-.229,-.012),l(-.315,-.55),l(.109,-.254),l(.337,-.213),l(.367,-.043),l(.09,.112),l(.14,.368),l(.186,.162),l(-.001,.148),l(.026,.193),l(.068,.09),l(.004,.198),l(.253,.258),l(.329,-.02),l(.699,.111),l(.455,.07),l(.593,.196),l(.323,.254),l(.393,.564),l(.156,.635),l(.358,.324),l(.359,.084),l(1.02,-.129),l(.928,-.059),l(.59,-.058),l(.799,-.059),l(.714,.125),l(.4,.479),l(.267,.169),l(.578,.253),l(.49,.14),l(1.094,.04),l(.382,-.057),l(.388,-.227),l(1.042,-.807),l(.47,-.185),l(.453,.042),l(.959,-.073),l(1.152,-.073),l(.919,.055),l(.248,.112),l(-.056,.141),l(-.294,.185),l(-.854,-.041),l(-.433,.015),l(-.083,.212),l(.059,.184),l(.593,.253),l(.609,.535),l(.195,.649),l(.246,-.523),l(.185,-.142),l(.415,.253),l(.483,.027),l(.374,.098),l(.258,.338),l(.918,.394),l(.464,.295),l(-.729,.496),l(-.161,.65),l(-.214,.226),l(-1.055,.417),l(.5,.064),l(.598,.098),l(.368,-.029),l(.33,-.142),l(.929,-.03),l(.725,.083),l(.84,.274),l(.095,.296),l(-.061,.41),l(-1.655,1.239),l(-.101,.255),l(.074,.212),l(.62,.604),l(.141,.282),l(-.308,.299),l(-.41,.144),l(-1.032,.19),l(-.061,.452),l(.008,.58),l(-.395,.539),l(-.071,.212),l(.324,.521),l(.732,.745),l(.503,.647),
+N(493.044,204.258),l(-1.223,-1.771),l(-.027,-.932),l(-.03,-1.43),l(-.042,-2.045),l(-.003,-1.017),l(0,-.438),l(.016,-.848),l(.004,-1.215),l(.002,-.508),l(1.649,-2.467),l(.453,-.511),l(.305,-.101),l(1.216,-.078),l(.337,-.115),l(.294,-.426),l(.502,-.497),l(.388,-.214),l(.562,-.215),l(.626,-.088),l(1.693,.046),l(.8,-.004),l(.813,-.909),l(1.562,-1.69),l(4.087,-4.205),l(-.236,-.154),l(-1.875,.04),l(-1.447,-.472),l(-4.26,-1.443),l(-.54,-.209),l(-.634,-.321),l(-.596,-.547),l(-.732,-.801),l(-.587,-.844),l(-.428,-.732),l(-.083,-.409),l(.363,-.807),l(.34,-.567),l(.37,-.468),l(.114,-.26),l(.154,.044),l(.935,1.142),l(.586,.62),l(.243,.381),l(.265,.211),l(.372,-.071),l(.417,-.001),l(.465,.027),l(.372,-.071),l(.572,-.27),l(.836,-.425),l(.585,-.157),l(.397,.098),l(.76,.267),l(.549,-.072),l(.56,-.326),l(.779,-.566),l(.247,-.127),l(.447,.041),l(.479,.098),l(.419,-.043),l(1.195,-.482),l(.288,.027),l(.682,.196),l(.74,-.03),l(.764,-.185),l(.964,-.327),l(.9,-.666),l(.47,-.382),l(.604,.154),l(.391,.211),l(.08,.014),l(.147,.268),l(-.414,.919),l(.021,.564),l(.132,.621),l(-.165,.452),l(-.375,.509),l(-.028,.678),l(-.047,.833),l(-.163,.509),l(-1.264,2.262),l(-.842,.792),l(-.122,.311),l(.102,.353),l(-.893,1.569),l(-.834,1.272),l(-.214,.947),l(-.351,.636),l(-.712,1.117),l(-.874,1.188),l(-1.159,1.498),l(-.384,.439),l(-2.274,2.504),l(-1.82,1.557),l(-2.164,1.121),l(-.593,.382),l(-1.28,1.09),l(-1.74,1.755),l(-.06,.061),l(-1.055,1.1),l(-1.235,1.569),l(-.615,.835),l(.1,.353),l(-.094,.276),
+N(264.768,176.039),l(-.128,.225),l(-.115,.067),l(-.029,.135),l(.039,.25),l(-.058,.086),l(.125,.376),l(-.039,.424),l(-.453,.154),l(-.135,-.01),l(-.144,.039),l(-.482,-.039),l(-.192,.039),l(-.087,-.048),l(-.356,0),l(-.02,-.058),l(.039,-.067),l(.202,-.029),l(.222,-.135),l(.019,-.087),l(.106,.02),l(.154,.01),l(.135,-.145),l(-.096,-.279),l(.048,-.125),l(.029,-.183),l(-.067,-.125),l(-.097,-.135),l(-.279,-.048),l(.116,-.096),l(.164,-.019),l(.231,-.029),l(.115,-.087),l(.385,.02),l(.106,-.039),l(.299,-.067),l(.244,.006),
+N(654.075,190.187),l(.206,-.125),l(.63,-.114),l(.656,-.938),l(.241,-.07),l(-.069,.268),l(.122,.087),l(.187,-.046),l(.11,.174),l(.148,.444),l(-.024,.111),l(-.013,.247),l(.197,.197),l(.025,.086),l(-1.234,.42),l(-.383,.271),l(-.309,-.271),l(-.111,-.259),l(-.234,.012),l(-.062,-.37),l(-.084,-.126),
+N(493.044,204.258),l(-.602,.389),l(-.557,.171),l(-.385,-.112),l(-.086,.777),l(-.282,.367),l(-.67,.115),l(-.394,.382),l(-.088,.48),l(.006,.353),l(-.356,.622),l(-.964,1.358),l(.092,.536),l(-.337,.65),l(-.25,.255),l(-.334,.1),l(-.084,.152),l(-1.067,-.807),l(-2.427,-1.752),l(-.07,-.239),l(.116,-.552),l(-.137,-.381),l(-3.553,-1.984),l(-4.663,-2.568),l(-1.448,.033),l(1.144,-2.479),l(.105,-.229),l(.656,-.835),l(.985,-.938),l(.477,-.525),l(.43,-.695),l(.143,-.566),l(-.048,-.664),l(-.223,-.606),l(-.224,-.352),l(-.732,-1.069),l(-.174,-.465),l(-.027,-.861),l(-.126,-.226),l(-.477,-.463),l(-.3,-.493),l(.678,-.795),l(.291,-.327),l(.671,.052),l(.832,-.005),l(1.009,-.133),l(.464,-.017),l(.079,.028),l(.319,.069),l(1.054,.149),l(.749,.193),l(.604,.293),l(2.353,1.525),l(.335,.041),l(1.373,.133),l(.67,.193),l(.847,.094),l(.16,-.114),l(.71,-.753),l(.258,-.199),l(.675,-.343),l(.852,-.358),l(.271,.098),l(.46,.336),l(.461,.181),l(1.103,.106),l(-1.649,2.467),l(-.002,.508),l(-.004,1.215),l(-.016,.848),l(0,.438),l(.003,1.017),l(.042,2.045),l(.03,1.43),l(.027,.932),l(1.223,1.771),
+N(466.196,203.275),l(.188,-.298),l(.076,-.27),l(-.057,-.748),l(.025,-.734),l(-.021,-.593),l(.107,-.507),l(.217,-1.02),l(.395,-.681),l(.255,-.284),l(1.241,-.996),l(1.195,-1.066),l(.191,-.453),l(-.111,-.31),l(-.271,-.182),l(-.479,-.04),l(-.191,-.027),l(-.128,-.253),l(.26,-1.88),l(.018,-.424),l(-.159,-.183),l(-.063,-.028),l(.496,-.229),l(.464,-.087),l(.495,.011),l(.942,.234),l(.911,-.048),l(.881,-.33),l(.88,-.132),l(.303,.097),l(.303,.196),l(.367,-.016),l(.626,-.314),l(.563,-.54),l(.3,.493),l(.477,.463),l(.126,.226),l(.027,.861),l(.174,.465),l(.732,1.069),l(.224,.352),l(.223,.606),l(.048,.664),l(-.143,.566),l(-.43,.695),l(-.477,.525),l(-.985,.938),l(-.656,.835),l(-.105,.229),l(-1.144,2.479),l(-4.659,0),l(-1.277,.05),l(-.319,.017),l(-.554,.398),l(-.458,.427),l(-.431,.045),l(-.546,-.223),l(-.064,-.042),
+N(713.621,206.298),l(.169,7.966),l(-.44,.822),l(.431,1.368),l(.046,.805),l(-.031,3.438),l(-.515,-.512),l(-.927,-.888),l(-.716,-.902),l(-.406,-.056),l(-.776,.101),l(-.739,.143),l(-.434,-.013),l(.091,-.382),l(.435,-.65),l(.006,-.283),l(-.561,-.521),l(-.565,-.775),l(.028,-.226),l(.442,.111),l(.236,-.042),l(.135,-.113),l(-.467,-.409),l(-.595,-.408),l(-.287,-.381),l(-.275,-.648),l(-1.053,-1.693),l(-.508,-.394),l(-.467,-.282),l(-.604,-.196),l(-1.983,-.603),l(-1.26,-.379),l(-.613,-.069),l(-.705,-.238),l(-.63,-.323),l(.072,-.34),l(-.098,-.268),l(-.193,-.028),l(-.617,.101),l(-.389,-.07),l(-.412,-.196),l(-.408,-.395),l(-.209,-.579),l(.133,-.494),l(-.155,-.226),l(-.187,.113),l(-.234,.396),l(-.122,.664),l(-.251,.608),l(-.334,.269),l(-.696,.354),l(-.155,-.169),l(-.331,-.677),l(.022,-.155),l(.384,-.27),l(-.152,-.424),l(-.173,-.239),l(-.564,-.395),l(-.707,-.394),l(-.338,-.056),l(-.059,-.212),l(.038,-.226),l(.413,-.044),l(.388,.084),l(.603,.239),l(.158,-.029),l(.368,-.34),l(.525,-.41),l(.146,.056),l(.3,.269),l(1.021,-.045),l(.139,-.128),l(.09,-.522),l(-.063,-.409),l(-.238,.028),l(-.345,.199),l(-.604,.071),l(-.656,-.041),l(-.766,.044),l(-1.026,-.082),l(-.411,-.31),l(-.135,-.197),l(-.148,-.664),l(-.202,-.338),l(-.42,-.155),l(-1.249,-.124),l(.265,-.297),l(.058,-.255),l(.004,-.593),l(.463,-.029),l(.92,-.411),l(.49,-.383),l(.444,-.283),l(.352,.027),l(.4,.069),l(1.494,.646),l(.515,.169),l(.913,.153),l(.382,.705),l(.138,.396),l(-.283,.749),l(-.067,.381),l(.221,.381),l(.115,.494),l(.115,.48),l(.215,.521),l(.186,.197),l(.197,.127),l(.226,-.65),l(.085,.113),l(.087,.141),l(.309,1.073),l(.169,.169),l(.234,.183),l(.294,.112),l(.354,.056),l(.58,-.198),l(.504,-.439),l(1.192,-1.853),l(.352,-.015),l(1.078,-.215),l(.378,-.142),l(.045,-.085),l(.014,-.509),l(.219,-.17),l(1.1,-.609),l(.335,-.043),l(1.732,.759),l(2.129,.941),l(1.54,.52),l(1.299,.404),M(691.208,208.707),l(-.388,-.069),l(-.693,-.38),l(-.852,-.647),l(-.295,-.141),l(-.414,.028),l(-.059,.1),l(.024,.452),l(-.206,.028),l(-1.014,-.407),l(-.258,-.353),l(-.582,.199),l(-.289,.269),l(-.326,.185),l(-.186,-.184),l(-.312,-.451),l(-.245,-.451),l(.246,-.198),l(.303,-.029),l(.274,.056),l(1.104,.04),l(.574,.31),l(.319,-.015),l(.544,-.326),l(.414,-.015),l(.534,.126),l(.857,.21),l(.499,.395),l(.293,.395),l(.179,.621),l(-.049,.254),M(682.045,208.699),l(-.419,-.056),l(-.715,-.493),l(-.232,-.451),l(.146,-.283),l(.603,-.1),l(.766,-.044),l(.246,.126),l(.256,.311),l(.313,.197),l(.108,.226),l(-.067,.226),l(-.125,.057),l(-.879,.285),M(707.635,219.095),l(-1.11,-.209),l(.589,-1.032),l(.56,-.708),l(.407,-.269),l(.427,-.072),l(.527,.338),l(.198,.24),l(-.11,.184),l(-.324,.637),l(-.256,.17),l(-.638,.693),l(-.27,.028),M(673.797,218.703),l(-.562,.257),l(.034,.233),l(-.886,.326),l(-.582,.274),l(-.339,-.041),l(-.453,.325),l(-.504,-.069),l(-.427,-.112),l(-.378,.255),l(-.3,.058),l(-.358,-.07),l(-.58,-.196),l(-1.046,-.04),l(-.316,.043),l(-.211,-.564),l(.027,-.24),l(.383,-.198),l(.672,-.199),l(.528,-.016),l(1.142,.407),l(.445,.324),l(.338,.013),l(.326,-.297),l(.464,-.016),l(.429,-.071),l(.414,.187),l(.467,-.116),l(-.072,-.222),l(.421,-.187),l(.404,-.233),l(.094,-.151),l(-.076,-.117),l(-.184,.023),l(.116,-.198),l(.16,.012),l(.22,.094),l(.177,.221),l(.013,.304),M(662.661,219.065),l(-.312,-.099),l(-.203,-.127),l(-.062,-.169),l(.03,-.212),l(.256,-.198),l(.315,-.036),l(.17,.092),l(.053,.212),l(.182,.098),l(.305,-.145),l(.34,.105),l(.104,.151),l(-.012,.451),l(.183,-.148),l(.163,-.304),l(.318,-.029),l(.229,.226),l(.021,.424),l(.181,-.036),l(.062,.104),l(-.025,.397),l(-.316,-.211),l(-.311,-.058),l(-.141,.058),l(.072,.155),l(-.852,.157),l(-.143,-.091),l(.097,-.268),l(-.085,-.059),l(-.308,.269),l(-.229,.256),l(-.296,-.046),l(-.63,.225),l(-.624,.199),l(-.357,-.051),l(-.31,.123),l(-.392,-.07),l(-.103,-.07),l(-.202,-.123),l(-.063,-.279),l(.143,-.261),l(-.08,-.253),l(.193,-.115),l(.23,-.113),l(.233,-.156),l(.224,.07),l(.61,.013),l(.4,.104),l(.089,.28),l(.291,.109),l(.294,.056),l(.189,-.259),l(.29,-.012),l(.051,-.187),l(-.263,-.15),M(656.294,219.602),l(-.393,-.282),l(-.855,-.449),l(-.118,-.269),l(.417,-.001),l(.514,-.185),l(.462,-.029),l(.925,.521),l(-.338,.17),l(-.232,.1),l(-.381,.425),M(631.053,200.125),l(-.061,.225),l(-.413,.439),l(-.204,.41),l(-.381,.354),l(.164,.353),l(.162,.169),l(.806,.493),l(.832,.055),l(.241,.112),l(.151,.381),l(.128,.763),l(-.007,.409),l(.267,.423),l(.212,.127),l(.544,.041),l(-.45,.933),l(.151,.212),l(.703,-.453),l(.824,.252),l(.177,.042),l(.265,.254),l(.144,.438),l(.698,.676),l(-.515,1.979),l(-.04,.452),l(.23,.946),l(-.021,.438),l(.021,.664),l(-.002,.268),l(-.149,1.06),l(-.087,.156),l(-.107,.07),l(-.367,-.253),l(-.381,-.522),l(-.261,-.084),l(-.262,.481),l(-.081,.268),l(-1.043,-.619),l(-.219,.086),l(.394,.747),l(-.163,.213),l(-.204,-.197),l(-1.343,-1.424),l(-.775,-.761),l(-1.011,-.859),l(-1.348,-.958),l(-.391,-.451),l(-.199,-.493),l(-.191,-.339),l(-1.003,-.633),l(-.697,-.677),l(-1.186,-1.509),l(-.074,-.353),l(.039,-.339),l(-.324,-.875),l(-.841,-1.467),l(-.667,-1.044),l(-.612,-.775),l(-.369,-.301),l(-.287,-.234),l(-.64,-.295),l(-.254,-.748),l(-.688,-1.806),l(.067,-.24),l(-.107,-.311),l(-.157,-.197),l(-.662,-.507),l(-.711,-.394),l(-.539,-.21),l(-.317,-.099),l(-.119,-.353),l(-.077,-.734),l(-.18,-.409),l(-.386,-.479),l(-.818,-.831),l(-.368,-.423),l(-.725,.128),l(-.613,-.676),l(-.646,-.606),l(-.593,-.69),l(-.562,-.945),l(-.229,-.635),l(-.032,-.367),l(.057,-.198),l(.149,-.113),l(.401,-.043),l(.364,.098),l(.25,.126),l(.632,.563),l(.361,.155),l(.922,.153),l(.335,.027),l(.548,-.1),l(.454,-.142),l(.4,-.015),l(.323,.31),l(.919,1.156),l(.513,.31),l(.058,.155),l(-.12,.537),l(1.066,.916),l(.749,.493),l(1.175,.689),l(.678,.323),l(.139,.169),l(.03,.593),l(-.02,.155),l(.573,.055),l(.745,.944),l(.612,.55),l(.271,-.015),l(.004,-.198),l(-.123,-.226),l(.069,-.24),l(.507,.21),l(.479,.804),l(.441,.38),l(.446,.056),l(.429,.197),l(.314,.366),l(.28,.734),l(.316,.437),l(.431,.268),l(.511,.126),l(.767,.083),l(.431,.154),l(.494,.38),l(.576,.606),l(-.019,.071),M(684.201,200.125),l(-.007,-.172),l(-.414,-1.058),l(.18,-.551),l(-.078,-.141),l(-.141,-.296),l(.036,-.325),l(.286,-.89),l(.514,-.82),l(.263,.367),l(.152,.353),l(-.054,.283),l(-.246,.396),l(-.361,.763),l(.061,.325),l(.19,.141),l(.097,-.141),l(.436,-.411),l(.135,-.522),l(.179,-.142),l(.806,-.412),l(.141,.141),l(-.052,.254),l(.104,.55),l(-.354,.212),l(-.467,.354),l(-.162,.311),l(.159,.099),l(.446,.126),l(.398,.211),l(-.016,.141),l(.159,.353),l(-.688,-.154),l(-.431,-.154),l(-.367,-.042),l(-.304,.156),l(-.08,.438),l(.049,.258),l(.131,.688),l(.341,.62),l(.405,.438),l(.196,.282),l(-.156,.212),l(-.26,-.211),l(-.664,-.648),l(-.55,-.733),l(-.002,-.396),l(-.011,-.251),M(637.361,207.144),l(-.863,-.394),l(-.377,-.239),l(-.205,-.367),l(-.045,-.367),l(-.156,-.395),l(-.507,-.395),l(-.291,-.099),l(-.446,.029),l(-.116,-.141),l(.271,-.65),l(.234,-.24),l(.509,.55),l(.148,-.467),l(.313,-.269),l(.072,.395),l(.312,.89),l(.648,.817),l(.698,.31),l(-.265,.184),l(-.118,.283),l(.183,.564),M(634.321,215.345),l(-.091,-.187),l(.316,-.023),l(.402,.093),l(.369,-.129),l(.068,-.524),l(.018,-.14),l(.309,.057),l(-.043,-.5),l(.222,-.235),l(.093,-.277),l(.202,.121),l(.631,.112),l(.474,-.047),l(.237,.443),l(.524,-.089),l(.158,-.297),l(.022,-.244),l(.259,.116),l(.618,.168),l(.411,.438),l(.338,-.046),l(.204,.271),l(.446,-.029),l(.453,-.185),l(.302,.211),l(.369,.522),l(.179,.521),l(.884,.041),l(.462,.188),l(.49,-.077),l(1.435,.124),l(.479,-.029),l(.34,-.17),l(.213,-.65),l(.271,-.269),l(.447,-.015),l(.223,.211),l(.289,.494),l(.633,.125),l(.53,.027),l(.774,.083),l(.796,.153),l(.289,.24),l(.293,.288),l(-.08,.445),l(.275,.466),l(.119,.099),l(.877,.352),l(.422,.069),l(.658,.013),l(.45,-.185),l(.415,-.015),l(.628,.238),l(.048,.197),l(-.255,.425),l(-.152,.494),l(.578,.776),l(-.499,-.211),l(-.802,-.196),l(-.599,-.253),l(-.891,-.309),l(-.528,.001),l(-.589,.256),l(-.348,.057),l(-.714,-.098),l(-1.454,-.138),l(-1.47,-.138),l(-.805,-.253),l(-.839,-.479),l(-1.099,-.336),l(-1.125,-.267),l(-.948,-.04),l(-.556,.298),l(-.445,.043),l(-.957,-.153),l(-.805,-.492),l(-.357,-.07),l(-1.606,-.066),l(-.363,-.155),l(.055,-.141),l(.448,-.468),l(-.402,-.267),l(-.551,-.099),l(-.506,-.14),l(-.307,-.027),l(-1.261,-.121),M(675.004,223.092),l(.249,-.494),l(.023,-.537),l(.113,-.312),l(.674,-.481),l(1.447,-.624),l(.662,-.454),l(.36,-.607),l(.466,-.157),l(1.578,-.102),l(.91,-.214),l(.541,-.044),l(.869,-.143),l(.118,.07),l(.099,.197),l(-.237,.212),l(-.36,.256),l(-1.609,.61),l(-1.369,.44),l(-.713,.256),l(-.606,.354),l(-1.09,.963),l(-.653,.481),l(-.439,.086),l(-.552,.228),l(-.48,.015),M(667.866,223.149),l(-.217,-.069),l(-.917,-.605),l(-.8,-.45),l(-.347,-.099),l(-.493,-.126),l(-.292,-.197),l(.108,-.212),l(.371,-.142),l(.992,-.03),l(.502,-.114),l(.35,.296),l(1.147,.746),l(.265,.381),l(-.125,.325),l(-.246,.24),l(-.299,.057),M(661.819,191.241),l(-.041,.09),l(.319,.691),l(-.23,.142),l(-.546,.043),l(-.579,.086),l(.198,.226),l(.115,.296),l(-.169,.226),l(.216,.211),l(.235,.112),l(.546,.832),l(.536,.747),l(.043,.198),l(-.338,.721),l(.075,.226),l(.406,.465),l(.743,.45),l(.6,.493),l(.551,.761),l(-.465,.17),l(-.75,-.026),l(-.797,-.238),l(-.337,.1),l(-.387,.467),l(-.354,.918),l(-.08,.476),l(-.046,.272),l(.132,.649),l(.116,.424),l(-.133,.848),l(-.256,0),l(-.466,-.154),l(-1.037,.963),l(-.433,.65),l(-.751,.608),l(.443,.381),l(.06,.396),l(.17,.296),l(-.685,.058),l(.452,.578),l(.009,.212),l(-.103,.227),l(-.547,.665),l(-.206,.396),l(-.127,.354),l(-.529,.594),l(-1.294,.61),l(-.607,.284),l(-.292,.198),l(-.194,-.311),l(.024,-.424),l(-.33,-.804),l(-.306,-.381),l(-.265,-.184),l(-.286,.029),l(-.503,.523),l(-.302,.029),l(-.328,-.508),l(-.313,-.197),l(-.437,-.112),l(-.387,-.451),l(-.342,-.154),l(-.35,.806),l(-.135,.198),l(-.381,.058),l(-.356,-.112),l(-.442,.128),l(-.318,.354),l(-.364,.071),l(-.059,-.551),l(.034,-.311),l(-.314,-1.03),l(-.336,.396),l(-1.42,.44),l(-.321,-.408),l(-.639,.015),l(-.281,.156),l(-.303,.029),l(-.058,-.649),l(-.022,-.65),l(-.267,-1.411),l(-.012,-.48),l(-.352,-.747),l(-.406,-.409),l(-.79,-.422),l(-.146,-.141),l(.555,-.354),l(-.531,-.38),l(-.258,-.296),l(.188,-.735),l(-.074,-.128),l(-.278,-.478),l(-.352,-.296),l(.065,-.466),l(-.125,-.593),l(.182,-.65),l(.133,-.353),l(.424,-.58),l(.303,-.806),l(.318,.028),l(.204,.11),l(.288,.792),l(.253,.295),l(1,.983),l(.304,.083),l(.446,.28),l(.928,-.416),l(.255,-.001),l(.526,.223),l(.543,.11),l(.399,-.172),l(.528,-.342),l(.403,-.525),l(.531,-.441),l(.479,-.074),l(.431,.11),l(.557,.251),l(.524,.223),l(.559,.152),l(.287,-.03),l(.467,-.356),l(.465,-.172),l(.864,-.175),l(.387,-.299),l(.928,-1.785),l(-.076,-.748),l(.218,-.34),l(.646,-.244),l(.22,-.383),l(-.106,-.988),l(.119,-.565),l(.381,-.638),l(.247,-.157),l(.464,-.017),l(.748,.081),l(.651,.081),l(.624,-.018),l(.446,.04),l(.753,.292),l(.182,.09),M(666.561,200.125),l(.012,-.049),l(.48,-1.188),l(.434,-.41),l(.289,-.142),l(.429,.338),l(.29,-.311),l(.162,-.325),l(.293,-.481),l(.496,-.058),l(.605,.14),l(.729,.535),l(.447,.027),l(.863,-.044),l(.478,.168),l(.749,.267),l(.577,-.227),l(1.853,.081),l(.72,-.128),l(.627,-.354),l(.211,-.283),l(-.156,-.268),l(.196,-.283),l(.388,-.241),l(.295,-.41),l(.289,-.057),l(.075,.24),l(-.073,.537),l(-.117,.311),l(-.081,.127),l(-.082,.127),l(-.969,1.259),l(-.416,.396),l(-.464,.1),l(-1.23,.229),l(-.495,-.069),l(-.591,-.422),l(-1.149,-.068),l(-1.151,.059),l(-.878,-.041),l(-1.039,.045),l(-.575,-.083),l(-.671,.029),l(-.415,.1),l(-.433,.368),l(-.259,.461),l(-.154,.274),l(-.187,.721),l(.068,.48),l(.263,.494),l(.194,.183),l(.403,.226),l(.259,.196),l(.221,.607),l(.179,.154),l(.226,.042),l(.815,.026),l(.249,-.269),l(.652,-.976),l(.385,.056),l(.307,.183),l(.496,.041),l(.363,-.227),l(.669,-.156),l(.62,-.143),l(.268,-.298),l(.271,-.057),l(.466,.196),l(.131,.212),l(-.083,.734),l(-.469,-.267),l(-.544,-.042),l(-.361,.298),l(-.389,.523),l(-.438,.425),l(-1.059,.439),l(-.214,.325),l(-.143,.029),l(-.241,-.042),l(-.468,-.126),l(-.03,.056),l(.025,.312),l(.212,.126),l(.676,.578),l(.467,.521),l(.854,1.24),l(-.097,.325),l(-.156,.679),l(.102,.409),l(.447,.535),l(.555,.438),l(.062,.226),l(-.045,.282),l(-.436,-.056),l(-.652,.059),l(-.412,.297),l(-.224,.692),l(-.498,-.026),l(-.461,-.183),l(-.107,-.17),l(.052,-.649),l(.204,-.58),l(-.978,-.845),l(-.417,-.31),l(-.174,-.269),l(.036,-.24),l(.284,-.396),l(.116,-.579),l(-.165,-.494),l(-.737,-.055),l(-.503,.213),l(-.494,.396),l(.16,.353),l(.143,.932),l(-.068,.509),l(-.236,1.145),l(.363,.903),l(-.01,.311),l(-.377,.636),l(-.019,.227),l(.275,.564),l(-.726,.171),l(-.513,.241),l(-.476,.071),l(-.245,-.324),l(-.16,-.522),l(.156,-.325),l(.181,-.466),l(.069,-.876),l(.06,-1.073),l(-.125,-.509),l(.029,-.339),l(-.213,-.395),l(-.311,-.127),l(-.391,.171),l(-.574,.029),l(.011,-.41),l(-.25,-1.284),l(.131,-.311),l(.491,-.524),l(.469,-.777),l(.161,-.48),l(-.089,-.918),l(-.006,-.254),l(.087,-.452),l(.339,-.721),l(.447,-.058),l(-.043,-.861),l(.254,-1.053),
+N(341.05,41.069),l(2.084,.272),l(.344,.361),l(-.869,.174),l(-.541,.139),l(-1.678,.106),l(-1.159,.037),l(-.689,.156),l(-.372,.224),l(-.308,.6),l(-.361,.376),l(1.05,.39),l(.971,.168),l(2.117,.064),l(.601,-.001),l(1.775,-.242),l(1.93,-.038),l(.866,.135),l(.933,.219),l(.417,.135),l(.284,-.018),l(1.001,-.002),l(1.277,.032),l(.615,.05),l(-1.277,.626),l(-1.583,.457),l(-1.976,.523),l(-.556,-.016),l(-.695,-.116),l(-.951,.671),l(-1.061,.503),l(-1.246,.452),l(-1.125,.296),l(-.211,.056),l(-2.212,.054),l(-.525,.134),l(-.502,.001),l(-.982,.201),l(-.665,.167),l(-.528,.051),l(-.946,-.413),l(-.375,.05),l(-.69,.913),l(-.958,.118),l(-.631,-.065),l(-.743,-.197),l(-.622,-.463),l(-.854,-.43),l(-.647,-.215),l(-.109,0),l(.008,.2),l(.707,1.043),l(-.192,.249),l(-.319,.017),l(-.69,.249),l(-.84,.249),l(-.573,.38),l(-1,.906),l(-.657,.657),l(-1.051,.851),l(-.776,.262),l(-1.034,.083),l(-1.023,-.275),l(-.148,.554),l(-.438,.569),l(-.783,.277),l(-.992,-.095),l(-.616,.05),l(-1.18,.439),l(.942,-1.723),l(-.121,.017),l(-.795,-.015),l(-1.055,-.177),l(.26,.423),l(-.026,.455),l(-.386,.407),l(-.794,.39),l(-1.16,.164),l(-.973,.002),l(-1.255,.083),l(.467,.403),l(.212,.403),l(-.09,.387),l(-.379,.097),l(-.321,-.063),l(-.47,.033),l(-1.792,-.157),l(.517,.32),l(.765,.462),l(.295,.351),l(-.01,.224),l(-.26,.176),l(-1.197,.034),l(-1.051,.129),l(.844,.413),l(.47,.126),l(.448,.222),l(.389,.333),l(-.554,.461),l(-.285,.111),l(-.599,-.094),l(-.478,.096),l(.345,.474),l(-.009,.127),L(308.501,60),l(-.486,-.125),l(-.583,-.062),l(.026,.158),l(.255,.457),l(-.101,.347),l(-.288,0),l(-.656,-.093),l(-.089,-.016),l(-.979,.112),l(-1.081,.018),l(.682,.487),l(1.108,.391),l(.331,.204),l(-.077,1.035),l(-.382,.938),l(-.427,.094),l(-.815,-.061),l(.489,.591),l(-.016,.498),l(.156,.233),l(-.068,.373),l(-.316,.062),l(-.495,-.03),l(-.771,.079),l(.762,.386),l(.427,.603),l(-.117,.447),l(-.287,.031),l(-.967,-.26),l(-1.052,-.508),l(-.498,.294),l(-.425,.602),l(-.635,-.599),l(.158,-.573),l(-.387,-.201),l(-1.124,-.184),l(-.577,-.309),l(.04,-.187),l(.253,-.249),l(.066,-.218),l(-.325,-.28),l(-.366,-.186),l(-.668,.359),l(-.276,.016),l(-.3,.141),l(-.444,-.046),l(-.98,.064),l(-.417,.017),l(-.571,.296),l(-.476,.28),l(-.426,-.403),l(-.104,-.357),l(-.222,-.217),l(-.513,-.233),l(-.817,-.232),l(-.772,-.389),l(-.517,-.781),l(.07,-.737),l(-.199,-.156),l(-.434,-.094),l(-.467,.048),l(-.97,-.266),l(-.108,-.094),l(-.138,-.236),l(.14,-.457),l(.459,-.395),l(.071,-.269),l(-.258,-.062),l(-.551,-.031),l(-.542,-.094),l(-.278,-.221),l(-.058,-.633),l(-.458,-.126),l(-.616,.049),l(-.589,-.57),l(.023,-.191),l(.198,-.254),l(.618,-.367),l(1.22,-.337),l(.405,-.304),l(.476,-.128),l(.051,-.383),l(-.277,-.287),l(-.473,.097),l(-.921,.082),l(-.493,.097),l(-.635,.416),l(-.538,.129),l(-.63,.304),l(-.339,-.318),l(.038,-.623),l(-.114,-.784),l(-.206,-.451),l(.015,-.355),l(-.243,-.323),l(-.504,.082),l(-.271,-.032),l(-.666,-.355),l(-.594,-.485),l(-.013,-.357),l(.842,-.538),l(.265,.019),l(-.556,-.189),l(-1.083,.064),l(-.103,-.284),l(.383,-.176),l(.677,-.03),l(.586,-.052),l(.456,-.087),l(.322,-.672),l(-1.208,-.047),l(-.572,.05),l(-.362,-.032),l(-.29,-.163),l(-.116,-.197),l(.223,-.28),l(.218,-.008),l(.18,-.16),l(.427,-.055),l(-.375,-.188),l(-.552,.073),l(-.22,-.248),l(.057,-.188),l(.073,-.132),l(.259,0),l(.309,-.099),l(.827,-.25),l(1.218,.081),l(.854,.163),l(.776,.032),l(.378,.131),l(.927,.146),l(1.027,.097),l(-.031,-.363),l(.299,-.545),l(-.298,-.182),l(-1.02,-.263),l(-1.356,-.312),l(-.903,-.164),l(-1.592,-.33),l(-.354,-.116),l(.336,-.35),l(.788,-.001),l(1.462,.363),l(1.034,.048),l(.463,-.067),l(.114,-.067),l(.088,-.6),l(.088,-.301),l(.595,-.034),l(.528,.116),l(.227,-.101),l(-.027,-.351),l(-.195,-.184),l(-.891,-.317),l(.162,-.437),l(.528,-.455),l(-.258,-.286),l(-1.21,-.167),l(-1.154,.002),l(-1.178,-.286),l(-1.649,-.49),l(-.78,-.101),l(-.903,-.05),l(-.76,-.34),l(-.811,-.477),l(.156,-.035),l(.323,-.155),l(.605,-.001),l(.572,-.019),l(2.085,.305),l(.716,.033),l(1.249,.306),l(1.451,.458),l(.729,.169),l(.056,-.307),l(-.311,-.426),l(-.86,-.546),l(-.172,-.446),l(-.603,-.446),l(-.485,-.051),l(-.677,-.24),l(.361,-.277),l(.542,-.139),L(285.644,41),l(-.704,-.241),l(-1.101,-.015),l(-.625,-.086),l(-1.132,-.327),l(-.88,.608),l(-.324,.156),l(-.274,.294),l(-.875,.243),l(-1.402,-.066),l(-1.031,-.343),l(-.306,-.242),l(-.027,-.294),l(.438,-.313),l(.293,-.645),l(-.152,-1.259),l(.582,-.054),l(.691,.192),l(.372,-.124),l(.151,-.334),l(-.383,-.369),l(-.933,-.545),l(-.452,-.141),l(-.946,-.796),l(-.895,-.925),l(-1.105,-1.289),l(-.578,-.485),l(-1.855,-.379),l(-.667,-.255),l(-.291,-.202),l(-.052,-.701),l(-.904,-.406),l(-.962,-.109),l(-1.589,-.165),l(-1.928,-.425),l(-1.903,-.333),l(-2.133,-.183),l(-.997,-.054),l(-1.632,-.035),l(-.785,.189),l(-1.043,.096),l(-.806,.188),l(-1.419,.152),l(-1.228,-.166),l(-1.46,-.296),l(.319,.747),l(-.051,.093),l(-1.051,-.017),l(-1.294,-.184),l(-3.168,-.611),l(1.538,-.566),l(.463,-.114),l(-.092,-.226),l(-.423,-.169),l(-1.067,-.017),l(-2.21,-.015),l(-.812,-.074),l(-.629,-.018),l(-1.238,-.434),l(-.87,-.208),l(.587,-.306),l(1.257,-.041),l(3.036,.147),l(2.025,.034),l(1.343,.017),l(2.117,-.157),l(1.055,-.212),l(.292,-.096),l(.054,-.345),l(-.627,-.287),l(-.82,-.21),l(-1.217,.156),l(-1.11,.252),l(-1.31,.021),l(-1.138,-.113),l(-.753,.078),l(-.879,.098),l(-.68,-.056),l(-.857,-.19),l(-.664,-.365),l(-.816,-.191),l(-.662,-.057),l(-.726,.059),l(-.486,-.076),l(-1.416,-.481),l(-.044,-.35),l(.36,-.45),l(.81,-.119),l(1.235,-.1),l(1.517,-.14),l(2.074,-.161),l(1.29,-.081),l(.951,-.396),l(1.089,-.259),l(.843,-.081),l(2.478,-.005),l(1.101,-.101),l(1.942,.036),l(.402,-.139),l(.31,-.199),l(.609,-.16),l(.202,-.658),l(.276,-.501),l(.116,-.101),l(-.89,-.228),l(-1.947,-.039),l(-1.155,.194),l(-.959,-.125),l(-1.243,-.383),l(.595,-.781),l(1.38,-.332),l(2.845,-.359),l(1.407,-.225),l(1.962,-.249),l(2.112,-.162),l(1.163,.087),l(1.213,-.07),l(1.319,-.07),l(.345,-.181),l(.011,-.226),l(-.357,-.753),l(-.022,-.208),l(.522,-.14),l(1.886,-.05),l(1.526,.205),l(2.141,.41),l(1.296,.226),l(.802,.181),l(.823,-.275),l(-1.657,-.525),l(-.697,-.509),l(.167,-.047),l(2.2,-.122),l(1.166,-.12),l(1.854,-.216),l(2.52,-.195),l(.73,.069),l(1.064,.116),l(.232,1.738),l(.913,-.162),l(.539,-.322),l(.432,-1),l(1.003,.021),l(2.004,.323),l(1.858,.414),l(1.529,.25),l(.205,-.3),l(-.644,-.3),l(-.816,-.537),l(-.894,-.4),l(.295,-.287),l(.742,.022),l(1.758,.02),l(1.136,.212),l(2.754,.373),l(1.284,.279),l(2.109,.322),l(1.878,.274),l(1.872,.204),l(.8,-.209),l(.816,-1.483),l(-.326,-.191),l(-1.292,-.334),l(-1.176,-.533),l(.708,-.247),l(2.404,-.005),l(2.962,-.328),l(1.329,-.077),l(1.527,.17),l(2.221,.488),l(1.567,.167),l(2.005,.142),l(.3,-.761),l(-.3,-.472),l(2.646,-.206),l(2.021,-.08),l(2.589,.095),l(1.989,.146),l(1.886,-.18),l(2.367,-.207),l(2.043,-.005),l(1.859,.223),l(1.825,-.055),l(1.315,.072),l(.619,.099),l(.55,-.102),l(1.946,.146),l(1.707,.046),l(1.673,.096),l(2.438,.761),l(1.368,.241),l(1.345,-.076),l(1.118,.168),l(2.594,.237),l(.445,.408),l(-.304,.12),l(-.492,.192),l(-1.683,.146),l(-2.303,.124),l(-1.152,.121),l(-1.233,.05),l(-1.469,-.068),l(-2.831,-.064),l(-2.22,-.066),l(-1.389,.168),l(-1.614,.027),l(-1.933,.027),l(-1.16,.026),l(-1.485,.168),l(-.444,.118),l(-1.322,.213),l(-.335,.464),l(.743,.251),l(2.551,-.281),l(1.367,-.072),l(3.912,.038),l(2.223,-.12),l(2.331,-.005),l(.997,-.025),l(.93,.067),l(1.77,.434),l(.671,.09),l(1.087,-.186),l(1.663,-.21),l(1.536,-.281),l(1.964,-.144),l(.59,.462),l(-.566,.482),l(-2.316,.639),l(-.973,.338),l(-1.281,.734),l(.12,.307),l(.319,.152),l(.796,-.089),l(.477,-.044),l(1.616,-.553),l(1.766,-.537),l(1.413,-.385),l(1.706,-.32),l(.775,-.207),l(1.662,-.163),l(1.618,.111),l(1.391,.065),l(1.497,-.3),l(.703,-.324),l(1.129,-.234),l(2.148,-.004),l(1.672,.112),l(1.097,.044),l(1.197,.136),l(1.135,.228),l(1.107,.112),l(.316,.25),l(-.181,.273),l(-1.97,.252),l(-1.491,.138),l(-1.245,.494),l(-.557,.289),l(-1.604,.355),l(-1.57,.548),l(-1.063,.089),l(-.918,-.042),l(-1.592,.047),l(-2.213,-.039),l(-1.491,.198),l(-.731,.217),l(-.495,.535),l(.166,.322),l(1.949,-.305),l(1.581,-.046),l(1.856,.101),l(.003,.42),l(-.743,.241),l(-2.388,.124),l(-.463,.14),l(-.213,.199),l(-.156,.595),l(-.471,.71),l(-.678,.158),l(-1.06,-.077),l(-.742,.041),l(-.837,.9),l(-.987,1.087),l(-.15,.347),l(.454,.307),l(.403,.095),l(.602,-.481),l(.743,-.368),l(.856,-.041),l(2.345,.266),l(.353,.096),l(.262,.288),l(-.059,.211),l(-1.234,-.074),l(-.673,-.018),l(-.512,.097),l(-.136,.191),l(.29,.286),l(1.756,.188),l(.557,.132),l(1.802,-.137),l(.526,.208),l(.214,.323),l(-.049,.436),l(-.256,.133),l(-1.835,-.186),l(-1.653,-.054),l(-.781,-.074),l(-1.295,.078),l(-1.382,.475),l(-.823,-.13),l(-.49,-.15),l(-1.06,.04),l(-.283,.377),l(1.393,.599),l(1.187,.222),l(1.298,.128),l(1.665,.072),l(.696,.148),l(.551,.482),l(.272,.444),l(.014,.554),l(-.434,.405),l(-.384,.074),l(-1.292,-.181),l(-.82,-.109),l(-.372,.111),l(.023,.55),l(.118,.236),l(.426,.162),l(.618,.089),l(.723,.215),l(.914,.142),l(.752,.16),l(.383,.376),l(-.338,.233),l(-.832,.145),l(-.647,.126),l(-1.747,-.032),l(-1.176,-.087),l(-1.624,-.086),l(-.592,.448),l(.551,.195),l(1.396,.051),l(1.052,.158),l(.724,.248),l(.088,.319),l(-.035,.549),l(-.13,-.005),l(-1.092,-.045),l(-1.247,.108),l(-.596,.266),l(-1.246,.02),l(-1.225,-.139),l(-1.497,-.404),l(-.922,-.478),l(-.373,-.07),l(-1.094,.286),L(345,36.811),l(-1.084,.09),l(-.589,.178),l(-1.451,-.033),l(-.913,-.087),l(-.969,.143),l(-.395,.125),l(-.174,.283),l(.006,.141),l(.354,.527),l(.71,.245),l(1.284,.05),l(1.515,.26),l(1.567,-.056),l(1.323,.54),l(.758,.226),l(.482,.226),l(1.196,.329),l(1.252,.38),l(.376,.276),l(.483,.898),l(.892,-.208),l(.278,-.139),l(.397,.207),l(.298,.43),l(.071,.344),l(.198,1.164),l(-.169,.205),l(-.371,.12),l(-.541,-.101),l(-.546,-.119),l(-.917,.002),l(-1.041,.036),l(-1.488,-.27),l(-.637,-.409),l(-.415,-.634),l(-.354,-.274),l(-1.17,-.566),l(-.84,-.292),l(-.748,-.137),l(-1.095,-.084),l(-.521,.14),l(-.962,.105),M(351.365,40.026),l(-1.527,-.537),l(-.96,-.225),l(-.712,-.156),l(-.159,-.069),l(-.314,-.419),l(1.483,-.038),l(.893,.139),l(1.064,.26),l(.819,.296),l(.162,.488),l(-.215,.209),l(-.533,.053),M(281.574,46.135),l(-.568,-.133),l(-.707,-.318),l(-.801,-.183),l(-.197,-.101),l(-.25,-.218),l(-.08,-.844),l(.287,-.34),l(.368,-.018),l(.646,.135),l(1.157,.066),l(1.287,.27),l(.748,.269),l(.595,.1),l(.777,.217),l(.603,.335),l(-.144,.202),l(-.112,.034),l(-.543,.051),l(-.774,.035),l(-.77,.186),l(-1.009,.153),l(-.511,.102),
+N(105.98,81.688),l(-.952,-.826),l(-.198,-.342),l(-.024,-.476),l(.095,-.104),l(.408,.044),l(.312,-.045),l(.781,.177),l(.658,-.076),l(.28,.119),l(.138,.163),l(-.234,.224),l(-.173,.565),l(-.028,.312),l(-.581,.075),l(-.483,.19),M(125.24,92.375),l(-1.312,-.288),l(-1.345,-.434),l(-.218,-.174),l(.061,-.189),l(.376,-.466),l(-1.023,.002),l(-.413,.248),l(-.299,-.072),l(-.416,-.188),l(.166,-.452),l(-.487,-.334),l(-.269,-.014),l(-.735,-.086),l(-.226,-.262),l(.317,-.292),l(-.976,-.524),l(-.556,.118),l(-.386,-.102),l(-.852,-.511),l(-1.277,-.863),l(-.219,-.235),l(.02,-.117),l(.962,-.12),l(.337,.043),l(1.979,.598),l(.981,.204),l(1.772,.202),l(.385,.263),l(.618,.526),l(.426,.642),l(.433,.422),l(.362,.189),l(1.587,.536),l(.316,.203),l(.48,.756),l(.116,.407),l(-.279,.349),l(-.407,.016),M(271.379,92.089),l(-1.202,-.23),l(.641,-.743),l(.358,-.161),l(.279,.058),l(.292,0),l(.355,-.263),l(-.697,-.653),l(.079,-.219),L(272,89.003),l(1.121,-1.35),l(1.454,-1.31),l(.725,-.442),l(.496,-.192),l(1.315,-.194),l(.198,.073),l(.11,.221),l(-.299,.221),l(-.582,.03),l(-.242,.133),l(.349,.44),l(-.755,.78),l(-1.226,1.438),l(-.271,.526),l(.113,.291),l(.11,0),l(.428,-.176),l(.483,-.555),l(.458,-.191),l(1.115,.305),l(-.896,.687),l(.261,.203),l(.229,.072),l(1.423,.565),l(.758,-.03),l(.325,-.408),l(.309,-.059),l(.718,.057),l(.826,.202),l(.616,.231),l(-.297,.292),l(-.373,.233),l(-.708,.467),l(.339,.333),l(.477,.362),l(.26,.014),l(.417,-.161),l(.464,-.132),l(.278,.116),l(.02,.16),l(-.254,.262),l(-.404,.248),l(-.892,.104),L(280.84,93),l(.273,.362),l(.124,.405),l(.28,.231),l(.183,-.203),l(.309,-.262),l(.527,.159),l(-.099,.449),l(.149,.275),l(.716,.028),l(.085,-.015),l(.015,.203),l(-.168,.304),l(-.25,.652),l(-.34,.651),l(-.222,-.072),l(-.71,-.128),l(-.301,-.144),l(-.042,-.651),l(-.601,.406),l(-.374,.015),l(-.095,-.274),l(.497,-.652),l(.011,-.333),l(-.421,-.478),l(-.279,-.072),l(-.388,.392),l(-.423,.291),l(-.365,.146),l(-.435,.204),l(-.552,.536),l(-.496,.334),l(-.881,-.042),l(-.222,-.217),l(.165,-.145),l(1.229,-.408),l(.466,-.522),l(.632,-.363),l(-.699,-.129),l(-.601,-.057),l(-.322,.464),l(-.412,.015),l(-.13,-.159),l(.04,-.493),l(-.757,.016),l(-.148,.29),l(-.41,.218),l(-1.052,.045),l(-.709,-.057),l(-1.139,-.186),l(-1.012,-.085),l(-1.355,.061),l(-1.014,.147),l(-.145,-.188),l(-.215,-.463),l(.187,-.175),l(.561,-.334),l(.734,-.408),l(.502,-.161),l(.636,-.335),M(265.435,98.655),l(-.469,-.057),l(-.497,-.273),l(-.356,-.562),l(.062,-.635),l(.742,-.738),l(.932,-1.043),l(.816,.432),l(-.375,.435),l(-.112,.462),l(-.233,.333),l(-.262,.116),l(-.58,.319),l(-.244,.448),l(.522,.244),l(.168,-.029),l(.279,-.26),l(.42,-.362),l(.617,-.319),l(.309,.057),l(.495,.461),l(-.177,.347),l(-.246,.159),l(-1.134,.42),l(-.682,.044),M(211.34,59.677),l(-.68,-.046),l(.068,-.872),l(-.375,-.333),l(-.958,.161),l(-2.375,.29),l(.107,-.461),l(.56,-.303),l(1.644,-.561),l(-.302,-.478),l(-.102,-.415),l(.106,-.417),l(.398,-.835),l(.434,-.566),l(.254,-.648),l(.331,-.471),l(1.11,.566),l(-.312,.518),l(.791,.386),l(.527,.047),l(.402,-.469),l(.67,.112),l(.806,.289),l(.917,.514),l(.582,.255),l(2.168,.492),l(.442,.271),l(.176,.255),l(-.09,.925),l(.539,.047),l(.57,-.065),l(.934,.046),l(.701,.142),l(1.019,.427),l(-.419,.096),l(-.269,.127),l(-.46,.271),l(-.949,-.046),l(-.623,-.125),l(-1.328,-.125),l(-.438,-.126),L(217.259,58),l(-.528,-.301),l(-1.017,-.237),l(-.528,.017),l(-.203,.271),l(.174,.588),l(-.126,.096),l(-1.314,.161),l(-.673,.493),l(-.588,.302),l(-1.116,.287),M(200.125,19.1),l(-.862,-.015),l(-1.085,-.195),l(-.308,-.664),l(.819,-.304),l(.77,-.072),l(.666,-.024),l(3.475,-.125),l(1.263,-.12),l(1.374,-.026),l(1.714,.324),l(.397,-.094),l(.397,-.377),l(1.303,-.287),l(1.759,-.099),l(1.975,.209),l(.746,-.001),l(2.562,.137),l(2.621,.324),l(1.424,.09),l(1.461,.161),l(.448,-.165),l(-1.433,-.42),l(-1.67,-.352),l(-.816,-.429),l(.293,-.242),l(1.361,-.148),l(1.101,-.246),l(1.431,-.101),l(2.382,-.201),l(1.666,.119),l(1.944,.191),l(1.009,.265),l(1.19,.456),l(.354,.047),l(.273,-.362),l(-.959,-.508),l(-.828,-.292),l(.499,-.248),l(1.45,.121),l(1.832,.168),l(1.653,.07),l(1.639,.46),l(.378,.023),l(.062,-.195),l(-.301,-.539),l(1.781,-.004),l(1.408,.046),l(.832,.269),l(.831,.34),l(.618,-.001),l(-.044,-.268),l(-.331,-.467),l(1.075,-.077),l(3.691,.386),l(2.726,.288),l(1.937,-.077),l(2.987,.018),l(.967,.047),l(.757,.12),l(.126,0),l(1.419,.094),l(1.089,.191),l(.744,.095),l(1.685,.044),l(1.357,.357),l(-.385,.358),l(-1.237,.121),l(-1.206,.356),l(-1.849,.191),l(-.978,-.045),l(-2.191,-.159),l(-2.284,.005),l(-.776,.142),l(-1.915,.168),l(-.597,.465),l(.75,.366),l(.761,.044),l(1.03,-.048),l(1.705,-.279),l(.79,.021),l(.808,.434),l(-.168,.114),l(-1.246,.139),l(-1.38,.207),l(-1.174,.295),l(-2.098,.518),l(-1.316,.224),l(-1.19,.355),l(-.924,.286),l(-2.252,.005),l(.65,.906),l(-.449,.193),l(-2.297,.455),l(-.768,-.019),l(-1.587,-.037),l(-1.462,-.218),l(-2.386,-.164),l(-.66,.33),l(2.591,.695),l(-.662,.141),l(-.967,-.038),l(-1.297,.022),l(-1.068,.022),l(-2.58,-.214),l(-2.009,.063),l(-.134,.66),l(1.257,-.105),l(1.065,.018),l(2.312,.292),l(.557,.157),l(.12,.67),l(-.33,.197),l(-1.031,.12),l(-.515,.705),l(-1.073,.021),l(-.448,-.058),l(-.402,.176),l(.297,.253),l(.759,.25),l(-.328,.136),l(-1.615,.08),l(-.867,-.037),l(-1.71,-.171),l(-.422,.078),l(.41,.791),l(-.08,.231),l(-.649,.289),l(-.767,.155),l(-1.52,-.112),l(-2.039,-.111),l(-1.43,-.227),l(-1.008,.079),l(-1.219,.5),l(1.031,.112),l(.368,.057),l(2.154,.11),l(1.759,.13),l(1.534,.168),l(2.001,.034),l(.66,.34),l(.045,.359),l(-.907,.398),l(-2.685,.268),l(-.927,.115),l(-1.054,.227),l(-1.115,.077),l(-.467,-.28),l(-.797,-.638),l(-.56,.039),l(-.631,.001),l(-1.453,-.318),l(-.001,.17),l(.331,.508),l(-1.477,-.016),l(-1.5,-.129),l(-.875,-.319),l(-1.033,-.471),l(-.388,.058),l(.527,.717),l(-.24,.17),l(-.821,.133),l(-1.72,-.109),l(-2.276,-.033),l(-.972,-.073),l(-1.382,-.394),l(-.642,-.131),l(-.282,.453),l(-.619,.152),l(-1.843,-.316),l(.161,-.586),l(.219,-.228),l(1.525,-.117),l(.61,-.249),l(.961,-.173),l(1.179,.036),l(.499,-.172),l(-1.073,-.4),l(-1.043,-.651),l(.052,-.154),l(.479,-.117),l(1.316,.036),l(1.743,.093),l(.888,.21),l(1.108,.517),l(1.35,.323),l(1.085,.093),l(1.667,-.022),l(.829,-.136),l(.086,-.268),l(.514,-.304),l(-3.019,.001),l(-1.025,-.171),l(-.156,-.85),l(.211,-.154),l(-1.74,-.153),l(-1.963,-.152),l(-.274,0),l(-.631,.114),l(.204,-.758),l(1.159,-.551),l(1.104,-.16),l(1.837,-.003),l(1.164,.037),l(1.37,.076),l(2.023,.311),l(1.342,.115),l(.486,-.158),l(1.132,-.041),l(-3.399,-.802),l(-1.742,-.313),l(-3.555,-1.27),l(-.406,.242),l(-1.398,-.878),l(.025,-.258),l(.313,-.108),l(1.747,.104),l(1.905,-.004),l(2.019,.06),l(1.6,.382),l(2.535,.784),l(1.448,-.043),l(.833,.095),l(-1.387,-.555),l(-2.015,-.317),l(1.208,-.743),l(1.456,-.329),l(1.731,-.025),l(1.529,-.222),l(2.042,-.07),l(1.157,-.112),l(1.414,-.051),l(-1.778,-.479),l(-1.425,-.153),l(-2.501,.027),l(-1.243,.248),l(-1.305,.158),l(-1.425,.202),l(-1.447,.047),l(-.586,.067),l(-1.532,-.438),l(-.214,.111),l(-.543,.156),l(-2.16,-.018),l(-1.58,.365),l(.311,-.828),l(.98,-.292),l(.007,-.202),l(-.606,-.247),l(-1.375,-.156),l(-1.39,.003),l(-4.189,.505),l(-2.031,.672),l(-.408,-.11),l(-.569,-.251),l(.395,-.133),l(.678,-.023),l(-.117,-.316),l(-.698,-.398),l(-1.216,-.056),l(-.216,-.003),M(200.125,20.844),l(.899,-.096),l(.832,.196),l(.339,.5),l(.511,.495),l(.427,.063),l(1.141,.041),l(-.081,-.236),l(.056,-.411),l(.438,-.109),l(.718,.194),l(.718,.322),l(.374,.3),l(-.066,.171),l(.056,.826),l(.764,.442),l(.953,-.017),l(1.276,-.074),l(1.646,.504),l(-1.123,-.264),l(-1.528,.34),l(-1.599,.221),l(-.83,.377),l(-.287,.197),l(-.265,.315),l(-.448,.021),l(-1.493,-.41),l(-.656,.335),l(.465,.43),l(-.029,.235),l(-.412,.196),l(-.392,.04),l(-1.086,-.31),l(-.944,-.311),l(-.26,.645),l(-.117,.068),l(-.083,.049),l(-.888,.041),l(-1.74,-.094),l(-1.458,-.153),l(-.888,-.154),l(-.494,.021),l(-3.115,-1.31),l(-.191,-.276),l(1.971,-.241),l(3.32,.093),l(.889,.097),l(1.573,.1),l(-2.485,-.693),l(-3.019,-.213),l(-1.103,.122),l(-1.43,-.017),l(-.597,.18),l(-1.008,.022),l(-.606,-.198),l(-1.066,-.517),l(-1.425,-.479),l(-.341,-.355),l(1.971,.124),l(2.278,-.175),l(-1.255,-.249),l(-.756,-.351),l(.38,-.305),l(.729,-.132),l(.769,-.023),l(.921,.042),l(.156,-.219),l(-1.799,-.793),l(1.053,-.114),l(1.213,-.182),l(1.13,.087),l(.584,-.046),l(.145,-.18),l(-.514,-.475),l(1.362,.134),l(.941,.066),l(.83,.202),l(1.589,.869),l(.653,.264),l(.772,.24),l(.674,-.001),l(.36,-.039),M(179.067,27.216),l(-1.156,-.056),l(-.604,-.173),l(-.926,-.638),l(-.621,-.193),l(-3.102,-.091),l(-1.487,.081),l(-.622,.001),l(-1.444,-.056),l(-.767,-.154),l(-1.019,-.37),l(-.161,-.234),l(.335,-.138),l(.802,-.001),l(1.687,.232),l(.867,-.021),l(-.031,-.235),l(-.252,-.275),l(-1.344,-.49),l(-.579,-.098),l(-1.075,-.077),l(-1.392,-.196),l(.065,-.397),l(2.246,-.124),l(2.392,.155),l(.77,.376),l(.999,.453),l(1.979,.193),l(2.189,.114),l(1.178,.233),l(.604,.254),l(1.123,.721),l(.581,.446),l(.168,.426),l(-.481,.194),l(-.919,.137),M(185.907,26.758),l(-1.078,-.037),L(184,26.529),l(-1.029,-.484),l(-1.144,-.76),l(-.03,-.216),l(.239,-.099),l(2.296,-.044),l(1.816,.311),l(3.101,.542),l(-.047,.351),l(-.254,.331),l(-.436,.04),l(-1.563,.177),l(-1.043,.08),M(156.886,26.865),l(-1.573,.646),l(-.558,.27),l(-1.85,.042),l(-1.019,.079),l(-1.898,-.15),l(-.577,-.114),l(-.302,-.423),l(.334,-.291),l(1.365,-.177),l(.899,.056),l(2.351,-.102),l(.496,0),l(2.331,.163),M(132.902,31.305),l(-.53,-.186),l(-.95,-.466),l(-.424,-.112),l(-.33,.057),l(-.56,.207),l(-1.269,.059),l(-.786,-.279),l(-.283,-.319),l(.23,-.264),l(1.13,-.097),l(.503,-.133),l(.771,-.134),l(.977,-.399),l(.848,-.211),l(.726,-.172),l(.548,-.344),l(1.083,-.231),l(1.277,-.079),l(2.532,-.158),l(1.68,.016),l(.888,-.29),l(1.038,-.079),l(1.503,.438),l(-.756,.097),l(-.852,.231),l(-.22,.268),l(.12,.266),l(.469,.474),l(-.777,.001),l(-.912,.115),l(-.918,.662),l(-1,-.017),l(-.867,-.981),l(-.694,-.15),l(-.379,.02),l(-.229,.285),l(-.588,.342),l(-.63,.623),l(-.595,.151),l(-.284,.375),l(-.705,.356),l(-.787,.058),M(191.827,30.313),l(-1.266,-.054),l(-2.278,-.165),l(-.426,.058),l(-.332,-.094),l(-.896,-.489),l(-1.185,-.414),l(.192,-.229),l(2.433,-.042),l(1.542,.263),l(1.472,.054),l(.171,0),l(.89,.358),l(-.179,.246),l(.123,.32),l(-.263,.188),M(144.688,31.739),l(-2.222,-.395),l(-.325,-.674),l(.503,-.057),l(.595,-.17),l(.945,-.096),l(.953,-.133),l(1.279,-.059),l(.522,.187),l(.65,.374),l(.659,.186),l(1.55,-.209),l(.617,.149),l(1.624,.762),l(1.016,.351),l(.897,.036),l(.96,-.058),l(1.418,.09),l(.591,-.02),l(1.116,-.169),l(.092,-.297),l(-.557,-.559),l(-.941,-.391),l(-1.347,-.354),l(.96,-.322),l(.524,-.379),l(.569,-.152),l(1.097,-.116),l(.507,.17),l(.773,.678),l(-.017,.413),l(.518,.654),l(.565,.111),l(.9,.036),l(1.805,.406),l(-.334,-.465),l(.151,-.28),l(.409,-.076),l(1.495,.24),l(.932,.39),l(-.292,.409),l(.039,.5),l(-.358,.461),l(-.573,.277),l(-.755,.111),l(-.782,.001),l(-1.682,.095),l(-1.156,-.071),l(-1.757,-.18),l(-.622,-.017),l(-1.129,.277),l(-1.132,.202),l(-.76,.182),l(-.977,.254),l(-1.625,.292),l(-1.338,.2),L(149.23,34.5),l(-.748,-.07),l(-1.445,-.286),l(-.276,-.378),l(.648,-.128),l(1.219,-.038),l(.738,-.146),l(.852,-.075),l(1.166,-.057),l(.622,.017),l(1.09,-.149),l(.483,-.553),l(-2.768,-.087),l(-.925,-.054),l(-1.564,.28),l(-1.625,.168),l(-1.292,.04),l(-.795,.093),l(-1.681,-.347),l(-.479,.167),l(-.92,.075),l(-.979,-.127),l(-.854,-.33),l(.023,-.111),l(.863,-.427),l(1.098,-.058),l(2.047,-.022),l(.96,-.159),M(178.479,33.234),l(-.984,-.219),l(-.193,-.294),l(.764,-.389),l(.433,-.112),l(.088,-.167),l(-.447,-.333),l(-1.161,-.054),l(-2.13,.227),l(-.939,.076),l(-.331,.019),l(-.854,-.276),l(.039,-.335),l(.739,-.02),l(.542,-.244),l(.587,-.057),l(-.466,-.598),l(.176,-.245),l(.132,-.226),l(.49,.018),l(.859,.224),l(1.942,.746),l(.426,.186),l(.46,-.094),l(-.101,-.243),l(-.959,-.486),l(-.371,-.131),l(-.407,-.357),l(.436,-.095),l(.956,-.059),l(.713,.131),l(1.033,.262),l(.572,.168),l(.27,.018),l(.162,-.452),l(.478,-.133),l(.73,.112),l(.717,.168),l(.327,.168),l(.367,.75),l(-.034,.616),l(-.247,.242),l(-.831,.335),l(-.017,.352),l(.35,.625),l(-.361,.147),l(-1.648,-.089),l(-.862,.112),l(-1.446,.003),M(200.125,30.572),l(-.895,.045),l(-.853,.17),l(-.37,.467),l(1.133,.054),l(.984,-.038),l(.046,-.001),l(.847,.11),l(.463,.129),l(.498,.463),l(.727,.424),l(.621,.091),l(.213,-.074),l(.043,-.314),l(.286,-.056),l(1.075,-.002),l(.883,-.187),l(.766,.11),l(.835,.239),l(.665,.257),l(.976,.053),l(.775,-.463),l(1.393,-.281),l(1.704,-.114),l(1.951,-.246),l(1.533,.053),l(2.59,.014),l(.381,.037),l(.79,.314),l(.911,.239),l(1.418,.146),l(.653,.128),l(.21,.037),l(.361,.166),l(.181,.257),l(-.4,.148),l(-1.833,.407),l(-.135,.255),l(.469,.666),l(-2.486,.076),l(-.592,.02),l(-.651,.091),l(-.768,-.053),l(-.846,-.16),l(-.405,-.125),l(-.306,-.667),l(-.833,-.218),l(-.366,.129),l(.072,.723),l(-.536,.127),l(-.747,-.053),l(-.91,.109),l(-.728,-.017),l(-.495,.001),l(-1.342,-.213),l(-.593,-.197),l(-.495,-.017),l(-.209,.433),l(-1.801,.111),l(-.831,.074),l(-1.453,-.069),l(-.404,-.251),l(-.144,-.686),l(-1.237,.129),l(-.389,.181),l(-.326,.325),l(-.955,.2),l(-1.011,-.034),l(-.112,-.027),l(-.704,-.169),l(-1.186,-.575),l(-.675,.489),l(-1.131,-.07),l(-.666,-.688),l(-.442,-.717),l(.587,-.481),l(.019,-.371),l(-.292,-.316),l(-1.249,-.651),l(-.617,-.299),l(-.047,-.338),l(.636,-.133),l(1.226,-.078),l(2.472,-.023),l(.763,.093),l(1.118,.261),l(.188,.04),l(.872,.184),l(-.613,.189),l(-.259,.013),M(128.19,41.985),l(-.926,-.016),l(-1.059,-.102),l(-.362,-.466),l(-.549,-.467),l(-.432,-.259),l(-1.123,-.363),l(-1.36,-.067),l(-.951,-.138),l(-.469,-.19),l(-.168,-.174),l(.537,-.106),l(.589,-.298),l(.481,-.211),l(.08,-.386),l(-.437,-.809),l(.552,-.001),l(.468,-.177),l(.307,-.372),l(1.104,-.533),l(.526,-.588),l(-.121,-.32),l(-.271,-.16),l(-1.229,-.677),l(-.375,-.448),l(.869,-.001),l(.823,-.056),l(1.455,.051),l(.97,.016),l(1.515,-.092),l(1.284,-.146),l(1.242,-.074),l(.495,.125),l(3.242,.801),l(.918,.088),l(.708,-.055),l(1.316,-.127),l(1.223,.016),l(.771,.07),l(1.35,.373),l(2.389,.815),l(-.242,.143),l(-.432,.036),l(-.26,.072),l(-1.609,.322),l(-1.073,.144),l(-1.829,.428),l(-1.069,.319),l(-1.604,.725),l(-1.025,.563),l(-.549,.089),l(-.974,.124),l(.066,.924),l(-.271,.504),l(-.662,.278),l(-1.215,.124),l(-1.213,-.067),l(-.521,.485),l(-.898,.312),M(190.483,39.666),l(-1.146,-.208),l(-.146,-.524),l(-.941,-.806),l(-.207,-.582),l(.058,-.389),l(.27,-.657),l(.377,-.321),l(1.256,.033),l(-.089,-.16),l(-.416,-.266),l(-.185,-.286),l(.211,-.09),l(.234,-.072),l(2.154,-.058),l(1.215,.087),l(1.464,.248),l(1.282,.051),l(1.316,-.146),l(1.051,.016),l(.694,.105),l(.639,.213),l(-.007,.089),l(-.224,.179),l(-.824,.428),l(-.874,.746),l(-1.513,.92),l(-1.386,.073),l(-2.379,-.154),l(-1.269,.055),l(1.392,.717),l(-.188,.315),l(-.855,.369),l(-.964,.072),M(181.204,41.523),l(-.491,-.085),l(-1.101,-.552),l(-.952,-.641),l(-1.014,-.468),l(-.978,-.225),l(-1.438,-.12),l(-.55,-.174),l(-2.255,-1.066),l(.866,-.654),l(.653,.14),l(1.032,.474),l(1.063,.227),l(.46,.052),l(.615,-.283),l(.908,-.619),l(.415,-.036),l(.018,-.212),l(-1.062,-.565),l(-1.068,-.424),l(-.177,-.231),l(.132,-.107),l(1.683,.086),l(.711,-.215),l(.42,0),l(.996,.39),l(.56,.035),l(.58,-.055),l(.435,-.25),l(1.232,-.127),l(1.354,.069),l(.912,.23),l(-.324,.268),l(-.58,.125),l(-.323,.338),l(-1.55,.375),l(-.392,.16),l(-.069,.194),l(.253,.247),l(.506,.105),l(.692,-.089),l(1.08,.174),l(.868,.245),l(.391,.017),l(.564,.262),l(.186,.438),l(-.681,.352),l(-.156,.35),l(-.271,.68),l(-.457,.366),l(-.508,.14),l(-.658,.019),l(-.582,-.103),l(-.773,-.346),l(-.653,-.103),l(.013,.208),l(1.054,.553),l(-.817,.399),l(-.77,.036),M(243.524,60.394),l(-.234,-.208),l(-1.199,-.235),l(-.673,-.331),l(-.154,-.269),l(.346,-.064),l(.616,-.461),l(-1.378,-.521),l(-1.132,-.125),l(-.76,-.349),l(-.929,-.731),l(-.035,-.511),l(-1.115,-.062),l(-1.311,-.366),l(-.675,-.031),l(.284,.767),l(-.155,.096),l(-.409,-.015),l(-1.704,-.332),l(-.309,.033),l(-.325,.304),l(-.441,.288),l(-1.312,.082),l(-1.349,-.173),l(-1.343,-.189),l(-.813,-.254),l(-.052,-.319),l(.196,-.4),l(.382,-.354),l(1.066,-.163),l(.192,-.178),l(-.128,-.516),l(.206,-.033),l(1.357,.11),l(1.408,.175),l(.517,.144),l(.962,.626),l(.051,-.386),l(-.154,-.193),l(.077,-.194),l(.585,-.033),l(.977,-.099),l(.652,-.163),l(.649,-.114),l(.515,.063),l(.785,.031),l(.166,-.275),l(-1.138,-.825),l(-.773,-.356),l(-.119,-.228),l(.167,-.163),l(.586,-.066),l(.72,-.246),l(1.409,-.591),l(.361,-.541),l(.771,-.46),l(.493,-.379),l(-.109,-.593),l(-.899,-.841),l(-.407,-.496),l(-.541,-.364),l(-.414,.001),l(-1.258,-.33),l(-1.041,-.481),l(-.244,-.467),l(-.527,-.384),l(-.442,.202),l(-.551,.202),l(-.825,-.015),l(-.293,.117),l(-.62,.018),l(-1.255,.169),l(-.214,-.667),l(1.032,-.052),l(1.23,-.103),l(.163,-.269),l(-1.604,-.618),l(-1.552,-.67),l(-.879,-.015),l(-.567,-.185),l(-.169,-.542),l(-.677,-.339),l(-.45,-.05),l(-.918,-.306),l(-.687,-.341),l(-.385,-.119),l(-.611,.155),l(-.81,-.187),l(-1.177,-.238),l(-.489,-.085),l(-.379,.138),l(.529,.307),l(.453,.05),l(2.838,.712),l(.438,.271),l(.069,.306),l(-.505,.221),l(-.669,.069),l(-.541,-.033),l(-.757,-.049),l(-.818,-.252),l(-1.153,-.27),l(-.667,-.066),l(-.323,.17),l(.044,.204),l(.426,.236),l(.259,.438),l(-1.703,-.553),l(-.47,-.05),l(-.396,.119),l(-.63,.153),l(-.767,-.218),l(-.693,-.117),l(-.859,.12),l(-1.474,-.184),l(-1.995,-.167),l(-1.321,.037),l(-1.146,-.032),l(-.862,-.186),l(-.003,-.597),l(-.363,-.153),l(-.904,-.049),l(-.396,.342),l(-.623,.086),l(-1.214,-.049),l(-1.076,-.168),l(-1.303,-.477),l(-.415,-.376),l(.123,-.275),l(.868,-.07),l(1.131,.067),l(1.212,.101),l(.879,-.019),l(.312,-.19),l(-.934,-.463),l(-.8,-.275),l(-.905,-.102),l(-1.106,-.119),l(-.752,.036),l(-.539,-.017),l(-1.249,-.223),l(.114,-.416),l(.292,-.557),l(.34,-.14),l(.646,-.054),l(.081,-.227),l(-1.082,-.4),l(-.044,-.175),l(.449,-.79),l(1.197,-.919),l(.565,-.284),l(.918,-.321),l(.74,-.374),l(.423,-.037),l(.37,-.178),l(.698,-.001),l(.481,-.125),l(.71,-.09),l(1.436,-.109),l(1.348,.033),l(.857,.194),l(-.92,.393),l(-.815,.48),l(-1.394,.639),l(-.43,.529),l(.169,.369),l(1.256,.541),l(-.444,.298),l(-.076,.402),l(.257,.313),l(.862,.554),l(1.559,.621),l(-.096,.121),l(-1.272,.331),l(-.072,.31),l(.959,.033),l(1.504,.101),l(.654,-.639),l(-.103,-.415),l(-.343,-.277),l(-.724,-.103),l(-.422,-.138),l(-.884,-.538),l(.101,-.157),l(.506,-.245),l(.473,-.193),l(1.001,.12),l(.837,-.071),l(-1.204,-.47),l(-.703,-.034),l(-.793,-.279),l(-.056,-.193),l(.053,-.545),l(.886,-.319),l(1.207,.086),l(1.509,-.056),l(-.939,-.281),l(-1.233,-.351),l(.793,-.303),l(1.288,-.198),l(1.044,-.126),l(1.688,-.323),l(1.114,.016),l(.642,.052),l(.833,.141),l(.782,.478),l(1.536,.97),l(.058,.141),l(-.583,.687),l(-.709,.632),l(.038,.733),l(.364,.086),l(.65,.033),l(1.088,-.315),l(.284,-.455),l(.595,-.088),l(.791,.034),l(.454,.174),l(-.006,.262),l(.16,.47),l(.875,.189),l(.196,-.122),l(-.204,-.854),l(.218,-.123),l(.456,-.474),l(1.038,-.265),l(.98,-.054),l(.748,.034),l(.98,.174),l(1.172,.138),l(1.151,-.09),l(.688,.139),l(.327,.262),l(.621,.331),l(.574,.191),L(235.438,40),l(0,.191),l(-.531,.088),l(-.484,.279),l(-.818,.262),l(-.148,.225),l(.45,.259),l(.427,.068),l(.897,-.417),l(.652,-.174),l(.502,.051),l(.476,.242),l(.365,.466),l(.516,.413),l(.342,-.242),l(1.304,-.798),l(1.935,.256),l(.915,.361),l(-.051,.069),l(-.638,.346),l(-.708,.517),l(1.167,-.054),l(.455,-.173),l(1.078,-.105),l(.033,.704),l(.797,.324),l(.523,-.069),l(.831,-.207),l(1.316,-.088),l(.816,.221),l(.566,.273),l(-.162,.154),l(-.461,.223),l(-1.87,.43),l(-.238,.272),l(.523,.253),l(.456,-.068),l(.747,-.171),l(1.235,-.122),l(.406,-.29),l(.361,-.103),l(.479,.067),l(.51,.187),l(.544,.339),l(.636,.522),l(-1.019,.002),l(-1.2,.053),l(-.424,.135),l(.059,.269),l(.372,.134),l(1.333,.065),l(.938,.183),l(.543,.217),l(.233,.301),l(-.37,.034),l(-.748,.001),l(-1.011,-.082),l(-.875,-.216),l(-.824,-.065),l(-.316,.185),l(1.23,.583),l(-.216,.201),l(-1.552,.12),l(.245,.283),l(.437,.166),l(.551,.032),l(1.331,.364),l(1.312,.347),l(.247,.182),l(.039,.282),l(.351,.38),l(.75,-.217),l(.536,.049),l(1.413,.295),l(.298,-.067),l(.649,-.15),l(.61,.032),l(.752,.379),l(.862,.477),l(.376,.346),l(-.685,.1),l(-.801,.117),l(-.027,.444),l(.795,-.001),l(1.405,-.052),l(.51,-.132),l(.895,.048),l(-.386,.559),l(.918,.179),l(.514,-.001),l(.943,-.379),l(.685,.343),l(1.089,.407),l(.194,.098),l(-.275,.229),l(-.254,.099),l(-.103,.326),l(-.819,.05),l(-.718,-.21),l(-.247,-.048),l(-.794,.213),l(.968,.454),l(.279,.162),l(.057,.276),l(-1.057,.197),l(-.356,.228),l(-.312,.292),l(-.372,-.113),l(-.819,-.583),l(-.29,1.103),l(.354,.903),l(-.419,.065),l(-.677,-.257),l(-.751,-.176),l(-.205,-.177),l(-.018,-.243),l(-.315,-.274),l(-.93,.276),l(-.743,-.613),l(.051,-.292),l(.27,-.374),l(-.304,-.129),l(-.224,-.016),l(-.992,-.08),l(-.718,-.292),l(-1.17,-.617),l(-.769,-.292),l(-.762,-.048),l(-.452,.23),l(-.645,.083),L(250,52.592),l(.281,.179),l(1.05,.682),l(-.321,.114),l(-.686,.05),l(-.359,-.259),L(249.277,53),l(-.646,-.21),l(.275,.488),l(.859,.972),l(.604,.015),l(.587,.08),l(.5,.581),l(.612,.805),l(.513,.432),l(.615,-.321),l(.285,.047),l(.592,.399),l(.585,.271),l(1.38,.396),l(-.634,.113),l(-.213,.208),l(.254,.19),l(.568,.286),l(.962,.444),l(.324,.237),l(.242,.682),l(-.112,.428),l(-1.302,-1.155),l(-.554,-.237),l(-.027,.238),l(.118,.27),l(1.055,1.281),l(-.01,.3),l(-.926,-.125),l(.053,.205),l(.432,.409),l(.378,.519),l(-.563,-.172),l(-.615,-.313),l(-.889,-.693),l(-.145,-.031),l(-.719,.064),l(-.91,-.188),l(-1.44,-.662),l(-.319,-.285),l(-1.062,-.665),l(.187,.777),l(-1.22,-.473),l(-.567,-.158),l(-.872,-.03),l(.095,.222),l(.799,.696),l(.853,.426),l(1.842,.645),l(1.296,.644),l(.774,.549),l(.442,.486),l(.429,.689),l(-1.833,-.341),l(-1.524,-.421),l(-1.251,-.28),l(-1.444,-.107),l(-1.092,-.25),l(-.898,-.644),l(-1.146,-.14),l(-.638,-.204),l(-.635,-.141),l(-.058,.145),M(146.194,38.698),l(.818,-.037),l(.78,-.125),l(1.138,-.548),l(.895,-.019),l(1.723,.243),l(.939,.262),l(-.188,.877),l(.515,-.071),l(.66,-.019),l(.792,-.229),l(.599,-.141),l(.758,.016),l(.334,-.071),l(-.989,-.965),l(.156,-.036),l(1.38,.138),l(1.208,.245),l(.675,.245),l(.259,.245),l(.194,.508),l(.965,1.063),l(.638,.346),l(1.045,-.315),l(.14,-.261),l(-1.243,-1.361),l(-.439,-1.321),l(.228,-.354),l(1.91,.262),l(1.775,.156),l(2.031,.719),l(.36,.175),l(.3,.316),l(.16,.701),l(.511,.645),l(.352,.26),l(.856,.606),l(.048,.19),l(-.178,.243),l(-.333,.605),l(.179,.31),l(.224,.12),l(1.4,.649),l(.509,.171),l(1.151,.254),l(1.513,.1),l(2.056,.576),l(1.012,.39),l(.364,.793),l(-.168,.101),l(-1.071,-.082),l(-.811,-.234),l(-.945,-.234),l(-.551,.169),l(-.665,.204),l(-1.021,.036),l(-.256,.118),l(.208,.689),l(1.087,-.069),l(.614,-.152),l(.676,-.119),l(.876,.536),l(-.01,.235),l(-.526,.151),l(-.517,.252),l(-.583,.102),l(-1.417,.12),l(-1.049,-.015),l(-1.194,-.082),l(-1.594,-.248),l(-2.278,-.499),l(-.553,-.217),l(-.436,-.335),l(-.482,-.033),l(-.581,.102),l(-.402,.37),l(-1.114,.505),l(-1.055,.019),l(-1.411,.103),l(-1.253,.42),l(-2.753,.356),l(-1.42,.019),l(-1.205,.086),l(-1.984,-.063),l(-.483,.101),l(-.916,-.015),l(-1,-.282),l(-.061,-.468),l(.198,-.101),l(.002,-.302),l(-.395,-.2),l(-.462,-.1),l(-3.146,-.112),l(-1.258,-.115),l(-.864,-.167),l(-.801,-.2),l(-.753,-.504),l(-1.274,-.554),l(.303,-.069),l(.531,-.222),l(1.572,-.054),l(.603,-.188),l(.558,.016),l(.91,-.019),l(.904,-.087),l(1.716,.031),l(.935,-.002),l(2.14,.047),l(1.09,-.002),l(1.711,-.038),l(.415,-.154),l(-.681,-.221),l(-2.312,-.492),l(-1.942,-.202),l(-4.059,-.061),l(-1.569,-.014),l(-1.694,.055),l(-.955,.053),l(-.604,.001),l(-1.651,-.529),l(.011,-.207),l(.28,-.069),l(.823,-.053),l(1.315,-.209),l(.996,.032),l(1.78,-.141),l(.931,-.105),l(.5,-.277),l(-.392,-.346),l(-2.023,.073),l(-1.578,.159),l(-.393,-.051),l(-.554,-.189),l(-.677,-.346),l(-.65,-.19),l(-.692,.054),l(-.709,-.242),l(-.039,-.279),l(1.304,-.981),l(2.62,-.848),l(.909,-.143),l(.373,-.177),l(1.297,-.267),l(1.324,-.162),l(.701,-.267),l(1.113,-.091),l(1.026,.246),l(-.07,.212),l(-.548,.354),l(-.021,.81),M(251.273,99.526),l(-.188,.153),l(-.16,-.291),l(.192,-.077),l(-.02,-.256),l(.143,-.069),l(-.042,-.154),l(-.224,0),l(-.606,-.231),l(.077,-.229),l(-.31,-2.819),l(-.174,-.274),l(-.488,-.288),l(-.771,-.025),l(-.41,.176),l(-.381,-.085),l(-.505,-.36),l(-.273,-.085),l(-.632,.526),l(-.514,.626),l(-1.139,2.22),l(-1.139,1.45),l(-1.161,-.124),l(-.402,.06),l(-.363,.435),l(-.174,.375),l(-1.093,-.095),l(-1.855,-.004),l(-2.508,-.029),l(-1.76,.009),l(-.968,.523),l(-.534,.305),l(-1.754,.814),l(-.545,.164),l(-.146,.434),l(-.163,.512),l(-.44,.275),l(-1.156,.197),l(-1.305,-.138),l(-1.123,-.01),l(-.93,.091),l(-.47,.203),l(-.162,.375),l(.018,.319),l(.16,.471),l(.047,.362),l(-.875,.427),l(-1.464,.452),l(-.944,.163),l(-.919,.062),l(-.88,.262),l(-.939,.478),l(-.925,.506),l(-.524,.117),l(-.573,-.068),l(-.497,-.169),l(-.371,-.427),l(-.012,-.33),l(.044,-.218),l(.707,-.525),l(.414,-.294),l(.264,-.433),l(.294,-.544),l(.377,-.576),l(.028,-.746),l(-.054,-.545),l(-.876,-3.16),l(-2.529,-1.05),l(-.26,-.33),l(.11,-.318),l(-.307,-.235),l(-.916,-.181),l(-.184,-.294),l(-.178,-.135),l(-.628,.024),l(-.46,-.465),l(-.101,-.429),l(-2.15,-1.061),l(-3.975,-1.576),l(-.977,-.386),l(-.797,-.227),l(-.805,.189),l(-1.469,.592),l(-.707,-.074),l(-.542,.049),l(-.196,-.144),l(-.156,-.115),l(-.474,-.041),l(-.855,.083),l(-.197,-.116),l(-.028,-.282),l(-.373,.075),l(-.412,.191),l(-.219,.06),l(-.573,.141),l(-.506,-.098),l(-.064,-.185),l(-.469,-.086),l(-.241,-.271),l(-.502,-.013),l(-.16,.247),l(-.338,-.48),l(-.271,.012),l(-.02,-.185),l(-1.425,-.208),l(-.518,.076),l(-.833,-.451),l(-.468,-.46),l(-.279,-.371),l(-.896,-.748),l(-.501,.036),l(.131,.347),l(.387,.588),l(-.68,-.003),l(-2.687,.029),l(-2.798,-.029),l(-1.348,.007),l(-2.105,-.003),l(-2.915,.016),l(-2.781,-.029),l(-2.131,.012),l(-2.935,-.014),l(-.601,.003),l(-4.84,-.018),l(-3.617,.004),l(-.875,.005),l(-3.821,-.023),l(-1.089,.035),l(-4.13,-.021),l(-.74,-.011),l(-5.117,.028),l(-1.687,-.006),l(-2.87,.001),l(-3.938,-.008),l(-4.588,.025),l(-1.335,-.022),l(-2.579,-.001),l(-.194,-.013),l(-.187,-.151),l(-.509,-.305),l(-.071,-.437),l(.074,-.346),l(-.708,.25),l(-.373,-.029),l(-.331,-.305),l(-.162,-.496),l(-.125,-.189),l(-.385,.088),l(-.23,.205),l(-.483,.059),l(-.721,-.495),l(-.119,-.425),l(-.201,-.821),l(-1.051,.104),l(-1.01,-.277),l(-.487,-.087),l(-.173,-.087),l(-.143,-.396),l(-.438,-.352),l(-.591,.222),l(-1.236,.046),l(-.461,-.117),l(-.383,-.249),l(-.106,-.25),l(.257,-.648),l(.458,-.222),l(-.227,-.294),l(-1.24,-.086),l(.617,-.518),l(.398,-.281),l(.547,-.149),l(.605,-.508),l(-.874,.006),l(-.621,.149),l(-.362,-.043),L(116,83.422),l(-.039,-.978),l(-.789,.002),l(-1.015,-1.066),l(.132,-.238),l(.034,-.53),l(-.547,.056),l(-.83,.492),l(-1.266,-.934),l(-.384,-.521),l(-.204,-.402),l(-.068,-.432),l(.419,-.404),l(.161,-.254),l(.436,-.3),l(-.358,-.689),l(-.393,-.777),l(.163,-.788),l(-.402,-.255),l(-2.025,-.763),l(-.98,-.314),l(-.189,-.029),l(-.512,-.393),l(-1.67,-1.882),l(-1.769,-1.768),l(-.814,-.58),l(-2.048,-1.175),l(-.35,-.322),l(-.371,-.492),l(-.316,-.199),l(-.832,-.073),l(-.495,.126),l(-.731,.498),l(-1.225,.67),l(-.848,.205),l(-.238,.325),l(-.945,-.673),l(-2.162,-1.318),l(-.348,-.292),l(-.173,-.387),l(-.332,-.388),l(-.739,-.059),l(-2.424,.122),l(-.84,-.074),l(-.196,-.279),l(-.089,-1.046),l(-.026,-2.167),l(.043,-4.334),l(.026,-2.183),l(-.129,-2.796),l(-.052,-2.335),l(-.039,-2.259),l(.003,-2.855),l(-.102,-.483),l(.71,.024),l(.9,-.086),l(.964,.116),l(2.012,.451),l(1.601,.518),l(1.214,.266),l(1.04,.115),l(.731,.032),l(1.619,.164),l(.888,.232),l(.429,.149),l(.254,-.034),l(-.452,-.601),l(-.357,-.2),l(-.345,-.15),l(-.064,-.419),l(1.344,-.423),l(.745,.066),l(.578,-.068),l(.15,-.102),l(1.736,.148),l(.771,-.001),l(1.125,-.373),l(.309,-.186),l(.442,0),l(.656,-.221),l(.759,-.069),l(.866,-.086),l(.734,-.086),l(.469,-.239),l(.392,-.188),l(.771,-.104),l(1.045,-.002),l(.872,.123),l(-.445,.404),l(-.352,.119),l(-1.101,.137),l(-1.092,.373),l(-1.244,.171),l(-1.22,.271),l(-.699,.522),l(-1.767,.255),l(-.681,.487),l(.846,.266),l(1.441,.748),l(-.219,-.55),l(.168,-.351),l(1.196,-.253),l(.39,-.235),l(.726,-.421),l(1.727,-.053),l(.96,-.372),l(1.158,-.389),l(2.066,-.173),l(.643,-.338),l(.921,-.272),l(.821,-.189),l(.476,-.239),l(-.178,-.272),l(-.702,-.392),l(-.655,-.444),l(.899,.101),l(.764,.272),l(.701,.306),l(.412,.324),l(.376,.476),l(.449,.523),l(.393,.235),l(1.246,.486),l(.186,.067),l(1.154,.216),l(.394,-.018),l(.199,-.151),l(-.511,-.639),l(.07,-.27),l(.548,-.035),l(.334,-.136),l(.627,-.103),l(.383,.354),l(.059,.421),l(-.205,.287),l(.833,.133),l(.938,-.069),l(1.136,-.457),l(.536,-.49),l(.479,-.069),l(1.131,.015),l(1.536,.267),l(1.745,.435),l(1.396,.334),l(2.095,.349),l(1.024,.216),l(.619,.066),l(1.572,.282),l(1.121,.065),l(1.144,.148),l(1.096,.032),l(1.4,-.086),l(.899,.099),l(1.008,.282),l(.982,.349),l(.434,.249),l(.191,.333),l(-.524,.134),l(-.935,-.032),l(-.566,.051),l(-.849,.135),l(-.354,.714),l(3.323,.358),l(1.726,.079),l(1.749,.014),l(.868,-.068),l(.738,-.051),l(.94,-.167),l(.895,-.118),l(.938,-.101),l(.886,.032),l(1.432,.477),l(1.452,.179),l(.42,.115),l(1.225,.443),l(-.013,.312),l(-.504,.083),l(-.35,.247),l(.305,.147),l(1.823,.979),l(-.162,-.392),l(-.024,-.312),l(.456,-.05),l(.617,-.132),l(-.062,-.181),l(-.972,-.656),l(-.128,-.198),l(-.145,-.445),l(.121,-.745),l(.35,-.034),l(1.944,-.136),l(.928,-.151),l(.207,-.299),l(.459,-.217),l(.613,-.035),l(1.098,.281),l(1.528,.279),l(.968,.064),l(.969,-.102),l(.612,.414),l(.248,.082),l(.962,.213),l(1.211,.13),l(.678,.081),l(1.146,-.002),l(.879,-.2),l(1.755,-.02),l(1.876,.029),l(1.07,-.052),l(1.18,-.267),l(.959,.478),l(.95,.296),l(.522,-.018),l(.243,-.314),l(-.017,-.513),l(-.666,-.231),l(-.732,-.131),l(-1.377,-.064),l(.089,-.449),l(1.193,-.085),l(.575,.065),l(.804,.214),l(.871,.198),l(.858,.048),l(.498,.198),l(.088,.183),l(-.095,.132),l(-.287,.86),l(.179,.51),l(.304,.164),l(.177,.065),l(.792,.097),l(.951,.311),l(-.071,-.559),l(-.466,-.989),l(.137,-.48),l(.258,-.266),l(.712,.015),l(.811,-.035),l(1.229,-.85),l(.492,-.051),l(.479,-.001),l(.517,-.151),l(.033,-.133),l(-.15,-.367),l(-.375,-.35),l(-.307,.001),l(-.81,.185),l(-.988,-.082),l(.535,-.52),l(.806,-.069),l(.435,-.168),l(.572,-.001),l(.739,.4),l(.464,.167),l(.065,-.268),l(-.081,-.956),l(-.744,.069),l(-.897,-.032),l(-.68,-.116),l(-.859,-.318),l(-.725,.085),l(-1.245,-.183),l(-.861,-.234),l(-.956,-.218),l(-.657,-.338),l(-.092,-.136),l(-.022,-.324),l(.33,-.137),l(.842,-.463),l(-.486,-.221),l(-1.188,-.375),l(.09,-.207),l(.58,-.604),l(.593,-.294),l(.387,-.035),l(1.032,.257),l(.139,-.035),l(.173,-.346),l(-.709,-.362),l(-.201,-.277),l(.23,-.035),l(.551,-.331),l(.367,-.035),l(1.841,-.021),l(.559,.086),l(.728,.189),l(1.26,.449),l(.432,.328),l(.195,.38),l(-.246,.603),l(1.261,.53),l(.809,.495),l(1.134,.493),l(-.377,.341),l(-.985,.036),l(-.474,.273),l(-.416,.557),l(.471,.067),l(1.071,.233),l(.805,.049),l(.387,-.136),l(.597,-.001),l(1.477,.351),l(-.335,.353),l(-.563,.219),l(.092,.151),l(.796,.467),l(.358,.601),l(.025,.833),l(.303,-.063),l(.021,-.004),l(.411,-.067),l(.608,-.367),l(.655,-1.137),l(.668,-.42),l(.523,.016),l(.731,.284),l(1.064,.55),l(.473,.383),l(.209,.45),l(-.159,.433),l(-.336,.034),l(-.796,-.098),l(-.202,.299),l(-.043,.415),l(.35,.396),l(1.146,.659),l(.61,.493),l(.463,.279),l(.595,-.166),l(.896,-.167),l(.369,-.132),l(.208,-.66),l(.764,-.398),l(.599,-.416),l(.249,-.664),l(.363,-.75),l(.237,-.184),l(1.394,.081),l(.329,-.067),l(.134,-.518),l(-.985,-.333),l(-.918,-.35),l(.088,-.891),l(.595,-.271),l(.787,.032),l(.42,-.068),l(.571,.016),l(3.459,.616),l(1.325,.669),l(.506,-.001),l(.553,-.068),l(.454,.201),l(.244,1.036),l(-.474,.268),l(-.431,.101),l(-.243,-.05),l(-.718,-.532),l(-.263,0),l(-.799,.269),l(.123,.316),l(.309,.515),l(.699,.729),l(.855,.528),l(1.108,.576),l(.024,.313),l(-.478,.642),l(-.439,.181),l(-1.407,.772),l(-.674,.083),l(-1.123,.509),l(-.763,-.276),l(-1.654,-.962),l(-.586,-.262),l(-.497,-.048),l(-.684,.281),l(1.364,.521),l(1.483,.896),l(-.708,.067),l(-.691,-.081),l(-1.288,.084),l(-.375,-.129),l(-.596,-.62),l(-1.147,-.014),l(-1.857,.118),l(-.253,.229),l(.614,.244),l(1.311,.421),l(-.159,.195),l(-.611,.327),l(-2.045,1.106),l(-.657,.179),l(-.527,.001),l(-.859,-.241),l(-.816,-.484),l(-.225,-.081),l(-1.189,-.225),l(-.736,-.259),l(-.598,-.112),l(-.947,.014),l(-.289,.004),l(-1.214,.174),l(1.503,.278),l(1.136,.21),l(1.751,.774),l(1.629,.433),l(1.233,.126),l(1.02,.031),l(-.618,1.091),l(-1.237,.705),l(-.856,.432),l(-.728,.161),l(-.829,.049),l(-.928,-.126),l(-1.062,-.38),l(-.048,.351),l(-.025,.287),l(.321,.572),l(-.02,.159),l(-.741,.031),l(-.058,.002),l(-1.365,-.108),l(-1.649,-.41),l(-.884,-.078),l(-2.962,-.322),l(2.146,.864),l(1.576,.156),l(1.367,.267),l(.562,.205),l(.33,.268),l(-.011,.19),l(-.642,.333),l(-1.106,.207),l(-1.429,-.076),l(-.511,-.062),l(-.367,.269),l(1.254,.423),l(-.469,.426),l(-1.06,.316),l(-1.454,.662),l(-.421,.252),l(.218,.704),l(-.313,.235),l(-.909,.205),l(-.31,.282),l(-.529,.64),l(-.276,.296),l(-.241,.669),l(-.274,.543),l(-.323,.666),l(.056,.416),l(-.161,.554),l(.123,.875),l(.136,.536),l(.598,.366),l(.25,.015),l(.257,.091),l(.664,.014),l(1.164,-.094),l(.276,.045),l(.367,.29),l(.413,.763),l(.813,1.157),l(.22,.668),l(-.132,.91),l(.673,.014),l(1.874,-.428),l(1.261,-.033),l(.723,.074),l(.535,.157),l(1.062,.311),l(2.129,.435),l(1.896,.903),l(.993,.933),l(3.5,.67),l(.644,.225),l(.982,.403),l(.986,.253),l(.553,.104),l(.702,-.091),l(.453,.044),l(.828,-.077),l(1.245,.163),l(1.407,.207),l(.401,.194),l(-.297,.702),l(-.142,.85),l(.154,.283),l(.307,.342),l(.07,.416),l(-.115,1.025),l(-.309,.593),l(.022,.208),l(.604,.266),l(.481,.339),l(.264,.354),l(.046,.488),l(-.076,.354),l(.97,.116),l(.963,.47),l(.676,.588),l(.392,.588),l(.078,.162),l(.64,.014),l(.726,.41),l(.907,.601),l(-.349,-.66),l(-.22,-.279),l(.134,-.338),l(.573,-.414),l(.365,.176),l(.381,.456),l(.262,.353),l(.165,-.354),l(.107,-.545),l(-.215,-.456),l(.541,-.532),l(.139,-.546),l(-.183,-.517),l(-.337,-.458),l(-.261,-.754),l(-.004,-.548),l(-.205,-.593),l(-.218,-.43),l(.615,-.016),l(-.097,-.476),l(-.296,-.252),l(-.657,-.163),l(-.375,-.282),l(-.326,-.923),l(1.252,-.271),l(.872,-.241),l(.625,-.271),l(1.758,-.949),l(.629,-.302),l(1.043,-.935),l(.434,-.544),l(.237,-.665),l(.054,-.529),l(-.257,-1.045),l(-.246,-.531),l(-.239,-.319),l(-.938,-.729),l(-.467,-.274),l(-1.105,-.532),l(-.363,-.122),l(-.453,-.274),l(-.151,-.046),l(-.293,-.351),l(.08,-.107),l(.868,-.522),l(.553,-.875),l(.293,-.416),l(.25,-.092),l(.447,-.017),l(.295,-.277),l(-.106,-.523),l(-.18,-.355),l(-.316,-.402),l(-.048,-.202),l(.258,-.357),l(.005,-.264),l(-1.751,-.105),l(1.084,-.92),l(.503,-.704),l(.007,-.125),l(-.316,-.203),l(-.609,-.265),l(-.244,-.266),l(-.043,-.533),l(.305,-.425),l(.554,-.315),l(.57,-.19),l(.827,.062),l(1.781,.374),l(1.097,.234),l(.753,.077),l(1.44,.013),l(1.08,-.144),l(.86,-.222),l(.21,-.047),l(.179,-.063),l(.589,.078),l(.991,.407),l(.254,.125),l(.754,.454),l(.918,.375),l(.796,.437),l(-.294,.391),l(.406,.233),l(1.698,.496),l(1.958,.354),l(.725,-.033),l(.368,-.203),l(.339,.295),l(-.013,.404),l(-.577,.343),l(-.123,.45),l(.438,1.327),l(.136,.722),l(.23,.414),l(-.049,.353),l(-.248,.169),l(-.445,-.014),l(-.347,-.015),l(-.138,.674),l(.375,.274),l(1.137,-.415),l(.366,-.047),l(.781,-.047),l(.286,.015),l(.677,.32),l(.378,.351),l(.004,.259),l(-.081,.123),l(.277,.32),l(.516,-.184),l(.306,-.046),l(1.173,-.079),l(.636,-.184),l(.436,-.383),l(.333,-.551),l(.326,.015),l(.194,.122),l(.693,.717),l(.042,-.062),l(.108,-.764),l(.317,-.583),l(.475,-.262),l(.539,-.385),l(-.651,-.505),l(.008,-.308),l(.272,-.139),l(.98,-.094),l(.193,-.139),l(.512,-.665),l(.667,.37),l(.607,.599),l(.785,.506),l(.596,.797),l(1.045,.764),l(.264,.352),l(-.344,.291),l(.095,.335),l(.573,-.031),l(.365,.777),l(.182,.183),l(.324,.121),l(.743,.136),l(.281,.258),l(.133,.38),l(-.379,.092),l(-.416,.168),l(.411,.318),l(.397,.227),l(.77,.196),l(.279,.227),l(.034,.424),l(-.056,.076),l(-.409,.106),l(-.676,-.029),l(-.745,-.12),l(-.316,.061),l(.091,.166),l(.273,.181),l(.189,.241),l(.333,.513),l(.411,.226),l(.634,.029),l(.462,.18),l(.838,.496),l(.899,.435),l(.246,.33),l(-.035,.195),l(-.447,.781),l(.508,.059),l(.663,-.166),l(.786,-.077),l(.79,.164),l(.574,.194),l(1.162,.49),l(.981,.132),l(1.517,.295),l(-.184,.253),l(-.718,.21),l(-.736,.21),l(-.663,.046),l(-.834,.24),l(-.583,.402),l(-.65,.225),l(-1.032,.061),l(-.286,.075),l(-.324,.268),l(.029,.371),l(-.271,.535),l(1.175,-.343),l(.542,-.09),l(.649,-.105),l(1.201,-.774),l(1.251,-.478),l(1.146,-.106),l(.662,.237),l(.35,.341),l(-.398,.446),l(.036,.119),l(.307,.296),l(.616,-.224),l(.455,-.164),l(.655,.192),l(1.051,.487),l(.226,.251),l(.022,.178),l(-.299,.43),l(-.05,.355),l(-.406,.444),l(1.001,.929),l(-.365,.37),l(-.795,.282),l(-1.078,.621),l(-.662,.281),l(-1.097,.046),l(-.823,.119),l(-1.548,.077),l(-.433,.413),l(-.916,.795),l(-.686,.427),l(-.612,.294),l(-.938,.222),l(-1.494,.172),l(-1.845,.127),l(-1.452,-.07),l(-2.031,-.084),l(-.355,.03),l(-1.073,.075),l(-1.058,-.012),l(-1.873,-.099),l(-.917,-.027),l(-1.758,.106),l(-.547,.206),l(-.523,.294),l(-.537,.585),l(-.205,.554),l(-.287,.335),l(-.591,.19),l(-1.07,.104),l(-.537,.147),l(-1.098,.555),l(-.774,.54),l(-.794,.612),l(-.325,.363),l(-.33,.233),l(-.868,.843),l(-.485,.566),l(-.418,.276),l(-.46,.58),l(-.518,.968),l(.749,-.737),l(.375,-.131),l(.688,-.479),l(1.059,-.944),l(1.097,-.785),l(2.028,-.948),l(1.245,-.395),l(1.797,-.512),l(1.065,-.235),l(1.03,-.235),l(1.473,-.148),l(.922,.056),l(.895,.289),l(.509,.29),l(.136,.189),l(.144,.464),l(-.125,.218),l(-.326,.219),l(-1.059,.292),l(-.753,.452),l(-.581,.044),l(-.845,-.23),l(-.726,.045),l(-.645,.19),l(.279,.08),l(1.13,.229),l(.17,.122),l(.256,.444),l(.074,.095),l(1.299,-.485),l(-.028,.216),l(.479,-.148),l(.372,.162),l(-.36,.229),l(-.231,.256),l(.112,.27),l(-.163,.014),l(-.074,.229),l(-.91,.444),l(1.216,.013),l(.077,.188),l(-.187,.282),l(.091,.43),l(.118,-.081),l(.239,.134),l(-.063,.134),l(.048,.202),l(.351,.457),l(.009,.147),l(.824,.054),l(.154,.094),l(.04,-.067),l(.727,.147),l(-.315,.134),l(-.373,-.013),l(-.047,.134),l(.525,.147),l(.211,.241),l(.569,-.081),l(.135,.134),l(.212,-.014),l(.134,.174),l(.418,-.04),l(-.075,-.107),l(.843,.067),l(.241,.107),l(-.207,.201),l(.242,-.107),l(.26,.027),l(.245,-.013),l(.696,-.362),l(.303,-.081),l(.104,.362),l(.377,.161),l(.538,-.121),l(.488,.416),l(-.405,.254),l(.089,.107),l(.825,.027),l(.164,.174),l(-.521,.121),l(-.161,-.121),l(-.3,.134),l(.118,.094),l(-.515,0),l(-.23,-.04),l(.109,.161),l(-.45,.04),l(.056,.107),l(-.443,.014),l(-.128,.147),l(-.45,.04),l(-.368,.253),l(-.09,-.106),l(-.706,.28),l(-.046,.053),l(-.529,.133),l(-.119,-.267),l(-.274,.106),l(-.163,.267),l(-.188,-.187),l(-.068,.253),l(-.218,.08),l(-.094,.187),l(-.513,0),l(-.081,-.08),l(-.169,-.053),l(.032,-.347),l(-.242,.36),l(-.202,.12),l(-.131,-.253),l(-.354,.027),l(.043,.24),l(-.233,.04),l(.312,.08),l(.033,.213),l(-.103,.12),l(-.174,-.067),l(-.768,.453),l(.127,.16),l(-.235,.12),l(-.194,.053),l(.015,.213),l(-.161,-.12),l(.083,.173),l(-.217,.08),l(-.14,-.107),l(.096,.253),l(-.222,.066),l(-.146,-.08),l(-.148,0),l(-.064,.133),l(-.156,-.106),l(-.243,.227),l(-.086,.292),l(-.201,-.226),l(-.344,.133),l(-.154,-.187),l(-.349,-.479),l(-.138,.24),l(-.419,-.866),l(.456,-.773),l(.284,-.16),l(.035,-.12),l(-.35,.12),l(-.357,.267),l(-.076,-.106),l(.924,-.507),l(.125,.146),l(.195,-.093),l(-.258,-.107),l(1.103,-.52),l(1.109,-.562),l(.658,-.361),l(.336,.094),l(-.067,.428),l(.179,-.054),l(.258,.281),l(-.044,-.201),l(-.017,-.174),l(.632,-.214),l(.73,-.134),l(.192,.067),l(.202,-.081),l(-.152,-.094),l(-.653,-.053),l(-.595,.053),l(-.42,-.053),l(-.804,-.014),l(-.306,.027),l(-.251,.081),l(-.246,.094),l(.033,-.214),l(1.128,-.563),l(.054,-.201),l(.252,-.08),l(-.052,-.174),l(-.523,.281),l(.097,-.134),l(-.502,-.51),l(.309,.443),l(-.36,.482),l(-.328,.013),l(-1.974,.817),l(-.284,.08),l(-.362,-.201),l(-.227,-.067),l(.23,.201),l(-.788,.401),l(-.219,-.174),l(-1.019,-.054),l(-.124,.147),l(-.38,-.241),M(186.193,47.833),l(-.713,-.032),l(-.922,-.181),l(-.882,-.065),l(-1.25,-.314),l(-.973,-.182),l(-.604,-.049),l(-1.083,-.199),l(.43,-.335),l(1.542,-.405),l(.385,-.186),l(.115,-.673),l(.305,-.236),l(.831,-.069),l(.743,.184),l(1.436,.603),l(1.287,.4),l(.074,.285),l(.315,.284),l(1.094,.516),l(-.288,.117),l(-1.263,.486),l(-.578,.051),M(231.09,50.646),l(-1.319,-.03),l(-.449,-.147),l(-.232,-.247),l(-.173,-.478),l(.3,-.43),l(.708,-.664),l(.662,-.267),l(1.359,-.168),l(.911,.197),l(.79,.314),l(-.021,.464),l(-.039,.727),l(-.362,.265),l(-1.025,.348),l(-1.108,.117),
+N(444.972,79.145),l(.47,-.218),l(.307,-.093),l(-.294,-.024),l(-.419,.061),l(-.15,-.135),l(-.125,.184),l(-.108,-.012),l(.066,-.491),l(.177,-.218),l(.41,.009),l(1.489,.062),l(.417,.014),l(.339,-.075),l(.121,-.253),l(-.175,-.288),l(.246,-.05),l(-.068,-.122),l(-.068,-.123),l(.353,-.096),l(.12,-.034),l(.051,.154),l(.086,.052),l(.24,0),l(.223,.12),l(.257,.069),l(.514,.068),l(.086,.103),l(.223,-.051),l(.445,0),l(.257,0),l(.223,-.017),l(.086,.137),l(.103,.103),l(.188,.034),l(.171,.069),l(.018,.137),l(.052,.12),l(-.224,.12),l(-.068,.154),l(-.068,.206),l(.018,.171),l(.034,.137),l(.029,.038),l(-2.96,.101),l(-2.246,-.115),l(-.842,-.006),M(717.633,81.109),l(.42,.443),l(.429,.62),l(.183,.457),l(.01,.767),l(-.244,.442),l(-.197,.78),l(-.002,.764),l(.29,.777),l(.592,.849),l(.65,1.446),l(.899,1.614),l(1.115,1.679),l(-1.26,-.677),l(-.832,-.39),l(-.99,-.056),l(-.268,.088),l(-.396,.204),l(-.462,1.045),l(-.266,1.101),l(-.082,.579),l(.277,.982),l(.183,.216),l(.659,.908),l(.54,.201),l(.463,.648),l(-.314,1.246),l(-.664,-1.258),l(-.866,-.301),l(-.224,.029),l(-.415,.303),l(-.311,.534),l(-.643,.907),l(-.422,-.5),l(-.19,-.929),l(.637,-1.146),l(-.395,-.884),l(.175,-.454),l(.502,-.63),l(-.131,-.723),l(-.196,-.376),l(-.27,-.55),l(-.062,-.235),l(.403,-.302),l(.284,-.915),l(.075,-.784),l(.005,-1.326),l(.15,-1.302),l(-.09,-.732),l(-.213,-.469),l(-.83,-.85),l(-.1,-.897),l(.114,-.192),l(.359,-.722),l(.065,-.738),l(-.336,-.457),l(.172,-.237),l(.374,-.03),l(.62,-.031),l(1.023,-.534),M(471.158,84.281),l(-.002,-.142),l(-.165,-.066),l(-.082,-.115),l(-.164,-.082),l(.033,-.099),l(-.033,-.23),l(-.033,-.164),l(.082,-.099),l(-.147,-.131),l(-.099,-.148),l(.132,-.066),l(0,-.165),l(-.296,-.164),l(-.279,-.263),l(-.017,-.164),l(.099,-.131),l(.131,-.165),l(.362,-.017),l(.328,.049),l(.197,.132),l(.51,.016),l(.525,-.099),l(.444,-.247),l(.049,-.065),l(.148,-.083),l(.296,0),l(.065,-.164),l(-.033,-.131),l(-.279,-.066),l(-.296,-.148),l(-.099,-.181),l(.082,-.017),l(.066,-.049),l(.032,-.065),l(-.263,-.066),l(-.361,-.099),l(-.378,-.066),l(-.361,.066),l(-.182,-.066),l(.066,-.181),l(.099,-.197),l(-.066,-.148),l(-.164,-.099),l(-.279,-.082),l(-.23,-.066),l(-.443,-.213),l(-.115,-.23),l(-.164,-.263),l(-.214,-.017),l(-.017,-.099),l(.066,-.131),l(.099,-.115),l(-.132,-.033),l(-.181,.049),l(-.082,-.115),l(-.132,-.181),l(-.345,-.049),l(.049,-.147),l(.033,-.165),l(.099,-.049),l(.115,-.082),l(0,-.083),l(.114,0),l(.066,-.131),l(-.05,-.164),l(-.147,-.099),l(-.197,-.247),l(.131,-.165),l(.033,-.164),l(0,-.083),l(.065,-.115),l(-.049,-.115),l(-.147,.033),l(-.165,-.033),l(-.147,-.099),l(-.099,-.099),l(-.279,-.099),l(-.132,-.131),l(-.542,-.115),l(-.247,.049),l(-.099,-.049),l(-.131,-.049),l(-.23,.083),l(-.147,.099),l(-.165,0),l(-.279,.016),l(-.214,.197),l(-.197,0),l(-.164,-.148),l(-.065,-.148),l(.017,-.099),l(.164,-.099),l(0,-.115),l(-.147,-.017),l(-.296,-.065),l(-.312,-.049),l(-.361,.049),l(-.214,.065),l(-.197,.033),l(-.082,-.148),l(-.132,-.148),l(-.312,-.033),l(-.181,-.016),l(-.197,.131),l(-.229,-.066),l(-.165,-.147),l(.061,-.042),l(.015,-.117),l(.044,-.087),l(-.088,-.233),l(.015,-.189),l(-.131,-.117),l(.059,-.087),l(-.16,-.043),l(-.146,-.102),l(-.029,-.16),l(-.131,-.058),l(-.116,-.102),l(.043,-.073),l(.059,-.087),l(-.073,-.044),l(-.087,-.014),l(-.131,-.073),l(-.146,.015),l(-.204,.059),l(.044,-.102),l(.102,-.073),l(.073,-.087),l(-.029,-.117),l(.072,-.131),l(-.131,-.087),l(.103,-.029),l(.087,-.015),l(.102,-.073),l(.015,-.087),l(.029,-.116),l(.015,-.087),l(-.204,-.058),l(-.087,-.073),l(-.204,-.087),l(-.232,-.073),l(0,-.117),l(.015,-.116),l(-.37,.004),l(-.081,-.106),l(.116,-.058),L(461.402,72),l(.029,-.117),l(.131,0),l(.087,-.116),l(.059,-.102),l(.16,-.058),l(.262,-.043),l(.175,-.073),l(-.059,-.059),l(-.175,-.043),l(-.043,-.146),l(-.015,-.087),l(0,-.073),l(-.088,-.073),l(-.203,-.087),l(-.175,-.233),l(0,-.175),l(.175,-.131),l(-.029,-.16),l(-.073,-.189),l(-.131,-.437),l(-.029,-.16),l(.088,-.16),l(.204,-.131),l(.319,-.131),l(.219,-.204),l(.175,-.277),l(.058,-.131),l(.088,-.043),l(.116,0),l(.189,0),l(.175,-.044),l(.043,-.174),l(-.16,-.131),l(-.145,-.053),l(-.089,-.13),l(-.17,-.038),l(.1,-.253),l(.339,-.038),l(.153,.165),l(.229,.063),l(.188,-.088),l(-.094,-.139),l(.301,-.154),l(.485,.199),l(.296,-.062),l(.312,-.338),l(.311,-.185),l(.75,.106),l(.781,.275),l(.439,0),l(.363,-.154),l(-.386,-.399),l(-.59,-.323),l(-.393,-.03),l(-1.204,.08),l(-.616,-.091),l(-.271,-.108),l(-.299,-.309),l(.258,-.434),l(-.065,-.201),l(-.199,.044),l(.174,-.285),l(1.946,-1.145),l(1.983,-1.195),l(1.385,-.758),l(.591,-.536),l(.43,-.536),l(.105,-.409),l(-.161,-.346),l(-.436,-.392),l(-.703,-.265),l(-1.357,-.499),l(-.439,-.33),l(.327,-.191),l(.542,-.415),l(.057,-.254),l(-.151,-.253),l(-1.286,-1.395),l(-.37,-.509),l(.029,-.37),l(.187,-.403),l(.44,-.535),l(.196,-.356),l(-.772,-1.195),l(-1.402,-1.394),l(.328,-.296),l(1.303,-.777),l(.421,-.364),l(-.543,-.392),l(-.964,-.506),l(-.872,-.194),l(-.563,-.212),l(-.116,-.529),l(.258,-.465),l(.024,-.283),l(.689,-.303),l(1.013,-.672),l(1.023,-.49),l(.77,-.121),l(.824,-.021),l(.514,-.204),l(.404,-.288),l(.617,-.051),l(1.002,-.254),l(.643,-.237),l(.01,.151),l(.255,.386),l(.358,.284),l(.543,.2),l(.919,.082),l(.602,.1),l(.078,.602),l(.695,-.319),l(.421,.049),l(1.083,.048),l(.875,.015),l(.522,.032),l(1.116,-.002),l(1.293,.281),l(2.728,.512),l(.984,.364),l(1.595,.86),l(.583,.214),l(1.48,.246),l(1.296,.212),l(2.018,.623),l(.328,.279),l(-.051,.444),l(.147,.295),l(.426,.294),l(.104,.294),l(-.24,.344),l(-.69,.491),l(-1.092,.54),l(-.816,.262),l(-1.75,.36),l(-.907,.083),l(-1.631,-.013),l(-1.391,-.192),l(-2.038,-.175),l(-1.63,-.192),l(-1.342,-.339),l(-2.256,-.485),l(-1.114,-.112),l(-.476,-.048),l(-.621,-.473),l(-.371,-.163),l(-.771,-.13),l(-.943,.117),l(.307,.163),l(.149,.065),l(.73,.538),l(.482,.146),l(1.109,.601),l(.832,.291),l(.921,.161),l(.634,.242),l(.405,.453),l(-.002,.405),l(-.276,.291),l(-.684,.195),l(.086,.113),l(.208,.531),l(.771,.943),l(.093,.494),l(.155,.207),l(.438,.174),l(1.203,.078),l(.872,.125),l(.499,.619),l(.401,.095),l(1.26,.077),l(.575,.126),l(.364,.079),l(.402,-.128),l(.785,-.097),l(.243,-.302),l(-.001,-.318),l(-.387,-.397),l(-.471,-.079),l(-.455,.096),l(-.447,-.031),l(-.589,-.206),l(-.952,-.795),l(.701,-.674),l(.484,-.001),l(1.116,.479),l(1.441,.333),l(2.09,.427),l(.952,.078),l(.834,-.146),l(.723,.174),l(.261,-.224),l(.05,-.415),l(-.214,-.239),l(-.858,-.656),l(-.348,-.628),l(.285,-.323),l(.19,-.049),l(1.432,-.423),l(1.495,-.359),l(.599,-.244),l(1.133,-.717),l(.172,-.049),l(.462,.064),l(1.829,.29),l(1.41,.533),l(.341,-.001),l(.052,-.065),l(.154,-.503),l(.581,-.767),l(-.048,-.653),l(-.317,-.408),l(-.847,-.163),l(-.3,-.229),l(1.139,-1.005),l(.101,-.247),l(-.205,-.594),l(-.771,-.512),l(.069,-.315),l(.353,-.051),l(1.458,.23),l(2.025,-.12),l(.631,.132),l(.664,.611),l(.616,.445),l(.433,.461),l(-1.045,.051),l(-1.559,.085),l(-.822,.215),l(-.492,.51),l(.191,.18),l(.952,.293),l(.732,.555),l(.804,.194),l(.723,.097),l(1.268,-.133),l(1.33,-.084),l(.301,-.164),l(.257,-.491),l(.291,-.591),l(.284,-.412),l(1.232,-.2),l(1.223,-.414),l(.988,-.216),l(1.924,-.483),l(1.429,-.251),l(1.537,-.318),l(.921,-.3),l(.205,.464),l(.278,.083),l(.571,-.117),l(.487,-.266),l(.148,-.465),l(.386,-.167),l(.718,-.135),l(.859,.065),l(-.18,.399),l(-.058,.597),l(-.858,.084),l(-.178,.149),l(.002,.215),l(.687,.197),l(.507,-.083),l(1.169,-.167),l(.436,-.001),l(.161,.198),l(.23,.049),l(.278,-.133),l(.264,-.216),l(.29,-.431),l(.464,-.183),l(.861,-.118),l(1.049,-.068),l(.768,.032),l(1.075,.23),l(.755,-.018),l(.36,-.083),l(.963,-.467),l(1,-.285),l(.803,-.052),l(.952,.182),l(.326,.166),l(-.631,.45),l(.129,.232),l(.217,.099),l(.632,.131),l(.579,-.018),l(.288,-.232),l(.074,-.398),l(.342,-.084),l(.962,.065),l(.543,-.184),l(.395,-.316),l(.115,-.417),l(-1.37,-1.033),l(.405,-.168),l(.66,-.37),l(.403,-.068),l(.609,.016),l(2.171,.063),l(1.272,.199),l(1.241,.149),l(1.135,.199),l(2.111,.515),l(1.071,.098),l(1.712,.414),l(1.02,.248),l(1.305,.53),l(1.455,.611),l(.864,.379),l(.376,.049),l(.229,-.1),l(1.145,-1.047),l(.236,-.3),l(-.927,.035),l(-.4,-.049),l(-.564,-.232),l(-.365,-.433),l(.027,-.652),l(-.727,-.283),l(-1.987,-.147),l(-.19,-.268),l(.064,-.168),l(.305,-.303),l(.693,-.255),l(.236,-.153),l(.085,-.187),l(-.052,-.833),l(-.251,-.238),l(-1.135,-.066),l(-.232,-.29),l(.328,-.532),l(.359,-.241),l(.391,-.035),l(1.482,-.416),l(1.098,-.485),l(.521,-.416),l(.581,-.608),l(.544,-1.22),l(.637,-.421),l(.374,.069),l(1.562,.155),l(1.613,-.125),l(1.605,-.091),l(.695,.069),l(1.066,-.055),l(.574,.122),l(.309,.279),l(-.018,.332),l(-.423,.836),l(-.348,.348),l(-1.334,.833),l(-.223,.345),l(.752,.342),l(.931,.667),l(.277,.342),l(.21,.818),l(-.174,.222),l(-.575,.375),l(.254,1.179),l(-.058,1.305),l(.263,.583),l(.45,.381),l(1.027,.264),l(.19,.166),l(-.001,.133),l(-.485,.481),l(-.417,.826),l(-.333,.33),l(-.784,.462),l(-1.232,.625),l(-.63,.198),l(-.55,.263),l(.321,.522),l(-.433,.115),L(558,52.195),l(-1.599,-.372),l(-.731,-.08),l(-.97,.034),l(-.601,.115),l(.195,.31),l(.583,.276),l(.738,.21),l(1.569,.208),l(1.133,.079),l(.613,-.05),l(1.188,.144),l(.922,-.034),l(.472,-.358),l(.303,-.358),l(1.352,-.328),l(1.166,-.492),l(.268,-.278),l(.386,-.606),l(.818,-.313),l(.864,-.626),l(.064,-.362),l(-.225,-.561),l(-.609,-.545),l(.244,-.548),l(.237,-.1),l(.677,-.151),l(1.38,-.152),l(1.757,-.003),l(.74,.231),l(.842,.463),l(.151,.778),l(-.34,1.023),l(.302,.279),l(.92,.212),l(1.298,.047),l(.864,-.149),l(.129,-.296),l(-.514,-.18),l(-.797,-.18),l(-.571,.034),l(-.457,-.098),l(.068,-.379),l(1.03,-.382),l(.065,-.249),l(-.218,-.148),l(-.166,-.331),l(-.441,-.763),l(-.511,-.266),l(-.836,-.098),l(-1.093,-.231),l(-.801,-.116),l(-1.288,-.165),l(-.91,.186),l(-.638,.101),l(-1.297,-.181),l(-.896,.019),l(-.015,-.267),l(-.564,-1.071),l(.305,-.657),l(.736,-.697),l(.282,-.46),l(-.134,-.221),l(-1.092,-1.042),l(-.949,-.514),l(-.12,-.189),l(.833,-.554),l(1.213,-.106),l(.998,-.262),l(.744,-.348),l(.172,-.226),l(.169,-.644),l(-.13,-.663),l(.23,.069),l(.64,.051),l(.466,.086),l(.108,.471),l(-.186,.54),l(-.636,.608),l(-.167,.554),l(.14,.448),l(.373,.274),l(.485,.274),l(1.384,.134),l(1.574,.169),l(1.632,.083),l(.819,.409),l(.321,.017),l(.799,-.036),l(-.527,-.89),l(-.521,-.274),l(-1.893,-.1),l(-.931,-.067),l(-.576,-.154),l(-.609,-.448),l(.275,-.329),l(1.374,-.054),l(.444,.172),l(1.145,.084),l(.747,-.157),l(-.09,-.728),l(.408,-.088),l(.84,-.105),l(1.278,-.02),l(1.067,.207),l(1.413,.379),l(1.088,.535),l(1.326,.343),l(.547,.085),l(1.822,.014),l(.727,-.174),l(.138,.345),l(-.781,.38),l(-.696,.259),l(-.248,.771),l(-.129,.972),l(.333,.136),l(.68,-.785),l(.387,-.292),l(.285,.051),l(.604,.528),l(-.088,.749),l(.743,-.205),l(.681,-.273),l(-.044,-.306),l(-.191,-.119),l(-.147,-.358),l(-.748,-.821),l(.188,-.223),l(.686,-.759),l(-.797,-.448),l(-.772,-.258),l(-.93,-.241),l(-.257,-.382),l(-.655,-.051),l(-.979,-.242),l(-1.34,-.207),l(-.307,-.296),l(.062,-.577),l(-.096,-.386),l(-.811,-.667),l(.081,-.247),l(.266,-.16),l(.484,-.125),l(2.31,-.11),l(2.54,-.022),l(2.125,-.128),l(1.421,-.162),l(.475,.317),l(.382,.052),l(.844,-.267),l(1.056,-.286),l(1.413,-.109),l(.589,.194),l(-.957,.338),l(-.451,.407),l(1.737,-.233),l(.521,-.107),l(.955,-.374),l(.27,-.284),l(-.334,-.444),l(-.326,-.177),l(-.925,-.266),l(-.365,-.303),l(-.002,-.232),l(.324,-.539),l(1.176,-.397),l(.966,-.22),l(3.028,-.903),l(.889,-.094),l(.248,-.036),l(.522,-.076),l(1.899,-.096),l(1.663,-.114),l(2.302,-.244),l(2.048,-.263),l(1.595,-.43),l(.855,-.243),l(1.763,.034),l(1.065,-.002),l(.383,.185),l(-.351,.409),l(1.504,.108),l(1.018,-.039),l(1.261,-.188),l(1.345,-.225),l(.95,-.039),l(.982,.166),l(.687,.073),l(.693,-.206),l(.12,-.335),l(-.133,-.167),l(.466,-.337),l(.942,-.077),l(.939,.036),l(1.243,-.377),l(-.618,-.506),l(.122,-.34),l(1.165,-.438),l(1.554,-.383),l(2.23,-.406),l(1.229,-.077),l(.993,.056),l(1.486,-.003),l(.86,.265),l(.045,.266),l(-1.528,.401),l(-.66,.342),l(.488,.15),l(1.83,-.117),l(1.588,.148),l(2.039,-.079),l(.177,.113),l(-.375,.283),l(-1.187,.453),l(-.296,.3),l(1.971,-.004),l(.833,-.02),l(.234,.093),l(1.052,-.545),l(1.366,-.002),l(1.771,-.097),l(.631,.13),l(1.35,-.021),l(1.954,.165),l(1.4,.259),l(1.181,.427),l(.52,.445),l(.726,-.001),l(.854,-.076),l(.422,.5),l(-1.354,.832),l(.241,.128),l(.896,.365),l(-2.329,.859),l(-1.035,.235),l(-1.166,.11),l(-3.404,1.061),l(-3.018,.965),l(-.793,.285),l(-2.388,.375),l(-2.35,.586),l(-2.065,1.126),l(.715,.017),l(1.081,-.247),l(.922,-.458),l(1.663,-.161),l(1.231,-.02),l(2.101,-.268),l(1.879,-.286),l(.879,-.107),l(1.004,-.284),l(-.094,-.389),l(-.492,-.123),l(-.034,-.071),l(.281,-.249),l(.581,-.214),l(.873,.211),l(.603,.389),l(.621,.052),l(.593,.193),l(.737,.052),l(.853,-.055),l(1.155,-.268),l(.499,.07),l(.192,.3),l(.009,.512),l(.522,.404),l(1.422,-.778),l(1.66,-.021),l(1.506,-.145),l(2.354,.014),l(1.919,.155),l(.854,.034),l(1.204,.033),l(-.271,.74),l(.354,.333),l(2.043,.154),l(.848,.121),l(.698,.069),l(1.035,.103),l(2.49,-.145),l(1.209,-.02),l(1.42,.348),l(1.405,-.932),l(-.161,-.352),l(-.038,-.229),l(-.034,-.105),l(1.806,-.48),l(.521,-.019),l(.802,.104),l(1.148,.298),l(.851,.281),l(1.711,.032),l(1.354,-.073),l(1.384,.033),l(1.323,.431),l(.409,.181),l(.058,.386),l(-.52,.088),l(-.268,.036),l(-1.905,.406),l(-2.438,.737),l(-.233,.227),l(.253,.069),l(1.033,.067),l(.957,.016),l(.659,.155),l(.659,.293),l(1.014,.396),l(.583,.172),l(.78,.481),l(1.27,.805),l(1.814,.801),l(1.351,.305),l(.612,-.018),l(.795,-.394),l(.843,-.72),l(1.093,-1.051),l(.601,-.329),l(.29,.017),l(.236,.465),l(.772,.308),l(1.346,.29),l(1.105,.135),l(.848,-.087),l(1.973,-.468),l(.778,-.07),l(.813,.067),l(1.196,.239),l(1.921,.734),l(.315,-.052),l(.186,-.069),l(.491,-.258),l(.221,-.258),l(-.137,-.051),l(.013,-.189),l(.726,-.312),l(.509,-.018),l(.5,.257),l(.575,.188),l(1.302,.032),l(.181,-.5),l(-.194,-.466),l(.15,-.363),l(.093,-.521),l(-1.131,.159),l(-.643,.001),l(-.179,-.104),l(.442,-.296),l(.318,-.087),l(.986,-.089),l(1.021,-.02),l(.832,-.141),l(1.566,-.648),l(.254,0),l(1.76,.241),l(1.561,.137),l(2.036,.188),l(.997,.068),l(.654,.103),l(2.307,.065),l(-1.732,.628),l(.865,.051),l(1.011,-.089),l(.335,.138),l(-.305,.381),l(-.926,.192),l(-.846,.261),l(-.177,.293),l(.664,.033),l(.52,-.122),l(.916,-.14),l(.978,-.33),l(1.62,-.799),l(2.766,.012),l(1.196,.067),l(.903,.172),l(.946,.137),l(.205,.19),l(.221,.104),l(-2.247,.59),l(.559,.137),l(1.674,.289),l(2.174,.202),l(.946,.204),l(.801,.375),l(.367,.427),l(.564,.357),l(.522,.152),l(1.459,-.037),l(1.364,-.105),l(1.138,-.139),l(2.518,-.329),l(2.208,-.107),l(3.008,.131),l(1.515,.134),l(.734,.118),l(1.168,.424),l(.655,.169),l(.525,.338),l(.361,.39),l(-.123,.491),l(-.286,.521),l(.509,.25),l(.764,.065),l(.835,.015),l(.643,.083),l(-.017,.685),l(.419,.416),l(.686,-.168),l(.545,-.435),l(1.211,-.387),l(.348,-.067),l(.35,.049),l(1.696,-.02),l(1.521,-.288),l(.736,.032),l(.588,.434),l(.707,.116),l(1.541,.014),l(2.176,.062),l(.869,-.118),l(1.378,-.504),l(.406,.2),l(.93,.533),l(.396,.216),l(1.095,.265),l(.875,.332),l(.282,.398),l(.612,.148),l(1.556,-.136),l(1.653,-.319),l(.16,-.25),l(-.248,-.333),l(-.805,-.833),l(-.833,-.115),l(.4,-.336),l(.479,-.571),l(1.89,.098),l(1.214,.082),l(1.135,.065),l(1.221,.166),l(.222,.318),l(1.396,-.153),l(2.084,-.054),l(2.304,.013),l(1.292,.148),l(.786,.199),l(1.185,.199),l(1.391,.098),l(.751,.182),l(1.302,.332),l(.747,.065),l(.703,.182),l(1.145,.505),l(0,2.126),l(0,2.222),l(0,2.222),l(0,1.292),l(0,.157),l(0,.576),l(0,.219),l(-1.083,.371),l(-.651,.03),l(-.645,.37),l(-.56,.065),l(-1.044,.065),l(-.355,-.079),l(-.928,-.052),l(-.118,-.343),l(-.271,-.211),l(-.501,.027),l(.241,-.185),l(-.938,.324),l(-.846,.02),l(-.337,-.211),l(-.478,-.079),l(.424,.501),l(-.569,.29),l(.32,.103),l(.942,.205),l(.634,-.36),l(.395,.041),l(.335,.079),l(0,.477),l(.248,.206),l(.76,.269),l(1.059,-.228),l(-.439,.322),l(.741,-.243),l(.065,.336),l(.247,.206),l(.187,.363),l(.068,.189),l(-.722,.522),l(.593,-.064),l(.349,.172),l(.473,.503),l(.501,.157),l(.145,.251),l(-.162,.456),l(.792,-.111),l(-.125,.393),l(.023,.25),l(-.43,.299),l(-.691,.205),l(-.635,-.046),l(-.448,-.14),l(-1.243,-.154),l(-.889,-.077),l(-.347,-.14),l(.123,-.267),l(-.493,-.046),l(-.304,.032),l(-.559,.55),l(-.069,.11),l(-3.06,.913),l(-1.155,.174),l(-.245,0),l(-.43,.203),l(-.219,.188),l(-.719,.22),l(-.991,.033),l(-.308,.11),l(-.48,.405),l(-.462,.203),l(-.946,.033),l(-.854,.622),l(-.24,.279),l(-1.67,.452),l(-.392,.449),l(-1.229,.25),l(-.406,.14),l(-.151,.293),l(.01,.292),l(-.473,.292),l(-.406,.016),l(-.586,-.306),l(-.183,-.262),l(-.169,-.37),l(-.67,-.308),l(-1.074,-.044),l(-1.021,.048),l(-1.159,.172),l(-1.301,.188),l(-.523,.217),l(-1.333,.756),l(-.536,.277),l(-.184,-.138),l(.575,-1.293),l(-.55,.094),l(-.392,-.097),l(-.811,.531),l(-.67,.186),l(-.401,.155),l(-.114,.506),l(-.66,.154),l(-.317,-.168),l(-.253,-.49),l(-.483,-.261),l(-1.024,.636),l(.261,-.204),l(-.557,.062),l(-.283,.092),l(-.628,.522),l(-.141,.261),l(.126,.229),l(.344,.152),l(-.932,.521),l(-.182,.199),l(.342,.167),l(-.647,.352),l(-.88,.55),l(-.626,.503),l(-.298,.35),l(-.01,.531),l(.421,.317),l(.477,.09),l(1.382,-.048),l(.562,.166),l(.11,.167),l(-.436,.394),l(-.752,.455),l(-.181,.302),l(.224,.512),l(.292,.452),l(.786,.089),l(.165,.391),l(-.014,.616),l(-.349,.361),l(-.528,.061),l(-.481,-.209),l(-.017,-.21),l(.388,-.527),l(-.444,-.014),l(-.454,.242),l(-1.014,.843),l(-.56,.675),l(-.237,.599),l(.321,.672),l(.647,.311),l(.154,.237),l(-.294,.387),l(-.688,.313),l(-.956,.031),l(-.664,-.088),l(-.344,.001),l(-.619,.179),l(-.837,.476),l(-.214,.149),l(-.525,.504),l(-.137,.341),l(.111,.281),l(.492,.398),l(.038,.221),l(-.056,.133),l(-.679,.238),l(-.604,.016),L(753.44,82.4),l(-.727,.296),l(-.065,.251),l(.067,.28),l(-.161,.854),l(-.293,.412),l(-.8,.78),l(-1.53,.971),l(-.854,.5),l(-.285,.103),l(-.295,-.614),l(-.198,-.821),l(-.25,-.69),l(-.064,-.794),l(-.351,-.75),l(-.305,-.383),l(-.214,-.915),l(-.514,-1.36),l(-.008,-.578),l(-.154,-.563),l(-.017,-.327),l(-.105,-.193),l(-.262,-.817),l(-.026,-.792),l(.116,-.808),l(.271,-1.396),l(.167,-.226),l(1.185,-.86),l(.716,-.424),l(.57,-.695),l(.14,-.227),l(-.085,-.318),l(-.139,-.166),l(1.632,-.367),l(1.001,-.305),l(.811,-.32),l(1.729,-.884),l(.641,-.412),l(.431,-.428),l(.14,-.335),l(1.784,-.889),l(.872,-.445),l(1.535,-.861),l(.368,-.293),l(.26,-.433),l(1.252,-.435),l(2.106,-.514),l(.257,-.434),l(.773,-.528),l(.086,-.233),l(-.568,-.216),l(.814,-.904),l(-.036,-.483),l(.183,-.391),l(.598,-.204),l(1.729,-.082),l(.513,-.063),l(-.485,-.328),l(-2.065,-.215),l(-.71,.095),l(-1.062,.174),l(-.777,.189),l(.042,.328),l(-.664,.923),l(.125,.202),l(-.04,.14),l(-.662,.11),l(-.479,.11),l(-1.555,.718),l(-1.979,1.042),l(-1.169,.342),l(-.249,-.062),l(.156,-.325),l(.352,-.465),l(-.933,-.076),l(-.16,-.263),l(.252,-.451),l(.442,-.467),l(.207,-.328),l(-.069,-.202),l(-.339,-.031),l(-1.136,.454),l(-.496,.032),l(-.277,-.358),l(-.589,-.17),l(-1.606,.144),l(-1.312,.111),l(-.956,.08),l(-.606,.157),l(-.894,.359),l(-.093,.436),l(.082,.186),l(-1.262,.53),l(-.408,.233),l(.149,.495),l(-1.294,.357),l(-1.019,.434),l(-.84,.479),l(-.496,.461),l(-.332,.46),l(.004,.383),l(.527,.213),l(1.269,.043),l(.278,.275),l(.062,.122),l(-1.152,.139),l(-1.028,.262),l(-1.045,-.059),l(-.698,-.136),l(-.382,.031),l(-.311,.107),l(-.721,.398),l(-.695,-.35),l(-1.112,.383),l(-.747,.139),l(-.487,-.09),l(-.284,-.137),l(.108,-.29),l(.748,-.124),l(.868,-.124),l(.164,-.046),l(-.741,-.64),L(736.444,68),l(-1.06,.017),l(-.854,.155),l(-.353,-.061),l(-.868,-.458),l(-.775,-.029),l(-.745,.047),l(-.704,.246),l(.042,.398),l(-.26,.229),l(-.477,.215),l(-.695,-.243),l(-.408,-.122),l(-1.26,.063),l(-.784,.093),l(-.651,-.075),l(-.887,-.136),l(-.563,.078),l(-.067,.122),l(-.147,.474),l(-.677,.017),l(-.311,-.137),l(-.038,-.382),l(-.203,-.259),l(-1.241,.094),l(-1.014,-.059),l(-1.257,.033),l(-1.158,.063),l(-.836,-.029),l(-.18,.016),l(-1.085,.292),l(-.964,.444),l(-.74,.474),l(-.536,.504),l(-.789,.245),l(-.904,.336),l(-.194,.152),l(-1.047,1.17),l(-1.634,.684),l(-.949,.471),l(-1.157,.711),l(-1.653,1.253),l(-.828,.572),l(-1.573,.873),l(-.893,.376),l(-1.889,.871),l(-.632,.388),l(-.203,.298),l(.018,.357),l(.428,.281),l(.485,.043),l(.918,.013),l(1.046,-.15),l(.656,.043),l(-.329,1.261),l(.016,.415),l(.303,.103),l(.63,-.09),l(.601,-.371),l(.761,.117),l(-.127,.148),L(705.293,81),l(-.112,.222),l(.373,.073),l(1.645,-.018),l(.566,-.238),l(.39,-.519),l(.017,-.638),l(.763,.014),l(.647,-.001),l(.726,.014),l(.951,.265),l(.658,.354),l(.486,.591),l(.847,.575),l(.426,.176),l(.506,.324),l(-.07,.148),l(-.581,.355),l(.453,.221),l(.13,.309),l(-.336,.723),l(.491,.117),l(.215,.235),l(-.291,.515),l(-.348,.397),l(-.532,.559),l(-.724,1.364),l(-.181,.688),l(.057,.219),l(.24,.701),l(-.188,.917),l(-.098,.741),l(-.403,1.408),l(-.146,.493),l(-1.928,1.538),l(-.371,.435),l(-.217,.65),l(-.587,.42),l(-.741,.579),l(-.241,.361),l(-.574,.981),l(-.587,.606),l(-.941,.778),l(-1.784,1.512),l(-.464,.474),l(-.235,.458),l(-.323,.33),l(-.758,.388),l(-.618,.416),l(-.574,.702),l(-.431,.458),l(-.875,.673),l(-.955,.487),l(-1.838,.475),l(-.798,.244),l(-.278,-.427),l(-.519,-.085),l(-.243,.043),l(-.337,-.185),l(-.337,-.513),l(-.663,.272),l(-.464,.101),l(.424,-.586),l(-.624,.173),l(-.506,.486),l(-.649,.543),l(-1.326,1.001),l(-.072,.049),l(-.167,-.393),l(-.298,-.439),l(.111,-.058),l(1.252,-.462),l(.511,-.43),l(.156,-.329),l(-.112,-.299),l(.097,-.128),l(.025,-.385),l(.006,-.613),l(-.062,-.656),l(-.332,-.897),l(.048,-.557),l(1.664,-.982),l(.396,.041),l(.685,.24),l(.679,.225),l(.547,.098),l(.47,-.347),l(.551,-.69),l(.329,-.432),l(.627,-1.08),l(.538,-1.066),l(.278,-.893),l(.291,-.707),l(.66,-.393),l(.566,-.407),l(-.017,-.504),l(-.116,-.389),l(-.064,-.259),l(-.246,-.114),l(-.902,.034),l(-1.181,.208),l(-1.357,.31),l(-.953,.308),l(-.604,.22),l(-1.657,.052),l(-.649,.018),l(-.68,.033),l(-.261,-.446),l(-.44,-1.283),l(-.297,-.866),l(-.205,-.144),l(-2.659,-.839),l(-1.523,-.253),l(-1.247,-.341),l(-.507,-.2),l(-.436,-.389),l(-.927,-1.903),l(-.94,-1.588),l(-1.087,-2.384),l(-.742,-.952),l(-.763,-.467),l(-.539,-.026),l(-1.386,.125),l(-.683,-.188),l(-1.037,-.481),l(-1.148,-.215),l(-.917,.049),l(-1.203,.109),l(-.836,.123),l(-1.854,.143),l(-.602,.136),l(-.478,.165),l(-1.193,.787),l(-.375,.282),l(-.119,.25),l(.822,-.078),l(.558,.026),l(.465,.306),l(.107,.249),l(-.167,.794),l(-1.371,.608),l(-.599,.545),l(-.667,.779),l(-.416,.543),l(-.422,.426),l(-.103,.249),l(.062,.146),l(.35,.348),l(.056,.306),l(-.123,.233),l(-.779,.339),l(-2.44,.752),l(-.438,.089),l(-.343,.016),l(-1.126,-.574),l(-.452,-.172),l(-.046,-.018),l(-.431,-.168),l(-.622,.018),l(-1.228,.297),l(-.86,-.169),l(-.34,-.129),l(-.751,-.506),l(-.74,-.156),l(-.609,.047),l(-.333,.002),l(-1.165,.487),l(-.755,.498),l(-.447,.394),l(-.604,.264),l(-.526,.163),l(-1.147,.136),l(-.867,.106),l(-.532,.075),l(-1.018,.063),l(-1.602,.11),l(-.739,-.039),l(-.984,-.082),l(-.905,-.241),l(-1.318,-.254),l(-.812,-.373),l(-1.132,-.313),l(-.623,-.331),l(-1.333,-.75),l(-.769,-.229),l(-1.423,-.022),l(-1.172,-.037),l(-.796,.077),l(-2.48,.538),l(-.673,-.113),l(-1.643,-.531),l(-.421,-.333),l(-.408,-.451),l(-.182,-.481),l(-.004,-.541),l(-.145,-.204),l(-.767,-.143),l(-.989,-.317),l(-.702,-.231),l(-1.748,-.328),l(-1.036,-.185),l(-1.028,-.098),l(-.84,-.201),l(-1.269,.96),l(-.905,.839),l(-.098,.293),l(.409,.86),l(.396,.304),l(.116,.204),l(-.163,.526),l(-.744,.572),l(-.31,.162),l(-.755,.28),l(-.562,.018),l(-.576,-.186),l(-.312,-.114),l(-.875,-.068),l(-.85,.004),l(-.719,-.083),l(-1.458,.008),l(-.699,-.113),l(-.393,-.406),l(-.694,-.755),l(-.831,-.083),l(-1.842,-.122),l(-.932,-.156),l(-.953,-.097),l(-.84,.18),l(-1.512,.476),l(-1.143,.341),l(-.787,.398),l(-.971,.692),l(-.017,.012),l(-.727,.381),l(-.603,.148),l(-1.387,.08),l(-.599,.207),l(-.799,.425),l(-.154,.044),l(-.244,.074),l(-.569,.003),l(-.228,.014),l(-.064,-.145),l(-.589,0),l(-.294,-.478),l(-.441,-.331),l(.073,-.331),l(-.625,.184),l(-.478,.368),l(-.993,-.074),l(-.882,-.073),l(-.662,-.699),l(-.588,-.552),l(-.956,-.147),l(-.331,-.625),l(-.772,-.588),l(-.698,-.441),l(-.993,.037),l(-.771,.221),l(-.993,.221),l(-.992,0),l(-.589,0),l(-.184,-.184),l(-.258,-.257),l(-.478,0),l(0,-.368),l(-.367,-.331),l(-.92,0),l(-.367,.515),l(-.331,.257),l(-.515,.257),l(-1.104,-1.434),l(-.846,-.882),l(-1.69,-2.133),l(-1.066,-1.029),l(-1.287,-.772),l(-.809,-.294),l(-1.104,-.588),l(.11,-.368),l(.515,-.11),l(0,-.441),l(-.809,.074),l(-.515,.22),l(-.772,.221),l(-.956,.515),l(-1.103,.257),l(-.772,.441),l(-.294,.294),l(-.552,-.184),l(-.441,-.037),l(-.771,.073),l(-.441,.11),l(-.331,-.184),l(.331,-.441),l(.441,-.184),l(.146,-.294),l(-.367,0),l(-.441,.221),l(-.478,-.11),l(-.405,-.294),l(-.478,-.037),l(-.184,.147),l(-.147,.147),l(-.367,-.221),l(-.295,-.368),l(-.294,-.11),l(-.331,.221),l(-.367,-.074),l(-.368,.147),l(-.44,-.11),l(-.295,.147),l(-.478,-.074),l(-.184,-.257),l(.33,-.037),l(-.073,-.331),l(.147,-.257),l(.11,-.331),l(-.515,-.22),l(-.147,-.221),l(.037,-.331),l(-.368,-.404),l(-.882,.037),l(-.625,.11),l(-.772,-.257),l(-.515,-.11),l(-.919,-.147),l(-.735,.037),l(-.11,.221),l(-.589,.184),l(-.515,.037),l(0,.294),l(-.367,.368),l(-.625,.074),l(-1.876,.073),l(-2.021,.405),l(-1.177,.037),l(-.625,.331),l(-.221,.331),l(-.331,-.073),l(-.588,.073),l(-1.545,.11),l(-.735,.11),l(-1.029,.037),l(-1.396,.405),l(-.368,.184),l(-.772,0),l(-.515,0),L(537.304,80),l(-.33,.074),l(-.185,.515),l(.074,.441),l(.294,.221),l(-.294,.074),l(0,.331),l(1.065,.11),l(.956,.294),l(-.11,.257),l(-.515,.073),l(-1.103,-.147),l(-.698,.184),l(-.662,.515),l(.146,.257),l(.441,.478),l(-.331,.294),l(-.588,.147),l(-.735,.368),l(-.467,.067),l(.164,.274),l(.239,0),l(.377,.137),l(-.068,.171),l(.377,.137),l(.651,.069),l(.274,.308),l(1.165,.171),l(.24,.24),l(-.138,.686),l(-.137,.309),l(-1.577,.411),l(-.959,-.034),l(-.343,-.343),l(-.24,0),l(-.171,.309),l(-.651,.343),l(-.411,-.171),l(-.754,-.137),l(-.926,-.309),l(-.274,-.548),l(-.754,-.103),l(-1.062,.103),l(-.137,.412),l(-.617,.068),l(-.651,-.411),l(-.65,-.035),l(-.823,-.068),l(-.514,.377),l(-.377,.343),l(-.274,.274),l(-.686,.171),l(-.411,-.24),l(-.686,-.137),l(-.582,-.548),l(-.72,-.068),l(.034,.24),l(.205,.48),l(-.239,.274),l(-.274,-.137),l(-.068,-.583),l(-.411,-.274),l(-.789,-.343),l(-.582,-.206),l(0,-.343),l(-.96,-.171),l(-.617,.069),l(-.788,-.035),l(-.411,-.514),l(-.411,-.069),l(-.617,.24),l(-.273,.137),l(-.651,.137),l(-.309,-.274),l(-.479,0),l(-.651,-.069),l(-.515,.309),l(-.548,.343),l(-.788,.377),l(-.549,.068),l(-.514,.171),l(-.309,.309),l(-.172,.24),L(509.58,87.5),l(-.479,.206),l(.068,.445),l(.171,.411),l(-.068,.446),l(-.411,.24),l(-.651,0),l(-.514,-.411),l(-.48,-.548),l(-.514,-.24),l(-.411,.069),l(-.103,.308),l(-.343,.549),l(-.823,.137),l(-.205,1.303),l(.343,.171),l(.239,.274),l(-.239,.206),l(-.446,.274),l(-.65,1.165),l(1.37,.343),l(.138,.377),l(-.068,.309),l(.514,.514),l(.103,-.343),l(.583,.206),l(.343,-.034),l(.514,.034),l(.515,.445),l(.479,.206),l(.343,.514),l(.96,1.131),l(-.138,.103),l(-.445,-.103),l(-.309,-.103),l(-.343,.103),l(.068,.308),l(.857,.377),l(.616,.19),l(-.167,.2),l(-.399,.28),l(-.38,.12),l(-.12,0),l(0,.14),l(0,.22),l(-.14,.08),l(-.3,-.2),l(-.34,.2),l(-.399,.26),l(-.64,.12),l(-.319,.08),l(-.26,-.08),l(-.181,-.08),l(-.1,.04),l(-.06,.16),l(.12,.26),l(-.221,.2),l(-.18,.3),l(-.18,.319),l(-.319,.42),l(-.18,.28),l(-.32,.16),l(-.34,.24),l(-.14,.32),l(.08,.2),l(.34,.2),l(.319,.04),l(.18,.3),l(.24,.04),l(.239,.34),l(.28,.419),l(-.06,.38),l(-.101,.2),l(.061,.16),l(.1,-.2),l(.1,-.34),l(.12,-.22),l(.16,-.02),l(-.141,.439),l(-.22,.36),l(.061,.4),l(.12,.1),l(-.16,.2),l(-.04,.4),l(.38,.24),l(.119,.1),l(.12,.52),l(.28,.06),l(.359,.42),l(.2,.28),l(.439,.419),l(.18,.36),l(.359,.06),l(.047,.146),l(-.292,.449),l(-.496,.284),l(-.283,.094),l(-.308,.331),l(-.165,.213),l(-.379,.047),l(-.449,-.142),l(-.591,-.094),l(0,-.308),l(-.283,-.284),l(-.118,0),l(-.095,-.118),l(-.473,-.284),l(-.142,-.189),H(504.5,0),l(-.213,.047),L(504.264,107),l(-.229,.023),l(-.126,-.189),l(-.236,-.071),l(-.236,.023),l(-.284,-.047),l(-.26,-.094),l(-.284,-.166),l(-.354,-.284),l(.118,-.307),l(.118,-.189),l(-.118,-.142),l(-.354,-.024),l(-.378,0),l(-.213,-.166),l(-.189,-.118),l(-.212,0),l(-.143,-.094),l(-.236,-.118),l(-.118,0),l(-.095,.071),l(-.142,.166),l(-.188,-.142),l(-.261,-.071),l(-.354,0),l(-.213,.071),l(-.094,.095),l(-.166,.166),l(-.283,0),l(-.261,.118),l(-.212,-.071),l(-.261,-.118),l(.048,-.118),l(.142,-.118),l(-.308,-.119),l(-.236,-.118),l(-.354,-.071),l(-.52,-.118),l(-.284,-.213),l(-.095,-.142),l(-.354,-.166),l(-.283,.047),l(-.189,0),l(-.401,-.166),l(-.544,0),l(-.426,.095),l(-.307,0),l(-.355,-.047),l(-.307,-.071),l(-.261,-.095),l(-.212,-.166),l(-.213,0),l(-.331,0),l(-.189,-.047),l(-.188,-.094),l(-.284,-.142),l(-.283,-.095),l(-.449,-.023),l(-.402,-.023),l(-.07,-.047),l(-.284,-.047),l(-.26,.166),l(-.112,.309),l(-1.421,-1.012),l(-1.188,-.842),l(-.817,-.385),l(-.62,-.084),l(-.373,-.157),l(-.509,-.5),l(-.236,-.057),l(-.338,.159),l(-.329,-.042),l(-.347,-.515),l(-.795,-.674),l(.595,-.188),l(.519,-.001),l(.445,-.073),l(.1,-.519),l(.359,-.476),L(485,97.85),l(.526,-.03),l(.516,-.131),l(-.432,-.532),l(-.654,-.273),l(-.474,-.36),l(.243,-.116),l(.367,-.03),l(.82,-.117),l(.715,-.348),l(1.244,-.436),l(-.196,-.375),l(-.076,-.058),l(-.799,.088),l(-1.312,.175),l(.012,-.126),l(.021,-.112),l(0,-.224),l(.09,-.514),l(.224,-.089),l(.357,-.022),l(.38,-.134),l(.223,-.179),l(.022,-.179),l(.269,0),l(.736,-.045),l(.805,.157),l(.335,-.134),l(0,-.156),l(.156,-.291),l(.156,-.491),l(-.066,-.067),l(-.09,-.201),l(-.045,-.179),l(-.044,-.134),l(-.179,-.067),l(-.156,-.067),l(.044,-.224),l(.045,-.179),l(.246,0),l(.312,0),l(.134,-.156),l(-.29,-.044),l(-.269,-.089),l(-.223,-.246),l(.312,-.044),l(.357,-.201),l(.156,-.067),l(.201,-.089),l(.045,-.224),l(-.09,-.179),l(-.111,-.089),l(.022,-.179),l(.089,-.111),l(-.156,-.089),l(-.201,.089),l(-.134,.044),l(-.269,0),l(-.357,-.156),l(-.111,-.224),l(-.469,-.022),l(-.291,-.089),l(-.201,-.179),l(-.357,.067),l(-.268,-.112),l(-.469,-.112),l(-.425,-.067),l(-.29,-.268),l(-.224,.067),l(-.045,.157),l(-.29,.134),l(-.224,-.112),l(-.179,-.179),l(-.402,-.044),l(-.022,-.134),l(-.201,-.179),l(0,-.134),l(-.268,-.179),l(-.111,-.156),l(-.357,.067),l(-.536,.134),l(-.269,0),l(-.312,.112),l(-.425,.112),l(-.179,-.156),l(-.179,-.022),l(-.201,.067),l(-.469,-.291),l(-.268,-.067),l(-.47,.067),l(-.268,.179),l(-.291,-.29),l(-.179,-.089),l(-.089,-.224),l(.089,-.179),l(-.089,-.246),l(-.224,-.268),l(0,-.357),l(-.402,0),l(0,-.312),l(-.38,-.022),l(-.514,.067),l(-.156,-.112),l(-.647,0),l(-.269,-.29),l(-.111,-.357),l(-.134,-.291),l(.312,-.134),l(.312,.022),l(0,-.268),l(-.312,-.156),l(-.246,-.156),l(-.134,-.201),l(-.246,-.335),l(-.312,-.134),l(-.201,-.268),l(-.514,.134),l(-.692,-.112),l(-.67,.223),l(-.536,.022),l(-.536,-.246),l(-.134,.268),l(-.179,.291),l(-.313,.156),l(-.469,-.022),l(-.357,-.089),M(527.156,37.071),l(-.59,-.14),l(-.955,-.21),l(-1.128,-.139),l(-.739,.054),l(-.959,.037),l(-.732,.143),l(-.411,-.105),l(-1.025,-.476),l(.737,-.303),l(1.21,-.429),l(.654,-.09),l(1.549,-.002),l(.135,-.357),l(-.728,-.338),l(.351,-.269),l(.419,-.144),l(.676,-.02),l(.852,-.181),l(-.25,-.161),l(-.526,-.233),l(1.539,-.895),l(.513,-.129),l(.226,.073),l(.892,.017),l(.981,-.535),l(.863,-.333),l(1.02,-.261),l(.975,-.15),l(1.305,-.113),l(1.274,.053),l(.738,-.15),l(.786,-.615),l(.273,.018),l(.873,-.132),l(1.722,.276),l(.471,-.038),l(1.93,-.321),l(.958,-.039),l(2.184,-.247),l(1.864,-.116),l(.771,-.564),l(.376,-.152),l(2.511,-.137),l(1.965,-.079),l(.471,.131),l(.442,.225),l(.154,.357),l(-.812,.47),l(-.541,.169),l(-1.346,.319),l(-2.609,.433),l(-4.329,.49),l(-2.187,.281),l(-2.122,.299),l(-1.842,.316),l(-2.102,.242),l(-.941,.203),l(-.288,.274),l(.644,.216),l(-.422,.217),l(-.943,.361),l(-.527,.037),l(-2.047,-.068),l(-.432,.18),l(-.119,.233),l(.621,.249),l(-.331,.233),l(-1.206,.448),l(-.402,-.142),l(-.752,-.087),l(-.592,.304),l(.877,.283),l(.052,.319),l(-1.094,.657),l(-.822,.284),M(517.491,38.443),l(1.041,-.37),l(.512,-.299),l(.428,-.212),l(1.426,-.021),l(1.316,-.249),l(.987,-.02),l(1.412,-.091),l(.551,.069),l(.988,.227),l(-.063,.176),l(-.463,.528),l(-.302,.158),l(-.697,.071),l(-.443,.228),l(-.233,.385),l(.006,.818),l(.445,1.039),l(.957,.826),l(.505,.308),l(.775,.307),l(1.162,.392),l(-.028,.282),l(-2.62,-.089),l(-.844,.053),l(-.917,.326),l(-.596,.086),l(-.676,-.494),l(-.382,-.034),l(-1.091,.088),l(-.673,-.102),l(-.031,-.359),l(1.347,-.362),l(.073,-.24),l(-.102,-.017),l(-.944,-.273),l(-1.442,-.411),l(-1.519,-.17),l(-.33,.156),l(-.624,.122),l(-.681,-.033),l(-.625,-.396),l(-.114,-.415),l(.229,-.312),l(.39,-.209),l(.344,-.036),l(.318,.104),l(.65,.016),l(.518,-.192),l(1.121,-.768),l(.243,-.35),l(-.322,0),l(-.981,-.243),M(.125,56.089),l(0,-.562),l(0,-.576),l(0,-.157),l(0,-1.292),V(0,51.28),l(0,-2.222),l(0,-2.12),l(2.917,.61),l(1.693,.598),l(.933,.181),l(3.819,.99),l(1.059,.395),l(.204,.149),l(.074,.214),l(.445,.429),l(.406,.789),l(-.209,.428),l(1.034,.8),l(.982,.26),l(-.02,-.18),l(.297,-.148),l(-.051,-.196),l(-.638,-.392),l(.016,-.542),l(.077,-.296),l(1.026,-.183),l(.984,.278),l(.573,.098),l(.767,.064),l(1.003,-.117),l(.933,.13),l(.93,.425),l(.694,.359),l(1.676,.684),l(.32,.081),l(.584,.179),l(.43,.211),l(.09,.13),l(-.343,.033),l(-1.026,-.096),l(-.364,.034),l(-.808,.798),l(-1.539,-.468),l(.138,.178),l(.438,.227),l(.465,.324),l(-1.177,-.111),l(-1.008,.05),l(-1.202,-.387),l(-.708,-.096),l(.135,.129),l(.289,.259),l(.084,0),l(.561,.259),l(.205,.307),l(.131,.453),l(-.056,.339),l(-.814,.05),l(-.805,.065),l(-.189,.161),l(.5,.865),l(-.115,.272),l(-1.04,-.078),l(-.397,.081),l(-1.193,-.174),l(-.264,-.352),l(-1.795,-.51),l(-.253,.273),L(9.85,55.79),l(-.276,-.161),l(-.265,-.403),l(.174,-.178),l(-.321,-.42),l(-.87,-.339),l(-.565,-.063),l(-.762,.034),l(-.858,.229),l(-1.343,.084),L(3.57,54.443),l(.059,-.325),l(-.155,-.325),l(-.618,-.487),L(1.958,53.43),l(-.45,.409),l(-.655,1.228),l(-.166,.715),l(-.562,.307),
+N(449.401,22.792),l(-1.596,-.014),l(-2.019,-.016),l(-1.739,.063),l(-.764,.061),l(-1.972,-.316),l(.812,-.456),l(.826,-.172),l(.735,-.453),l(1.148,-.588),l(1.354,.691),l(.998,.105),l(1.116,-.088),l(.9,.084),l(.704,.341),l(.865,-.323),l(.53,-.454),l(.868,-.306),l(-.311,.823),l(.086,.32),l(.851,-.001),l(.991,-.495),l(1.061,-.261),l(.803,.128),l(.559,.472),l(.705,.041),l(2.007,-.111),l(1.543,.189),l(.551,.376),l(-.507,.201),l(-2.004,.622),l(-1.623,.38),l(-1.069,.062),l(-.976,.14),l(-1.324,.366),l(-6.271,-.097),l(-.033,-.377),l(1.492,-.26),l(.702,-.677),M(430.027,22.752),l(.068,.697),l(.252,.119),l(1.694,.155),l(.221,-.377),l(.13,-.418),l(.573,-.141),l(.523,-.041),l(.949,.477),l(1.192,.771),l(.798,.235),l(.568,-.218),l(-.222,-.296),l(-.46,-.356),l(-.327,-.477),l(-.04,-.22),l(.91,-.407),l(1.001,.103),l(.485,.18),l(1.278,.018),l(.586,.179),l(-.08,.419),l(-.169,.298),l(.104,.159),l(.549,.118),l(.743,-.338),l(.44,-.1),l(.662,.396),l(.678,.335),l(.785,.156),l(.948,.117),l(1.672,.429),l(.498,.234),l(-1.305,.277),l(-1.981,.218),l(-.696,.293),l(-.731,1.144),l(-.885,.885),l(-1.243,.117),l(-.766,.535),l(-.455,.589),l(-.029,.378),l(-.786,.209),l(-.556,-.018),l(-1.593,-.355),l(-1.883,-.507),l(-1.365,-.568),l(.651,-.364),l(1.565,-.041),l(1.788,-.137),l(.944,-.386),l(-.652,-.249),l(-1.822,.139),l(-1.566,.118),l(-1.694,.042),l(-.502,-.519),l(.959,-.06),l(1.371,-.215),l(2.149,-.314),l(1.547,-.45),l(-2.525,-.405),l(-.881,-.292),l(-.589,.138),l(-1.036,.646),l(-1.069,.293),l(-.562,.059),l(-1.236,-.172),l(-.338,-.174),l(-1.05,-.368),l(-.807,-.233),l(-.698,-.41),l(1.698,-.396),l(-.817,-.571),l(-1.359,.319),l(-.467,-.078),l(-.924,-.751),l(.812,-.36),l(.516,-.021),l(1.075,-.122),l(1.017,.038),l(.577,-.061),l(1.188,-.042),M(425.42,68.82),l(-.148,-.21),l(-.629,.132),l(-.134,-.026),l(-.249,-.237),l(-.239,-.343),l(.188,-.158),l(-.143,-.291),l(-.361,.185),l(-.062,.29),l(.113,.237),l(-.147,.105),l(-.339,.316),l(-.086,.185),l(-.521,.105),l(-.533,-.131),l(-.781,.342),l(.057,.131),l(-.502,.289),l(-.498,.263),l(-1.658,.813),L(418.697,71),l(-.274,.052),l(-.271,0),l(-2.111,.209),l(-.188,-.236),l(-.33,-.131),l(-.183,.209),L(414.976,71),l(.384,-.184),l(-.935,-.236),l(-.794,-.341),l(-.574,-.052),l(-.479,-.578),l(.292,-.368),l(-.126,-.21),l(.34,.026),l(.085,.316),l(.284,-.21),l(.667,.263),l(-.244,-.197),l(.127,-.145),l(.5,-.092),l(-.479,.026),l(-.245,.105),l(-.263,-.184),l(-.111,-.132),l(.579,-.276),l(.455,-.185),l(-.482,.066),l(-.317,-.132),l(.441,-.237),l(.083,-.237),l(-.661,.475),l(-.036,-.264),l(-.265,-.171),l(.005,.211),l(.076,.171),l(-.419,.158),l(-.41,0),l(.014,-.277),l(-.15,.264),l(-.235,-.079),l(-.2,-.448),l(.658,-.449),l(.08,.436),l(.068,-.317),l(.438,.158),l(.211,-.092),l(-.166,-.106),l(.674,-.079),l(.479,-.251),l(-.611,.159),l(-.48,0),l(-.335,-.159),l(.196,-.132),l(.387,-.146),l(.196,-.471),l(-.821,-.014),l(-.546,.094),l(-.406,-.309),l(.368,-.14),l(.643,-.404),l(-.212,-.186),l(-.445,.063),l(-.399,-.062),l(-.211,-.217),l(.284,-.482),l(.619,-.265),l(-.595,-.248),l(-.225,-.374),l(.272,-.188),l(-.089,-.687),l(.106,-.094),l(.594,-.063),l(.392,-.045),l(.455,.044),l(.082,-.11),l(-.255,-.134),l(-.425,-.118),l(-.228,-.17),l(.098,-.188),l(.211,-.125),l(.575,-.064),l(.511,-.346),l(.567,.109),l(.498,-.111),l(.179,-.55),l(.835,.093),l(.668,.125),l(.571,-.252),l(-.989,-.234),l(-.266,-.314),l(.236,-.143),l(1.151,.014),l(.851,-.08),l(.538,.219),l(.06,-.473),l(.477,-.27),l(.297,-.333),l(.78,-.175),l(.438,.189),l(.138,.079),l(.5,-.476),l(.869,-.413),l(.084,-.429),l(.437,-.398),l(1.497,-.735),l(.335,-.192),l(.235,-.048),l(.481,.175),l(.335,-.001),l(.319,-.224),l(-.225,-.223),l(.141,-.128),l(.488,-.224),l(.457,-.305),l(.481,-.483),l(.245,.064),l(.676,-.017),l(-.067,-.612),l(-.471,-.112),l(.434,-.405),l(.511,-.648),l(.841,.063),l(.047,-.341),l(.096,-.228),l(.954,-.116),l(-.396,-.357),l(-.327,-.097),l(-.193,-.146),l(.164,-.245),l(.313,-.246),l(.464,.048),l(.888,-.067),l(-.543,-.522),l(.249,-.082),l(.435,-.034),l(.707,-.263),l(.592,-.067),l(.308,-.208),l(-.358,-.064),l(-.105,-.187),l(.289,-.1),l(.616,-.33),l(.557,.032),l(.351,.098),l(.434,-.264),l(.369,-.031),l(.035,-.176),l(-.421,-.321),l(.627,-.232),l(.146,-.275),l(.336,.01),l(.359,.297),l(.397,.082),l(.526,-.381),l(-.281,-.656),l(.438,.065),l(.698,-.058),l(.207,-.174),l(-.604,-.315),l(.411,-.224),l(.816,-.251),l(.093,-.257),l(.261,-.194),l(.73,-.135),l(.074,.067),l(.274,-.051),l(.102,-.067),l(.492,-.67),l(.521,.25),l(.96,-.153),l(.411,.133),l(.265,.1),l(.646,.065),l(.536,-.419),l(.747,-.84),l(.286,-.085),l(.16,.168),l(-.178,.286),l(-.182,.587),l(.791,-.454),l(.403,-.572),l(.819,-.085),l(.688,-.439),l(.437,.117),l(.665,.353),l(.567,-.643),l(.318,-.272),l(.976,.1),l(1.019,.506),l(.197,-.152),l(.479,-.595),l(.709,-.444),l(.283,-.052),l(.562,.067),l(.338,-.308),l(.469,-.291),l(.619,-.189),l(1.2,-.173),l(.984,.015),l(-1.337,.755),l(-.24,.273),l(-.107,.646),l(.42,.084),l(.691,-.579),l(1.53,-.941),l(.764,-.275),l(.028,.257),l(-.004,.905),l(.704,-.172),l(.438,-.239),l(.855,-.874),l(.959,-.104),l(.586,-.001),l(.216,.154),l(-.383,.257),l(-.335,.257),l(.074,.239),l(-.319,.41),l(.921,.118),l(.221,-.443),l(.902,-.651),l(.421,.017),l(1.682,.561),l(.667,.135),l(.935,.015),l(.649,.237),l(.1,.272),l(-1.216,.393),l(-1.148,.036),l(-2.233,-.047),l(.193,.084),l(.585,.304),l(1.058,.284),l(.383,.302),l(.728,-.052),l(.679,-.102),l(.831,.032),l(.708,.25),l(-.404,.288),l(-.514,.204),l(-.824,.021),l(-.77,.121),l(-1.023,.49),l(-1.013,.672),l(-.689,.303),l(-.001,-.2),l(.096,-.367),l(.874,-.923),l(-.044,-.268),l(-.88,-.348),l(-.672,-.114),l(-1.125,-.431),l(-.556,.003),l(-.555,.07),l(-2.004,.095),l(-.865,.374),l(-.567,.422),l(-.26,.437),l(-.079,.501),l(-.188,.5),l(-1.25,.472),l(-.582,.368),l(-.31,-.148),l(-1.288,-.492),l(-1.657,.225),l(-1.411,-.042),l(-.536,-.13),l(-.861,-.595),l(-.994,-.612),l(-.486,-.082),l(-.355,.103),l(-1.012,.656),l(-.114,-.063),l(-.41,-.031),l(-.865,.038),l(-.281,1.066),l(-.164,.449),l(-.271,.25),l(-.323,-.015),l(-.67,-.129),l(-.972,-.144),l(-1.731,-.389),l(-.168,.183),l(-.021,.663),l(-.083,.199),l(-.318,.299),l(-.695,.004),l(-.871,-.095),l(-.279,-.015),l(-.465,.167),l(-1.484,1.176),l(.05,.213),l(.171,.507),l(-.188,.345),l(-.615,.346),l(-1.325,.919),l(-.687,.442),l(-.981,.021),l(-.121,.244),l(-.06,.971),l(-.32,.598),l(-.383,.469),l(-.574,.499),l(-.495,.545),l(.339,.125),l(.381,.269),l(.252,.587),l(-.17,.176),l(-.44,.177),l(-.733,.036),l(-.932,-.027),l(-.618,.114),l(-.613,.257),l(-.617,.479),l(-.389,.492),l(-.077,.664),l(-.349,1.093),l(.65,.729),l(-.335,1.171),l(.582,.39),l(.715,.186),l(.297,.243),l(-.432,.67),l(-.941,.16),l(.571,.735),l(.26,.427),l(-.249,.346),l(-.029,.532),l(-.769,.384),l(-.414,.013),l(-.117,.423),l(-.506,.224),l(.22,.831),l(-.324,.737),l(-.41,.013),l(-.15,-.342),l(-.293,-.132),
+N(464.349,47.431),l(-.024,.283),l(-.258,.465),l(.116,.529),l(.563,.212),l(.872,.194),l(.964,.506),l(.543,.392),l(-.421,.364),l(-1.303,.777),l(-.328,.296),l(1.402,1.394),l(.772,1.195),l(-.196,.356),l(-.44,.535),l(-.187,.403),l(-.029,.37),l(.37,.509),l(1.286,1.395),l(.151,.253),l(-.057,.254),l(-.542,.415),l(-.327,.191),l(.439,.33),l(1.357,.499),l(.703,.265),l(.436,.392),l(.161,.346),l(-.105,.409),l(-.43,.536),l(-.591,.536),l(-1.385,.758),l(-1.983,1.195),l(-1.946,1.145),l(-.174,.285),l(-.935,.206),l(-1.195,.188),l(-.149,.181),l(-.506,-.217),l(-.518,.146),l(-.052,.134),l(-.688,-.07),l(-.193,-.108),l(.057,-.387),l(-.241,.527),l(-.268,.14),l(-.633,.047),l(-.328,.03),l(-.1,.267),l(-.589,-.326),l(-.29,.275),l(-.676,.064),l(-.34,.178),l(-.052,-.127),l(-.504,.108),l(-.504,.108),l(-.211,.266),l(-.311,-.152),l(-.672,.126),l(-.04,-.114),l(-.658,.215),l(-.547,.013),l(-.482,.025),l(-.487,-.253),l(-.223,-.274),l(.273,-.34),l(-.846,.017),l(-.517,.177),l(.065,-.382),l(-.446,.076),l(-.644,-.271),l(-.409,-.061),l(-.415,-.231),l(-.26,-.403),l(-.036,-.714),l(.158,-.374),l(.05,-.436),l(.09,-.234),l(-.347,-.483),l(-.431,-.375),l(.3,-.658),l(-.02,-.392),l(-.305,-.204),l(-.37,-.093),l(.062,-.299),l(.295,-.331),l(.637,-.285),l(.144,-.189),l(-.113,-.331),l(.382,-.143),l(.633,.125),l(.274,.063),l(.483,-.222),l(.303,-.427),l(.104,-.459),l(.207,-.27),l(.301,.316),l(.27,0),l(1.678,-1.114),l(1.142,-.654),l(.835,-.576),l(1.026,-.401),l(.874,.03),l(.06,-.304),l(-.13,-.144),l(-.357,-.16),l(.119,-.371),l(.146,-.387),l(-.329,-.274),l(-1.139,-.095),l(-.836,-.451),l(-.594,-.024),l(-.113,-.234),l(-.327,-.307),l(-.208,-.535),l(.5,-.8),l(-.028,-.392),l(-.405,-.685),l(-.507,-.637),l(.004,-.526),l(.062,-.413),l(-.77,-.558),l(-.508,-.229),l(-1.583,-.207),l(-1.085,-.292),l(-1.286,-.658),l(-.616,-.463),l(-.146,-.033),l(1.012,-.656),l(.355,-.103),l(.486,.082),l(.994,.612),l(.861,.595),l(.536,.13),l(1.411,.042),l(1.657,-.225),l(1.288,.492),l(.31,.148),l(.582,-.368),l(1.25,-.472),l(.188,-.5),l(.079,-.501),l(.26,-.437),l(.567,-.422),l(.865,-.374),l(2.004,-.095),l(.555,-.07),l(.556,-.003),l(1.125,.431),l(.672,.114),l(.88,.348),l(.044,.268),l(-.874,.923),l(-.096,.367),l(.001,.2),
+N(453.795,53.873),l(-.23,-.004),l(-.975,.164),l(-.447,.098),l(-.902,-.387),l(-.339,-.178),l(-.347,.114),l(-.641,.374),l(-.542,.599),l(-.309,.146),l(-.658,.018),l(-.545,.355),l(.325,.241),l(.146,.192),l(-.355,.273),l(-.907,.401),l(.317,.271),l(.385,.159),l(.33,.302),l(-.749,.367),l(-.405,.43),l(-.368,.461),l(-1.591,.669),l(-.699,.286),l(-.456,-.205),l(-.326,.08),l(-.538,.539),l(-.646,.144),l(-.663,.348),l(-.217,.284),l(-.191,.142),l(-.746,.033),l(-.221,-.031),l(.151,.535),l(-.484,.425),L(439,61.33),l(.216,.533),l(.243,.25),l(-.244,.955),l(-.498,.063),l(-.217,.204),l(.189,.757),l(-.009,.544),l(.381,.444),l(-.287,.175),l(.926,.082),l(.225,.187),l(.499,-.082),l(.652,.594),l(.428,.314),l(.86,.163),l(.198,.406),l(.32,.139),l(.014,.335),l(-.391,0),l(-.508,.323),l(-.861,.3),l(-.492,.162),l(-.521,-.012),l(-.146,-.115),l(-.805,-.115),l(-.66,-.173),l(-.634,-.069),l(-.137,.104),l(-.446,-.115),l(-.257,.3),l(.819,-.069),l(.497,.265),l(.591,.046),l(.205,.208),l(.481,.069),l(.021,-.127),l(.616,.069),l(.258,-.196),l(.297,.011),l(.481,-.104),l(.226,.081),l(.026,-.15),l(.164,0),l(.214,.15),l(-.029,.081),l(-.722,.023),l(.219,.288),l(-.792,.265),l(-.168,.288),l(-.386,.08),l(-.089,-.092),l(.042,-.161),l(-.014,-.276),l(-.258,.023),l(-.091,.46),l(-.501,.333),l(-.248,.058),l(-.36,-.069),l(-.005,.218),l(-1.418,.035),l(.156,.458),l(.513,.258),l(.066,.609),l(-.109,.33),l(-.281,.051),l(-.308,-.064),l(.038,.429),l(.29,.081),l(-.126,.268),l(.24,.228),l(-.365,.364),l(-.222,.455),l(-.041,.56),l(-.766,1.043),l(-.58,.71),l(-.165,-.062),l(-.442,-.236),l(-.614,.193),l(-1.262,-.089),l(-.106,.311),l(-.252,-.083),l(-.518,.264),l(-.295,.517),l(.356,.336),l(-.376,.374),l(-.48,-.129),l(-.173,-.037),l(-1.158,.269),l(-1.11,-.116),l(-.001,-.142),l(.19,-.078),l(-.062,-.181),l(.281,-.297),l(-.638,-.53),l(-.413,-.479),l(-.22,-.272),l(.529,-.116),l(-.082,-.312),l(.421,.077),l(.147,-.245),l(-.19,-.234),l(-.285,.013),l(-.292,-.377),l(-.527,-.221),l(-.63,-.99),l(-.286,0),l(.011,-.408),l(-.256,-.364),l(-.348,-.298),l(.221,-.484),l(.206,-.341),l(-.418,-.154),l(-.405,.102),l(-.055,-.288),l(-.412,.051),l(-.18,-1.207),l(-.225,-.131),l(.311,-.355),l(.293,.132),l(.15,.342),l(.41,-.013),l(.324,-.737),l(-.22,-.831),l(.506,-.224),l(.117,-.423),l(.414,-.013),l(.769,-.384),l(.029,-.532),l(.249,-.346),l(-.26,-.427),l(-.571,-.735),l(.941,-.16),l(.432,-.67),l(-.297,-.243),l(-.715,-.186),l(-.582,-.39),l(.335,-1.171),l(-.65,-.729),l(.349,-1.093),l(.077,-.664),l(.389,-.492),l(.617,-.479),l(.613,-.257),l(.618,-.114),l(.932,.027),l(.733,-.036),l(.44,-.177),l(.17,-.176),l(-.252,-.587),l(-.381,-.269),l(-.339,-.125),l(.495,-.545),l(.574,-.499),l(.383,-.469),l(.32,-.598),l(.06,-.971),l(.121,-.244),l(.981,-.021),l(.687,-.442),l(1.325,-.919),l(.615,-.346),l(.188,-.345),l(-.171,-.507),l(-.05,-.213),l(1.484,-1.176),l(.465,-.167),l(.279,.015),l(.871,.095),l(.695,-.004),l(.318,-.299),l(.083,-.199),l(.021,-.663),l(.168,-.183),l(1.731,.389),l(.972,.144),l(.67,.129),l(.323,.015),l(.271,-.25),l(.164,-.449),l(.281,-1.066),l(.865,-.038),l(.41,.031),l(.114,.063),l(.146,.033),l(.616,.463),l(1.286,.658),l(1.085,.292),l(1.583,.207),l(.508,.229),l(.77,.558),l(-.062,.413),l(-.004,.526),l(.507,.637),l(.405,.685),l(.028,.392),l(-.5,.8),l(.208,.535),l(.327,.307),l(.113,.234),
+N(238.107,361.753),l(.515,-.688),l(.859,0),l(1.202,-.515),l(-.171,-.858),l(-3.091,.344),l(-2.061,.515),l(-1.545,-.344),l(-.515,-.858),l(1.374,-.515),l(1.202,-.172),l(3.091,-.172),l(1.374,-.515),l(-.172,-1.03),l(.859,-.516),l(0,-1.374),l(-1.326,-1.054),l(.982,-.491),l(1.202,-.344),l(1.545,-.172),l(.858,.344),l(.858,.858),l(1.03,1.374),l(1.374,1.202),l(1.03,1.373),l(-.515,2.061),l(-1.545,.516),l(-1.545,.858),l(-3.434,.172),l(-3.435,0),M(172.686,360.379),l(3.091,-.687),l(3.262,0),l(5.495,0),l(2.919,1.202),l(-2.748,.687),l(-3.759,-.337),l(-5.169,-.35),l(-3.091,-.516),M(65.13,371.085),l(1.194,-.265),l(1.393,.133),l(.796,.464),l(-1.99,0),l(-1.393,-.332),M(277.944,379.954),l(.515,-1.202),l(2.404,-1.03),l(2.748,-.172),l(2.061,-.171),l(1.545,-.859),l(.343,-1.545),l(1.374,-.687),l(3.091,-.688),l(4.464,0),l(2.404,0),l(3.434,.688),l(.687,1.889),l(0,1.202),l(-2.061,1.201),l(-11.848,1.03),l(-11.161,.344),M(36.004,376.434),l(1.202,-.858),l(2.061,-.343),l(4.121,.515),l(4.293,1.374),l(-.887,.482),l(-2.719,.204),l(-4.293,-.515),l(-3.777,-.859),M(777.843,385.46),l(3.823,.391),l(.899,.029),l(.322,.234),l(1.202,.294),l(2.329,.088),l(2.126,-.003),l(5.218,.329),l(3.046,.348),l(1.144,-.059),l(.762,.029),l(1.411,.37),l(0,2.175),l(0,2.223),l(0,2.222),l(0,2.223),l(0,2.222),l(0,1.551),l(-.041,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.182,0),l(-.041,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.182,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),H(9.014,0),H(6.792,0),H(4.569,0),H(2.347,0),H(.125,0),l(0,-1.544),l(0,-2.222),l(0,-2.223),l(0,-2.222),l(0,-2.223),l(0,-2.223),l(3.941,.297),l(10.131,0),l(7.898,.516),l(6.868,.172),l(8.586,.858),l(6.353,.515),l(8.757,.172),l(4.808,-.172),l(6.525,-.172),l(2.404,.344),l(3.606,-.858),l(16.312,.344),l(4.638,-.013),l(1.143,-.467),l(-14.366,-.551),l(-9.616,-.688),l(-2.232,0),l(-3.091,-.172),l(-.858,-.171),l(-1.545,-.344),l(-.498,-.455),l(.155,-1.434),l(.687,-.858),l(1.889,-.688),l(-3.263,-.687),l(-2.232,-.344),l(-.953,-.503),l(1.589,-.521),l(-2.891,-.6),l(-3.074,-.208),l(-.104,-.261),l(2.857,-.312),l(2.748,0),l(6.525,.343),l(3.434,0),l(2.576,.344),l(4.636,-1.202),l(2.404,-.687),l(-2.748,-1.03),l(-3.778,-.858),l(-4.391,-.405),l(-2.649,-.625),l(-3.262,-.172),l(-2.919,0),l(-2.919,-.858),l(2.576,-.516),l(1.28,-.342),l(-1.28,-.517),l(-2.919,.516),H(52.66,0),l(-1.717,-.344),L(49.054,373),l(.343,-1.202),l(1.956,-.07),l(1.65,-.273),l(4.98,0),l(4.626,.493),l(3.272,.709),l(1.374,.172),l(4.465,-.858),l(4.089,.243),l(0,-.729),l(.066,-.597),l(-2.255,-.73),l(-2.93,-.075),l(-2.576,-.344),l(2.404,-.687),l(4.121,.171),l(1.717,-.343),l(3.091,-.516),l(3.09,-.343),l(5.667,-.688),l(4.465,-.343),l(3.949,-.516),l(4.464,-.515),l(2.748,.343),l(5.667,0),l(4.464,.258),l(4.121,-.515),l(7.898,.343),l(7.555,-.687),l(3.091,.172),l(1.545,-.688),l(1.545,.516),l(5.323,-.172),l(.121,-.87),l(1.758,-.293),l(1.433,.325),l(.586,.554),l(-.423,.813),l(2.364,.329),l(1.38,-.264),l(-.006,-.938),l(1.438,-.267),l(1.48,.267),l(.212,1.036),l(-1.009,.423),l(.521,.781),l(3.024,-.351),l(1.889,.343),l(3.434,.172),l(2.576,-.687),l(3.778,.086),l(4.868,.33),l(2.344,.013),l(1.449,.109),l(.693,-.53),l(-.611,-.285),l(-2.202,-.122),l(1.305,-.285),l(.041,-.408),l(-.367,-.245),l(-1.386,.123),l(-.693,.04),l(-.856,-.979),l(-2.178,-.337),l(-.676,-.193),l(-.182,-.665),l(4.056,.462),l(3.874,-.245),l(-1.224,-.489),l(-6.035,-.163),l(-.774,-.082),l(-.653,-.489),l(0,-.815),l(2.301,.105),l(.839,.67),l(5.301,-.204),l(7.253,.736),l(2.404,-.172),l(3.262,-.172),l(4.464,.172),l(3.263,.172),l(2.061,-.516),l(.687,-.687),l(1.202,0),l(.344,1.03),l(2.576,.343),l(2.404,-.343),l(.858,.515),l(3.435,.688),l(3.777,.343),l(2.061,.172),l(1.03,-.515),l(.687,-1.202),l(2.747,-.172),l(1.03,.515),l(1.717,.688),l(3.091,-.172),l(3.434,.258),l(4.121,-.344),l(4.979,-.516),l(5.495,-.858),l(3.091,-.515),l(1.202,-.688),l(0,-1.373),l(-1.374,-1.202),l(-.859,-1.545),l(-1.202,-.688),l(-.344,-1.03),l(1.202,-1.03),l(1.717,-.343),l(.858,-1.202),l(-.343,-.858),l(-.172,-1.03),l(-1.202,-.516),l(.344,-1.545),l(1.889,-.172),l(2.404,-1.374),l(1.545,-.515),l(.859,-.859),l(1.03,-.687),l(2.919,-1.202),l(3.606,-.515),l(2.404,-1.202),l(2.404,-.172),l(2.232,-1.03),l(1.545,-.343),l(.343,1.03),l(-1.374,.515),l(-1.03,.344),l(-1.202,.515),l(-.858,0),l(-1.202,0),l(-2.919,1.202),l(-1.03,.687),l(-1.717,1.374),l(-.172,1.202),l(-.687,.687),l(-1.374,-.344),l(-1.03,0),l(-1.202,.516),l(-1.202,.687),l(-1.03,.688),l(-.687,1.201),l(.515,.688),l(.687,.687),l(1.374,.344),l(1.545,0),l(.858,.515),l(.687,1.202),l(1.545,1.546),l(.687,.858),l(1.03,.687),l(.687,1.374),l(.858,1.373),l(.344,1.546),l(-.344,.858),l(-.858,1.717),l(-2.919,1.889),l(-1.202,.172),l(-1.03,.858),l(-1.717,1.03),l(-3.263,.344),l(-4.979,.858),l(-2.404,.344),l(-2.919,.687),l(-7.377,-.141),l(-4.556,-.316),l(-.773,-.401),l(-1.717,-.344),l(-1.717,-.343),l(-1.374,0),l(-.859,.515),l(.515,.858),l(2.061,.688),l(4.121,1.202),l(4.995,.04),l(1.202,.759),l(-3.278,.574),l(-5.667,-.343),l(-4.979,-.516),l(-3.097,-.285),l(-2.151,.253),l(.823,.696),l(1.164,.538),l(3.262,.172),l(2.232,0),l(1.374,.343),l(-.249,.402),l(-.782,.113),l(-2.232,.515),l(-5.151,-.171),l(-1.374,-.172),l(-2.232,-1.202),l(-2.404,0),l(.128,.917),l(2.62,1.144),l(1.03,.172),l(1.202,-.172),l(1.374,.344),l(2.404,0),l(4.98,-.516),l(3.09,.687),l(.385,.431),l(-.041,.6),l(-2.061,.172),l(-3.263,.172),l(-2.608,-.185),l(3.811,.871),l(3.656,-.238),l(1.324,.41),l(2.576,.687),l(6.869,.859),l(8.585,.858),l(10.646,1.373),l(6.525,.516),l(2.061,.858),l(.687,1.03),l(3.091,-.344),l(5.323,-1.545),l(6.525,-.687),l(2.455,-.066),l(6.474,-.105),l(9.788,-.344),l(1.889,.344),l(2.576,-1.202),l(8.414,-1.03),l(11.333,-.172),l(8.929,-.858),l(1.202,-.858),l(-1.202,-.516),l(-.271,-1.07),l(-1.184,-.338),l(-5.071,.035),l(-2.232,.172),l(-4.808,-.344),l(-3.091,0),l(0,-1.202),l(3.263,-1.545),l(3.949,-1.202),l(2.404,-.172),l(4.121,-1.03),l(9.444,-1.202),l(5.323,-.858),l(6.525,0),l(4.979,-.516),l(2.747,-2.061),l(6.039,-1.541),l(-1.23,-.52),l(-2.576,.516),l(-2.061,-.344),l(1.545,-1.03),l(1.545,-.343),l(2.48,-.249),l(.696,-.742),l(3.85,-.742),l(1.577,-.418),l(.603,-.557),l(-1.716,-.881),l(-.093,-.604),l(1.252,-.231),l(.464,.742),l(1.017,-.097),l(2.061,-.858),l(1.03,-.343),l(.858,.171),l(1.203,1.544),l(2.403,-.342),l(.242,-.91),l(.96,-.807),l(1.889,-.516),l(1.374,.516),l(-1.162,.574),l(-.139,.604),l(3.189,-.319),l(4.808,.258),l(3.263,-.172),l(1.03,.858),l(1.545,-.344),l(1.717,-.515),l(5.839,-.858),l(7.212,-1.03),l(4.292,-.858),l(2.061,0),l(2.061,1.373),l(1.718,.344),l(1.889,-.344),l(1.545,-.858),l(7.556,-.344),l(3.434,-.171),l(4.293,.171),l(6.697,.945),l(2.575,0),l(4.293,-.516),l(6.01,-.687),l(5.151,-.688),l(2.404,-.515),l(2.231,-.344),l(.615,-.959),l(1.148,-.835),l(1.671,-.095),l(.938,.965),l(1.294,.409),l(1.732,1.052),l(1.009,.139),l(1.009,-.661),l(1.322,-.174),l(.209,.522),l(-.835,.312),l(.661,.244),l(.8,.278),l(.383,-.383),l(.313,-.383),l(.312,.209),l(-.174,.348),l(0,.521),l(.592,-.174),l(1.913,-.557),l(.418,-1.704),l(5.102,-1.137),l(1.374,-.687),l(3.605,-.172),l(1.363,-.646),l(2.758,-.126),l(.21,-.27),l(-.165,-.297),l(.692,-.23),l(1.221,.165),l(.197,.593),l(.66,.231),l(2.165,-.536),l(1.265,-.223),l(-.726,-.297),l(-.561,-.264),l(.099,-.362),l(1.451,-.1),l(1.562,.215),l(.647,.28),l(.692,-.132),l(-.066,-.33),l(-.527,-.33),l(0,-.561),l(.297,-.23),l(.846,-.242),l(4.292,-.858),l(2.92,-.172),l(3.058,.115),l(2.296,1.076),l(1.316,.023),l(.741,.144),l(.023,.383),l(-.908,.096),l(-.168,.454),l(1.723,.216),l(4.892,.646),l(5.571,.453),l(1.546,.172),l(1.717,-.172),l(7.556,.688),l(5.323,0),l(.687,.687),l(.2,1.075),l(-.73,1.232),l(-.672,.439),l(-.425,1.113),l(-.73,.319),l(-.905,-.402),l(-.83,.402),l(-.73,.959),l(1.507,.457),l(.594,.045),l(.959,-.593),l(.411,.365),l(-.867,1.05),l(-1.215,.062),l(-1.717,1.374),l(0,.858),l(1.889,.688),l(2.919,0),l(1.718,-.859),l(1.889,-1.545),l(1.717,-1.717),l(1.374,-.688),l(4.121,-1.03),l(2.231,-.687),l(3.263,-.344),l(2.061,-1.03),l(1.03,-1.03),l(3.435,-1.03),l(2.403,-.687),l(2.061,-.687),l(2.061,-.172),l(6.182,-.687),l(3.778,.171),l(1.204,-.542),l(.169,-.659),l(.54,-.759),l(.49,-.101),l(.471,.776),l(.305,.775),l(4.892,-.35),l(5.838,0),l(4.979,-.172),l(3.091,.344),l(2.112,-.214),l(1.328,.085),l(1.018,.594),l(1.188,-.764),l(2.714,-1.046),l(1.866,-.226),l(.664,-.028),l(.594,-.028),l(.777,-.057),l(1.512,.311),l(1.166,-.172),l(3.606,.687),l(3.777,.344),l(1.03,0),l(1.064,.573),l(.745,.088),l(2.149,-.088),l(1.271,-.263),l(1.315,-.438),l(-.192,-.216),l(.28,-.53),l(1.447,-.131),l(.921,-.088),l(.786,.062),l(2.195,-.501),l(2.097,.501),l(.688,.687),l(.373,.435),l(1.842,-.131),l(.921,-.044),l(.985,.255),l(1.889,.688),l(2.919,.515),l(2.919,-.343),l(4.121,-.258),l(2.232,-.344),l(2.404,0),l(3.521,.315),l(.702,-.755),l(2.158,-.162),l(.863,1.133),l(4.909,.323),l(.917,-1.133),l(1.889,-.593),l(5.988,.013),l(.756,-.283),l(1.996,.108),l(-.432,-1.403),l(.054,-.809),l(1.232,-.36),l(.872,1.277),l(-.647,1.079),l(.805,.219),l(2.81,.482),l(5.262,.376),l(5.494,.344),l(2.278,.583),l(1.283,.14),l(1.396,-.167),l(2.204,.446),l(1.961,-.167),l(.719,.278),l(-.435,.431),l(-.151,.351),l(.293,.123),l(2.081,.331),l(1.078,.484),l(2.706,-.134),l(.377,.595),l(1.038,.227),l(4.808,.515),l(-.123,.536),l(.567,.236),l(2.695,-.095),l(3.214,.181),l(-.329,-.984),l(.71,-.095),l(.804,.426),l(.331,.709),l(1.135,.284),l(2.672,.519),l(2.576,-.343),l(4.017,.999),l(1.626,.495),l(1.672,.871),l(1.626,.023),l(.504,.187),l(.532,-.021),l(.754,-.047),l(.777,.047),l(.896,.589),l(.541,.118),l(.542,.07),l(.142,-.259),l(.471,0),l(1.484,-.048),l(1.416,.237),l(5.951,.535),l(.729,.516),l(1.733,.323),l(2.979,.944),l(.43,-.335),l(.551,.191),l(.454,.67),l(-.741,.215),l(-1.124,.167),l(-.216,.359),l(.168,.263),l(.55,-.048),l(-.024,.67),l(-.43,-.048),l(-.096,.287),l(-.312,.071),l(-.598,.622),l(-.526,.12),l(-.55,.287),l(-.168,.669),l(-1.603,.096),l(-1.339,-.239),l(-1.794,.359),l(-2.153,.425),l(-2.629,.764),l(1.271,1.103),l(-1.907,.212),l(-1.23,-.255),l(-.763,.212),l(-.043,.637),l(-2.374,.169),l(.136,.514),l(.924,.632),l(-.127,.763),l(-.382,.085),l(-.466,.467),l(.551,.466),l(.085,.764),l(-.764,.424),l(.637,.254),l(.763,0),l(.764,.255),l(.339,.509),l(.17,.721),l(1.284,-.187),l(.836,.907),l(2.035,.297),l(.339,.339),l(2.672,.552),l(-4.113,0),l(-2.799,.138),l(-2.332,.541),l(-1.823,-.085),l(-.806,.212),l(-1.611,.339),l(-1.326,-.32),l(-.546,.426),l(1.116,.529),l(-.503,.447),l(-.669,.195),l(-1.117,.753),l(-2.623,.642),l(.475,.391),l(2.205,-.111),l(.53,0),l(.809,.307),l(.168,.363),l(.499,.18),l(.422,.183),l(.111,.894),l(.209,.502),l(3.195,.279),l(2.874,.948),l(3.662,.801),l(5.151,1.202),l(1.456,.062),l(1.015,.17),l(-.146,.234),l(-1.67,.264),l(-.47,.264),l(1.173,.088),l(2.198,-.293),l(1.988,.166),
+E(0,0)
+};
+
+#undef N
+#undef M
+#undef L
+#undef l
+#undef E
diff --git a/perf/micro/zrusin-another.h b/perf/micro/zrusin-another.h
new file mode 100644
index 000000000..f6e72aed4
--- /dev/null
+++ b/perf/micro/zrusin-another.h
@@ -0,0 +1,668 @@
+/* The data in this file was created by Zack Rusin and downloaded from:
+
+ http://ktown.kde.org/~zrusin/examples/cairorender.tar.bz2
+
+ It is included in the cairo performance test suite by his
+ permission, (given in email to Carl Worth on 2006-10-23)
+*/
+point_t zrusin_another[] = {
+{107.893088734820,103.841923410053}, {106.908713734820,104.920048410053},
+{106.605078419636,105.201721390261}, {102.286079757931,107.612435141518},
+{95.848592904540,109.855345077872}, {95.820873452616,109.863161445001},
+{90.517184462013,111.170008329713}, {87.125000000000,111.625000000000},
+{82.393245921775,111.316572641568}, {77.855183975790,110.402282596173},
+{73.577390672683,108.898617908665}, {69.626442523093,106.822066623894},
+{69.373711344187,106.641023992165}, {57.717461344187,97.141023992165},
+{60.861283165549,97.153157587308}, {52.861026127481,102.679312400770},
+{43.297199733607,107.707604120505}, {38.061787185467,109.824994465236},
+{32.824736230810,111.354170438973}, {27.636335844151,112.281599723349},
+{22.546875000000,112.593750000000}, {19.478437557032,111.949288129016},
+{16.158848619890,110.212087077375}, {13.224557514711,107.109984243309},
+{12.401022392395,105.215121771751}, {12.109375000000,103.234375000000},
+{12.857968117079,98.340329228563}, {15.050447208669,93.495802782054},
+{18.606861885297,88.792446786896}, {23.447261757492,84.321912369510},
+{23.462751811761,84.309735859104}, {29.835792474114,80.170241641945},
+{36.826339837257,77.183700966953}, {44.355342734713,75.374150023260},
+{52.343750000000,74.765625000000}, {54.172214431835,74.493658379815},
+{55.005326273741,73.240819884599}, {54.891695624471,73.637732784350},
+{55.835419478567,69.288398667240}, {56.941029555972,65.553969608663},
+{57.993585771605,68.524034756036}, {53.681468264740,66.410473849442},
+{48.062136369578,64.586219029579}, {42.258612309644,63.317877950046},
+{37.437500000000,62.906250000000}, {32.573685233275,63.044800246717},
+{26.989159126193,63.632907811096}, {20.752015377001,64.279295952574},
+{16.562500000000,64.484375000000}, {16.408072340842,64.479600861137},
+{11.611197340842,64.182725861137}, {11.453516511116,64.167941148499},
+{6.725716011250,62.845442977500}, {4.607850691978,60.769517471259},
+{3.781250000000,57.859375000000}, {4.373461857036,55.042556375256},
+{5.951936001924,52.702230099626}, {6.143541831166,52.540844514692},
+{9.884650718045,51.301737345381}, {10.233131146503,51.254965794601},
+{14.936256146503,50.958090794601}, {15.093750000000,50.953125000000},
+{19.896489079886,51.056672881330}, {25.533897731570,51.448761318515},
+{25.296875000000,51.437500000000}, {30.909892241200,52.067729129895},
+{30.484375000000,52.031250000000}, {39.960841830525,52.410121686268},
+{48.752300459876,53.538988916016}, {48.757228534847,53.539874692156},
+{54.123571896675,54.731960341587}, {58.970980406852,56.270657465230},
+{63.248918806945,58.141504425356}, {66.906851838519,60.330039584234},
+{66.896289983187,60.322652661852}, {70.654761046586,63.581911162241},
+{73.423041490057,67.400928399521}, {75.133561184297,71.670457102504},
+{75.718750000000,76.281250000000}, {74.721151272876,79.892293861068},
+{72.068677652167,83.513297493231}, {70.325052633091,85.868624092784},
+{69.828125000000,88.250000000000}, {70.186304443223,90.552747673203},
+{71.326302526678,92.735137555366}, {73.346308881046,94.894011912335},
+{76.344513137007,97.126213009954}, {79.989627194854,99.164217236556},
+{83.789048154438,100.596188457783}, {87.811323321056,101.441306202608},
+{92.125000000000,101.718750000000}, {97.462586180660,101.070932456387},
+{97.557831952069,101.055648080491}, {103.015964519671,99.851433056816},
+{103.984375000000,99.656250000000}, {106.046875000000,99.656250000000},
+{107.893088734820,103.841923410053}, {106.046875000000,104.656250000000},
+{103.984375000000,104.656250000000}, {104.952785480329,104.461066943184},
+{98.254668047931,106.006851919509}, {98.349913819340,105.991567543613},
+{92.125000000000,106.718750000000}, {87.170121991444,106.371193797392},
+{82.386733095562,105.341311542217}, {77.843380617646,103.648282763444},
+{73.608611862993,101.311286990046}, {69.914433306454,98.422394337665},
+{67.154166223322,95.217987444634}, {65.426000244277,91.794908576797},
+{64.828125000000,88.250000000000}, {65.079958470471,86.099459712769},
+{65.803853616909,83.955594657216}, {68.478197347833,80.033577506769},
+{70.243692477124,77.869424888932}, {70.718750000000,76.281250000000},
+{70.335188815703,72.767042897496}, {69.139458509943,69.692821600479},
+{67.063988953414,66.949338837759}, {64.041210016813,64.427347338148},
+{64.030648161481,64.419960415766}, {57.122769593148,60.885592534770},
+{47.867771465153,58.460125307844}, {47.872699540124,58.461011083984},
+{39.531345669475,57.386753313732}, {30.484375000000,57.031250000000},
+{30.058857758800,56.994770870105}, {25.296875000000,56.437500000000},
+{25.059852268430,56.426238681485}, {19.697260920114,56.052702118670},
+{15.093750000000,55.953125000000}, {15.251243853497,55.948159205399},
+{10.548118853497,56.245034205399}, {10.896599281955,56.198262654619},
+{9.168958168834,56.521655485308}, {9.360563998076,56.360269900374},
+{8.781250000000,57.859375000000}, {8.758601803360,58.189255218076},
+{8.735899308021,58.292982528741}, {8.961783988750,58.373307022500},
+{12.077733488884,59.207058851501}, {11.920052659158,59.192274138863},
+{16.716927659158,59.489149138863}, {16.562500000000,59.484375000000},
+{20.310484622999,59.298829047426}, {26.432715873807,58.663967188904},
+{32.129439766725,58.064574753283}, {37.437500000000,57.906250000000},
+{42.956231440356,58.377434549954}, {49.359738630422,59.757530970421},
+{55.603687985260,61.808276150558}, {60.600164228395,64.257215243964},
+{61.652720444028,67.227280391337}, {60.695830521433,70.461601332760},
+{59.795804375529,74.612267215650}, {59.682173726259,75.009180115401},
+{58.534870256371,76.967235761415}, {56.827785568165,78.467279120185},
+{54.713289027441,79.427384197713}, {52.343750000000,79.765625000000},
+{45.078251015287,80.284053101740}, {38.408035162743,81.855361533047},
+{32.254051275886,84.503586483055}, {26.537248188239,88.252764140896},
+{26.552738242508,88.240587630490}, {22.301341239703,92.064975088104},
+{19.363615291331,95.777634717946}, {17.659610007921,99.470217646437},
+{17.109375000000,103.234375000000}, {17.462942485289,104.745484506691},
+{18.934901380110,106.053537922625}, {21.052812442968,107.257743120984},
+{22.546875000000,107.593750000000}, {27.127336030849,107.323869026651},
+{31.729951269190,106.505204561027}, {36.405009689533,105.124224284764},
+{41.202800266393,103.167395879495}, {50.256161372519,98.422250099230},
+{57.732466834451,93.253092412692}, {60.876288655813,93.265226007835},
+{72.532538655813,102.765226007835}, {72.279807476907,102.584183376106},
+{75.647218702317,104.376772716335}, {79.199503524210,105.636779903827},
+{83.003238453225,106.380692983432}, {87.125000000000,106.625000000000},
+{94.491626547384,105.043088554999}, {94.463907095460,105.050904922128},
+{100.135795242069,103.121939858482}, {103.519921580364,101.267028609739},
+{103.216286265180,101.548701589947}, {104.200661265180,100.470576589947},
+{106.046875000000,104.656250000000}, {107.893088734820,103.841923410053},
+{55.872490683787,89.763134548637}, {54.997490683787,85.841259548637},
+{55.036476188094,85.993355189713}, {52.343750000000,85.750000000000},
+{46.702141892082,86.180801752650}, {41.285068752391,87.490050907175},
+{36.021375201732,89.703013308437}, {30.839905860908,92.844954801298},
+{30.840393168266,92.844613599752}, {24.841774707763,97.553563991314},
+{23.093750000000,100.109375000000}, {23.668337709691,101.518994849695},
+{23.371174656526,101.224323797050}, {23.620948599883,101.397798979282},
+{24.023420115060,101.552272092059}, {25.484375000000,101.718750000000},
+{29.298199671143,101.348354407082}, {33.545396502623,100.218839979757},
+{38.283160693967,98.302715245167}, {43.568687444697,95.572488730454},
+{43.462444284634,95.635929361188}, {56.978069284634,87.104679361188},
+{55.872490683787,89.763134548637}, {107.893088734820,103.841923410053},
+{59.646930715366,91.332820638812}, {46.131305715366,99.864070638812},
+{46.025062555303,99.927511269546}, {40.294964306033,102.857441004833},
+{34.923353497377,104.984285020243}, {29.967425328857,106.280551842918},
+{25.484375000000,106.718750000000}, {22.429704884940,106.291477907941},
+{20.160075343474,105.056926202950}, {19.862912290309,104.762255150305},
+{18.581942192719,102.559691058502}, {18.093750000000,100.109375000000},
+{18.781885833597,97.630167914546}, {20.751975292237,94.868311008686},
+{27.972106831734,88.749136400248}, {27.972594139092,88.748795198702},
+{33.744249798268,85.287221066563}, {39.777431247609,82.783386592825},
+{46.000983107918,81.262557622350}, {52.343750000000,80.750000000000},
+{54.881053553302,80.995299290410}, {57.121823397686,81.724997675285},
+{58.847249996203,82.929795925088}, {59.838523811906,84.600394810287},
+{59.877509316213,84.752490451363}, {60.752509316213,88.674365451363},
+{59.646930715366,91.332820638812}, {107.893088734820,103.841923410053},
+{155.484375000000,101.859375000000}, {154.564834615754,105.515207938449},
+{152.115670325806,108.366761454651}, {148.955163295626,109.891294781728},
+{145.437500000000,110.437500000000}, {142.960397099416,109.918703000637},
+{140.390467597390,108.438024620128}, {137.806753458193,106.109033784838},
+{135.288296646094,103.045299421136}, {135.165845369106,102.859481271949},
+{127.322095369106,89.718856271949}, {127.315939322101,89.708486304067},
+{123.037165252408,83.240466071649}, {119.422893480005,79.457711309224},
+{123.333764624626,78.181432151290}, {119.923748586047,88.267600564284},
+{116.288451493331,96.371224650234}, {116.310270123205,96.328970526240},
+{111.013619195867,105.085481651574}, {104.498474377631,112.833853093888},
+{102.718750000000,113.578125000000}, {98.109375000000,113.578125000000},
+{95.790533815800,112.012456612681}, {92.715536961613,101.759617602767},
+{90.624767168816,88.808240839597}, {90.625938562396,88.818553777181},
+{88.018863793847,68.357428789163}, {88.022375537533,68.374401202625},
+{86.904794319936,64.234191072834}, {85.466909526601,60.964474099786},
+{83.670654326939,58.467433589062}, {81.477961890361,56.645252846242},
+{80.463845731714,53.674615230649}, {82.823220731714,47.205865230649},
+{82.883587418943,47.055653464335}, {83.966380643129,44.754922491868},
+{85.291281927099,42.535861182972}, {88.514402164445,41.595109434025},
+{91.785870247761,43.817111177877}, {94.599270325866,47.029404143594},
+{96.906293571887,51.130222797294}, {98.658631158949,56.017801605095},
+{98.664492355983,56.039251079522}, {100.006630671722,63.228131068770},
+{101.762541190731,76.272848032637}, {101.765778670251,76.300425005941},
+{103.467098832178,87.353480411923}, {105.697048617918,94.795754781373},
+{102.319980907406,93.545204629259}, {104.354680083199,92.248641487426},
+{106.296883956259,90.334282557687}, {110.081726403105,84.371439341729},
+{110.069085073875,84.396782220394}, {112.413266990492,78.560599894318},
+{114.080111889746,71.934817013191}, {115.075734612596,64.464258680566},
+{115.406250000000,56.093750000000}, {117.906250000000,53.593750000000},
+{122.515625000000,53.593750000000}, {124.596624760838,54.708311442938},
+{155.065374760838,100.473936442938}, {155.484375000000,101.859375000000},
+{107.893088734820,103.841923410053}, {150.903375239162,103.244813557062},
+{120.434625239162,57.479188557062}, {122.515625000000,58.593750000000},
+{117.906250000000,58.593750000000}, {120.406250000000,56.093750000000},
+{120.037546637404,64.922460069434}, {118.935513110254,72.987057986809},
+{117.106264259508,80.232368855682}, {114.555914926125,86.603217779606},
+{114.543273596895,86.628560658271}, {112.308927321184,90.508291033149},
+{109.859366043741,93.751654942313}, {107.239069916801,96.288467887574},
+{104.492519092594,98.048545370741}, {101.115451382082,96.797995218627},
+{98.626651167822,88.552769588077}, {96.796721329749,76.855824994059},
+{96.799958809269,76.883401967363}, {95.087119328278,64.107806431230},
+{93.835507644017,57.335748920478}, {93.841368841051,57.357198394905},
+{92.427690803113,53.221339702706}, {90.736667174134,50.033095856406},
+{88.719989127239,47.690701322123}, {86.329347835555,46.092390565975},
+{89.552468072901,45.151638817028}, {88.346119356871,47.166952508132},
+{87.460162581057,49.069346535665}, {87.520529268286,48.919134769351},
+{85.161154268286,55.387884769351}, {84.147038109639,52.417247153758},
+{87.106689423061,54.909519535937}, {89.579965473399,58.293338400214},
+{91.528799430064,62.470887052166}, {92.915124462467,67.344348797375},
+{92.918636206153,67.361321210837}, {95.592811437604,88.243946222819},
+{95.593982831184,88.254259160403}, {97.565713038387,100.591944897233},
+{100.428216184200,110.143793387319}, {98.109375000000,108.578125000000},
+{102.718750000000,108.578125000000}, {100.939025622369,109.322396906112},
+{106.962943304133,102.180143348427}, {111.845979876795,94.077279473760},
+{111.867798506669,94.035025349766}, {115.287188913953,86.412086935716},
+{118.541235375374,76.756067848710}, {122.452106519995,75.479788690776},
+{126.837834747592,80.025158928351}, {131.621560677899,87.166513695933},
+{131.615404630894,87.156143728051}, {139.459154630894,100.296768728051},
+{139.336703353906,100.110950578864}, {142.906407402610,104.257287879872},
+{145.437500000000,105.437500000000}, {147.478430454374,105.175111468272},
+{149.243704674194,104.273863545349}, {150.251571634246,103.277760811551},
+{150.484375000000,101.859375000000}, {150.903375239162,103.244813557062},
+{107.893088734820,103.841923410053}, {231.343750000000,91.875000000000},
+{230.760913847107,95.964970754466}, {229.068047862611,99.735912943733},
+{226.348615757792,103.075786207286}, {222.686081243924,105.872550184609},
+{222.648873373705,105.894655312846}, {215.093162016193,109.098726800095},
+{205.138412990776,111.389009633945}, {205.099511514392,111.395066324151},
+{196.531910121565,112.292873746127}, {187.093750000000,112.593750000000},
+{180.736641615184,112.156201510495}, {174.578395035074,110.855968371846},
+{168.685194057574,108.711669078852}, {163.123222480588,105.741922126310},
+{163.102786019362,105.728945017668}, {158.065383006950,101.833715472335},
+{154.350564084671,97.489870440862}, {152.052565874896,92.798170193375},
+{151.265625000000,87.859375000000}, {151.531470468770,85.013668760581},
+{152.287360086651,82.060400295498}, {152.321821893194,81.964698849566},
+{155.704155919825,73.828381186220}, {158.270837388345,69.249451319292},
+{158.258242073026,69.265568807584}, {162.161895999987,65.281962610977},
+{167.278829839386,61.794937132641}, {173.532669176810,58.834467171163},
+{180.847039597849,56.430527525129}, {179.144548452656,58.005986305326},
+{180.222673452656,54.974736305326}, {180.222279555972,54.975844608663},
+{182.650011718926,50.400876966176}, {185.678714551395,49.466466465483},
+{192.833058049629,52.996232862321}, {201.831199616962,58.692914409530},
+{211.602112156950,65.789874557518}, {220.243790039283,73.085988470431},
+{220.250361498213,73.092084369790}, {227.553434625305,81.089470457139},
+{229.783449199558,84.667905408782}, {230.987849850362,87.897461316292},
+{231.037603485703,88.222391630780}, {231.334478485703,91.659891630780},
+{231.343750000000,91.875000000000}, {107.893088734820,103.841923410053},
+{226.353021514297,92.090108369220}, {226.056146514297,88.652608369220},
+{226.105900149638,88.977538683708}, {225.181394550443,86.544985216218},
+{223.368440374695,83.730842042861}, {216.843388501787,76.751665630210},
+{216.849959960717,76.757761529569}, {208.538512843050,69.741375442482},
+{199.012550383038,62.822710590470}, {190.370066950371,57.347517137679},
+{183.790035448605,54.096033534517}, {186.818738281074,53.161623033824},
+{184.933970444028,56.649155391337}, {184.933576547344,56.650263694674},
+{183.855451547344,59.681513694674}, {182.152960402151,61.256972474871},
+{175.418502698190,63.429204703837}, {169.900857660614,65.978500367359},
+{165.523650875013,68.934834264023}, {162.210507926974,72.328181192416},
+{162.197912611655,72.344298680708}, {160.116156580175,76.155993813780},
+{156.990678106806,83.754051150434}, {157.025139913349,83.658349704502},
+{156.265625000000,87.859375000000}, {156.814621625104,91.570970431625},
+{158.524435915329,95.017942059138}, {161.489304493050,98.301050152665},
+{165.803463980638,101.521054982332}, {165.783027519412,101.508077873690},
+{170.773790317426,104.198487171148}, {175.945042464926,106.097156628154},
+{181.362967759816,107.222704739505}, {187.093750000000,107.593750000000},
+{196.179027378435,107.308688753873}, {204.369238485608,106.448683675849},
+{204.330337009224,106.454740366055}, {213.484962983807,104.385648199905},
+{220.132376626295,101.574094687154}, {220.095168756076,101.596199815391},
+{222.954118617208,99.523823167714}, {224.892889637389,97.287524556267},
+{225.994945527893,94.775263620534}, {226.343750000000,91.875000000000},
+{226.353021514297,92.090108369220}, {107.893088734820,103.841923410053},
+{219.781250000000,95.890625000000}, {219.378166433508,93.853798730227},
+{218.111752188172,91.489941446073}, {212.645950385807,85.475693519170},
+{212.685981945341,85.511936058310}, {206.545320157918,80.643069684901},
+{198.180220478697,74.962876659750}, {198.191932106006,74.970352872652},
+{191.582535336704,71.037624006410}, {191.504903114611,70.993386859602},
+{190.358726480976,70.329891393482}, {194.093750000000,68.156250000000},
+{193.486799914207,72.326466575586}, {191.750022838432,75.648693620488},
+{191.727672642897,75.674671879974}, {189.796209835616,77.308949639626},
+{187.307360975056,78.497446987452}, {184.374093537693,79.223076311545},
+{181.109375000000,79.468750000000}, {178.539517280969,79.274893727068},
+{176.586499975916,78.676142180991}, {173.086052480141,74.877460550577},
+{176.026873378540,75.790765650642}, {173.637934677835,76.966105971818},
+{171.454775584042,78.628861257931}, {167.479150931130,83.659399177979},
+{167.492959438562,83.636441477986}, {164.707555748674,89.579684053440},
+{164.890625000000,88.640625000000}, {165.429801946489,91.718738201013},
+{167.140367049889,94.413281660069}, {170.161871706101,96.828214751252},
+{174.633867311024,99.067496848641}, {174.595883286589,99.052025896332},
+{183.311717611230,101.570655775842}, {188.036065935963,102.270678900324},
+{192.781250000000,102.500000000000}, {204.722829878151,102.082467436594},
+{212.458857303872,100.833616072622}, {214.905535432122,99.897801735668},
+{216.940228691241,98.604487224303}, {220.087216056537,94.692203098109},
+{219.781250000000,95.890625000000}, {107.893088734820,103.841923410053},
+{224.475283943463,97.089046901891}, {222.495392805158,99.992428606532},
+{220.012896308759,102.426762775697}, {217.106183317878,104.328760764332},
+{213.853642696128,105.635133927378}, {205.324045121849,107.034720063406},
+{192.781250000000,107.500000000000}, {187.549871564037,107.241039849676},
+{182.344532388770,106.476219224158}, {172.747866713411,103.697974103668},
+{172.709882688976,103.682503151359}, {167.310784543899,100.802644623748},
+{163.281507950111,97.266405839931}, {160.761604303511,93.177746173987},
+{160.111277146626,90.958745814619}, {159.890625000000,88.640625000000},
+{160.073694251326,87.701565946560}, {163.194540561438,81.082308522014},
+{163.208349068870,81.059350822021}, {165.573405849355,77.703241627766},
+{168.240536915958,74.886763742069}, {171.153080947165,72.670612778182},
+{174.254376621460,71.115484349358}, {177.195197519859,72.028789449423},
+{178.991625024084,74.292607819009}, {181.109375000000,74.468750000000},
+{185.450451524944,73.971303012548}, {187.959827357103,72.387828120026},
+{187.937477161568,72.413806379512}, {188.825700085793,70.736033424413},
+{189.093750000000,68.156250000000}, {192.828773519024,65.982608606518},
+{194.057596885389,66.694113140398}, {193.979964663296,66.649875993590},
+{200.870567893994,70.748397127348}, {200.882279521303,70.755873340250},
+{209.532804842082,76.638180315099}, {216.001518054659,81.769313941690},
+{216.041549614192,81.805556480830}, {219.736550554799,85.597619431325},
+{222.481997811828,89.260058553927}, {224.192146066492,92.716513769773},
+{224.781250000000,95.890625000000}, {224.475283943463,97.089046901891},
+{107.893088734820,103.841923410053}, {274.375000000000,74.921875000000},
+{274.375000000000,76.000000000000}, {273.941340954992,77.877573018672},
+{272.878932097861,79.515803527315}, {273.201644884750,79.109789854043},
+{272.240878131027,80.634530144823}, {272.178064435979,80.731878545843},
+{270.366672394243,82.164949472839}, {268.046875000000,82.703125000000},
+{266.183148747233,82.484226579792}, {265.676843902484,82.347511014208},
+{261.919943241226,81.056638412991}, {261.845529920936,81.035610157726},
+{257.771892015055,80.000491652766}, {254.812500000000,79.671875000000},
+{253.064641952966,80.017766952966}, {253.029646790629,80.052082662255},
+{253.183319188544,79.921363850038}, {253.251518993920,79.984611568497},
+{253.185946392942,81.106825858762}, {253.000000000000,86.578125000000},
+{253.496255380785,102.128843883245}, {253.498940253820,102.192840332413},
+{254.068093288267,110.651263719025}, {251.578125000000,113.375000000000},
+{246.875000000000,113.375000000000}, {246.340326851360,113.317155732979},
+{244.239667843345,112.409341061474}, {241.449240399376,110.489665586259},
+{233.966932708158,103.861287459859}, {233.964253154933,103.858697290509},
+{230.739570245917,99.429986748935}, {227.863465886694,92.900734302334},
+{227.865566738278,92.906614054351}, {224.904456445713,83.297192679644},
+{223.890625000000,76.390625000000}, {224.718172891760,73.652424627265},
+{226.991950628026,71.671512863124}, {230.398659300280,70.468125917422},
+{234.625000000000,70.062500000000}, {239.436000436064,69.828681464349},
+{240.453125000000,69.140625000000}, {239.621272369169,63.470278877568},
+{237.983036171748,55.833595299706}, {237.978023315197,55.813489579321},
+{235.265625000000,42.968750000000}, {235.414374888933,43.818233911095},
+{223.164374888933,9.911983911095}, {223.454623060848,7.647483743269},
+{225.610873060848,4.506858743269}, {225.803351703291,4.260965402925},
+{227.719534150475,2.932735689909}, {230.078782966130,2.347671229322},
+{230.218750000000,2.343750000000}, {231.580832848366,2.789728316683},
+{232.871346377781,3.980786060276}, {235.131457239225,7.716876589460},
+{240.051188613236,19.745668022304}, {244.970104457946,33.805503176211},
+{247.762510801176,44.143184476801}, {247.777764624530,44.225329525617},
+{252.184014624530,70.381579525617}, {251.352799675865,68.904817480577},
+{254.575226795957,69.673348314939}, {260.406250000000,70.359375000000},
+{270.523910039912,70.690857394210}, {273.186407177161,72.174765791999},
+{274.049624252688,73.457293811137}, {274.375000000000,74.921875000000},
+{107.893088734820,103.841923410053}, {269.375000000000,74.921875000000},
+{269.694839960088,75.621642605790}, {260.406250000000,75.359375000000},
+{253.596648204043,74.576651685061}, {250.197596782742,73.718304003256},
+{248.084700324135,72.688932519423}, {247.253485375470,71.212170474383},
+{242.847235375470,45.055920474383}, {242.862489198824,45.138065523199},
+{240.182239292054,35.233559323790}, {235.370686386764,21.504331977696},
+{230.614636510775,9.861248410540}, {229.674552059719,7.679370189724},
+{229.774391761009,7.390935745817}, {230.218750000000,7.343750000000},
+{230.358717033870,7.339828770678}, {229.540398296709,7.582784597075},
+{229.732876939152,7.336891256731}, {227.576626939152,10.477516256731},
+{227.866875111067,8.213016088905}, {240.116875111067,42.119266088905},
+{240.265625000000,42.968750000000}, {242.834476684803,54.624010420679},
+{242.829463828252,54.603904700294}, {244.534977630831,62.545346122432},
+{245.453125000000,69.140625000000}, {244.611402180226,71.735213821357},
+{242.306187063936,73.585381035651}, {238.867409665678,74.693638982119},
+{234.625000000000,75.062500000000}, {229.906486871974,75.367549636876},
+{229.092373983240,75.779215997735}, {228.934535185216,76.058687905577},
+{228.890625000000,76.390625000000}, {229.790856054287,82.319994820356},
+{232.571933261722,91.218385945649}, {232.574034113306,91.224265697666},
+{234.986992254083,96.851263251065}, {237.441996845067,100.266302709491},
+{237.439317291842,100.263712540141}, {244.074197100624,106.275959413741},
+{247.409673148640,108.432844267021}, {246.875000000000,108.375000000000},
+{251.578125000000,108.375000000000}, {249.088156711733,111.098736280975},
+{248.501059746180,102.338409667587}, {248.503744619215,102.402406116755},
+{248.000000000000,86.578125000000}, {248.204678607058,80.674424141238},
+{248.635199756080,78.226325931503}, {249.564103209371,76.447917337745},
+{249.529108047034,76.482233047034}, {251.855421271850,75.142541341903},
+{254.812500000000,74.671875000000}, {258.571857984945,75.077633347234},
+{263.279470079064,76.245639842274}, {263.205056758774,76.224611587009},
+{267.479406097516,77.683738985792}, {266.973101252767,77.547023420208},
+{268.046875000000,77.703125000000}, {268.247054721136,77.733964370993},
+{268.227077605757,77.803800527161}, {268.040685564021,77.924371454157},
+{267.977871868973,78.021719855177}, {268.985855115250,76.421460145957},
+{269.308567902139,76.015446472685}, {269.418034045008,75.973989481328},
+{269.375000000000,76.000000000000}, {269.375000000000,74.921875000000},
+{107.893088734820,103.841923410053}, {243.911209450369,105.662056821622},
+{240.832004992147,102.845101845416}, {236.815516984936,97.742848726260},
+{236.813922800164,97.740633958664}, {232.773597278734,91.287437871638},
+{230.710552894044,85.924483215760}, {230.745327869205,86.067653416413},
+{229.840275149638,82.415038683708}, {229.855893749637,82.481339062591},
+{229.093750000000,78.546875000000}, {229.510257350732,77.264688549054},
+{230.557731326090,76.286764971873}, {233.333290689663,75.138571514324},
+{238.843750000000,74.468750000000}, {241.980836948934,74.687319511759},
+{245.189547085049,75.561169162745}, {247.167986856352,77.549353232692},
+{248.217702574415,80.638507879225}, {248.687500000000,88.140625000000},
+{248.194671228610,98.736670034806}, {248.200295344311,98.650162873539},
+{247.698246960594,103.850772804200}, {243.911209450369,105.662056821622},
+{107.893088734820,103.841923410053}, {242.739253039406,103.211727195800},
+{243.205954655689,98.412337126461}, {243.211578771390,98.325829965194},
+{243.687500000000,88.140625000000}, {243.282297425585,81.439617120775},
+{243.185452914951,80.141955837255}, {241.300413051066,79.640805488241},
+{238.843750000000,79.468750000000}, {234.557334310337,79.986428485676},
+{234.323615830224,80.043375869145}, {234.139295619945,80.082650511165},
+{233.899908001681,80.106538837663}, {233.805549923910,79.924172528127},
+{234.093750000000,78.546875000000}, {234.706606250363,81.268660937409},
+{234.722224850362,81.334961316292}, {235.567172130795,84.744846583587},
+{235.601947105956,84.888016784240}, {237.273277721266,89.165687128362},
+{240.873577199836,94.821866041336}, {240.871983015064,94.819651273740},
+{244.355495007853,99.326773154584}, {246.526290549631,101.400443178378},
+{242.739253039406,103.211727195800}, {107.893088734820,103.841923410053},
+{304.579027849556,115.887559254375}, {299.647333003501,118.498603127587},
+{299.601234810263,118.526555579345}, {296.960609810263,120.089055579345},
+{295.687500000000,120.437500000000}, {292.434178516679,119.763451801101},
+{289.591538470777,117.850158805700}, {287.263626957927,114.860898415742},
+{285.554491073762,110.958948033170}, {285.546168760441,110.932189402305},
+{283.409425227272,100.413450166388}, {283.408069329655,100.405281467271},
+{280.968147929764,87.644193704042}, {284.218299056292,87.914012723915},
+{279.519746335556,93.766171451312}, {279.798545332977,93.224824860858},
+{274.937093489612,105.343910553875}, {272.454127837569,109.762553039486},
+{269.772550129691,112.314814767144}, {266.294988321147,110.999865652887},
+{264.699764075525,105.167535274279}, {264.676753039406,105.022647804200},
+{264.221109604112,100.702343060691}, {264.171875000000,98.828125000000},
+{263.607902205199,91.869081828698}, {263.613915250645,91.062865437610},
+{263.781250000000,89.718750000000}, {263.644962649638,88.985351183708},
+{262.873500431741,86.703985451358}, {262.739182179139,86.219942105230},
+{260.786057179139,74.844942105230}, {260.786249814804,74.846062487964},
+{256.958124814804,52.611687487964}, {256.955473276820,52.595988114755},
+{254.892973276820,40.142863114755}, {254.909488793847,40.232428789163},
+{254.331363793847,37.388678789163}, {254.339079247810,37.425229542768},
+{253.651579247810,34.284604542768}, {253.593750000000,33.750000000000},
+{254.239654341050,30.319069019177}, {254.154681406546,30.589185956325},
+{256.319133024351,26.771372253672}, {258.818704827809,25.924919245868},
+{261.217531024880,26.988383072536}, {263.253153025566,28.888095452080},
+{264.856582863559,31.480336604342}, {265.958832572550,34.621386749163},
+{266.013105788729,34.918097636045}, {267.200714432551,44.731495841479},
+{267.198350954149,44.712535224402}, {269.443623734153,61.037071609407},
+{269.421396014347,60.906344576785}, {270.652021489737,67.736566992690},
+{271.992261513603,76.440263813345}, {271.992747064473,76.443809223415},
+{273.038636247453,85.686082548185}, {273.390625000000,92.953125000000},
+{273.238407027301,96.898129287691}, {272.771685367998,99.590064317759},
+{267.989237947004,98.132898258783}, {271.223612947004,86.961023258783},
+{271.391159168632,86.533772766328}, {274.526090303798,81.379570646076},
+{274.584318175231,81.310286998919}, {276.982682022500,78.600716011250},
+{277.142029400154,78.326905342657}, {279.265919333198,75.301911531816},
+{279.298622345235,75.258362091268}, {281.876153531632,73.009942282517},
+{284.906250000000,72.125000000000}, {287.318073492888,72.767987310135},
+{289.339116026344,74.544184270464}, {290.903803647217,77.224443425871},
+{291.946562402359,80.579617321243}, {291.963278527291,80.666832095730},
+{293.477578855570,88.491377103079}, {294.532438780850,92.026218792971},
+{294.690170210143,92.371639700252}, {298.832669585147,102.687317191341},
+{298.821447919079,102.663322107333}, {301.483679194839,107.248880594573},
+{302.541048238599,108.202972500861}, {303.515625000000,108.484375000000},
+{306.015625000000,110.984375000000}, {306.015625000000,113.625000000000},
+{304.579027849556,115.887559254375}, {107.893088734820,103.841923410053},
+{301.015625000000,113.625000000000}, {301.015625000000,110.984375000000},
+{303.515625000000,113.484375000000}, {300.984342386401,112.859527499139},
+{298.555383305161,111.094869405427}, {296.303526841571,108.355227332168},
+{294.303552080921,104.805427892667}, {294.292330414853,104.781432808659},
+{289.997329789857,94.097110299748}, {290.155061219150,94.442531207029},
+{288.709921144430,89.953935396921}, {287.036721472709,81.520667904270},
+{287.053437597641,81.607882678757}, {286.004633973656,77.940190729536},
+{284.906250000000,77.125000000000}, {284.500063101353,77.160595459408},
+{284.155096468369,77.318182717483}, {283.263877654765,78.304137908732},
+{283.296580666802,78.260588468184}, {281.295470599846,81.110594657343},
+{281.454817977500,80.836783988750}, {278.353181824769,84.595963001081},
+{278.411409696202,84.526679353924}, {275.858840831368,88.778727233672},
+{276.026387052996,88.351476741217}, {272.792012052996,99.523351741217},
+{268.009564632002,98.066185682241}, {268.390625000000,92.953125000000},
+{268.055113752547,86.056104951815}, {267.038502935527,77.118690776585},
+{267.038988486397,77.122236186655}, {265.722978510263,68.575933007310},
+{264.516103985653,61.874905423215}, {264.493876265847,61.744178390593},
+{262.239149045851,45.349964775598}, {262.236785567449,45.331004158521},
+{261.049394211271,35.519402363955}, {261.103667427450,35.816113250837},
+{259.699971974434,32.150967047920}, {257.681295172191,30.793830754132},
+{260.180866975649,29.947377746328}, {259.001568593454,31.817064043675},
+{258.916595658950,32.087180980823}, {258.593750000000,33.750000000000},
+{258.535920752190,33.215395457232}, {259.223420752190,36.356020457232},
+{259.231136206153,36.392571210837}, {259.809261206153,39.236321210837},
+{259.825776723180,39.325886885245}, {261.888276723180,51.779011885245},
+{261.885625185196,51.763312512036}, {265.713750185196,73.997687512036},
+{265.713942820861,73.998807894770}, {267.667067820861,85.373807894770},
+{267.532749568259,84.889764548642}, {268.526912350362,87.905273816292},
+{268.781250000000,89.718750000000}, {268.542334749355,91.905884562390},
+{268.548347794801,91.099668171302}, {269.171875000000,98.828125000000},
+{269.216390395888,100.485156939309}, {269.635746960594,104.383602195800},
+{269.612735924475,104.238714725721}, {270.955011678853,109.187634347113},
+{267.477449870309,107.872685232856}, {268.686497162431,106.569478210514},
+{270.375406510388,103.296714446125}, {275.107704667023,91.493925139142},
+{275.386503664444,90.952578548688}, {278.700840527029,86.470174071108},
+{281.281700943708,83.867237276085}, {284.531852070236,84.137056295958},
+{285.408419686884,85.805066273498}, {286.324716189650,88.997159604327},
+{288.341930670345,99.594718532729}, {288.340574772728,99.586549833612},
+{290.328831239559,109.474060597695}, {290.320508926238,109.447301966830},
+{291.419966792073,112.312929709258}, {292.611586529223,114.157653694300},
+{293.999415233321,115.144751323899}, {295.687500000000,115.437500000000},
+{294.414390189737,115.785944420655}, {297.055015189737,114.223444420655},
+{297.008916996499,114.251396872413}, {302.452222150444,111.362440745625},
+{301.015625000000,113.625000000000}, {107.893088734820,103.841923410053},
+{374.437500000000,106.765625000000}, {373.775309600600,109.463093710969},
+{372.064906958700,112.117295697199}, {372.041004786215,112.144602045402},
+{368.522704503395,114.706400007155}, {366.442611342446,115.399541345014},
+{364.281250000000,115.640625000000}, {355.911205219123,114.726652651698},
+{341.052591424867,111.966274658224}, {341.038040421249,111.963294783992},
+{326.905309277070,108.757693347762}, {319.727026481732,106.439595965247},
+{319.807037817648,106.479160754059}, {310.484453831953,101.696158824691},
+{304.482826587959,97.721718623918}, {304.310358047034,97.564641952966},
+{302.095819571999,95.254869206705}, {298.220153609739,90.667578419636},
+{300.367638895226,91.618501549714}, {296.258263895226,91.915376549714},
+{296.078125000000,91.921875000000}, {293.025957236218,91.709450913344},
+{290.151865257421,91.083888117023}, {285.254658796565,88.663603177256},
+{285.219422230119,88.636374171395}, {281.529900243089,84.536170132203},
+{280.513144708967,82.282593311151}, {280.156250000000,80.015625000000},
+{280.896516775664,77.119922391977}, {282.806537684315,74.726645730656},
+{285.448073147177,73.263018105533}, {288.686079158715,72.443690273534},
+{290.750793112766,73.122099563886}, {293.797668112766,76.059599563886},
+{293.736465601749,76.002539206463}, {295.798965601749,77.861914206463},
+{294.222063773555,77.220634985862}, {301.862688773555,77.517509985862},
+{299.265625000000,80.015625000000}, {299.934685624955,74.754308742711},
+{301.898213943218,69.792099871114}, {305.090729619888,65.230982029954},
+{309.446752320064,61.172938863978}, {309.482902906976,61.145713152252},
+{318.065904047846,56.213131631660}, {329.455658353400,51.953267244508},
+{329.496351456999,51.941186017188}, {336.615241964605,50.572965088062},
+{336.666137267666,50.568817238037}, {342.150512267666,50.178192238037},
+{342.328125000000,50.171875000000}, {347.088673798588,50.461178987176},
+{351.635436696472,51.319590054257}, {355.904450990616,52.732856859568},
+{359.831753977986,54.686728061438}, {363.292951645549,57.250115143707},
+{365.880587968213,60.272932122861}, {367.501493801268,63.647371305944},
+{368.062500000000,67.265625000000}, {367.659428864193,69.524372763002},
+{366.507997055207,71.901249483478}, {362.306741008310,76.690232523947},
+{362.309449580203,76.687848273793}, {355.067416613929,81.592460070084},
+{345.579434368324,85.619156329617}, {345.543296906352,85.631025936969},
+{338.856518222681,87.434049611292}, {331.674077585810,88.726763309129},
+{324.032609882622,89.505258086643}, {315.968750000000,89.765625000000},
+{315.697255981477,89.750839477245}, {313.837880981477,89.547714477245},
+{314.109375000000,89.562500000000}, {315.203325765838,88.142787621838},
+{315.234375000000,87.750000000000}, {315.261368553241,87.459370280378},
+{315.416652198286,87.453346686481}, {316.557907675735,88.522399326740},
+{316.429841220906,88.403882310796}, {319.273591220906,90.857007310796},
+{318.935343465338,90.611377991437}, {331.091593465338,97.970752991437},
+{330.612118984109,97.746034726917}, {334.956642245028,98.975789357391},
+{339.851927078584,99.850564497063}, {351.453125000000,100.546875000000},
+{354.203872313810,100.381670729150}, {355.159915151904,99.886038066767},
+{355.055436157189,100.055596900919}, {357.900435727416,97.290434866877},
+{362.379803562479,95.425955323112}, {363.015625000000,95.343750000000},
+{366.828125000000,95.343750000000}, {368.997562855593,96.601357392681},
+{374.106937855593,105.523232392681}, {374.437500000000,106.765625000000},
+{107.893088734820,103.841923410053}, {369.768062144407,108.008017607319},
+{364.658687144407,99.086142607319}, {366.828125000000,100.343750000000},
+{363.015625000000,100.343750000000}, {363.651446437521,100.261544676888},
+{360.724564272584,101.303315133123}, {359.413313842811,102.506903099081},
+{359.308834848096,102.676461933233}, {358.021570604282,103.932262067178},
+{356.186752686190,104.829266770850}, {351.453125000000,105.546875000000},
+{345.006190631125,105.353277680068}, {339.085572921416,104.774435502937},
+{333.730857754972,103.813273142609}, {328.981631015891,102.472715273083},
+{328.502156534662,102.247997008563}, {316.345906534662,94.888622008563},
+{316.007658779094,94.642992689204}, {313.163908779094,92.189867689204},
+{313.035842324265,92.071350673260}, {311.083347801714,89.820090813519},
+{310.234375000000,87.750000000000}, {310.265424234162,87.357212378162},
+{310.780311953087,86.191927459145}, {311.752715552710,85.312201869144},
+{314.109375000000,84.562500000000}, {314.380869018523,84.577285522755},
+{316.240244018523,84.780410522755}, {315.968750000000,84.765625000000},
+{323.705671367377,84.524038788357}, {330.935297414190,83.796674190871},
+{337.694263027319,82.579622263708}, {344.019203093648,80.868974063031},
+{343.983065631676,80.880843670383}, {352.635708386071,77.251289929916},
+{359.003050419797,72.937151726207}, {359.005758991690,72.934767476053},
+{362.163877944793,69.637813016522}, {363.062500000000,67.265625000000},
+{362.747529636232,64.880949006556}, {361.740505781787,62.777849127139},
+{359.948259291951,60.848517668793}, {357.277621022014,58.985146938562},
+{353.920744321884,57.295463452932}, {350.352844553528,56.106191195743},
+{346.509959013911,55.403078825324}, {342.328125000000,55.171875000000},
+{342.505737732334,55.165557761963}, {337.021362732334,55.556182761963},
+{337.072258035395,55.552034911938}, {330.878648543001,56.746313982812},
+{330.919341646600,56.734232755492}, {320.246595952154,60.693118368340},
+{312.454597093024,65.166786847748}, {312.490747679936,65.139561136022},
+{308.794036005112,68.485814845046}, {306.234598556782,72.012587628886},
+{304.746955000045,75.821863132289}, {304.265625000000,80.015625000000},
+{301.668561226445,82.513740014138}, {294.027936226445,82.216865014138},
+{292.451034398251,81.575585793537}, {290.388534398251,79.716210793537},
+{290.327331887234,79.659150436114}, {287.280456887234,76.721650436114},
+{289.345170841285,77.400059726466}, {287.321458102823,77.850263144467},
+{285.927837315685,78.632729269344}, {285.271451974336,79.274608858023},
+{285.175338636761,79.581613557521}, {285.156250000000,80.015625000000},
+{285.837287256911,82.245079867797}, {288.311827769881,84.707375828605},
+{288.276591203435,84.680146822744}, {291.660634742579,86.384861882977},
+{296.078125000000,86.921875000000}, {295.897986104774,86.928373450286},
+{300.007361104774,86.631498450286}, {302.154846390261,87.582421580364},
+{305.732305428001,91.823255793295}, {307.845891952966,94.029108047034},
+{307.673423412041,93.872031376082}, {313.085858668047,97.436653675309},
+{321.942962182352,101.958339245941}, {322.022973518268,101.997904034753},
+{328.415003222930,104.000119152238}, {342.055709578751,107.067955216008},
+{342.041158575133,107.064975341776}, {356.698169780877,109.788972348302},
+{364.281250000000,110.640625000000}, {366.516357996605,110.246724992845},
+{368.302745213785,108.824147954598}, {368.278843041300,108.851454302801},
+{369.437500000000,106.765625000000}, {369.768062144407,108.008017607319},
+{107.893088734820,103.841923410053}, {359.034454681034,69.861443602839},
+{357.173548986071,72.638610976591}, {353.435826646756,75.215386191513},
+{347.992418306797,77.582163291606}, {341.014454609897,79.729336320871},
+{326.426284670840,82.761098429090}, {319.640717587115,83.525315463381},
+{313.234375000000,83.781250000000}, {312.706760041223,83.724940335389},
+{311.331760041223,83.428065335389}, {311.389194323030,83.439762979730},
+{309.920444323030,83.158512979730}, {310.390625000000,83.203125000000},
+{309.032298883605,83.610801187634}, {305.860259182280,80.222501196670},
+{308.487654632717,75.272571710106}, {311.451975717975,70.927537861140},
+{314.718319876723,67.239682598354}, {318.251784547635,64.261288870324},
+{318.235984828743,64.272646821685}, {322.460311501394,61.735717754517},
+{327.134482463160,59.899177687483}, {332.183220900533,58.782772982128},
+{337.531250000000,58.406250000000}, {345.475041381297,58.786142249068},
+{351.020038715603,59.929523334009}, {351.130689531816,59.972424607386},
+{353.699762084814,61.379594420291}, {355.915109055748,63.288105475323},
+{357.703808635445,65.619192847673}, {358.992939014732,68.294091612533},
+{359.034454681034,69.861443602839}, {107.893088734820,103.841923410053},
+{354.288310985268,69.987158387467}, {352.366140944252,66.657207024677},
+{349.213060468184,64.590075392614}, {349.323711284397,64.632976665991},
+{344.735896118703,63.713857750932}, {337.531250000000,63.406250000000},
+{332.857794724467,63.703555142872}, {328.623330036840,64.608634812517},
+{324.752579123606,66.141235370483}, {321.170265171257,68.321103178315},
+{321.154465452365,68.332461129676}, {318.096133248277,70.895083026646},
+{315.305836782025,74.049024638860}, {312.748673492282,77.846568914895},
+{310.389740817720,82.339998803330}, {307.217701116395,78.951698812366},
+{310.390625000000,78.203125000000}, {310.860805676970,78.247737020270},
+{312.329555676970,78.528987020270}, {312.386989958777,78.540684664611},
+{313.761989958777,78.837559664611}, {313.234375000000,78.781250000000},
+{319.326079287885,78.541090786619}, {325.753402829160,77.817026570910},
+{339.735545390103,74.895663679129}, {350.446985853244,71.354926308487},
+{353.125279138929,69.816467148409}, {354.246795318966,68.419806397161},
+{354.288310985268,69.987158387467}, {107.893088734820,103.841923410053},
+{412.906150029990,61.293260146951}, {409.761470127352,62.134684085464},
+{407.280172710472,63.259435125605}, {407.285792255081,63.256184676520},
+{404.793374271599,64.364965077547}, {402.406250000000,64.781250000000},
+{400.799037804796,64.455489160260}, {399.281565012266,63.565560595750},
+{396.896451926356,60.617324020679}, {395.843750000000,59.187500000000},
+{394.132759007664,59.586356110398}, {392.227223295325,60.862510968959},
+{387.514233459670,66.524236094764}, {387.523930329881,66.510005317299},
+{384.972470502350,70.813073903396}, {383.182220364063,75.072391356081},
+{382.127155126215,79.356608210051}, {381.781250000000,83.734375000000},
+{382.036891605602,86.926476407739}, {382.837535469594,90.232985146136},
+{382.953125000000,90.984375000000}, {382.953125000000,110.781250000000},
+{380.453125000000,113.281250000000}, {374.875000000000,113.281250000000},
+{372.797350977108,112.469290573921}, {370.771127450416,110.197059087430},
+{366.940746762890,102.253660683699}, {366.931766441279,102.229357657717},
+{364.988344509233,95.969248633492}, {363.592635453443,89.400212341223},
+{362.750737781251,82.563409292771}, {362.468750000000,75.500000000000},
+{362.469585639102,75.564633561058}, {362.375835639102,71.939633561058},
+{362.376194806642,71.952282634846}, {362.282444806642,68.921032634846},
+{362.281250000000,68.843750000000}, {362.557974048920,65.558176179264},
+{363.371209408870,62.925233614273}, {365.078767647837,60.585701488502},
+{367.830147985199,58.062445160283}, {369.390625000000,57.515625000000},
+{372.609375000000,57.515625000000}, {375.044088155839,59.448023159988},
+{375.637838155839,61.994898159988}, {375.701153736333,62.463240580013},
+{375.794903736333,64.822615580013}, {375.796875000000,64.921875000000},
+{375.796875000000,66.390625000000}, {375.727843254951,66.974057381188},
+{375.364882971473,68.609156073692}, {375.377354243352,68.535253718305},
+{374.986729243352,71.082128718305}, {375.015625000000,70.703125000000},
+{375.946084438562,73.051058522014}, {371.472688855144,73.407169646001},
+{374.338903268299,66.961197216653}, {377.510670879106,61.308691210684},
+{380.962283852915,56.499192859154}, {384.668034355078,52.582243393122},
+{384.668120639869,52.582165462116}, {388.032154904598,50.002880989291},
+{391.626628158728,48.110057708285}, {395.367786243461,46.944465688666},
+{399.171875000000,46.546875000000}, {400.072873198005,46.714879663986},
+{404.885373198005,48.574254663986}, {404.871260445955,48.568850974212},
+{412.883679720929,50.905386234424}, {414.906250000000,53.359375000000},
+{414.906250000000,58.843750000000}, {412.906150029990,61.293260146951},
+{107.893088734820,103.841923410053}, {409.906250000000,58.843750000000},
+{409.906250000000,53.359375000000}, {411.928820279071,55.813363765576},
+{403.097489554045,53.243649025788}, {403.083376801995,53.238245336014},
+{398.270876801995,51.378870336014}, {399.171875000000,51.546875000000},
+{396.227916881538,51.823112436334}, {393.443684341272,52.679004791715},
+{390.735423220402,54.155322135709}, {388.019379360131,56.292834537884},
+{388.019465644922,56.292756606878}, {384.707638022085,59.784010265846},
+{381.637766620894,64.074121289316}, {378.784143606701,69.212630908347},
+{376.121061144856,75.249080353999}, {371.647665561438,75.605191477986},
+{370.464152438185,73.063686657060}, {370.015625000000,70.703125000000},
+{370.044520756648,70.324121281695}, {370.435145756648,67.777246281695},
+{370.447617028527,67.703343926308}, {370.865906745049,65.807192618812},
+{370.796875000000,66.390625000000}, {370.796875000000,64.921875000000},
+{370.798846263667,65.021134419987}, {370.705096263667,62.661759419987},
+{370.768411844161,63.130101840012}, {370.174661844161,60.583226840012},
+{372.609375000000,62.515625000000}, {369.390625000000,62.515625000000},
+{370.951102014801,61.968804839717}, {367.847540591130,65.152891385727},
+{367.281250000000,68.843750000000}, {367.280055193358,68.766467365154},
+{367.373805193358,71.797717365154}, {367.374164360898,71.810366438942},
+{367.467914360898,75.435366438942}, {367.468750000000,75.500000000000},
+{367.725824718749,82.182684457229}, {368.501114546557,88.552912658777},
+{369.800717990767,94.651845116508}, {371.630733558721,100.520642342283},
+{371.621753237110,100.496339316301}, {374.875000000000,108.281250000000},
+{380.453125000000,108.281250000000}, {377.953125000000,110.781250000000},
+{377.953125000000,90.984375000000}, {378.068714530406,91.735764853864},
+{377.111545894398,87.698523592261}, {376.781250000000,83.734375000000},
+{377.206829248785,78.659016789949}, {378.466217135937,73.583858643919},
+{380.533388872650,68.577551096604}, {383.382319670119,63.708744682701},
+{383.392016540330,63.694513905236}, {386.493443824758,59.714265008269},
+{389.655589204675,56.723426531041}, {392.798881617336,54.841378264602},
+{395.843750000000,54.187500000000}, {397.450962195204,54.513260839740},
+{398.968434987734,55.403189404250}, {401.353548073644,58.351425979321},
+{402.406250000000,59.781250000000}, {404.776707744919,58.931315323480},
+{404.782327289528,58.928064874395}, {408.035404872648,57.459065914536},
+{411.906349970010,56.394239853049}, {409.906250000000,58.843750000000},
+{107.893088734820, 103.841923410053}
+};
diff --git a/perf/micro/zrusin.c b/perf/micro/zrusin.c
new file mode 100644
index 000000000..3dee74d23
--- /dev/null
+++ b/perf/micro/zrusin.c
@@ -0,0 +1,97 @@
+/*
+ * Copyright © 2006 Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+#include "cairo-perf.h"
+
+typedef struct {
+ double x;
+ double y;
+} point_t;
+
+#include "zrusin-another.h"
+
+static void
+zrusin_another_path (cairo_t *cr)
+{
+ unsigned int i;
+
+ for (i=0; i < ARRAY_LENGTH (zrusin_another); i++)
+ cairo_line_to (cr, zrusin_another[i].x, zrusin_another[i].y);
+}
+
+static cairo_time_t
+zrusin_another_tessellate (cairo_t *cr, int width, int height, int loops)
+{
+ zrusin_another_path (cr);
+
+ cairo_perf_timer_start ();
+
+ /* We'd like to measure just tessellation without
+ * rasterization. For now, we can do that with cairo_in_fill. But
+ * we'll have to be careful since cairo_in_fill might eventually
+ * be optimized to have an implementation that doesn't necessarily
+ * include tessellation. */
+ while (loops--)
+ cairo_in_fill (cr, 50, 50);
+
+ cairo_perf_timer_stop ();
+
+ cairo_new_path (cr);
+
+ return cairo_perf_timer_elapsed ();
+}
+
+static cairo_time_t
+zrusin_another_fill (cairo_t *cr, int width, int height, int loops)
+{
+ zrusin_another_path (cr);
+ cairo_set_source_rgb (cr, 0.0, 0.0, 0.8); /* blue */
+
+ cairo_perf_timer_start ();
+
+ while (loops--)
+ cairo_fill_preserve (cr);
+
+ cairo_perf_timer_stop ();
+
+ cairo_new_path (cr);
+
+ return cairo_perf_timer_elapsed ();
+}
+
+cairo_bool_t
+zrusin_enabled (cairo_perf_t *perf)
+{
+ return cairo_perf_can_run (perf, "zrusin", NULL);
+}
+
+void
+zrusin (cairo_perf_t *perf, cairo_t *cr, int width, int height)
+{
+
+ cairo_perf_run (perf, "zrusin-another-tessellate", zrusin_another_tessellate, NULL);
+ cairo_perf_run (perf, "zrusin-another-fill", zrusin_another_fill, NULL);
+}
diff --git a/src/.gitignore b/src/.gitignore
index fd53c8649..534263a15 100755..100644
--- a/src/.gitignore
+++ b/src/.gitignore
@@ -31,3 +31,7 @@ check-has-hidden-symbols.i
check-link
check-skiplist
headers-standalone
+!cairo.pc.in
+!cairo-uninstalled.pc.in
+!cairo-features.pc.in
+!cairo-features-uninstalled.pc.in
diff --git a/src/Makefile.am b/src/Makefile.am
index acf0a8281..acf0a8281 100755..100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
diff --git a/src/Makefile.am.analysis b/src/Makefile.am.analysis
index fab4cf7a5..fab4cf7a5 100755..100644
--- a/src/Makefile.am.analysis
+++ b/src/Makefile.am.analysis
diff --git a/src/Makefile.sources b/src/Makefile.sources
index 0c9bfbe54..558065cbe 100755..100644
--- a/src/Makefile.sources
+++ b/src/Makefile.sources
@@ -86,6 +86,8 @@ cairo_private = \
cairo-image-info-private.h \
cairo-image-surface-inline.h \
cairo-image-surface-private.h \
+ cairo-line-inline.h \
+ cairo-line-private.h \
cairo-list-inline.h \
cairo-list-private.h \
cairo-malloc-private.h \
@@ -101,6 +103,7 @@ cairo_private = \
cairo-path-private.h \
cairo-pattern-inline.h \
cairo-pattern-private.h \
+ cairo-pixman-private.h \
cairo-private.h \
cairo-recording-surface-inline.h \
cairo-recording-surface-private.h \
@@ -130,11 +133,11 @@ cairo_private = \
cairo-time-private.h \
cairo-types-private.h \
cairo-traps-private.h \
+ cairo-convex-fill-private.h \
cairo-tristrip-private.h \
cairo-user-font-private.h \
cairo-wideint-private.h \
cairo-wideint-type-private.h \
- cairo-thread-local-private.h \
$(NULL)
cairo_sources = \
cairo-analysis-surface.c \
@@ -182,6 +185,7 @@ cairo_sources = \
cairo-image-info.c \
cairo-image-source.c \
cairo-image-surface.c \
+ cairo-line.c \
cairo-lzw.c \
cairo-matrix.c \
cairo-mask-compositor.c \
@@ -198,6 +202,7 @@ cairo_sources = \
cairo-path.c \
cairo-path-fill.c \
cairo-path-fixed.c \
+ cairo-convex-fill.c \
cairo-path-in-fill.c \
cairo-path-stroke.c \
cairo-path-stroke-boxes.c \
@@ -268,6 +273,7 @@ cairo_sources += $(_cairo_font_subset_sources)
cairo_egl_sources =
cairo_glx_sources =
cairo_wgl_sources =
+cairo_cgl_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
@@ -342,6 +348,7 @@ cairo_xcb_sources = \
cairo-xcb-surface.c \
cairo-xcb-surface-core.c \
cairo-xcb-surface-render.c \
+ cairo-xcb-resources.c \
$(NULL)
cairo_qt_headers = cairo-qt.h
@@ -418,6 +425,9 @@ cairo_glesv3_headers = $(cairo_gl_headers)
cairo_glesv3_private = $(cairo_gl_private)
cairo_glesv3_sources = $(cairo_gl_sources)
+cairo_evasgl_headers =
+cairo_evasgl_private =
+cairo_evasgl_sources =
if CAIRO_HAS_EVASGL_SURFACE
if CAIRO_HAS_GL_SURFACE
cairo_evasgl_headers =
@@ -440,10 +450,6 @@ cairo_evasgl_sources = $(cairo_gl_sources)
endif
endif
endif
-else
-cairo_evasgl_headers =
-cairo_evasgl_private =
-cairo_evasgl_sources =
endif
cairo_egl_sources += cairo-egl-context.c
@@ -451,6 +457,7 @@ cairo_glx_sources += cairo-glx-context.c
cairo_wgl_sources += cairo-wgl-context.c
cairo_evasgl_headers += cairo-evas-gl.h
cairo_evasgl_sources += cairo-evas-gl-context.c
+cairo_cgl_sources += cairo-cgl-context.c
cairo_directfb_headers = cairo-directfb.h
cairo_directfb_sources = cairo-directfb-surface.c
@@ -511,11 +518,3 @@ cairo_cogl_sources = cairo-cogl-surface.c \
cairo-cogl-gradient.c \
cairo-cogl-context.c \
cairo-cogl-utils.c
-
-cairo_tg_headers = cairo-tg.h
-cairo_tg_private = cairo-tg-private.h \
- cairo-tg-allocator-private.h \
- cairo-tg-journal-private.h \
- cairo-tg-composite-extents-private.h
-cairo_tg_sources = cairo-tg-surface.c \
- cairo-tg-journal.c
diff --git a/src/Makefile.win32 b/src/Makefile.win32
index 864791f37..864791f37 100755..100644
--- a/src/Makefile.win32
+++ b/src/Makefile.win32
diff --git a/src/Makefile.win32.features b/src/Makefile.win32.features
index 268117094..fe7627c9c 100755..100644
--- a/src/Makefile.win32.features
+++ b/src/Makefile.win32.features
@@ -21,24 +21,6 @@ enabled_cairo_sources = $(cairo_sources)
all_cairo_pkgconf = cairo.pc
enabled_cairo_pkgconf = cairo.pc
-all_cairo_private += $(cairo_tls_private) $(cairo_tls_headers)
-all_cairo_cxx_sources += $(cairo_tls_cxx_sources)
-all_cairo_sources += $(cairo_tls_sources)
-ifeq ($(CAIRO_HAS_TLS),1)
-enabled_cairo_private += $(cairo_tls_private) $(cairo_tls_headers)
-enabled_cairo_cxx_sources += $(cairo_tls_cxx_sources)
-enabled_cairo_sources += $(cairo_tls_sources)
-endif
-
-all_cairo_private += $(cairo_pthread_setspecific_private) $(cairo_pthread_setspecific_headers)
-all_cairo_cxx_sources += $(cairo_pthread_setspecific_cxx_sources)
-all_cairo_sources += $(cairo_pthread_setspecific_sources)
-ifeq ($(CAIRO_HAS_PTHREAD_SETSPECIFIC),1)
-enabled_cairo_private += $(cairo_pthread_setspecific_private) $(cairo_pthread_setspecific_headers)
-enabled_cairo_cxx_sources += $(cairo_pthread_setspecific_cxx_sources)
-enabled_cairo_sources += $(cairo_pthread_setspecific_sources)
-endif
-
supported_cairo_headers += $(cairo_xlib_headers)
all_cairo_headers += $(cairo_xlib_headers)
all_cairo_private += $(cairo_xlib_private)
@@ -407,22 +389,6 @@ ifeq ($(CAIRO_HAS_DIRECTFB_SURFACE),1)
enabled_cairo_pkgconf += cairo-directfb.pc
endif
-unsupported_cairo_headers += $(cairo_tg_headers)
-all_cairo_headers += $(cairo_tg_headers)
-all_cairo_private += $(cairo_tg_private)
-all_cairo_cxx_sources += $(cairo_tg_cxx_sources)
-all_cairo_sources += $(cairo_tg_sources)
-ifeq ($(CAIRO_HAS_TG_SURFACE),1)
-enabled_cairo_headers += $(cairo_tg_headers)
-enabled_cairo_private += $(cairo_tg_private)
-enabled_cairo_cxx_sources += $(cairo_tg_cxx_sources)
-enabled_cairo_sources += $(cairo_tg_sources)
-endif
-all_cairo_pkgconf += cairo-tg.pc
-ifeq ($(CAIRO_HAS_TG_SURFACE),1)
-enabled_cairo_pkgconf += cairo-tg.pc
-endif
-
unsupported_cairo_headers += $(cairo_vg_headers)
all_cairo_headers += $(cairo_vg_headers)
all_cairo_private += $(cairo_vg_private)
@@ -471,6 +437,22 @@ ifeq ($(CAIRO_HAS_GLX_FUNCTIONS),1)
enabled_cairo_pkgconf += cairo-glx.pc
endif
+supported_cairo_headers += $(cairo_cgl_headers)
+all_cairo_headers += $(cairo_cgl_headers)
+all_cairo_private += $(cairo_cgl_private)
+all_cairo_cxx_sources += $(cairo_cgl_cxx_sources)
+all_cairo_sources += $(cairo_cgl_sources)
+ifeq ($(CAIRO_HAS_CGL_FUNCTIONS),1)
+enabled_cairo_headers += $(cairo_cgl_headers)
+enabled_cairo_private += $(cairo_cgl_private)
+enabled_cairo_cxx_sources += $(cairo_cgl_cxx_sources)
+enabled_cairo_sources += $(cairo_cgl_sources)
+endif
+all_cairo_pkgconf += cairo-cgl.pc
+ifeq ($(CAIRO_HAS_CGL_FUNCTIONS),1)
+enabled_cairo_pkgconf += cairo-cgl.pc
+endif
+
supported_cairo_headers += $(cairo_wgl_headers)
all_cairo_headers += $(cairo_wgl_headers)
all_cairo_private += $(cairo_wgl_private)
@@ -674,15 +656,6 @@ enabled_cairo_private += $(cairo_user_private)
enabled_cairo_cxx_sources += $(cairo_user_cxx_sources)
enabled_cairo_sources += $(cairo_user_sources)
-all_cairo_private += $(cairo_openmp_private) $(cairo_openmp_headers)
-all_cairo_cxx_sources += $(cairo_openmp_cxx_sources)
-all_cairo_sources += $(cairo_openmp_sources)
-ifeq ($(CAIRO_HAS_OPENMP),1)
-enabled_cairo_private += $(cairo_openmp_private) $(cairo_openmp_headers)
-enabled_cairo_cxx_sources += $(cairo_openmp_cxx_sources)
-enabled_cairo_sources += $(cairo_openmp_sources)
-endif
-
all_cairo_private += $(cairo_pthread_private) $(cairo_pthread_headers)
all_cairo_cxx_sources += $(cairo_pthread_cxx_sources)
all_cairo_sources += $(cairo_pthread_sources)
diff --git a/src/README b/src/README
index 03e4455ea..03e4455ea 100755..100644
--- a/src/README
+++ b/src/README
diff --git a/src/cairo-analysis-surface-private.h b/src/cairo-analysis-surface-private.h
index 1e054c209..1e054c209 100755..100644
--- a/src/cairo-analysis-surface-private.h
+++ b/src/cairo-analysis-surface-private.h
diff --git a/src/cairo-analysis-surface.c b/src/cairo-analysis-surface.c
index 6717f7369..6717f7369 100755..100644
--- a/src/cairo-analysis-surface.c
+++ b/src/cairo-analysis-surface.c
diff --git a/src/cairo-arc-private.h b/src/cairo-arc-private.h
index a22c01ac9..a22c01ac9 100755..100644
--- a/src/cairo-arc-private.h
+++ b/src/cairo-arc-private.h
diff --git a/src/cairo-arc.c b/src/cairo-arc.c
index 5cbd11238..390397bae 100755..100644
--- a/src/cairo-arc.c
+++ b/src/cairo-arc.c
@@ -236,6 +236,10 @@ _cairo_arc_in_direction (cairo_t *cr,
step = -step;
}
+ cairo_line_to (cr,
+ xc + radius * cos (angle_min),
+ yc + radius * sin (angle_min));
+
for (i = 0; i < segments; i++, angle_min += step) {
_cairo_arc_segment (cr, xc, yc, radius,
angle_min, angle_min + step);
diff --git a/src/cairo-array-private.h b/src/cairo-array-private.h
index 35b29e5fc..35b29e5fc 100755..100644
--- a/src/cairo-array-private.h
+++ b/src/cairo-array-private.h
diff --git a/src/cairo-array.c b/src/cairo-array.c
index e37bb9980..e37bb9980 100755..100644
--- a/src/cairo-array.c
+++ b/src/cairo-array.c
diff --git a/src/cairo-atomic-private.h b/src/cairo-atomic-private.h
index 327fed1d9..327fed1d9 100755..100644
--- a/src/cairo-atomic-private.h
+++ b/src/cairo-atomic-private.h
diff --git a/src/cairo-atomic.c b/src/cairo-atomic.c
index 909cfea49..909cfea49 100755..100644
--- a/src/cairo-atomic.c
+++ b/src/cairo-atomic.c
diff --git a/src/cairo-backend-private.h b/src/cairo-backend-private.h
index cc5d5f313..8129fa22c 100755..100644
--- a/src/cairo-backend-private.h
+++ b/src/cairo-backend-private.h
@@ -116,6 +116,7 @@ struct _cairo_backend {
cairo_status_t (*arc) (void *cr, double xc, double yc, double radius, double angle1, double angle2, cairo_bool_t forward);
cairo_status_t (*rectangle) (void *cr, double x, double y, double width, double height);
+ cairo_status_t (*rounded_rectangle) (void *cr, double x, double y, double width, double height, double r_top_left, double r_top_right, double r_bottom_left, double r_bottom_right);
void (*path_extents) (void *cr, double *x1, double *y1, double *x2, double *y2);
cairo_bool_t (*has_current_point) (void *cr);
diff --git a/src/cairo-base64-stream.c b/src/cairo-base64-stream.c
index 636431372..636431372 100755..100644
--- a/src/cairo-base64-stream.c
+++ b/src/cairo-base64-stream.c
diff --git a/src/cairo-base85-stream.c b/src/cairo-base85-stream.c
index f81affb49..f81affb49 100755..100644
--- a/src/cairo-base85-stream.c
+++ b/src/cairo-base85-stream.c
diff --git a/src/cairo-bentley-ottmann-rectangular.c b/src/cairo-bentley-ottmann-rectangular.c
index 5541bdc3a..5541bdc3a 100755..100644
--- a/src/cairo-bentley-ottmann-rectangular.c
+++ b/src/cairo-bentley-ottmann-rectangular.c
diff --git a/src/cairo-bentley-ottmann-rectilinear.c b/src/cairo-bentley-ottmann-rectilinear.c
index 7c0be69b7..7c0be69b7 100755..100644
--- a/src/cairo-bentley-ottmann-rectilinear.c
+++ b/src/cairo-bentley-ottmann-rectilinear.c
diff --git a/src/cairo-bentley-ottmann.c b/src/cairo-bentley-ottmann.c
index 7259add0c..3f6f02422 100755..100644
--- a/src/cairo-bentley-ottmann.c
+++ b/src/cairo-bentley-ottmann.c
@@ -38,9 +38,10 @@
/* Provide definitions for standalone compilation */
#include "cairoint.h"
+#include "cairo-combsort-inline.h"
#include "cairo-error-private.h"
#include "cairo-freelist-private.h"
-#include "cairo-combsort-inline.h"
+#include "cairo-line-inline.h"
#include "cairo-traps-private.h"
#define DEBUG_PRINT_STATE 0
@@ -307,156 +308,6 @@ _slope_compare (const cairo_bo_edge_t *a,
}
}
-/*
- * We need to compare the x-coordinates of a pair of lines for a particular y,
- * without loss of precision.
- *
- * The x-coordinate along an edge for a given y is:
- * X = A_x + (Y - A_y) * A_dx / A_dy
- *
- * So the inequality we wish to test is:
- * A_x + (Y - A_y) * A_dx / A_dy ∘ B_x + (Y - B_y) * B_dx / B_dy,
- * where ∘ is our inequality operator.
- *
- * By construction, we know that A_dy and B_dy (and (Y - A_y), (Y - B_y)) are
- * all positive, so we can rearrange it thus without causing a sign change:
- * A_dy * B_dy * (A_x - B_x) ∘ (Y - B_y) * B_dx * A_dy
- * - (Y - A_y) * A_dx * B_dy
- *
- * Given the assumption that all the deltas fit within 32 bits, we can compute
- * this comparison directly using 128 bit arithmetic. For certain, but common,
- * input we can reduce this down to a single 32 bit compare by inspecting the
- * deltas.
- *
- * (And put the burden of the work on developing fast 128 bit ops, which are
- * required throughout the tessellator.)
- *
- * See the similar discussion for _slope_compare().
- */
-static int
-edges_compare_x_for_y_general (const cairo_bo_edge_t *a,
- const cairo_bo_edge_t *b,
- int32_t y)
-{
- /* XXX: We're assuming here that dx and dy will still fit in 32
- * bits. That's not true in general as there could be overflow. We
- * should prevent that before the tessellation algorithm
- * begins.
- */
- int32_t dx;
- int32_t adx, ady;
- int32_t bdx, bdy;
- enum {
- HAVE_NONE = 0x0,
- HAVE_DX = 0x1,
- HAVE_ADX = 0x2,
- HAVE_DX_ADX = HAVE_DX | HAVE_ADX,
- HAVE_BDX = 0x4,
- HAVE_DX_BDX = HAVE_DX | HAVE_BDX,
- HAVE_ADX_BDX = HAVE_ADX | HAVE_BDX,
- HAVE_ALL = HAVE_DX | HAVE_ADX | HAVE_BDX
- } have_dx_adx_bdx = HAVE_ALL;
-
- /* don't bother solving for abscissa if the edges' bounding boxes
- * can be used to order them. */
- {
- int32_t amin, amax;
- int32_t bmin, bmax;
- if (a->edge.line.p1.x < a->edge.line.p2.x) {
- amin = a->edge.line.p1.x;
- amax = a->edge.line.p2.x;
- } else {
- amin = a->edge.line.p2.x;
- amax = a->edge.line.p1.x;
- }
- if (b->edge.line.p1.x < b->edge.line.p2.x) {
- bmin = b->edge.line.p1.x;
- bmax = b->edge.line.p2.x;
- } else {
- bmin = b->edge.line.p2.x;
- bmax = b->edge.line.p1.x;
- }
- if (amax < bmin) return -1;
- if (amin > bmax) return +1;
- }
-
- ady = a->edge.line.p2.y - a->edge.line.p1.y;
- adx = a->edge.line.p2.x - a->edge.line.p1.x;
- if (adx == 0)
- have_dx_adx_bdx &= ~HAVE_ADX;
-
- bdy = b->edge.line.p2.y - b->edge.line.p1.y;
- bdx = b->edge.line.p2.x - b->edge.line.p1.x;
- if (bdx == 0)
- have_dx_adx_bdx &= ~HAVE_BDX;
-
- dx = a->edge.line.p1.x - b->edge.line.p1.x;
- if (dx == 0)
- have_dx_adx_bdx &= ~HAVE_DX;
-
-#define L _cairo_int64x32_128_mul (_cairo_int32x32_64_mul (ady, bdy), dx)
-#define A _cairo_int64x32_128_mul (_cairo_int32x32_64_mul (adx, bdy), y - a->edge.line.p1.y)
-#define B _cairo_int64x32_128_mul (_cairo_int32x32_64_mul (bdx, ady), y - b->edge.line.p1.y)
- switch (have_dx_adx_bdx) {
- default:
- case HAVE_NONE:
- return 0;
- case HAVE_DX:
- /* A_dy * B_dy * (A_x - B_x) ∘ 0 */
- return dx; /* ady * bdy is positive definite */
- case HAVE_ADX:
- /* 0 ∘ - (Y - A_y) * A_dx * B_dy */
- return adx; /* bdy * (y - a->top.y) is positive definite */
- case HAVE_BDX:
- /* 0 ∘ (Y - B_y) * B_dx * A_dy */
- return -bdx; /* ady * (y - b->top.y) is positive definite */
- case HAVE_ADX_BDX:
- /* 0 ∘ (Y - B_y) * B_dx * A_dy - (Y - A_y) * A_dx * B_dy */
- if ((adx ^ bdx) < 0) {
- return adx;
- } else if (a->edge.line.p1.y == b->edge.line.p1.y) { /* common origin */
- cairo_int64_t adx_bdy, bdx_ady;
-
- /* ∴ A_dx * B_dy ∘ B_dx * A_dy */
-
- adx_bdy = _cairo_int32x32_64_mul (adx, bdy);
- bdx_ady = _cairo_int32x32_64_mul (bdx, ady);
-
- return _cairo_int64_cmp (adx_bdy, bdx_ady);
- } else
- return _cairo_int128_cmp (A, B);
- case HAVE_DX_ADX:
- /* A_dy * (A_x - B_x) ∘ - (Y - A_y) * A_dx */
- if ((-adx ^ dx) < 0) {
- return dx;
- } else {
- cairo_int64_t ady_dx, dy_adx;
-
- ady_dx = _cairo_int32x32_64_mul (ady, dx);
- dy_adx = _cairo_int32x32_64_mul (a->edge.line.p1.y - y, adx);
-
- return _cairo_int64_cmp (ady_dx, dy_adx);
- }
- case HAVE_DX_BDX:
- /* B_dy * (A_x - B_x) ∘ (Y - B_y) * B_dx */
- if ((bdx ^ dx) < 0) {
- return dx;
- } else {
- cairo_int64_t bdy_dx, dy_bdx;
-
- bdy_dx = _cairo_int32x32_64_mul (bdy, dx);
- dy_bdx = _cairo_int32x32_64_mul (y - b->edge.line.p1.y, bdx);
-
- return _cairo_int64_cmp (bdy_dx, dy_bdx);
- }
- case HAVE_ALL:
- /* XXX try comparing (a->edge.line.p2.x - b->edge.line.p2.x) et al */
- return _cairo_int128_cmp (L, _cairo_int128_sub (B, A));
- }
-#undef B
-#undef A
-#undef L
-}
/*
* We need to compare the x-coordinate of a line for a particular y wrt to a
@@ -510,58 +361,6 @@ edge_compare_for_y_against_x (const cairo_bo_edge_t *a,
return _cairo_int64_cmp (L, R);
}
-static int
-edges_compare_x_for_y (const cairo_bo_edge_t *a,
- const cairo_bo_edge_t *b,
- int32_t y)
-{
- /* If the sweep-line is currently on an end-point of a line,
- * then we know its precise x value (and considering that we often need to
- * compare events at end-points, this happens frequently enough to warrant
- * special casing).
- */
- enum {
- HAVE_NEITHER = 0x0,
- HAVE_AX = 0x1,
- HAVE_BX = 0x2,
- HAVE_BOTH = HAVE_AX | HAVE_BX
- } have_ax_bx = HAVE_BOTH;
- int32_t ax, bx;
-
- if (y == a->edge.line.p1.y)
- ax = a->edge.line.p1.x;
- else if (y == a->edge.line.p2.y)
- ax = a->edge.line.p2.x;
- else
- have_ax_bx &= ~HAVE_AX;
-
- if (y == b->edge.line.p1.y)
- bx = b->edge.line.p1.x;
- else if (y == b->edge.line.p2.y)
- bx = b->edge.line.p2.x;
- else
- have_ax_bx &= ~HAVE_BX;
-
- switch (have_ax_bx) {
- default:
- case HAVE_NEITHER:
- return edges_compare_x_for_y_general (a, b, y);
- case HAVE_AX:
- return -edge_compare_for_y_against_x (b, y, ax);
- case HAVE_BX:
- return edge_compare_for_y_against_x (a, y, bx);
- case HAVE_BOTH:
- return ax - bx;
- }
-}
-
-static inline int
-_line_equal (const cairo_line_t *a, const cairo_line_t *b)
-{
- return a->p1.x == b->p1.x && a->p1.y == b->p1.y &&
- a->p2.x == b->p2.x && a->p2.y == b->p2.y;
-}
-
static inline int
_cairo_bo_sweep_line_compare_edges (const cairo_bo_sweep_line_t *sweep_line,
const cairo_bo_edge_t *a,
@@ -569,28 +368,11 @@ _cairo_bo_sweep_line_compare_edges (const cairo_bo_sweep_line_t *sweep_line,
{
int cmp;
- /* compare the edges if not identical */
- if (! _line_equal (&a->edge.line, &b->edge.line)) {
- if (MAX (a->edge.line.p1.x, a->edge.line.p2.x) <
- MIN (b->edge.line.p1.x, b->edge.line.p2.x))
- return -1;
- else if (MIN (a->edge.line.p1.x, a->edge.line.p2.x) >
- MAX (b->edge.line.p1.x, b->edge.line.p2.x))
- return 1;
-
- cmp = edges_compare_x_for_y (a, b, sweep_line->current_y);
- if (cmp)
- return cmp;
-
- /* The two edges intersect exactly at y, so fall back on slope
- * comparison. We know that this compare_edges function will be
- * called only when starting a new edge, (not when stopping an
- * edge), so we don't have to worry about conditionally inverting
- * the sense of _slope_compare. */
- cmp = _slope_compare (a, b);
- if (cmp)
+ cmp = cairo_lines_compare_at_y (&a->edge.line,
+ &b->edge.line,
+ sweep_line->current_y);
+ if (cmp)
return cmp;
- }
/* We've got two collinear edges now. */
return b->edge.bottom - a->edge.bottom;
@@ -1090,7 +872,7 @@ _cairo_bo_event_queue_insert_if_intersect_below_current_y (cairo_bo_event_queue_
MIN (right->edge.line.p1.x, right->edge.line.p2.x))
return CAIRO_STATUS_SUCCESS;
- if (_line_equal (&left->edge.line, &right->edge.line))
+ if (cairo_lines_equal (&left->edge.line, &right->edge.line))
return CAIRO_STATUS_SUCCESS;
/* The names "left" and "right" here are correct descriptions of
@@ -1691,7 +1473,7 @@ _cairo_bentley_ottmann_tessellate_polygon (cairo_traps_t *traps,
cairo_bo_event_t **event_ptrs;
cairo_bo_start_event_t *stack_event_y[64];
cairo_bo_start_event_t **event_y = NULL;
- int i, num_events, y, ymin = 0, ymax = 0;
+ int i, num_events, y, ymin, ymax;
cairo_status_t status;
num_events = polygon->num_edges;
diff --git a/src/cairo-beos-surface.cpp b/src/cairo-beos-surface.cpp
index c97641685..c97641685 100755..100644
--- a/src/cairo-beos-surface.cpp
+++ b/src/cairo-beos-surface.cpp
diff --git a/src/cairo-beos.h b/src/cairo-beos.h
index fdb89a6c4..fdb89a6c4 100755..100644
--- a/src/cairo-beos.h
+++ b/src/cairo-beos.h
diff --git a/src/cairo-botor-scan-converter.c b/src/cairo-botor-scan-converter.c
index 515305bf2..515305bf2 100755..100644
--- a/src/cairo-botor-scan-converter.c
+++ b/src/cairo-botor-scan-converter.c
diff --git a/src/cairo-box-inline.h b/src/cairo-box-inline.h
index d6b994127..d6b994127 100755..100644
--- a/src/cairo-box-inline.h
+++ b/src/cairo-box-inline.h
diff --git a/src/cairo-boxes-intersect.c b/src/cairo-boxes-intersect.c
index 96ae66334..96ae66334 100755..100644
--- a/src/cairo-boxes-intersect.c
+++ b/src/cairo-boxes-intersect.c
diff --git a/src/cairo-boxes-private.h b/src/cairo-boxes-private.h
index d1f9dfcd1..d1f9dfcd1 100755..100644
--- a/src/cairo-boxes-private.h
+++ b/src/cairo-boxes-private.h
diff --git a/src/cairo-boxes.c b/src/cairo-boxes.c
index 63b68ddfb..63b68ddfb 100755..100644
--- a/src/cairo-boxes.c
+++ b/src/cairo-boxes.c
diff --git a/src/cairo-cache-private.h b/src/cairo-cache-private.h
index 76b556194..24b6d0b20 100755..100644
--- a/src/cairo-cache-private.h
+++ b/src/cairo-cache-private.h
@@ -43,7 +43,7 @@
#include "cairo-types-private.h"
/**
- * cairo_cache_entry_t:
+ * _cairo_cache_entry:
*
* A #cairo_cache_entry_t contains both a key and a value for
* #cairo_cache_t. User-derived types for #cairo_cache_entry_t must
diff --git a/src/cairo-cache.c b/src/cairo-cache.c
index 5c4e4caa3..5c4e4caa3 100755..100644
--- a/src/cairo-cache.c
+++ b/src/cairo-cache.c
diff --git a/src/cairo-cff-subset.c b/src/cairo-cff-subset.c
index 6e60568e6..da49e8e1e 100755..100644
--- a/src/cairo-cff-subset.c
+++ b/src/cairo-cff-subset.c
@@ -295,7 +295,6 @@ decode_nibble (int n, char *buf)
static unsigned char *
decode_real (unsigned char *p, double *real)
{
- struct lconv *locale_data;
const char *decimal_point;
int decimal_point_len;
int n;
@@ -305,8 +304,7 @@ decode_real (unsigned char *p, double *real)
char *buf = buffer;
char *buf_end = buffer + sizeof (buffer);
- locale_data = localeconv ();
- decimal_point = locale_data->decimal_point;
+ decimal_point = cairo_get_locale_decimal_point ();
decimal_point_len = strlen (decimal_point);
assert (decimal_point_len != 0);
@@ -435,7 +433,7 @@ cff_index_read (cairo_array_t *index, unsigned char **ptr, unsigned char *end_pt
p = *ptr;
if (p + 2 > end_ptr)
return CAIRO_INT_STATUS_UNSUPPORTED;
- count = be16_to_cpu( *((uint16_t *)p) );
+ count = get_unaligned_be16 (p);
p += 2;
if (count > 0) {
offset_size = *p++;
@@ -905,6 +903,8 @@ cairo_cff_font_read_name (cairo_cff_font_t *font)
memcpy (font->ps_name, p, len);
font->ps_name[len] = 0;
+
+ status = _cairo_escape_ps_name (&font->ps_name);
}
cff_index_fini (&index);
@@ -990,14 +990,14 @@ cairo_cff_font_read_fdselect (cairo_cff_font_t *font, unsigned char *p)
for (i = 0; i < font->num_glyphs; i++)
font->fdselect[i] = *p++;
} else if (type == 3) {
- num_ranges = be16_to_cpu( *((uint16_t *)p) );
+ num_ranges = get_unaligned_be16 (p);
p += 2;
for (i = 0; i < num_ranges; i++)
{
- first = be16_to_cpu( *((uint16_t *)p) );
+ first = get_unaligned_be16 (p);
p += 2;
fd = *p++;
- last = be16_to_cpu( *((uint16_t *)p) );
+ last = get_unaligned_be16 (p);
for (j = first; j < last; j++)
font->fdselect[j] = fd;
}
@@ -1058,13 +1058,13 @@ cairo_cff_font_read_cid_fontdict (cairo_cff_font_t *font, unsigned char *ptr)
goto fail;
}
- font->fd_default_width = calloc (sizeof (int), font->num_fontdicts);
+ font->fd_default_width = calloc (font->num_fontdicts, sizeof (double));
if (unlikely (font->fd_default_width == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail;
}
- font->fd_nominal_width = calloc (sizeof (int), font->num_fontdicts);
+ font->fd_nominal_width = calloc (font->num_fontdicts, sizeof (double));
if (unlikely (font->fd_nominal_width == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail;
@@ -1757,7 +1757,7 @@ cairo_cff_font_get_gid_for_cid (cairo_cff_font_t *font, unsigned long cid, unsi
p = font->charset + 1;
g = 1;
while (g <= (unsigned)font->num_glyphs && p < font->data_end) {
- c = be16_to_cpu( *((uint16_t *)p) );
+ c = get_unaligned_be16 (p);
if (c == cid) {
*gid = g;
return CAIRO_STATUS_SUCCESS;
@@ -1772,7 +1772,7 @@ cairo_cff_font_get_gid_for_cid (cairo_cff_font_t *font, unsigned long cid, unsi
first_gid = 1;
p = font->charset + 1;
while (first_gid <= (unsigned)font->num_glyphs && p + 2 < font->data_end) {
- first_cid = be16_to_cpu( *((uint16_t *)p) );
+ first_cid = get_unaligned_be16 (p);
num_left = p[2];
if (cid >= first_cid && cid <= first_cid + num_left) {
*gid = first_gid + cid - first_cid;
@@ -1788,8 +1788,8 @@ cairo_cff_font_get_gid_for_cid (cairo_cff_font_t *font, unsigned long cid, unsi
first_gid = 1;
p = font->charset + 1;
while (first_gid <= (unsigned)font->num_glyphs && p + 3 < font->data_end) {
- first_cid = be16_to_cpu( *((uint16_t *)p) );
- num_left = be16_to_cpu( *((uint16_t *)(p+2)) );
+ first_cid = get_unaligned_be16 (p);
+ num_left = get_unaligned_be16 (p+2);
if (cid >= first_cid && cid <= first_cid + num_left) {
*gid = first_gid + cid - first_cid;
return CAIRO_STATUS_SUCCESS;
@@ -2366,7 +2366,7 @@ cairo_cff_font_write_cid_fontdict (cairo_cff_font_t *font)
unsigned int i;
cairo_int_status_t status;
unsigned int offset_array;
- uint32_t *offset_array_ptr;
+ unsigned char *offset_array_ptr;
int offset_base;
uint16_t count;
uint8_t offset_size = 4;
@@ -2387,7 +2387,7 @@ cairo_cff_font_write_cid_fontdict (cairo_cff_font_t *font)
if (unlikely (status))
return status;
offset_base = _cairo_array_num_elements (&font->output) - 1;
- *offset_array_ptr = cpu_to_be32(1);
+ put_unaligned_be32(1, offset_array_ptr);
offset_array += sizeof(uint32_t);
for (i = 0; i < font->num_subset_fontdicts; i++) {
status = cff_dict_write (font->fd_dict[font->fd_subset_map[i]],
@@ -2395,8 +2395,9 @@ cairo_cff_font_write_cid_fontdict (cairo_cff_font_t *font)
if (unlikely (status))
return status;
- offset_array_ptr = (uint32_t *) _cairo_array_index (&font->output, offset_array);
- *offset_array_ptr = cpu_to_be32(_cairo_array_num_elements (&font->output) - offset_base);
+ offset_array_ptr = _cairo_array_index (&font->output, offset_array);
+ put_unaligned_be32 (_cairo_array_num_elements (&font->output) - offset_base,
+ offset_array_ptr);
offset_array += sizeof(uint32_t);
}
@@ -2647,7 +2648,7 @@ cairo_cff_font_create_set_widths (cairo_cff_font_t *font)
unsigned int i;
tt_hhea_t hhea;
int num_hmetrics;
- unsigned char buf[10];
+ uint16_t short_entry;
int glyph_index;
cairo_int_status_t status;
@@ -2667,7 +2668,8 @@ cairo_cff_font_create_set_widths (cairo_cff_font_t *font)
status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
TT_TAG_hmtx,
glyph_index * long_entry_size,
- buf, &short_entry_size);
+ (unsigned char *) &short_entry,
+ &short_entry_size);
if (unlikely (status))
return status;
}
@@ -2676,11 +2678,12 @@ cairo_cff_font_create_set_widths (cairo_cff_font_t *font)
status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
TT_TAG_hmtx,
(num_hmetrics - 1) * long_entry_size,
- buf, &short_entry_size);
+ (unsigned char *) &short_entry,
+ &short_entry_size);
if (unlikely (status))
return status;
}
- font->widths[i] = be16_to_cpu (*((int16_t*)buf));
+ font->widths[i] = be16_to_cpu (short_entry);
}
return CAIRO_STATUS_SUCCESS;
diff --git a/src/cairo-cgl-context.c b/src/cairo-cgl-context.c
new file mode 100644
index 000000000..6f5e557f4
--- /dev/null
+++ b/src/cairo-cgl-context.c
@@ -0,0 +1,224 @@
+/* cairo - a vector graphics library with display and print output
+ *
+ * Copyright © 2009 Eric Anholt
+ * Copyright © 2009 Chris Wilson
+ * Copyright © 2005 Red Hat, Inc
+ * Copyright © 2015 Samsung Research America, Inc. - Silicon Valley
+ *
+ * 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 Red Hat, Inc.
+ *
+ * Contributor(s):
+ * Carl Worth <cworth@cworth.org>
+ * Chris Wilson <chris@chris-wilson.co.uk>
+ * Henry Songn <hsong@sisa.samsung.com>
+ */
+
+#include "cairoint.h"
+
+#include "cairo-gl-private.h"
+
+#include "cairo-error-private.h"
+
+#include <dlfcn.h>
+
+typedef struct _cairo_cgl_context {
+ cairo_gl_context_t base;
+
+ CGLContextObj context;
+ CGLContextObj prev_context;
+} cairo_cgl_context_t;
+
+typedef struct _cairo_cgl_surface {
+ cairo_gl_surface_t base;
+
+ CGLContextObj context;
+} cairo_cgl_surface_t;
+
+static void *
+_cgl_query_current_state (cairo_cgl_context_t * ctx)
+{
+ ctx->prev_context = CGLGetCurrentContext ();
+}
+
+static void
+_cgl_acquire (void *abstract_ctx)
+{
+ cairo_cgl_context_t *ctx = abstract_ctx;
+ _cgl_query_current_state (ctx);
+
+ if (ctx->prev_context == ctx->context)
+ return;
+
+ _cairo_gl_context_reset (&ctx->base);
+
+ CGLLockContext (ctx->context);
+ CGLSetCurrentContext (ctx->context);
+}
+
+static void
+_cgl_make_current (void *abstract_ctx, cairo_gl_surface_t *abstract_surface)
+{
+ cairo_cgl_context_t *ctx = abstract_ctx;
+ cairo_cgl_surface_t *surface = (cairo_cgl_surface_t *) abstract_surface;
+
+ /* Set the window as the target of our context. */
+ if (ctx->context != surface->context) {
+ CGLLockContext (surface->context);
+ CGLSetCurrentContext (surface->context);
+ }
+}
+
+static void
+_cgl_release (void *abstract_ctx)
+{
+ cairo_cgl_context_t *ctx = abstract_ctx;
+
+ if (!ctx->base.thread_aware)
+ return;
+
+ CGLSetCurrentContext (NULL);
+ CGLUnlockContext (ctx->context);
+}
+
+static void
+_cgl_swap_buffers (void *abstract_ctx,
+ cairo_gl_surface_t *abstract_surface)
+{
+ cairo_cgl_context_t *ctx = abstract_ctx;
+ cairo_cgl_surface_t *surface = (cairo_cgl_surface_t *)abstract_surface;
+
+ /* is it possible to have different context? */
+ if (ctx->context == surface->context)
+ CGLFlushDrawable (surface->context);
+}
+
+static void
+_cgl_destroy (void *abstract_ctx)
+{
+ cairo_cgl_context_t *ctx = abstract_ctx;
+
+ CGLSetCurrentContext (NULL);
+ CGLReleaseContext (ctx->context);
+ CGLUnlockContext (ctx->context);
+}
+
+static cairo_gl_generic_func_t
+_cairo_cgl_get_proc_address (void *data, const char *name)
+{
+ return dlsym (RTLD_DEFAULT, name);
+}
+
+cairo_device_t *
+cairo_cgl_device_create (CGLContextObj context)
+{
+ cairo_cgl_context_t *ctx;
+ cairo_status_t status;
+
+ ctx = calloc (1, sizeof (cairo_cgl_context_t));
+ if (unlikely (ctx == NULL))
+ return _cairo_gl_context_create_in_error (CAIRO_STATUS_NO_MEMORY);
+
+ ctx->context = CGLRetainContext (context);
+
+ ctx->base.acquire = _cgl_acquire;
+ ctx->base.release = _cgl_release;
+ ctx->base.make_current = _cgl_make_current;
+ ctx->base.swap_buffers = _cgl_swap_buffers;
+ ctx->base.destroy = _cgl_destroy;
+
+ _cgl_query_current_state (ctx);
+ if (ctx->context != ctx->prev_context) {
+ CGLLockContext (ctx->context);
+ CGLSetCurrentContext (ctx->context);
+ }
+
+ status = _cairo_gl_dispatch_init (&ctx->base.dispatch,
+ (cairo_gl_get_proc_addr_func_t) _cairo_cgl_get_proc_address,
+ NULL);
+
+ if (unlikely (status)) {
+ ctx->base.release (ctx);
+ CGLReleaseContext (ctx->context);
+ free (ctx);
+ return _cairo_gl_context_create_in_error (status);
+ }
+
+ status = _cairo_gl_context_init (&ctx->base);
+ if (unlikely (status)) {
+ ctx->base.release (ctx);
+ CGLReleaseContext (ctx->context);
+ free (ctx);
+ return _cairo_gl_context_create_in_error (status);
+ }
+
+ ctx->base.release (ctx);
+
+ return &ctx->base.base;
+}
+
+CGLContextObj
+cairo_cgl_device_get_context (cairo_device_t *device)
+{
+ cairo_cgl_context_t *ctx;
+
+ if (device->backend->type != CAIRO_DEVICE_TYPE_GL) {
+ _cairo_error_throw (CAIRO_STATUS_DEVICE_TYPE_MISMATCH);
+ return NULL;
+ }
+
+ ctx = (cairo_cgl_context_t *) device;
+
+ return ctx->context;
+}
+
+cairo_surface_t *
+cairo_gl_surface_create_for_cgl (cairo_device_t *device,
+ int width,
+ int height)
+{
+ cairo_cgl_surface_t *surface;
+
+ if (unlikely (device->status))
+ return _cairo_surface_create_in_error (device->status);
+
+ if (device->backend->type != CAIRO_DEVICE_TYPE_GL)
+ 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));
+
+ surface = calloc (1, sizeof (cairo_cgl_surface_t));
+ if (unlikely (surface == NULL))
+ return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
+
+ _cairo_gl_surface_init (device, &surface->base,
+ CAIRO_CONTENT_COLOR_ALPHA, width, height);
+ surface->context = ((cairo_cgl_context_t *) device)->context;
+
+ return &surface->base.base;
+}
diff --git a/src/cairo-clip-boxes.c b/src/cairo-clip-boxes.c
index eae0919af..0501fa273 100755..100644
--- a/src/cairo-clip-boxes.c
+++ b/src/cairo-clip-boxes.c
@@ -173,7 +173,7 @@ _cairo_clip_intersect_rectangle_box (cairo_clip_t *clip,
clip->extents = *r;
} else {
if (! _cairo_rectangle_intersect (&clip->extents, r))
- clip = _cairo_clip_set_all_clipped (clip);
+ return _cairo_clip_set_all_clipped (clip);
}
if (clip->path == NULL)
clip->is_region = _cairo_box_is_pixel_aligned (box);
@@ -258,6 +258,9 @@ _cairo_clip_intersect_box (cairo_clip_t *clip,
{
cairo_rectangle_int_t r;
+ if (_cairo_clip_is_all_clipped (clip))
+ return clip;
+
_cairo_box_round_to_rectangle (box, &r);
if (r.width == 0 || r.height == 0)
return _cairo_clip_set_all_clipped (clip);
@@ -315,10 +318,12 @@ _cairo_clip_intersect_boxes (cairo_clip_t *clip,
_cairo_boxes_extents (boxes, &limits);
_cairo_box_round_to_rectangle (&limits, &extents);
- if (clip->path == NULL)
+ if (clip->path == NULL) {
clip->extents = extents;
- else if (! _cairo_rectangle_intersect (&clip->extents, &extents))
+ } else if (! _cairo_rectangle_intersect (&clip->extents, &extents)) {
clip = _cairo_clip_set_all_clipped (clip);
+ goto out;
+ }
if (clip->region) {
cairo_region_destroy (clip->region);
diff --git a/src/cairo-clip-inline.h b/src/cairo-clip-inline.h
index a9f232692..a9f232692 100755..100644
--- a/src/cairo-clip-inline.h
+++ b/src/cairo-clip-inline.h
diff --git a/src/cairo-clip-polygon.c b/src/cairo-clip-polygon.c
index f40faefba..f40faefba 100755..100644
--- a/src/cairo-clip-polygon.c
+++ b/src/cairo-clip-polygon.c
diff --git a/src/cairo-clip-private.h b/src/cairo-clip-private.h
index c2ed66419..c2ed66419 100755..100644
--- a/src/cairo-clip-private.h
+++ b/src/cairo-clip-private.h
diff --git a/src/cairo-clip-region.c b/src/cairo-clip-region.c
index e3f4891e3..e3f4891e3 100755..100644
--- a/src/cairo-clip-region.c
+++ b/src/cairo-clip-region.c
diff --git a/src/cairo-clip-surface.c b/src/cairo-clip-surface.c
index f1c13a4ae..a92379eba 100755..100644
--- a/src/cairo-clip-surface.c
+++ b/src/cairo-clip-surface.c
@@ -134,11 +134,11 @@ _cairo_clip_get_surface (const cairo_clip_t *clip,
cairo_path_fixed_t path;
int i;
- surface = _cairo_surface_create_similar_solid (target,
- CAIRO_CONTENT_ALPHA,
- clip->extents.width,
- clip->extents.height,
- CAIRO_COLOR_TRANSPARENT);
+ surface = _cairo_surface_create_scratch (target,
+ CAIRO_CONTENT_ALPHA,
+ clip->extents.width,
+ clip->extents.height,
+ CAIRO_COLOR_TRANSPARENT);
if (unlikely (surface->status))
return surface;
@@ -164,11 +164,11 @@ _cairo_clip_get_surface (const cairo_clip_t *clip,
return _cairo_surface_create_in_error (status);
}
} else {
- surface = _cairo_surface_create_similar_solid (target,
- CAIRO_CONTENT_ALPHA,
- clip->extents.width,
- clip->extents.height,
- CAIRO_COLOR_WHITE);
+ surface = _cairo_surface_create_scratch (target,
+ CAIRO_CONTENT_ALPHA,
+ clip->extents.width,
+ clip->extents.height,
+ CAIRO_COLOR_WHITE);
if (unlikely (surface->status))
return surface;
}
diff --git a/src/cairo-clip-tor-scan-converter.c b/src/cairo-clip-tor-scan-converter.c
index e32a5a9d9..e32a5a9d9 100755..100644
--- a/src/cairo-clip-tor-scan-converter.c
+++ b/src/cairo-clip-tor-scan-converter.c
diff --git a/src/cairo-clip.c b/src/cairo-clip.c
index dcafaf229..dcafaf229 100755..100644
--- a/src/cairo-clip.c
+++ b/src/cairo-clip.c
diff --git a/src/cairo-cogl-context-private.h b/src/cairo-cogl-context-private.h
index 0a7185ef1..0a7185ef1 100755..100644
--- a/src/cairo-cogl-context-private.h
+++ b/src/cairo-cogl-context-private.h
diff --git a/src/cairo-cogl-context.c b/src/cairo-cogl-context.c
index 0116b0a5a..0116b0a5a 100755..100644
--- a/src/cairo-cogl-context.c
+++ b/src/cairo-cogl-context.c
diff --git a/src/cairo-cogl-gradient-private.h b/src/cairo-cogl-gradient-private.h
index fa684d2c6..fa684d2c6 100755..100644
--- a/src/cairo-cogl-gradient-private.h
+++ b/src/cairo-cogl-gradient-private.h
diff --git a/src/cairo-cogl-gradient.c b/src/cairo-cogl-gradient.c
index f8c800416..f8c800416 100755..100644
--- a/src/cairo-cogl-gradient.c
+++ b/src/cairo-cogl-gradient.c
diff --git a/src/cairo-cogl-private.h b/src/cairo-cogl-private.h
index 13fe5a8dc..13fe5a8dc 100755..100644
--- a/src/cairo-cogl-private.h
+++ b/src/cairo-cogl-private.h
diff --git a/src/cairo-cogl-surface.c b/src/cairo-cogl-surface.c
index 27c3676de..c57fd7f43 100755..100644
--- a/src/cairo-cogl-surface.c
+++ b/src/cairo-cogl-surface.c
@@ -143,7 +143,7 @@ typedef struct _cairo_cogl_path_fill_meta {
* and translations but not for different scales.
*
* one idea is to track the diagonal lenghts of a unit rectangle
- * transformed through the original ctm use to tesselate the geometry
+ * transformed through the original ctm use to tessellate the geometry
* so we can check what the lengths are for any new ctm to know if
* this geometry is compatible.
*/
@@ -167,7 +167,7 @@ typedef struct _cairo_cogl_path_stroke_meta {
* and translations but not for different scales.
*
* one idea is to track the diagonal lenghts of a unit rectangle
- * transformed through the original ctm use to tesselate the geometry
+ * transformed through the original ctm use to tessellate the geometry
* so we can check what the lengths are for any new ctm to know if
* this geometry is compatible.
*/
@@ -805,7 +805,7 @@ _cairo_cogl_journal_flush (cairo_cogl_surface_t *surface)
_cairo_path_fixed_approximate_clip_extents (&path->path, &extents);
/* TODO - maintain a fifo of the last 10 used clips with cached
- * primitives to see if we can avoid tesselating the path and
+ * primitives to see if we can avoid tessellating the path and
* uploading the vertices...
*/
#if 0
@@ -2789,7 +2789,7 @@ cairo_cogl_device_create (CoglContext *cogl_context)
ERROR:
g_free (dev);
- return NULL;
+ return _cairo_device_create_in_error (CAIRO_STATUS_DEVICE_ERROR);
}
slim_hidden_def (cairo_cogl_device_create);
diff --git a/src/cairo-cogl-utils-private.h b/src/cairo-cogl-utils-private.h
index ee77f3034..ee77f3034 100755..100644
--- a/src/cairo-cogl-utils-private.h
+++ b/src/cairo-cogl-utils-private.h
diff --git a/src/cairo-cogl-utils.c b/src/cairo-cogl-utils.c
index 4f02aaa52..4f02aaa52 100755..100644
--- a/src/cairo-cogl-utils.c
+++ b/src/cairo-cogl-utils.c
diff --git a/src/cairo-cogl.h b/src/cairo-cogl.h
index f270d74d3..f270d74d3 100755..100644
--- a/src/cairo-cogl.h
+++ b/src/cairo-cogl.h
diff --git a/src/cairo-color.c b/src/cairo-color.c
index 9c852559e..c2a11a177 100755..100644
--- a/src/cairo-color.c
+++ b/src/cairo-color.c
@@ -78,18 +78,13 @@ _cairo_stock_color (cairo_stock_t stock)
}
/* Convert a double in [0.0, 1.0] to an integer in [0, 65535]
- * The conversion is designed to divide the input range into 65536
- * equally-sized regions. This is achieved by multiplying by 65536 and
- * then special-casing the result of an input value of 1.0 so that it
- * maps to 65535 instead of 65536.
+ * The conversion is designed to choose the integer i such that
+ * i / 65535.0 is as close as possible to the input value.
*/
uint16_t
_cairo_color_double_to_short (double d)
{
- uint32_t i;
- i = (uint32_t) (d * 65536);
- i -= (i >> 16);
- return i;
+ return d * 65535.0 + 0.5;
}
static void
diff --git a/src/cairo-combsort-inline.h b/src/cairo-combsort-inline.h
index d359faeb5..d359faeb5 100755..100644
--- a/src/cairo-combsort-inline.h
+++ b/src/cairo-combsort-inline.h
diff --git a/src/cairo-compiler-private.h b/src/cairo-compiler-private.h
index f3e971ebb..216e71b4e 100755..100644
--- a/src/cairo-compiler-private.h
+++ b/src/cairo-compiler-private.h
@@ -221,16 +221,14 @@
be needed for GCC but it seems fine for now. */
#define CAIRO_ENSURE_UNIQUE \
do { \
- char func[] = __FUNCTION__; \
char file[] = __FILE__; \
__asm { \
__asm jmp __internal_skip_line_no \
- __asm _emit (__LINE__ & 0xff) \
- __asm _emit ((__LINE__>>8) & 0xff) \
- __asm _emit ((__LINE__>>16) & 0xff) \
- __asm _emit ((__LINE__>>24) & 0xff) \
- __asm lea eax, func \
- __asm lea eax, file \
+ __asm _emit (__COUNTER__ & 0xff) \
+ __asm _emit ((__COUNTER__>>8) & 0xff) \
+ __asm _emit ((__COUNTER__>>16) & 0xff)\
+ __asm _emit ((__COUNTER__>>24) & 0xff)\
+ __asm lea eax, dword ptr file \
__asm __internal_skip_line_no: \
}; \
} while (0)
diff --git a/src/cairo-composite-rectangles-private.h b/src/cairo-composite-rectangles-private.h
index 108137427..108137427 100755..100644
--- a/src/cairo-composite-rectangles-private.h
+++ b/src/cairo-composite-rectangles-private.h
diff --git a/src/cairo-composite-rectangles.c b/src/cairo-composite-rectangles.c
index f288bb785..2f0013fa7 100755..100644
--- a/src/cairo-composite-rectangles.c
+++ b/src/cairo-composite-rectangles.c
@@ -61,7 +61,7 @@ _cairo_composite_rectangles_check_lazy_init (cairo_composite_rectangles_t *exten
if (type == CAIRO_PATTERN_TYPE_SURFACE) {
cairo_surface_pattern_t *surface_pattern = (cairo_surface_pattern_t *) pattern;
- cairo_surface_t *pattern_surface = surface_pattern->surface;
+ cairo_surface_t *pattern_surface = pattern_surface = surface_pattern->surface;
/* XXX: both source and target are GL surface */
if (cairo_surface_get_type (pattern_surface) == CAIRO_SURFACE_TYPE_GL &&
@@ -87,7 +87,7 @@ _cairo_composite_reduce_pattern (const cairo_pattern_t *src,
if (dst->base.type == CAIRO_PATTERN_TYPE_SOLID)
return;
- dst->base.filter = _cairo_pattern_analyze_filter (&dst->base, NULL),
+ dst->base.filter = _cairo_pattern_analyze_filter (&dst->base);
tx = ty = 0;
if (_cairo_matrix_is_pixman_translation (&dst->base.matrix,
@@ -244,6 +244,13 @@ _cairo_composite_rectangles_intersect (cairo_composite_rectangles_t *extents,
_cairo_clip_get_extents (extents->clip)))
return CAIRO_INT_STATUS_NOTHING_TO_DO;
+ if (! _cairo_rectangle_intersect (&extents->bounded,
+ _cairo_clip_get_extents (extents->clip)) &&
+ extents->is_bounded & CAIRO_OPERATOR_BOUND_BY_MASK)
+ {
+ return CAIRO_INT_STATUS_NOTHING_TO_DO;
+ }
+
if (extents->source_pattern.base.type != CAIRO_PATTERN_TYPE_SOLID)
_cairo_pattern_sampled_area (&extents->source_pattern.base,
&extents->bounded,
diff --git a/src/cairo-compositor-private.h b/src/cairo-compositor-private.h
index 3a461bf06..d4230b1bc 100755..100644
--- a/src/cairo-compositor-private.h
+++ b/src/cairo-compositor-private.h
@@ -242,18 +242,18 @@ struct cairo_traps_compositor {
int dst_y,
unsigned int width,
unsigned int height);
- cairo_int_status_t
- (*lerp_color_glyph) (void *_dst,
- cairo_surface_t *abstract_src,
- cairo_surface_t *abstract_mask,
- int src_x,
- int src_y,
- int mask_x,
- int mask_y,
- int dst_x,
- int dst_y,
- unsigned int width,
- unsigned int height);
+ cairo_int_status_t
+ (*lerp_color_glyph) (void *_dst,
+ cairo_surface_t *abstract_src,
+ cairo_surface_t *abstract_mask,
+ int src_x,
+ int src_y,
+ int mask_x,
+ int mask_y,
+ int dst_x,
+ int dst_y,
+ unsigned int width,
+ unsigned int height);
cairo_int_status_t
(*composite_boxes) (void *surface,
diff --git a/src/cairo-compositor.c b/src/cairo-compositor.c
index 0c4d34cc0..0c4d34cc0 100755..100644
--- a/src/cairo-compositor.c
+++ b/src/cairo-compositor.c
diff --git a/src/cairo-contour-inline.h b/src/cairo-contour-inline.h
index 7972c1ac5..7972c1ac5 100755..100644
--- a/src/cairo-contour-inline.h
+++ b/src/cairo-contour-inline.h
diff --git a/src/cairo-contour-private.h b/src/cairo-contour-private.h
index 1dfc46f3a..1dfc46f3a 100755..100644
--- a/src/cairo-contour-private.h
+++ b/src/cairo-contour-private.h
diff --git a/src/cairo-contour.c b/src/cairo-contour.c
index d356f4f65..9ad75bdbf 100755..100644
--- a/src/cairo-contour.c
+++ b/src/cairo-contour.c
@@ -332,7 +332,6 @@ _cairo_contour_simplify (cairo_contour_t *contour, double tolerance)
}
/* stage2: polygon simplification using Douglas-Peucker */
- simplified = FALSE;
do {
last = &contour->chain.points[0];
iter_init (&furthest, contour);
diff --git a/src/cairo-convex-fill-private.h b/src/cairo-convex-fill-private.h
new file mode 100644
index 000000000..ba76045b3
--- /dev/null
+++ b/src/cairo-convex-fill-private.h
@@ -0,0 +1,112 @@
+/* cairo - a vector graphics library with display and print output
+ *
+ * Copyright © 2014 Samsung Research America, Silicon Valley
+ *
+ * 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 Red Hat, Inc.
+ *
+ * Contributor(s):
+ * Srikanth Chevalam<chevalam.s@samsung.com>
+ * Suyambulingam Rathinasamy<suyambu.rm@samsung.com>
+ * Henry Song <henry.song@samsung.com>
+ */
+#ifndef __CAIRO_CONVEX_FILL_H_
+#define __CAIRO_CONVEX_FILL_H_
+
+#include "cairo-box-inline.h"
+#include "cairo-list-inline.h"
+#include "cairo-stroke-dash-private.h"
+#include "cairo-slope-private.h"
+
+#define NUM_SPLINE_CALLS 64
+
+typedef struct cairo_convex_fill_closure {
+ cairo_status_t (*add_triangle_fan) (void *closure,
+ const cairo_point_t *points,
+ int npoints);
+ double tolerance;
+ cairo_point_t current_point;
+ cairo_point_t start_point;
+ void *closure;
+ unsigned int pcount;
+ unsigned int capacity;
+ cairo_bool_t midp_added;
+ cairo_point_t embedded_points[NUM_SPLINE_CALLS];
+ cairo_point_t *convex_points;
+} cairo_convex_fill_closure_t;
+
+typedef cairo_warn cairo_status_t
+(*cairo_convex_fill_closure_add_triangle_fan) (void *closure,
+ const cairo_point_t *points,
+ int npoints);
+
+cairo_status_t
+_cairo_convex_fill_spline_to (void *closure,
+ const cairo_point_t *point,
+ const cairo_slope_t *tangent);
+
+
+cairo_status_t
+_cairo_convex_fill_curve_to (void *closure,
+ const cairo_point_t *b,
+ const cairo_point_t *c,
+ const cairo_point_t *d);
+
+cairo_status_t
+_cairo_convex_fill_move_to (void *closure,
+ const cairo_point_t *point);
+
+cairo_status_t
+_cairo_path_fixed_fill_to_convex (cairo_convex_fill_closure_add_triangle_fan add_triangle_fan,
+ const cairo_path_fixed_t *path,
+ cairo_path_fixed_move_to_func_t *move_to,
+ cairo_path_fixed_line_to_func_t *line_to,
+ cairo_path_fixed_curve_to_func_t *curve_to,
+ cairo_path_fixed_close_path_func_t *close_path,
+ void *closure);
+
+
+cairo_status_t
+_cairo_path_fixed_convex_fill_interpret (const cairo_path_fixed_t *path,
+ cairo_path_fixed_move_to_func_t *move_to,
+ cairo_path_fixed_line_to_func_t *line_to,
+ cairo_path_fixed_curve_to_func_t *curve_to,
+ cairo_path_fixed_close_path_func_t *close_path,
+ void *closure);
+
+cairo_status_t
+_cairo_convex_fill_line_to (void *closure,
+ const cairo_point_t *point);
+
+cairo_status_t
+_cairo_convex_fill_close_path (void *closure);
+
+cairo_status_t
+_add_triangle (void *closure,
+ const cairo_point_t triangle[3]);
+
+#endif
diff --git a/src/cairo-convex-fill.c b/src/cairo-convex-fill.c
new file mode 100644
index 000000000..e5fefe315
--- /dev/null
+++ b/src/cairo-convex-fill.c
@@ -0,0 +1,219 @@
+/* cairo - a vector graphics library with display and print output
+*
+* Copyright © 2014 Samsung Research America, Silicon Valley
+*
+* 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 Red Hat, Inc.
+*
+* Contributor(s):
+* Srikanth Chevalam<chevalam.s@samsung.com>
+* Suyambulingam Rathinasamy<suyambu.rm@samsung.com>
+* Henry Song <henry.song@samsung.com>
+*/
+
+#include "cairo-convex-fill-private.h"
+#include <sys/time.h>
+
+cairo_status_t
+_add_triangle (void *closure,
+ const cairo_point_t* triangle)
+{
+ cairo_convex_fill_closure_t *filler = closure;
+ int required_space = 1;
+ if (! filler->midp_added)
+ required_space = 2;
+
+ if(filler->capacity < filler->pcount + required_space) {
+ filler->capacity += NUM_SPLINE_CALLS;
+ if (filler->convex_points == filler->embedded_points) {
+ filler->convex_points = _cairo_malloc_ab (filler->capacity, sizeof(cairo_point_t));
+ memcpy (filler->convex_points, filler->embedded_points, sizeof(cairo_point_t) * NUM_SPLINE_CALLS);
+ }
+ else
+ filler->convex_points = _cairo_realloc_ab (filler->convex_points, filler->capacity, sizeof (cairo_point_t));
+ }
+
+ if (! filler->midp_added) {
+ filler->convex_points[filler->pcount++] = filler->start_point;
+ filler->midp_added = TRUE;
+ }
+ filler->convex_points[filler->pcount++] = *triangle;
+
+ return CAIRO_STATUS_SUCCESS;
+}
+
+cairo_status_t
+_cairo_convex_fill_spline_to (void *closure,
+ const cairo_point_t *point,
+ const cairo_slope_t *tangent)
+{
+ cairo_convex_fill_closure_t *filler = closure;
+ if (filler->current_point.x == point->x &&
+ filler->current_point.y == point->y)
+ return CAIRO_STATUS_SUCCESS;
+
+ if ((filler->current_point.x != point->x ||
+ filler->current_point.y != point->y))
+ _add_triangle (filler, point);
+
+ filler->current_point = *point;
+ return CAIRO_STATUS_SUCCESS;
+}
+
+
+cairo_status_t
+_cairo_convex_fill_move_to (void *closure,
+ const cairo_point_t *point)
+{
+ cairo_convex_fill_closure_t *path = closure;
+ path->current_point = *point;
+ path->start_point = path->current_point;
+ return CAIRO_STATUS_SUCCESS;
+}
+
+cairo_status_t
+_cairo_convex_fill_line_to (void *closure,
+ const cairo_point_t *point)
+{
+ cairo_convex_fill_closure_t *filler = closure;
+
+ _add_triangle(filler, point);
+
+ filler->current_point = *point;
+
+ return CAIRO_STATUS_SUCCESS;
+}
+
+cairo_status_t
+_cairo_convex_fill_close_path (void *closure)
+{
+ cairo_convex_fill_closure_t *filler = closure;
+ _cairo_convex_fill_line_to (closure, &filler->start_point);
+ return CAIRO_STATUS_SUCCESS;
+}
+
+cairo_status_t
+_cairo_path_fixed_fill_to_convex (cairo_convex_fill_closure_add_triangle_fan add_triangle_fan,
+ const cairo_path_fixed_t *path,
+ cairo_path_fixed_move_to_func_t *move_to,
+ cairo_path_fixed_line_to_func_t *line_to,
+ cairo_path_fixed_curve_to_func_t *curve_to,
+ cairo_path_fixed_close_path_func_t *close_path,
+ void *closure)
+{
+ cairo_convex_fill_closure_t *filler = closure ;
+ cairo_status_t status = CAIRO_STATUS_SUCCESS;
+ filler->current_point = path->current_point;
+ filler->start_point = filler->current_point;
+ filler->add_triangle_fan = add_triangle_fan;
+ filler->pcount = 0 ;
+ filler->capacity = NUM_SPLINE_CALLS;
+ filler->convex_points = filler->embedded_points;
+ //filler->convex_points = _cairo_malloc_ab (filler->capacity, sizeof(cairo_point_t));
+ status = _cairo_path_fixed_convex_fill_interpret (path,
+ move_to,
+ line_to,
+ curve_to,
+ close_path,
+ filler);
+ return status;
+}
+
+cairo_status_t
+_cairo_convex_fill_curve_to (void *closure,
+ const cairo_point_t *b,
+ const cairo_point_t *c,
+ const cairo_point_t *d)
+{
+ cairo_convex_fill_closure_t *filler = closure;
+ cairo_spline_t spline;
+ cairo_status_t status = CAIRO_STATUS_SUCCESS;
+ if (! _cairo_spline_init (&spline,
+ (cairo_spline_add_point_func_t) _cairo_convex_fill_spline_to,
+ filler,
+ &filler->current_point, b, c, d))
+ return _cairo_convex_fill_line_to (closure, d);
+
+ status = _cairo_spline_decompose (&spline, filler->tolerance);
+
+ if (unlikely (status))
+ return status;
+ return CAIRO_STATUS_SUCCESS;
+}
+
+cairo_status_t
+_cairo_path_fixed_convex_fill_interpret (const cairo_path_fixed_t *path,
+ cairo_path_fixed_move_to_func_t *move_to,
+ cairo_path_fixed_line_to_func_t *line_to,
+ cairo_path_fixed_curve_to_func_t *curve_to,
+ cairo_path_fixed_close_path_func_t *close_path,
+ void *closure)
+{
+ const cairo_path_buf_t *buf;
+ cairo_status_t status;
+ cairo_convex_fill_closure_t *filler = closure;
+
+ cairo_path_foreach_buf_start (buf, path) {
+ const cairo_point_t *points = buf->points;
+ unsigned int i;
+
+ for (i = 0; i < buf->num_ops; i++) {
+ switch (buf->op[i]) {
+ case CAIRO_PATH_OP_MOVE_TO:
+ status = (*move_to) (closure, &points[0]);
+ points += 1;
+ break;
+ case CAIRO_PATH_OP_LINE_TO:
+ status = (*line_to) (closure, &points[0]);
+ points += 1;
+ break;
+ case CAIRO_PATH_OP_CURVE_TO:
+ status = (*curve_to) (closure, &points[0], &points[1], &points[2]);
+ points += 3;
+ break;
+ default:
+ ASSERT_NOT_REACHED;
+ case CAIRO_PATH_OP_CLOSE_PATH:
+ status = (*close_path) (closure);
+ break;
+ }
+
+ if (unlikely (status))
+ return status;
+ }
+ } cairo_path_foreach_buf_end (buf, path);
+
+ if (filler->pcount) {
+ filler->add_triangle_fan (filler->closure,
+ filler->convex_points,
+ filler->pcount);
+ }
+ if (filler->convex_points != filler->embedded_points)
+ free (filler->convex_points);
+
+ return status;
+}
diff --git a/src/cairo-damage-private.h b/src/cairo-damage-private.h
index 97b177e86..97b177e86 100755..100644
--- a/src/cairo-damage-private.h
+++ b/src/cairo-damage-private.h
diff --git a/src/cairo-damage.c b/src/cairo-damage.c
index 63191fee9..63191fee9 100755..100644
--- a/src/cairo-damage.c
+++ b/src/cairo-damage.c
diff --git a/src/cairo-debug.c b/src/cairo-debug.c
index 33d46aa3f..33d46aa3f 100755..100644
--- a/src/cairo-debug.c
+++ b/src/cairo-debug.c
diff --git a/src/cairo-default-context-private.h b/src/cairo-default-context-private.h
index fd159b496..fd159b496 100755..100644
--- a/src/cairo-default-context-private.h
+++ b/src/cairo-default-context-private.h
diff --git a/src/cairo-default-context.c b/src/cairo-default-context.c
index b7a38d2f0..4b63d53be 100755..100644
--- a/src/cairo-default-context.c
+++ b/src/cairo-default-context.c
@@ -139,7 +139,6 @@ _cairo_default_context_push_group (void *abstract_cr, cairo_content_t content)
cairo_surface_t *group_surface;
cairo_clip_t *clip;
cairo_status_t status;
-
clip = _cairo_gstate_get_clip (cr->gstate);
if (_cairo_clip_is_all_clipped (clip)) {
group_surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 0, 0);
@@ -153,6 +152,11 @@ _cairo_default_context_push_group (void *abstract_cr, cairo_content_t content)
parent_surface = _cairo_gstate_get_target (cr->gstate);
+ if (unlikely (parent_surface->status))
+ return parent_surface->status;
+ if (unlikely (parent_surface->finished))
+ return _cairo_error (CAIRO_STATUS_SURFACE_FINISHED);
+
/* Get the extents that we'll use in creating our new group surface */
bounded = _cairo_surface_get_extents (parent_surface, &extents);
if (clip)
@@ -165,11 +169,11 @@ _cairo_default_context_push_group (void *abstract_cr, cairo_content_t content)
group_surface = cairo_recording_surface_create (content, NULL);
extents.x = extents.y = 0;
} else {
- group_surface = _cairo_surface_create_similar_solid (parent_surface,
- content,
- extents.width,
- extents.height,
- CAIRO_COLOR_TRANSPARENT);
+ group_surface = _cairo_surface_create_scratch (parent_surface,
+ content,
+ extents.width,
+ extents.height,
+ CAIRO_COLOR_TRANSPARENT);
}
status = group_surface->status;
if (unlikely (status))
@@ -184,6 +188,10 @@ _cairo_default_context_push_group (void *abstract_cr, cairo_content_t content)
parent_surface->device_transform.x0 - extents.x,
parent_surface->device_transform.y0 - extents.y);
+ cairo_surface_set_device_scale (group_surface,
+ parent_surface->device_transform.xx,
+ parent_surface->device_transform.yy);
+
/* If we have a current path, we need to adjust it to compensate for
* the device offset just applied. */
_cairo_path_fixed_translate (cr->path,
@@ -209,7 +217,8 @@ _cairo_default_context_pop_group (void *abstract_cr)
cairo_default_context_t *cr = abstract_cr;
cairo_surface_t *group_surface;
cairo_pattern_t *group_pattern;
- cairo_matrix_t group_matrix, device_transform_matrix;
+ cairo_surface_t *parent_surface;
+ cairo_matrix_t group_matrix;
cairo_status_t status;
/* Verify that we are at the right nesting level */
@@ -223,29 +232,21 @@ _cairo_default_context_pop_group (void *abstract_cr)
status = _cairo_gstate_restore (&cr->gstate, &cr->gstate_freelist);
assert (status == CAIRO_STATUS_SUCCESS);
+ parent_surface = _cairo_gstate_get_target (cr->gstate);
+
group_pattern = cairo_pattern_create_for_surface (group_surface);
status = group_pattern->status;
if (unlikely (status))
goto done;
_cairo_gstate_get_matrix (cr->gstate, &group_matrix);
- /* Transform by group_matrix centered around device_transform so that when
- * we call _cairo_gstate_copy_transformed_pattern the result is a pattern
- * with a matrix equivalent to the device_transform of group_surface. */
- if (_cairo_surface_has_device_transform (group_surface)) {
- cairo_pattern_set_matrix (group_pattern, &group_surface->device_transform);
- _cairo_pattern_transform (group_pattern, &group_matrix);
- _cairo_pattern_transform (group_pattern, &group_surface->device_transform_inverse);
- } else {
- cairo_pattern_set_matrix (group_pattern, &group_matrix);
- }
+ cairo_pattern_set_matrix (group_pattern, &group_matrix);
/* If we have a current path, we need to adjust it to compensate for
* the device offset just removed. */
- cairo_matrix_multiply (&device_transform_matrix,
- &_cairo_gstate_get_target (cr->gstate)->device_transform,
- &group_surface->device_transform_inverse);
- _cairo_path_fixed_transform (cr->path, &device_transform_matrix);
+ _cairo_path_fixed_translate (cr->path,
+ _cairo_fixed_from_int (parent_surface->device_transform.x0 - group_surface->device_transform.x0),
+ _cairo_fixed_from_int (parent_surface->device_transform.y0 - group_surface->device_transform.y0));
done:
cairo_surface_destroy (group_surface);
@@ -267,7 +268,7 @@ _current_source_matches_solid (const cairo_pattern_t *pattern,
double red,
double green,
double blue,
- double alpha)
+ double alpha)
{
cairo_color_t color;
@@ -299,11 +300,8 @@ _cairo_default_context_set_source_rgba (void *abstract_cr, double red, double gr
_cairo_default_context_set_source (cr, (cairo_pattern_t *) &_cairo_pattern_black);
pattern = cairo_pattern_create_rgba (red, green, blue, alpha);
- if (unlikely (pattern->status)) {
- status = pattern->status;
- cairo_pattern_destroy (pattern);
- return pattern->status;
- }
+ if (unlikely (pattern->status))
+ return pattern->status;
status = _cairo_default_context_set_source (cr, pattern);
cairo_pattern_destroy (pattern);
@@ -326,11 +324,8 @@ _cairo_default_context_set_source_surface (void *abstract_cr,
_cairo_default_context_set_source (cr, (cairo_pattern_t *) &_cairo_pattern_black);
pattern = cairo_pattern_create_for_surface (surface);
- if (unlikely (pattern->status)) {
- status = pattern->status;
- cairo_pattern_destroy (pattern);
- return status;
- }
+ if (unlikely (pattern->status))
+ return pattern->status;
cairo_matrix_init_translate (&matrix, -x, -y);
cairo_pattern_set_matrix (pattern, &matrix);
@@ -711,7 +706,6 @@ _cairo_default_context_line_to (void *abstract_cr, double x, double y)
{
cairo_default_context_t *cr = abstract_cr;
cairo_fixed_t x_fixed, y_fixed;
-
_cairo_gstate_user_to_backend (cr->gstate, &x, &y);
x_fixed = _cairo_fixed_from_double (x);
y_fixed = _cairo_fixed_from_double (y);
@@ -729,7 +723,6 @@ _cairo_default_context_curve_to (void *abstract_cr,
cairo_fixed_t x1_fixed, y1_fixed;
cairo_fixed_t x2_fixed, y2_fixed;
cairo_fixed_t x3_fixed, y3_fixed;
-
_cairo_gstate_user_to_backend (cr->gstate, &x1, &y1);
_cairo_gstate_user_to_backend (cr->gstate, &x2, &y2);
_cairo_gstate_user_to_backend (cr->gstate, &x3, &y3);
@@ -758,13 +751,16 @@ _cairo_default_context_arc (void *abstract_cr,
cairo_default_context_t *cr = abstract_cr;
cairo_status_t status;
+ cairo_fixed_t x_fixed, y_fixed;
+
+ cairo_bool_t path_empty = _cairo_path_fixed_is_empty (cr->path);
+
/* Do nothing, successfully, if radius is <= 0 */
if (radius <= 0.0) {
- cairo_fixed_t x_fixed, y_fixed;
-
_cairo_gstate_user_to_backend (cr->gstate, &xc, &yc);
x_fixed = _cairo_fixed_from_double (xc);
y_fixed = _cairo_fixed_from_double (yc);
+
status = _cairo_path_fixed_line_to (cr->path, x_fixed, y_fixed);
if (unlikely (status))
return status;
@@ -788,6 +784,16 @@ _cairo_default_context_arc (void *abstract_cr,
else
_cairo_arc_path_negative (&cr->base, xc, yc, radius, angle1, angle2);
+ if (path_empty) {
+ x_fixed = _cairo_fixed_from_double (xc + radius * cos (angle1));
+ y_fixed = _cairo_fixed_from_double (yc + radius * sin (angle1));
+ cr->path->start_point.x = x_fixed;
+ cr->path->start_point.y = y_fixed;
+ cr->path->is_convex = TRUE;
+ }
+ else
+ cr->path->is_convex = FALSE;
+
return CAIRO_STATUS_SUCCESS; /* any error will have already been set on cr */
}
@@ -885,6 +891,161 @@ _cairo_default_context_rectangle (void *abstract_cr,
return _cairo_default_context_close_path (cr);
}
+static cairo_status_t
+_cairo_default_context_rounded_rectangle_curve_to (void *abstract_cr,
+ double xc, double yc,
+ double radius,
+ double angle_a,
+ double angle_b)
+{
+ double sin_a, cos_a;
+ double sin_b, cos_b;
+ double h;
+
+ sin_a = radius * sin (angle_a);
+ cos_a = radius * cos (angle_a);
+ sin_b = radius * sin (angle_b);
+ cos_b = radius * cos (angle_b);
+ h = 4.0/3.0 * tan ((angle_b - angle_a) / 4.0);
+ return _cairo_default_context_curve_to (abstract_cr,
+ xc + cos_a - h * sin_a,
+ yc + sin_a + h * cos_a,
+ xc + cos_b + h * sin_b,
+ yc + sin_b - h * cos_b,
+ xc + cos_b, yc + sin_b);
+}
+
+static cairo_status_t
+_cairo_default_context_rounded_rectangle (void *abstract_cr,
+ double x, double y,
+ double width, double height,
+ double r_top_left, double r_top_right,
+ double r_bottom_left, double r_bottom_right)
+{
+ cairo_default_context_t *cr = abstract_cr;
+ cairo_status_t status;
+ double temp_scale, scale = 1.0;
+ double length;
+ cairo_bool_t path_empty;
+ double x_start, y_start;
+
+ if (width <= 0.0 || height <= 0.0)
+ return CAIRO_STATUS_SUCCESS;
+
+ path_empty = _cairo_path_fixed_is_empty (cr->path);
+
+ if (r_top_left <= 0.0)
+ r_top_left = 0.0;
+ if (r_top_right <= 0.0)
+ r_top_left = 0.0;
+ if (r_bottom_left < 0.0)
+ r_bottom_left = 0.0;
+ if (r_bottom_right <= 0.0)
+ r_bottom_right = 0.0;
+
+ length = r_top_left + r_top_right;
+ if (length > width) {
+ temp_scale = width / length;
+ scale = temp_scale;
+ }
+ length = r_top_right + r_bottom_right;
+ if (length > height) {
+ temp_scale = height / length;
+ if (temp_scale < scale)
+ scale = temp_scale;
+ }
+ length = r_bottom_right + r_bottom_left;
+ if (length > width) {
+ temp_scale = width / length;
+ if (temp_scale < scale)
+ scale = temp_scale;
+ }
+ length = r_bottom_left + r_top_left;
+ if (length > height) {
+ temp_scale = height / length;
+ if (temp_scale < scale)
+ scale = temp_scale;
+ }
+
+ if (scale != 0) {
+ r_top_left *= scale;
+ r_top_right *= scale;
+ r_bottom_left *= scale;
+ r_bottom_right *= scale;
+ }
+
+ status = _cairo_default_context_move_to (cr, x, y + r_top_left);
+ if (unlikely (status))
+ return status;
+
+ status = _cairo_default_context_rounded_rectangle_curve_to (cr,
+ x + r_top_left,
+ y + r_top_left,
+ r_top_left,
+ M_PI,
+ 1.5 * M_PI);
+ if (unlikely (status))
+ return status;
+
+ status = _cairo_default_context_rel_line_to (cr,
+ width - r_top_left - r_top_right,
+ 0);
+ if (unlikely (status))
+ return status;
+
+ status = _cairo_default_context_rounded_rectangle_curve_to (cr,
+ x + width - r_top_right,
+ y + r_top_right,
+ r_top_right,
+ 1.5 *M_PI,
+ 2.0 * M_PI);
+ if (unlikely (status))
+ return status;
+
+ status = _cairo_default_context_rel_line_to (cr, 0, height - r_top_right - r_bottom_right);
+ if (unlikely (status))
+ return status;
+
+ status = _cairo_default_context_rounded_rectangle_curve_to (cr,
+ x + width - r_bottom_right,
+ y + height - r_bottom_right,
+ r_bottom_right,
+ 0,
+ 0.5 * M_PI);
+ if (unlikely (status))
+ return status;
+
+ status = _cairo_default_context_rel_line_to (cr, -width + r_bottom_right + r_bottom_left, 0);
+ if (unlikely (status))
+ return status;
+
+ status = _cairo_default_context_rounded_rectangle_curve_to (cr,
+ x + r_bottom_left,
+ y + height - r_bottom_left,
+ r_bottom_left,
+ 0.5 * M_PI,
+ M_PI);
+ if (unlikely (status))
+ return status;
+
+ status = _cairo_default_context_close_path (cr);
+ if (unlikely (status))
+ return status;
+
+ if (path_empty) {
+ x_start = x;
+ y_start = y + r_top_left;
+ _cairo_gstate_user_to_backend (cr->gstate, &x_start, &y_start);
+ cr->path->start_point.x = _cairo_fixed_from_double (x_start);
+ cr->path->start_point.y = _cairo_fixed_from_double (y_start);
+ cr->path->is_convex = TRUE;
+ }
+ else
+ cr->path->is_convex = FALSE;
+
+ return CAIRO_STATUS_SUCCESS;
+}
+
static void
_cairo_default_context_path_extents (void *abstract_cr,
double *x1,
@@ -950,8 +1111,12 @@ _cairo_default_context_append_path (void *abstract_cr,
const cairo_path_t *path)
{
cairo_default_context_t *cr = abstract_cr;
+ cairo_bool_t can_apply_convex = _cairo_path_fixed_is_empty (cr->path);
- return _cairo_path_append_to_context (path, &cr->base);
+ cairo_status_t status = _cairo_path_append_to_context (path, &cr->base);
+ if (can_apply_convex && path->is_convex)
+ cr->path->is_convex = path->is_convex;
+ return status;
}
static cairo_status_t
@@ -1055,7 +1220,7 @@ _cairo_default_context_fill (void *abstract_cr)
{
cairo_default_context_t *cr = abstract_cr;
cairo_status_t status;
-
+
status = _cairo_gstate_fill (cr->gstate, cr->path);
if (unlikely (status))
return status;
@@ -1297,7 +1462,6 @@ _cairo_default_context_glyphs (void *abstract_cr,
cairo_glyph_text_info_t *info)
{
cairo_default_context_t *cr = abstract_cr;
-
return _cairo_gstate_show_text_glyphs (cr->gstate, glyphs, num_glyphs, info);
}
@@ -1307,7 +1471,6 @@ _cairo_default_context_glyph_path (void *abstract_cr,
int num_glyphs)
{
cairo_default_context_t *cr = abstract_cr;
-
return _cairo_gstate_glyph_path (cr->gstate,
glyphs, num_glyphs,
cr->path);
@@ -1320,7 +1483,6 @@ _cairo_default_context_glyph_extents (void *abstract_cr,
cairo_text_extents_t *extents)
{
cairo_default_context_t *cr = abstract_cr;
-
return _cairo_gstate_glyph_extents (cr->gstate, glyphs, num_glyphs, extents);
}
@@ -1458,6 +1620,7 @@ static const cairo_backend_t _cairo_default_context_backend = {
_cairo_default_context_close_path,
_cairo_default_context_arc,
_cairo_default_context_rectangle,
+ _cairo_default_context_rounded_rectangle,
_cairo_default_context_path_extents,
_cairo_default_context_has_current_point,
_cairo_default_context_get_current_point,
diff --git a/src/cairo-deflate-stream.c b/src/cairo-deflate-stream.c
index ae23bda94..ae23bda94 100755..100644
--- a/src/cairo-deflate-stream.c
+++ b/src/cairo-deflate-stream.c
diff --git a/src/cairo-deprecated.h b/src/cairo-deprecated.h
index 7a56aadbf..7a56aadbf 100755..100644
--- a/src/cairo-deprecated.h
+++ b/src/cairo-deprecated.h
diff --git a/src/cairo-device-private.h b/src/cairo-device-private.h
index 1c687d2fe..1c687d2fe 100755..100644
--- a/src/cairo-device-private.h
+++ b/src/cairo-device-private.h
diff --git a/src/cairo-device.c b/src/cairo-device.c
index e845912a3..b4d1f8422 100755..100644
--- a/src/cairo-device.c
+++ b/src/cairo-device.c
@@ -159,6 +159,7 @@ _cairo_device_create_in_error (cairo_status_t status)
case CAIRO_STATUS_INVALID_CONTENT:
case CAIRO_STATUS_INVALID_MESH_CONSTRUCTION:
case CAIRO_STATUS_DEVICE_FINISHED:
+ case CAIRO_STATUS_JBIG2_GLOBAL_MISSING:
default:
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return (cairo_device_t *) &_nil_device;
@@ -345,7 +346,7 @@ cairo_device_destroy (cairo_device_t *device)
while (! cairo_list_is_empty (&device->shadow_caches)) {
cairo_shadow_cache_t *shadow;
- shadow = cairo_list_first_entry (&device->shadow_caches,
+ shadow = cairo_list_first_entry (&device->shadow_caches,
cairo_shadow_cache_t,
link);
diff --git a/src/cairo-directfb-surface.c b/src/cairo-directfb-surface.c
index 16e367af8..5ac64ba98 100755..100644
--- a/src/cairo-directfb-surface.c
+++ b/src/cairo-directfb-surface.c
@@ -197,7 +197,7 @@ _cairo_dfb_surface_map_to_image (void *abstract_surface,
_cairo_image_surface_init (&surface->image, image, surface->image.pixman_format);
}
- return _cairo_surface_map_to_image (&surface->image.base, extents);
+ return _cairo_image_surface_map_to_image (&surface->image.base, extents);
}
static cairo_int_status_t
@@ -205,7 +205,7 @@ _cairo_dfb_surface_unmap_image (void *abstract_surface,
cairo_image_surface_t *image)
{
cairo_dfb_surface_t *surface = abstract_surface;
- return _cairo_surface_unmap_image (&surface->image.base, image);
+ return _cairo_image_surface_unmap_image (&surface->image.base, image);
}
static cairo_status_t
diff --git a/src/cairo-directfb.h b/src/cairo-directfb.h
index e3d818c66..e3d818c66 100755..100644
--- a/src/cairo-directfb.h
+++ b/src/cairo-directfb.h
diff --git a/src/cairo-drm.h b/src/cairo-drm.h
index 907610dcd..907610dcd 100755..100644
--- a/src/cairo-drm.h
+++ b/src/cairo-drm.h
diff --git a/src/cairo-egl-context.c b/src/cairo-egl-context.c
index fa52a04ba..5b67d4b3c 100755..100644
--- a/src/cairo-egl-context.c
+++ b/src/cairo-egl-context.c
@@ -93,7 +93,6 @@ typedef struct _cairo_egl_context {
EGLSurface dummy_surface;
EGLSurface current_surface;
- EGLDisplay previous_display;
EGLContext previous_context;
EGLSurface previous_surface;
} cairo_egl_context_t;
@@ -110,8 +109,7 @@ _context_acquisition_changed_egl_state (cairo_egl_context_t *ctx,
EGLSurface current_surface)
{
return ctx->previous_context != ctx->context ||
- ctx->previous_surface != current_surface ||
- ctx->previous_display != ctx->display;
+ ctx->previous_surface != current_surface;
}
static EGLSurface
@@ -128,19 +126,8 @@ _egl_get_current_surface (cairo_egl_context_t *ctx)
static void
_egl_query_current_state (cairo_egl_context_t *ctx)
{
- ctx->previous_surface = eglGetCurrentSurface (EGL_DRAW);
ctx->previous_context = eglGetCurrentContext ();
- ctx->previous_display = eglGetCurrentDisplay ();
-
- /* If any of the values were none, assume they are all none. Not all
- drivers seem well behaved when it comes to using these values across
- multiple threads. */
- if (ctx->previous_surface == EGL_NO_SURFACE ||
- ctx->previous_context == EGL_NO_CONTEXT || ctx->previous_display == EGL_NO_DISPLAY) {
- ctx->previous_surface = EGL_NO_SURFACE;
- ctx->previous_context = EGL_NO_CONTEXT;
- ctx->previous_display = EGL_NO_DISPLAY;
- }
+ ctx->previous_surface = eglGetCurrentSurface (EGL_DRAW);
}
static void
@@ -272,7 +259,7 @@ _cairo_egl_get_proc_address (void *data, const char *name)
};
for (i = 0; func_map[i].name; i++) {
- if (! strncmp (func_map[i].name, name, strlen(name)))
+ if (! strcmp (func_map[i].name, name))
return func_map[i].func;
}
@@ -352,6 +339,12 @@ cairo_egl_device_create (EGLDisplay dpy, EGLContext egl)
return _cairo_gl_context_create_in_error (status);
}
+ /* Tune the default VBO size to reduce overhead on embedded devices.
+ * This smaller size means that flushing needs to be done more often,
+ * but it is less demanding of scarce memory on embedded devices.
+ */
+ ctx->base.vbo_size = 16*1024;
+
eglMakeCurrent (dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
ctx->current_surface = EGL_NO_SURFACE;
diff --git a/src/cairo-error-inline.h b/src/cairo-error-inline.h
index 9126c5e61..9126c5e61 100755..100644
--- a/src/cairo-error-inline.h
+++ b/src/cairo-error-inline.h
diff --git a/src/cairo-error-private.h b/src/cairo-error-private.h
index ea9c2ea31..178078ad6 100755..100644
--- a/src/cairo-error-private.h
+++ b/src/cairo-error-private.h
@@ -46,10 +46,13 @@
CAIRO_BEGIN_DECLS
-/* Sure wish C had a real enum type so that this would be distinct
+/* _cairo_int_status: internal status
+ *
+ * Sure wish C had a real enum type so that this would be distinct
* from #cairo_status_t. Oh well, without that, I'll use this bogus 100
* offset. We want to keep it fit in int8_t as the compiler may choose
- * that for #cairo_status_t */
+ * that for #cairo_status_t
+ */
enum _cairo_int_status {
CAIRO_INT_STATUS_SUCCESS = 0,
@@ -90,6 +93,7 @@ enum _cairo_int_status {
CAIRO_INT_STATUS_DEVICE_ERROR,
CAIRO_INT_STATUS_INVALID_MESH_CONSTRUCTION,
CAIRO_INT_STATUS_DEVICE_FINISHED,
+ CAIRO_INT_STATUS_JBIG2_GLOBAL_MISSING,
CAIRO_INT_STATUS_LAST_STATUS,
diff --git a/src/cairo-error.c b/src/cairo-error.c
index 1b9bd76be..1b9bd76be 100755..100644
--- a/src/cairo-error.c
+++ b/src/cairo-error.c
diff --git a/src/cairo-evas-gl-context.c b/src/cairo-evas-gl-context.c
index 3f256cbc2..3cd4e0e0b 100755..100644
--- a/src/cairo-evas-gl-context.c
+++ b/src/cairo-evas-gl-context.c
@@ -180,7 +180,7 @@ _cairo_evas_gl_get_proc_addr (void *data, const char *name)
}
return evas_gl_proc_address_get (gl, name);
-}
+}
static cairo_bool_t
_context_acquisition_changed_evas_gl_state (cairo_evas_gl_context_t *ctx,
@@ -204,8 +204,8 @@ _evas_gl_get_current_surface (cairo_evas_gl_context_t *ctx)
static void
_evas_gl_query_current_state (cairo_evas_gl_context_t *ctx)
{
- ctx->queried_context = evas_gl_current_context_get (ctx->evas_gl);
- ctx->current_surface = evas_gl_current_surface_get (ctx->evas_gl);
+ ctx->queried_context = evas_gl_current_context_get (ctx->evas_gl);
+ ctx->current_surface = evas_gl_current_surface_get (ctx->evas_gl);
}
static void
@@ -394,13 +394,13 @@ cairo_gl_surface_create_for_evas_gl (cairo_device_t *device,
static cairo_bool_t is_evas_gl_device (cairo_device_t *device)
{
- return (device->backend != NULL &&
+ return (device->backend != NULL &&
device->backend->type == CAIRO_DEVICE_TYPE_GL);
}
static cairo_evas_gl_context_t *to_evas_gl_context (cairo_device_t *device)
{
- return (cairo_evas_gl_context_t *) device;
+ return (cairo_evas_gl_context_t *) device;
}
cairo_public Evas_GL *
@@ -412,7 +412,7 @@ cairo_evas_gl_device_get_gl (cairo_device_t *device)
return NULL;
}
- if (! is_evas_gl_device (device)) {
+ if (! is_evas_gl_device (device)) {
_cairo_error_throw (CAIRO_STATUS_DEVICE_TYPE_MISMATCH);
return NULL;
}
diff --git a/src/cairo-fallback-compositor.c b/src/cairo-fallback-compositor.c
index 3f6199fe2..3f6199fe2 100755..100644
--- a/src/cairo-fallback-compositor.c
+++ b/src/cairo-fallback-compositor.c
diff --git a/src/cairo-features-uninstalled.pc.in b/src/cairo-features-uninstalled.pc.in
index b9cd9d3ad..b9cd9d3ad 100755..100644
--- a/src/cairo-features-uninstalled.pc.in
+++ b/src/cairo-features-uninstalled.pc.in
diff --git a/src/cairo-features.pc.in b/src/cairo-features.pc.in
index 9a4b657c8..9a4b657c8 100755..100644
--- a/src/cairo-features.pc.in
+++ b/src/cairo-features.pc.in
diff --git a/src/cairo-filters-private.h b/src/cairo-filters-private.h
index 89b7037d6..89b7037d6 100755..100644
--- a/src/cairo-filters-private.h
+++ b/src/cairo-filters-private.h
diff --git a/src/cairo-filters.c b/src/cairo-filters.c
index dfacda58b..dfacda58b 100755..100644
--- a/src/cairo-filters.c
+++ b/src/cairo-filters.c
diff --git a/src/cairo-fixed-private.h b/src/cairo-fixed-private.h
index b6cc6be7d..9ff8f7503 100755..100644
--- a/src/cairo-fixed-private.h
+++ b/src/cairo-fixed-private.h
@@ -40,12 +40,13 @@
#include "cairo-fixed-type-private.h"
#include "cairo-wideint-private.h"
+#include "cairoint.h"
/* Implementation */
#if (CAIRO_FIXED_BITS != 32)
# error CAIRO_FIXED_BITS must be 32, and the type must be a 32-bit type.
-# error To remove this limitation, you will have to fix the tesselator.
+# error To remove this limitation, you will have to fix the tessellator.
#endif
#define CAIRO_FIXED_ONE ((cairo_fixed_t)(1 << CAIRO_FIXED_FRAC_BITS))
@@ -311,7 +312,7 @@ _cairo_fixed_mul_div_floor (cairo_fixed_t a, cairo_fixed_t b, cairo_fixed_t c)
return _cairo_int64_32_div (_cairo_int32x32_64_mul (a, b), c);
}
-
+/* compute y from x so that (x,y), p1, and p2 are collinear */
static inline cairo_fixed_t
_cairo_edge_compute_intersection_y_for_x (const cairo_point_t *p1,
const cairo_point_t *p2,
@@ -332,6 +333,7 @@ _cairo_edge_compute_intersection_y_for_x (const cairo_point_t *p1,
return y;
}
+/* compute x from y so that (x,y), p1, and p2 are collinear */
static inline cairo_fixed_t
_cairo_edge_compute_intersection_x_for_y (const cairo_point_t *p1,
const cairo_point_t *p2,
@@ -352,6 +354,40 @@ _cairo_edge_compute_intersection_x_for_y (const cairo_point_t *p1,
return x;
}
+/* Intersect two segments based on the algorithm described at
+ * http://paulbourke.net/geometry/pointlineplane/. This implementation
+ * uses floating point math. */
+static inline cairo_bool_t
+_slow_segment_intersection (const cairo_point_t *seg1_p1,
+ const cairo_point_t *seg1_p2,
+ const cairo_point_t *seg2_p1,
+ const cairo_point_t *seg2_p2,
+ cairo_point_t *intersection)
+{
+ double denominator, u_a, u_b;
+ double seg1_dx, seg1_dy, seg2_dx, seg2_dy, seg_start_dx, seg_start_dy;
+
+ seg1_dx = _cairo_fixed_to_double (seg1_p2->x - seg1_p1->x);
+ seg1_dy = _cairo_fixed_to_double (seg1_p2->y - seg1_p1->y);
+ seg2_dx = _cairo_fixed_to_double (seg2_p2->x - seg2_p1->x);
+ seg2_dy = _cairo_fixed_to_double (seg2_p2->y - seg2_p1->y);
+ denominator = (seg2_dy * seg1_dx) - (seg2_dx * seg1_dy);
+ if (denominator == 0)
+ return FALSE;
+
+ seg_start_dx = _cairo_fixed_to_double (seg1_p1->x - seg2_p1->x);
+ seg_start_dy = _cairo_fixed_to_double (seg1_p1->y - seg2_p1->y);
+ u_a = ((seg2_dx * seg_start_dy) - (seg2_dy * seg_start_dx)) / denominator;
+ u_b = ((seg1_dx * seg_start_dy) - (seg1_dy * seg_start_dx)) / denominator;
+
+ if (u_a <= 0 || u_a >= 1 || u_b <= 0 || u_b >= 1)
+ return FALSE;
+
+ intersection->x = seg1_p1->x + _cairo_fixed_from_double ((u_a * seg1_dx));
+ intersection->y = seg1_p1->y + _cairo_fixed_from_double ((u_a * seg1_dy));
+ return TRUE;
+}
+
#else
# error Please define multiplication and other operands for your fixed-point type size
#endif
diff --git a/src/cairo-fixed-type-private.h b/src/cairo-fixed-type-private.h
index 2bbd5f786..e9f26f615 100755..100644
--- a/src/cairo-fixed-type-private.h
+++ b/src/cairo-fixed-type-private.h
@@ -50,7 +50,7 @@ typedef cairo_int128_t cairo_fixed_64_64_t;
typedef cairo_int128_t cairo_fixed_96_32_t;
/* Eventually, we should allow changing this, but I think
- * there are some assumptions in the tesselator about the
+ * there are some assumptions in the tessellator about the
* size of a fixed type. For now, it must be 32.
*/
#define CAIRO_FIXED_BITS 32
diff --git a/src/cairo-fixed.c b/src/cairo-fixed.c
index 03e055923..03e055923 100755..100644
--- a/src/cairo-fixed.c
+++ b/src/cairo-fixed.c
diff --git a/src/cairo-font-face-twin-data.c b/src/cairo-font-face-twin-data.c
index ff09cb2be..ff09cb2be 100755..100644
--- a/src/cairo-font-face-twin-data.c
+++ b/src/cairo-font-face-twin-data.c
diff --git a/src/cairo-font-face-twin.c b/src/cairo-font-face-twin.c
index 22f87394a..22f87394a 100755..100644
--- a/src/cairo-font-face-twin.c
+++ b/src/cairo-font-face-twin.c
diff --git a/src/cairo-font-face.c b/src/cairo-font-face.c
index b93bd8caa..3bcd2a1e6 100755..100644
--- a/src/cairo-font-face.c
+++ b/src/cairo-font-face.c
@@ -115,7 +115,7 @@ cairo_font_face_t *
cairo_font_face_reference (cairo_font_face_t *font_face)
{
if (font_face == NULL ||
- CAIRO_REFERENCE_COUNT_IS_INVALID (&font_face->ref_count))
+ CAIRO_REFERENCE_COUNT_IS_INVALID (&font_face->ref_count))
return font_face;
/* We would normally assert that we have a reference here but we
@@ -128,6 +128,28 @@ cairo_font_face_reference (cairo_font_face_t *font_face)
}
slim_hidden_def (cairo_font_face_reference);
+static inline cairo_bool_t
+__put(cairo_reference_count_t *v)
+{
+ int c, old;
+
+ c = CAIRO_REFERENCE_COUNT_GET_VALUE(v);
+ while (c != 1 && (old = _cairo_atomic_int_cmpxchg_return_old(&v->ref_count, c, c - 1)) != c)
+ c = old;
+
+ return c != 1;
+}
+
+cairo_bool_t
+_cairo_font_face_destroy (void *abstract_face)
+{
+#if 0 /* Nothing needs to be done, we can just drop the last reference */
+ cairo_font_face_t *font_face = abstract_face;
+ return _cairo_reference_count_dec_and_test (&font_face->ref_count);
+#endif
+ return TRUE;
+}
+
/**
* cairo_font_face_destroy:
* @font_face: a #cairo_font_face_t
@@ -142,22 +164,19 @@ void
cairo_font_face_destroy (cairo_font_face_t *font_face)
{
if (font_face == NULL ||
- CAIRO_REFERENCE_COUNT_IS_INVALID (&font_face->ref_count))
+ CAIRO_REFERENCE_COUNT_IS_INVALID (&font_face->ref_count))
return;
assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&font_face->ref_count));
- if (! _cairo_reference_count_dec_and_test (&font_face->ref_count))
- return;
-
- if (font_face->backend->destroy)
- font_face->backend->destroy (font_face);
-
/* We allow resurrection to deal with some memory management for the
* FreeType backend where cairo_ft_font_face_t and cairo_ft_unscaled_font_t
* need to effectively mutually reference each other
*/
- if (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&font_face->ref_count))
+ if (__put (&font_face->ref_count))
+ return;
+
+ if (! font_face->backend->destroy (font_face))
return;
_cairo_user_data_array_fini (&font_face->user_data);
@@ -201,7 +220,7 @@ unsigned int
cairo_font_face_get_reference_count (cairo_font_face_t *font_face)
{
if (font_face == NULL ||
- CAIRO_REFERENCE_COUNT_IS_INVALID (&font_face->ref_count))
+ CAIRO_REFERENCE_COUNT_IS_INVALID (&font_face->ref_count))
return 0;
return CAIRO_REFERENCE_COUNT_GET_VALUE (&font_face->ref_count);
@@ -309,10 +328,11 @@ _cairo_unscaled_font_destroy (cairo_unscaled_font_t *unscaled_font)
assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&unscaled_font->ref_count));
- if (! _cairo_reference_count_dec_and_test (&unscaled_font->ref_count))
+ if (__put (&unscaled_font->ref_count))
return;
- unscaled_font->backend->destroy (unscaled_font);
+ if (! unscaled_font->backend->destroy (unscaled_font))
+ return;
free (unscaled_font);
}
diff --git a/src/cairo-font-options.c b/src/cairo-font-options.c
index 7b26853ad..d8883a5b5 100755..100644
--- a/src/cairo-font-options.c
+++ b/src/cairo-font-options.c
@@ -73,7 +73,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->color = CAIRO_FONT_COLOR_DEFAULT;
+ options->color = CAIRO_FONT_COLOR_DEFAULT;
}
void
@@ -86,7 +86,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->color = other->color;
+ options->color = other->color;
}
/**
@@ -228,7 +228,7 @@ 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->color != CAIRO_FONT_COLOR_DEFAULT)
+ if (other->color != CAIRO_FONT_COLOR_DEFAULT)
options->color = other->color;
}
slim_hidden_def (cairo_font_options_merge);
@@ -264,7 +264,7 @@ cairo_font_options_equal (const 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->color == other->color);
+ options->color == other->color);
}
slim_hidden_def (cairo_font_options_equal);
@@ -293,7 +293,7 @@ cairo_font_options_hash (const cairo_font_options_t *options)
(options->lcd_filter << 8) |
(options->hint_style << 12) |
(options->hint_metrics << 16) |
- (options->color << 20));
+ (options->color << 20));
}
slim_hidden_def (cairo_font_options_hash);
@@ -539,22 +539,23 @@ cairo_font_options_get_hint_metrics (const cairo_font_options_t *options)
return options->hint_metrics;
}
+
void
cairo_font_options_set_font_color (cairo_font_options_t *options,
- cairo_font_color_t font_color)
+ cairo_font_color_t font_color)
{
- if (cairo_font_options_status (options))
+ if (cairo_font_options_status (options))
return;
- options->color = font_color;
+ options->color = font_color;
}
slim_hidden_def (cairo_font_options_set_font_color);
cairo_font_color_t
cairo_font_options_get_font_color (const cairo_font_options_t *options)
{
- if (cairo_font_options_status ((cairo_font_options_t *) options))
+ if (cairo_font_options_status ((cairo_font_options_t *) options))
return CAIRO_FONT_COLOR_DEFAULT;
- return options->color;
+ return options->color;
}
diff --git a/src/cairo-fontconfig-private.h b/src/cairo-fontconfig-private.h
index ea873abe7..ea873abe7 100755..100644
--- a/src/cairo-fontconfig-private.h
+++ b/src/cairo-fontconfig-private.h
diff --git a/src/cairo-freed-pool-private.h b/src/cairo-freed-pool-private.h
index 0ec6de3d1..0ec6de3d1 100755..100644
--- a/src/cairo-freed-pool-private.h
+++ b/src/cairo-freed-pool-private.h
diff --git a/src/cairo-freed-pool.c b/src/cairo-freed-pool.c
index cfdc8e96b..cfdc8e96b 100755..100644
--- a/src/cairo-freed-pool.c
+++ b/src/cairo-freed-pool.c
diff --git a/src/cairo-freelist-private.h b/src/cairo-freelist-private.h
index 8fe6516f3..8fe6516f3 100755..100644
--- a/src/cairo-freelist-private.h
+++ b/src/cairo-freelist-private.h
diff --git a/src/cairo-freelist-type-private.h b/src/cairo-freelist-type-private.h
index 4dd056461..4dd056461 100755..100644
--- a/src/cairo-freelist-type-private.h
+++ b/src/cairo-freelist-type-private.h
diff --git a/src/cairo-freelist.c b/src/cairo-freelist.c
index d596eab81..d596eab81 100755..100644
--- a/src/cairo-freelist.c
+++ b/src/cairo-freelist.c
diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c
index 43df78e0b..868ccc2c8 100755..100644
--- a/src/cairo-ft-font.c
+++ b/src/cairo-ft-font.c
@@ -45,6 +45,7 @@
#include "cairo-image-surface-private.h"
#include "cairo-ft-private.h"
#include "cairo-pattern-private.h"
+#include "cairo-pixman-private.h"
#include <float.h>
@@ -54,11 +55,11 @@
#include FT_FREETYPE_H
#include FT_OUTLINE_H
#include FT_IMAGE_H
+#include FT_BITMAP_H
#include FT_TRUETYPE_TABLES_H
#include FT_XFREE86_H
#if HAVE_FT_GLYPHSLOT_EMBOLDEN
#include FT_SYNTHESIS_H
-#define USE_FT_OUTLINE_EMBOLDEN 1
#endif
#if HAVE_FT_LIBRARY_SETLCDFILTER
@@ -587,23 +588,20 @@ _cairo_ft_unscaled_font_create_from_face (FT_Face face,
return _cairo_ft_unscaled_font_create_internal (TRUE, NULL, 0, face, out);
}
-static void
+static cairo_bool_t
_cairo_ft_unscaled_font_destroy (void *abstract_font)
{
cairo_ft_unscaled_font_t *unscaled = abstract_font;
cairo_ft_unscaled_font_map_t *font_map;
- if (unscaled == NULL)
- return;
-
font_map = _cairo_ft_unscaled_font_map_lock ();
/* All created objects must have been mapped in the font map. */
assert (font_map != NULL);
- if (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&unscaled->base.ref_count)) {
+ if (! _cairo_reference_count_dec_and_test (&unscaled->base.ref_count)) {
/* somebody recreated the font whilst we waited for the lock */
_cairo_ft_unscaled_font_map_unlock ();
- return;
+ return FALSE;
}
_cairo_hash_table_remove (font_map->hash_table,
@@ -625,6 +623,7 @@ _cairo_ft_unscaled_font_destroy (void *abstract_font)
_cairo_ft_unscaled_font_map_unlock ();
_cairo_ft_unscaled_font_fini (unscaled);
+ return TRUE;
}
static cairo_bool_t
@@ -740,19 +739,26 @@ _compute_transform (cairo_ft_font_transform_t *sf,
if (unscaled && (unscaled->face->face_flags & FT_FACE_FLAG_SCALABLE) == 0) {
double min_distance = DBL_MAX;
+ cairo_bool_t magnify = TRUE;
int i;
- int best_i = 0;
double best_x_size = 0;
double best_y_size = 0;
for (i = 0; i < unscaled->face->num_fixed_sizes; i++) {
- double x_size = unscaled->face->available_sizes[i].y_ppem / 64.;
+ double x_size = unscaled->face->available_sizes[i].x_ppem / 64.;
double y_size = unscaled->face->available_sizes[i].y_ppem / 64.;
- double distance = fabs (y_size - y_scale);
+ double distance = y_size - y_scale;
+
+ /*
+ * distance is positive if current strike is larger than desired
+ * size, and negative if smaller.
+ *
+ * We like to prefer down-scaling to upscaling.
+ */
- if (distance <= min_distance) {
- min_distance = distance;
- best_i = i;
+ if ((magnify && distance >= 0) || fabs (distance) <= min_distance) {
+ magnify = distance < 0;
+ min_distance = fabs (distance);
best_x_size = x_size;
best_y_size = y_size;
}
@@ -1114,15 +1120,17 @@ _fill_xrender_bitmap(FT_Bitmap *target,
*/
static cairo_status_t
_get_bitmap_surface (FT_Bitmap *bitmap,
+ FT_Library library,
cairo_bool_t own_buffer,
cairo_font_options_t *font_options,
cairo_image_surface_t **surface)
{
- int width, height, stride;
+ unsigned int width, height;
unsigned char *data;
int format = CAIRO_FORMAT_A8;
+ int stride;
cairo_image_surface_t *image;
- cairo_bool_t component_alpha = TRUE;
+ cairo_bool_t component_alpha = TRUE;
width = bitmap->width;
height = bitmap->rows;
@@ -1179,8 +1187,18 @@ _get_bitmap_surface (FT_Bitmap *bitmap,
case FT_PIXEL_MODE_LCD:
case FT_PIXEL_MODE_LCD_V:
case FT_PIXEL_MODE_GRAY:
- if (font_options->antialias != CAIRO_ANTIALIAS_SUBPIXEL) {
+ if (font_options->antialias != CAIRO_ANTIALIAS_SUBPIXEL ||
+ bitmap->pixel_mode == FT_PIXEL_MODE_GRAY)
+ {
stride = bitmap->pitch;
+
+ /* We don't support stride not multiple of 4. */
+ if (stride & 3)
+ {
+ assert (!own_buffer);
+ goto convert;
+ }
+
if (own_buffer) {
data = bitmap->buffer;
} else {
@@ -1193,49 +1211,91 @@ _get_bitmap_surface (FT_Bitmap *bitmap,
format = CAIRO_FORMAT_A8;
} else {
- /* color glyph is rendered as bitmap, does not come from
- * _fill_xrender_bitmap */
- if (! own_buffer) {
- stride = bitmap->pitch;
- data = _cairo_malloc_ab (height, stride);
- if (!data)
- return _cairo_error (CAIRO_STATUS_NO_MEMORY);
-
- memcpy (data, bitmap->buffer, stride * height);
- format = CAIRO_FORMAT_A8;
- } else {
- /* if we get there, the data from the source bitmap
- * really comes from _fill_xrender_bitmap, and is
- * made of 32-bit ARGB or ABGR values */
- assert (own_buffer != 0);
- assert (bitmap->pixel_mode != FT_PIXEL_MODE_GRAY);
-
- data = bitmap->buffer;
- stride = bitmap->pitch;
- format = CAIRO_FORMAT_ARGB32;
- }
- }
- break;
- // color font
- /*
- case FT_PIXEL_MODE_BGRA:
+ /* color glyph is rendered as bitmap, does not come from
+ * _fill_xrender_bitmap */
+ if (! own_buffer) {
stride = bitmap->pitch;
- if (own_buffer) {
- data = bitmap->buffer;
- } else {
- data = _cairo_malloc_ab (height, stride);
- if (!data)
- return _cairo_error (CAIRO_STATUS_NO_MEMORY);
-
- memcpy (data, bitmap->buffer, stride * height);
- }
+ data = _cairo_malloc_ab (height, stride);
+ if (!data)
+ return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
+ memcpy (data, bitmap->buffer, stride * height);
+ format = CAIRO_FORMAT_A8;
+ } else {
+ /* if we get there, the data from the source bitmap
+ * really comes from _fill_xrender_bitmap, and is
+ * made of 32-bit ARGB or ABGR values */
+ assert (own_buffer != 0);
+ assert (bitmap->pixel_mode != FT_PIXEL_MODE_GRAY);
+ data = bitmap->buffer;
+ stride = bitmap->pitch;
format = CAIRO_FORMAT_ARGB32;
- component_alpha = FALSE;
+ }
+ }
break;
- */
+ // color font
+ #if 0 // TODO(suyambu.rm) Build error for Tizen 3.0
+ case FT_PIXEL_MODE_BGRA:
+ stride = bitmap->pitch;
+
+ if (own_buffer) {
+ data = bitmap->buffer;
+ } else {
+ data = _cairo_malloc_ab (height, stride);
+ if (!data)
+ return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
+ memcpy (data, bitmap->buffer, stride * height);
+ }
+
+ format = CAIRO_FORMAT_ARGB32;
+ component_alpha = FALSE;
+ break;
+ #endif
case FT_PIXEL_MODE_GRAY2:
case FT_PIXEL_MODE_GRAY4:
+ convert:
+ if (!own_buffer && library)
+ {
+ /* This is pretty much the only case that we can get in here. */
+ /* Convert to 8bit grayscale. */
+
+ FT_Bitmap tmp;
+ FT_Int align;
+
+ format = CAIRO_FORMAT_A8;
+
+ align = cairo_format_stride_for_width (format, bitmap->width);
+
+ FT_Bitmap_New( &tmp );
+
+ if (FT_Bitmap_Convert( library, bitmap, &tmp, align ))
+ return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
+ FT_Bitmap_Done( library, bitmap );
+ *bitmap = tmp;
+
+ stride = bitmap->pitch;
+ data = _cairo_malloc_ab (height, stride);
+ if (!data)
+ return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
+ if (bitmap->num_grays != 256)
+ {
+ unsigned int x, y;
+ unsigned int mul = 255 / (bitmap->num_grays - 1);
+ FT_Byte *p = bitmap->buffer;
+ for (y = 0; y < height; y++) {
+ for (x = 0; x < width; x++)
+ p[x] *= mul;
+ p += bitmap->pitch;
+ }
+ }
+
+ memcpy (data, bitmap->buffer, stride * height);
+ break;
+ }
/* These could be triggered by very rare types of TrueType fonts */
default:
if (own_buffer)
@@ -1429,7 +1489,7 @@ _render_glyph_outline (FT_Face face,
/* Note:
* _get_bitmap_surface will free bitmap.buffer if there is an error
*/
- status = _get_bitmap_surface (&bitmap, TRUE, font_options, surface);
+ status = _get_bitmap_surface (&bitmap, NULL, TRUE, font_options, surface);
if (unlikely (status))
return status;
@@ -1470,6 +1530,7 @@ _render_glyph_bitmap (FT_Face face,
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
status = _get_bitmap_surface (&glyphslot->bitmap,
+ glyphslot->library,
FALSE, font_options,
surface);
if (unlikely (status))
@@ -1511,7 +1572,7 @@ _transform_glyph_bitmap (cairo_matrix_t * shape,
* the "shape" portion of the font transform
*/
original_to_transformed = *shape;
-
+
cairo_surface_get_device_offset (&(*surface)->base, &origin_x, &origin_y);
orig_width = (*surface)->width;
orig_height = (*surface)->height;
@@ -2193,10 +2254,23 @@ _cairo_ft_scaled_glyph_init (void *abstract_font,
vertical_layout = TRUE;
}
- #ifdef FT_LOAD_COLOR
- /*Color-glyph support */
- load_flags |= FT_LOAD_COLOR;
- #endif
+#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; */
+
+ /* Color-glyph support */
+ if (scaled_font->ft_options.base.color == CAIRO_FONT_COLOR_DEFAULT)
+ load_flags |= FT_LOAD_COLOR;
+#endif
error = FT_Load_Glyph (face,
_cairo_scaled_glyph_index(scaled_glyph),
@@ -2215,22 +2289,7 @@ _cairo_ft_scaled_glyph_init (void *abstract_font,
*/
#if HAVE_FT_GLYPHSLOT_EMBOLDEN
if (scaled_font->ft_options.synth_flags & CAIRO_FT_SYNTHESIZE_BOLD)
-#if USE_FT_OUTLINE_EMBOLDEN
- {
- /*UX team request us to use 64 instead 34*/
- FT_Pos xstr;
- if(face && face->size)
- xstr = FT_MulFix(face->units_per_EM, face->size->metrics.y_scale) / 64;
- else
- goto FAIL;
- if(face->glyph)
- FT_Outline_Embolden(&face->glyph->outline, xstr);
- else
- goto FAIL;
- }
-#else
FT_GlyphSlot_Embolden (glyph);
-#endif // USE_FT_OUTLINE_EMBOLDEN
#endif
#if HAVE_FT_GLYPHSLOT_OBLIQUE
@@ -2384,22 +2443,7 @@ _cairo_ft_scaled_glyph_init (void *abstract_font,
}
#if HAVE_FT_GLYPHSLOT_EMBOLDEN
if (scaled_font->ft_options.synth_flags & CAIRO_FT_SYNTHESIZE_BOLD)
-#if USE_FT_OUTLINE_EMBOLDEN
- {
- /*UX team request us to use 64 instead 34*/
- FT_Pos xstr;
- if(face && face->size)
- xstr = FT_MulFix(face->units_per_EM, face->size->metrics.y_scale) / 64;
- else
- goto FAIL;
- if(face->glyph)
- FT_Outline_Embolden(&face->glyph->outline, xstr);
- else
- goto FAIL;
- }
-#else
- FT_GlyphSlot_Embolden (glyph);
-#endif // USE_FT_OUTLINE_EMBOLDEN
+ FT_GlyphSlot_Embolden (glyph);
#endif
#if HAVE_FT_GLYPHSLOT_OBLIQUE
if (scaled_font->ft_options.synth_flags & CAIRO_FT_SYNTHESIZE_OBLIQUE)
@@ -2752,7 +2796,7 @@ _cairo_ft_font_face_create_for_toy (cairo_toy_font_face_t *toy_face,
}
#endif
-static void
+static cairo_bool_t
_cairo_ft_font_face_destroy (void *abstract_face)
{
cairo_ft_font_face_t *font_face = abstract_face;
@@ -2778,12 +2822,10 @@ _cairo_ft_font_face_destroy (void *abstract_face)
font_face->unscaled->faces == font_face &&
CAIRO_REFERENCE_COUNT_GET_VALUE (&font_face->unscaled->base.ref_count) > 1)
{
- cairo_font_face_reference (&font_face->base);
-
_cairo_unscaled_font_destroy (&font_face->unscaled->base);
font_face->unscaled = NULL;
- return;
+ return FALSE;
}
if (font_face->unscaled) {
@@ -2815,6 +2857,8 @@ _cairo_ft_font_face_destroy (void *abstract_face)
cairo_font_face_destroy (font_face->resolved_font_face);
}
#endif
+
+ return TRUE;
}
static cairo_font_face_t *
diff --git a/src/cairo-ft-private.h b/src/cairo-ft-private.h
index 392151866..0dc811472 100755..100644
--- a/src/cairo-ft-private.h
+++ b/src/cairo-ft-private.h
@@ -37,8 +37,8 @@
#ifndef CAIRO_FT_PRIVATE_H
#define CAIRO_FT_PRIVATE_H
-#include "cairo-ft.h"
#include "cairoint.h"
+#include "cairo-ft.h"
#if CAIRO_HAS_FT_FONT
diff --git a/src/cairo-ft.h b/src/cairo-ft.h
index 29c43c965..29c43c965 100755..100644
--- a/src/cairo-ft.h
+++ b/src/cairo-ft.h
diff --git a/src/cairo-gl-composite.c b/src/cairo-gl-composite.c
index c9f7782d1..57d7ddf31 100755..100644
--- a/src/cairo-gl-composite.c
+++ b/src/cairo-gl-composite.c
@@ -76,7 +76,7 @@ _cairo_gl_composite_set_source_operand (cairo_gl_composite_t *setup,
_cairo_gl_operand_copy (&setup->src, source);
if (source->type == CAIRO_GL_OPERAND_TEXTURE ||
source->type == CAIRO_GL_OPERAND_GAUSSIAN)
- status = _cairo_gl_surface_resolve_multisampling (source->texture.surface);
+ status = _cairo_gl_surface_resolve_multisampling (source->texture.surface);
}
void
@@ -96,7 +96,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_INT_STATUS_SUCCESS;
return _cairo_gl_operand_init (&setup->mask, pattern, setup->dst,
sample, extents, use_texgen, FALSE);
@@ -112,7 +112,7 @@ _cairo_gl_composite_set_mask_operand (cairo_gl_composite_t *setup,
_cairo_gl_operand_copy (&setup->mask, mask);
if (mask->type == CAIRO_GL_OPERAND_TEXTURE ||
mask->type == CAIRO_GL_OPERAND_GAUSSIAN)
- status = _cairo_gl_surface_resolve_multisampling (mask->texture.surface);
+ status = _cairo_gl_surface_resolve_multisampling (mask->texture.surface);
}
}
@@ -146,7 +146,7 @@ static void
_cairo_gl_composite_bind_to_shader (cairo_gl_context_t *ctx,
cairo_gl_composite_t *setup)
{
- _cairo_gl_shader_bind_matrix4f(ctx, CAIRO_GL_UNIFORM_PROJECTION_MATRIX,
+ _cairo_gl_shader_bind_matrix4f(ctx, ctx->current_shader->mvp_location,
ctx->modelviewprojection_matrix);
_cairo_gl_operand_bind_to_shader (ctx, &setup->src, CAIRO_GL_TEX_SOURCE);
_cairo_gl_operand_bind_to_shader (ctx, &setup->mask, CAIRO_GL_TEX_MASK);
@@ -259,7 +259,7 @@ _cairo_gl_context_setup_operand (cairo_gl_context_t *ctx,
if (operand->constant.encode_as_attribute) {
dispatch->VertexAttribPointer (CAIRO_GL_COLOR_ATTRIB_INDEX, 4,
GL_FLOAT, GL_FALSE, ctx->vertex_size,
- ctx->vb + vertex_offset);
+ ctx->vbo ? (GLvoid *)vertex_offset : (GLvoid *)(ctx->vb + vertex_offset));
dispatch->EnableVertexAttribArray (CAIRO_GL_COLOR_ATTRIB_INDEX);
}
break;
@@ -278,7 +278,7 @@ _cairo_gl_context_setup_operand (cairo_gl_context_t *ctx,
if (! operand->texture.texgen) {
dispatch->VertexAttribPointer (CAIRO_GL_TEXCOORD0_ATTRIB_INDEX + tex_unit, 2,
GL_FLOAT, GL_FALSE, ctx->vertex_size,
- ctx->vb + offset);
+ ctx->vbo ? (GLvoid *)offset : (GLvoid *)(ctx->vb + offset));
dispatch->EnableVertexAttribArray (CAIRO_GL_TEXCOORD0_ATTRIB_INDEX + tex_unit);
offset += 2 * sizeof (GLfloat);
}
@@ -287,12 +287,12 @@ _cairo_gl_context_setup_operand (cairo_gl_context_t *ctx,
dispatch->VertexAttribPointer (CAIRO_GL_START_COORD0_ATTRIB_INDEX + tex_unit,
2, GL_FLOAT, GL_FALSE,
ctx->vertex_size,
- ctx->vb + offset);
+ ctx->vbo ? (GLvoid *)offset : (GLvoid *)(ctx->vb + offset));
dispatch->EnableVertexAttribArray (CAIRO_GL_START_COORD0_ATTRIB_INDEX + tex_unit);
dispatch->VertexAttribPointer (CAIRO_GL_STOP_COORD0_ATTRIB_INDEX + tex_unit,
2, GL_FLOAT, GL_FALSE,
ctx->vertex_size,
- ctx->vb + offset + 2 * sizeof (float));
+ ctx->vbo ? (GLvoid *)(offset + 2 * sizeof (float)) : (GLvoid *)(ctx->vb + offset + 2 * sizeof (float)));
dispatch->EnableVertexAttribArray (CAIRO_GL_STOP_COORD0_ATTRIB_INDEX + tex_unit);
}
break;
@@ -312,7 +312,7 @@ _cairo_gl_context_setup_operand (cairo_gl_context_t *ctx,
if (! operand->gradient.texgen) {
dispatch->VertexAttribPointer (CAIRO_GL_TEXCOORD0_ATTRIB_INDEX + tex_unit, 2,
GL_FLOAT, GL_FALSE, ctx->vertex_size,
- ctx->vb + vertex_offset);
+ ctx->vbo ? (GLvoid *)vertex_offset : (GLvoid *)(ctx->vb + vertex_offset));
dispatch->EnableVertexAttribArray (CAIRO_GL_TEXCOORD0_ATTRIB_INDEX + tex_unit);
}
break;
@@ -341,7 +341,7 @@ _cairo_gl_context_setup_spans (cairo_gl_context_t *ctx,
dispatch->VertexAttribPointer (CAIRO_GL_COLOR_ATTRIB_INDEX, 4,
GL_UNSIGNED_BYTE, GL_TRUE, vertex_size,
- ctx->vb + vertex_offset);
+ ctx->vbo ? (GLvoid *)vertex_offset : (GLvoid *)(ctx->vb + vertex_offset));
dispatch->EnableVertexAttribArray (CAIRO_GL_COLOR_ATTRIB_INDEX);
ctx->spans = TRUE;
}
@@ -617,7 +617,7 @@ _cairo_gl_composite_setup_vbo (cairo_gl_context_t *ctx,
if (_cairo_gl_context_is_flushed (ctx)) {
ctx->dispatch.VertexAttribPointer (CAIRO_GL_VERTEX_ATTRIB_INDEX, 2,
GL_FLOAT, GL_FALSE, size_per_vertex,
- ctx->vb);
+ ctx->vbo ? 0 : ctx->vb);
ctx->dispatch.EnableVertexAttribArray (CAIRO_GL_VERTEX_ATTRIB_INDEX);
}
@@ -655,17 +655,18 @@ _cairo_gl_composite_setup_painted_clipping (cairo_gl_composite_t *setup,
_enable_stencil_buffer (ctx);
_enable_scissor_buffer (ctx);
+
+ /* We only want to clear the part of the stencil buffer
+ * that we are about to use. It also does not hurt to
+ * scissor around the painted clip. */
_cairo_gl_scissor_to_rectangle (dst, _cairo_clip_get_extents (clip));
if (clip_is_equal)
goto activate_stencil_buffer_and_return;
- /* Clear the stencil buffer, but only the areas that we are
- * going to be drawing to. */
- if (old_clip) {
- _cairo_clip_destroy (setup->dst->clip_on_stencil_buffer);
- }
-
+ if (old_clip) {
+ _cairo_clip_destroy (setup->dst->clip_on_stencil_buffer);
+ }
setup->dst->clip_on_stencil_buffer = _cairo_clip_copy (setup->clip);
ctx->dispatch.ClearStencil (0);
@@ -783,6 +784,7 @@ _cairo_gl_set_operands_and_operator (cairo_gl_composite_t *setup,
ctx->pre_shader = NULL;
return status;
}
+
if (ctx->current_shader != shader)
_cairo_gl_composite_flush (ctx);
@@ -842,10 +844,12 @@ _cairo_gl_composite_begin (cairo_gl_composite_t *setup,
setup->dst->content_cleared = FALSE;
_cairo_gl_context_set_destination (ctx, setup->dst, setup->multisample);
+
if (ctx->states_cache.blend_enabled == FALSE) {
ctx->dispatch.Enable (GL_BLEND);
ctx->states_cache.blend_enabled = TRUE;
}
+
status = _cairo_gl_set_operands_and_operator (setup, ctx);
if (unlikely (status))
goto FAIL;
@@ -869,18 +873,24 @@ _cairo_gl_composite_draw_tristrip (cairo_gl_context_t *ctx)
cairo_array_t* indices = &ctx->tristrip_indices;
const unsigned short *indices_array = _cairo_array_index_const (indices, 0);
+ if (ctx->ibo) {
+ ctx->dispatch.BufferSubData (GL_ELEMENT_ARRAY_BUFFER, 0,
+ _cairo_array_num_elements (indices) * sizeof (unsigned short),
+ (GLvoid *) indices_array);
+ }
+
if (ctx->pre_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);
- ctx->dispatch.DrawElements (GL_TRIANGLE_STRIP, _cairo_array_num_elements (indices), GL_UNSIGNED_SHORT, indices_array);
+ ctx->dispatch.DrawElements (GL_TRIANGLE_STRIP, _cairo_array_num_elements (indices), GL_UNSIGNED_SHORT, ctx->ibo ? 0 : indices_array);
_cairo_gl_set_shader (ctx, prev_shader);
_cairo_gl_set_operator (ctx, CAIRO_OPERATOR_ADD, TRUE);
}
- ctx->dispatch.DrawElements (GL_TRIANGLE_STRIP, _cairo_array_num_elements (indices), GL_UNSIGNED_SHORT, indices_array);
+ ctx->dispatch.DrawElements (GL_TRIANGLE_STRIP, _cairo_array_num_elements (indices), GL_UNSIGNED_SHORT, ctx->ibo ? 0 :indices_array);
_cairo_array_truncate (indices, 0);
}
@@ -894,18 +904,24 @@ _cairo_gl_composite_draw_line (cairo_gl_context_t *ctx)
if (ctx->draw_mode == CAIRO_GL_LINES)
type = GL_LINES;
+ if (ctx->ibo) {
+ ctx->dispatch.BufferSubData (GL_ELEMENT_ARRAY_BUFFER, 0,
+ _cairo_array_num_elements (indices) * sizeof (unsigned short),
+ (GLvoid *) indices_array);
+ }
+
if (ctx->pre_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);
- ctx->dispatch.DrawElements (type, _cairo_array_num_elements (indices), GL_UNSIGNED_SHORT, indices_array);
+ ctx->dispatch.DrawElements (type, _cairo_array_num_elements (indices), GL_UNSIGNED_SHORT, ctx->ibo ? 0 : indices_array);
_cairo_gl_set_shader (ctx, prev_shader);
_cairo_gl_set_operator (ctx, CAIRO_OPERATOR_ADD, TRUE);
}
- ctx->dispatch.DrawElements (type, _cairo_array_num_elements (indices), GL_UNSIGNED_SHORT, indices_array);
+ ctx->dispatch.DrawElements (type, _cairo_array_num_elements (indices), GL_UNSIGNED_SHORT, ctx->ibo ? 0 : indices_array);
_cairo_array_truncate (indices, 0);
}
@@ -954,6 +970,11 @@ _cairo_gl_composite_draw_triangles_with_clip_region (cairo_gl_context_t *ctx,
static void
_cairo_gl_composite_unmap_vertex_buffer (cairo_gl_context_t *ctx)
{
+ if (ctx->vbo) {
+ ctx->dispatch.BufferSubData (GL_ARRAY_BUFFER, 0,
+ ctx->vb_offset,
+ (const GLvoid *)ctx->vb);
+ }
ctx->vb_offset = 0;
}
@@ -966,7 +987,11 @@ _cairo_gl_composite_flush (cairo_gl_context_t *ctx)
if (_cairo_gl_context_is_flushed (ctx))
return;
+ /* ensure we are binding to vbo and ibo */
+ _cairo_gl_ensure_drawbuffers (ctx);
+
count = ctx->vb_offset / ctx->vertex_size;
+
_cairo_gl_composite_unmap_vertex_buffer (ctx);
if (ctx->primitive_type == CAIRO_GL_PRIMITIVE_TYPE_TRISTRIPS) {
@@ -996,7 +1021,8 @@ _cairo_gl_composite_prepare_buffer (cairo_gl_context_t *ctx,
ctx->primitive_type = primitive_type;
}
- if (ctx->vb_offset + n_vertices * ctx->vertex_size > CAIRO_GL_VBO_SIZE)
+ assert(ctx->vbo_size > 0);
+ if (ctx->vb_offset + n_vertices * ctx->vertex_size > ctx->vbo_size)
_cairo_gl_composite_flush (ctx);
}
@@ -1141,17 +1167,17 @@ _cairo_gl_composite_emit_solid_span (cairo_gl_context_t *ctx,
v = (GLfloat *) (void *) &ctx->vb[ctx->vb_offset];
- v[15 + 20*src_use_atlas + 20*mask_use_atlas] =
+ v[15 + 20*src_use_atlas + 20*mask_use_atlas] =
v[ 6 + 8*src_use_atlas + 8*mask_use_atlas] =
v[ 0 ] = x1;
v[10 + 12*src_use_atlas + 12*mask_use_atlas] =
v[ 4 + 4*src_use_atlas + 4*mask_use_atlas] =
v[ 1 ] = y1;
v[12 + 16*src_use_atlas + 16*mask_use_atlas] =
- v[ 9 + 12*src_use_atlas + 12*mask_use_atlas] =
+ v[ 9 + 12*src_use_atlas + 12*mask_use_atlas] =
v[ 3 + 4*src_use_atlas + 4*mask_use_atlas] = x2;
- v[16 + 20*src_use_atlas + 20*mask_use_atlas] =
- v[13 + 16*src_use_atlas + 16*mask_use_atlas] =
+ v[16 + 20*src_use_atlas + 20*mask_use_atlas] =
+ v[13 + 16*src_use_atlas + 16*mask_use_atlas] =
v[ 7 + 8*src_use_atlas + 8*mask_use_atlas] = y2;
fi.bytes[0] = 0;
@@ -1159,77 +1185,77 @@ _cairo_gl_composite_emit_solid_span (cairo_gl_context_t *ctx,
fi.bytes[2] = 0;
fi.bytes[3] = alpha;
v[17 + 24*src_use_atlas + 24*mask_use_atlas] =
- v[14 + 20*src_use_atlas + 20*mask_use_atlas] =
- v[11 + 16*src_use_atlas + 16*mask_use_atlas] =
- v[ 8 + 12*src_use_atlas + 12*mask_use_atlas] =
- v[ 5 + 8*src_use_atlas + 8*mask_use_atlas] =
+ v[14 + 20*src_use_atlas + 20*mask_use_atlas] =
+ v[11 + 16*src_use_atlas + 16*mask_use_atlas] =
+ v[ 8 + 12*src_use_atlas + 12*mask_use_atlas] =
+ v[ 5 + 8*src_use_atlas + 8*mask_use_atlas] =
v[ 2 + 4*src_use_atlas + 4*mask_use_atlas ] = fi.f;
if (src_use_atlas) {
v[ 2 ] =
- v[ 5 + 4*src_use_atlas + 4*mask_use_atlas] =
- v[ 8 + 8*src_use_atlas + 8*mask_use_atlas] =
+ v[ 5 + 4*src_use_atlas + 4*mask_use_atlas] =
+ v[ 8 + 8*src_use_atlas + 8*mask_use_atlas] =
v[11 + 12*src_use_atlas + 12*mask_use_atlas] =
v[14 + 16*src_use_atlas + 16*mask_use_atlas] =
- v[17 + 20*src_use_atlas + 20*mask_use_atlas] =
+ v[17 + 20*src_use_atlas + 20*mask_use_atlas] =
ctx->operands[CAIRO_GL_TEX_SOURCE].texture.p1.x;
v[ 3 ] =
- v[ 6 + 4*src_use_atlas + 4*mask_use_atlas] =
- v[ 9 + 8*src_use_atlas + 8*mask_use_atlas] =
+ v[ 6 + 4*src_use_atlas + 4*mask_use_atlas] =
+ v[ 9 + 8*src_use_atlas + 8*mask_use_atlas] =
v[12 + 12*src_use_atlas + 12*mask_use_atlas] =
v[15 + 16*src_use_atlas + 16*mask_use_atlas] =
- v[18 + 20*src_use_atlas + 20*mask_use_atlas] =
+ v[18 + 20*src_use_atlas + 20*mask_use_atlas] =
ctx->operands[CAIRO_GL_TEX_SOURCE].texture.p1.y;
-
+
v[ 4 ] =
- v[ 7 + 4*src_use_atlas + 4*mask_use_atlas] =
- v[10 + 8*src_use_atlas + 8*mask_use_atlas] =
+ v[ 7 + 4*src_use_atlas + 4*mask_use_atlas] =
+ v[10 + 8*src_use_atlas + 8*mask_use_atlas] =
v[13 + 12*src_use_atlas + 12*mask_use_atlas] =
v[16 + 16*src_use_atlas + 16*mask_use_atlas] =
- v[19 + 20*src_use_atlas + 20*mask_use_atlas] =
+ v[19 + 20*src_use_atlas + 20*mask_use_atlas] =
ctx->operands[CAIRO_GL_TEX_SOURCE].texture.p2.x;
v[ 5 ] =
- v[ 8 + 4*src_use_atlas + 4*mask_use_atlas] =
- v[11 + 8*src_use_atlas + 8*mask_use_atlas] =
+ v[ 8 + 4*src_use_atlas + 4*mask_use_atlas] =
+ v[11 + 8*src_use_atlas + 8*mask_use_atlas] =
v[14 + 12*src_use_atlas + 12*mask_use_atlas] =
v[17 + 16*src_use_atlas + 16*mask_use_atlas] =
- v[20 + 20*src_use_atlas + 20*mask_use_atlas] =
+ v[20 + 20*src_use_atlas + 20*mask_use_atlas] =
ctx->operands[CAIRO_GL_TEX_SOURCE].texture.p2.y;
}
if (mask_use_atlas) {
v[ 2 + 4*src_use_atlas ] =
- v[ 5 + 8*src_use_atlas + 4*mask_use_atlas] =
- v[ 8 + 12*src_use_atlas + 8*mask_use_atlas] =
+ v[ 5 + 8*src_use_atlas + 4*mask_use_atlas] =
+ v[ 8 + 12*src_use_atlas + 8*mask_use_atlas] =
v[11 + 16*src_use_atlas + 12*mask_use_atlas] =
v[14 + 20*src_use_atlas + 16*mask_use_atlas] =
- v[17 + 24*src_use_atlas + 20*mask_use_atlas] =
+ v[17 + 24*src_use_atlas + 20*mask_use_atlas] =
ctx->operands[CAIRO_GL_TEX_MASK].texture.p1.x;
v[ 3 + 4*src_use_atlas ] =
- v[ 6 + 4*src_use_atlas + 4*mask_use_atlas] =
- v[ 9 + 8*src_use_atlas + 8*mask_use_atlas] =
+ v[ 6 + 4*src_use_atlas + 4*mask_use_atlas] =
+ v[ 9 + 8*src_use_atlas + 8*mask_use_atlas] =
v[12 + 12*src_use_atlas + 12*mask_use_atlas] =
v[15 + 16*src_use_atlas + 16*mask_use_atlas] =
- v[18 + 20*src_use_atlas + 20*mask_use_atlas] =
+ v[18 + 20*src_use_atlas + 20*mask_use_atlas] =
ctx->operands[CAIRO_GL_TEX_MASK].texture.p1.y;
-
+
v[ 4 + 4*src_use_atlas ] =
- v[ 7 + 4*src_use_atlas + 4*mask_use_atlas] =
- v[10 + 8*src_use_atlas + 8*mask_use_atlas] =
+ v[ 7 + 4*src_use_atlas + 4*mask_use_atlas] =
+ v[10 + 8*src_use_atlas + 8*mask_use_atlas] =
v[13 + 12*src_use_atlas + 12*mask_use_atlas] =
v[16 + 16*src_use_atlas + 16*mask_use_atlas] =
- v[19 + 20*src_use_atlas + 20*mask_use_atlas] =
+ v[19 + 20*src_use_atlas + 20*mask_use_atlas] =
ctx->operands[CAIRO_GL_TEX_MASK].texture.p2.x;
v[ 5 + 4*src_use_atlas ] =
- v[ 8 + 4*src_use_atlas + 4*mask_use_atlas] =
- v[11 + 8*src_use_atlas + 8*mask_use_atlas] =
+ v[ 8 + 4*src_use_atlas + 4*mask_use_atlas] =
+ v[11 + 8*src_use_atlas + 8*mask_use_atlas] =
v[14 + 12*src_use_atlas + 12*mask_use_atlas] =
v[17 + 16*src_use_atlas + 16*mask_use_atlas] =
- v[20 + 20*src_use_atlas + 20*mask_use_atlas] =
+ v[20 + 20*src_use_atlas + 20*mask_use_atlas] =
ctx->operands[CAIRO_GL_TEX_MASK].texture.p2.y;
}
@@ -1309,17 +1335,17 @@ _cairo_gl_composite_emit_glyph_vertex (cairo_gl_context_t *ctx,
static inline void
_cairo_gl_composite_emit_color_glyph_vertex (cairo_gl_context_t *ctx,
- GLfloat x, GLfloat y,
- GLfloat glyph_x, GLfloat glyph_y)
+ GLfloat x, GLfloat y,
+ GLfloat glyph_x, GLfloat glyph_y)
{
- GLfloat *vb = (GLfloat *) (void *) &ctx->vb[ctx->vb_offset];
+ GLfloat *vb = (GLfloat *) (void *) &ctx->vb[ctx->vb_offset];
- *vb++ = x;
- *vb++ = y;
- *vb++ = glyph_x;
- *vb++ = glyph_y;
+ *vb++ = x;
+ *vb++ = y;
+ *vb++ = glyph_x;
+ *vb++ = glyph_y;
- ctx->vb_offset += ctx->vertex_size;
+ ctx->vb_offset += ctx->vertex_size;
}
static void
@@ -1348,26 +1374,26 @@ _cairo_gl_composite_emit_glyph (cairo_gl_context_t *ctx,
static void
_cairo_gl_composite_emit_color_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)
{
- if (ctx->draw_mode != CAIRO_GL_VERTEX) {
+ if (ctx->draw_mode != CAIRO_GL_VERTEX) {
_cairo_gl_composite_flush (ctx);
ctx->draw_mode = CAIRO_GL_VERTEX;
- }
+ }
- _cairo_gl_composite_prepare_buffer (ctx, 6,
- CAIRO_GL_PRIMITIVE_TYPE_TRIANGLES);
+ _cairo_gl_composite_prepare_buffer (ctx, 6,
+ CAIRO_GL_PRIMITIVE_TYPE_TRIANGLES);
- _cairo_gl_composite_emit_color_glyph_vertex (ctx, x1, y1, glyph_x1, glyph_y1);
- _cairo_gl_composite_emit_color_glyph_vertex (ctx, x2, y1, glyph_x2, glyph_y1);
- _cairo_gl_composite_emit_color_glyph_vertex (ctx, x1, y2, glyph_x1, glyph_y2);
+ _cairo_gl_composite_emit_color_glyph_vertex (ctx, x1, y1, glyph_x1, glyph_y1);
+ _cairo_gl_composite_emit_color_glyph_vertex (ctx, x2, y1, glyph_x2, glyph_y1);
+ _cairo_gl_composite_emit_color_glyph_vertex (ctx, x1, y2, glyph_x1, glyph_y2);
- _cairo_gl_composite_emit_color_glyph_vertex (ctx, x2, y1, glyph_x2, glyph_y1);
- _cairo_gl_composite_emit_color_glyph_vertex (ctx, x2, y2, glyph_x2, glyph_y2);
- _cairo_gl_composite_emit_color_glyph_vertex (ctx, x1, y2, glyph_x1, glyph_y2);
+ _cairo_gl_composite_emit_color_glyph_vertex (ctx, x2, y1, glyph_x2, glyph_y1);
+ _cairo_gl_composite_emit_color_glyph_vertex (ctx, x2, y2, glyph_x2, glyph_y2);
+ _cairo_gl_composite_emit_color_glyph_vertex (ctx, x1, y2, glyph_x1, glyph_y2);
}
static void
@@ -1400,13 +1426,12 @@ _cairo_gl_composite_emit_solid_glyph (cairo_gl_context_t *ctx,
cairo_gl_emit_glyph_t
_cairo_gl_context_choose_emit_glyph (cairo_gl_context_t *ctx,
- const cairo_bool_t is_color_glyph)
+ const cairo_bool_t is_color_glyph)
{
-
- if ( is_color_glyph) {
+ if ( is_color_glyph) {
/* color glyph ignore all source and mask */
return _cairo_gl_composite_emit_color_glyph;
- }
+ }
switch (ctx->operands[CAIRO_GL_TEX_SOURCE].type) {
default:
diff --git a/src/cairo-gl-device.c b/src/cairo-gl-device.c
index a22ac63bb..dbb6f162f 100755..100644
--- a/src/cairo-gl-device.c
+++ b/src/cairo-gl-device.c
@@ -215,6 +215,15 @@ _gl_destroy (void *device)
cairo_region_destroy (ctx->clip_region);
free (ctx->vb);
+ if (ctx->vao) {
+ ctx->dispatch.DeleteVertexArrays (1, &ctx->vao);
+ }
+ if (ctx->vbo) {
+ ctx->dispatch.DeleteBuffers (1, &ctx->vbo);
+ }
+ if (ctx->ibo) {
+ ctx->dispatch.DeleteBuffers (1, &ctx->ibo);
+ }
ctx->destroy (ctx);
@@ -269,6 +278,11 @@ _cairo_gl_context_init (cairo_gl_context_t *ctx)
cairo_bool_t is_gles = (gl_flavor == CAIRO_GL_FLAVOR_ES2 ||
gl_flavor == CAIRO_GL_FLAVOR_ES3);
+ if (gl_version >= CAIRO_GL_VERSION_ENCODE (3, 30) &&
+ gl_flavor == CAIRO_GL_FLAVOR_DESKTOP)
+ ctx->is_gl33 = TRUE;
+ else
+ ctx->is_gl33 = FALSE;
_cairo_device_init (&ctx->base, &_cairo_gl_device_backend);
/* XXX The choice of compositor should be made automatically at runtime.
@@ -293,7 +307,8 @@ _cairo_gl_context_init (cairo_gl_context_t *ctx)
/* Check for required extensions */
if (is_desktop) {
- if (_cairo_gl_has_extension (&ctx->dispatch, "GL_ARB_texture_non_power_of_two")) {
+ if (gl_version >= CAIRO_GL_VERSION_ENCODE (3, 0) ||
+ _cairo_gl_has_extension (&ctx->dispatch, "GL_ARB_texture_non_power_of_two")) {
ctx->tex_target = GL_TEXTURE_2D;
ctx->has_npot_repeat = TRUE;
} else if (_cairo_gl_has_extension (&ctx->dispatch, "GL_ARB_texture_rectangle")) {
@@ -326,7 +341,9 @@ _cairo_gl_context_init (cairo_gl_context_t *ctx)
_cairo_gl_has_extension (&ctx->dispatch, "GL_MESA_pack_invert");
ctx->has_packed_depth_stencil =
- (is_desktop && _cairo_gl_has_extension (&ctx->dispatch, "GL_EXT_packed_depth_stencil")) ||
+ (is_desktop &&
+ (gl_version >= CAIRO_GL_VERSION_ENCODE (3, 0) ||
+ _cairo_gl_has_extension (&ctx->dispatch, "GL_EXT_packed_depth_stencil"))) ||
(is_gles && _cairo_gl_has_extension (&ctx->dispatch, "GL_OES_packed_depth_stencil"));
ctx->num_samples = 1;
@@ -336,51 +353,51 @@ _cairo_gl_context_init (cairo_gl_context_t *ctx)
if (is_desktop && ctx->has_packed_depth_stencil &&
(gl_version >= CAIRO_GL_VERSION_ENCODE (3, 0) ||
_cairo_gl_has_extension (&ctx->dispatch, "GL_ARB_framebuffer_object") ||
- (_cairo_gl_has_extension (&ctx->dispatch, "GL_EXT_framebuffer_blit") &&
- _cairo_gl_has_extension (&ctx->dispatch, "GL_EXT_framebuffer_multisample")))) {
- ctx->dispatch.GetIntegerv(GL_MAX_SAMPLES_EXT, &ctx->num_samples);
+ (_cairo_gl_has_extension (&ctx->dispatch, "GL_EXT_framebuffer_blit") &&
+ _cairo_gl_has_extension (&ctx->dispatch, "GL_EXT_framebuffer_multisample")))) {
+ ctx->dispatch.GetIntegerv(GL_MAX_SAMPLES_EXT, &ctx->num_samples);
}
#endif
#if (CAIRO_HAS_GLESV2_SURFACE || CAIRO_HAS_EVASGL_SURFACE) && GL_MAX_SAMPLES_EXT
if (is_gles && ctx->has_packed_depth_stencil &&
_cairo_gl_has_extension (&ctx->dispatch, "GL_EXT_multisampled_render_to_texture")) {
- ctx->dispatch.GetIntegerv(GL_MAX_SAMPLES_EXT, &ctx->num_samples);
- ctx->msaa_type = CAIRO_GL_EXT_MULTISAMPLE_TO_TEXTURE;
+ ctx->dispatch.GetIntegerv(GL_MAX_SAMPLES_EXT, &ctx->num_samples);
+ ctx->msaa_type = CAIRO_GL_EXT_MULTISAMPLE_TO_TEXTURE;
}
#endif
#if (CAIRO_HAS_GLESV2_SURFACE || CAIRO_HAS_EVASGL_SURFACE) && GL_MAX_SAMPLES_IMG
if (ctx->msaa_type == CAIRO_GL_NONE_MULTISAMPLE_TO_TEXTURE &&
- is_gles &&
- ctx->has_packed_depth_stencil &&
+ is_gles &&
+ ctx->has_packed_depth_stencil &&
_cairo_gl_has_extension (&ctx->dispatch, "GL_IMG_multisampled_render_to_texture")) {
- ctx->dispatch.GetIntegerv(GL_MAX_SAMPLES_IMG, &ctx->num_samples);
- ctx->msaa_type = CAIRO_GL_IMG_MULTISAMPLE_TO_TEXTURE;
+ ctx->dispatch.GetIntegerv(GL_MAX_SAMPLES_IMG, &ctx->num_samples);
+ ctx->msaa_type = CAIRO_GL_IMG_MULTISAMPLE_TO_TEXTURE;
}
#endif
#if (CAIRO_HAS_GLESV2_SURFACE || CAIRO_HAS_EVASGL_SURFACE) && GL_MAX_SAMPLES_ANGLE
if (ctx->msaa_type == CAIRO_GL_NONE_MULTISAMPLE_TO_TEXTURE &&
- is_gles &&
- ctx->has_packed_depth_stencil &&
+ is_gles &&
+ ctx->has_packed_depth_stencil &&
_cairo_gl_has_extension (&ctx->dispatch, "GL_ANGLE_framebuffer_blit") &&
- _cairo_gl_has_extension (&ctx->dispatch, "GL_ANGLE_framebuffer_multisample")) {
- ctx->dispatch.GetIntegerv(GL_MAX_SAMPLES_ANGLE, &ctx->num_samples);
+ _cairo_gl_has_extension (&ctx->dispatch, "GL_ANGLE_framebuffer_multisample")) {
+ ctx->dispatch.GetIntegerv(GL_MAX_SAMPLES_ANGLE, &ctx->num_samples);
ctx->has_angle_multisampling = TRUE;
}
#endif
#if CAIRO_HAS_GLESV3_SURFACE || CAIRO_HAS_EVASGL_SURFACE
if (ctx->msaa_type == CAIRO_GL_NONE_MULTISAMPLE_TO_TEXTURE &&
- is_gles && ctx->has_packed_depth_stencil) {
- ctx->dispatch.GetIntegerv(GL_MAX_SAMPLES, &ctx->num_samples);
- /* this is work around for evasgl. At this moment, if
- we still get samples == 1, it means gles2 does not have any
+ is_gles && ctx->has_packed_depth_stencil) {
+ ctx->dispatch.GetIntegerv(GL_MAX_SAMPLES, &ctx->num_samples);
+ /* this is work around for evasgl. At this moment, if
+ we still get samples == 1, it means gles2 does not have any
support for extensions we have supported
- */
- if (gl_flavor == CAIRO_GL_FLAVOR_ES2)
- ctx->num_samples = 1;
+ */
+ if (gl_flavor == CAIRO_GL_FLAVOR_ES2)
+ ctx->num_samples = 1;
}
#endif
@@ -410,18 +427,45 @@ _cairo_gl_context_init (cairo_gl_context_t *ctx)
if (unlikely (status))
return status;
- ctx->vb = malloc (CAIRO_GL_VBO_SIZE);
+ ctx->vbo_size = _cairo_gl_get_vbo_size();
+
+ if (ctx->gl_flavor == CAIRO_GL_FLAVOR_DESKTOP &&
+ gl_version > CAIRO_GL_VERSION_ENCODE (3, 0)) {
+ ctx->dispatch.GenVertexArrays (1, &ctx->vao);
+ ctx->dispatch.BindVertexArray (ctx->vao);
+
+ ctx->dispatch.GenBuffers (1, &ctx->vbo);
+ ctx->dispatch.BindBuffer (GL_ARRAY_BUFFER, ctx->vbo);
+ ctx->dispatch.BufferData (GL_ARRAY_BUFFER, ctx->vbo_size,
+ NULL, GL_DYNAMIC_DRAW);
+
+ ctx->dispatch.GenBuffers (1, &ctx->ibo);
+ ctx->dispatch.BindBuffer (GL_ELEMENT_ARRAY_BUFFER, ctx->ibo);
+ ctx->dispatch.BufferData (GL_ELEMENT_ARRAY_BUFFER,
+ ctx->vbo_size * 2,
+ NULL, GL_DYNAMIC_DRAW);
+ ctx->states_cache.bound_vao = ctx->vao;
+ ctx->states_cache.bound_vbo = ctx->vbo;
+ ctx->states_cache.bound_ibo = ctx->ibo;
+ } else {
+ ctx->vbo = 0;
+ ctx->vao = 0;
+ ctx->ibo = 0;
+ }
+
+ ctx->vb = malloc (ctx->vbo_size);
+
if (unlikely (ctx->vb == NULL)) {
- _cairo_cache_fini (&ctx->gradients);
- return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ _cairo_cache_fini (&ctx->gradients);
+ ctx->dispatch.DeleteVertexArrays (1, &ctx->vao);
+ ctx->dispatch.DeleteBuffers (1, &ctx->vbo);
+ ctx->dispatch.DeleteBuffers (1, &ctx->ibo);
+ return _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
ctx->primitive_type = CAIRO_GL_PRIMITIVE_TYPE_TRIANGLES;
_cairo_array_init (&ctx->tristrip_indices, sizeof (unsigned short));
- /* PBO for any sort of texture upload */
- dispatch->GenBuffers (1, &ctx->texture_load_pbo);
-
ctx->max_framebuffer_size = 0;
ctx->dispatch.GetIntegerv (GL_MAX_RENDERBUFFER_SIZE, &ctx->max_framebuffer_size);
ctx->max_texture_size = 0;
@@ -655,7 +699,9 @@ _cairo_gl_ensure_multisampling (cairo_gl_context_t *ctx,
ctx->dispatch.ClearColor (0, 0, 0, 0);
// reset cached clear colors
memset (&ctx->states_cache.clear_red, 0, sizeof (GLclampf) * 4);
+
ctx->dispatch.Clear (GL_COLOR_BUFFER_BIT);
+
}
static cairo_bool_t
@@ -666,7 +712,7 @@ _cairo_gl_ensure_msaa_depth_stencil_buffer (cairo_gl_context_t *ctx,
if (surface->msaa_depth_stencil)
return TRUE;
- _cairo_gl_ensure_multisampling (ctx, surface);
+ //_cairo_gl_ensure_framebuffer (ctx, surface);
dispatch->GenRenderbuffers (1, &surface->msaa_depth_stencil);
dispatch->BindRenderbuffer (GL_RENDERBUFFER,
@@ -805,8 +851,6 @@ bind_multisample_framebuffer (cairo_gl_context_t *ctx,
GLbitfield mask;
if (ctx->gl_flavor == CAIRO_GL_FLAVOR_DESKTOP) {
- stencil_test_enabled = ctx->states_cache.stencil_test_enabled;
- scissor_test_enabled = ctx->states_cache.scissor_test_enabled;
has_stencil_cache = surface->clip_on_stencil_buffer ? TRUE : FALSE;
mask = GL_COLOR_BUFFER_BIT;
@@ -832,34 +876,37 @@ bind_multisample_framebuffer (cairo_gl_context_t *ctx,
#if CAIRO_HAS_GL_SURFACE || CAIRO_HAS_EVASGL_SURFACE
/* we must disable scissor and stencil test */
if (ctx->gl_flavor == CAIRO_GL_FLAVOR_DESKTOP) {
- _disable_stencil_buffer (ctx);
- _disable_scissor_buffer (ctx);
+ stencil_test_enabled = ctx->states_cache.stencil_test_enabled;
+ scissor_test_enabled = ctx->states_cache.scissor_test_enabled;
+ _disable_stencil_buffer (ctx);
+ _disable_scissor_buffer (ctx);
ctx->dispatch.Enable (GL_MULTISAMPLE);
- if (has_stencil_cache)
- mask |= GL_STENCIL_BUFFER_BIT;
-
- /* 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
- multisampling framebuffer. */
- ctx->dispatch.BindFramebuffer (GL_DRAW_FRAMEBUFFER, surface->msaa_fb);
- ctx->dispatch.BindFramebuffer (GL_READ_FRAMEBUFFER, surface->fb);
- ctx->dispatch.BlitFramebuffer (0, 0, surface->width, surface->height,
- 0, 0, surface->width, surface->height,
- mask, GL_NEAREST);
- surface->content_synced = TRUE;
+ if (has_stencil_cache)
+ mask |= GL_STENCIL_BUFFER_BIT;
+
+ /* 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
+ multisampling framebuffer. */
+ ctx->dispatch.BindFramebuffer (GL_DRAW_FRAMEBUFFER, surface->msaa_fb);
+ ctx->dispatch.BindFramebuffer (GL_READ_FRAMEBUFFER, surface->fb);
+ ctx->dispatch.BlitFramebuffer (0, 0, surface->width, surface->height,
+ 0, 0, surface->width, surface->height,
+ mask, GL_NEAREST);
+ surface->content_synced = TRUE;
}
#endif
+
ctx->dispatch.BindFramebuffer (GL_FRAMEBUFFER, surface->msaa_fb);
#if CAIRO_HAS_GL_SURFACE || CAIRO_HAS_EVASGL_SURFACE
if (ctx->gl_flavor == CAIRO_GL_FLAVOR_DESKTOP) {
- /* re-enable stencil and scissor test */
- if (scissor_test_enabled)
- _enable_scissor_buffer (ctx);
- if (stencil_test_enabled)
- _enable_stencil_buffer (ctx);
+ /* re-enable stencil and scissor test */
+ if (stencil_test_enabled)
+ _enable_stencil_buffer (ctx);
+ if (scissor_test_enabled)
+ _enable_scissor_buffer (ctx);
}
#endif
}
@@ -869,14 +916,14 @@ bind_singlesample_framebuffer (cairo_gl_context_t *ctx,
cairo_gl_surface_t *surface)
{
cairo_bool_t has_stencil_cache = surface->clip_on_stencil_buffer ? TRUE : FALSE;
- cairo_bool_t stencil_test_enabled = ctx->states_cache.stencil_test_enabled;
- cairo_bool_t scissor_test_enabled = ctx->states_cache.scissor_test_enabled;
+ cairo_bool_t stencil_test_enabled;
+ cairo_bool_t scissor_test_enabled;
GLbitfield mask = GL_COLOR_BUFFER_BIT;
if (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES2 &&
! ctx->has_angle_multisampling)
return;
-
+
_cairo_gl_ensure_framebuffer (ctx, surface);
if (! surface->msaa_active) {
@@ -890,9 +937,11 @@ bind_singlesample_framebuffer (cairo_gl_context_t *ctx,
_cairo_gl_composite_flush (ctx);
- /* we must disable scissor and stencil test */
- _disable_stencil_buffer (ctx);
+ stencil_test_enabled = ctx->states_cache.stencil_test_enabled;
+ scissor_test_enabled = ctx->states_cache.scissor_test_enabled;
+ _disable_stencil_buffer (ctx);
_disable_scissor_buffer (ctx);
+
#if CAIRO_HAS_GL_SURFACE || CAIRO_HAS_EVASGL_FLAVOR
if (ctx->gl_flavor == CAIRO_GL_FLAVOR_DESKTOP)
ctx->dispatch.Disable (GL_MULTISAMPLE);
@@ -906,12 +955,12 @@ bind_singlesample_framebuffer (cairo_gl_context_t *ctx,
non-multisampling framebuffer. */
#if CAIRO_HAS_GLESV2_SURFACE || CAIRO_HAS_EVASGL_SURFACE
if (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES2) {
- ctx->dispatch.BindFramebuffer (GL_DRAW_FRAMEBUFFER_ANGLE, surface->fb);
- ctx->dispatch.BindFramebuffer (GL_READ_FRAMEBUFFER_ANGLE, surface->msaa_fb);
+ ctx->dispatch.BindFramebuffer (GL_DRAW_FRAMEBUFFER_ANGLE, surface->fb);
+ ctx->dispatch.BindFramebuffer (GL_READ_FRAMEBUFFER_ANGLE, surface->msaa_fb);
}
#if CAIRO_HAS_EVASGL_SURFACE
else {
- ctx->dispatch.BindFramebuffer (GL_DRAW_FRAMEBUFFER, surface->fb);
+ ctx->dispatch.BindFramebuffer (GL_DRAW_FRAMEBUFFER, surface->fb);
ctx->dispatch.BindFramebuffer (GL_READ_FRAMEBUFFER, surface->msaa_fb);
}
#endif
@@ -925,11 +974,12 @@ bind_singlesample_framebuffer (cairo_gl_context_t *ctx,
ctx->dispatch.BindFramebuffer (GL_FRAMEBUFFER, surface->fb);
surface->content_synced = TRUE;
+
/* re-enable stencil and scissor test */
- if (scissor_test_enabled)
- _enable_scissor_buffer (ctx);
if (stencil_test_enabled)
_enable_stencil_buffer (ctx);
+ if (scissor_test_enabled)
+ _enable_scissor_buffer (ctx);
}
void
@@ -1018,8 +1068,8 @@ _cairo_gl_context_set_destination (cairo_gl_context_t *ctx,
if (! _cairo_gl_surface_is_texture (surface)) {
#if CAIRO_HAS_GL_SURFACE || CAIRO_HAS_EVASGL_SURFACE
if (ctx->gl_flavor == CAIRO_GL_FLAVOR_DESKTOP &&
- ctx->dispatch.DrawBuffer &&
- ctx->dispatch.ReadBuffer) {
+ ctx->dispatch.DrawBuffer &&
+ ctx->dispatch.ReadBuffer) {
ctx->dispatch.DrawBuffer (GL_BACK_LEFT);
ctx->dispatch.ReadBuffer (GL_BACK_LEFT);
}
@@ -1046,22 +1096,11 @@ void
cairo_gl_device_set_thread_aware (cairo_device_t *device,
cairo_bool_t thread_aware)
{
- if ((! device)||(cairo_device_status(device)!= CAIRO_STATUS_SUCCESS)) {
- fprintf (stderr, "cairo_gl_device_set_thread_aware(): cairo_device is NULL or not available\n");
- _cairo_error_throw (CAIRO_STATUS_DEVICE_ERROR);
- return;
- }
if (device->backend->type != CAIRO_DEVICE_TYPE_GL) {
_cairo_error_throw (CAIRO_STATUS_DEVICE_TYPE_MISMATCH);
return;
}
- if(thread_aware == 0 || thread_aware == 1){
- ((cairo_gl_context_t *) device)->thread_aware = thread_aware;
- }
- else{
- _cairo_device_set_error (device, CAIRO_STATUS_INVALID_STATUS);
- return;
- }
+ ((cairo_gl_context_t *) device)->thread_aware = thread_aware;
}
void _cairo_gl_context_reset (cairo_gl_context_t *ctx)
@@ -1085,8 +1124,12 @@ void _cairo_gl_context_reset (cairo_gl_context_t *ctx)
ctx->states_cache.depth_mask = FALSE;
- /* FIXME: this is hack to fix mali driver*/
- ctx->dispatch.Disable (GL_DITHER);
+ /* FIXME: this is hack to fix mali driver */
+ ctx->dispatch.Disable (GL_DITHER);
+
+ ctx->current_shader = NULL;
- ctx->current_shader = NULL;
+ ctx->states_cache.bound_vbo = 0;
+ ctx->states_cache.bound_vao = 0;
+ ctx->states_cache.bound_ibo = 0;
}
diff --git a/src/cairo-gl-dispatch-private.h b/src/cairo-gl-dispatch-private.h
index 5996ebdc7..5d4144f03 100755..100644
--- a/src/cairo-gl-dispatch-private.h
+++ b/src/cairo-gl-dispatch-private.h
@@ -78,6 +78,7 @@ cairo_private cairo_gl_dispatch_entry_t dispatch_core_entries[] = {
DISPATCH_ENTRY_CORE (ClearStencil),
DISPATCH_ENTRY_CORE (ColorMask),
DISPATCH_ENTRY_CORE (DeleteTextures),
+ DISPATCH_ENTRY_CORE (DepthMask),
DISPATCH_ENTRY_CORE (Disable),
DISPATCH_ENTRY_CORE (DrawArrays),
DISPATCH_ENTRY_CORE (DrawElements),
@@ -89,6 +90,7 @@ cairo_private cairo_gl_dispatch_entry_t dispatch_core_entries[] = {
DISPATCH_ENTRY_CORE (GetFloatv),
DISPATCH_ENTRY_CORE (GetIntegerv),
DISPATCH_ENTRY_CORE (GetString),
+ DISPATCH_ENTRY_CORE (GetStringi),
DISPATCH_ENTRY_CORE (PixelStorei),
DISPATCH_ENTRY_CORE (ReadPixels),
DISPATCH_ENTRY_CORE (Scissor),
@@ -102,17 +104,21 @@ cairo_private cairo_gl_dispatch_entry_t dispatch_core_entries[] = {
DISPATCH_ENTRY_CORE (DrawBuffer),
DISPATCH_ENTRY_CORE (ReadBuffer),
#endif
- DISPATCH_ENTRY_CORE (DepthMask),
DISPATCH_ENTRY_CORE (Viewport),
DISPATCH_ENTRY_LAST
};
cairo_private cairo_gl_dispatch_entry_t dispatch_buffers_entries[] = {
DISPATCH_ENTRY_ARB (GenBuffers),
+ DISPATCH_ENTRY_ARB (DeleteBuffers),
DISPATCH_ENTRY_ARB (BindBuffer),
DISPATCH_ENTRY_ARB (BufferData),
+ DISPATCH_ENTRY_ARB (BufferSubData),
DISPATCH_ENTRY_ARB_OES (MapBuffer),
DISPATCH_ENTRY_ARB_OES (UnmapBuffer),
+ DISPATCH_ENTRY_ARB (GenVertexArrays),
+ DISPATCH_ENTRY_ARB (DeleteVertexArrays),
+ DISPATCH_ENTRY_ARB (BindVertexArray),
DISPATCH_ENTRY_LAST
};
diff --git a/src/cairo-gl-dispatch.c b/src/cairo-gl-dispatch.c
index aaa234661..c38fe8cad 100755..100644
--- a/src/cairo-gl-dispatch.c
+++ b/src/cairo-gl-dispatch.c
@@ -111,7 +111,7 @@ _cairo_gl_dispatch_init_entries (cairo_gl_dispatch_t *dispatch,
static cairo_status_t
_cairo_gl_dispatch_init_buffers (cairo_gl_dispatch_t *dispatch,
cairo_gl_get_proc_addr_func_t get_proc_addr,
- void *data,
+ void *data,
int gl_version, cairo_gl_flavor_t gl_flavor)
{
cairo_gl_dispatch_name_t dispatch_name;
diff --git a/src/cairo-gl-ext-def-private.h b/src/cairo-gl-ext-def-private.h
index a261947be..9c11a9691 100755..100644
--- a/src/cairo-gl-ext-def-private.h
+++ b/src/cairo-gl-ext-def-private.h
@@ -140,4 +140,12 @@
#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56
#endif
+#ifndef GL_NUM_EXTENSIONS
+#define GL_NUM_EXTENSIONS 0x821D
+#endif
+
+#ifndef GL_VERTEX_ARRAY_BINDING
+#define GL_VERTEX_ARRAY_BINDING 0x85B5
+#endif
+
#endif /* CAIRO_GL_EXT_DEF_PRIVATE_H */
diff --git a/src/cairo-gl-filters.c b/src/cairo-gl-filters.c
index 7ddc4a246..612e599d5 100755..100644
--- a/src/cairo-gl-filters.c
+++ b/src/cairo-gl-filters.c
@@ -165,14 +165,12 @@ gaussian_filter_stage_1 (cairo_bool_t x_axis,
if (is_opaque)
_cairo_gl_shader_bind_float (ctx_out,
- _cairo_gl_shader_uniform_for_texunit (
- CAIRO_GL_UNIFORM_ALPHA, CAIRO_GL_TEX_SOURCE),
- 1.0);
+ ctx_out->current_shader->alpha_location[CAIRO_GL_TEX_SOURCE],
+ 1.0);
else
_cairo_gl_shader_bind_float (ctx_out,
- _cairo_gl_shader_uniform_for_texunit (
- CAIRO_GL_UNIFORM_ALPHA, CAIRO_GL_TEX_SOURCE),
- 0.0);
+ ctx_out->current_shader->alpha_location[CAIRO_GL_TEX_SOURCE],
+ 0.0);
rect.x = 0;
rect.y = 0;
@@ -212,7 +210,7 @@ gaussian_filter_stage_2 (cairo_bool_t y_axis,
col = original_pattern->base.x_radius * 2 + 1;
memset (&stage_2_src->operand.texture.coef[0], 0, sizeof (float) * row);
- compute_y_coef_to_float (original_pattern->base.convolution_matrix,
+ compute_y_coef_to_float (original_pattern->base.convolution_matrix,
row, col, &stage_2_src->operand.texture.coef[2]);
stage_2_src->operand.texture.y_radius = original_pattern->base.y_radius;
stage_2_src->operand.texture.x_radius = 1;
diff --git a/src/cairo-gl-glyphs.c b/src/cairo-gl-glyphs.c
index 8e5892e6e..b28eef3bc 100755..100644
--- a/src/cairo-gl-glyphs.c
+++ b/src/cairo-gl-glyphs.c
@@ -178,8 +178,8 @@ _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_bool_t has_component_alpha,
- cairo_gl_glyph_cache_t **cache_out)
+ cairo_bool_t has_component_alpha,
+ cairo_gl_glyph_cache_t **cache_out)
{
cairo_gl_glyph_cache_t *cache;
cairo_content_t content;
@@ -189,13 +189,12 @@ cairo_gl_context_get_glyph_cache (cairo_gl_context_t *ctx,
case CAIRO_FORMAT_RGB16_565:
case CAIRO_FORMAT_ARGB32:
case CAIRO_FORMAT_RGB24:
- if (has_component_alpha) {
- cache = &ctx->glyph_cache[0];
- } else {
- cache = &ctx->glyph_cache[2];
- }
+ if (has_component_alpha) {
+ cache = &ctx->glyph_cache[0];
+ } else {
+ cache = &ctx->glyph_cache[2];
+ }
content = CAIRO_CONTENT_COLOR_ALPHA;
- break;
break;
case CAIRO_FORMAT_A8:
case CAIRO_FORMAT_A1:
@@ -275,7 +274,7 @@ render_glyphs (cairo_gl_surface_t *dst,
cairo_format_t last_format = CAIRO_FORMAT_INVALID;
cairo_gl_glyph_cache_t *cache = NULL;
cairo_gl_context_t *ctx;
- cairo_gl_emit_glyph_t emit;
+ cairo_gl_emit_glyph_t emit = NULL;
cairo_gl_composite_t setup;
cairo_int_status_t status;
int i = 0;
@@ -325,34 +324,35 @@ render_glyphs (cairo_gl_surface_t *dst,
{
continue;
}
+
if (! *has_component_alpha)
- *has_component_alpha = pixman_image_get_component_alpha (scaled_glyph->surface->pixman_image);
+ *has_component_alpha = pixman_image_get_component_alpha (scaled_glyph->surface->pixman_image);
/* color glyph has ARGB32 format and dst mask surface is ALPHA */
if (scaled_glyph->surface->format == CAIRO_FORMAT_ARGB32 &&
- dst->base.content == CAIRO_CONTENT_ALPHA &&
- *has_component_alpha == FALSE)
- return CAIRO_STATUS_SURFACE_TYPE_MISMATCH;
+ dst->base.content == CAIRO_CONTENT_ALPHA &&
+ *has_component_alpha == FALSE)
+ return CAIRO_STATUS_SURFACE_TYPE_MISMATCH;
if (scaled_glyph->surface->format != last_format) {
status = cairo_gl_context_get_glyph_cache (ctx,
scaled_glyph->surface->format,
- *has_component_alpha,
+ *has_component_alpha,
&cache);
if (unlikely (status))
goto FINISH;
last_format = scaled_glyph->surface->format;
- if (! *has_component_alpha &&
+ if (! *has_component_alpha &&
cache->surface->base.content == CAIRO_CONTENT_COLOR_ALPHA) {
/* we have color glyph */
_cairo_gl_composite_set_source_operand (&setup, &cache->surface->operand);
*is_color_glyph = TRUE;
- } else {
+ } else {
_cairo_gl_composite_set_mask_operand (&setup, &cache->surface->operand);
*is_color_glyph = FALSE;
- }
+ }
/* XXX Shoot me. */
if (dst->msaa_active)
@@ -407,6 +407,7 @@ render_glyphs (cairo_gl_surface_t *dst,
goto FINISH;
}
glyph = _cairo_gl_glyph_cache_lock (cache, scaled_glyph);
+ assert (emit);
emit (ctx,
x1, y1, x2, y2,
glyph->p1.x, glyph->p1.y,
@@ -433,7 +434,7 @@ render_glyphs_via_mask (cairo_gl_surface_t *dst,
cairo_status_t status;
cairo_bool_t has_component_alpha;
cairo_gl_context_t *ctx;
- cairo_bool_t is_color_glyph;
+ cairo_bool_t is_color_glyph;
int width = info->extents.width;
int height = info->extents.height;
@@ -505,27 +506,27 @@ render_glyphs_via_mask (cairo_gl_surface_t *dst,
clip_extents.height = info->extents.height;
clip = _cairo_clip_intersect_rectangle (clip, &clip_extents);
- if(is_color_glyph) {
- if(op == CAIRO_OPERATOR_SOURCE) {
- /* do dest_out then add*/
- status = _cairo_surface_paint (&dst->base,
- CAIRO_OPERATOR_DEST_OUT,
- &mask_pattern.base,
- clip);
- status = _cairo_surface_paint (&dst->base,
- CAIRO_OPERATOR_ADD,
- &mask_pattern.base, clip);
- } else {
- status = _cairo_surface_paint (&dst->base,op,
- &mask_pattern.base,
- clip);
- }
- }
+ if (is_color_glyph) {
+ if (op == CAIRO_OPERATOR_SOURCE) {
+ /* do dest_out then add */
+ status = _cairo_surface_paint (&dst->base,
+ CAIRO_OPERATOR_DEST_OUT,
+ &mask_pattern.base,
+ clip);
+ status = _cairo_surface_paint (&dst->base,
+ CAIRO_OPERATOR_ADD,
+ &mask_pattern.base, clip);
+ } else {
+ status = _cairo_surface_paint (&dst->base, op,
+ &mask_pattern.base,
+ clip);
+ }
+ }
else
- status = _cairo_surface_mask (&dst->base, op,
- &source_pattern.base,
- &mask_pattern.base,
- clip);
+ status = _cairo_surface_mask (&dst->base, op,
+ &source_pattern.base,
+ &mask_pattern.base,
+ clip);
_cairo_clip_destroy (clip);
@@ -567,7 +568,7 @@ _cairo_gl_composite_glyphs_with_clip (void *_dst,
{
cairo_gl_surface_t *dst = _dst;
cairo_bool_t has_component_alpha;
- cairo_bool_t is_color_glyph;
+ cairo_bool_t is_color_glyph;
TRACE ((stderr, "%s\n", __FUNCTION__));
diff --git a/src/cairo-gl-gradient-private.h b/src/cairo-gl-gradient-private.h
index 024549e5d..d66f3dc3b 100755..100644
--- a/src/cairo-gl-gradient-private.h
+++ b/src/cairo-gl-gradient-private.h
@@ -3,6 +3,7 @@
* Copyright © 2009 Eric Anholt
* Copyright © 2009 Chris Wilson
* Copyright © 2005,2010 Red Hat, Inc
+ * Copyright © 2011,2015 Samsung Research America, Inc - Silicon Valley
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
@@ -36,6 +37,7 @@
* Carl Worth <cworth@cworth.org>
* Chris Wilson <chris@chris-wilson.co.uk>
* Eric Anholt <eric@anholt.net>
+ * Henry Songt <hsong@sisa.samsung.com>
*/
#ifndef CAIRO_GL_GRADIENT_PRIVATE_H
@@ -51,21 +53,26 @@
#include "cairo-gl.h"
-#if 0
#if CAIRO_HAS_EVASGL_SURFACE
-#include <Evas_GL.h>
+ #include <Evas_GL.h>
#else
- #if CAIRO_HAS_GL_SURFACE
- #include <GL/gl.h>
- #include <GL/glext.h>
- #elif CAIRO_HAS_GLESV2_SURFACE
- #include <GLES2/gl2.h>
- #include <GLES2/gl2ext.h>
- #elif CAIRO_HAS_GLESV3_SURFACE
- #include <GLES3/gl3.h>
- #include <GLES3/gl3ext.h>
- #endif
-#endif
+ #if CAIRO_HAS_GL_SURFACE
+ #if CAIRO_HAS_CGL_FUNCTIONS
+ #include <OpenGL/gl.h>
+ #include <OpenGL/glext.h>
+ #else
+ #include <GL/gl.h>
+ #include <GL/glext.h>
+ #endif
+ #elif CAIRO_HAS_GLESV2_SURFACE
+ #include <GLES2/gl2.h>
+ #include <GLES2/gl2ext.h>
+ #elif CAIRO_HAS_GLESV3_SURFACE
+ #include <GLES3/gl3.h>
+ #include <GLES3/gl3ext.h>
+ #elif CAIRO_HAS_EVASGL_SURFACE
+ #include <Evas_GL.h>
+ #endif
#endif
#define CAIRO_GL_GRADIENT_CACHE_SIZE 4096
@@ -77,7 +84,7 @@ typedef struct _cairo_gl_gradient {
cairo_cache_entry_t cache_entry;
cairo_reference_count_t ref_count;
cairo_device_t *device; /* NB: we don't hold a reference */
- unsigned int tex;
+ GLuint tex;
unsigned int n_stops;
const cairo_gradient_stop_t *stops;
cairo_gradient_stop_t stops_embedded[1];
diff --git a/src/cairo-gl-gradient.c b/src/cairo-gl-gradient.c
index ddf869ead..2f8c725b6 100755..100644
--- a/src/cairo-gl-gradient.c
+++ b/src/cairo-gl-gradient.c
@@ -290,7 +290,7 @@ _cairo_gl_gradient_create (cairo_gl_context_t *ctx,
ctx->dispatch.TexImage2D (ctx->tex_target, 0, internal_format,
tex_width, 1, 0,
- GL_BGRA, GL_UNSIGNED_BYTE, data);
+ GL_BGRA, GL_UNSIGNED_BYTE, data);
free (data);
diff --git a/src/cairo-gl-hairline-stroke.c b/src/cairo-gl-hairline-stroke.c
index 9ff59e502..7ce75d7c7 100755..100644
--- a/src/cairo-gl-hairline-stroke.c
+++ b/src/cairo-gl-hairline-stroke.c
@@ -46,6 +46,8 @@ _add_cap (cairo_gl_hairline_closure_t *hairline,
cairo_bool_t lead_cap,
cairo_point_t *outp)
{
+ // Do we really need cap?
+/*
double dx, dy;
if (hairline->cap_style == CAIRO_LINE_CAP_BUTT)
@@ -57,7 +59,7 @@ _add_cap (cairo_gl_hairline_closure_t *hairline,
cairo_matrix_transform_distance (hairline->ctm, &dx, &dy);
outp->x += _cairo_fixed_from_double (dx);
outp->y += _cairo_fixed_from_double (dy);
-
+*/
return TRUE;
}
@@ -121,20 +123,21 @@ _cairo_gl_hairline_style_is_hairline (const cairo_stroke_style_t *style,
x = fabs (x - 1.0);
y = fabs (y - 1.0);
+ // do not consider line join
return style->line_width == 1.0 &&
- (style->line_join != CAIRO_LINE_JOIN_MITER ||
- style->miter_limit <= 10.0) &&
(x <= SCALE_TOLERANCE && y <= SCALE_TOLERANCE);
}
static cairo_status_t
_path_add_first_and_last_cap (cairo_gl_hairline_closure_t *hairline)
{
+ // Do we really need caps and join for single point line?
+/*
cairo_point_t p[2];
cairo_status_t status = CAIRO_STATUS_SUCCESS;
cairo_bool_t needs_to_cap;
- /* check last point */
+ // check last point
if (hairline->initialized) {
if (! hairline->line_last_capped) {
p[0] = hairline->line_last_point;
@@ -166,7 +169,7 @@ _path_add_first_and_last_cap (cairo_gl_hairline_closure_t *hairline)
}
}
}
-
+*/
return CAIRO_STATUS_SUCCESS;
}
diff --git a/src/cairo-gl-info.c b/src/cairo-gl-info.c
index 33dc0cc56..fffea58b1 100755..100644
--- a/src/cairo-gl-info.c
+++ b/src/cairo-gl-info.c
@@ -32,6 +32,29 @@
#include "cairoint.h"
#include "cairo-gl-private.h"
+#include <errno.h>
+int _cairo_glsl_get_version (cairo_gl_dispatch_t *dispatch)
+{
+ int major, minor;
+ const char *version = (const char *) dispatch->GetString (GL_SHADING_LANGUAGE_VERSION);
+ const char *dot = version == NULL ? NULL : strchr (version, '.');
+ const char *major_start = dot;
+
+ /* Sanity check */
+ if (dot == NULL || dot == version || *(dot + 1) == '\0') {
+ major = 0;
+ minor = 0;
+ } else {
+ /* Find the start of the major version in the string */
+ while (major_start > version && *major_start != ' ')
+ --major_start;
+ major = strtol (major_start, NULL, 10);
+ minor = strtol (dot + 1, NULL, 10);
+ }
+
+ return CAIRO_GL_VERSION_ENCODE (major, minor);
+}
+
int _cairo_gl_get_version (cairo_gl_dispatch_t *dispatch)
{
int major, minor;
@@ -78,21 +101,54 @@ _cairo_gl_get_flavor (cairo_gl_dispatch_t *dispatch)
return flavor;
}
+unsigned long
+_cairo_gl_get_vbo_size (void)
+{
+ unsigned long vbo_size;
+
+ const char *env = getenv ("CAIRO_GL_VBO_SIZE");
+ if (env == NULL) {
+ vbo_size = CAIRO_GL_VBO_SIZE_DEFAULT;
+ } else {
+ errno = 0;
+ vbo_size = strtol (env, NULL, 10);
+ assert (errno == 0);
+ assert (vbo_size > 0);
+ }
+
+ return vbo_size;
+}
+
cairo_bool_t
_cairo_gl_has_extension (cairo_gl_dispatch_t *dispatch, const char *ext)
{
- const char *extensions = (const char *) dispatch->GetString (GL_EXTENSIONS);
- size_t len = strlen (ext);
- const char *ext_ptr = extensions;
+ int version = _cairo_gl_get_version (dispatch);
+ if (version >= CAIRO_GL_VERSION_ENCODE (3, 0)) {
+ GLuint max_num_extensions;
+ int i;
+ dispatch->GetIntegerv (GL_NUM_EXTENSIONS, &max_num_extensions);
- if (unlikely (ext_ptr == NULL))
- return 0;
+ for (i = 0; i < max_num_extensions; i++) {
+ const char *extension = (const char *) dispatch->GetStringi (GL_EXTENSIONS, i);
+ if (strstr (extension, ext) == 0)
+ return TRUE;
+ }
+ return FALSE;
+ } else {
+ const char *extensions = (const char *) dispatch->GetString (GL_EXTENSIONS);
+ size_t len = strlen (ext);
+ const char *ext_ptr = extensions;
+
- while ((ext_ptr = strstr (ext_ptr, ext)) != NULL) {
- if (ext_ptr[len] == ' ' || ext_ptr[len] == '\0')
- break;
- ext_ptr += len;
- }
+ if (unlikely (ext_ptr == NULL))
+ return 0;
+
+ while ((ext_ptr = strstr (ext_ptr, ext)) != NULL) {
+ if (ext_ptr[len] == ' ' || ext_ptr[len] == '\0')
+ break;
+ ext_ptr += len;
+ }
- return (ext_ptr != NULL);
+ return (ext_ptr != NULL);
+ }
}
diff --git a/src/cairo-gl-msaa-compositor.c b/src/cairo-gl-msaa-compositor.c
index 7ce5c7a4b..99d8cc01a 100755..100644
--- a/src/cairo-gl-msaa-compositor.c
+++ b/src/cairo-gl-msaa-compositor.c
@@ -47,6 +47,7 @@
#include "cairo-gl-private.h"
#include "cairo-path-private.h"
#include "cairo-traps-private.h"
+#include "cairo-convex-fill-private.h"
static cairo_bool_t
can_use_msaa_compositor (cairo_gl_surface_t *surface,
@@ -151,8 +152,8 @@ _draw_traps (cairo_gl_context_t *ctx,
static cairo_int_status_t
_draw_int_rect (cairo_gl_context_t *ctx,
- cairo_gl_composite_t *setup,
- cairo_rectangle_int_t *rect)
+ cairo_gl_composite_t *setup,
+ cairo_rectangle_int_t *rect)
{
int quad[8];
@@ -536,10 +537,12 @@ _cairo_gl_msaa_compositor_mask_source_operator (const cairo_compositor_t *compos
status = _draw_int_rect (ctx, &setup, &composite->bounded);
else
status = _draw_traps (ctx, &setup, &traps);
+ if (unlikely (status))
+ goto finish;
/* Now draw the second pass. */
status = _cairo_gl_composite_set_operator (&setup, CAIRO_OPERATOR_ADD,
- FALSE /* assume_component_alpha */);
+ FALSE /* assume_component_alpha */);
if (unlikely (status))
goto finish;
status = _cairo_gl_composite_set_source (&setup,
@@ -716,7 +719,7 @@ _cairo_gl_msaa_compositor_mask (const cairo_compositor_t *compositor,
if (clip) {
cairo_clip_t *clip_copy = _cairo_clip_copy (clip);
-
+
clip_copy = _cairo_clip_intersect_rectangle (clip_copy, &rect);
status = _cairo_gl_msaa_compositor_draw_clip (ctx, &setup,
clip_copy);
@@ -769,6 +772,59 @@ _stroke_shaper_add_triangle_fan (void *closure,
}
static cairo_status_t
+_fill_add_triangle_fan (void *closure,
+ const cairo_point_t *points,
+ int npoints)
+{
+ cairo_status_t status = CAIRO_STATUS_SUCCESS;
+ int n = npoints - 1, idx = 1;
+ cairo_bool_t done = FALSE;
+ struct _tristrip_composite_info *info = closure;
+ cairo_point_t triangle[3], quad[4];
+ cairo_point_t midp = points[0];
+
+ if (n <= 1)
+ return status;
+ else if (n <= 2) {
+ triangle[0] = midp;
+ triangle[1] = points[idx];
+ triangle[2] = points[++idx];
+ return _cairo_gl_composite_emit_triangle_as_tristrip (info->ctx, &info->setup, triangle);
+ }
+ else {
+ quad[0] = midp;
+ quad[1] = points[idx];
+ quad[2] = points[++idx];
+ quad[3] = points[++idx];
+ n -= 3;
+ status = _cairo_gl_composite_emit_quad_as_tristrip (info->ctx, &info->setup, quad);
+ }
+
+ while (! done) {
+ if (n == 0)
+ break;
+ if (n == 1) {
+ triangle[0] = midp;
+ triangle[1] = points[idx];
+ triangle[2] = points[++idx];
+ status = _cairo_gl_composite_emit_triangle_as_tristrip (info->ctx, &info->setup, triangle);
+ break;
+ }
+ else {
+ quad[0] = midp;
+ quad[1] = points[idx];
+ quad[2] = points[++idx];
+ quad[3] = points[++idx];
+ n -= 2;
+ status = _cairo_gl_composite_emit_quad_as_tristrip (info->ctx, &info->setup, quad);
+ if (unlikely (status))
+ break;
+ }
+ }
+ return status;
+}
+
+static cairo_status_t
_stroke_shaper_add_quad (void *closure,
const cairo_point_t quad[4])
{
@@ -918,9 +974,9 @@ _cairo_gl_msaa_compositor_stroke (const cairo_compositor_t *compositor,
if (stroke_extents.width != 0 &&
stroke_extents.height != 0) {
- if ((stroke_extents.width / stroke_extents.height > 10 &&
+ if ((stroke_extents.width / stroke_extents.height > 10 &&
stroke_extents.height < 10) ||
- (stroke_extents.height / stroke_extents.width > 10 &&
+ (stroke_extents.height / stroke_extents.width > 10 &&
stroke_extents.width < 10)) {
return CAIRO_INT_STATUS_UNSUPPORTED;
}
@@ -981,14 +1037,23 @@ _cairo_gl_msaa_compositor_stroke (const cairo_compositor_t *compositor,
if (_cairo_gl_hairline_style_is_hairline (style, ctm)) {
cairo_gl_hairline_closure_t closure;
+ /* prevent overlapping is very expensive, we should avoid it
+ at all cost. In case of hairline, the overlapping occurs
+ on a single pixel and is almost indistinguishable. To
+ trade-off quality vs performance, for hairline, we disable
+ overlapping
+ */
+ /*
if (! (_is_continuous_arc (path, style) ||
- _is_continuous_single_line (path, style))) {
+ _is_continuous_single_line (path, style) ||
+ path->is_convex)) {
status = _prevent_overlapping_strokes (info.ctx, &info.setup,
composite, path,
style, ctm);
if (unlikely (status))
goto finish;
}
+ */
closure.ctx = info.ctx;
@@ -1045,7 +1110,6 @@ _draw_simple_quad_path (cairo_gl_context_t *ctx,
cairo_point_t triangle[3];
cairo_int_status_t status;
const cairo_point_t *points;
-
points = cairo_path_head (path)->points;
triangle[0] = points[0];
@@ -1076,6 +1140,7 @@ _cairo_gl_msaa_compositor_fill (const cairo_compositor_t *compositor,
cairo_traps_t traps;
cairo_bool_t draw_path_with_traps;
cairo_rectangle_int_t fill_extents;
+ struct _tristrip_composite_info info;
if (! can_use_msaa_compositor (dst, antialias))
return CAIRO_INT_STATUS_UNSUPPORTED;
@@ -1084,9 +1149,9 @@ _cairo_gl_msaa_compositor_fill (const cairo_compositor_t *compositor,
_cairo_path_fixed_approximate_fill_extents (path, &fill_extents);
if (fill_extents.width != 0 && fill_extents.height != 0) {
- if ((fill_extents.width / fill_extents.height > 10 &&
+ if ((fill_extents.width / fill_extents.height > 10 &&
fill_extents.height < 10) ||
- (fill_extents.height / fill_extents.width > 10 &&
+ (fill_extents.height / fill_extents.width > 10 &&
fill_extents.width < 10)) {
return CAIRO_INT_STATUS_UNSUPPORTED;
}
@@ -1122,13 +1187,6 @@ _cairo_gl_msaa_compositor_fill (const cairo_compositor_t *compositor,
draw_path_with_traps = ! _cairo_path_fixed_is_simple_quad (path);
- if (draw_path_with_traps) {
- _cairo_traps_init (&traps);
- status = _cairo_path_fixed_fill_to_traps (path, fill_rule, tolerance, &traps);
- if (unlikely (status))
- goto cleanup_traps;
- }
-
status = _cairo_gl_composite_init (&setup,
composite->op,
dst,
@@ -1147,15 +1205,44 @@ _cairo_gl_msaa_compositor_fill (const cairo_compositor_t *compositor,
_cairo_gl_msaa_compositor_set_clip (composite, &setup);
if (antialias != CAIRO_ANTIALIAS_NONE)
_cairo_gl_composite_set_multisample (&setup);
-
+
status = _cairo_gl_composite_begin (&setup, &ctx);
if (unlikely (status))
goto cleanup_setup;
- if (! draw_path_with_traps)
+ if(path->is_convex) {
+
+ cairo_convex_fill_closure_t filler;
+ filler.tolerance = tolerance;
+ info.ctx = ctx;
+ info.setup = setup;
+ filler.closure = &info;
+ filler.midp_added = FALSE;
+ status = _cairo_path_fixed_fill_to_convex((*_fill_add_triangle_fan),
+ path,
+ _cairo_convex_fill_move_to,
+ _cairo_convex_fill_line_to,
+ _cairo_convex_fill_curve_to,
+ _cairo_convex_fill_close_path,
+ &filler);
+ if (unlikely (status))
+ goto cleanup_setup;
+
+ }
+ else if (draw_path_with_traps) {
+ _cairo_traps_init (&traps);
+ status = _cairo_path_fixed_fill_to_traps (path, fill_rule, tolerance, &traps);
+ if (unlikely (status))
+ goto cleanup_traps;
+ }
+
+ if (!path->is_convex && ! draw_path_with_traps)
status = _draw_simple_quad_path (ctx, &setup, path);
else
- status = _draw_traps (ctx, &setup, &traps);
+ {
+ if(!path->is_convex)
+ status = _draw_traps (ctx, &setup, &traps);
+ }
if (unlikely (status))
goto cleanup_setup;
@@ -1168,7 +1255,7 @@ cleanup_setup:
status = _cairo_gl_context_release (ctx, status);
cleanup_traps:
- if (draw_path_with_traps)
+ if (draw_path_with_traps && !path->is_convex)
_cairo_traps_fini (&traps);
return status;
@@ -1215,7 +1302,13 @@ _cairo_gl_msaa_compositor_glyphs (const cairo_compositor_t *compositor,
return _paint_back_unbounded_surface (compositor, composite, surface);
}
-
+/*
+ if (scaled_font->options.antialias != CAIRO_ANTIALIAS_NONE) {
+ status = _blit_texture_to_renderbuffer (dst);
+ if (unlikely (status))
+ return status;
+ }
+*/
src = _cairo_gl_pattern_to_source (&dst->base,
composite->original_source_pattern,
FALSE,
@@ -1253,6 +1346,7 @@ _cairo_gl_msaa_compositor_glyphs (const cairo_compositor_t *compositor,
dst->content_synced = FALSE;
finish:
+ if (src)
cairo_surface_destroy (src);
return status;
@@ -1264,7 +1358,6 @@ _cairo_gl_msaa_compositor_init (cairo_compositor_t *compositor,
{
compositor->delegate = delegate;
compositor->lazy_init = TRUE;
-
compositor->paint = _cairo_gl_msaa_compositor_paint;
compositor->mask = _cairo_gl_msaa_compositor_mask;
compositor->fill = _cairo_gl_msaa_compositor_fill;
diff --git a/src/cairo-gl-operand.c b/src/cairo-gl-operand.c
index 8c21e6985..2bbd99b74 100755..100644
--- a/src/cairo-gl-operand.c
+++ b/src/cairo-gl-operand.c
@@ -119,7 +119,7 @@ _cairo_gl_copy_texture (cairo_gl_surface_t *surface,
/* paint image to dst */
_cairo_pattern_init_for_surface (&pattern, &image->base);
- cairo_matrix_init_translate (&pattern.base.matrix,
+ cairo_matrix_init_translate (&pattern.base.matrix,
-dst_x + src_x, -dst_y + src_y);
rect.x = dst_x;
@@ -231,7 +231,7 @@ _cairo_gl_image_cache_replace_image (cairo_gl_image_t *image_node,
{
cairo_int_status_t status;
/* Paint image to cache. */
- status = _cairo_gl_copy_texture (dst, cache_surface,
+ status = _cairo_gl_copy_texture (dst, cache_surface,
image, image_node->node.x,
image_node->node.y,
0, 0,
@@ -256,7 +256,7 @@ _cairo_gl_image_cache_add_image (cairo_gl_context_t *ctx,
if (! image->base.device ||
(image->width >= IMAGE_CACHE_MAX_SIZE ||
- image->height >= IMAGE_CACHE_MAX_SIZE))
+ image->height >= IMAGE_CACHE_MAX_SIZE))
return CAIRO_INT_STATUS_UNSUPPORTED;
else if (! _cairo_gl_surface_is_texture (image))
return CAIRO_INT_STATUS_UNSUPPORTED;
@@ -350,7 +350,7 @@ _cairo_gl_image_cache_add_image (cairo_gl_context_t *ctx,
status = _cairo_gl_copy_texture (dst, ctx->image_cache->surface,
image, node->x, node->y,
0, 0,
- image->width, image->height,
+ image->width, image->height,
FALSE, &ctx);
if (unlikely (status))
return status;
@@ -528,7 +528,7 @@ _cairo_gl_subsurface_operand_init (cairo_gl_operand_t *operand,
operand->texture.texgen = use_texgen;
- if (blur_surface == surface &&
+ if (blur_surface == surface &&
surface->needs_to_cache &&
surface->base.device) {
status = _cairo_gl_context_acquire (dst->base.device, &ctx);
@@ -562,11 +562,10 @@ _cairo_gl_subsurface_operand_init (cairo_gl_operand_t *operand,
operand->texture.p2.x = (double) blur_extents.width / (double) blur_surface->width;
operand->texture.p2.y = (double) blur_extents.height / (double) blur_surface->height;
- operand->texture.p1.x += 0.5 / blur_surface->width;
- operand->texture.p1.y += 0.5 / blur_surface->height;
- operand->texture.p2.x -= 0.5 / blur_surface->width;
- operand->texture.p2.y -= 0.5 / blur_surface->height;
-
+ operand->texture.p1.x += 0.5 / blur_surface->width;
+ operand->texture.p1.y += 0.5 / blur_surface->height;
+ operand->texture.p2.x -= 0.5 / blur_surface->width;
+ operand->texture.p2.y -= 0.5 / blur_surface->height;
operand->texture.surface = blur_surface;
operand->texture.owns_surface = NULL;
@@ -597,19 +596,18 @@ _cairo_gl_subsurface_operand_init (cairo_gl_operand_t *operand,
operand->texture.p2.x = image_node->p2.x;
operand->texture.p2.y = image_node->p2.y;
- operand->texture.p1.x += 0.5 / ctx->image_cache->surface->width;
- operand->texture.p1.y += 0.5 / ctx->image_cache->surface->height;
- operand->texture.p2.x -= 0.5 / ctx->image_cache->surface->width;
- operand->texture.p2.y -= 0.5 / ctx->image_cache->surface->height;
-
+ operand->texture.p1.x += 0.5 / ctx->image_cache->surface->width;
+ operand->texture.p1.y += 0.5 / ctx->image_cache->surface->height;
+ operand->texture.p2.x -= 0.5 / ctx->image_cache->surface->width;
+ operand->texture.p2.y -= 0.5 / ctx->image_cache->surface->height;
cairo_matrix_multiply (&attributes->matrix,
&matrix,
&ctx->image_cache->surface->operand.texture.attributes.matrix);
}
+ cairo_surface_destroy (&blur_surface->base);
status = CAIRO_STATUS_SUCCESS;
- cairo_surface_destroy (&blur_surface->base);
if (ctx_acquired)
return _cairo_gl_context_release (ctx, status);
@@ -674,8 +672,8 @@ _cairo_gl_surface_operand_init (cairo_gl_operand_t *operand,
operand->texture.texgen = use_texgen;
- if (surface->base.device &&
- blur_surface == surface &&
+ if (surface->base.device &&
+ blur_surface == surface &&
surface->needs_to_cache) {
status = _cairo_gl_context_acquire (dst->base.device, &ctx);
if (status == CAIRO_INT_STATUS_SUCCESS) {
@@ -703,11 +701,10 @@ _cairo_gl_surface_operand_init (cairo_gl_operand_t *operand,
operand->texture.p2.x = (double) blur_extents.width / (double) blur_surface->width;
operand->texture.p2.y = (double) blur_extents.height / (double) blur_surface->height;
- operand->texture.p1.x += 0.5 / blur_surface->width;
- operand->texture.p1.y += 0.5 / blur_surface->height;
- operand->texture.p2.x -= 0.5 / blur_surface->width;
- operand->texture.p2.y -= 0.5 / blur_surface->height;
-
+ operand->texture.p1.x += 0.5 / blur_surface->width;
+ operand->texture.p1.y += 0.5 / blur_surface->height;
+ operand->texture.p2.x -= 0.5 / blur_surface->width;
+ operand->texture.p2.y -= 0.5 / blur_surface->height;
operand->texture.surface = blur_surface;
operand->texture.owns_surface = NULL;
@@ -733,11 +730,10 @@ _cairo_gl_surface_operand_init (cairo_gl_operand_t *operand,
operand->texture.p2.x = image_node->p2.x;
operand->texture.p2.y = image_node->p2.y;
- operand->texture.p1.x += 0.5 / ctx->image_cache->surface->width;
- operand->texture.p1.y += 0.5 / ctx->image_cache->surface->height;
- operand->texture.p2.x -= 0.5 / ctx->image_cache->surface->width;
- operand->texture.p2.y -= 0.5 / ctx->image_cache->surface->height;
-
+ operand->texture.p1.x += 0.5 / ctx->image_cache->surface->width;
+ operand->texture.p1.y += 0.5 / ctx->image_cache->surface->height;
+ operand->texture.p2.x -= 0.5 / ctx->image_cache->surface->width;
+ operand->texture.p2.y -= 0.5 / ctx->image_cache->surface->height;
operand->texture.surface = ctx->image_cache->surface;
operand->texture.owns_surface = NULL;
@@ -749,9 +745,9 @@ _cairo_gl_surface_operand_init (cairo_gl_operand_t *operand,
&ctx->image_cache->surface->operand.texture.attributes.matrix);
}
- cairo_surface_destroy (&blur_surface->base);
status = CAIRO_STATUS_SUCCESS;
+ cairo_surface_destroy (&blur_surface->base);
if (ctx_acquired)
return _cairo_gl_context_release (ctx, status);
@@ -825,7 +821,7 @@ _cairo_gl_pattern_texture_setup (cairo_gl_operand_t *operand,
operand->texture.attributes.matrix.x0 -= extents->x * operand->texture.attributes.matrix.xx;
operand->texture.attributes.matrix.y0 -= extents->y * operand->texture.attributes.matrix.yy;
- if (_cairo_gl_surface_is_texture (dst) &&
+ if (_cairo_gl_surface_is_texture (dst) &&
dst->width <= IMAGE_CACHE_MAX_SIZE &&
dst->height <= IMAGE_CACHE_MAX_SIZE &&
! dst->force_no_cache)
@@ -1128,7 +1124,7 @@ _cairo_gl_operand_get_gl_filter (cairo_gl_operand_t *operand)
cairo_bool_t
_cairo_gl_operand_get_use_atlas (cairo_gl_operand_t *operand)
{
- if (operand->type != CAIRO_GL_OPERAND_TEXTURE &&
+ if (operand->type != CAIRO_GL_OPERAND_TEXTURE &&
operand->type != CAIRO_GL_OPERAND_GAUSSIAN)
return FALSE;
@@ -1201,30 +1197,27 @@ _cairo_gl_operand_bind_to_shader (cairo_gl_context_t *ctx,
return;
_cairo_gl_shader_bind_vec4 (ctx,
- _cairo_gl_shader_uniform_for_texunit (
- CAIRO_GL_UNIFORM_CONSTANT, tex_unit),
- operand->constant.color[0],
- operand->constant.color[1],
- operand->constant.color[2],
- operand->constant.color[3]);
- return;
+ 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:
case CAIRO_GL_OPERAND_RADIAL_GRADIENT_EXT:
_cairo_gl_shader_bind_float (ctx,
- _cairo_gl_shader_uniform_for_texunit (
- CAIRO_GL_UNIFORM_A, tex_unit),
+ ctx->current_shader->a_location[tex_unit],
operand->gradient.a);
/* fall through */
case CAIRO_GL_OPERAND_RADIAL_GRADIENT_A0:
- _cairo_gl_shader_bind_vec3 (ctx,
- _cairo_gl_shader_uniform_for_texunit (
- CAIRO_GL_UNIFORM_CIRCLE_D, tex_unit),
+ _cairo_gl_shader_bind_vec3 (ctx,
+ ctx->current_shader->circle_d_location[tex_unit],
operand->gradient.circle_d.center.x,
operand->gradient.circle_d.center.y,
operand->gradient.circle_d.radius);
_cairo_gl_shader_bind_float (ctx,
- _cairo_gl_shader_uniform_for_texunit (
- CAIRO_GL_UNIFORM_RADIUS_0, tex_unit),
+ ctx->current_shader->radius_0_location[tex_unit],
operand->gradient.radius_0);
/* fall through */
case CAIRO_GL_OPERAND_LINEAR_GRADIENT:
@@ -1252,8 +1245,7 @@ _cairo_gl_operand_bind_to_shader (cairo_gl_context_t *ctx,
}
if (operand->type != CAIRO_GL_OPERAND_GAUSSIAN)
_cairo_gl_shader_bind_vec2 (ctx,
- _cairo_gl_shader_uniform_for_texunit (
- CAIRO_GL_UNIFORM_TEXDIMS, tex_unit),
+ ctx->current_shader->texdims_location[tex_unit],
width, height);
}
@@ -1266,60 +1258,52 @@ _cairo_gl_operand_bind_to_shader (cairo_gl_context_t *ctx,
float y_axis = 0.0;
float temp_width;
float near_zero = 0.00001;
+ _cairo_gl_shader_bind_float (ctx,
+ ctx->current_shader->blur_x_axis_location[tex_unit],
+ x_axis);
+
+ _cairo_gl_shader_bind_float (ctx,
+ ctx->current_shader->blur_y_axis_location[tex_unit],
+ y_axis);
- _cairo_gl_shader_bind_float (ctx,
- _cairo_gl_shader_uniform_for_texunit (
- CAIRO_GL_UNIFORM_BLUR_X_AXIS, tex_unit),
- x_axis);
- _cairo_gl_shader_bind_float (ctx,
- _cairo_gl_shader_uniform_for_texunit (
- CAIRO_GL_UNIFORM_BLUR_Y_AXIS, tex_unit),
- y_axis);
_cairo_gl_shader_bind_int (ctx,
- _cairo_gl_shader_uniform_for_texunit (
- CAIRO_GL_UNIFORM_BLUR_RADIUS, tex_unit),
- operand->texture.x_radius);
+ ctx->current_shader->blur_radius_location[tex_unit],
+ operand->texture.x_radius);
temp_width = cairo_gl_surface_get_width (&operand->texture.surface->base);
temp_width = (temp_width == 0) ? near_zero : temp_width;
_cairo_gl_shader_bind_float (ctx,
- _cairo_gl_shader_uniform_for_texunit (
- CAIRO_GL_UNIFORM_BLUR_STEP, tex_unit),
- 1.0 / temp_width);
+ ctx->current_shader->blur_step_location[tex_unit],
+ 1.0 / temp_width);
_cairo_gl_shader_bind_float_array (ctx,
- _cairo_gl_shader_uniform_for_texunit (
- CAIRO_GL_UNIFORM_BLURS, tex_unit),
- operand->texture.x_radius * 2 + 1,
- &operand->texture.coef[0]);
+ ctx->current_shader->blurs_location [tex_unit],
+ operand->texture.x_radius * 2 + 1,
+ operand->texture.coef);
}
else if (operand->type == CAIRO_GL_OPERAND_GAUSSIAN &&
operand->pass == 2) {
float x_axis = 0.0;
float y_axis = 1.0;
+ _cairo_gl_shader_bind_float (ctx,
+ ctx->current_shader->blur_x_axis_location[tex_unit],
+ x_axis);
+
+ _cairo_gl_shader_bind_float (ctx,
+ ctx->current_shader->blur_y_axis_location[tex_unit],
+ y_axis);
- _cairo_gl_shader_bind_float (ctx,
- _cairo_gl_shader_uniform_for_texunit (
- CAIRO_GL_UNIFORM_BLUR_X_AXIS, tex_unit),
- x_axis);
- _cairo_gl_shader_bind_float (ctx,
- _cairo_gl_shader_uniform_for_texunit (
- CAIRO_GL_UNIFORM_BLUR_Y_AXIS, tex_unit),
- y_axis);
_cairo_gl_shader_bind_int (ctx,
- _cairo_gl_shader_uniform_for_texunit (
- CAIRO_GL_UNIFORM_BLUR_RADIUS, tex_unit),
- operand->texture.y_radius);
+ ctx->current_shader->blur_radius_location[tex_unit],
+ operand->texture.y_radius);
- _cairo_gl_shader_bind_float (ctx,
- _cairo_gl_shader_uniform_for_texunit (
- CAIRO_GL_UNIFORM_BLUR_STEP, tex_unit),
- 1.0 / cairo_gl_surface_get_height (&operand->texture.surface->base));
+ _cairo_gl_shader_bind_float (ctx,
+ ctx->current_shader->blur_step_location[tex_unit],
+ 1.0 / cairo_gl_surface_get_height (&operand->texture.surface->base));
_cairo_gl_shader_bind_float_array (ctx,
- _cairo_gl_shader_uniform_for_texunit (
- CAIRO_GL_UNIFORM_BLURS, tex_unit),
+ ctx->current_shader->blurs_location[tex_unit],
operand->texture.y_radius * 2 + 1,
&operand->texture.coef[0]);
}
@@ -1332,12 +1316,10 @@ _cairo_gl_operand_bind_to_shader (cairo_gl_context_t *ctx,
if (operand->gradient.texgen)
texgen = &operand->gradient.m;
}
-
if (texgen) {
- _cairo_gl_shader_bind_matrix (ctx,
- _cairo_gl_shader_uniform_for_texunit (
- CAIRO_GL_UNIFORM_TEXGEN, tex_unit),
- texgen);
+ _cairo_gl_shader_bind_matrix(ctx,
+ ctx->current_shader->texgen_location[tex_unit],
+ texgen);
}
}
diff --git a/src/cairo-gl-private.h b/src/cairo-gl-private.h
index c46a3e8cc..ad08abd9f 100755..100644
--- a/src/cairo-gl-private.h
+++ b/src/cairo-gl-private.h
@@ -4,6 +4,7 @@
* Copyright © 2009 Chris Wilson
* Copyright © 2005,2010 Red Hat, Inc
* Copyright © 2011 Linaro Limited
+ * Copyright © 2011,2015 Samsung Research America, Inc - Silicon Valley
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
@@ -39,6 +40,7 @@
* Eric Anholt <eric@anholt.net>
* T. Zachary Laine <whatwasthataddress@gmail.com>
* Alexandros Frantzis <alexandros.frantzis@linaro.org>
+ * Henry Song <hsong@sisa.samsung.com>
*/
#ifndef CAIRO_GL_PRIVATE_H
@@ -62,11 +64,16 @@
#include <assert.h>
#if CAIRO_HAS_EVASGL_SURFACE
-#include <Evas_GL.h>
+ #include <Evas_GL.h>
#else
#if CAIRO_HAS_GL_SURFACE
+ #if CAIRO_HAS_CGL_FUNCTIONS
+ #include <OpenGL/gl.h>
+ #include <OpenGL/glext.h>
+ #else
#include <GL/gl.h>
#include <GL/glext.h>
+ #endif
#elif CAIRO_HAS_GLESV2_SURFACE
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
@@ -76,7 +83,6 @@
#endif
#endif
-
#include "cairo-gl-ext-def-private.h"
#define DEBUG_GL 0
@@ -104,8 +110,9 @@
/* VBO size that we allocate, smaller size means we gotta flush more often,
* but larger means hogging more memory and can cause trouble for drivers
- * (especially on embedded devices). */
-#define CAIRO_GL_VBO_SIZE (16*1024)
+ * (especially on embedded devices). Use the CAIRO_GL_VBO_SIZE environment
+ * variable to set this to a different size. */
+#define CAIRO_GL_VBO_SIZE_DEFAULT (1024*1024)
#define MIN_IMAGE_CACHE_WIDTH 512
#define MIN_IMAGE_CACHE_HEIGHT 512
@@ -142,7 +149,7 @@ typedef enum cairo_gl_flavor {
CAIRO_GL_FLAVOR_ES3 = 3
} cairo_gl_flavor_t;
-/* The order here is sensitive because of the logic of
+/* The order here is sensitive because of the logic of
*_cairo_gl_shader_uniform_for_texunit. */
typedef enum cairo_gl_uniform_t {
CAIRO_GL_UNIFORM_TEXDIMS, /* "source_texdims" */
@@ -310,7 +317,19 @@ typedef enum cairo_gl_tex {
typedef struct cairo_gl_shader {
GLuint fragment_shader;
GLuint program;
- GLint uniforms[CAIRO_GL_UNIFORM_MAX];
+ GLint mvp_location;
+ GLint constant_location[2];
+ GLint a_location[2];
+ GLint circle_d_location[2];
+ GLint radius_0_location[2];
+ GLint texdims_location[2];
+ GLint texgen_location[2];
+ GLint blur_radius_location[2];
+ GLint blurs_location[2];
+ GLint blur_step_location[2];
+ GLint blur_x_axis_location[2];
+ GLint blur_y_axis_location[2];
+ GLint alpha_location[2];
} cairo_gl_shader_t;
typedef struct _cairo_gl_image_cache {
@@ -406,7 +425,7 @@ typedef struct _cairo_gl_dispatch {
void (*ClearStencil) (GLint s);
void (*ColorMask) (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
void (*DeleteTextures) (GLsizei n, const GLuint *textures);
- void (*DepthMask)(GLboolean flag);
+ void (*DepthMask) (GLboolean flag);
void (*Disable) (GLenum cap);
void (*DrawArrays) (GLenum mode, GLint first, GLsizei count);
void (*DrawElements) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices);
@@ -418,6 +437,7 @@ typedef struct _cairo_gl_dispatch {
void (*GetFloatv) (GLenum pname, GLfloat *data);
void (*GetIntegerv) (GLenum pname, GLint *data);
const GLubyte *(*GetString) (GLenum pname);
+ const GLubyte *(*GetStringi) (GLenum pname, GLuint i);
void (*PixelStorei) (GLenum pname, GLint param);
void (*ReadPixels) (GLint x, GLint y, GLsizei width, GLsizei height,
GLenum format, GLenum type, GLvoid *data);
@@ -442,11 +462,17 @@ typedef struct _cairo_gl_dispatch {
/* Buffers */
void (*GenBuffers) (GLsizei n, GLuint *buffers);
+ void (*DeleteBuffers) (GLsizei n, const GLuint *buffers);
void (*BindBuffer) (GLenum target, GLuint buffer);
void (*BufferData) (GLenum target, GLsizeiptr size,
const GLvoid* data, GLenum usage);
+ void (*BufferSubData) (GLenum target, GLintptr offset,
+ GLsizeiptr size, const GLvoid *data);
GLvoid *(*MapBuffer) (GLenum target, GLenum access);
GLboolean (*UnmapBuffer) (GLenum target);
+ void (*GenVertexArrays) (GLsizei n, GLuint *arrays);
+ void (*BindVertexArray) (GLuint array);
+ void (*DeleteVertexArrays) (GLsizei n, const GLuint *arrays);
/* Shaders */
GLuint (*CreateShader) (GLenum type);
@@ -540,6 +566,9 @@ typedef struct _cairo_gl_states {
cairo_bool_t scissor_test_enabled;
cairo_bool_t stencil_test_enabled;
+ GLuint bound_vbo;
+ GLuint bound_vao;
+ GLuint bound_ibo;
} cairo_gl_states_t;
struct _cairo_gl_context {
@@ -547,7 +576,6 @@ struct _cairo_gl_context {
const cairo_compositor_t *compositor;
- GLuint texture_load_pbo;
GLint max_framebuffer_size;
GLint max_texture_size;
GLint max_textures;
@@ -556,6 +584,9 @@ struct _cairo_gl_context {
GLint num_samples;
cairo_bool_t supports_msaa;
char *vb;
+ GLuint vbo;
+ GLuint vao;
+ GLuint ibo;
cairo_bool_t has_shader_support;
@@ -565,9 +596,9 @@ struct _cairo_gl_context {
cairo_cache_t gradients;
- /* cache[0] for gray font, cache[1] for rgba component alpha
- * cache[2] for color glyph */
- cairo_gl_glyph_cache_t glyph_cache[3];
+ /* cache[0] for gray font, cache[1] for rgba component alpha
+ * cache[2] for color glyph */
+ cairo_gl_glyph_cache_t glyph_cache[3];
cairo_list_t fonts;
cairo_gl_surface_t *current_target;
@@ -578,6 +609,7 @@ struct _cairo_gl_context {
cairo_gl_operand_t operands[2];
cairo_bool_t spans;
+ unsigned int vbo_size;
unsigned int vb_offset;
unsigned int vertex_size;
cairo_region_t *clip_region;
@@ -593,6 +625,7 @@ struct _cairo_gl_context {
cairo_bool_t has_packed_depth_stencil;
cairo_bool_t has_npot_repeat;
cairo_bool_t can_read_bgra;
+ cairo_bool_t is_gl33;
cairo_bool_t thread_aware;
@@ -755,7 +788,7 @@ _cairo_gl_context_choose_emit_span (cairo_gl_context_t *ctx);
cairo_private cairo_gl_emit_glyph_t
_cairo_gl_context_choose_emit_glyph (cairo_gl_context_t *ctx,
- const cairo_bool_t is_color_glyph);
+ const cairo_bool_t is_color_glyph);
cairo_private void
_cairo_gl_context_activate (cairo_gl_context_t *ctx,
@@ -804,6 +837,45 @@ _enable_scissor_buffer (cairo_gl_context_t *ctx)
}
}
+static cairo_always_inline void
+_cairo_gl_ensure_drawbuffers (cairo_gl_context_t *ctx)
+{
+ GLint vbo, ibo, vao;
+
+ if ((ctx->vao != 0 &&
+ (ctx->vao != ctx->states_cache.bound_vao))) {
+ ctx->dispatch.GetIntegerv (GL_VERTEX_ARRAY_BINDING, &vao);
+ if (vao != ctx->states_cache.bound_vao) {
+ ctx->dispatch.BindVertexArray (ctx->vao);
+ ctx->states_cache.bound_vao = ctx->vao;
+
+ ctx->dispatch.BindBuffer (GL_ARRAY_BUFFER, ctx->vbo);
+ ctx->states_cache.bound_vbo = ctx->vbo;
+
+ ctx->dispatch.BindBuffer (GL_ELEMENT_ARRAY_BUFFER, ctx->ibo);
+ ctx->states_cache.bound_ibo = ctx->ibo;
+ }
+ }
+
+ if ((ctx->vbo != 0 &&
+ (ctx->vbo != ctx->states_cache.bound_vbo))) {
+ ctx->dispatch.GetIntegerv (GL_ARRAY_BUFFER_BINDING, &vbo);
+ if (vbo != (GLint) ctx->states_cache.bound_vbo) {
+ ctx->dispatch.BindBuffer (GL_ARRAY_BUFFER, ctx->vbo);
+ }
+ ctx->states_cache.bound_vbo = ctx->vbo;
+ }
+
+ if ((ctx->ibo != 0 &&
+ (ctx->ibo != ctx->states_cache.bound_ibo))) {
+ ctx->dispatch.GetIntegerv (GL_ELEMENT_ARRAY_BUFFER_BINDING, &ibo);
+ if (ibo != (GLint) ctx->states_cache.bound_ibo) {
+ ctx->dispatch.BindBuffer (GL_ELEMENT_ARRAY_BUFFER, ctx->ibo);
+ }
+ ctx->states_cache.bound_ibo = ctx->ibo;
+ }
+}
+
cairo_private cairo_status_t
_cairo_gl_composite_init (cairo_gl_composite_t *setup,
cairo_operator_t op,
@@ -886,6 +958,12 @@ _cairo_gl_composite_emit_triangle_as_tristrip (cairo_gl_context_t *ctx,
const cairo_point_t triangle[3]);
cairo_private cairo_int_status_t
+_cairo_gl_composite_emit_triangle_fan (cairo_gl_context_t *ctx,
+ cairo_gl_composite_t *setup,
+ const cairo_point_t *fan,
+ int count);
+
+cairo_private cairo_int_status_t
_cairo_gl_composite_emit_point_as_tristrip_line (cairo_gl_context_t *ctx,
const cairo_point_t point[2],
cairo_bool_t start_point);
@@ -944,49 +1022,49 @@ _cairo_gl_get_shader_by_type (cairo_gl_context_t *ctx,
cairo_private cairo_gl_uniform_t
_cairo_gl_shader_uniform_for_texunit (cairo_gl_uniform_t uniform,
- cairo_gl_tex_t tex_unit);
+ cairo_gl_tex_t tex_unit);
cairo_private void
_cairo_gl_shader_bind_float (cairo_gl_context_t *ctx,
- cairo_gl_uniform_t uniform,
+ GLint location,
float value);
cairo_private void
_cairo_gl_shader_bind_float_array (cairo_gl_context_t *ctx,
- cairo_gl_uniform_t uniform,
+ GLint location,
int num, float *values);
cairo_private void
_cairo_gl_shader_bind_int (cairo_gl_context_t *ctx,
- cairo_gl_uniform_t uniform,
+ GLint location,
int value);
cairo_private void
_cairo_gl_shader_bind_vec2 (cairo_gl_context_t *ctx,
- cairo_gl_uniform_t uniform,
+ GLint location,
float value0, float value1);
cairo_private void
_cairo_gl_shader_bind_vec3 (cairo_gl_context_t *ctx,
- cairo_gl_uniform_t uniform,
+ GLint location,
float value0,
float value1,
float value2);
cairo_private void
_cairo_gl_shader_bind_vec4 (cairo_gl_context_t *ctx,
- cairo_gl_uniform_t uniform,
+ GLint location,
float value0, float value1,
float value2, float value3);
cairo_private void
_cairo_gl_shader_bind_matrix (cairo_gl_context_t *ctx,
- cairo_gl_uniform_t uniform,
+ GLint location,
const cairo_matrix_t* m);
cairo_private void
_cairo_gl_shader_bind_matrix4f (cairo_gl_context_t *ctx,
- cairo_gl_uniform_t uniform,
+ GLint location,
GLfloat* gl_m);
cairo_private void
@@ -999,9 +1077,15 @@ _cairo_gl_shader_fini (cairo_gl_context_t *ctx, cairo_gl_shader_t *shader);
cairo_private int
_cairo_gl_get_version (cairo_gl_dispatch_t *dispatch);
+cairo_private int
+_cairo_glsl_get_version (cairo_gl_dispatch_t *dispatch);
+
cairo_private cairo_gl_flavor_t
_cairo_gl_get_flavor (cairo_gl_dispatch_t *dispatch);
+cairo_private unsigned long
+_cairo_gl_get_vbo_size (void);
+
cairo_private cairo_bool_t
_cairo_gl_has_extension (cairo_gl_dispatch_t *dispatch, const char *ext);
diff --git a/src/cairo-gl-shaders.c b/src/cairo-gl-shaders.c
index 0f8073ba6..7d7b669a8 100755..100644
--- a/src/cairo-gl-shaders.c
+++ b/src/cairo-gl-shaders.c
@@ -44,50 +44,40 @@
#include "cairo-error-private.h"
#include "cairo-output-stream-private.h"
-static GLint
-_cairo_gl_shader_get_uniform_location (cairo_gl_context_t *ctx,
- cairo_gl_shader_t *shader,
- cairo_gl_uniform_t uniform)
+enum {
+ CAIRO_GLSL_VERSION_UNKNOWN,
+ CAIRO_GLSL_VERSION_330,
+ CAIRO_GLSL_VERSION_NON_330
+};
+
+static int needs_glsl330 = CAIRO_GLSL_VERSION_UNKNOWN;
+/*static const char[] glsl330_frag_out = "fsColorOut";
+static const char[] non_glsl330_frag_out = "gl_FragColor";
+static const char[] glsl330_in_attrib = "in";
+static const char[] non_glsl330_in_attrib = "attribute";
+static const char[] glsl330_out_attrib = "varying";
+static const char[] non_glsl330_out_attrib = "out";
+static const char[] glsl330 = "#version 330";
+*/
+static cairo_bool_t _cairo_needs_glsl330 (cairo_gl_context_t *ctx)
{
- /* This should be kept in sync with the enum
- * definition in cairo-gl-private.h. */
- const char *names[CAIRO_GL_UNIFORM_MAX] = {
- "source_texdims",
- "source_texgen",
- "source_constant",
- "source_sampler",
- "source_a",
- "source_circle_d",
- "source_radius_0",
- "source_blur_radius",
- "source_blurs",
- "source_blur_step",
- "source_blur_x_axis",
- "source_blur_y_axis",
- "source_alpha",
- "mask_texdims",
- "mask_texgen",
- "mask_constant",
- "mask_sampler",
- "mask_a",
- "mask_circle_d",
- "mask_radius_0",
- "mask_blur_radius",
- "mask_blurs",
- "mask_blur_step",
- "mask_blur_x_axis",
- "mask_blur_y_axis",
- "mask_alpha",
- "ModelViewProjectionMatrix"
- };
-
- if (shader->uniforms[uniform] != -1)
- return shader->uniforms[uniform];
+ int version;
+ cairo_gl_flavor_t flavor;
+
+ if (needs_glsl330 == CAIRO_GLSL_VERSION_UNKNOWN) {
+ version = _cairo_glsl_get_version (&ctx->dispatch);
+ flavor = _cairo_gl_get_flavor (&ctx->dispatch);
+
+ if ((flavor == CAIRO_GL_FLAVOR_DESKTOP &&
+ version >= CAIRO_GL_VERSION_ENCODE (3, 30)) ||
+ (flavor == CAIRO_GL_FLAVOR_ES3 &&
+ version >= CAIRO_GL_VERSION_ENCODE (3, 1)))
+ needs_glsl330 = CAIRO_GLSL_VERSION_330;
+ else
+ needs_glsl330 = CAIRO_GLSL_VERSION_NON_330;
+ }
- shader->uniforms[uniform] =
- ctx->dispatch.GetUniformLocation (shader->program,
- names[uniform]);
- return shader->uniforms[uniform];
+ return needs_glsl330 == CAIRO_GLSL_VERSION_330;
}
cairo_gl_uniform_t
@@ -212,12 +202,8 @@ _cairo_gl_shader_cache_destroy (void *data)
static void
_cairo_gl_shader_init (cairo_gl_shader_t *shader)
{
- int i;
shader->fragment_shader = 0;
shader->program = 0;
-
- for (i = 0; i < CAIRO_GL_UNIFORM_MAX; i++)
- shader->uniforms[i] = -1;
}
cairo_status_t
@@ -232,8 +218,23 @@ _cairo_gl_context_init_shaders (cairo_gl_context_t *ctx)
"{\n"
" gl_FragColor = color;\n"
"}\n";
+
+ static const char *glsl330_fill_fs_source =
+ "#version 330\n"
+ "#ifdef GL_ES\n"
+ "precision mediump float;\n"
+ "#endif\n"
+ "uniform vec4 color;\n"
+ "out vec4 fsColorOut;\n"
+ "void main()\n"
+ "{\n"
+ " fsColorOut = color;\n"
+ "}\n";
+
cairo_status_t status;
+ _cairo_needs_glsl330 (ctx);
+
if (_cairo_gl_get_version (&ctx->dispatch) >= CAIRO_GL_VERSION_ENCODE (2, 0) ||
(_cairo_gl_has_extension (&ctx->dispatch, "GL_ARB_shader_objects") &&
_cairo_gl_has_extension (&ctx->dispatch, "GL_ARB_fragment_shader") &&
@@ -258,7 +259,17 @@ _cairo_gl_context_init_shaders (cairo_gl_context_t *ctx)
return status;
_cairo_gl_shader_init (&ctx->fill_rectangles_shader);
- status = _cairo_gl_shader_compile_and_link (ctx,
+ if (needs_glsl330 == CAIRO_GLSL_VERSION_330)
+ status = _cairo_gl_shader_compile_and_link (ctx,
+ &ctx->fill_rectangles_shader,
+ CAIRO_GL_VAR_NONE,
+ CAIRO_GL_VAR_NONE,
+ FALSE,
+ glsl330_fill_fs_source,
+ CAIRO_EXTEND_NONE, CAIRO_EXTEND_NONE,
+ FALSE, FALSE);
+ else
+ status = _cairo_gl_shader_compile_and_link (ctx,
&ctx->fill_rectangles_shader,
CAIRO_GL_VAR_NONE,
CAIRO_GL_VAR_NONE,
@@ -334,32 +345,63 @@ cairo_gl_shader_emit_variable (cairo_output_stream_t *stream,
case CAIRO_GL_VAR_NONE:
break;
case CAIRO_GL_VAR_TEXCOORDS:
- _cairo_output_stream_printf (stream,
+ if (needs_glsl330 == CAIRO_GLSL_VERSION_330) {
+ _cairo_output_stream_printf (stream,
+ "in vec4 MultiTexCoord%d;\n"
+ "out vec2 %s_texcoords;\n",
+ name,
+ operand_names[name]);
+ if (use_atlas)
+ _cairo_output_stream_printf (stream,
+ "out vec2 %s_start_coords;\n"
+ "out vec2 %s_stop_coords;\n",
+ operand_names[name], operand_names[name]);
+ } else {
+ _cairo_output_stream_printf (stream,
"attribute vec4 MultiTexCoord%d;\n"
"varying vec2 %s_texcoords;\n",
name,
operand_names[name]);
- if (use_atlas)
- _cairo_output_stream_printf (stream,
+ if (use_atlas)
+ _cairo_output_stream_printf (stream,
"varying vec2 %s_start_coords;\n"
"varying vec2 %s_stop_coords;\n",
operand_names[name], operand_names[name]);
+ }
break;
case CAIRO_GL_VAR_TEXGEN:
- _cairo_output_stream_printf (stream,
+ if (needs_glsl330 == CAIRO_GLSL_VERSION_330) {
+ _cairo_output_stream_printf (stream,
+ "uniform mat3 %s_texgen;\n"
+ "out vec2 %s_texcoords;\n",
+ operand_names[name],
+ operand_names[name]);
+ /*if (use_atlas)
+ _cairo_output_stream_printf (stream,
+ "out vec2 %s_start_coords;\n"
+ "out vec2 %s_stop_coords;\n",
+ operand_names[name], operand_names[name]);
+ */
+ } else {
+ _cairo_output_stream_printf (stream,
"uniform mat3 %s_texgen;\n"
"varying vec2 %s_texcoords;\n",
operand_names[name],
operand_names[name]);
- /*if (use_atlas)
- _cairo_output_stream_printf (stream,
+ /*if (use_atlas)
+ _cairo_output_stream_printf (stream,
"varying vec2 %s_start_coords;\n"
"varying vec2 %s_stop_coords;\n",
operand_names[name], operand_names[name]);
-*/
+ */
+ }
break;
case CAIRO_GL_VAR_COLOR:
- _cairo_output_stream_printf (stream,
+ if (needs_glsl330 == CAIRO_GLSL_VERSION_330)
+ _cairo_output_stream_printf (stream,
+ "out vec4 fragment_color;\n");
+ else
+ _cairo_output_stream_printf (stream,
"varying vec4 fragment_color;\n");
break;
}
@@ -395,7 +437,10 @@ cairo_gl_shader_emit_vertex (cairo_output_stream_t *stream,
static void
cairo_gl_shader_dcl_coverage (cairo_output_stream_t *stream)
{
- _cairo_output_stream_printf (stream, "varying float coverage;\n");
+ if (needs_glsl330 == CAIRO_GLSL_VERSION_330)
+ _cairo_output_stream_printf (stream, "out float coverage;\n");
+ else
+ _cairo_output_stream_printf (stream, "varying float coverage;\n");
}
static void
@@ -422,10 +467,16 @@ cairo_gl_shader_emit_varying (cairo_output_stream_t *stream,
{
const char *namestr = operand_names[name];
- _cairo_output_stream_printf (stream,
- "varying vec2 %s_start_coords;\n"
- "varying vec2 %s_stop_coords;\n",
- namestr, namestr);
+ if (needs_glsl330 == CAIRO_GLSL_VERSION_330)
+ _cairo_output_stream_printf (stream,
+ "out vec2 %s_start_coords;\n"
+ "out vec2 %s_stop_coords;\n",
+ namestr, namestr);
+ else
+ _cairo_output_stream_printf (stream,
+ "varying vec2 %s_start_coords;\n"
+ "varying vec2 %s_stop_coords;\n",
+ namestr, namestr);
}
static cairo_status_t
@@ -442,6 +493,11 @@ cairo_gl_shader_get_vertex_source (cairo_gl_var_type_t src,
unsigned long length;
cairo_status_t status;
+ if (needs_glsl330 == CAIRO_GLSL_VERSION_330)
+ _cairo_output_stream_printf (stream, "#version 330\n");
+
+ _cairo_output_stream_printf (stream, "#ifdef GL_ES\nprecision mediump float;\n#endif\n");
+
cairo_gl_shader_emit_variable (stream, src, CAIRO_GL_TEX_SOURCE, src_use_atlas);
cairo_gl_shader_emit_variable (stream, mask, CAIRO_GL_TEX_MASK, mask_use_atlas);
if (use_coverage)
@@ -453,7 +509,20 @@ cairo_gl_shader_get_vertex_source (cairo_gl_var_type_t src,
if (mask_use_atlas && mask == CAIRO_GL_VAR_TEXGEN)
cairo_gl_shader_emit_varying (stream, CAIRO_GL_TEX_MASK);
- _cairo_output_stream_printf (stream,
+ if (needs_glsl330 == CAIRO_GLSL_VERSION_330) {
+ _cairo_output_stream_printf (stream,
+ "in vec4 Vertex;\n"
+ "in vec4 Color;\n"
+ "in vec2 StartCoords0;\n"
+ "in vec2 StartCoords1;\n"
+ "in vec2 StopCoords0;\n"
+ "in vec2 StopCoords1;\n"
+ "uniform mat4 ModelViewProjectionMatrix;\n"
+ "void main()\n"
+ "{\n"
+ " gl_Position = ModelViewProjectionMatrix * Vertex;\n");
+ } else {
+ _cairo_output_stream_printf (stream,
"attribute vec4 Vertex;\n"
"attribute vec4 Color;\n"
"attribute vec2 StartCoords0;\n"
@@ -464,6 +533,7 @@ cairo_gl_shader_get_vertex_source (cairo_gl_var_type_t src,
"void main()\n"
"{\n"
" gl_Position = ModelViewProjectionMatrix * Vertex;\n");
+ }
cairo_gl_shader_emit_vertex (stream, src, CAIRO_GL_TEX_SOURCE);
cairo_gl_shader_emit_vertex (stream, mask, CAIRO_GL_TEX_MASK);
@@ -479,10 +549,8 @@ cairo_gl_shader_get_vertex_source (cairo_gl_var_type_t src,
"}\n\0", 3);
status = _cairo_memory_stream_destroy (stream, &source, &length);
- if (unlikely (status)) {
- free (source);
- return status;
- }
+ if (unlikely (status))
+ return status;
*out = (char *) source;
return CAIRO_STATUS_SUCCESS;
@@ -512,6 +580,7 @@ cairo_gl_shader_emit_color (cairo_output_stream_t *stream,
cairo_gl_tex_t name)
{
const char *namestr = operand_names[name];
+ const char *textstr = (needs_glsl330 == CAIRO_GLSL_VERSION_330) ? "" : "2D";
const char *rectstr = (ctx->tex_target == GL_TEXTURE_RECTANGLE ? "Rect" : "");
cairo_bool_t use_atlas = _cairo_gl_operand_get_use_atlas (op);
@@ -521,7 +590,7 @@ cairo_gl_shader_emit_color (cairo_output_stream_t *stream,
ASSERT_NOT_REACHED;
break;
case CAIRO_GL_OPERAND_NONE:
- _cairo_output_stream_printf (stream,
+ _cairo_output_stream_printf (stream,
"vec4 get_%s()\n"
"{\n"
" return vec4 (0, 0, 0, 1);\n"
@@ -530,13 +599,22 @@ cairo_gl_shader_emit_color (cairo_output_stream_t *stream,
break;
case CAIRO_GL_OPERAND_CONSTANT:
if (op->constant.encode_as_attribute) {
- _cairo_output_stream_printf (stream,
- "varying vec4 fragment_color;\n"
- "vec4 get_%s()\n"
- "{\n"
- " return fragment_color;\n"
- "}\n",
- namestr);
+ if (needs_glsl330 == CAIRO_GLSL_VERSION_330)
+ _cairo_output_stream_printf (stream,
+ "in vec4 fragment_color;\n"
+ "vec4 get_%s()\n"
+ "{\n"
+ " return fragment_color;\n"
+ "}\n",
+ namestr);
+ else
+ _cairo_output_stream_printf (stream,
+ "varying vec4 fragment_color;\n"
+ "vec4 get_%s()\n"
+ "{\n"
+ " return fragment_color;\n"
+ "}\n",
+ namestr);
} else {
_cairo_output_stream_printf (stream,
"uniform vec4 %s_constant;\n"
@@ -546,23 +624,41 @@ cairo_gl_shader_emit_color (cairo_output_stream_t *stream,
"}\n",
namestr, namestr, namestr);
}
- break;
+ break;
case CAIRO_GL_OPERAND_TEXTURE:
case CAIRO_GL_OPERAND_GAUSSIAN:
- if (! use_atlas) {
- _cairo_output_stream_printf (stream,
- "uniform sampler2D%s %s_sampler;\n"
- "uniform vec2 %s_texdims;\n"
- "varying vec2 %s_texcoords;\n",
- rectstr, namestr, namestr, namestr);
+ if (needs_glsl330 == CAIRO_GLSL_VERSION_330) {
+ if (! use_atlas) {
+ _cairo_output_stream_printf (stream,
+ "uniform sampler2D%s %s_sampler;\n"
+ "uniform vec2 %s_texdims;\n"
+ "in vec2 %s_texcoords;\n",
+ rectstr, namestr, namestr, namestr);
+ } else {
+ _cairo_output_stream_printf (stream,
+ "uniform sampler2D%s %s_sampler;\n"
+ "uniform vec2 %s_texdims;\n"
+ "in vec2 %s_texcoords;\n"
+ "in vec2 %s_start_coords;\n"
+ "in vec2 %s_stop_coords;\n",
+ rectstr, namestr, namestr, namestr, namestr, namestr);
+ }
} else {
- _cairo_output_stream_printf (stream,
- "uniform sampler2D%s %s_sampler;\n"
- "uniform vec2 %s_texdims;\n"
- "varying vec2 %s_texcoords;\n"
- "varying vec2 %s_start_coords;\n"
- "varying vec2 %s_stop_coords;\n",
- rectstr, namestr, namestr, namestr, namestr, namestr);
+ if (! use_atlas) {
+ _cairo_output_stream_printf (stream,
+ "uniform sampler2D%s %s_sampler;\n"
+ "uniform vec2 %s_texdims;\n"
+ "varying vec2 %s_texcoords;\n",
+ rectstr, namestr, namestr, namestr);
+ } else {
+ _cairo_output_stream_printf (stream,
+ "uniform sampler2D%s %s_sampler;\n"
+ "uniform vec2 %s_texdims;\n"
+ "varying vec2 %s_texcoords;\n"
+ "varying vec2 %s_start_coords;\n"
+ "varying vec2 %s_stop_coords;\n",
+ rectstr, namestr, namestr, namestr, namestr, namestr);
+ }
}
if (op->type != CAIRO_GL_OPERAND_TEXTURE) {
@@ -582,17 +678,17 @@ cairo_gl_shader_emit_color (cairo_output_stream_t *stream,
namestr);
if (op->type == CAIRO_GL_OPERAND_TEXTURE) {
- if ((ctx->gl_flavor == CAIRO_GL_FLAVOR_ES2 ||
+ if ((ctx->gl_flavor == CAIRO_GL_FLAVOR_ES2 ||
ctx->gl_flavor == CAIRO_GL_FLAVOR_ES3) &&
_cairo_gl_shader_needs_border_fade (op))
{
if (! use_atlas) {
_cairo_output_stream_printf (stream,
" vec2 border_fade = %s_border_fade (%s_texcoords, %s_texdims);\n"
- " vec4 texel = texture2D%s (%s_sampler, %s_texcoords);\n"
+ " vec4 texel = texture%s%s (%s_sampler, %s_texcoords);\n"
" return texel * border_fade.x * border_fade.y;\n"
"}\n",
- namestr, namestr, namestr, rectstr, namestr, namestr);
+ namestr, namestr, namestr, textstr, rectstr, namestr, namestr);
}
else {
_cairo_output_stream_printf (stream,
@@ -600,25 +696,24 @@ cairo_gl_shader_emit_color (cairo_output_stream_t *stream,
" vec2 co = %s_wrap (%s_texcoords, %s_start_coords, %s_stop_coords);\n"
" if (co.x == -1.0 && co.y == -1.0)\n"
" return vec4(0.0, 0.0, 0.0, 0.0);\n"
- " vec4 texel = texture2D%s (%s_sampler, co);\n"
+ " vec4 texel = texture%s%s (%s_sampler, %s_wrap (%s_texcoords, %s_start_coords, %s_stop_coords));\n"
" return texel * border_fade.x * border_fade.y;\n"
"}\n",
- namestr, namestr, namestr, namestr,
- namestr, namestr, namestr, rectstr, namestr);
+ namestr, namestr, namestr, namestr, namestr, namestr, namestr, textstr, rectstr, namestr, namestr, namestr, namestr, namestr);
}
}
else
{
if (! use_atlas) {
_cairo_output_stream_printf (stream,
- " return texture2D%s (%s_sampler, %s_wrap (%s_texcoords));\n"
+ " return texture%s%s (%s_sampler, %s_wrap (%s_texcoords));\n"
"}\n",
- rectstr, namestr, namestr, namestr);
+ textstr, rectstr, namestr, namestr, namestr);
} else {
_cairo_output_stream_printf (stream,
- " return texture2D%s (%s_sampler, %s_wrap (%s_texcoords, %s_start_coords, %s_stop_coords));\n"
+ " return texture%s%s (%s_sampler, %s_wrap (%s_texcoords, %s_start_coords, %s_stop_coords));\n"
"}\n",
- rectstr, namestr, namestr, namestr, namestr, namestr);
+ textstr, rectstr, namestr, namestr, namestr, namestr, namestr);
}
}
}
@@ -631,7 +726,7 @@ cairo_gl_shader_emit_color (cairo_output_stream_t *stream,
" vec2 wrapped_coords = %s_wrap (%s_texcoords, %s_start_coords, %s_stop_coords);\n"
" if (wrapped_coords == vec2 (-1.0, -1.0))\n"
" return texel;\n"
- " texel += texture2D%s (%s_sampler, wrapped_coords);\n"
+ " texel += texture%s%s (%s_sampler, wrapped_coords);\n"
" texel = texel * %s_blurs[%s_blur_radius];\n"
" for (i = -%s_blur_radius; i <= %s_blur_radius; i++) {\n"
" if (i == 0)\n"
@@ -642,160 +737,255 @@ cairo_gl_shader_emit_color (cairo_output_stream_t *stream,
" if (wrapped_coords == vec2 (-1.0, -1.0))\n"
" texel += vec4 (0.0, 0.0, 0.0, alpha) * %s_blurs[i+%s_blur_radius];\n"
" else\n"
- " texel += texture2D%s (%s_sampler, wrapped_coords) * %s_blurs[i+%s_blur_radius];\n"
+ " texel += texture%s%s (%s_sampler, wrapped_coords) * %s_blurs[i+%s_blur_radius];\n"
" }\n"
" return texel;\n"
"}\n",
namestr, namestr, namestr, namestr, namestr,
- rectstr, namestr, namestr, namestr,
+ textstr, rectstr, namestr, namestr, namestr,
namestr, namestr, namestr, namestr,
namestr, namestr, namestr, namestr,
namestr, namestr, namestr, namestr,
- rectstr, namestr, namestr, namestr);
+ textstr, rectstr, namestr, namestr, namestr);
}
break;
case CAIRO_GL_OPERAND_LINEAR_GRADIENT:
- _cairo_output_stream_printf (stream,
- "varying vec2 %s_texcoords;\n"
- "uniform vec2 %s_texdims;\n"
- "uniform sampler2D%s %s_sampler;\n"
- "\n"
- "vec4 get_%s()\n"
- "{\n",
- namestr, namestr, rectstr, namestr, namestr);
- if ((ctx->gl_flavor == CAIRO_GL_FLAVOR_ES2 ||
+ if (needs_glsl330 == CAIRO_GLSL_VERSION_330) {
+ _cairo_output_stream_printf (stream,
+ "in vec2 %s_texcoords;\n"
+ "uniform vec2 %s_texdims;\n"
+ "uniform sampler2D%s %s_sampler;\n"
+ "\n"
+ "vec4 get_%s()\n"
+ "{\n",
+ namestr, namestr, rectstr, namestr, namestr);
+ }
+ else {
+ _cairo_output_stream_printf (stream,
+ "varying vec2 %s_texcoords;\n"
+ "uniform vec2 %s_texdims;\n"
+ "uniform sampler2D%s %s_sampler;\n"
+ "\n"
+ "vec4 get_%s()\n"
+ "{\n",
+ namestr, namestr, rectstr, namestr, namestr);
+ }
+
+ if ((ctx->gl_flavor == CAIRO_GL_FLAVOR_ES2 ||
ctx->gl_flavor == CAIRO_GL_FLAVOR_ES3) &&
_cairo_gl_shader_needs_border_fade (op))
{
_cairo_output_stream_printf (stream,
" float border_fade = %s_border_fade (%s_texcoords.x, %s_texdims.x);\n"
- " vec4 texel = texture2D%s (%s_sampler, vec2 (%s_texcoords.x, 0.5));\n"
+ " vec4 texel = texture%s%s (%s_sampler, vec2 (%s_texcoords.x, 0.5));\n"
" return texel * border_fade;\n"
"}\n",
- namestr, namestr, namestr, rectstr, namestr, namestr);
+ namestr, namestr, namestr, textstr, rectstr, namestr, namestr);
}
else
{
_cairo_output_stream_printf (stream,
- " return texture2D%s (%s_sampler, %s_wrap (vec2 (%s_texcoords.x, 0.5)));\n"
+ " return texture%s%s (%s_sampler, %s_wrap (vec2 (%s_texcoords.x, 0.5)));\n"
"}\n",
- rectstr, namestr, namestr, namestr);
+ textstr, rectstr, namestr, namestr, namestr);
}
break;
case CAIRO_GL_OPERAND_RADIAL_GRADIENT_A0:
- _cairo_output_stream_printf (stream,
- "varying vec2 %s_texcoords;\n"
- "uniform vec2 %s_texdims;\n"
- "uniform sampler2D%s %s_sampler;\n"
- "uniform vec3 %s_circle_d;\n"
- "uniform float %s_radius_0;\n"
- "\n"
- "vec4 get_%s()\n"
- "{\n"
- " vec3 pos = vec3 (%s_texcoords, %s_radius_0);\n"
- " \n"
- " float B = dot (pos, %s_circle_d);\n"
- " float C = dot (pos, vec3 (pos.xy, -pos.z));\n"
- " \n"
- " float t = 0.5 * C / B;\n"
- " 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_ES2 ||
+ if (needs_glsl330 == CAIRO_GLSL_VERSION_330) {
+ _cairo_output_stream_printf (stream,
+ "in vec2 %s_texcoords;\n"
+ "uniform vec2 %s_texdims;\n"
+ "uniform sampler2D%s %s_sampler;\n"
+ "uniform vec3 %s_circle_d;\n"
+ "uniform float %s_radius_0;\n"
+ "\n"
+ "vec4 get_%s()\n"
+ "{\n"
+ " vec3 pos = vec3 (%s_texcoords, %s_radius_0);\n"
+ " \n"
+ " float B = dot (pos, %s_circle_d);\n"
+ " float C = dot (pos, vec3 (pos.xy, -pos.z));\n"
+ " \n"
+ " float t = 0.5 * C / B;\n"
+ " 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);
+ } else {
+ _cairo_output_stream_printf (stream,
+ "varying vec2 %s_texcoords;\n"
+ "uniform vec2 %s_texdims;\n"
+ "uniform sampler2D%s %s_sampler;\n"
+ "uniform vec3 %s_circle_d;\n"
+ "uniform float %s_radius_0;\n"
+ "\n"
+ "vec4 get_%s()\n"
+ "{\n"
+ " vec3 pos = vec3 (%s_texcoords, %s_radius_0);\n"
+ " \n"
+ " float B = dot (pos, %s_circle_d);\n"
+ " float C = dot (pos, vec3 (pos.xy, -pos.z));\n"
+ " \n"
+ " float t = 0.5 * C / B;\n"
+ " 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_ES2 ||
ctx->gl_flavor == CAIRO_GL_FLAVOR_ES3) &&
_cairo_gl_shader_needs_border_fade (op))
{
_cairo_output_stream_printf (stream,
" float border_fade = %s_border_fade (t, %s_texdims.x);\n"
- " vec4 texel = texture2D%s (%s_sampler, vec2 (t, 0.5));\n"
+ " vec4 texel = texture%s%s (%s_sampler, vec2 (t, 0.5));\n"
" return mix (vec4 (0.0), texel * border_fade, is_valid);\n"
"}\n",
- namestr, namestr, rectstr, namestr);
+ namestr, namestr, textstr, rectstr, namestr);
}
else
{
_cairo_output_stream_printf (stream,
- " vec4 texel = texture2D%s (%s_sampler, %s_wrap (vec2 (t, 0.5)));\n"
+ " vec4 texel = texture%s%s (%s_sampler, %s_wrap (vec2 (t, 0.5)));\n"
" return mix (vec4 (0.0), texel, is_valid);\n"
"}\n",
- rectstr, namestr, namestr);
+ textstr, rectstr, namestr, namestr);
}
break;
case CAIRO_GL_OPERAND_RADIAL_GRADIENT_NONE:
- _cairo_output_stream_printf (stream,
- "varying vec2 %s_texcoords;\n"
- "uniform vec2 %s_texdims;\n"
- "uniform sampler2D%s %s_sampler;\n"
- "uniform vec3 %s_circle_d;\n"
- "uniform float %s_a;\n"
- "uniform float %s_radius_0;\n"
- "\n"
- "vec4 get_%s()\n"
- "{\n"
- " vec3 pos = vec3 (%s_texcoords, %s_radius_0);\n"
- " \n"
- " float B = dot (pos, %s_circle_d);\n"
- " float C = dot (pos, vec3 (pos.xy, -pos.z));\n"
- " \n"
- " float det = dot (vec2 (B, %s_a), vec2 (B, -C));\n"
- " float sqrtdet = sqrt (abs (det));\n"
- " vec2 t = (B + vec2 (sqrtdet, -sqrtdet)) / %s_a;\n"
- " \n"
- " vec2 is_valid = step (vec2 (0.0), t) * step (t, vec2(1.0));\n"
- " float has_color = step (0., det) * max (is_valid.x, is_valid.y);\n"
- " \n"
- " 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_ES2 ||
+ if (needs_glsl330 == CAIRO_GLSL_VERSION_330) {
+ _cairo_output_stream_printf (stream,
+ "in vec2 %s_texcoords;\n"
+ "uniform vec2 %s_texdims;\n"
+ "uniform sampler2D%s %s_sampler;\n"
+ "uniform vec3 %s_circle_d;\n"
+ "uniform float %s_a;\n"
+ "uniform float %s_radius_0;\n"
+ "\n"
+ "vec4 get_%s()\n"
+ "{\n"
+ " vec3 pos = vec3 (%s_texcoords, %s_radius_0);\n"
+ " \n"
+ " float B = dot (pos, %s_circle_d);\n"
+ " float C = dot (pos, vec3 (pos.xy, -pos.z));\n"
+ " \n"
+ " float det = dot (vec2 (B, %s_a), vec2 (B, -C));\n"
+ " float sqrtdet = sqrt (abs (det));\n"
+ " vec2 t = (B + vec2 (sqrtdet, -sqrtdet)) / %s_a;\n"
+ " \n"
+ " vec2 is_valid = step (vec2 (0.0), t) * step (t, vec2(1.0));\n"
+ " float has_color = step (0., det) * max (is_valid.x, is_valid.y);\n"
+ " \n"
+ " 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);
+ } else {
+ _cairo_output_stream_printf (stream,
+ "varying vec2 %s_texcoords;\n"
+ "uniform vec2 %s_texdims;\n"
+ "uniform sampler2D%s %s_sampler;\n"
+ "uniform vec3 %s_circle_d;\n"
+ "uniform float %s_a;\n"
+ "uniform float %s_radius_0;\n"
+ "\n"
+ "vec4 get_%s()\n"
+ "{\n"
+ " vec3 pos = vec3 (%s_texcoords, %s_radius_0);\n"
+ " \n"
+ " float B = dot (pos, %s_circle_d);\n"
+ " float C = dot (pos, vec3 (pos.xy, -pos.z));\n"
+ " \n"
+ " float det = dot (vec2 (B, %s_a), vec2 (B, -C));\n"
+ " float sqrtdet = sqrt (abs (det));\n"
+ " vec2 t = (B + vec2 (sqrtdet, -sqrtdet)) / %s_a;\n"
+ " \n"
+ " vec2 is_valid = step (vec2 (0.0), t) * step (t, vec2(1.0));\n"
+ " float has_color = step (0., det) * max (is_valid.x, is_valid.y);\n"
+ " \n"
+ " 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_ES2 ||
ctx->gl_flavor == CAIRO_GL_FLAVOR_ES3) &&
_cairo_gl_shader_needs_border_fade (op))
{
_cairo_output_stream_printf (stream,
" float border_fade = %s_border_fade (upper_t, %s_texdims.x);\n"
- " vec4 texel = texture2D%s (%s_sampler, vec2 (upper_t, 0.5));\n"
+ " vec4 texel = texture%s%s (%s_sampler, vec2 (upper_t, 0.5));\n"
" return mix (vec4 (0.0), texel * border_fade, has_color);\n"
"}\n",
- namestr, namestr, rectstr, namestr);
+ namestr, namestr, textstr, rectstr, namestr);
}
else
{
_cairo_output_stream_printf (stream,
- " vec4 texel = texture2D%s (%s_sampler, %s_wrap (vec2(upper_t, 0.5)));\n"
+ " vec4 texel = texture%s%s (%s_sampler, %s_wrap (vec2(upper_t, 0.5)));\n"
" return mix (vec4 (0.0), texel, has_color);\n"
"}\n",
- rectstr, namestr, namestr);
+ textstr, rectstr, namestr, namestr);
}
break;
case CAIRO_GL_OPERAND_RADIAL_GRADIENT_EXT:
- _cairo_output_stream_printf (stream,
- "varying vec2 %s_texcoords;\n"
- "uniform sampler2D%s %s_sampler;\n"
- "uniform vec3 %s_circle_d;\n"
- "uniform float %s_a;\n"
- "uniform float %s_radius_0;\n"
- "\n"
- "vec4 get_%s()\n"
- "{\n"
- " vec3 pos = vec3 (%s_texcoords, %s_radius_0);\n"
- " \n"
- " float B = dot (pos, %s_circle_d);\n"
- " float C = dot (pos, vec3 (pos.xy, -pos.z));\n"
- " \n"
- " float det = dot (vec2 (B, %s_a), vec2 (B, -C));\n"
- " float sqrtdet = sqrt (abs (det));\n"
- " vec2 t = (B + vec2 (sqrtdet, -sqrtdet)) / %s_a;\n"
- " \n"
- " vec2 is_valid = step (vec2 (-%s_radius_0), t * %s_circle_d.z);\n"
- " float has_color = step (0., det) * max (is_valid.x, is_valid.y);\n"
- " \n"
- " float upper_t = mix (t.y, t.x, is_valid.x);\n"
- " vec4 texel = texture2D%s (%s_sampler, %s_wrap (vec2(upper_t, 0.5)));\n"
- " return mix (vec4 (0.0), texel, has_color);\n"
- "}\n",
- namestr, rectstr, namestr, namestr, namestr, namestr,
- namestr, namestr, namestr, namestr, namestr,
- namestr, namestr, namestr, rectstr, namestr, namestr);
+ if (needs_glsl330 == CAIRO_GLSL_VERSION_330) {
+ _cairo_output_stream_printf (stream,
+ "in vec2 %s_texcoords;\n"
+ "uniform sampler2D%s %s_sampler;\n"
+ "uniform vec3 %s_circle_d;\n"
+ "uniform float %s_a;\n"
+ "uniform float %s_radius_0;\n"
+ "\n"
+ "vec4 get_%s()\n"
+ "{\n"
+ " vec3 pos = vec3 (%s_texcoords, %s_radius_0);\n"
+ " \n"
+ " float B = dot (pos, %s_circle_d);\n"
+ " float C = dot (pos, vec3 (pos.xy, -pos.z));\n"
+ " \n"
+ " float det = dot (vec2 (B, %s_a), vec2 (B, -C));\n"
+ " float sqrtdet = sqrt (abs (det));\n"
+ " vec2 t = (B + vec2 (sqrtdet, -sqrtdet)) / %s_a;\n"
+ " \n"
+ " vec2 is_valid = step (vec2 (-%s_radius_0), t * %s_circle_d.z);\n"
+ " float has_color = step (0., det) * max (is_valid.x, is_valid.y);\n"
+ " \n"
+ " float upper_t = mix (t.y, t.x, is_valid.x);\n"
+ " vec4 texel = texture%s%s (%s_sampler, %s_wrap (vec2(upper_t, 0.5)));\n"
+ " return mix (vec4 (0.0), texel, has_color);\n"
+ "}\n",
+ namestr, rectstr, namestr, namestr, namestr, namestr,
+ namestr, namestr, namestr, namestr, namestr,
+ namestr, namestr, namestr, textstr, rectstr, namestr, namestr);
+ } else {
+ _cairo_output_stream_printf (stream,
+ "varying vec2 %s_texcoords;\n"
+ "uniform sampler2D%s %s_sampler;\n"
+ "uniform vec3 %s_circle_d;\n"
+ "uniform float %s_a;\n"
+ "uniform float %s_radius_0;\n"
+ "\n"
+ "vec4 get_%s()\n"
+ "{\n"
+ " vec3 pos = vec3 (%s_texcoords, %s_radius_0);\n"
+ " \n"
+ " float B = dot (pos, %s_circle_d);\n"
+ " float C = dot (pos, vec3 (pos.xy, -pos.z));\n"
+ " \n"
+ " float det = dot (vec2 (B, %s_a), vec2 (B, -C));\n"
+ " float sqrtdet = sqrt (abs (det));\n"
+ " vec2 t = (B + vec2 (sqrtdet, -sqrtdet)) / %s_a;\n"
+ " \n"
+ " vec2 is_valid = step (vec2 (-%s_radius_0), t * %s_circle_d.z);\n"
+ " float has_color = step (0., det) * max (is_valid.x, is_valid.y);\n"
+ " \n"
+ " float upper_t = mix (t.y, t.x, is_valid.x);\n"
+ " vec4 texel = texture%s%s (%s_sampler, %s_wrap (vec2(upper_t, 0.5)));\n"
+ " return mix (vec4 (0.0), texel, has_color);\n"
+ "}\n",
+ namestr, rectstr, namestr, namestr, namestr, namestr,
+ namestr, namestr, namestr, namestr, namestr,
+ namestr, namestr, namestr, textstr, rectstr, namestr, namestr);
+ }
break;
}
}
@@ -962,21 +1152,13 @@ cairo_gl_shader_get_fragment_source (cairo_gl_context_t *ctx,
cairo_status_t status;
const char *coverage_str;
- // dy5.kim: Use highp only for gradients to handle the following test case
- // http://w3c-test.org/html/tests/approved/canvas/2d.gradient.radial.touch1.html
- if (src->type == CAIRO_GL_OPERAND_LINEAR_GRADIENT ||
- src->type == CAIRO_GL_OPERAND_RADIAL_GRADIENT_A0 ||
- src->type == CAIRO_GL_OPERAND_RADIAL_GRADIENT_NONE ||
- src->type == CAIRO_GL_OPERAND_RADIAL_GRADIENT_EXT)
- _cairo_output_stream_printf (stream,
- "#ifdef GL_ES\n"
- "precision highp float;\n"
- "#endif\n");
- else
- _cairo_output_stream_printf (stream,
- "#ifdef GL_ES\n"
- "precision mediump float;\n"
- "#endif\n");
+ if (_cairo_needs_glsl330 (ctx))
+ _cairo_output_stream_printf (stream, "#version 330\n");
+
+ _cairo_output_stream_printf (stream,
+ "#ifdef GL_ES\n"
+ "precision mediump float;\n"
+ "#endif\n");
_cairo_gl_shader_emit_wrap (ctx, stream, src, CAIRO_GL_TEX_SOURCE);
_cairo_gl_shader_emit_wrap (ctx, stream, mask, CAIRO_GL_TEX_MASK);
@@ -994,10 +1176,17 @@ cairo_gl_shader_get_fragment_source (cairo_gl_context_t *ctx,
coverage_str = "";
if (use_coverage) {
- _cairo_output_stream_printf (stream, "varying float coverage;\n");
+ if (_cairo_needs_glsl330 (ctx)) {
+ _cairo_output_stream_printf (stream, "in float coverage;\n");
+ } else {
+ _cairo_output_stream_printf (stream, "varying float coverage;\n");
+ }
coverage_str = " * coverage";
}
+ if (_cairo_needs_glsl330 (ctx))
+ _cairo_output_stream_printf (stream, "out vec4 fsColorOut;\n");
+
_cairo_output_stream_printf (stream,
"void main()\n"
"{\n");
@@ -1006,19 +1195,34 @@ cairo_gl_shader_get_fragment_source (cairo_gl_context_t *ctx,
default:
ASSERT_NOT_REACHED;
case CAIRO_GL_SHADER_IN_NORMAL:
- _cairo_output_stream_printf (stream,
- " gl_FragColor = get_source() * get_mask().a%s;\n",
- coverage_str);
+ if (_cairo_needs_glsl330 (ctx))
+ _cairo_output_stream_printf (stream,
+ " fsColorOut = get_source() * get_mask().a%s;\n",
+ coverage_str);
+ else
+ _cairo_output_stream_printf (stream,
+ " gl_FragColor = get_source() * get_mask().a%s;\n",
+ coverage_str);
break;
case CAIRO_GL_SHADER_IN_CA_SOURCE:
- _cairo_output_stream_printf (stream,
- " gl_FragColor = get_source() * get_mask()%s;\n",
- coverage_str);
+ if (_cairo_needs_glsl330 (ctx))
+ _cairo_output_stream_printf (stream,
+ " fsColorOut = get_source() * get_mask()%s;\n",
+ coverage_str);
+ else
+ _cairo_output_stream_printf (stream,
+ " gl_FragColor = get_source() * get_mask()%s;\n",
+ coverage_str);
break;
case CAIRO_GL_SHADER_IN_CA_SOURCE_ALPHA:
- _cairo_output_stream_printf (stream,
- " gl_FragColor = get_source().a * get_mask()%s;\n",
- coverage_str);
+ if (_cairo_needs_glsl330 (ctx))
+ _cairo_output_stream_printf (stream,
+ " fsColorOut = get_source().a * get_mask()%s;\n",
+ coverage_str);
+ else
+ _cairo_output_stream_printf (stream,
+ " gl_FragColor = get_source().a * get_mask()%s;\n",
+ coverage_str);
break;
}
@@ -1026,10 +1230,8 @@ cairo_gl_shader_get_fragment_source (cairo_gl_context_t *ctx,
"}\n\0", 3);
status = _cairo_memory_stream_destroy (stream, &source, &length);
- if (unlikely (status)) {
- free (source);
+ if (unlikely (status))
return status;
- }
*out = (char *) source;
return CAIRO_STATUS_SUCCESS;
@@ -1133,6 +1335,22 @@ link_shader_program (cairo_gl_context_t *ctx,
ASSERT_NOT_REACHED;
}
+static GLint
+_cairo_gl_get_op_uniform_location(cairo_gl_context_t *ctx,
+ cairo_gl_shader_t *shader,
+ cairo_gl_tex_t tex_unit,
+ const char *suffix)
+{
+ cairo_gl_dispatch_t *dispatch = &ctx->dispatch;
+ char uniform_name[100];
+ const char *unit_name[2] = { "source", "mask" };
+
+ snprintf (uniform_name, sizeof (uniform_name), "%s_%s",
+ unit_name[tex_unit], suffix);
+
+ return dispatch->GetUniformLocation (shader->program, uniform_name);
+}
+
static cairo_status_t
_cairo_gl_shader_compile_and_link (cairo_gl_context_t *ctx,
cairo_gl_shader_t *shader,
@@ -1145,8 +1363,12 @@ _cairo_gl_shader_compile_and_link (cairo_gl_context_t *ctx,
cairo_bool_t src_use_atlas,
cairo_bool_t mask_use_atlas)
{
+ cairo_gl_dispatch_t *dispatch = &ctx->dispatch;
unsigned int vertex_shader;
cairo_status_t status;
+ int i;
+
+ _cairo_needs_glsl330 (ctx);
assert (shader->program == 0);
@@ -1167,12 +1389,14 @@ _cairo_gl_shader_compile_and_link (cairo_gl_context_t *ctx,
use_coverage,
CAIRO_GL_VAR_NONE,
&source);
- if (unlikely (status))
- goto FAILURE;
+ if (unlikely (status))
+ goto FAILURE;
+
+ printf ("\n\n======= vertex source ========\n%s\n\n", source);
compile_shader (ctx, &ctx->vertex_shaders[vertex_shader],
GL_VERTEX_SHADER, source);
- free (source);
+ free (source);
}
compile_shader (ctx, &shader->fragment_shader,
@@ -1182,6 +1406,37 @@ _cairo_gl_shader_compile_and_link (cairo_gl_context_t *ctx,
ctx->vertex_shaders[vertex_shader],
shader->fragment_shader);
+ shader->mvp_location =
+ dispatch->GetUniformLocation (shader->program,
+ "ModelViewProjectionMatrix");
+
+ for (i = 0; i < 2; i++) {
+ shader->constant_location[i] =
+ _cairo_gl_get_op_uniform_location (ctx, shader, i, "constant");
+ shader->a_location[i] =
+ _cairo_gl_get_op_uniform_location (ctx, shader, i, "a");
+ shader->circle_d_location[i] =
+ _cairo_gl_get_op_uniform_location (ctx, shader, i, "circle_d");
+ shader->radius_0_location[i] =
+ _cairo_gl_get_op_uniform_location (ctx, shader, i, "radius_0");
+ shader->texdims_location[i] =
+ _cairo_gl_get_op_uniform_location (ctx, shader, i, "texdims");
+ shader->texgen_location[i] =
+ _cairo_gl_get_op_uniform_location (ctx, shader, i, "texgen");
+ shader->blur_radius_location[i] =
+ _cairo_gl_get_op_uniform_location (ctx, shader, i, "blur_radius");
+ shader->blurs_location[i] =
+ _cairo_gl_get_op_uniform_location (ctx, shader, i, "blurs");
+ shader->blur_step_location[i] =
+ _cairo_gl_get_op_uniform_location (ctx, shader, i, "blur_step");
+ shader->blur_x_axis_location[i] =
+ _cairo_gl_get_op_uniform_location (ctx, shader, i, "blur_x_axis");
+ shader->blur_y_axis_location[i] =
+ _cairo_gl_get_op_uniform_location (ctx, shader, i, "blur_y_axis");
+ shader->alpha_location[i] =
+ _cairo_gl_get_op_uniform_location (ctx, shader, i, "alpha");
+ }
+
return CAIRO_STATUS_SUCCESS;
FAILURE:
@@ -1211,14 +1466,12 @@ _cairo_gl_shader_set_samplers (cairo_gl_context_t *ctx,
dispatch->GetIntegerv (GL_CURRENT_PROGRAM, &saved_program);
dispatch->UseProgram (shader->program);
- location = _cairo_gl_shader_get_uniform_location (ctx, shader,
- CAIRO_GL_UNIFORM_SAMPLER);
+ location = dispatch->GetUniformLocation (shader->program, "source_sampler");
if (location != -1) {
dispatch->Uniform1i (location, CAIRO_GL_TEX_SOURCE);
}
- location = _cairo_gl_shader_get_uniform_location (ctx, shader,
- CAIRO_GL_UNIFORM_MASK_SAMPLER);
+ location = dispatch->GetUniformLocation (shader->program, "mask_sampler");
if (location != -1) {
dispatch->Uniform1i (location, CAIRO_GL_TEX_MASK);
}
@@ -1228,96 +1481,74 @@ _cairo_gl_shader_set_samplers (cairo_gl_context_t *ctx,
void
_cairo_gl_shader_bind_float (cairo_gl_context_t *ctx,
- cairo_gl_uniform_t uniform,
+ GLint location,
float value)
{
cairo_gl_dispatch_t *dispatch = &ctx->dispatch;
- GLint location = _cairo_gl_shader_get_uniform_location (ctx,
- ctx->current_shader,
- uniform);
assert (location != -1);
dispatch->Uniform1f (location, value);
}
void
_cairo_gl_shader_bind_int (cairo_gl_context_t *ctx,
- cairo_gl_uniform_t uniform,
+ GLint location,
int value)
{
cairo_gl_dispatch_t *dispatch = &ctx->dispatch;
- GLint location = _cairo_gl_shader_get_uniform_location (ctx,
- ctx->current_shader,
- uniform);
assert (location != -1);
dispatch->Uniform1i (location, value);
}
void
_cairo_gl_shader_bind_float_array (cairo_gl_context_t *ctx,
- cairo_gl_uniform_t uniform,
+ GLint location,
int num, float *values)
{
cairo_gl_dispatch_t *dispatch = &ctx->dispatch;
- GLint location = _cairo_gl_shader_get_uniform_location (ctx,
- ctx->current_shader,
- uniform);
assert (location != -1);
dispatch->Uniform1fv (location, num, values);
}
void
_cairo_gl_shader_bind_vec2 (cairo_gl_context_t *ctx,
- cairo_gl_uniform_t uniform,
+ GLint location,
float value0,
float value1)
{
cairo_gl_dispatch_t *dispatch = &ctx->dispatch;
- GLint location = _cairo_gl_shader_get_uniform_location (ctx,
- ctx->current_shader,
- uniform);
assert (location != -1);
dispatch->Uniform2f (location, value0, value1);
}
void
_cairo_gl_shader_bind_vec3 (cairo_gl_context_t *ctx,
- cairo_gl_uniform_t uniform,
+ GLint location,
float value0,
float value1,
float value2)
{
cairo_gl_dispatch_t *dispatch = &ctx->dispatch;
- GLint location = _cairo_gl_shader_get_uniform_location (ctx,
- ctx->current_shader,
- uniform);
assert (location != -1);
dispatch->Uniform3f (location, value0, value1, value2);
}
void
_cairo_gl_shader_bind_vec4 (cairo_gl_context_t *ctx,
- cairo_gl_uniform_t uniform,
+ GLint location,
float value0, float value1,
float value2, float value3)
{
cairo_gl_dispatch_t *dispatch = &ctx->dispatch;
- GLint location = _cairo_gl_shader_get_uniform_location (ctx,
- ctx->current_shader,
- uniform);
assert (location != -1);
dispatch->Uniform4f (location, value0, value1, value2, value3);
}
void
_cairo_gl_shader_bind_matrix (cairo_gl_context_t *ctx,
- cairo_gl_uniform_t uniform,
+ GLint location,
const cairo_matrix_t* m)
{
cairo_gl_dispatch_t *dispatch = &ctx->dispatch;
- GLint location = _cairo_gl_shader_get_uniform_location (ctx,
- ctx->current_shader,
- uniform);
-
float gl_m[9] = {
m->xx, m->yx, 0,
m->xy, m->yy, 0,
@@ -1329,13 +1560,9 @@ _cairo_gl_shader_bind_matrix (cairo_gl_context_t *ctx,
void
_cairo_gl_shader_bind_matrix4f (cairo_gl_context_t *ctx,
- cairo_gl_uniform_t uniform,
- GLfloat* gl_m)
+ GLint location, GLfloat* gl_m)
{
cairo_gl_dispatch_t *dispatch = &ctx->dispatch;
- GLint location = _cairo_gl_shader_get_uniform_location (ctx,
- ctx->current_shader,
- uniform);
assert (location != -1);
dispatch->UniformMatrix4fv (location, 1, GL_FALSE, gl_m);
}
@@ -1411,6 +1638,8 @@ _cairo_gl_get_shader_by_type (cairo_gl_context_t *ctx,
if (unlikely (status))
return status;
+ printf ("\n\n======= fragment source ========\n%s\n\n", fs_source);
+
entry = malloc (sizeof (cairo_shader_cache_entry_t));
if (unlikely (entry == NULL)) {
free (fs_source);
diff --git a/src/cairo-gl-source.c b/src/cairo-gl-source.c
index 53c3ed35a..53c3ed35a 100755..100644
--- a/src/cairo-gl-source.c
+++ b/src/cairo-gl-source.c
diff --git a/src/cairo-gl-spans-compositor.c b/src/cairo-gl-spans-compositor.c
index 724ae6661..df337404e 100755..100644
--- a/src/cairo-gl-spans-compositor.c
+++ b/src/cairo-gl-spans-compositor.c
@@ -299,9 +299,6 @@ draw_image_boxes (void *_dst,
struct _cairo_boxes_chunk *chunk;
int i;
- if (_cairo_gl_surface_is_texture (dst))
- return CAIRO_INT_STATUS_UNSUPPORTED;
-
for (chunk = &boxes->chunks; chunk; chunk = chunk->next) {
for (i = 0; i < chunk->count; i++) {
cairo_box_t *b = &chunk->base[i];
diff --git a/src/cairo-gl-surface-legacy.c b/src/cairo-gl-surface-legacy.c
index 92b27c905..92b27c905 100755..100644
--- a/src/cairo-gl-surface-legacy.c
+++ b/src/cairo-gl-surface-legacy.c
diff --git a/src/cairo-gl-surface.c b/src/cairo-gl-surface.c
index ac19a13ad..665ab244a 100755..100644
--- a/src/cairo-gl-surface.c
+++ b/src/cairo-gl-surface.c
@@ -76,7 +76,7 @@ _cairo_gl_surface_shadow_surface (void *surface,
return NULL;
shadow_surface = ctx->shadow_scratch_surfaces[0];
-
+
if (shadow_surface) {
shadow_width = shadow_surface->width;
shadow_height = shadow_surface->height;
@@ -258,7 +258,7 @@ _cairo_gl_surface_glyph_shadow_surface (void *surface,
shadow_surface = ctx->shadow_scratch_surfaces[1];
else
shadow_surface = ctx->shadow_scratch_surfaces[2];
-
+
if (shadow_surface) {
shadow_width = shadow_surface->width;
shadow_height = shadow_surface->height;
@@ -273,7 +273,7 @@ _cairo_gl_surface_glyph_shadow_surface (void *surface,
if (! shadow_surface) {
shadow_surface = (cairo_gl_surface_t *)
_cairo_gl_surface_create_scratch (ctx,
- CAIRO_CONTENT_COLOR_ALPHA,
+ CAIRO_CONTENT_COLOR_ALPHA,
width, height);
if (unlikely (shadow_surface->base.status)) {
cairo_surface_destroy (&shadow_surface->base);
@@ -309,10 +309,10 @@ _cairo_gl_surface_glyph_shadow_mask_surface (void *surface,
return NULL;
mask_surface = ctx->shadow_masks[index + 2];
-
+
if (mask_surface) {
if (mask_surface->width != width ||
- mask_surface->height != height) {
+ mask_surface->height != height) {
cairo_surface_destroy (&mask_surface->base);
mask_surface = NULL;
ctx->shadow_masks[index + 2] = NULL;
@@ -542,6 +542,9 @@ _cairo_gl_get_image_format_and_type_gl (pixman_format_code_t pixman_format,
*type = GL_UNSIGNED_BYTE;
return TRUE;
+#if PIXMAN_VERSION >= PIXMAN_VERSION_ENCODE(0,27,2)
+ case PIXMAN_a8r8g8b8_sRGB:
+#endif
case PIXMAN_a2b10g10r10:
case PIXMAN_x2b10g10r10:
case PIXMAN_a4r4g4b4:
@@ -690,17 +693,32 @@ _cairo_gl_surface_init (cairo_device_t *device,
_cairo_gl_surface_embedded_operand_init (surface);
}
+static cairo_bool_t
+_cairo_gl_surface_size_valid_for_context (cairo_gl_context_t *ctx,
+ int width, int height)
+{
+ return width > 0 && height > 0 &&
+ width <= ctx->max_framebuffer_size &&
+ height <= ctx->max_framebuffer_size;
+}
+
+static cairo_bool_t
+_cairo_gl_surface_size_valid (cairo_gl_surface_t *surface,
+ int width, int height)
+{
+ cairo_gl_context_t *ctx = (cairo_gl_context_t *)surface->base.device;
+ return _cairo_gl_surface_size_valid_for_context (ctx, width, height);
+}
+
static cairo_surface_t *
_cairo_gl_surface_create_scratch_for_texture (cairo_gl_context_t *ctx,
cairo_content_t content,
GLuint tex,
int width,
- int height,
- cairo_bool_t set_tex_param)
+ int height)
{
cairo_gl_surface_t *surface;
- assert (width <= ctx->max_framebuffer_size && height <= ctx->max_framebuffer_size);
surface = calloc (1, sizeof (cairo_gl_surface_t));
if (unlikely (surface == NULL))
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
@@ -713,12 +731,10 @@ _cairo_gl_surface_create_scratch_for_texture (cairo_gl_context_t *ctx,
surface->supports_stencil = TRUE;
/* Create the texture used to store the surface's data. */
- if (!set_tex_param) {
_cairo_gl_context_activate (ctx, CAIRO_GL_TEX_TEMP);
ctx->dispatch.BindTexture (ctx->tex_target, surface->tex);
ctx->dispatch.TexParameteri (ctx->tex_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
ctx->dispatch.TexParameteri (ctx->tex_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- }
return &surface->base;
}
@@ -737,7 +753,7 @@ _create_scratch_internal (cairo_gl_context_t *ctx,
ctx->dispatch.GenTextures (1, &tex);
surface = (cairo_gl_surface_t *)
_cairo_gl_surface_create_scratch_for_texture (ctx, content,
- tex, width, height, FALSE);
+ tex, width, height);
if (unlikely (surface->base.status))
return &surface->base;
@@ -753,7 +769,7 @@ _create_scratch_internal (cairo_gl_context_t *ctx,
default:
ASSERT_NOT_REACHED;
case CAIRO_CONTENT_COLOR_ALPHA:
- if (ctx->can_read_bgra)
+ if(ctx->can_read_bgra)
format = GL_BGRA;
else
format = GL_RGBA;
@@ -762,7 +778,7 @@ _create_scratch_internal (cairo_gl_context_t *ctx,
/* When using GL_ALPHA, compositing doesn't work properly, but for
* caching surfaces, we are just uploading pixel data, so it isn't
* an issue. */
- if (for_caching)
+ if (for_caching && !ctx->is_gl33)
format = GL_ALPHA;
else
format = GL_RGBA;
@@ -776,7 +792,7 @@ _create_scratch_internal (cairo_gl_context_t *ctx,
* specified. So, we have to store RGBA, and fill the alpha
* channel with 1 when blending.
*/
- if (ctx->can_read_bgra)
+ if(ctx->can_read_bgra)
format = GL_BGRA;
else
format = GL_RGBA;
@@ -785,7 +801,7 @@ _create_scratch_internal (cairo_gl_context_t *ctx,
ctx->dispatch.TexImage2D (ctx->tex_target, 0, format,
width, height, 0,
- format, GL_UNSIGNED_BYTE, NULL);
+ format, GL_UNSIGNED_BYTE, NULL);
return &surface->base;
}
@@ -861,15 +877,14 @@ _cairo_gl_surface_clear (cairo_gl_surface_t *surface,
}
/* optimize for mobile gl driver with deferred rendering */
- if (surface->clip_on_stencil_buffer ||
- ctx->gl_flavor == CAIRO_GL_FLAVOR_DESKTOP)
+ if (ctx->gl_flavor == CAIRO_GL_FLAVOR_DESKTOP)
ctx->dispatch.Clear (GL_COLOR_BUFFER_BIT);
else {
- if (surface->clip_on_stencil_buffer) {
- _cairo_clip_destroy(surface->clip_on_stencil_buffer);
- surface->clip_on_stencil_buffer = NULL;
- }
- ctx->dispatch.Clear (GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ if (surface->clip_on_stencil_buffer) {
+ _cairo_clip_destroy (surface->clip_on_stencil_buffer);
+ surface->clip_on_stencil_buffer = NULL;
+ }
+ ctx->dispatch.Clear (GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
if (a == 0)
@@ -931,6 +946,11 @@ cairo_gl_surface_create (cairo_device_t *abstract_device,
if (unlikely (status))
return _cairo_surface_create_in_error (status);
+ if (! _cairo_gl_surface_size_valid_for_context (ctx, width, height)) {
+ status = _cairo_gl_context_release (ctx, status);
+ return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_SIZE));
+ }
+
surface = (cairo_gl_surface_t *)
_cairo_gl_surface_create_and_clear_scratch (ctx, content, width, height);
if (unlikely (surface->base.status)) {
@@ -1003,9 +1023,14 @@ cairo_gl_surface_create_for_texture (cairo_device_t *abstract_device,
if (unlikely (status))
return _cairo_surface_create_in_error (status);
+ if (! _cairo_gl_surface_size_valid_for_context (ctx, width, height)) {
+ status = _cairo_gl_context_release (ctx, status);
+ return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_SIZE));
+ }
+
surface = (cairo_gl_surface_t *)
_cairo_gl_surface_create_scratch_for_texture (ctx, content,
- tex, width, height, TRUE);
+ tex, width, height);
status = _cairo_gl_context_release (ctx, status);
return &surface->base;
@@ -1090,7 +1115,6 @@ cairo_gl_surface_swapbuffers (cairo_surface_t *abstract_surface)
status = _cairo_gl_context_acquire (surface->base.device, &ctx);
if (unlikely (status))
return;
-
/* And in any case we should flush any pending operations. */
_cairo_gl_composite_flush (ctx);
@@ -1099,7 +1123,7 @@ cairo_gl_surface_swapbuffers (cairo_surface_t *abstract_surface)
ctx->swap_buffers (ctx, surface);
- /* according to khronos specs on egl 1.4, stencil buffer is
+ /* according to khronos specs on egl 1.4, stencil buffer is
* not preserved after eglSwapBuffers */
if (surface->clip_on_stencil_buffer) {
_cairo_clip_destroy (surface->clip_on_stencil_buffer);
@@ -1112,16 +1136,6 @@ cairo_gl_surface_swapbuffers (cairo_surface_t *abstract_surface)
}
}
-static cairo_bool_t
-_cairo_gl_surface_size_valid (cairo_gl_surface_t *surface,
- int width, int height)
-{
- cairo_gl_context_t *ctx = (cairo_gl_context_t *)surface->base.device;
- return width > 0 && height > 0 &&
- width <= ctx->max_framebuffer_size &&
- height <= ctx->max_framebuffer_size;
-}
-
static cairo_surface_t *
_cairo_gl_surface_create_similar (void *abstract_surface,
cairo_content_t content,
@@ -1214,8 +1228,10 @@ _cairo_gl_surface_draw_image (cairo_gl_surface_t *dst,
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;
+ if (src->pixman_format != pixman_format) {
+ if (!ctx->can_read_bgra)
+ require_conversion = TRUE;
+ }
}
else if (dst->base.content != CAIRO_CONTENT_ALPHA)
require_conversion = TRUE;
@@ -1227,6 +1243,7 @@ _cairo_gl_surface_draw_image (cairo_gl_surface_t *dst,
}
if (require_conversion) {
+ src->base.is_clear = FALSE;
rgba_clone = (cairo_image_surface_t *)
_cairo_image_surface_create_with_pixman_format (NULL,
pixman_format,
@@ -1246,7 +1263,32 @@ _cairo_gl_surface_draw_image (cairo_gl_surface_t *dst,
src = rgba_clone;
}
- }
+ } else if (ctx->is_gl33 && src->base.content == CAIRO_CONTENT_ALPHA) {
+ /* use RGBA for ALPHA */
+ pixman_format_code_t pixman_format;
+ cairo_surface_pattern_t pattern;
+ src->base.is_clear = FALSE;
+ pixman_format = _cairo_is_little_endian () ? PIXMAN_a8b8g8r8 : PIXMAN_r8g8b8a8;
+
+ 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,
@@ -1311,6 +1353,9 @@ _cairo_gl_surface_draw_image (cairo_gl_surface_t *dst,
}
else
{
+ /* When cpp != 4, setting GL_UNPACK_ALIGNMENT to cpp
+ causes many failures in cairo tests with respect to
+ GLESV2 */
ctx->dispatch.PixelStorei (GL_UNPACK_ALIGNMENT, 4);
if (ctx->gl_flavor == CAIRO_GL_FLAVOR_DESKTOP ||
ctx->gl_flavor == CAIRO_GL_FLAVOR_ES3)
@@ -1320,18 +1365,18 @@ _cairo_gl_surface_draw_image (cairo_gl_surface_t *dst,
/* 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;
- }
+ if (unlikely (status)) {
+ free (data_start_gles2);
+ goto FAIL;
+ }
_cairo_gl_context_activate (ctx, CAIRO_GL_TEX_TEMP);
ctx->dispatch.BindTexture (ctx->tex_target, dst->tex);
ctx->dispatch.TexParameteri (ctx->tex_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
ctx->dispatch.TexParameteri (ctx->tex_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
ctx->dispatch.TexSubImage2D (ctx->tex_target, 0,
- dst_x, dst_y, width, height,
- format, type, data_start);
+ dst_x, dst_y, width, height,
+ format, type, data_start);
free (data_start_gles2);
@@ -1498,8 +1543,8 @@ _cairo_gl_surface_map_to_image (void *abstract_surface,
return NULL;
}
- if (_cairo_gl_surface_flavor (surface) == CAIRO_GL_FLAVOR_ES2 ||
- _cairo_gl_surface_flavor (surface) == CAIRO_GL_FLAVOR_ES3) {
+ /*if (_cairo_gl_surface_flavor (surface) == CAIRO_GL_FLAVOR_ES2 ||
+ _cairo_gl_surface_flavor (surface) == CAIRO_GL_FLAVOR_ES3)*/ {
/* 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
@@ -1538,11 +1583,11 @@ _cairo_gl_surface_map_to_image (void *abstract_surface,
/* If the original surface has not been modified or
* is clear, we can avoid downloading data. */
- if (surface->base.is_clear || surface->base.serial == 0) {
+/* if (surface->base.is_clear || surface->base.serial == 0) {
status = _cairo_gl_context_release (ctx, status);
return image;
}
-
+*/
/* This is inefficient, as we'd rather just read the thing without making
* it the destination. But then, this is the fallback path, so let's not
* fall back instead.
@@ -1554,10 +1599,11 @@ _cairo_gl_surface_map_to_image (void *abstract_surface,
flipped = ! _cairo_gl_surface_is_texture (surface);
mesa_invert = flipped && ctx->has_mesa_pack_invert;
- ctx->dispatch.PixelStorei (GL_PACK_ALIGNMENT, 4);
+ ctx->dispatch.PixelStorei (GL_PACK_ALIGNMENT, cpp);
if (ctx->gl_flavor == CAIRO_GL_FLAVOR_DESKTOP ||
ctx->gl_flavor == CAIRO_GL_FLAVOR_ES3)
ctx->dispatch.PixelStorei (GL_PACK_ROW_LENGTH, image->stride / cpp);
+
if (mesa_invert)
ctx->dispatch.PixelStorei (GL_PACK_INVERT_MESA, 1);
@@ -1566,8 +1612,9 @@ _cairo_gl_surface_map_to_image (void *abstract_surface,
y = surface->height - extents->y - extents->height;
ctx->dispatch.ReadPixels (extents->x, y,
- extents->width, extents->height,
- format, type, image->data);
+ extents->width, extents->height,
+ format, type, image->data);
+
if (mesa_invert)
ctx->dispatch.PixelStorei (GL_PACK_INVERT_MESA, 0);
@@ -1707,9 +1754,10 @@ _cairo_gl_surface_flush (void *abstract_surface, unsigned flags)
_cairo_gl_composite_flush (ctx);
status = _cairo_gl_surface_resolve_multisampling (surface);
-
+#if 0
if (ctx->msaa_type != CAIRO_GL_NONE_MULTISAMPLE_TO_TEXTURE)
- ctx->dispatch.Flush ();
+ ctx->dispatch.Flush ();
+#endif
return _cairo_gl_context_release (ctx, status);
}
@@ -1772,7 +1820,7 @@ _cairo_gl_surface_paint (void *surface,
&source->shadow);
ctx->source_scratch_in_use = FALSE;
if (unlikely (status)) {
- cairo_device_release (dst->base.device);
+ cairo_device_release (dst->base.device);
return status;
}
@@ -1781,13 +1829,12 @@ _cairo_gl_surface_paint (void *surface,
dst->content_changed = TRUE;
dst->content_synced = FALSE;
}
-
+
ctx->source_scratch_in_use = FALSE;
cairo_device_release (dst->base.device);
return status;
}
-#if 0 // Currently glClear does not get flushed to GPU so do not use this fast path for the time being
/* simplify the common case of clearing the surface */
if (clip == NULL) {
if (op == CAIRO_OPERATOR_CLEAR) {
@@ -1800,11 +1847,10 @@ _cairo_gl_surface_paint (void *surface,
(op == CAIRO_OPERATOR_OVER && _cairo_pattern_is_opaque_solid (source)))) {
status = _cairo_gl_surface_clear (surface,
&((cairo_solid_pattern_t *) source)->color);
- cairo_device_release (dst->base.device);
+ cairo_device_release (dst->base.device);
return status;
}
}
-#endif
status = _cairo_compositor_paint (get_compositor (surface), surface,
op, source, clip);
@@ -1812,7 +1858,7 @@ _cairo_gl_surface_paint (void *surface,
dst->content_changed = TRUE;
dst->content_synced = FALSE;
}
-
+
ctx->source_scratch_in_use = FALSE;
cairo_device_release (dst->base.device);
return status;
@@ -1837,7 +1883,7 @@ _cairo_gl_surface_mask (void *surface,
&source->shadow);
ctx->source_scratch_in_use = FALSE;
if (unlikely (status)) {
- cairo_device_release (dst->base.device);
+ cairo_device_release (dst->base.device);
return status;
}
@@ -1845,8 +1891,8 @@ _cairo_gl_surface_mask (void *surface,
if (status == CAIRO_INT_STATUS_SUCCESS) {
dst->content_changed = TRUE;
dst->content_synced = FALSE;
- }
-
+ }
+
ctx->source_scratch_in_use = FALSE;
cairo_device_release (dst->base.device);
return status;
@@ -1857,7 +1903,7 @@ _cairo_gl_surface_mask (void *surface,
if (status == CAIRO_INT_STATUS_SUCCESS) {
dst->content_changed = TRUE;
dst->content_synced = FALSE;
-
+
ctx->source_scratch_in_use = FALSE;
cairo_device_release (dst->base.device);
return status;
@@ -2016,7 +2062,6 @@ _cairo_gl_surface_fill (void *surface,
ctx->source_scratch_in_use = FALSE;
cairo_device_release (dst->base.device);
-
return status;
}
diff --git a/src/cairo-gl-traps-compositor.c b/src/cairo-gl-traps-compositor.c
index 022a37d77..4e95e9a57 100755..100644
--- a/src/cairo-gl-traps-compositor.c
+++ b/src/cairo-gl-traps-compositor.c
@@ -84,9 +84,6 @@ draw_image_boxes (void *_dst,
struct _cairo_boxes_chunk *chunk;
int i;
- if (_cairo_gl_surface_is_texture (dst))
- return CAIRO_INT_STATUS_UNSUPPORTED;
-
for (chunk = &boxes->chunks; chunk; chunk = chunk->next) {
for (i = 0; i < chunk->count; i++) {
cairo_box_t *b = &chunk->base[i];
@@ -268,7 +265,6 @@ lerp (void *dst,
0, 0,
dst_x, dst_y,
width, height);
-
if (unlikely (status))
return status;
@@ -284,27 +280,26 @@ lerp (void *dst,
}
static cairo_int_status_t
-lerp_color_glyph (void *dst,
- cairo_surface_t *src,
- cairo_surface_t *mask,
- int src_x,
- int src_y,
- int mask_x,
- int mask_y,
- int dst_x,
- int dst_y,
- unsigned int width,
- unsigned int height)
+lerp_color_glyph (void *dst,
+ cairo_surface_t *src,
+ cairo_surface_t *mask,
+ int src_x,
+ int src_y,
+ int mask_x,
+ int mask_y,
+ int dst_x,
+ int dst_y,
+ unsigned int width,
+ unsigned int height)
{
- cairo_int_status_t status;
+ cairo_int_status_t status;
- /*we could avoid some repetition... */
+ /* we could avoid some repetition... */
status = composite (dst, CAIRO_OPERATOR_DEST_OUT, mask, src,
mask_x, mask_y,
0, 0,
dst_x, dst_y,
width, height);
-
if (unlikely (status))
return status;
@@ -351,44 +346,12 @@ traps_to_operand (void *_dst,
return status;
}
- /* GLES2 only supports RGB/RGBA when uploading */
-#if 0
- if (_cairo_gl_get_flavor () == CAIRO_GL_FLAVOR_ES2) {
- 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)) {
- cairo_surface_destroy (image);
- 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;
- }
- }
-#endif
-
- mask = _cairo_surface_create_similar_scratch (_dst,
- CAIRO_CONTENT_COLOR_ALPHA,
- extents->width,
- extents->height);
+ mask = _cairo_surface_create_scratch (_dst,
+ CAIRO_CONTENT_COLOR_ALPHA,
+ extents->width,
+ extents->height,
+ NULL);
+
if (unlikely (mask->status)) {
cairo_surface_destroy (image);
return mask->status;
@@ -419,7 +382,7 @@ traps_to_operand (void *_dst,
if (unlikely (status))
goto error;
- operand->texture.owns_surface = mask;
+ operand->texture.owns_surface = (cairo_gl_surface_t *)mask;
return CAIRO_STATUS_SUCCESS;
error:
@@ -442,42 +405,42 @@ composite_traps (void *_dst,
cairo_gl_composite_t setup;
cairo_gl_context_t *ctx;
cairo_int_status_t status;
- cairo_surface_t *src = (cairo_surface_t *) abstract_src;
- cairo_surface_t *dst = (cairo_surface_t *) _dst;
- cairo_surface_t *new_surface = NULL;
- cairo_surface_t *new_src = (cairo_surface_t *) abstract_src;
- int new_src_x, new_src_y;
- cairo_surface_pattern_t new_surface_pattern;
-
- if (dst == src) {
- new_surface = _cairo_surface_create_similar_scratch (src,
- src->content,
- extents->width,
- extents->height);
- status = new_surface->status;
- if (unlikely (status)) {
- cairo_surface_destroy (new_surface);
- return status;
- }
+ cairo_surface_t *src = (cairo_surface_t *) abstract_src;
+ cairo_surface_t *dst = (cairo_surface_t *) _dst;
+ cairo_surface_t *new_surface = NULL;
+ cairo_surface_t *new_src = (cairo_surface_t *) abstract_src;
+ int new_src_x, new_src_y;
+ cairo_surface_pattern_t new_surface_pattern;
+
+ if (dst == src) {
+ new_surface = _cairo_surface_create_similar_scratch (src,
+ src->content,
+ extents->width,
+ extents->height);
+ status = new_surface->status;
+ if (unlikely (status)) {
+ cairo_surface_destroy (new_surface);
+ return status;
+ }
_cairo_pattern_init_for_surface (&new_surface_pattern, src);
new_surface_pattern.base.extend = CAIRO_EXTEND_NONE;
new_surface_pattern.base.filter = CAIRO_FILTER_NEAREST;
status = _cairo_surface_paint (new_surface, CAIRO_OPERATOR_SOURCE,
- &new_surface_pattern.base, NULL);
+ &new_surface_pattern.base, NULL);
if (unlikely (status)) {
- _cairo_pattern_fini (&new_surface_pattern.base);
- cairo_surface_destroy (new_surface);
- return status;
- }
+ _cairo_pattern_fini (&new_surface_pattern.base);
+ cairo_surface_destroy (new_surface);
+ return status;
+ }
new_src = _cairo_gl_pattern_to_source (dst,
- &new_surface_pattern.base,
- FALSE,
- extents, extents,
- &new_src_x, &new_src_y);
- }
+ &new_surface_pattern.base,
+ FALSE,
+ extents, extents,
+ &new_src_x, &new_src_y);
+ }
status = _cairo_gl_composite_init (&setup, op, _dst, FALSE);
if (unlikely (status))
@@ -485,9 +448,8 @@ composite_traps (void *_dst,
_cairo_gl_composite_set_source_operand (&setup,
source_to_operand (new_src));
-
- if (src == new_src)
- _cairo_gl_operand_translate (&setup.src, -src_x-dst_x, -src_y-dst_y);
+ if (src == new_src)
+ _cairo_gl_operand_translate (&setup.src, -src_x-dst_x, -src_y-dst_y);
status = traps_to_operand (_dst, extents, antialias, traps, &setup.mask, dst_x, dst_y);
if (unlikely (status))
goto FAIL;
@@ -506,12 +468,12 @@ composite_traps (void *_dst,
FAIL:
_cairo_gl_composite_fini (&setup);
- if (new_src != src) {
- cairo_surface_destroy (new_src);
- cairo_surface_destroy (new_surface);
- _cairo_pattern_fini (&new_surface_pattern.base);
- }
-
+ if (new_src != src) {
+ cairo_surface_destroy (new_src);
+ cairo_surface_destroy (new_surface);
+ _cairo_pattern_fini (&new_surface_pattern.base);
+ }
+
return status;
}
@@ -542,10 +504,11 @@ tristrip_to_surface (void *_dst,
return (cairo_gl_surface_t *)image;
}
- mask = _cairo_surface_create_similar_scratch (_dst,
- CAIRO_CONTENT_COLOR_ALPHA,
- extents->width,
- extents->height);
+ mask = _cairo_surface_create_scratch (_dst,
+ CAIRO_CONTENT_COLOR_ALPHA,
+ extents->width,
+ extents->height,
+ NULL);
if (unlikely (mask->status)) {
cairo_surface_destroy (image);
return (cairo_gl_surface_t *)mask;
@@ -648,8 +611,8 @@ _cairo_gl_traps_compositor_get (void)
compositor.check_composite = check_composite;
compositor.composite = composite;
compositor.lerp = lerp;
- //FIXME:
- compositor.lerp_color_glyph = lerp_color_glyph;
+ // FIXME:
+ compositor.lerp_color_glyph = lerp_color_glyph;
//compositor.check_composite_boxes = check_composite_boxes;
compositor.composite_boxes = composite_boxes;
//compositor.check_composite_traps = check_composite_traps;
diff --git a/src/cairo-gl.h b/src/cairo-gl.h
index 69738a265..85a0ac69e 100755..100644
--- a/src/cairo-gl.h
+++ b/src/cairo-gl.h
@@ -130,6 +130,21 @@ cairo_gl_surface_create_for_dc (cairo_device_t *device,
int height);
#endif
+#if CAIRO_HAS_CGL_FUNCTIONS
+#include <OpenGL/OpenGL.h>
+
+cairo_public cairo_device_t *
+cairo_cgl_device_create (CGLContextObj ctx);
+
+cairo_public cairo_surface_t *
+cairo_gl_surface_create_for_cgl (cairo_device_t *device,
+ int width,
+ int height);
+
+cairo_public CGLContextObj
+cairo_cgl_device_get_context (cairo_device_t *device);
+#endif
+
#if CAIRO_HAS_EGL_FUNCTIONS
#include <EGL/egl.h>
diff --git a/src/cairo-glx-context.c b/src/cairo-glx-context.c
index b4d706007..59e939292 100755..100644
--- a/src/cairo-glx-context.c
+++ b/src/cairo-glx-context.c
@@ -55,6 +55,7 @@ typedef struct _cairo_glx_context {
GLXDrawable current_drawable;
GLXContext previous_context;
+ GLXDrawable previous_drawable;
cairo_bool_t has_multithread_makecurrent;
} cairo_glx_context_t;
@@ -68,7 +69,8 @@ typedef struct _cairo_glx_surface {
static cairo_bool_t
_context_acquisition_changed_glx_state (cairo_glx_context_t *ctx)
{
- return ctx->previous_context != ctx->context;
+ return ctx->previous_context != ctx->context ||
+ ctx->previous_drawable != ctx->current_drawable;
}
static GLXDrawable
@@ -86,6 +88,7 @@ static void *
_glx_query_current_state (cairo_glx_context_t * ctx)
{
ctx->previous_context = glXGetCurrentContext ();
+ ctx->previous_drawable = glXGetCurrentDrawable ();
}
static void
@@ -252,7 +255,7 @@ _cairo_glx_get_proc_address (void *data, const char *name)
return func_map[i].func;
}
- return glXGetProcAddress (name);
+ return glXGetProcAddress (name);
}
cairo_device_t *
diff --git a/src/cairo-gstate-private.h b/src/cairo-gstate-private.h
index 92d3bb3c3..92d3bb3c3 100755..100644
--- a/src/cairo-gstate-private.h
+++ b/src/cairo-gstate-private.h
diff --git a/src/cairo-gstate.c b/src/cairo-gstate.c
index 84b47fe9a..c747b3fa8 100755..100644
--- a/src/cairo-gstate.c
+++ b/src/cairo-gstate.c
@@ -975,7 +975,7 @@ _cairo_gstate_copy_transformed_pattern (cairo_gstate_t *gstate,
surface = surface_pattern->surface;
if (_cairo_surface_has_device_transform (surface))
- _cairo_pattern_transform (pattern, &surface->device_transform);
+ _cairo_pattern_pretransform (pattern, &surface->device_transform);
}
if (! _cairo_matrix_is_identity (ctm_inverse))
@@ -1087,7 +1087,7 @@ _cairo_gstate_paint (cairo_gstate_t *gstate)
op = _reduce_op (gstate);
/* do not use static pattern */
if (op == CAIRO_OPERATOR_CLEAR) {
- if (! _cairo_gstate_has_shadow (gstate))
+ if (! _cairo_gstate_has_shadow (gstate))
pattern = &_cairo_pattern_clear.base;
else {
pattern = cairo_pattern_create_rgba (0, 0, 0, 0);
@@ -1219,6 +1219,8 @@ _cairo_gstate_stroke (cairo_gstate_t *gstate, cairo_path_fixed_t *path)
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))
@@ -1239,8 +1241,15 @@ _cairo_gstate_stroke (cairo_gstate_t *gstate, cairo_path_fixed_t *path)
assert (gstate->opacity == 1.0);
+ 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, &gstate->ctm, gstate->tolerance)) {
+ 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,
@@ -1259,8 +1268,8 @@ _cairo_gstate_stroke (cairo_gstate_t *gstate, cairo_path_fixed_t *path)
&source_pattern.base,
path,
&style,
- &gstate->ctm,
- &gstate->ctm_inverse,
+ &aggregate_transform,
+ &aggregate_transform_inverse,
gstate->tolerance,
gstate->antialias,
gstate->clip);
@@ -1364,7 +1373,7 @@ _cairo_gstate_fill (cairo_gstate_t *gstate, cairo_path_fixed_t *path)
op = _reduce_op (gstate);
/* FIXME: I don't like this */
if (op == CAIRO_OPERATOR_CLEAR) {
- if (_cairo_gstate_has_shadow (gstate))
+ if (_cairo_gstate_has_shadow (gstate))
pattern = &_cairo_pattern_clear.base;
else {
pattern = cairo_pattern_create_rgba (0, 0, 0, 0);
@@ -1553,19 +1562,19 @@ _cairo_gstate_stroke_extents (cairo_gstate_t *gstate,
}
if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
- cairo_traps_t traps;
-
- _cairo_traps_init (&traps);
- status = _cairo_path_fixed_stroke_polygon_to_traps (path,
- &gstate->stroke_style,
- &gstate->ctm,
- &gstate->ctm_inverse,
- gstate->tolerance,
- &traps);
- empty = traps.num_traps == 0;
+ cairo_polygon_t polygon;
+
+ _cairo_polygon_init (&polygon, NULL, 0);
+ status = _cairo_path_fixed_stroke_to_polygon (path,
+ &gstate->stroke_style,
+ &gstate->ctm,
+ &gstate->ctm_inverse,
+ gstate->tolerance,
+ &polygon);
+ empty = polygon.num_edges == 0;
if (! empty)
- _cairo_traps_extents (&traps, &extents);
- _cairo_traps_fini (&traps);
+ extents = polygon.extents;
+ _cairo_polygon_fini (&polygon);
}
if (! empty) {
_cairo_gstate_extents_to_user_rectangle (gstate, &extents,
@@ -1924,6 +1933,7 @@ _cairo_gstate_ensure_scaled_font (cairo_gstate_t *gstate)
cairo_status_t status;
cairo_font_options_t options;
cairo_scaled_font_t *scaled_font;
+ cairo_matrix_t font_ctm;
if (gstate->scaled_font != NULL)
return gstate->scaled_font->status;
@@ -1935,9 +1945,13 @@ _cairo_gstate_ensure_scaled_font (cairo_gstate_t *gstate)
cairo_surface_get_font_options (gstate->target, &options);
cairo_font_options_merge (&options, &gstate->font_options);
+ cairo_matrix_multiply (&font_ctm,
+ &gstate->ctm,
+ &gstate->target->device_transform);
+
scaled_font = cairo_scaled_font_create (gstate->font_face,
&gstate->font_matrix,
- &gstate->ctm,
+ &font_ctm,
&options);
status = cairo_scaled_font_status (scaled_font);
@@ -2094,6 +2108,7 @@ _cairo_gstate_show_text_glyphs (cairo_gstate_t *gstate,
if (cairo_surface_has_show_text_glyphs (gstate->target) ||
_cairo_scaled_font_get_max_scale (gstate->scaled_font) <= 10240)
{
+
if (info != NULL) {
status = _cairo_surface_show_text_glyphs (gstate->target, op, pattern,
info->utf8, info->utf8_len,
diff --git a/src/cairo-hash-private.h b/src/cairo-hash-private.h
index 30e51ffe6..30e51ffe6 100755..100644
--- a/src/cairo-hash-private.h
+++ b/src/cairo-hash-private.h
diff --git a/src/cairo-hash.c b/src/cairo-hash.c
index 928c74b8b..928c74b8b 100755..100644
--- a/src/cairo-hash.c
+++ b/src/cairo-hash.c
diff --git a/src/cairo-hull.c b/src/cairo-hull.c
index c65593327..c65593327 100755..100644
--- a/src/cairo-hull.c
+++ b/src/cairo-hull.c
diff --git a/src/cairo-image-compositor.c b/src/cairo-image-compositor.c
index a732f2a3a..18a44fb8c 100755..100644
--- a/src/cairo-image-compositor.c
+++ b/src/cairo-image-compositor.c
@@ -52,9 +52,7 @@
#include "cairo-traps-private.h"
#include "cairo-tristrip-private.h"
-#if CAIRO_HAS_TG_SURFACE
-#include "cairo-thread-local-private.h"
-#endif
+#include "cairo-pixman-private.h"
static pixman_image_t *
to_pixman_image (cairo_surface_t *s)
@@ -260,9 +258,9 @@ _pixman_operator (cairo_operator_t op)
}
static cairo_bool_t
-fill_reduces_to_source (cairo_operator_t op,
- const cairo_color_t *color,
- cairo_image_surface_t *dst)
+__fill_reduces_to_source (cairo_operator_t op,
+ const cairo_color_t *color,
+ const cairo_image_surface_t *dst)
{
if (op == CAIRO_OPERATOR_SOURCE || op == CAIRO_OPERATOR_CLEAR)
return TRUE;
@@ -274,6 +272,19 @@ fill_reduces_to_source (cairo_operator_t op,
return FALSE;
}
+static cairo_bool_t
+fill_reduces_to_source (cairo_operator_t op,
+ const cairo_color_t *color,
+ const cairo_image_surface_t *dst,
+ uint32_t *pixel)
+{
+ if (__fill_reduces_to_source (op, color, dst)) {
+ return color_to_pixel (color, dst->pixman_format, pixel);
+ }
+
+ return FALSE;
+}
+
static cairo_int_status_t
fill_rectangles (void *_dst,
cairo_operator_t op,
@@ -287,9 +298,7 @@ fill_rectangles (void *_dst,
TRACE ((stderr, "%s\n", __FUNCTION__));
- if (fill_reduces_to_source (op, color, dst) &&
- color_to_pixel (color, dst->pixman_format, &pixel))
- {
+ if (fill_reduces_to_source (op, color, dst, &pixel)) {
for (i = 0; i < num_rects; i++) {
pixman_fill ((uint32_t *) dst->data, dst->stride / sizeof (uint32_t),
PIXMAN_FORMAT_BPP (dst->pixman_format),
@@ -297,12 +306,10 @@ fill_rectangles (void *_dst,
rects[i].width, rects[i].height,
pixel);
}
- }
- else
- {
+ } else {
pixman_image_t *src = _pixman_image_for_color (color);
- if (src == NULL)
- return CAIRO_STATUS_NULL_POINTER;
+ if (unlikely (src == NULL))
+ return _cairo_error (CAIRO_STATUS_NO_MEMORY);
op = _pixman_operator (op);
for (i = 0; i < num_rects; i++) {
@@ -333,9 +340,7 @@ fill_boxes (void *_dst,
TRACE ((stderr, "%s x %d\n", __FUNCTION__, boxes->num_boxes));
- if (fill_reduces_to_source (op, color, dst) &&
- color_to_pixel (color, dst->pixman_format, &pixel))
- {
+ if (fill_reduces_to_source (op, color, dst, &pixel)) {
for (chunk = &boxes->chunks; chunk; chunk = chunk->next) {
for (i = 0; i < chunk->count; i++) {
int x = _cairo_fixed_integer_part (chunk->base[i].p1.x);
@@ -352,8 +357,8 @@ fill_boxes (void *_dst,
else
{
pixman_image_t *src = _pixman_image_for_color (color);
- if (src == NULL)
- return CAIRO_STATUS_NULL_POINTER;
+ if (unlikely (src == NULL))
+ return _cairo_error (CAIRO_STATUS_NO_MEMORY);
op = _pixman_operator (op);
for (chunk = &boxes->chunks; chunk; chunk = chunk->next) {
@@ -472,49 +477,49 @@ lerp (void *_dst,
}
static cairo_int_status_t
-lerp_color_glyph (void *_dst,
- cairo_surface_t *abstract_src,
- cairo_surface_t *abstract_mask,
- int src_x,
- int src_y,
- int mask_x,
- int mask_y,
- int dst_x,
- int dst_y,
- unsigned int width,
- unsigned int height)
-{
- cairo_image_surface_t *dst = _dst;
- cairo_image_source_t *src = (cairo_image_source_t *)abstract_src;
- cairo_image_source_t *mask = (cairo_image_source_t *)abstract_mask;
-
- TRACE ((stderr, "%s\n", __FUNCTION__));
-
- /* Punch the clip out of the destination */
- TRACE ((stderr, "%s - OUT_REVERSE (mask=%d/%p, dst=%d/%p)\n",
- __FUNCTION__,
- mask->base.unique_id, mask->pixman_image,
- dst->base.unique_id, dst->pixman_image));
- pixman_image_composite32 (PIXMAN_OP_OUT_REVERSE,
- mask->pixman_image, src->pixman_image, dst->pixman_image,
- mask_x, mask_y,
- 0, 0,
- dst_x, dst_y,
- width, height);
-
- /* Now add the two results together */
- TRACE ((stderr, "%s - ADD (src=%d/%p, mask=%d/%p, dst=%d/%p)\n",
- __FUNCTION__,
- src->base.unique_id, src->pixman_image,
- mask->base.unique_id, mask->pixman_image,
- dst->base.unique_id, dst->pixman_image));
- pixman_image_composite32 (PIXMAN_OP_ADD,
- src->pixman_image, mask->pixman_image, dst->pixman_image,
- src_x, src_y,
- mask_x, mask_y,
- dst_x, dst_y,
- width, height);
- return CAIRO_STATUS_SUCCESS;
+lerp_color_glyph (void *_dst,
+ cairo_surface_t *abstract_src,
+ cairo_surface_t *abstract_mask,
+ int src_x,
+ int src_y,
+ int mask_x,
+ int mask_y,
+ int dst_x,
+ int dst_y,
+ unsigned int width,
+ unsigned int height)
+{
+ cairo_image_surface_t *dst = _dst;
+ cairo_image_source_t *src = (cairo_image_source_t *)abstract_src;
+ cairo_image_source_t *mask = (cairo_image_source_t *)abstract_mask;
+
+ TRACE ((stderr, "%s\n", __FUNCTION__));
+
+ /* Punch the clip out of the destination */
+ TRACE ((stderr, "%s - OUT_REVERSE (mask=%d/%p, dst=%d/%p)\n",
+ __FUNCTION__,
+ mask->base.unique_id, mask->pixman_image,
+ dst->base.unique_id, dst->pixman_image));
+ pixman_image_composite32 (PIXMAN_OP_OUT_REVERSE,
+ mask->pixman_image, src->pixman_image, dst->pixman_image,
+ mask_x, mask_y,
+ 0, 0,
+ dst_x, dst_y,
+ width, height);
+
+ /* Now add the two results together */
+ TRACE ((stderr, "%s - ADD (src=%d/%p, mask=%d/%p, dst=%d/%p)\n",
+ __FUNCTION__,
+ src->base.unique_id, src->pixman_image,
+ mask->base.unique_id, mask->pixman_image,
+ dst->base.unique_id, dst->pixman_image));
+ pixman_image_composite32 (PIXMAN_OP_ADD,
+ src->pixman_image, mask->pixman_image, dst->pixman_image,
+ src_x, src_y,
+ mask_x, mask_y,
+ dst_x, dst_y,
+ width, height);
+ return CAIRO_STATUS_SUCCESS;
}
static cairo_int_status_t
@@ -552,9 +557,8 @@ composite_boxes (void *_dst,
op = PIXMAN_OP_LERP_CLEAR;
#else
free_src = src = _pixman_image_for_color (CAIRO_COLOR_WHITE);
- if (src == NULL)
- return CAIRO_STATUS_NULL_POINTER;
-
+ if (unlikely (src == NULL))
+ return _cairo_error (CAIRO_STATUS_NO_MEMORY);
op = PIXMAN_OP_OUT_REVERSE;
#endif
} else if (op == CAIRO_OPERATOR_SOURCE) {
@@ -691,11 +695,18 @@ composite_traps (void *_dst,
{
cairo_image_surface_t *dst = (cairo_image_surface_t *) _dst;
cairo_image_source_t *src = (cairo_image_source_t *) abstract_src;
+ cairo_int_status_t status;
pixman_image_t *mask;
pixman_format_code_t format;
TRACE ((stderr, "%s\n", __FUNCTION__));
+ /* pixman doesn't eliminate self-intersecting trapezoids/edges */
+ status = _cairo_bentley_ottmann_tessellate_traps (traps,
+ CAIRO_FILL_RULE_WINDING);
+ if (status != CAIRO_INT_STATUS_SUCCESS)
+ return status;
+
/* Special case adding trapezoids onto a mask surface; we want to avoid
* creating an intermediate temporary mask unnecessarily.
*
@@ -731,6 +742,7 @@ composite_traps (void *_dst,
return CAIRO_STATUS_SUCCESS;
}
+#if PIXMAN_VERSION >= PIXMAN_VERSION_ENCODE(0,22,0)
static void
set_point (pixman_point_fixed_t *p, cairo_point_t *c)
{
@@ -779,6 +791,31 @@ composite_tristrip (void *_dst,
if (strip->num_points < 3)
return CAIRO_STATUS_SUCCESS;
+ if (1) { /* pixman doesn't eliminate self-intersecting triangles/edges */
+ cairo_int_status_t status;
+ cairo_traps_t traps;
+ int n;
+
+ _cairo_traps_init (&traps);
+ for (n = 0; n < strip->num_points; n++) {
+ cairo_point_t p[4];
+
+ p[0] = strip->points[0];
+ p[1] = strip->points[1];
+ p[2] = strip->points[2];
+ p[3] = strip->points[0];
+
+ _cairo_traps_tessellate_convex_quad (&traps, p);
+ }
+ status = composite_traps (_dst, op, abstract_src,
+ src_x, src_y,
+ dst_x, dst_y,
+ extents, antialias, &traps);
+ _cairo_traps_fini (&traps);
+
+ return status;
+ }
+
format = antialias == CAIRO_ANTIALIAS_NONE ? PIXMAN_a1 : PIXMAN_a8;
if (dst->pixman_format == format &&
(abstract_src == NULL ||
@@ -806,6 +843,7 @@ composite_tristrip (void *_dst,
return CAIRO_STATUS_SUCCESS;
}
+#endif
static cairo_int_status_t
check_composite_glyphs (const cairo_composite_rectangles_t *extents,
@@ -817,51 +855,30 @@ check_composite_glyphs (const cairo_composite_rectangles_t *extents,
}
#if 0 && HAS_PIXMAN_GLYPHS
-#if CAIRO_HAS_TG_SURFACE
-CAIRO_DEFINE_THREAD_LOCAL (pixman_glyph_cache_t *, per_thread_glyph_cache);
-#else
static pixman_glyph_cache_t *global_glyph_cache;
-#endif
static inline pixman_glyph_cache_t *
get_glyph_cache (void)
{
- pixman_glyph_cache_t **glyph_cache = NULL;
+ if (!global_glyph_cache)
+ global_glyph_cache = pixman_glyph_cache_create ();
-#if CAIRO_HAS_TG_SURFACE
- glyph_cache = CAIRO_GET_THREAD_LOCAL (per_thread_glyph_cache);
-#else
- glyph_cache = &global_glyph_cache;
-#endif
-
- if (! (*glyph_cache))
- *glyph_cache = pixman_glyph_cache_create ();
-
- return *glyph_cache;
+ return global_glyph_cache;
}
void
_cairo_image_scaled_glyph_fini (cairo_scaled_font_t *scaled_font,
cairo_scaled_glyph_t *scaled_glyph)
{
- pixman_glyph_cache_t *glyph_cache = NULL;
-
-#if CAIRO_HAS_TG_SURFACE
- glyph_cache = *CAIRO_GET_THREAD_LOCAL (per_thread_glyph_cache);
-#else
- glyph_cache = global_glyph_cache;
CAIRO_MUTEX_LOCK (_cairo_glyph_cache_mutex);
-#endif
- if (glyph_cache) {
+ if (global_glyph_cache) {
pixman_glyph_cache_remove (
- glyph_cache, scaled_font,
+ global_glyph_cache, scaled_font,
(void *)_cairo_scaled_glyph_index (scaled_glyph));
}
-#if ! CAIRO_HAS_TG_SURFACE
CAIRO_MUTEX_UNLOCK (_cairo_glyph_cache_mutex);
-#endif
}
static cairo_int_status_t
@@ -883,9 +900,7 @@ composite_glyphs (void *_dst,
TRACE ((stderr, "%s\n", __FUNCTION__));
-#if ! CAIRO_HAS_TG_SURFACE
CAIRO_MUTEX_LOCK (_cairo_glyph_cache_mutex);
-#endif
glyph_cache = get_glyph_cache();
if (unlikely (glyph_cache == NULL)) {
@@ -913,43 +928,23 @@ composite_glyphs (void *_dst,
cairo_scaled_glyph_t *scaled_glyph;
cairo_image_surface_t *glyph_surface;
-#if ! CAIRO_HAS_TG_SURFACE
/* This call can actually end up recursing, so we have to
* drop the mutex around it.
*/
CAIRO_MUTEX_UNLOCK (_cairo_glyph_cache_mutex);
-#else
- _cairo_scaled_font_freeze_cache (info->font);
- CAIRO_MUTEX_LOCK (_cairo_tg_scaled_glyph_mutex);
-#endif
-
status = _cairo_scaled_glyph_lookup (info->font, index,
CAIRO_SCALED_GLYPH_INFO_SURFACE,
&scaled_glyph);
-
-#if ! CAIRO_HAS_TG_SURFACE
CAIRO_MUTEX_LOCK (_cairo_glyph_cache_mutex);
-#endif
- if (unlikely (status)) {
-#if CAIRO_HAS_TG_SURFACE
- CAIRO_MUTEX_UNLOCK (_cairo_tg_scaled_glyph_mutex);
- _cairo_scaled_font_thaw_cache (info->font);
-#endif
+ if (unlikely (status))
goto out_thaw;
- }
glyph_surface = scaled_glyph->surface;
glyph = pixman_glyph_cache_insert (glyph_cache, info->font, (void *)index,
glyph_surface->base.device_transform.x0,
glyph_surface->base.device_transform.y0,
glyph_surface->pixman_image);
-
-#if CAIRO_HAS_TG_SURFACE
- CAIRO_MUTEX_UNLOCK (_cairo_tg_scaled_glyph_mutex);
- _cairo_scaled_font_thaw_cache (info->font);
-#endif
-
if (unlikely (!glyph)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto out_thaw;
@@ -992,10 +987,7 @@ out_thaw:
free(pglyphs);
out_unlock:
-#if ! CAIRO_HAS_TG_SURFACE
CAIRO_MUTEX_UNLOCK (_cairo_glyph_cache_mutex);
-#endif
-
return status;
}
#else
@@ -1015,7 +1007,7 @@ composite_one_glyph (void *_dst,
int dst_y,
cairo_composite_glyphs_info_t *info)
{
- cairo_image_surface_t *dst_surface = (cairo_image_surface_t *)_dst;
+ cairo_image_surface_t *dst_surface = (cairo_image_surface_t *)_dst;
cairo_image_surface_t *glyph_surface;
cairo_scaled_glyph_t *scaled_glyph;
cairo_status_t status;
@@ -1035,11 +1027,11 @@ composite_one_glyph (void *_dst,
if (glyph_surface->width == 0 || glyph_surface->height == 0)
return CAIRO_INT_STATUS_NOTHING_TO_DO;
- if (glyph_surface->format == CAIRO_FORMAT_ARGB32 &&
- dst_surface->format != CAIRO_FORMAT_ARGB32) {
+ if (glyph_surface->format == CAIRO_FORMAT_ARGB32 &&
+ dst_surface->format != CAIRO_FORMAT_ARGB32) {
/* FIXME: color glyph */
return CAIRO_STATUS_SURFACE_TYPE_MISMATCH;
- }
+ }
/* round glyph locations to the nearest pixel */
/* XXX: FRAGILE: We're ignoring device_transform scaling here. A bug? */
@@ -1048,28 +1040,27 @@ composite_one_glyph (void *_dst,
y = _cairo_lround (info->glyphs[0].y -
glyph_surface->base.device_transform.y0);
-
- if (glyph_surface->format != CAIRO_FORMAT_ARGB32 ||
- pixman_image_get_component_alpha (glyph_surface->pixman_image))
- pixman_image_composite32 (_pixman_operator (op),
- ((cairo_image_source_t *)_src)->pixman_image,
- glyph_surface->pixman_image,
- to_pixman_image (_dst),
- x + src_x, y + src_y,
- 0, 0,
- x - dst_x, y - dst_y,
- glyph_surface->width,
- glyph_surface->height);
- else /* color glyph */
- pixman_image_composite32 (_pixman_operator (op),
- glyph_surface->pixman_image,
- NULL,
- to_pixman_image (_dst),
- 0, 0,
- x + src_x, y + src_y,
- x - dst_x, y - dst_y,
- glyph_surface->width,
- glyph_surface->height);
+ if (glyph_surface->format != CAIRO_FORMAT_ARGB32 ||
+ pixman_image_get_component_alpha (glyph_surface->pixman_image))
+ pixman_image_composite32 (_pixman_operator (op),
+ ((cairo_image_source_t *)_src)->pixman_image,
+ glyph_surface->pixman_image,
+ to_pixman_image (_dst),
+ x + src_x, y + src_y,
+ 0, 0,
+ x - dst_x, y - dst_y,
+ glyph_surface->width,
+ glyph_surface->height);
+ else /* color glyph */
+ pixman_image_composite32 (_pixman_operator (op),
+ glyph_surface->pixman_image,
+ NULL,
+ to_pixman_image (_dst),
+ 0, 0,
+ x + src_x, y + src_y,
+ x - dst_x, y - dst_y,
+ glyph_surface->width,
+ glyph_surface->height);
return CAIRO_INT_STATUS_SUCCESS;
}
@@ -1092,7 +1083,7 @@ composite_glyphs_via_mask (void *_dst,
pixman_format_code_t format;
cairo_status_t status;
int i;
- cairo_bool_t component_alpha = FALSE;
+ cairo_bool_t component_alpha = FALSE;
TRACE ((stderr, "%s\n", __FUNCTION__));
@@ -1167,7 +1158,7 @@ composite_glyphs_via_mask (void *_dst,
glyph_surface = scaled_glyph->surface;
if (! component_alpha)
- component_alpha = pixman_image_get_component_alpha (glyph_surface->pixman_image);
+ component_alpha = pixman_image_get_component_alpha (glyph_surface->pixman_image);
if (glyph_surface->width && glyph_surface->height) {
if (glyph_surface->base.content & CAIRO_CONTENT_COLOR &&
format == PIXMAN_a8) {
@@ -1225,22 +1216,22 @@ composite_glyphs_via_mask (void *_dst,
if (format == PIXMAN_a8r8g8b8 && component_alpha)
pixman_image_set_component_alpha (mask, TRUE);
- if (format != PIXMAN_a8r8g8b8 || component_alpha)
- pixman_image_composite32 (_pixman_operator (op),
- ((cairo_image_source_t *)_src)->pixman_image,
- mask,
- to_pixman_image (_dst),
- info->extents.x + src_x, info->extents.y + src_y,
- 0, 0,
- info->extents.x - dst_x, info->extents.y - dst_y,
- info->extents.width, info->extents.height);
- else /* color glyph */
- pixman_image_composite32 (_pixman_operator (op), mask, NULL,
- to_pixman_image (_dst),
- 0, 0,
- info->extents.x + src_x, info->extents.y + src_y,
- info->extents.x - dst_x, info->extents.y - dst_y,
- info->extents.width, info->extents.height);
+ if (format != PIXMAN_a8r8g8b8 || component_alpha)
+ pixman_image_composite32 (_pixman_operator (op),
+ ((cairo_image_source_t *)_src)->pixman_image,
+ mask,
+ to_pixman_image (_dst),
+ info->extents.x + src_x, info->extents.y + src_y,
+ 0, 0,
+ info->extents.x - dst_x, info->extents.y - dst_y,
+ info->extents.width, info->extents.height);
+ else /* color glyph */
+ pixman_image_composite32 (_pixman_operator (op), mask, NULL,
+ to_pixman_image (_dst),
+ 0, 0,
+ info->extents.x + src_x, info->extents.y + src_y,
+ info->extents.x - dst_x, info->extents.y - dst_y,
+ info->extents.width, info->extents.height);
pixman_image_unref (mask);
pixman_image_unref (white);
@@ -1261,24 +1252,17 @@ composite_glyphs (void *_dst,
pixman_image_t *dst, *src;
cairo_status_t status;
int i;
- cairo_image_surface_t *dst_surface = (cairo_image_surface_t *)_dst;
+ cairo_image_surface_t *dst_surface = (cairo_image_surface_t *)_dst;
TRACE ((stderr, "%s\n", __FUNCTION__));
-#if CAIRO_HAS_TG_SURFACE
- _cairo_scaled_font_freeze_cache (info->font);
- CAIRO_MUTEX_LOCK (_cairo_tg_scaled_glyph_mutex);
-#endif
+ /* XXX */
+ if (0 && info->num_glyphs == 1)
+ return composite_one_glyph(_dst, op, _src, src_x, src_y, dst_x, dst_y, info);
- if (0 && info->num_glyphs == 1) {
- status = composite_one_glyph(_dst, op, _src, src_x, src_y, dst_x, dst_y, info);
- goto out_thaw;
- }
-
- if (0 && info->use_mask) {
- status = composite_glyphs_via_mask(_dst, op, _src, src_x, src_y, dst_x, dst_y, info);
- goto out_thaw;
- }
+ /* XXX */
+ if (info->use_mask)
+ return composite_glyphs_via_mask(_dst, op, _src, src_x, src_y, dst_x, dst_y, info);
op = _pixman_operator (op);
dst = to_pixman_image (_dst);
@@ -1310,9 +1294,9 @@ composite_glyphs (void *_dst,
glyph_surface = scaled_glyph->surface;
if (glyph_surface->format == CAIRO_FORMAT_ARGB32 &&
- dst_surface->format != CAIRO_FORMAT_ARGB32) {
- /* FIXME: color glyph */
- return CAIRO_STATUS_SURFACE_TYPE_MISMATCH;
+ dst_surface->format != CAIRO_FORMAT_ARGB32) {
+ /* FIXME: color glyph */
+ return CAIRO_STATUS_SURFACE_TYPE_MISMATCH;
}
if (glyph_surface->width && glyph_surface->height) {
@@ -1323,30 +1307,24 @@ composite_glyphs (void *_dst,
y = _cairo_lround (info->glyphs[i].y -
glyph_surface->base.device_transform.y0);
- if (glyph_surface->format != CAIRO_FORMAT_ARGB32 ||
+ if (glyph_surface->format != CAIRO_FORMAT_ARGB32 ||
pixman_image_get_component_alpha (glyph_surface->pixman_image))
- pixman_image_composite32 (op, src, glyph_surface->pixman_image, dst,
- x + src_x, y + src_y,
- 0, 0,
- x - dst_x, y - dst_y,
- glyph_surface->width,
- glyph_surface->height);
- else /* Color glyph. */
- pixman_image_composite32 (op, glyph_surface->pixman_image, NULL, dst,
- 0, 0,
- x + src_x, y + src_y,
- x - dst_x, y - dst_y,
- glyph_surface->width,
- glyph_surface->height);
- }
+ pixman_image_composite32 (op, src, glyph_surface->pixman_image, dst,
+ x + src_x, y + src_y,
+ 0, 0,
+ x - dst_x, y - dst_y,
+ glyph_surface->width,
+ glyph_surface->height);
+ else /* Color glyph. */
+ pixman_image_composite32 (op, glyph_surface->pixman_image, NULL, dst,
+ 0, 0,
+ x + src_x, y + src_y,
+ x - dst_x, y - dst_y,
+ glyph_surface->width,
+ glyph_surface->height);
+ }
}
-out_thaw:
-#if CAIRO_HAS_TG_SURFACE
- _cairo_scaled_font_thaw_cache (info->font);
- CAIRO_MUTEX_UNLOCK (_cairo_tg_scaled_glyph_mutex);
-#endif
-
return status;
}
#endif
@@ -1381,7 +1359,9 @@ _cairo_image_traps_compositor_get (void)
//compositor.check_composite_traps = check_composite_traps;
compositor.composite_traps = composite_traps;
//compositor.check_composite_tristrip = check_composite_traps;
+#if PIXMAN_VERSION >= PIXMAN_VERSION_ENCODE(0,22,0)
compositor.composite_tristrip = composite_tristrip;
+#endif
compositor.check_composite_glyphs = check_composite_glyphs;
compositor.composite_glyphs = composite_glyphs;
}
@@ -1404,9 +1384,10 @@ _cairo_image_mask_compositor_get (void)
compositor.draw_image_boxes = draw_image_boxes;
compositor.fill_rectangles = fill_rectangles;
compositor.fill_boxes = fill_boxes;
- //compositor.check_composite = check_composite;
+ compositor.check_composite = check_composite;
compositor.composite = composite;
//compositor.lerp = lerp;
+ //compositor.lerp_color_glyph = lerp_color_glyph;
//compositor.check_composite_boxes = check_composite_boxes;
compositor.composite_boxes = composite_boxes;
compositor.check_composite_glyphs = check_composite_glyphs;
@@ -1714,7 +1695,7 @@ typedef struct _cairo_image_span_renderer {
} mask;
} u;
uint8_t _buf[0];
-#define SZ_BUF (sizeof (cairo_abstract_span_renderer_t) - sizeof (cairo_image_span_renderer_t))
+#define SZ_BUF (int)(sizeof (cairo_abstract_span_renderer_t) - sizeof (cairo_image_span_renderer_t))
} cairo_image_span_renderer_t;
COMPILE_TIME_ASSERT (sizeof (cairo_image_span_renderer_t) <= sizeof (cairo_abstract_span_renderer_t));
@@ -2184,8 +2165,7 @@ mono_renderer_init (cairo_image_span_renderer_t *r,
if (composite->op == CAIRO_OPERATOR_CLEAR)
color = CAIRO_COLOR_TRANSPARENT;
- if (fill_reduces_to_source (composite->op, color, dst) &&
- color_to_pixel (color, dst->pixman_format, &r->u.fill.pixel)) {
+ if (fill_reduces_to_source (composite->op, color, dst, &r->u.fill.pixel)) {
/* Use plain C for the fill operations as the span length is
* typically small, too small to payback the startup overheads of
* using SSE2 etc.
@@ -2366,10 +2346,10 @@ _fill_xrgb32_lerp_opaque_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;
}
- } else while (len--) {
+ } else while (len-- > 0) {
*d = lerp8x4 (r->u.fill.pixel, a, *d);
d++;
}
@@ -2943,8 +2923,7 @@ inplace_renderer_init (cairo_image_span_renderer_t *r,
if (composite->op == CAIRO_OPERATOR_CLEAR)
color = CAIRO_COLOR_TRANSPARENT;
- if (fill_reduces_to_source (composite->op, color, dst) &&
- color_to_pixel (color, dst->pixman_format, &r->u.fill.pixel)) {
+ if (fill_reduces_to_source (composite->op, color, dst, &r->u.fill.pixel)) {
/* Use plain C for the fill operations as the span length is
* typically small, too small to payback the startup overheads of
* using SSE2 etc.
@@ -3181,7 +3160,7 @@ span_renderer_init (cairo_abstract_span_renderer_t *_r,
r->u.mask.extents = composite->unbounded;
r->u.mask.stride = (r->u.mask.extents.width + 3) & ~3;
- if (r->u.mask.extents.height * r->u.mask.stride > (int)sizeof (r->_buf)) {
+ if (r->u.mask.extents.height * r->u.mask.stride > SZ_BUF) {
r->mask = pixman_image_create_bits (PIXMAN_a8,
r->u.mask.extents.width,
r->u.mask.extents.height,
@@ -3217,12 +3196,11 @@ span_renderer_fini (cairo_abstract_span_renderer_t *_r,
TRACE ((stderr, "%s\n", __FUNCTION__));
if (likely (status == CAIRO_INT_STATUS_SUCCESS)) {
- if (r->base.finish)
+ if (r->base.finish)
r->base.finish (r);
}
-
if (likely (status == CAIRO_INT_STATUS_SUCCESS && r->bpp == 0)) {
- const cairo_composite_rectangles_t *composite = r->composite;
+ const cairo_composite_rectangles_t *composite = r->composite;
pixman_image_composite32 (r->op, r->src, r->mask,
to_pixman_image (composite->surface),
diff --git a/src/cairo-image-filters-private.h b/src/cairo-image-filters-private.h
index a9e47f0b3..2761c7b29 100755..100644
--- a/src/cairo-image-filters-private.h
+++ b/src/cairo-image-filters-private.h
@@ -49,8 +49,8 @@
#define MAX_BLUR_SIZE 256
-cairo_private cairo_surface_t *
-_cairo_image_gaussian_filter (cairo_surface_t *src,
+cairo_private cairo_surface_t *
+_cairo_image_gaussian_filter (cairo_surface_t *src,
const cairo_pattern_t *pattern);
#endif /* CAIRO_IMAGE_FILTERS_PRIVATE_H */
diff --git a/src/cairo-image-filters.c b/src/cairo-image-filters.c
index 1f0531ef2..1216b7931 100755..100644
--- a/src/cairo-image-filters.c
+++ b/src/cairo-image-filters.c
@@ -106,7 +106,7 @@ _pixman_image_create_convolution_params (double *params,
return pixman_params;
}
-cairo_surface_t *
+cairo_surface_t *
_cairo_image_gaussian_filter (cairo_surface_t *src, const cairo_pattern_t *pattern)
{
int row, col;
@@ -139,10 +139,10 @@ _cairo_image_gaussian_filter (cairo_surface_t *src, const cairo_pattern_t *patt
row = pattern->y_radius * 2 + 1;
col = pattern->x_radius * 2 + 1;
- width = src_width / pattern->shrink_factor_x;
- height = src_height / pattern->shrink_factor_y;
+ width = src_width / pattern->shrink_factor_x;
+ height = src_height / pattern->shrink_factor_y;
stride = width * (src_image->stride / src_width);
-
+
clone_image = (cairo_image_surface_t *)
cairo_image_surface_create (src_image->format,
src_width, src_height);
@@ -152,7 +152,7 @@ _cairo_image_gaussian_filter (cairo_surface_t *src, const cairo_pattern_t *patt
clone_image = (cairo_image_surface_t *)cairo_surface_reference (src);
goto DONE;
}
-
+
/* XXX: we must always create a clone because we need to modify
* it transformation, no copy data */
temp_image = pixman_image_create_bits (src_image->pixman_format,
@@ -165,7 +165,7 @@ _cairo_image_gaussian_filter (cairo_surface_t *src, const cairo_pattern_t *patt
clone_image = (cairo_image_surface_t *)cairo_surface_reference (src);
goto DONE;
}
-
+
/* create scratch images */
for (i = 0; i < 2; i++) {
scratch_images[i] = pixman_image_create_bits (src_image->pixman_format,
@@ -183,7 +183,7 @@ _cairo_image_gaussian_filter (cairo_surface_t *src, const cairo_pattern_t *patt
if (width != src_width || height != src_height) {
pixman_image_set_filter (temp_image, PIXMAN_FILTER_NEAREST, NULL, 0);
/* set up transform matrix */
- cairo_matrix_init_scale (&matrix,
+ cairo_matrix_init_scale (&matrix,
(double) src_width / (double) width,
(double) src_height / (double) height);
status = _cairo_matrix_to_pixman_matrix_offset (&matrix,
@@ -264,7 +264,7 @@ _cairo_image_gaussian_filter (cairo_surface_t *src, const cairo_pattern_t *patt
/* paint scratch_surfaces[0] to clone */
/* set up transform matrix */
- cairo_matrix_init_scale (&matrix,
+ cairo_matrix_init_scale (&matrix,
(double) width / (double) src_width,
(double) height / (double) src_height);
status = _cairo_matrix_to_pixman_matrix_offset (&matrix,
diff --git a/src/cairo-image-info-private.h b/src/cairo-image-info-private.h
index 0d9ef8498..e64928e40 100755..100644
--- a/src/cairo-image-info-private.h
+++ b/src/cairo-image-info-private.h
@@ -60,4 +60,9 @@ _cairo_image_info_get_png_info (cairo_image_info_t *info,
const unsigned char *data,
unsigned long length);
+cairo_private cairo_int_status_t
+_cairo_image_info_get_jbig2_info (cairo_image_info_t *info,
+ const unsigned char *data,
+ unsigned long length);
+
#endif /* CAIRO_IMAGE_INFO_PRIVATE_H */
diff --git a/src/cairo-image-info.c b/src/cairo-image-info.c
index 4489698e8..26e7ae5af 100755..100644
--- a/src/cairo-image-info.c
+++ b/src/cairo-image-info.c
@@ -1,3 +1,4 @@
+/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
/* cairo - a vector graphics library with display and print output
*
* Copyright © 2008 Adrian Johnson
@@ -38,12 +39,6 @@
#include "cairo-error-private.h"
#include "cairo-image-info-private.h"
-static uint32_t
-_get_be32 (const unsigned char *p)
-{
- return p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3];
-}
-
/* JPEG (image/jpeg)
*
* http://www.w3.org/Graphics/JPEG/itu-t81.pdf
@@ -169,7 +164,7 @@ static const unsigned char _jpx_signature[] = {
static const unsigned char *
_jpx_next_box (const unsigned char *p)
{
- return p + _get_be32 (p);
+ return p + get_unaligned_be32 (p);
}
static const unsigned char *
@@ -184,8 +179,8 @@ _jpx_match_box (const unsigned char *p, const unsigned char *end, uint32_t type)
uint32_t length;
if (p + 8 < end) {
- length = _get_be32 (p);
- if (_get_be32 (p + 4) == type && p + length < end)
+ length = get_unaligned_be32 (p);
+ if (get_unaligned_be32 (p + 4) == type && p + length < end)
return TRUE;
}
@@ -207,8 +202,8 @@ _jpx_find_box (const unsigned char *p, const unsigned char *end, uint32_t type)
static void
_jpx_extract_info (const unsigned char *p, cairo_image_info_t *info)
{
- info->height = _get_be32 (p);
- info->width = _get_be32 (p + 4);
+ info->height = get_unaligned_be32 (p);
+ info->width = get_unaligned_be32 (p + 4);
info->num_components = (p[8] << 8) + p[9];
info->bits_per_component = p[10];
}
@@ -280,13 +275,147 @@ _cairo_image_info_get_png_info (cairo_image_info_t *info,
return CAIRO_INT_STATUS_UNSUPPORTED;
p += 4;
- if (_get_be32 (p) != PNG_IHDR)
+ if (get_unaligned_be32 (p) != PNG_IHDR)
return CAIRO_INT_STATUS_UNSUPPORTED;
p += 4;
- info->width = _get_be32 (p);
+ info->width = get_unaligned_be32 (p);
p += 4;
- info->height = _get_be32 (p);
+ info->height = get_unaligned_be32 (p);
return CAIRO_STATUS_SUCCESS;
}
+
+static const unsigned char *
+_jbig2_find_data_end (const unsigned char *p,
+ const unsigned char *end,
+ int type)
+{
+ unsigned char end_seq[2];
+ int mmr;
+
+ /* Segments of type "Immediate generic region" may have an
+ * unspecified data length. The JBIG2 specification specifies the
+ * method to find the end of the data for these segments. */
+ if (type == 36 || type == 38 || type == 39) {
+ if (p + 18 < end) {
+ mmr = p[17] & 0x01;
+ if (mmr) {
+ /* MMR encoding ends with 0x00, 0x00 */
+ end_seq[0] = 0x00;
+ end_seq[1] = 0x00;
+ } else {
+ /* Template encoding ends with 0xff, 0xac */
+ end_seq[0] = 0xff;
+ end_seq[1] = 0xac;
+ }
+ p += 18;
+ while (p < end) {
+ if (p[0] == end_seq[0] && p[1] == end_seq[1]) {
+ /* Skip the 2 terminating bytes and the 4 byte row count that follows. */
+ p += 6;
+ if (p < end)
+ return p;
+ }
+ p++;
+ }
+ }
+ }
+
+ return NULL;
+}
+
+static const unsigned char *
+_jbig2_get_next_segment (const unsigned char *p,
+ const unsigned char *end,
+ int *type,
+ const unsigned char **data,
+ unsigned long *data_len)
+{
+ unsigned long seg_num;
+ cairo_bool_t big_page_size;
+ int num_segs;
+ int ref_seg_bytes;
+ int referred_size;
+
+ if (p + 6 >= end)
+ return NULL;
+
+ seg_num = get_unaligned_be32 (p);
+ *type = p[4] & 0x3f;
+ big_page_size = (p[4] & 0x40) != 0;
+ p += 5;
+
+ num_segs = p[0] >> 5;
+ if (num_segs == 7) {
+ num_segs = get_unaligned_be32 (p) & 0x1fffffff;
+ ref_seg_bytes = 4 + ((num_segs + 1)/8);
+ } else {
+ ref_seg_bytes = 1;
+ }
+ p += ref_seg_bytes;
+
+ if (seg_num <= 256)
+ referred_size = 1;
+ else if (seg_num <= 65536)
+ referred_size = 2;
+ else
+ referred_size = 4;
+
+ p += num_segs * referred_size;
+ p += big_page_size ? 4 : 1;
+ if (p + 4 >= end)
+ return NULL;
+
+ *data_len = get_unaligned_be32 (p);
+ p += 4;
+ *data = p;
+
+ if (*data_len == 0xffffffff) {
+ /* if data length is -1 we have to scan through the data to find the end */
+ p = _jbig2_find_data_end (*data, end, *type);
+ if (!p || p >= end)
+ return NULL;
+
+ *data_len = p - *data;
+ } else {
+ p += *data_len;
+ }
+
+ if (p < end)
+ return p;
+ else
+ return NULL;
+}
+
+static void
+_jbig2_extract_info (cairo_image_info_t *info, const unsigned char *p)
+{
+ info->width = get_unaligned_be32 (p);
+ info->height = get_unaligned_be32 (p + 4);
+ info->num_components = 1;
+ info->bits_per_component = 1;
+}
+
+cairo_int_status_t
+_cairo_image_info_get_jbig2_info (cairo_image_info_t *info,
+ const unsigned char *data,
+ unsigned long length)
+{
+ const unsigned char *p = data;
+ const unsigned char *end = data + length;
+ int seg_type;
+ const unsigned char *seg_data;
+ unsigned long seg_data_len;
+
+ while (p && p < end) {
+ p = _jbig2_get_next_segment (p, end, &seg_type, &seg_data, &seg_data_len);
+ if (p && seg_type == 48 && seg_data_len > 8) {
+ /* page information segment */
+ _jbig2_extract_info (info, seg_data);
+ return CAIRO_STATUS_SUCCESS;
+ }
+ }
+
+ return CAIRO_INT_STATUS_UNSUPPORTED;
+}
diff --git a/src/cairo-image-mask-compositor.c b/src/cairo-image-mask-compositor.c
index 33fd6dd87..bb990dd65 100755..100644
--- a/src/cairo-image-mask-compositor.c
+++ b/src/cairo-image-mask-compositor.c
@@ -48,6 +48,8 @@
#include "cairo-compositor-private.h"
#include "cairo-region-private.h"
+#error This file isn't included in any Makefile
+
static cairo_int_status_t
acquire (void *abstract_dst)
{
@@ -398,6 +400,7 @@ _cairo_image_mask_compositor_get (void)
compositor.draw_image = draw_image;
compositor.fill_rectangles = fill_rectangles;
compositor.fill_boxes = fill_boxes;
+#error check_composite must never be NULL, because it gets called without a NULL pointer check
//compositor.check_composite = check_composite;
compositor.composite = composite;
//compositor.check_composite_boxes = check_composite_boxes;
diff --git a/src/cairo-image-source.c b/src/cairo-image-source.c
index e02ebe5e0..25cdf9373 100755..100644
--- a/src/cairo-image-source.c
+++ b/src/cairo-image-source.c
@@ -56,10 +56,6 @@
#include "cairo-surface-subsurface-private.h"
#include "cairo-image-filters-private.h"
-#if CAIRO_HAS_TG_SURFACE
-#include "cairo-tg-private.h"
-#endif
-
#define PIXMAN_MAX_INT ((pixman_fixed_1 >> 1) - pixman_fixed_e) /* need to ensure deltas also fit */
#if CAIRO_NO_MUTEX
@@ -444,51 +440,6 @@ _defer_free_cleanup (pixman_image_t *pixman_image,
cairo_surface_destroy (closure);
}
-typedef struct _cairo_image_buffer
-{
- cairo_format_t format;
- unsigned char *data;
- int width;
- int height;
- int stride;
- pixman_image_t *pixman_image;
- pixman_format_code_t pixman_format;
-} cairo_image_buffer_t;
-
-static inline void
-_get_image_buffer (cairo_surface_t *surface, cairo_image_buffer_t *image_buffer)
-{
- if (surface->backend->type == CAIRO_SURFACE_TYPE_IMAGE)
- {
- cairo_image_surface_t *image = (cairo_image_surface_t *)surface;
-
- image_buffer->format = image->format;
- image_buffer->data = image->data;
- image_buffer->width = image->width;
- image_buffer->height = image->height;
- image_buffer->stride = image->stride;
- image_buffer->pixman_image = image->pixman_image;
- image_buffer->pixman_format = image->pixman_format;
- }
-#if CAIRO_HAS_TG_SURFACE
- else if (surface->backend->type == CAIRO_SURFACE_TYPE_TG)
- {
- cairo_tg_surface_t *tg = (cairo_tg_surface_t *)surface;
-
- image_buffer->format = tg->format;
- image_buffer->data = tg->data;
- image_buffer->width = tg->width;
- image_buffer->height = tg->height;
- image_buffer->stride = tg->stride;
- image_buffer->pixman_image = ((cairo_image_surface_t *)(tg->image_surface))->pixman_image;
- image_buffer->pixman_format = ((cairo_image_surface_t *)(tg->image_surface))->pixman_format;
-
- /* flush the journal to make the memory image_buffer up-to-date. */
- cairo_surface_flush (surface);
- }
-#endif
-}
-
static uint16_t
expand_channel (uint16_t v, uint32_t bits)
{
@@ -502,25 +453,25 @@ expand_channel (uint16_t v, uint32_t bits)
}
static pixman_image_t *
-_pixel_to_solid (const cairo_image_buffer_t *image_buffer, int x, int y)
+_pixel_to_solid (cairo_image_surface_t *image, int x, int y)
{
uint32_t pixel;
pixman_color_t color;
TRACE ((stderr, "%s\n", __FUNCTION__));
- switch (image_buffer->format) {
+ switch (image->format) {
default:
case CAIRO_FORMAT_INVALID:
ASSERT_NOT_REACHED;
return NULL;
case CAIRO_FORMAT_A1:
- pixel = *(uint8_t *) (image_buffer->data + y * image_buffer->stride + x/8);
+ pixel = *(uint8_t *) (image->data + y * image->stride + x/8);
return pixel & (1 << (x&7)) ? _pixman_black_image () : _pixman_transparent_image ();
case CAIRO_FORMAT_A8:
- color.alpha = *(uint8_t *) (image_buffer->data + y * image_buffer->stride + x);
+ color.alpha = *(uint8_t *) (image->data + y * image->stride + x);
color.alpha |= color.alpha << 8;
if (color.alpha == 0)
return _pixman_transparent_image ();
@@ -531,7 +482,7 @@ _pixel_to_solid (const cairo_image_buffer_t *image_buffer, int x, int y)
return pixman_image_create_solid_fill (&color);
case CAIRO_FORMAT_RGB16_565:
- pixel = *(uint16_t *) (image_buffer->data + y * image_buffer->stride + 2 * x);
+ pixel = *(uint16_t *) (image->data + y * image->stride + 2 * x);
if (pixel == 0)
return _pixman_black_image ();
if (pixel == 0xffff)
@@ -544,7 +495,7 @@ _pixel_to_solid (const cairo_image_buffer_t *image_buffer, int x, int y)
return pixman_image_create_solid_fill (&color);
case CAIRO_FORMAT_RGB30:
- pixel = *(uint32_t *) (image_buffer->data + y * image_buffer->stride + 4 * x);
+ pixel = *(uint32_t *) (image->data + y * image->stride + 4 * x);
pixel &= 0x3fffffff; /* ignore alpha bits */
if (pixel == 0)
return _pixman_black_image ();
@@ -560,8 +511,8 @@ _pixel_to_solid (const cairo_image_buffer_t *image_buffer, int x, int y)
case CAIRO_FORMAT_ARGB32:
case CAIRO_FORMAT_RGB24:
- pixel = *(uint32_t *) (image_buffer->data + y * image_buffer->stride + 4 * x);
- color.alpha = image_buffer->format == CAIRO_FORMAT_ARGB32 ? (pixel >> 24) | (pixel >> 16 & 0xff00) : 0xffff;
+ pixel = *(uint32_t *) (image->data + y * image->stride + 4 * x);
+ color.alpha = image->format == CAIRO_FORMAT_ARGB32 ? (pixel >> 24) | (pixel >> 16 & 0xff00) : 0xffff;
if (color.alpha == 0)
return _pixman_transparent_image ();
if (pixel == 0xffffffff)
@@ -576,6 +527,368 @@ _pixel_to_solid (const cairo_image_buffer_t *image_buffer, int x, int y)
}
}
+/* ========================================================================== */
+
+/* Index into filter table */
+typedef enum
+{
+ KERNEL_IMPULSE,
+ KERNEL_BOX,
+ KERNEL_LINEAR,
+ KERNEL_MITCHELL,
+ KERNEL_NOTCH,
+ KERNEL_CATMULL_ROM,
+ KERNEL_LANCZOS3,
+ KERNEL_LANCZOS3_STRETCHED,
+ KERNEL_TENT
+} kernel_t;
+
+/* Produce contribution of a filter of size r for pixel centered on x.
+ For a typical low-pass function this evaluates the function at x/r.
+ If the frequency is higher than 1/2, such as when r is less than 1,
+ this may need to integrate several samples, see cubic for examples.
+*/
+typedef double (* kernel_func_t) (double x, double r);
+
+/* Return maximum number of pixels that will be non-zero. Except for
+ impluse this is the maximum of 2 and the width of the non-zero part
+ of the filter rounded up to the next integer.
+*/
+typedef int (* kernel_width_func_t) (double r);
+
+/* Table of filters */
+typedef struct
+{
+ kernel_t kernel;
+ kernel_func_t func;
+ kernel_width_func_t width;
+} filter_info_t;
+
+/* PIXMAN_KERNEL_IMPULSE: Returns pixel nearest the center. This
+ matches PIXMAN_FILTER_NEAREST. This is useful if you wish to
+ combine the result of nearest in one direction with another filter
+ in the other.
+*/
+
+static double
+impulse_kernel (double x, double r)
+{
+ return 1;
+}
+
+static int
+impulse_width (double r)
+{
+ return 1;
+}
+
+/* PIXMAN_KERNEL_BOX: Intersection of a box of width r with square
+ pixels. This is the smallest possible filter such that the output
+ image contains an equal contribution from all the input
+ pixels. Lots of software uses this. The function is a trapazoid of
+ width r+1, not a box.
+
+ When r == 1.0, PIXMAN_KERNEL_BOX, PIXMAN_KERNEL_LINEAR, and
+ PIXMAN_KERNEL_TENT all produce the same filter, allowing
+ them to be exchanged at this point.
+*/
+
+static double
+box_kernel (double x, double r)
+{
+ return MAX (0.0, MIN (MIN (r, 1.0),
+ MIN ((r + 1) / 2 - x, (r + 1) / 2 + x)));
+}
+
+static int
+box_width (double r)
+{
+ return r < 1.0 ? 2 : ceil(r + 1);
+}
+
+/* PIXMAN_KERNEL_LINEAR: Weighted sum of the two pixels nearest the
+ center, or a triangle of width 2. This matches
+ PIXMAN_FILTER_BILINEAR. This is useful if you wish to combine the
+ result of bilinear in one direction with another filter in the
+ other. This is not a good filter if r > 1. You may actually want
+ PIXMAN_FILTER_TENT.
+
+ When r == 1.0, PIXMAN_KERNEL_BOX, PIXMAN_KERNEL_LINEAR, and
+ PIXMAN_KERNEL_TENT all produce the same filter, allowing
+ them to be exchanged at this point.
+*/
+
+static double
+linear_kernel (double x, double r)
+{
+ return MAX (1.0 - fabs(x), 0.0);
+}
+
+static int
+linear_width (double r)
+{
+ return 2;
+}
+
+/* Cubic functions described in the Mitchell-Netravali paper.
+ http://mentallandscape.com/Papers_siggraph88.pdf. This describes
+ all possible cubic functions that can be used for sampling.
+*/
+
+static double
+general_cubic (double x, double r, double B, double C)
+{
+ double ax;
+ if (r < 1.0)
+ return
+ general_cubic(x * 2 - .5, r * 2, B, C) +
+ general_cubic(x * 2 + .5, r * 2, B, C);
+
+ ax = fabs (x / r);
+
+ if (ax < 1)
+ {
+ return (((12 - 9 * B - 6 * C) * ax +
+ (-18 + 12 * B + 6 * C)) * ax * ax +
+ (6 - 2 * B)) / 6;
+ }
+ else if (ax < 2)
+ {
+ return ((((-B - 6 * C) * ax +
+ (6 * B + 30 * C)) * ax +
+ (-12 * B - 48 * C)) * ax +
+ (8 * B + 24 * C)) / 6;
+ }
+ else
+ {
+ return 0.0;
+ }
+}
+
+static int
+cubic_width (double r)
+{
+ return MAX (2, ceil (r * 4));
+}
+
+/* PIXMAN_KERNEL_CATMULL_ROM: Catmull-Rom interpolation. Often called
+ "cubic interpolation", "b-spline", or just "cubic" by other
+ software. This filter has negative values so it can produce ringing
+ and output pixels outside the range of input pixels. This is very
+ close to lanczos2 so there is no reason to supply that as well.
+*/
+
+static double
+cubic_kernel (double x, double r)
+{
+ return general_cubic (x, r, 0.0, 0.5);
+}
+
+/* PIXMAN_KERNEL_MITCHELL: Cubic recommended by the Mitchell-Netravali
+ paper. This has negative values and because the values at +/-1 are
+ not zero it does not interpolate the pixels, meaning it will change
+ an image even if there is no translation.
+*/
+
+static double
+mitchell_kernel (double x, double r)
+{
+ return general_cubic (x, r, 1/3.0, 1/3.0);
+}
+
+/* PIXMAN_KERNEL_NOTCH: Cubic recommended by the Mitchell-Netravali
+ paper to remove postaliasing artifacts. This does not remove
+ aliasing already present in the source image, though it may appear
+ to due to it's excessive blurriness. In any case this is more
+ useful than gaussian for image reconstruction.
+*/
+
+static double
+notch_kernel (double x, double r)
+{
+ return general_cubic (x, r, 1.5, -0.25);
+}
+
+/* PIXMAN_KERNEL_LANCZOS3: lanczos windowed sinc function from -3 to
+ +3. Very popular with high-end software though I think any
+ advantage over cubics is hidden by quantization and programming
+ mistakes. You will see LANCZOS5 or even 7 sometimes.
+*/
+
+static double
+sinc (double x)
+{
+ return x ? sin (M_PI * x) / (M_PI * x) : 1.0;
+}
+
+static double
+lanczos (double x, double n)
+{
+ return fabs (x) < n ? sinc (x) * sinc (x * (1.0 / n)) : 0.0;
+}
+
+static double
+lanczos3_kernel (double x, double r)
+{
+ if (r < 1.0)
+ return
+ lanczos3_kernel (x * 2 - .5, r * 2) +
+ lanczos3_kernel (x * 2 + .5, r * 2);
+ else
+ return lanczos (x / r, 3.0);
+}
+
+static int
+lanczos3_width (double r)
+{
+ return MAX (2, ceil (r * 6));
+}
+
+/* PIXMAN_KERNEL_LANCZOS3_STRETCHED - The LANCZOS3 kernel widened by
+ 4/3. Recommended by Jim Blinn
+ http://graphics.cs.cmu.edu/nsp/course/15-462/Fall07/462/papers/jaggy.pdf
+*/
+
+static double
+nice_kernel (double x, double r)
+{
+ return lanczos3_kernel (x, r * (4.0/3));
+}
+
+static int
+nice_width (double r)
+{
+ return MAX (2.0, ceil (r * 8));
+}
+
+/* PIXMAN_KERNEL_TENT: Triangle of width 2r. Lots of software uses
+ this as a "better" filter, twice the size of a box but smaller than
+ a cubic.
+
+ When r == 1.0, PIXMAN_KERNEL_BOX, PIXMAN_KERNEL_LINEAR, and
+ PIXMAN_KERNEL_TENT all produce the same filter, allowing
+ them to be exchanged at this point.
+*/
+
+static double
+tent_kernel (double x, double r)
+{
+ if (r < 1.0)
+ return box_kernel(x, r);
+ else
+ return MAX (1.0 - fabs(x / r), 0.0);
+}
+
+static int
+tent_width (double r)
+{
+ return r < 1.0 ? 2 : ceil(2 * r);
+}
+
+
+static const filter_info_t filters[] =
+{
+ { KERNEL_IMPULSE, impulse_kernel, impulse_width },
+ { KERNEL_BOX, box_kernel, box_width },
+ { KERNEL_LINEAR, linear_kernel, linear_width },
+ { KERNEL_MITCHELL, mitchell_kernel, cubic_width },
+ { KERNEL_NOTCH, notch_kernel, cubic_width },
+ { KERNEL_CATMULL_ROM, cubic_kernel, cubic_width },
+ { KERNEL_LANCZOS3, lanczos3_kernel, lanczos3_width },
+ { KERNEL_LANCZOS3_STRETCHED,nice_kernel, nice_width },
+ { KERNEL_TENT, tent_kernel, tent_width }
+};
+
+/* Fills in one dimension of the filter array */
+static void get_filter(kernel_t filter, double r,
+ int width, int subsample,
+ pixman_fixed_t* out)
+{
+ int i;
+ pixman_fixed_t *p = out;
+ int n_phases = 1 << subsample;
+ double step = 1.0 / n_phases;
+ kernel_func_t func = filters[filter].func;
+
+ /* special-case the impulse filter: */
+ if (width <= 1)
+ {
+ for (i = 0; i < n_phases; ++i)
+ *p++ = pixman_fixed_1;
+ return;
+ }
+
+ for (i = 0; i < n_phases; ++i)
+ {
+ double frac = (i + .5) * step;
+ /* Center of left-most pixel: */
+ double x1 = ceil (frac - width / 2.0 - 0.5) - frac + 0.5;
+ double total = 0;
+ pixman_fixed_t new_total = 0;
+ int j;
+
+ for (j = 0; j < width; ++j)
+ {
+ double v = func(x1 + j, r);
+ total += v;
+ p[j] = pixman_double_to_fixed (v);
+ }
+
+ /* Normalize */
+ total = 1 / total;
+ for (j = 0; j < width; ++j)
+ new_total += (p[j] *= total);
+
+ /* Put any error on center pixel */
+ p[width / 2] += (pixman_fixed_1 - new_total);
+
+ p += width;
+ }
+}
+
+
+/* Create the parameter list for a SEPARABLE_CONVOLUTION filter
+ * with the given kernels and scale parameters.
+ */
+static pixman_fixed_t *
+create_separable_convolution (int *n_values,
+ kernel_t xfilter,
+ double sx,
+ kernel_t yfilter,
+ double sy)
+{
+ int xwidth, xsubsample, ywidth, ysubsample, size_x, size_y;
+ pixman_fixed_t *params;
+
+ xwidth = filters[xfilter].width(sx);
+ xsubsample = 0;
+ if (xwidth > 1)
+ while (sx * (1 << xsubsample) <= 128.0) xsubsample++;
+ size_x = (1 << xsubsample) * xwidth;
+
+ ywidth = filters[yfilter].width(sy);
+ ysubsample = 0;
+ if (ywidth > 1)
+ while (sy * (1 << ysubsample) <= 128.0) ysubsample++;
+ size_y = (1 << ysubsample) * ywidth;
+
+ *n_values = 4 + size_x + size_y;
+ params = malloc (*n_values * sizeof (pixman_fixed_t));
+ if (!params) return 0;
+
+ params[0] = pixman_int_to_fixed (xwidth);
+ params[1] = pixman_int_to_fixed (ywidth);
+ params[2] = pixman_int_to_fixed (xsubsample);
+ params[3] = pixman_int_to_fixed (ysubsample);
+
+ get_filter(xfilter, sx, xwidth, xsubsample, params + 4);
+ get_filter(yfilter, sy, ywidth, ysubsample, params + 4 + size_x);
+
+ return params;
+}
+
+/* ========================================================================== */
+
static cairo_bool_t
_pixman_image_set_properties (pixman_image_t *pixman_image,
const cairo_pattern_t *pattern,
@@ -605,16 +918,58 @@ _pixman_image_set_properties (pixman_image_t *pixman_image,
else
{
pixman_filter_t pixman_filter;
+ kernel_t kernel;
+ double dx, dy;
+
+ /* Compute scale factors from the pattern matrix. These scale
+ * factors are from user to pattern space, and as such they
+ * are greater than 1.0 for downscaling and less than 1.0 for
+ * upscaling. The factors are the size of an axis-aligned
+ * rectangle with the same area as the parallelgram a 1x1
+ * square transforms to.
+ */
+ dx = hypot (pattern->matrix.xx, pattern->matrix.xy);
+ dy = hypot (pattern->matrix.yx, pattern->matrix.yy);
+
+ /* Clip at maximum pixman_fixed number. Besides making it
+ * passable to pixman, this avoids errors from inf and nan.
+ */
+ if (! (dx < 0x7FFF)) dx = 0x7FFF;
+ if (! (dy < 0x7FFF)) dy = 0x7FFF;
switch (pattern->filter) {
case CAIRO_FILTER_FAST:
pixman_filter = PIXMAN_FILTER_FAST;
break;
case CAIRO_FILTER_GOOD:
- pixman_filter = PIXMAN_FILTER_GOOD;
+ pixman_filter = PIXMAN_FILTER_SEPARABLE_CONVOLUTION;
+ kernel = KERNEL_BOX;
+ /* Clip the filter size to prevent extreme slowness. This
+ value could be raised if 2-pass filtering is done */
+ if (dx > 16.0) dx = 16.0;
+ if (dy > 16.0) dy = 16.0;
+ /* Match the bilinear filter for scales > .75: */
+ if (dx < 1.0/0.75) dx = 1.0;
+ if (dy < 1.0/0.75) dy = 1.0;
break;
case CAIRO_FILTER_BEST:
- pixman_filter = PIXMAN_FILTER_BEST;
+ pixman_filter = PIXMAN_FILTER_SEPARABLE_CONVOLUTION;
+ kernel = KERNEL_CATMULL_ROM; /* LANCZOS3 is better but not much */
+ /* Clip the filter size to prevent extreme slowness. This
+ value could be raised if 2-pass filtering is done */
+ if (dx > 16.0) { dx = 16.0; kernel = KERNEL_BOX; }
+ /* blur up to 2x scale, then blend to square pixels for larger: */
+ else if (dx < 1.0) {
+ if (dx < 1.0/128) dx = 1.0/127;
+ else if (dx < 0.5) dx = 1.0 / (1.0 / dx - 1.0);
+ else dx = 1.0;
+ }
+ if (dy > 16.0) { dy = 16.0; kernel = KERNEL_BOX; }
+ else if (dy < 1.0) {
+ if (dy < 1.0/128) dy = 1.0/127;
+ else if (dy < 0.5) dy = 1.0 / (1.0 / dy - 1.0);
+ else dy = 1.0;
+ }
break;
case CAIRO_FILTER_NEAREST:
pixman_filter = PIXMAN_FILTER_NEAREST;
@@ -632,7 +987,17 @@ _pixman_image_set_properties (pixman_image_t *pixman_image,
pixman_filter = PIXMAN_FILTER_BEST;
}
- pixman_image_set_filter (pixman_image, pixman_filter, NULL, 0);
+ if (pixman_filter == PIXMAN_FILTER_SEPARABLE_CONVOLUTION) {
+ int n_params;
+ pixman_fixed_t *params;
+ params = create_separable_convolution
+ (&n_params, kernel, dx, kernel, dy);
+ pixman_image_set_filter (pixman_image, pixman_filter,
+ params, n_params);
+ free (params);
+ } else {
+ pixman_image_set_filter (pixman_image, pixman_filter, NULL, 0);
+ }
}
{
@@ -835,7 +1200,7 @@ _pixman_image_for_recording (cairo_image_surface_t *dst,
done:
/* filter with gaussian */
blurred_surface = _cairo_image_gaussian_filter (clone, &pattern->base);
-
+
pixman_image = pixman_image_ref (((cairo_image_surface_t *)blurred_surface)->pixman_image);
cairo_surface_destroy (blurred_surface);
cairo_surface_destroy (clone);
@@ -854,16 +1219,6 @@ done:
return pixman_image;
}
-static inline cairo_bool_t
-_surface_type_is_image_buffer (cairo_surface_type_t type)
-{
-#if CAIRO_HAS_TG_SURFACE
- return type == CAIRO_SURFACE_TYPE_IMAGE || type == CAIRO_SURFACE_TYPE_TG;
-#else
- return type == CAIRO_SURFACE_TYPE_IMAGE;
-#endif
-}
-
static pixman_image_t *
_pixman_image_for_surface (cairo_image_surface_t *dst,
const cairo_surface_pattern_t *pattern,
@@ -886,27 +1241,26 @@ _pixman_image_for_surface (cairo_image_surface_t *dst,
is_mask, extents, sample,
ix, iy);
- if (_surface_type_is_image_buffer (pattern->surface->type) &&
+ if (pattern->surface->type == CAIRO_SURFACE_TYPE_IMAGE &&
(! is_mask || ! pattern->base.has_component_alpha ||
(pattern->surface->content & CAIRO_CONTENT_COLOR) == 0))
{
cairo_surface_t *defer_free = NULL;
cairo_image_surface_t *source = (cairo_image_surface_t *) pattern->surface;
- cairo_image_buffer_t image_buffer;
+ cairo_surface_type_t type;
if (_cairo_surface_is_snapshot (&source->base)) {
defer_free = _cairo_surface_snapshot_get_target (&source->base);
source = (cairo_image_surface_t *) defer_free;
}
- if (_surface_type_is_image_buffer (source->base.backend->type)) {
- _get_image_buffer (source, &image_buffer);
-
+ type = source->base.backend->type;
+ if (type == CAIRO_SURFACE_TYPE_IMAGE) {
if (extend != CAIRO_EXTEND_NONE &&
sample->x >= 0 &&
sample->y >= 0 &&
- sample->x + sample->width <= image_buffer.width &&
- sample->y + sample->height <= image_buffer.height)
+ sample->x + sample->width <= source->width &&
+ sample->y + sample->height <= source->height)
{
extend = CAIRO_EXTEND_NONE;
}
@@ -914,8 +1268,8 @@ _pixman_image_for_surface (cairo_image_surface_t *dst,
if (sample->width == 1 && sample->height == 1) {
if (sample->x < 0 ||
sample->y < 0 ||
- sample->x >= image_buffer.width ||
- sample->y >= image_buffer.height)
+ sample->x >= source->width ||
+ sample->y >= source->height)
{
if (extend == CAIRO_EXTEND_NONE) {
cairo_surface_destroy (defer_free);
@@ -924,7 +1278,8 @@ _pixman_image_for_surface (cairo_image_surface_t *dst,
}
else
{
- pixman_image = _pixel_to_solid (&image_buffer, sample->x, sample->y);
+ pixman_image = _pixel_to_solid (source,
+ sample->x, sample->y);
if (pixman_image) {
cairo_surface_destroy (defer_free);
return pixman_image;
@@ -948,16 +1303,16 @@ _pixman_image_for_surface (cairo_image_surface_t *dst,
return blurred_pixman_image;
}
else
- return pixman_image_ref (image_buffer.pixman_image);
+ return pixman_image_ref (source->pixman_image);
}
#endif
if (pattern->base.filter != CAIRO_FILTER_GAUSSIAN) {
- pixman_image = pixman_image_create_bits (image_buffer.pixman_format,
- image_buffer.width,
- image_buffer.height,
- (uint32_t *) image_buffer.data,
- image_buffer.stride);
+ pixman_image = pixman_image_create_bits (source->pixman_format,
+ source->width,
+ source->height,
+ (uint32_t *) source->data,
+ source->stride);
if (unlikely (pixman_image == NULL)) {
cairo_surface_destroy (defer_free);
if (blurred_surface)
@@ -975,14 +1330,12 @@ _pixman_image_for_surface (cairo_image_surface_t *dst,
}
else
blurred_surface = _cairo_image_gaussian_filter (&source->base, &pattern->base);
- } else if (source->base.backend->type == CAIRO_SURFACE_TYPE_SUBSURFACE) {
+ } else if (type == CAIRO_SURFACE_TYPE_SUBSURFACE) {
cairo_surface_subsurface_t *sub;
cairo_bool_t is_contained = FALSE;
sub = (cairo_surface_subsurface_t *) source;
- source = sub->target;
-
- _get_image_buffer (source, &image_buffer);
+ source = (cairo_image_surface_t *) sub->target;
if (sample->x >= 0 &&
sample->y >= 0 &&
@@ -994,7 +1347,7 @@ _pixman_image_for_surface (cairo_image_surface_t *dst,
if (sample->width == 1 && sample->height == 1) {
if (is_contained) {
- pixman_image = _pixel_to_solid (&image_buffer,
+ pixman_image = _pixel_to_solid (source,
sub->extents.x + sample->x,
sub->extents.y + sample->y);
if (pixman_image)
@@ -1025,16 +1378,16 @@ _pixman_image_for_surface (cairo_image_surface_t *dst,
/* Avoid sub-byte offsets, force a copy in that case. */
if (pattern->base.filter != CAIRO_FILTER_GAUSSIAN) {
- if (PIXMAN_FORMAT_BPP (image_buffer.pixman_format) >= 8) {
- if (is_contained) {
- void *data = image_buffer.data
- + sub->extents.x * PIXMAN_FORMAT_BPP(image_buffer.pixman_format)/8
- + sub->extents.y * image_buffer.stride;
- pixman_image = pixman_image_create_bits (image_buffer.pixman_format,
- sub->extents.width,
- sub->extents.height,
- data,
- image_buffer.stride);
+ if (PIXMAN_FORMAT_BPP (source->pixman_format) >= 8) {
+ if (is_contained) {
+ void *data = source->data
+ + sub->extents.x * PIXMAN_FORMAT_BPP(source->pixman_format)/8
+ + sub->extents.y * source->stride;
+ pixman_image = pixman_image_create_bits (source->pixman_format,
+ sub->extents.width,
+ sub->extents.height,
+ data,
+ source->stride);
if (unlikely (pixman_image == NULL)) {
if (blurred_surface)
cairo_surface_destroy (blurred_surface);
@@ -1087,7 +1440,7 @@ _pixman_image_for_surface (cairo_image_surface_t *dst,
}
else
/* filter with gaussian */
- blurred_surface = _cairo_image_gaussian_filter (&image->base, &pattern->base);
+ blurred_surface = _cairo_image_gaussian_filter (&image->base, &pattern->base);
cleanup = malloc (sizeof (*cleanup));
if (unlikely (cleanup == NULL)) {
diff --git a/src/cairo-image-surface-inline.h b/src/cairo-image-surface-inline.h
index 743d5fd3e..743d5fd3e 100755..100644
--- a/src/cairo-image-surface-inline.h
+++ b/src/cairo-image-surface-inline.h
diff --git a/src/cairo-image-surface-private.h b/src/cairo-image-surface-private.h
index 8ca694c5e..8ca694c5e 100755..100644
--- a/src/cairo-image-surface-private.h
+++ b/src/cairo-image-surface-private.h
diff --git a/src/cairo-image-surface.c b/src/cairo-image-surface.c
index b68f4a9e7..1948a1add 100755..100644
--- a/src/cairo-image-surface.c
+++ b/src/cairo-image-surface.c
@@ -48,6 +48,7 @@
#include "cairo-image-surface-inline.h"
#include "cairo-paginated-private.h"
#include "cairo-pattern-private.h"
+#include "cairo-pixman-private.h"
#include "cairo-recording-surface-private.h"
#include "cairo-region-private.h"
#include "cairo-scaled-font-private.h"
@@ -123,7 +124,7 @@ _cairo_image_shadow_caches_destroy (void)
cairo_surface_destroy (shadow->surface);
free (shadow);
}
- shadow_caches_size = 0;
+ shadow_caches_size = 0;
}
}
@@ -222,7 +223,12 @@ _cairo_format_from_pixman_format (pixman_format_code_t pixman_format)
return CAIRO_FORMAT_A1;
case PIXMAN_r5g6b5:
return CAIRO_FORMAT_RGB16_565;
+#if PIXMAN_VERSION >= PIXMAN_VERSION_ENCODE(0,22,0)
case PIXMAN_r8g8b8a8: case PIXMAN_r8g8b8x8:
+#endif
+#if PIXMAN_VERSION >= PIXMAN_VERSION_ENCODE(0,27,2)
+ case PIXMAN_a8r8g8b8_sRGB:
+#endif
case PIXMAN_a8b8g8r8: case PIXMAN_x8b8g8r8: case PIXMAN_r8g8b8:
case PIXMAN_b8g8r8: case PIXMAN_b5g6r5:
case PIXMAN_a1r5g5b5: case PIXMAN_x1r5g5b5: case PIXMAN_a1b5g5r5:
@@ -239,7 +245,9 @@ _cairo_format_from_pixman_format (pixman_format_code_t pixman_format)
case PIXMAN_a2b10g10r10:
case PIXMAN_x2b10g10r10:
case PIXMAN_a2r10g10b10:
+#if PIXMAN_VERSION >= PIXMAN_VERSION_ENCODE(0,22,0)
case PIXMAN_x14r6g6b6:
+#endif
default:
return CAIRO_FORMAT_INVALID;
}
@@ -535,7 +543,7 @@ _cairo_image_surface_create_with_content (cairo_content_t content,
* <informalexample><programlisting>
* int stride;
* unsigned char *data;
- * #cairo_surface_t *surface;
+ * cairo_surface_t *surface;
*
* stride = cairo_format_stride_for_width (format, width);
* data = malloc (stride * height);
@@ -883,12 +891,12 @@ _cairo_image_surface_snapshot (void *abstract_surface)
return &clone->base;
image->pixman_image = NULL;
+ image->owns_data = FALSE;
clone->transparency = image->transparency;
clone->color = image->color;
- clone->owns_data = image->owns_data;
- image->owns_data = FALSE;
+ clone->owns_data = TRUE;
return &clone->base;
}
@@ -964,8 +972,9 @@ _cairo_image_surface_finish (void *abstract_surface)
}
if (surface->parent) {
- cairo_surface_destroy (surface->parent);
+ cairo_surface_t *parent = surface->parent;
surface->parent = NULL;
+ cairo_surface_destroy (parent);
}
_cairo_image_shadow_caches_destroy ();
@@ -1034,7 +1043,7 @@ _cairo_image_surface_paint (void *abstract_surface,
const cairo_clip_t *clip)
{
cairo_image_surface_t *surface = abstract_surface;
- cairo_int_status_t status;
+ cairo_int_status_t status;
TRACE ((stderr, "%s (surface=%d)\n",
__FUNCTION__, surface->base.unique_id));
@@ -1322,7 +1331,7 @@ _cairo_image_surface_shadow_surface (void *surface,
else
shadow_width = width;
}
-
+
if (height < MIN_IMAGE_SHADOW_SIZE)
shadow_height = height;
else if (has_blur) {
diff --git a/boilerplate/cairo-boilerplate-tg.c b/src/cairo-line-inline.h
index 018f7be9f..71cc5e7eb 100755..100644
--- a/boilerplate/cairo-boilerplate-tg.c
+++ b/src/cairo-line-inline.h
@@ -1,5 +1,7 @@
-/*
- * Copyright © 2012 SCore Corporation
+/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
+/* cairo - a vector graphics library with display and print output
+ *
+ * Copyright © 2014 Intel Corporation
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
@@ -24,58 +26,23 @@
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
* the specific language governing rights and limitations.
*
- * Author: Taekyun Kim (podain77@gmail.com)
+ * The Original Code is the cairo graphics library.
+ *
*/
-#include "cairo-boilerplate-private.h"
+#ifndef CAIRO_LINE_INLINE_H
+#define CAIRO_LINE_INLINE_H
-#include <cairo-tg.h>
-#include <assert.h>
+#include "cairo-types-private.h"
+#include "cairo-compiler-private.h"
+#include "cairo-fixed-private.h"
+#include "cairo-line-private.h"
-static cairo_surface_t *
-_cairo_boilerplate_tg_create_surface (const char *name,
- cairo_content_t content,
- double width,
- double height,
- double max_width,
- double max_height,
- cairo_boilerplate_mode_t mode,
- void **closure)
+static inline int
+cairo_lines_equal (const cairo_line_t *a, const cairo_line_t *b)
{
- cairo_format_t format;
-
- if (content == CAIRO_CONTENT_COLOR_ALPHA)
- {
- format = CAIRO_FORMAT_ARGB32;
- }
- else if (content == CAIRO_CONTENT_COLOR)
- {
- format = CAIRO_FORMAT_RGB24;
- }
- else
- {
- assert (0);
- return NULL;
- }
-
- *closure = NULL;
-
- return cairo_tg_surface_create (format, ceil (width), ceil (height));
+ return (a->p1.x == b->p1.x && a->p1.y == b->p1.y &&
+ a->p2.x == b->p2.x && a->p2.y == b->p2.y);
}
-static const cairo_boilerplate_target_t targets[] =
-{
- {
- "tg", "tg", NULL, NULL,
- CAIRO_SURFACE_TYPE_TG, CAIRO_CONTENT_COLOR_ALPHA, 0,
- NULL,
- _cairo_boilerplate_tg_create_surface,
- cairo_surface_create_similar,
- NULL, NULL,
- _cairo_boilerplate_get_image_surface,
- cairo_surface_write_to_png,
- NULL, NULL, NULL,
- TRUE, FALSE, FALSE
- }
-};
-CAIRO_BOILERPLATE (tg, targets)
+#endif /* CAIRO_LINE_INLINE_H */
diff --git a/src/cairo-tg.h b/src/cairo-line-private.h
index 97be60153..08bf4b358 100755..100644
--- a/src/cairo-tg.h
+++ b/src/cairo-line-private.h
@@ -1,5 +1,6 @@
-/*
- * Copyright © 2012 SCore Corporation
+/* cairo - a vector graphics library with display and print output
+ *
+ * Copyright © 2014 Intel Corporation, Inc
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
@@ -24,47 +25,27 @@
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
* the specific language governing rights and limitations.
*
- * Author: Taekyun Kim (podain77@gmail.com)
+ * The Original Code is the cairo graphics library.
+ *
+ * The Initial Developer of the Original Code is University of Southern
+ * California.
+ *
*/
-#ifndef CAIRO_TG_H
-#define CAIRO_TG_H
+#ifndef CAIRO_LINE_PRIVATE_H
+#define CAIRO_LINE_PRIVATE_H
-#include "cairo.h"
-
-#if CAIRO_HAS_TG_SURFACE
+#include "cairo-types-private.h"
+#include "cairo-error-private.h"
+#include "cairo-compiler-private.h"
CAIRO_BEGIN_DECLS
-cairo_public cairo_surface_t *
-cairo_tg_surface_create (cairo_format_t format,
- int width,
- int height);
-
-cairo_public cairo_surface_t *
-cairo_tg_surface_create_for_data (unsigned char *data,
- cairo_format_t format,
- int width,
- int height,
- int stride);
-
-cairo_public unsigned char *
-cairo_tg_surface_get_data (cairo_surface_t *surface);
-
-cairo_public cairo_format_t
-cairo_tg_surface_get_format (cairo_surface_t *surface);
-
-cairo_public int
-cairo_tg_surface_get_width (cairo_surface_t *surface);
-
-cairo_public int
-cairo_tg_surface_get_height (cairo_surface_t *surface);
-
-cairo_public int
-cairo_tg_surface_get_stride (cairo_surface_t *surface);
+cairo_private int
+cairo_lines_compare_at_y(const cairo_line_t *a,
+ const cairo_line_t *b,
+ int y);
CAIRO_END_DECLS
-#endif /* CAIRO_HAS_TG_SURFACE */
-
-#endif /* CAIRO_TG_H */
+#endif /* CAIRO_LINE_PRIVATE_H */
diff --git a/src/cairo-line.c b/src/cairo-line.c
new file mode 100644
index 000000000..cb13927bd
--- /dev/null
+++ b/src/cairo-line.c
@@ -0,0 +1,306 @@
+/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
+/*
+ * Copyright © 2004 Carl Worth
+ * Copyright © 2006 Red Hat, Inc.
+ * Copyright © 2008 Chris Wilson
+ * Copyright © 2014 Intel Corporation
+ *
+ * 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 Keith Packard
+ *
+ * Contributor(s):
+ * Carl D. Worth <cworth@cworth.org>
+ * Chris Wilson <chris@chris-wilson.co.uk>
+ *
+ */
+
+#include "cairoint.h"
+
+#include "cairo-line-inline.h"
+#include "cairo-slope-private.h"
+
+static int
+line_compare_for_y_against_x (const cairo_line_t *a,
+ int32_t y,
+ int32_t x)
+{
+ int32_t adx, ady;
+ int32_t dx, dy;
+ cairo_int64_t L, R;
+
+ if (x < a->p1.x && x < a->p2.x)
+ return 1;
+ if (x > a->p1.x && x > a->p2.x)
+ return -1;
+
+ adx = a->p2.x - a->p1.x;
+ dx = x - a->p1.x;
+
+ if (adx == 0)
+ return -dx;
+ if (dx == 0 || (adx ^ dx) < 0)
+ return adx;
+
+ dy = y - a->p1.y;
+ ady = a->p2.y - a->p1.y;
+
+ L = _cairo_int32x32_64_mul (dy, adx);
+ R = _cairo_int32x32_64_mul (dx, ady);
+
+ return _cairo_int64_cmp (L, R);
+}
+
+/*
+ * We need to compare the x-coordinates of a pair of lines for a particular y,
+ * without loss of precision.
+ *
+ * The x-coordinate along an edge for a given y is:
+ * X = A_x + (Y - A_y) * A_dx / A_dy
+ *
+ * So the inequality we wish to test is:
+ * A_x + (Y - A_y) * A_dx / A_dy ∘ B_x + (Y - B_y) * B_dx / B_dy,
+ * where ∘ is our inequality operator.
+ *
+ * By construction, we know that A_dy and B_dy (and (Y - A_y), (Y - B_y)) are
+ * all positive, so we can rearrange it thus without causing a sign change:
+ * A_dy * B_dy * (A_x - B_x) ∘ (Y - B_y) * B_dx * A_dy
+ * - (Y - A_y) * A_dx * B_dy
+ *
+ * Given the assumption that all the deltas fit within 32 bits, we can compute
+ * this comparison directly using 128 bit arithmetic. For certain, but common,
+ * input we can reduce this down to a single 32 bit compare by inspecting the
+ * deltas.
+ *
+ * (And put the burden of the work on developing fast 128 bit ops, which are
+ * required throughout the tessellator.)
+ *
+ * See the similar discussion for _slope_compare().
+ */
+static int
+lines_compare_x_for_y_general (const cairo_line_t *a,
+ const cairo_line_t *b,
+ int32_t y)
+{
+ /* XXX: We're assuming here that dx and dy will still fit in 32
+ * bits. That's not true in general as there could be overflow. We
+ * should prevent that before the tessellation algorithm
+ * begins.
+ */
+ int32_t dx;
+ int32_t adx, ady;
+ int32_t bdx, bdy;
+ enum {
+ HAVE_NONE = 0x0,
+ HAVE_DX = 0x1,
+ HAVE_ADX = 0x2,
+ HAVE_DX_ADX = HAVE_DX | HAVE_ADX,
+ HAVE_BDX = 0x4,
+ HAVE_DX_BDX = HAVE_DX | HAVE_BDX,
+ HAVE_ADX_BDX = HAVE_ADX | HAVE_BDX,
+ HAVE_ALL = HAVE_DX | HAVE_ADX | HAVE_BDX
+ } have_dx_adx_bdx = HAVE_ALL;
+
+ ady = a->p2.y - a->p1.y;
+ adx = a->p2.x - a->p1.x;
+ if (adx == 0)
+ have_dx_adx_bdx &= ~HAVE_ADX;
+
+ bdy = b->p2.y - b->p1.y;
+ bdx = b->p2.x - b->p1.x;
+ if (bdx == 0)
+ have_dx_adx_bdx &= ~HAVE_BDX;
+
+ dx = a->p1.x - b->p1.x;
+ if (dx == 0)
+ have_dx_adx_bdx &= ~HAVE_DX;
+
+#define L _cairo_int64x32_128_mul (_cairo_int32x32_64_mul (ady, bdy), dx)
+#define A _cairo_int64x32_128_mul (_cairo_int32x32_64_mul (adx, bdy), y - a->p1.y)
+#define B _cairo_int64x32_128_mul (_cairo_int32x32_64_mul (bdx, ady), y - b->p1.y)
+ switch (have_dx_adx_bdx) {
+ default:
+ case HAVE_NONE:
+ return 0;
+ case HAVE_DX:
+ /* A_dy * B_dy * (A_x - B_x) ∘ 0 */
+ return dx; /* ady * bdy is positive definite */
+ case HAVE_ADX:
+ /* 0 ∘ - (Y - A_y) * A_dx * B_dy */
+ return adx; /* bdy * (y - a->top.y) is positive definite */
+ case HAVE_BDX:
+ /* 0 ∘ (Y - B_y) * B_dx * A_dy */
+ return -bdx; /* ady * (y - b->top.y) is positive definite */
+ case HAVE_ADX_BDX:
+ /* 0 ∘ (Y - B_y) * B_dx * A_dy - (Y - A_y) * A_dx * B_dy */
+ if ((adx ^ bdx) < 0) {
+ return adx;
+ } else if (a->p1.y == b->p1.y) { /* common origin */
+ cairo_int64_t adx_bdy, bdx_ady;
+
+ /* ∴ A_dx * B_dy ∘ B_dx * A_dy */
+
+ adx_bdy = _cairo_int32x32_64_mul (adx, bdy);
+ bdx_ady = _cairo_int32x32_64_mul (bdx, ady);
+
+ return _cairo_int64_cmp (adx_bdy, bdx_ady);
+ } else
+ return _cairo_int128_cmp (A, B);
+ case HAVE_DX_ADX:
+ /* A_dy * (A_x - B_x) ∘ - (Y - A_y) * A_dx */
+ if ((-adx ^ dx) < 0) {
+ return dx;
+ } else {
+ cairo_int64_t ady_dx, dy_adx;
+
+ ady_dx = _cairo_int32x32_64_mul (ady, dx);
+ dy_adx = _cairo_int32x32_64_mul (a->p1.y - y, adx);
+
+ return _cairo_int64_cmp (ady_dx, dy_adx);
+ }
+ case HAVE_DX_BDX:
+ /* B_dy * (A_x - B_x) ∘ (Y - B_y) * B_dx */
+ if ((bdx ^ dx) < 0) {
+ return dx;
+ } else {
+ cairo_int64_t bdy_dx, dy_bdx;
+
+ bdy_dx = _cairo_int32x32_64_mul (bdy, dx);
+ dy_bdx = _cairo_int32x32_64_mul (y - b->p1.y, bdx);
+
+ return _cairo_int64_cmp (bdy_dx, dy_bdx);
+ }
+ case HAVE_ALL:
+ /* XXX try comparing (a->p2.x - b->p2.x) et al */
+ return _cairo_int128_cmp (L, _cairo_int128_sub (B, A));
+ }
+#undef B
+#undef A
+#undef L
+}
+
+static int
+lines_compare_x_for_y (const cairo_line_t *a,
+ const cairo_line_t *b,
+ int32_t y)
+{
+ /* If the sweep-line is currently on an end-point of a line,
+ * then we know its precise x value (and considering that we often need to
+ * compare events at end-points, this happens frequently enough to warrant
+ * special casing).
+ */
+ enum {
+ HAVE_NEITHER = 0x0,
+ HAVE_AX = 0x1,
+ HAVE_BX = 0x2,
+ HAVE_BOTH = HAVE_AX | HAVE_BX
+ } have_ax_bx = HAVE_BOTH;
+ int32_t ax, bx;
+
+ if (y == a->p1.y)
+ ax = a->p1.x;
+ else if (y == a->p2.y)
+ ax = a->p2.x;
+ else
+ have_ax_bx &= ~HAVE_AX;
+
+ if (y == b->p1.y)
+ bx = b->p1.x;
+ else if (y == b->p2.y)
+ bx = b->p2.x;
+ else
+ have_ax_bx &= ~HAVE_BX;
+
+ switch (have_ax_bx) {
+ default:
+ case HAVE_NEITHER:
+ return lines_compare_x_for_y_general (a, b, y);
+ case HAVE_AX:
+ return -line_compare_for_y_against_x (b, y, ax);
+ case HAVE_BX:
+ return line_compare_for_y_against_x (a, y, bx);
+ case HAVE_BOTH:
+ return ax - bx;
+ }
+}
+
+static int bbox_compare (const cairo_line_t *a,
+ const cairo_line_t *b)
+{
+ int32_t amin, amax;
+ int32_t bmin, bmax;
+
+ if (a->p1.x < a->p2.x) {
+ amin = a->p1.x;
+ amax = a->p2.x;
+ } else {
+ amin = a->p2.x;
+ amax = a->p1.x;
+ }
+
+ if (b->p1.x < b->p2.x) {
+ bmin = b->p1.x;
+ bmax = b->p2.x;
+ } else {
+ bmin = b->p2.x;
+ bmax = b->p1.x;
+ }
+
+ if (amax < bmin)
+ return -1;
+
+ if (amin > bmax)
+ return +1;
+
+ return 0;
+}
+
+int cairo_lines_compare_at_y (const cairo_line_t *a,
+ const cairo_line_t *b,
+ int y)
+{
+ cairo_slope_t sa, sb;
+ int ret;
+
+ if (cairo_lines_equal (a, b))
+ return 0;
+
+ /* Don't bother solving for abscissa if the edges' bounding boxes
+ * can be used to order them.
+ */
+ ret = bbox_compare (a, b);
+ if (ret)
+ return ret;
+
+ ret = lines_compare_x_for_y (a, b, y);
+ if (ret)
+ return ret;
+
+ _cairo_slope_init (&sa, &a->p1, &a->p2);
+ _cairo_slope_init (&sb, &b->p1, &b->p2);
+
+ return _cairo_slope_compare (&sb, &sa);
+}
diff --git a/src/cairo-list-inline.h b/src/cairo-list-inline.h
index d00f40e98..0955178d2 100755..100644
--- a/src/cairo-list-inline.h
+++ b/src/cairo-list-inline.h
@@ -145,9 +145,15 @@ __cairo_list_del (cairo_list_t *prev, cairo_list_t *next)
}
static inline void
-cairo_list_del (cairo_list_t *entry)
+_cairo_list_del (cairo_list_t *entry)
{
__cairo_list_del (entry->prev, entry->next);
+}
+
+static inline void
+cairo_list_del (cairo_list_t *entry)
+{
+ _cairo_list_del (entry);
cairo_list_init (entry);
}
diff --git a/src/cairo-list-private.h b/src/cairo-list-private.h
index 9f39b668f..9f39b668f 100755..100644
--- a/src/cairo-list-private.h
+++ b/src/cairo-list-private.h
diff --git a/src/cairo-lzw.c b/src/cairo-lzw.c
index de7f99983..de7f99983 100755..100644
--- a/src/cairo-lzw.c
+++ b/src/cairo-lzw.c
diff --git a/src/cairo-malloc-private.h b/src/cairo-malloc-private.h
index 1e2c67f8d..1e2c67f8d 100755..100644
--- a/src/cairo-malloc-private.h
+++ b/src/cairo-malloc-private.h
diff --git a/src/cairo-mask-compositor.c b/src/cairo-mask-compositor.c
index 31d116119..80bf0f5e6 100755..100644
--- a/src/cairo-mask-compositor.c
+++ b/src/cairo-mask-compositor.c
@@ -163,9 +163,10 @@ create_composite_mask (const cairo_mask_compositor_t *compositor,
struct blt_in info;
int i;
- surface = _cairo_surface_create_similar_scratch (dst, CAIRO_CONTENT_ALPHA,
- extents->bounded.width,
- extents->bounded.height);
+ surface = _cairo_surface_create_scratch (dst, CAIRO_CONTENT_ALPHA,
+ extents->bounded.width,
+ extents->bounded.height,
+ NULL);
if (unlikely (surface->status))
return surface;
@@ -346,9 +347,10 @@ clip_and_composite_combine (const cairo_mask_compositor_t *compositor,
cairo_status_t status;
int clip_x, clip_y;
- tmp = _cairo_surface_create_similar_scratch (dst, dst->content,
- extents->bounded.width,
- extents->bounded.height);
+ tmp = _cairo_surface_create_scratch (dst, dst->content,
+ extents->bounded.width,
+ extents->bounded.height,
+ NULL);
if (unlikely (tmp->status)) {
status = tmp->status;
goto cleanup;
diff --git a/src/cairo-matrix.c b/src/cairo-matrix.c
index ba975beae..ae498f515 100755..100644
--- a/src/cairo-matrix.c
+++ b/src/cairo-matrix.c
@@ -748,23 +748,32 @@ _cairo_matrix_is_integer_translation (const cairo_matrix_t *matrix,
return FALSE;
}
+#define SCALING_EPSILON _cairo_fixed_to_double(1)
+
+/* This only returns true if the matrix is 90 degree rotations or
+ * flips. It appears calling code is relying on this. It will return
+ * false for other rotations even if the scale is one. Approximations
+ * are allowed to handle matricies filled in using trig functions
+ * such as sin(M_PI_2).
+ */
cairo_bool_t
_cairo_matrix_has_unity_scale (const cairo_matrix_t *matrix)
{
- if (matrix->xy == 0.0 && matrix->yx == 0.0) {
- if (! (matrix->xx == 1.0 || matrix->xx == -1.0))
- return FALSE;
- if (! (matrix->yy == 1.0 || matrix->yy == -1.0))
- return FALSE;
- } else if (matrix->xx == 0.0 && matrix->yy == 0.0) {
- if (! (matrix->xy == 1.0 || matrix->xy == -1.0))
- return FALSE;
- if (! (matrix->yx == 1.0 || matrix->yx == -1.0))
- return FALSE;
- } else
- return FALSE;
-
- return TRUE;
+ /* check that the determinant is near +/-1 */
+ double det = _cairo_matrix_compute_determinant (matrix);
+ if (fabs (det * det - 1.0) < SCALING_EPSILON) {
+ /* check that one axis is close to zero */
+ if (fabs (matrix->xy) < SCALING_EPSILON &&
+ fabs (matrix->yx) < SCALING_EPSILON)
+ return TRUE;
+ if (fabs (matrix->xx) < SCALING_EPSILON &&
+ fabs (matrix->yy) < SCALING_EPSILON)
+ return TRUE;
+ /* If rotations are allowed then it must instead test for
+ * orthogonality. This is xx*xy+yx*yy ~= 0.
+ */
+ }
+ return FALSE;
}
/* By pixel exact here, we mean a matrix that is composed only of
diff --git a/src/cairo-mempool-private.h b/src/cairo-mempool-private.h
index a09f6ce51..a09f6ce51 100755..100644
--- a/src/cairo-mempool-private.h
+++ b/src/cairo-mempool-private.h
diff --git a/src/cairo-mempool.c b/src/cairo-mempool.c
index 96e4a62b2..751ede320 100755..100644
--- a/src/cairo-mempool.c
+++ b/src/cairo-mempool.c
@@ -157,7 +157,8 @@ get_buddy (cairo_mempool_t *pool, size_t offset, int bits)
{
struct _cairo_memblock *block;
- assert (offset + (1 << bits) <= pool->num_blocks);
+ if (offset + (1 << bits) >= pool->num_blocks)
+ return NULL; /* invalid */
if (BITTEST (pool, offset + (1 << bits) - 1))
return NULL; /* buddy is allocated */
diff --git a/src/cairo-mesh-pattern-rasterizer.c b/src/cairo-mesh-pattern-rasterizer.c
index 5342b3d22..86cd16833 100755..100644
--- a/src/cairo-mesh-pattern-rasterizer.c
+++ b/src/cairo-mesh-pattern-rasterizer.c
@@ -697,9 +697,9 @@ rasterize_bezier_patch (unsigned char *data, int width, int height, int stride,
cairo_point_double_t p[4][4], double col[4][4])
{
double pv[4][2][4], cstart[4], cend[4], dcstart[4], dcend[4];
- int vsteps, v, i, k;
+ int v, i, k;
- vsteps = 1 << vshift;
+ v = 1 << vshift;
/*
* pv[i][0] is the function (represented using forward
@@ -724,11 +724,12 @@ rasterize_bezier_patch (unsigned char *data, int width, int height, int stride,
for (i = 0; i < 4; ++i) {
cstart[i] = col[0][i];
cend[i] = col[1][i];
- dcstart[i] = (col[2][i] - col[0][i]) / vsteps;
- dcend[i] = (col[3][i] - col[1][i]) / vsteps;
+ dcstart[i] = (col[2][i] - col[0][i]) / v;
+ dcend[i] = (col[3][i] - col[1][i]) / v;
}
- for (v = 0; v <= vsteps; ++v) {
+ v++;
+ while (v--) {
cairo_point_double_t nodes[4];
for (i = 0; i < 4; ++i) {
nodes[i].x = pv[i][0][0];
diff --git a/src/cairo-misc.c b/src/cairo-misc.c
index bb37e1a0a..df8a4efc9 100755..100644
--- a/src/cairo-misc.c
+++ b/src/cairo-misc.c
@@ -156,6 +156,8 @@ cairo_status_to_string (cairo_status_t status)
return "invalid operation during mesh pattern construction";
case CAIRO_STATUS_DEVICE_FINISHED:
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";
default:
case CAIRO_STATUS_LAST_STATUS:
return "<unknown error status>";
@@ -757,6 +759,24 @@ _cairo_half_from_float (float f)
}
}
+#ifndef __BIONIC__
+# include <locale.h>
+
+const char *
+cairo_get_locale_decimal_point (void)
+{
+ struct lconv *locale_data = localeconv ();
+ return locale_data->decimal_point;
+}
+
+#else
+/* Android's Bionic libc doesn't provide decimal_point */
+const char *
+cairo_get_locale_decimal_point (void)
+{
+ return '.';
+}
+#endif
#ifdef _WIN32
diff --git a/src/cairo-mono-scan-converter.c b/src/cairo-mono-scan-converter.c
index 2a9546cf8..2a9546cf8 100755..100644
--- a/src/cairo-mono-scan-converter.c
+++ b/src/cairo-mono-scan-converter.c
diff --git a/src/cairo-mutex-impl-private.h b/src/cairo-mutex-impl-private.h
index 25223f3ea..25223f3ea 100755..100644
--- a/src/cairo-mutex-impl-private.h
+++ b/src/cairo-mutex-impl-private.h
diff --git a/src/cairo-mutex-list-private.h b/src/cairo-mutex-list-private.h
index d79a059ea..f46afadb0 100755..100644
--- a/src/cairo-mutex-list-private.h
+++ b/src/cairo-mutex-list-private.h
@@ -34,7 +34,6 @@
#ifndef CAIRO_FEATURES_H
/* This block is to just make this header file standalone */
#define CAIRO_MUTEX_DECLARE(mutex)
-#define CAIRO_RECURSIVE_MUTEX_DECLARE(mutex)
#endif
CAIRO_MUTEX_DECLARE (_cairo_pattern_solid_surface_cache_lock)
@@ -48,10 +47,6 @@ CAIRO_MUTEX_DECLARE (_cairo_scaled_glyph_page_cache_mutex)
CAIRO_MUTEX_DECLARE (_cairo_scaled_font_error_mutex)
CAIRO_MUTEX_DECLARE (_cairo_glyph_cache_mutex)
-#if CAIRO_HAS_TG_SURFACE
-CAIRO_RECURSIVE_MUTEX_DECLARE(_cairo_tg_scaled_glyph_mutex)
-#endif
-
#if CAIRO_HAS_FT_FONT
CAIRO_MUTEX_DECLARE (_cairo_ft_unscaled_font_map_mutex)
#endif
diff --git a/src/cairo-mutex-private.h b/src/cairo-mutex-private.h
index 0b806c186..61a7160a0 100755..100644
--- a/src/cairo-mutex-private.h
+++ b/src/cairo-mutex-private.h
@@ -59,10 +59,8 @@ cairo_private void _cairo_mutex_finalize (void);
/* Finally, extern the static mutexes and undef */
#define CAIRO_MUTEX_DECLARE(mutex) cairo_private extern cairo_mutex_t mutex;
-#define CAIRO_RECURSIVE_MUTEX_DECLARE(mutex) cairo_private extern cairo_recursive_mutex_t mutex;
#include "cairo-mutex-list-private.h"
#undef CAIRO_MUTEX_DECLARE
-#undef CAIRO_RECURSIVE_MUTEX_DECLARE
CAIRO_END_DECLS
diff --git a/src/cairo-mutex-type-private.h b/src/cairo-mutex-type-private.h
index e8c493985..e8c493985 100755..100644
--- a/src/cairo-mutex-type-private.h
+++ b/src/cairo-mutex-type-private.h
diff --git a/src/cairo-mutex.c b/src/cairo-mutex.c
index 41d5c73f4..0a31dced3 100755..100644
--- a/src/cairo-mutex.c
+++ b/src/cairo-mutex.c
@@ -36,11 +36,8 @@
#include "cairo-mutex-private.h"
#define CAIRO_MUTEX_DECLARE(mutex) cairo_mutex_t mutex = CAIRO_MUTEX_NIL_INITIALIZER;
-#define CAIRO_RECURSIVE_MUTEX_DECLARE(mutex) \
- cairo_recursive_mutex_t mutex = CAIRO_RECURSIVE_MUTEX_NIL_INITIALIZER;
#include "cairo-mutex-list-private.h"
#undef CAIRO_MUTEX_DECLARE
-#undef CAIRO_RECURSIVE_MUTEX_DECLARE
#if _CAIRO_MUTEX_IMPL_USE_STATIC_INITIALIZER || _CAIRO_MUTEX_IMPL_USE_STATIC_FINALIZER
@@ -65,10 +62,8 @@ void _cairo_mutex_initialize (void)
_cairo_mutex_initialized = TRUE;
#define CAIRO_MUTEX_DECLARE(mutex) CAIRO_MUTEX_INIT (mutex);
-#define CAIRO_RECURSIVE_MUTEX_DECLARE(mutex) CAIRO_RECURSIVE_MUTEX_INIT (mutex);
#include "cairo-mutex-list-private.h"
#undef CAIRO_MUTEX_DECLARE
-#undef CAIRO_RECURSIVE_MUTEX_DECLARE
}
#endif
@@ -81,9 +76,7 @@ void _cairo_mutex_finalize (void)
_cairo_mutex_initialized = FALSE;
#define CAIRO_MUTEX_DECLARE(mutex) CAIRO_MUTEX_FINI (mutex);
-#define CAIRO_RECURSIVE_MUTEX_DECLARE(mutex) CAIRO_MUTEX_FINI (mutex);
#include "cairo-mutex-list-private.h"
#undef CAIRO_MUTEX_DECLARE
-#undef CAIRO_RECURSIVE_MUTEX_DECLARE
}
#endif
diff --git a/src/cairo-no-compositor.c b/src/cairo-no-compositor.c
index 1602a12f6..1602a12f6 100755..100644
--- a/src/cairo-no-compositor.c
+++ b/src/cairo-no-compositor.c
diff --git a/src/cairo-observer.c b/src/cairo-observer.c
index 36d6b93bd..36d6b93bd 100755..100644
--- a/src/cairo-observer.c
+++ b/src/cairo-observer.c
diff --git a/src/cairo-os2-private.h b/src/cairo-os2-private.h
index 829dd3c8d..829dd3c8d 100755..100644
--- a/src/cairo-os2-private.h
+++ b/src/cairo-os2-private.h
diff --git a/src/cairo-os2-surface.c b/src/cairo-os2-surface.c
index 1ab50f977..1ab50f977 100755..100644
--- a/src/cairo-os2-surface.c
+++ b/src/cairo-os2-surface.c
diff --git a/src/cairo-os2.h b/src/cairo-os2.h
index d23f2dec4..d23f2dec4 100755..100644
--- a/src/cairo-os2.h
+++ b/src/cairo-os2.h
diff --git a/src/cairo-output-stream-private.h b/src/cairo-output-stream-private.h
index edaabbe78..2542646b8 100755..100644
--- a/src/cairo-output-stream-private.h
+++ b/src/cairo-output-stream-private.h
@@ -135,6 +135,11 @@ _cairo_output_stream_printf (cairo_output_stream_t *stream,
const char *fmt,
...) CAIRO_PRINTF_FORMAT (2, 3);
+/* Print matrix element values with rounding of insignificant digits. */
+cairo_private void
+_cairo_output_stream_print_matrix (cairo_output_stream_t *stream,
+ const cairo_matrix_t *matrix);
+
cairo_private long
_cairo_output_stream_get_position (cairo_output_stream_t *stream);
diff --git a/src/cairo-output-stream.c b/src/cairo-output-stream.c
index facc182f6..c29ea0e39 100755..100644
--- a/src/cairo-output-stream.c
+++ b/src/cairo-output-stream.c
@@ -43,7 +43,6 @@
#include "cairo-compiler-private.h"
#include <stdio.h>
-#include <locale.h>
#include <errno.h>
/* Numbers printed with %f are printed with this number of significant
@@ -303,7 +302,6 @@ _cairo_output_stream_write_hex_string (cairo_output_stream_t *stream,
static void
_cairo_dtostr (char *buffer, size_t size, double d, cairo_bool_t limited_precision)
{
- struct lconv *locale_data;
const char *decimal_point;
int decimal_point_len;
char *p;
@@ -314,8 +312,7 @@ _cairo_dtostr (char *buffer, size_t size, double d, cairo_bool_t limited_precisi
if (d == 0.0)
d = 0.0;
- locale_data = localeconv ();
- decimal_point = locale_data->decimal_point;
+ decimal_point = cairo_get_locale_decimal_point ();
decimal_point_len = strlen (decimal_point);
assert (decimal_point_len != 0);
@@ -530,6 +527,45 @@ _cairo_output_stream_printf (cairo_output_stream_t *stream,
va_end (ap);
}
+/* Matrix elements that are smaller than the value of the largest element * MATRIX_ROUNDING_TOLERANCE
+ * are rounded down to zero. */
+#define MATRIX_ROUNDING_TOLERANCE 1e-12
+
+void
+_cairo_output_stream_print_matrix (cairo_output_stream_t *stream,
+ const cairo_matrix_t *matrix)
+{
+ cairo_matrix_t m;
+ double s, e;
+
+ m = *matrix;
+ s = fabs (m.xx);
+ if (fabs (m.xy) > s)
+ s = fabs (m.xy);
+ if (fabs (m.yx) > s)
+ s = fabs (m.yx);
+ if (fabs (m.yy) > s)
+ s = fabs (m.yy);
+
+ e = s * MATRIX_ROUNDING_TOLERANCE;
+ if (fabs(m.xx) < e)
+ m.xx = 0;
+ if (fabs(m.xy) < e)
+ m.xy = 0;
+ if (fabs(m.yx) < e)
+ m.yx = 0;
+ if (fabs(m.yy) < e)
+ m.yy = 0;
+ if (fabs(m.x0) < e)
+ m.x0 = 0;
+ if (fabs(m.y0) < e)
+ m.y0 = 0;
+
+ _cairo_output_stream_printf (stream,
+ "%f %f %f %f %f %f",
+ m.xx, m.yx, m.xy, m.yy, m.x0, m.y0);
+}
+
long
_cairo_output_stream_get_position (cairo_output_stream_t *stream)
{
diff --git a/src/cairo-paginated-private.h b/src/cairo-paginated-private.h
index b827faba0..b827faba0 100755..100644
--- a/src/cairo-paginated-private.h
+++ b/src/cairo-paginated-private.h
diff --git a/src/cairo-paginated-surface-private.h b/src/cairo-paginated-surface-private.h
index ebf4b3424..ebf4b3424 100755..100644
--- a/src/cairo-paginated-surface-private.h
+++ b/src/cairo-paginated-surface-private.h
diff --git a/src/cairo-paginated-surface.c b/src/cairo-paginated-surface.c
index b4580d77b..6d6d6dd1c 100755..100644
--- a/src/cairo-paginated-surface.c
+++ b/src/cairo-paginated-surface.c
@@ -309,7 +309,7 @@ _paint_fallback_image (cairo_paginated_surface_t *surface,
image = _cairo_paginated_surface_create_image_surface (surface,
ceil (width * x_scale),
ceil (height * y_scale));
- _cairo_surface_set_device_scale (image, x_scale, y_scale);
+ cairo_surface_set_device_scale (image, x_scale, y_scale);
/* set_device_offset just sets the x0/y0 components of the matrix;
* so we have to do the scaling manually. */
cairo_surface_set_device_offset (image, -x*x_scale, -y*y_scale);
diff --git a/src/cairo-path-bounds.c b/src/cairo-path-bounds.c
index 77f23c887..e8cf0e320 100755..100644
--- a/src/cairo-path-bounds.c
+++ b/src/cairo-path-bounds.c
@@ -221,7 +221,7 @@ _cairo_path_fixed_approximate_stroke_exact_extents (const cairo_path_fixed_t *pa
box_extents.p1.y -= _cairo_fixed_from_double (dy);
box_extents.p2.x += _cairo_fixed_from_double (dx);
box_extents.p2.y += _cairo_fixed_from_double (dy);
-
+
_cairo_box_to_doubles (&box_extents, &x1, &y1, &x2, &y2);
extents->x = x1;
diff --git a/src/cairo-path-fill.c b/src/cairo-path-fill.c
index b38c2a8d3..4000c9c58 100755..100644
--- a/src/cairo-path-fill.c
+++ b/src/cairo-path-fill.c
@@ -339,4 +339,3 @@ _cairo_path_fixed_fill_rectilinear_to_boxes (const cairo_path_fixed_t *path,
antialias,
boxes);
}
-
diff --git a/src/cairo-path-fixed-private.h b/src/cairo-path-fixed-private.h
index cf7cd0836..adc3b532b 100755..100644
--- a/src/cairo-path-fixed-private.h
+++ b/src/cairo-path-fixed-private.h
@@ -101,6 +101,7 @@ typedef struct _cairo_path_buf_fixed {
struct _cairo_path_fixed {
cairo_point_t last_move_point;
cairo_point_t current_point;
+ cairo_point_t start_point;
unsigned int has_current_point : 1;
unsigned int needs_move_to : 1;
unsigned int has_extents : 1;
@@ -113,6 +114,7 @@ struct _cairo_path_fixed {
cairo_box_t extents;
cairo_path_buf_fixed_t buf;
+ unsigned int is_convex : 1;
};
cairo_private void
diff --git a/src/cairo-path-fixed.c b/src/cairo-path-fixed.c
index 2c198815d..5d57a61ec 100755..100644
--- a/src/cairo-path-fixed.c
+++ b/src/cairo-path-fixed.c
@@ -86,6 +86,7 @@ _cairo_path_fixed_init (cairo_path_fixed_t *path)
path->current_point.x = 0;
path->current_point.y = 0;
path->last_move_point = path->current_point;
+ path->start_point = path->current_point;
path->has_current_point = FALSE;
path->needs_move_to = TRUE;
@@ -95,6 +96,7 @@ _cairo_path_fixed_init (cairo_path_fixed_t *path)
path->fill_is_rectilinear = TRUE;
path->fill_maybe_region = TRUE;
path->fill_is_empty = TRUE;
+ path->is_convex = TRUE;
path->extents.p1.x = path->extents.p1.y = 0;
path->extents.p2.x = path->extents.p2.y = 0;
@@ -132,6 +134,9 @@ _cairo_path_fixed_init_copy (cairo_path_fixed_t *path,
path->buf.base.num_ops = other->buf.base.num_ops;
path->buf.base.num_points = other->buf.base.num_points;
+
+ path->is_convex = other->is_convex;
+
memcpy (path->buf.op, other->buf.base.op,
other->buf.base.num_ops * sizeof (other->buf.op[0]));
memcpy (path->buf.points, other->buf.points,
@@ -408,6 +413,11 @@ _cairo_path_fixed_move_to (cairo_path_fixed_t *path,
path->current_point.y = y;
path->last_move_point = path->current_point;
+ if (_cairo_path_fixed_is_empty (path))
+ path->is_convex = TRUE;
+ else
+ path->is_convex = FALSE;
+
return CAIRO_STATUS_SUCCESS;
}
@@ -450,6 +460,11 @@ _cairo_path_fixed_new_sub_path (cairo_path_fixed_t *path)
path->needs_move_to = TRUE;
}
+ if (_cairo_path_fixed_is_empty (path))
+ path->is_convex = TRUE;
+ else
+ path->is_convex = FALSE;
+
path->has_current_point = FALSE;
}
@@ -548,6 +563,13 @@ _cairo_path_fixed_line_to (cairo_path_fixed_t *path,
_cairo_box_add_point (&path->extents, &point);
+ /* if line to point does not match start point, is_convex false */
+ if (path->is_convex) {
+ if (path->start_point.x != x &&
+ path->start_point.y != y)
+ path->is_convex = FALSE;
+ }
+
return _cairo_path_fixed_add (path, CAIRO_PATH_OP_LINE_TO, &point, 1);
}
@@ -620,6 +642,8 @@ _cairo_path_fixed_curve_to (cairo_path_fixed_t *path,
path->fill_maybe_region = FALSE;
path->fill_is_empty = FALSE;
+ path->is_convex = FALSE;
+
return _cairo_path_fixed_add (path, CAIRO_PATH_OP_CURVE_TO, point, 3);
}
@@ -847,6 +871,9 @@ _cairo_path_fixed_interpret (const cairo_path_fixed_t *path,
}
} cairo_path_foreach_buf_end (buf, path);
+ if (path->needs_move_to && path->has_current_point)
+ return (*move_to) (closure, &path->current_point);
+
return CAIRO_STATUS_SUCCESS;
}
@@ -965,8 +992,19 @@ _cairo_path_fixed_offset_and_scale (cairo_path_fixed_t *path,
path->extents.p1.x = _cairo_fixed_mul (scalex, path->extents.p1.x) + offx;
path->extents.p2.x = _cairo_fixed_mul (scalex, path->extents.p2.x) + offx;
+ if (scalex < 0) {
+ cairo_fixed_t t = path->extents.p1.x;
+ path->extents.p1.x = path->extents.p2.x;
+ path->extents.p2.x = t;
+ }
+
path->extents.p1.y = _cairo_fixed_mul (scaley, path->extents.p1.y) + offy;
path->extents.p2.y = _cairo_fixed_mul (scaley, path->extents.p2.y) + offy;
+ if (scaley < 0) {
+ cairo_fixed_t t = path->extents.p1.y;
+ path->extents.p1.y = path->extents.p2.y;
+ path->extents.p2.y = t;
+ }
}
void
@@ -1289,7 +1327,7 @@ _cairo_path_fixed_is_box (const cairo_path_fixed_t *path,
}
/* Determine whether two lines A->B and C->D intersect based on the
- * algorithm described here: http://paulbourke.net/geometry/lineline2d/ */
+ * algorithm described here: http://paulbourke.net/geometry/pointlineplane/ */
static inline cairo_bool_t
_lines_intersect_or_are_coincident (cairo_point_t a,
cairo_point_t b,
@@ -1297,6 +1335,7 @@ _lines_intersect_or_are_coincident (cairo_point_t a,
cairo_point_t d)
{
cairo_int64_t numerator_a, numerator_b, denominator;
+ cairo_bool_t denominator_negative;
denominator = _cairo_int64_sub (_cairo_int32x32_64_mul (d.y - c.y, b.x - a.x),
_cairo_int32x32_64_mul (d.x - c.x, b.y - a.y));
@@ -1316,20 +1355,34 @@ _lines_intersect_or_are_coincident (cairo_point_t a,
return FALSE;
}
- /* If either division would produce a number between 0 and 1, i.e.
- * the numerator is smaller than the denominator and their signs are
- * the same, then the lines intersect. */
- if (_cairo_int64_lt (numerator_a, denominator) &&
- ! (_cairo_int64_negative (numerator_a) ^ _cairo_int64_negative(denominator))) {
- return TRUE;
- }
+ /* The lines intersect if both quotients are between 0 and 1 (exclusive). */
- if (_cairo_int64_lt (numerator_b, denominator) &&
- ! (_cairo_int64_negative (numerator_b) ^ _cairo_int64_negative(denominator))) {
- return TRUE;
+ /* We first test whether either quotient is a negative number. */
+ denominator_negative = _cairo_int64_negative (denominator);
+ if (_cairo_int64_negative (numerator_a) ^ denominator_negative)
+ return FALSE;
+ if (_cairo_int64_negative (numerator_b) ^ denominator_negative)
+ return FALSE;
+
+ /* A zero quotient indicates an "intersection" at an endpoint, which
+ * we aren't considering a true intersection. */
+ if (_cairo_int64_is_zero (numerator_a) || _cairo_int64_is_zero (numerator_b))
+ return FALSE;
+
+ /* If the absolute value of the numerator is larger than or equal to the
+ * denominator the result of the division would be greater than or equal
+ * to one. */
+ if (! denominator_negative) {
+ if (! _cairo_int64_lt (numerator_a, denominator) ||
+ ! _cairo_int64_lt (numerator_b, denominator))
+ return FALSE;
+ } else {
+ if (! _cairo_int64_lt (denominator, numerator_a) ||
+ ! _cairo_int64_lt (denominator, numerator_b))
+ return FALSE;
}
- return FALSE;
+ return TRUE;
}
cairo_bool_t
@@ -1454,6 +1507,19 @@ _cairo_path_fixed_is_single_line (const cairo_path_fixed_t *path)
}
cairo_bool_t
+_cairo_path_fixed_is_empty (const cairo_path_fixed_t *path)
+{
+ unsigned int i;
+ const cairo_path_buf_t *buf = cairo_path_head (path);
+ for (i = 0; i < buf->num_ops; i++) {
+ if (buf->op[i] != CAIRO_PATH_OP_MOVE_TO)
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+cairo_bool_t
_cairo_path_fixed_is_single_arc (const cairo_path_fixed_t *path)
{
const cairo_path_buf_t *buf = cairo_path_head (path);
diff --git a/src/cairo-path-in-fill.c b/src/cairo-path-in-fill.c
index 1787fb1a3..1787fb1a3 100755..100644
--- a/src/cairo-path-in-fill.c
+++ b/src/cairo-path-in-fill.c
diff --git a/src/cairo-path-private.h b/src/cairo-path-private.h
index 7b54317e2..7b54317e2 100755..100644
--- a/src/cairo-path-private.h
+++ b/src/cairo-path-private.h
diff --git a/src/cairo-path-stroke-boxes.c b/src/cairo-path-stroke-boxes.c
index 7f25bf76c..7f25bf76c 100755..100644
--- a/src/cairo-path-stroke-boxes.c
+++ b/src/cairo-path-stroke-boxes.c
diff --git a/src/cairo-path-stroke-polygon.c b/src/cairo-path-stroke-polygon.c
index b62ddfb8f..83e40854e 100755..100644
--- a/src/cairo-path-stroke-polygon.c
+++ b/src/cairo-path-stroke-polygon.c
@@ -1083,7 +1083,6 @@ spline_to (void *closure,
_cairo_contour_add_point (&stroker->path, point);
#endif
if ((tangent->dx | tangent->dy) == 0) {
- const cairo_point_t *inpt, *outpt;
struct stroke_contour *outer;
cairo_point_t t;
int clockwise;
@@ -1101,12 +1100,8 @@ spline_to (void *closure,
clockwise = join_is_clockwise (&stroker->current_face, &face);
if (clockwise) {
- inpt = &stroker->current_face.cw;
- outpt = &face.cw;
outer = &stroker->cw;
} else {
- inpt = &stroker->current_face.ccw;
- outpt = &face.ccw;
outer = &stroker->ccw;
}
@@ -1121,7 +1116,6 @@ spline_to (void *closure,
if ((face.dev_slope.x * stroker->current_face.dev_slope.x +
face.dev_slope.y * stroker->current_face.dev_slope.y) < stroker->spline_cusp_tolerance)
{
- const cairo_point_t *inpt, *outpt;
struct stroke_contour *outer;
int clockwise = join_is_clockwise (&stroker->current_face, &face);
@@ -1134,12 +1128,8 @@ spline_to (void *closure,
contour_add_point (stroker, &stroker->ccw, &stroker->current_face.ccw);
if (clockwise) {
- inpt = &stroker->current_face.cw;
- outpt = &face.cw;
outer = &stroker->cw;
} else {
- inpt = &stroker->current_face.ccw;
- outpt = &face.ccw;
outer = &stroker->ccw;
}
add_fan (stroker,
diff --git a/src/cairo-path-stroke-traps.c b/src/cairo-path-stroke-traps.c
index f95321491..03638961c 100755..100644
--- a/src/cairo-path-stroke-traps.c
+++ b/src/cairo-path-stroke-traps.c
@@ -249,9 +249,11 @@ join (struct stroker *stroker,
in->dev_slope.y * out->dev_slope.y) < stroker->spline_cusp_tolerance)
{
int start, stop;
- cairo_point_t tri[3];
+ cairo_point_t tri[3], edges[4];
cairo_pen_t *pen = &stroker->pen;
+ edges[0] = in->cw;
+ edges[1] = in->ccw;
tri[0] = in->point;
tri[1] = *inpt;
if (clockwise) {
@@ -261,8 +263,13 @@ join (struct stroker *stroker,
while (start != stop) {
tri[2] = in->point;
translate_point (&tri[2], &pen->vertices[start].point);
- _cairo_traps_tessellate_triangle (stroker->traps, tri);
+ edges[2] = in->point;
+ edges[3] = tri[2];
+ _cairo_traps_tessellate_triangle_with_edges (stroker->traps,
+ tri, edges);
tri[1] = tri[2];
+ edges[0] = edges[2];
+ edges[1] = edges[3];
if (start-- == 0)
start += pen->num_vertices;
@@ -274,17 +281,30 @@ join (struct stroker *stroker,
while (start != stop) {
tri[2] = in->point;
translate_point (&tri[2], &pen->vertices[start].point);
- _cairo_traps_tessellate_triangle (stroker->traps, tri);
+ edges[2] = in->point;
+ edges[3] = tri[2];
+ _cairo_traps_tessellate_triangle_with_edges (stroker->traps,
+ tri, edges);
tri[1] = tri[2];
+ edges[0] = edges[2];
+ edges[1] = edges[3];
if (++start == pen->num_vertices)
start = 0;
}
}
tri[2] = *outpt;
- _cairo_traps_tessellate_triangle (stroker->traps, tri);
- break;
+ edges[2] = out->cw;
+ edges[3] = out->ccw;
+ _cairo_traps_tessellate_triangle_with_edges (stroker->traps,
+ tri, edges);
+ } else {
+ cairo_point_t t[] = { { in->point.x, in->point.y}, { inpt->x, inpt->y }, { outpt->x, outpt->y } };
+ cairo_point_t e[] = { { in->cw.x, in->cw.y}, { in->ccw.x, in->ccw.y },
+ { out->cw.x, out->cw.y}, { out->ccw.x, out->ccw.y } };
+ _cairo_traps_tessellate_triangle_with_edges (stroker->traps, t, e);
}
+ break;
case CAIRO_LINE_JOIN_MITER:
default: {
@@ -442,12 +462,10 @@ join (struct stroker *stroker,
}
case CAIRO_LINE_JOIN_BEVEL: {
- cairo_point_t tri[3];
- tri[0] = in->point;
- tri[1] = *inpt;
- tri[2] = *outpt;
-
- _cairo_traps_tessellate_triangle (stroker->traps, tri);
+ cairo_point_t t[] = { { in->point.x, in->point.y }, { inpt->x, inpt->y }, { outpt->x, outpt->y } };
+ cairo_point_t e[] = { { in->cw.x, in->cw.y }, { in->ccw.x, in->ccw.y },
+ { out->cw.x, out->cw.y }, { out->ccw.x, out->ccw.y } };
+ _cairo_traps_tessellate_triangle_with_edges (stroker->traps, t, e);
break;
}
}
@@ -460,7 +478,7 @@ add_cap (struct stroker *stroker, cairo_stroke_face_t *f)
case CAIRO_LINE_CAP_ROUND: {
int start, stop;
cairo_slope_t in_slope, out_slope;
- cairo_point_t tri[3];
+ cairo_point_t tri[3], edges[4];
cairo_pen_t *pen = &stroker->pen;
in_slope = f->dev_vector;
@@ -468,19 +486,29 @@ add_cap (struct stroker *stroker, cairo_stroke_face_t *f)
out_slope.dy = -in_slope.dy;
_cairo_pen_find_active_cw_vertices (pen, &in_slope, &out_slope,
&start, &stop);
+ edges[0] = f->cw;
+ edges[1] = f->ccw;
tri[0] = f->point;
tri[1] = f->cw;
while (start != stop) {
tri[2] = f->point;
translate_point (&tri[2], &pen->vertices[start].point);
- _cairo_traps_tessellate_triangle (stroker->traps, tri);
+ edges[2] = f->point;
+ edges[3] = tri[2];
+ _cairo_traps_tessellate_triangle_with_edges (stroker->traps,
+ tri, edges);
tri[1] = tri[2];
+ edges[0] = edges[2];
+ edges[1] = edges[3];
if (++start == pen->num_vertices)
start = 0;
}
tri[2] = f->ccw;
- _cairo_traps_tessellate_triangle (stroker->traps, tri);
+ edges[2] = f->cw;
+ edges[3] = f->ccw;
+ _cairo_traps_tessellate_triangle_with_edges (stroker->traps,
+ tri, edges);
break;
}
@@ -937,7 +965,6 @@ spline_to (void *closure,
cairo_point_t rectangle[4];
compute_face (&stroker->current_face.point, tangent, stroker, &face);
-
join (stroker, &stroker->current_face, &face);
rectangle[0] = face.cw;
@@ -1024,7 +1051,7 @@ curve_to_dashed (void *closure,
func = (cairo_spline_add_point_func_t)line_to_dashed;
if (stroker->has_bounds &&
- ! _cairo_spline_intersects (&stroker->current_face.point, b, c, b,
+ ! _cairo_spline_intersects (&stroker->current_face.point, b, c, d,
&stroker->line_bounds))
return func (closure, d, NULL);
diff --git a/src/cairo-path-stroke-tristrip.c b/src/cairo-path-stroke-tristrip.c
index 3c232986b..3c232986b 100755..100644
--- a/src/cairo-path-stroke-tristrip.c
+++ b/src/cairo-path-stroke-tristrip.c
diff --git a/src/cairo-path-stroke.c b/src/cairo-path-stroke.c
index 73c554bd8..5c260c915 100755..100644
--- a/src/cairo-path-stroke.c
+++ b/src/cairo-path-stroke.c
@@ -54,6 +54,7 @@ typedef struct cairo_stroker {
const cairo_matrix_t *ctm_inverse;
double half_line_width;
double tolerance;
+ double spline_cusp_tolerance;
double ctm_determinant;
cairo_bool_t ctm_det_positive;
@@ -177,6 +178,18 @@ _cairo_stroker_init (cairo_stroker_t *stroker,
stroker->tolerance = tolerance;
stroker->half_line_width = stroke_style->line_width / 2.0;
+ /* To test whether we need to join two segments of a spline using
+ * a round-join or a bevel-join, we can inspect the angle between the
+ * two segments. If the difference between the chord distance
+ * (half-line-width times the cosine of the bisection angle) and the
+ * half-line-width itself is greater than tolerance then we need to
+ * inject a point.
+ */
+ stroker->spline_cusp_tolerance = 1 - tolerance / stroker->half_line_width;
+ stroker->spline_cusp_tolerance *= stroker->spline_cusp_tolerance;
+ stroker->spline_cusp_tolerance *= 2;
+ stroker->spline_cusp_tolerance -= 1;
+
stroker->ctm_determinant = _cairo_matrix_compute_determinant (stroker->ctm);
stroker->ctm_det_positive = stroker->ctm_determinant >= 0.0;
@@ -1052,39 +1065,61 @@ _cairo_stroker_spline_to (void *closure,
slope_dy = _cairo_fixed_to_double (tangent->dy);
if (! _compute_normalized_device_slope (&slope_dx, &slope_dy,
- stroker->ctm_inverse, NULL))
+ stroker->ctm_inverse, NULL))
return CAIRO_STATUS_SUCCESS;
_compute_face (point, tangent,
slope_dx, slope_dy,
stroker, &new_face);
- assert(stroker->has_current_face);
-
- if (_cairo_stroke_segment_intersect (&stroker->current_face.cw,
- &stroker->current_face.ccw,
- &new_face.cw,
- &new_face.ccw,
- &intersect_point)) {
- points[0] = stroker->current_face.ccw;
- points[1] = new_face.ccw;
- points[2] = intersect_point;
- stroker->add_triangle (stroker->closure, points);
-
- points[0] = stroker->current_face.cw;
- points[1] = new_face.cw;
- stroker->add_triangle (stroker->closure, points);
+ assert (stroker->has_current_face);
+
+ if ((new_face.dev_slope.x * stroker->current_face.dev_slope.x +
+ new_face.dev_slope.y * stroker->current_face.dev_slope.y) < stroker->spline_cusp_tolerance) {
+
+ const cairo_point_t *inpt, *outpt;
+ int clockwise = _cairo_stroker_join_is_clockwise (&new_face,
+ &stroker->current_face);
+
+ if (clockwise) {
+ inpt = &stroker->current_face.cw;
+ outpt = &new_face.cw;
+ } else {
+ inpt = &stroker->current_face.ccw;
+ outpt = &new_face.ccw;
+ }
+
+ _tessellate_fan (stroker,
+ &stroker->current_face.dev_vector,
+ &new_face.dev_vector,
+ &stroker->current_face.point,
+ inpt, outpt,
+ clockwise);
}
- else {
- points[0] = stroker->current_face.ccw;
- points[1] = stroker->current_face.cw;
- points[2] = new_face.cw;
- stroker->add_triangle (stroker->closure, points);
-
- points[0] = stroker->current_face.ccw;
- points[1] = new_face.cw;
- points[2] = new_face.ccw;
- stroker->add_triangle (stroker->closure, points);
+
+ if (_slow_segment_intersection (&stroker->current_face.cw,
+ &stroker->current_face.ccw,
+ &new_face.cw,
+ &new_face.ccw,
+ &intersect_point)) {
+ points[0] = stroker->current_face.ccw;
+ points[1] = new_face.ccw;
+ points[2] = intersect_point;
+ stroker->add_triangle (stroker->closure, points);
+
+ points[0] = stroker->current_face.cw;
+ points[1] = new_face.cw;
+ stroker->add_triangle (stroker->closure, points);
+ } else {
+ points[0] = stroker->current_face.ccw;
+ points[1] = stroker->current_face.cw;
+ points[2] = new_face.cw;
+ stroker->add_triangle (stroker->closure, points);
+
+ points[0] = stroker->current_face.ccw;
+ points[1] = new_face.cw;
+ points[2] = new_face.ccw;
+ stroker->add_triangle (stroker->closure, points);
}
/* compute join */
diff --git a/src/cairo-path.c b/src/cairo-path.c
index 43cd175a3..6ca06a74e 100755..100644
--- a/src/cairo-path.c
+++ b/src/cairo-path.c
@@ -342,7 +342,7 @@ _cairo_path_create_internal (cairo_path_fixed_t *path_fixed,
path->data = NULL;
path->status = CAIRO_STATUS_SUCCESS;
}
-
+ path->is_convex = path_fixed->is_convex;
return path;
}
diff --git a/src/cairo-pattern-inline.h b/src/cairo-pattern-inline.h
index 97e8ea034..97e8ea034 100755..100644
--- a/src/cairo-pattern-inline.h
+++ b/src/cairo-pattern-inline.h
diff --git a/src/cairo-pattern-private.h b/src/cairo-pattern-private.h
index a0092b135..5914b45f6 100755..100644
--- a/src/cairo-pattern-private.h
+++ b/src/cairo-pattern-private.h
@@ -259,6 +259,10 @@ cairo_private void
_cairo_pattern_transform (cairo_pattern_t *pattern,
const cairo_matrix_t *ctm_inverse);
+cairo_private void
+_cairo_pattern_pretransform (cairo_pattern_t *pattern,
+ const cairo_matrix_t *ctm);
+
cairo_private cairo_bool_t
_cairo_pattern_is_opaque_solid (const cairo_pattern_t *pattern);
@@ -307,7 +311,7 @@ _cairo_mesh_pattern_coord_box (const cairo_mesh_pattern_t *mesh,
double *out_xmax,
double *out_ymax);
-cairo_private_no_warn cairo_filter_t
+cairo_private void
_cairo_pattern_sampled_area (const cairo_pattern_t *pattern,
const cairo_rectangle_int_t *extents,
cairo_rectangle_int_t *sample);
@@ -350,6 +354,9 @@ cairo_private cairo_bool_t
_cairo_pattern_equal (const cairo_pattern_t *a,
const cairo_pattern_t *b);
+cairo_private cairo_filter_t
+_cairo_pattern_analyze_filter (const cairo_pattern_t *pattern);
+
/* cairo-mesh-pattern-rasterizer.c */
cairo_private void
@@ -380,7 +387,7 @@ _cairo_raster_source_pattern_init_copy (cairo_pattern_t *pattern,
cairo_private void
_cairo_raster_source_pattern_finish (cairo_pattern_t *abstract_pattern);
-cairo_private cairo_status_t
+cairo_private cairo_status_t
_cairo_pattern_create_gaussian_matrix (cairo_pattern_t *pattern,
double line_width);
diff --git a/src/cairo-pattern.c b/src/cairo-pattern.c
index 4d6094ba2..c7d269caa 100755..100644
--- a/src/cairo-pattern.c
+++ b/src/cairo-pattern.c
@@ -51,8 +51,8 @@
* @See_Also: #cairo_t, #cairo_surface_t
*
* #cairo_pattern_t is the paint with which cairo draws.
- * The primary use of patterns is as the source for all cairo drawing
- * operations, although they can also be used as masks, that is, as the
+ * The primary use of patterns is as the source for all cairo drawing
+ * operations, although they can also be used as masks, that is, as the
* brush too.
*
* A cairo pattern is created by using one of the many constructors,
@@ -2158,6 +2158,16 @@ cairo_pattern_get_extend (cairo_pattern_t *pattern)
slim_hidden_def (cairo_pattern_get_extend);
void
+_cairo_pattern_pretransform (cairo_pattern_t *pattern,
+ const cairo_matrix_t *ctm)
+{
+ if (pattern->status)
+ return;
+
+ cairo_matrix_multiply (&pattern->matrix, &pattern->matrix, ctm);
+}
+
+void
_cairo_pattern_transform (cairo_pattern_t *pattern,
const cairo_matrix_t *ctm_inverse)
{
@@ -3358,111 +3368,180 @@ _cairo_pattern_is_clear (const cairo_pattern_t *abstract_pattern)
return FALSE;
}
+/*
+ * Will given row of back-translation matrix work with bilinear scale?
+ * This is true for scales larger than 1. Also it was judged acceptable
+ * for scales larger than .75. And if there is integer translation
+ * then a scale of exactly .5 works.
+ */
+static int
+use_bilinear(double x, double y, double t)
+{
+ /* This is the inverse matrix! */
+ double h = x*x + y*y;
+ if (h < 1.0 / (0.75 * 0.75))
+ return TRUE; /* scale > .75 */
+ if ((h > 3.99 && h < 4.01) /* scale is 1/2 */
+ && !_cairo_fixed_from_double(x*y) /* parallel to an axis */
+ && _cairo_fixed_is_integer (_cairo_fixed_from_double (t)))
+ return TRUE;
+ return FALSE;
+}
+
/**
* _cairo_pattern_analyze_filter:
* @pattern: surface pattern
- * @pad_out: location to store necessary padding in the source image, or %NULL
* Returns: the optimized #cairo_filter_t to use with @pattern.
*
- * Analyze the filter to determine how much extra needs to be sampled
- * from the source image to account for the filter radius and whether
- * we can optimize the filter to a simpler value.
- *
- * XXX: We don't actually have any way of querying the backend for
- * the filter radius, so we just guess base on what we know that
- * backends do currently (see bug #10508)
+ * Possibly optimize the filter to a simpler value depending on transformation
**/
cairo_filter_t
-_cairo_pattern_analyze_filter (const cairo_pattern_t *pattern,
- double *pad_out)
+_cairo_pattern_analyze_filter (const cairo_pattern_t *pattern)
{
- double pad;
- cairo_filter_t optimized_filter;
-
switch (pattern->filter) {
case CAIRO_FILTER_GOOD:
case CAIRO_FILTER_BEST:
case CAIRO_FILTER_BILINEAR:
+ case CAIRO_FILTER_FAST:
/* If source pixels map 1:1 onto destination pixels, we do
* not need to filter (and do not want to filter, since it
* will cause blurriness)
*/
if (_cairo_matrix_is_pixel_exact (&pattern->matrix)) {
- pad = 0.;
- optimized_filter = CAIRO_FILTER_NEAREST;
+ return CAIRO_FILTER_NEAREST;
} else {
- /* 0.5 is enough for a bilinear filter. It's possible we
- * should defensively use more for CAIRO_FILTER_BEST, but
- * without a single example, it's hard to know how much
- * more would be defensive...
+ /* Use BILINEAR for any scale greater than .75 instead
+ * of GOOD. For scales of 1 and larger this is identical,
+ * for the smaller sizes it was judged that the artifacts
+ * were not worse than the artifacts from a box filer.
+ * BILINEAR can also be used if the scale is exactly .5
+ * and the translation in that direction is an integer.
*/
- pad = 0.5;
- optimized_filter = pattern->filter;
+ if (pattern->filter == CAIRO_FILTER_GOOD &&
+ use_bilinear (pattern->matrix.xx, pattern->matrix.xy,
+ pattern->matrix.x0) &&
+ use_bilinear (pattern->matrix.yx, pattern->matrix.yy,
+ pattern->matrix.y0))
+ return CAIRO_FILTER_BILINEAR;
}
break;
- case CAIRO_FILTER_FAST:
case CAIRO_FILTER_NEAREST:
case CAIRO_FILTER_GAUSSIAN:
default:
- pad = 0.;
- optimized_filter = pattern->filter;
break;
}
- if (pad_out)
- *pad_out = pad;
+ return pattern->filter;
+}
- return optimized_filter;
+/**
+ * _cairo_hypot:
+ * Returns: value similar to hypot(@x,@y)
+ *
+ * May want to replace this with Manhattan distance (abs(x)+abs(y)) if
+ * hypot is too slow, as there is no need for accuracy here.
+ **/
+static inline double
+_cairo_hypot(double x, double y)
+{
+ return hypot(x, y);
}
-cairo_filter_t
+/**
+ * _cairo_pattern_sampled_area:
+ *
+ * Return region of @pattern that will be sampled to fill @extents,
+ * based on the transformation and filter.
+ *
+ * This does not include pixels that are mulitiplied by values very
+ * close to zero by the ends of filters. This is so that transforms
+ * that should be the identity or 90 degree rotations do not expand
+ * the source unexpectedly.
+ *
+ * XXX: We don't actually have any way of querying the backend for
+ * the filter radius, so we just guess base on what we know that
+ * backends do currently (see bug #10508)
+ **/
+void
_cairo_pattern_sampled_area (const cairo_pattern_t *pattern,
const cairo_rectangle_int_t *extents,
cairo_rectangle_int_t *sample)
{
- cairo_filter_t filter;
double x1, x2, y1, y2;
- double pad;
+ double padx, pady;
- filter = _cairo_pattern_analyze_filter (pattern, &pad);
- if (pad == 0.0 && _cairo_matrix_is_identity (&pattern->matrix)) {
+ /* Assume filters are interpolating, which means identity
+ cannot change the image */
+ if (_cairo_matrix_is_identity (&pattern->matrix)) {
*sample = *extents;
- return filter;
+ return;
}
- x1 = extents->x;
- y1 = extents->y;
- x2 = extents->x + (int) extents->width;
- y2 = extents->y + (int) extents->height;
-
+ /* Transform the centers of the corner pixels */
+ x1 = extents->x + 0.5;
+ y1 = extents->y + 0.5;
+ x2 = x1 + (extents->width - 1);
+ y2 = y1 + (extents->height - 1);
_cairo_matrix_transform_bounding_box (&pattern->matrix,
&x1, &y1, &x2, &y2,
NULL);
- if (x1 > CAIRO_RECT_INT_MIN)
- sample->x = floor (x1 - pad);
- else
- sample->x = CAIRO_RECT_INT_MIN;
- if (y1 > CAIRO_RECT_INT_MIN)
- sample->y = floor (y1 - pad);
- else
- sample->y = CAIRO_RECT_INT_MIN;
+ /* How far away from center will it actually sample?
+ * This is the distance from a transformed pixel center to the
+ * furthest sample of reasonable size.
+ */
+ switch (pattern->filter) {
+ case CAIRO_FILTER_NEAREST:
+ case CAIRO_FILTER_FAST:
+ /* Correct value is zero, but when the sample is on an integer
+ * it is unknown if the backend will sample the pixel to the
+ * left or right. This value makes it include both possible pixels.
+ */
+ padx = pady = 0.004;
+ break;
+ case CAIRO_FILTER_BILINEAR:
+ case CAIRO_FILTER_GAUSSIAN:
+ default:
+ /* Correct value is .5 */
+ padx = pady = 0.495;
+ break;
+ case CAIRO_FILTER_GOOD:
+ /* Correct value is max(width,1)*.5 */
+ padx = _cairo_hypot (pattern->matrix.xx, pattern->matrix.xy);
+ if (padx <= 1.0) padx = 0.495;
+ else if (padx >= 16.0) padx = 7.92;
+ else padx *= 0.495;
+ pady = _cairo_hypot (pattern->matrix.yx, pattern->matrix.yy);
+ if (pady <= 1.0) pady = 0.495;
+ else if (pady >= 16.0) pady = 7.92;
+ else pady *= 0.495;
+ break;
+ case CAIRO_FILTER_BEST:
+ /* Correct value is width*2 */
+ padx = _cairo_hypot (pattern->matrix.xx, pattern->matrix.xy) * 1.98;
+ if (padx > 7.92) padx = 7.92;
+ pady = _cairo_hypot (pattern->matrix.yx, pattern->matrix.yy) * 1.98;
+ if (pady > 7.92) pady = 7.92;
+ break;
+ }
- if (x2 < CAIRO_RECT_INT_MAX)
- sample->width = ceil (x2 + pad);
- else
- sample->width = CAIRO_RECT_INT_MAX;
+ /* round furthest samples to edge of pixels */
+ x1 = floor (x1 - padx);
+ if (x1 < CAIRO_RECT_INT_MIN) x1 = CAIRO_RECT_INT_MIN;
+ sample->x = x1;
- if (y2 < CAIRO_RECT_INT_MAX)
- sample->height = ceil (y2 + pad);
- else
- sample->height = CAIRO_RECT_INT_MAX;
+ y1 = floor (y1 - pady);
+ if (y1 < CAIRO_RECT_INT_MIN) y1 = CAIRO_RECT_INT_MIN;
+ sample->y = y1;
- sample->width -= sample->x;
- sample->height -= sample->y;
+ x2 = floor (x2 + padx) + 1.0;
+ if (x2 > CAIRO_RECT_INT_MAX) x2 = CAIRO_RECT_INT_MAX;
+ sample->width = x2 - x1;
- return filter;
+ y2 = floor (y2 + pady) + 1.0;
+ if (y2 > CAIRO_RECT_INT_MAX) y2 = CAIRO_RECT_INT_MAX;
+ sample->height = y2 - y1;
}
/**
@@ -3482,7 +3561,9 @@ _cairo_pattern_get_extents (const cairo_pattern_t *pattern,
cairo_rectangle_int_t *extents)
{
double x1, y1, x2, y2;
- cairo_status_t status;
+ int ix1, ix2, iy1, iy2;
+ cairo_bool_t round_x = FALSE;
+ cairo_bool_t round_y = FALSE;
switch (pattern->type) {
case CAIRO_PATTERN_TYPE_SOLID:
@@ -3494,7 +3575,6 @@ _cairo_pattern_get_extents (const cairo_pattern_t *pattern,
const cairo_surface_pattern_t *surface_pattern =
(const cairo_surface_pattern_t *) pattern;
cairo_surface_t *surface = surface_pattern->surface;
- double pad;
if (! _cairo_surface_get_extents (surface, &surface_extents))
goto UNBOUNDED;
@@ -3505,14 +3585,12 @@ _cairo_pattern_get_extents (const cairo_pattern_t *pattern,
if (pattern->extend != CAIRO_EXTEND_NONE)
goto UNBOUNDED;
- /* The filter can effectively enlarge the extents of the
- * pattern, so extend as necessary.
- */
- _cairo_pattern_analyze_filter (&surface_pattern->base, &pad);
- x1 = surface_extents.x - pad;
- y1 = surface_extents.y - pad;
- x2 = surface_extents.x + (int) surface_extents.width + pad;
- y2 = surface_extents.y + (int) surface_extents.height + pad;
+ x1 = surface_extents.x;
+ y1 = surface_extents.y;
+ x2 = surface_extents.x + (int) surface_extents.width;
+ y2 = surface_extents.y + (int) surface_extents.height;
+
+ goto HANDLE_FILTER;
}
break;
@@ -3520,7 +3598,6 @@ _cairo_pattern_get_extents (const cairo_pattern_t *pattern,
{
const cairo_raster_source_pattern_t *raster =
(const cairo_raster_source_pattern_t *) pattern;
- double pad;
if (raster->extents.width == 0 || raster->extents.height == 0)
goto EMPTY;
@@ -3528,14 +3605,41 @@ _cairo_pattern_get_extents (const cairo_pattern_t *pattern,
if (pattern->extend != CAIRO_EXTEND_NONE)
goto UNBOUNDED;
- /* The filter can effectively enlarge the extents of the
- * pattern, so extend as necessary.
- */
- _cairo_pattern_analyze_filter (pattern, &pad);
- x1 = raster->extents.x - pad;
- y1 = raster->extents.y - pad;
- x2 = raster->extents.x + (int) raster->extents.width + pad;
- y2 = raster->extents.y + (int) raster->extents.height + pad;
+ x1 = raster->extents.x;
+ y1 = raster->extents.y;
+ x2 = raster->extents.x + (int) raster->extents.width;
+ y2 = raster->extents.y + (int) raster->extents.height;
+ }
+ HANDLE_FILTER:
+ switch (pattern->filter) {
+ case CAIRO_FILTER_NEAREST:
+ case CAIRO_FILTER_FAST:
+ round_x = round_y = TRUE;
+ /* We don't know which way .5 will go, so fudge it slightly. */
+ x1 -= 0.004;
+ y1 -= 0.004;
+ x2 += 0.004;
+ y2 += 0.004;
+ break;
+ case CAIRO_FILTER_BEST:
+ /* Assume best filter will produce nice antialiased edges */
+ break;
+ case CAIRO_FILTER_BILINEAR:
+ case CAIRO_FILTER_GAUSSIAN:
+ case CAIRO_FILTER_GOOD:
+ default:
+ /* These filters can blur the edge out 1/2 pixel when scaling up */
+ if (_cairo_hypot (pattern->matrix.xx, pattern->matrix.yx) < 1.0) {
+ x1 -= 0.5;
+ x2 += 0.5;
+ round_x = TRUE;
+ }
+ if (_cairo_hypot (pattern->matrix.xy, pattern->matrix.yy) < 1.0) {
+ y1 -= 0.5;
+ y2 += 0.5;
+ round_y = TRUE;
+ }
+ break;
}
break;
@@ -3607,6 +3711,10 @@ _cairo_pattern_get_extents (const cairo_pattern_t *pattern,
} else {
goto UNBOUNDED;
}
+
+ /* The current linear renderer just point-samples in the middle
+ of the pixels, similar to the NEAREST filter: */
+ round_x = round_y = TRUE;
}
break;
@@ -3614,22 +3722,8 @@ _cairo_pattern_get_extents (const cairo_pattern_t *pattern,
{
const cairo_mesh_pattern_t *mesh =
(const cairo_mesh_pattern_t *) pattern;
- double padx, pady;
- cairo_bool_t is_valid;
-
- is_valid = _cairo_mesh_pattern_coord_box (mesh, &x1, &y1, &x2, &y2);
- if (!is_valid)
+ if (! _cairo_mesh_pattern_coord_box (mesh, &x1, &y1, &x2, &y2))
goto EMPTY;
-
- padx = pady = 1.;
- cairo_matrix_transform_distance (&pattern->matrix, &padx, &pady);
- padx = fabs (padx);
- pady = fabs (pady);
-
- x1 -= padx;
- y1 -= pady;
- x2 += padx;
- y2 += pady;
}
break;
@@ -3642,6 +3736,7 @@ _cairo_pattern_get_extents (const cairo_pattern_t *pattern,
y1 -= pattern->matrix.y0; y2 -= pattern->matrix.y0;
} else {
cairo_matrix_t imatrix;
+ cairo_status_t status;
imatrix = pattern->matrix;
status = cairo_matrix_invert (&imatrix);
@@ -3653,22 +3748,34 @@ _cairo_pattern_get_extents (const cairo_pattern_t *pattern,
NULL);
}
- x1 = floor (x1);
+ if (!round_x) {
+ x1 -= 0.5;
+ x2 += 0.5;
+ }
if (x1 < CAIRO_RECT_INT_MIN)
- x1 = CAIRO_RECT_INT_MIN;
- y1 = floor (y1);
- if (y1 < CAIRO_RECT_INT_MIN)
- y1 = CAIRO_RECT_INT_MIN;
-
- x2 = ceil (x2);
+ ix1 = CAIRO_RECT_INT_MIN;
+ else
+ ix1 = _cairo_lround (x1);
if (x2 > CAIRO_RECT_INT_MAX)
- x2 = CAIRO_RECT_INT_MAX;
- y2 = ceil (y2);
+ ix2 = CAIRO_RECT_INT_MAX;
+ else
+ ix2 = _cairo_lround (x2);
+ extents->x = ix1; extents->width = ix2 - ix1;
+
+ if (!round_y) {
+ y1 -= 0.5;
+ y2 += 0.5;
+ }
+ if (y1 < CAIRO_RECT_INT_MIN)
+ iy1 = CAIRO_RECT_INT_MIN;
+ else
+ iy1 = _cairo_lround (y1);
if (y2 > CAIRO_RECT_INT_MAX)
- y2 = CAIRO_RECT_INT_MAX;
+ iy2 = CAIRO_RECT_INT_MAX;
+ else
+ iy2 = _cairo_lround (y2);
+ extents->y = iy1; extents->height = iy2 - iy1;
- extents->x = x1; extents->width = x2 - x1;
- extents->y = y1; extents->height = y2 - y1;
return;
UNBOUNDED:
@@ -4251,7 +4358,7 @@ cairo_pattern_get_rgba (cairo_pattern_t *pattern,
* cairo_pattern_get_surface:
* @pattern: a #cairo_pattern_t
* @surface: return value for surface of pattern, or %NULL
- *
+ *
* Gets the surface of a surface pattern. The reference returned in
* @surface is owned by the pattern; the caller should call
* cairo_surface_reference() if the surface is to be retained.
@@ -4291,8 +4398,9 @@ cairo_pattern_get_surface (cairo_pattern_t *pattern,
* @alpha: return value for alpha component of color, or %NULL
*
* Gets the color and offset information at the given @index for a
- * gradient pattern. Values of @index are 0 to 1 less than the number
- * returned by cairo_pattern_get_color_stop_count().
+ * gradient pattern. Values of @index range from 0 to n-1
+ * where n is the number returned
+ * by cairo_pattern_get_color_stop_count().
*
* Return value: %CAIRO_STATUS_SUCCESS, or %CAIRO_STATUS_INVALID_INDEX
* if @index is not valid for the given pattern. If the pattern is
@@ -4502,7 +4610,7 @@ slim_hidden_def (cairo_mesh_pattern_get_patch_count);
* Gets path defining the patch @patch_num for a mesh
* pattern.
*
- * @patch_num can range 0 to 1 less than the number returned by
+ * @patch_num can range from 0 to n-1 where n is the number returned by
* cairo_mesh_pattern_get_patch_count().
*
* Return value: the path defining the patch, or a path with status
@@ -4598,7 +4706,7 @@ slim_hidden_def (cairo_mesh_pattern_get_path);
* Gets the color information in corner @corner_num of patch
* @patch_num for a mesh pattern.
*
- * @patch_num can range 0 to 1 less than the number returned by
+ * @patch_num can range from 0 to n-1 where n is the number returned by
* cairo_mesh_pattern_get_patch_count().
*
* Valid values for @corner_num are from 0 to 3 and identify the
@@ -4666,7 +4774,7 @@ slim_hidden_def (cairo_mesh_pattern_get_corner_color_rgba);
* Gets the control point @point_num of patch @patch_num for a mesh
* pattern.
*
- * @patch_num can range 0 to 1 less than the number returned by
+ * @patch_num can range from 0 to n-1 where n is the number returned by
* cairo_mesh_pattern_get_patch_count().
*
* Valid values for @point_num are from 0 to 3 and identify the
@@ -4840,7 +4948,7 @@ _cairo_pattern_create_gaussian_matrix (cairo_pattern_t *pattern,
break;
x_sigma /= 2.0;
- x_factor *= 2;
+ x_factor *= 2;
width *= 0.5;
test_line_width *= 0.5;
}
diff --git a/src/cairo-pdf-operators-private.h b/src/cairo-pdf-operators-private.h
index 6e1ae1833..4314a042e 100755..100644
--- a/src/cairo-pdf-operators-private.h
+++ b/src/cairo-pdf-operators-private.h
@@ -53,9 +53,10 @@
*/
#define PDF_GLYPH_BUFFER_SIZE 200
-typedef cairo_status_t (*cairo_pdf_operators_use_font_subset_t) (unsigned int font_id,
- unsigned int subset_id,
- void *closure);
+typedef cairo_int_status_t
+(*cairo_pdf_operators_use_font_subset_t) (unsigned int font_id,
+ unsigned int subset_id,
+ void *closure);
typedef struct _cairo_pdf_glyph {
unsigned int glyph_index;
@@ -69,6 +70,7 @@ typedef struct _cairo_pdf_operators {
cairo_scaled_font_subsets_t *font_subsets;
cairo_pdf_operators_use_font_subset_t use_font_subset;
void *use_font_subset_closure;
+ cairo_bool_t ps_output; /* output is for PostScript */
cairo_bool_t use_actual_text;
cairo_bool_t in_text_object; /* inside BT/ET pair */
@@ -100,7 +102,8 @@ cairo_private void
_cairo_pdf_operators_init (cairo_pdf_operators_t *pdf_operators,
cairo_output_stream_t *stream,
cairo_matrix_t *cairo_to_pdf,
- cairo_scaled_font_subsets_t *font_subsets);
+ cairo_scaled_font_subsets_t *font_subsets,
+ cairo_bool_t ps);
cairo_private cairo_status_t
_cairo_pdf_operators_fini (cairo_pdf_operators_t *pdf_operators);
diff --git a/src/cairo-pdf-operators.c b/src/cairo-pdf-operators.c
index fceaf1cc4..dcee25f0c 100755..100644
--- a/src/cairo-pdf-operators.c
+++ b/src/cairo-pdf-operators.c
@@ -57,11 +57,13 @@ void
_cairo_pdf_operators_init (cairo_pdf_operators_t *pdf_operators,
cairo_output_stream_t *stream,
cairo_matrix_t *cairo_to_pdf,
- cairo_scaled_font_subsets_t *font_subsets)
+ cairo_scaled_font_subsets_t *font_subsets,
+ cairo_bool_t ps)
{
pdf_operators->stream = stream;
pdf_operators->cairo_to_pdf = *cairo_to_pdf;
pdf_operators->font_subsets = font_subsets;
+ pdf_operators->ps_output = ps;
pdf_operators->use_font_subset = NULL;
pdf_operators->use_font_subset_closure = NULL;
pdf_operators->in_text_object = FALSE;
@@ -176,6 +178,7 @@ typedef struct _word_wrap_stream {
cairo_output_stream_t base;
cairo_output_stream_t *output;
int max_column;
+ cairo_bool_t ps_output;
int column;
cairo_word_wrap_state_t state;
cairo_bool_t in_escape;
@@ -269,7 +272,7 @@ _word_wrap_stream_count_string_up_to (word_wrap_stream_t *stream,
if (*s == '\\') {
stream->in_escape = TRUE;
stream->escape_digits = 0;
- } else if (stream->column > stream->max_column) {
+ } else if (stream->ps_output && stream->column > stream->max_column) {
newline = TRUE;
break;
}
@@ -348,7 +351,7 @@ _word_wrap_stream_close (cairo_output_stream_t *base)
}
static cairo_output_stream_t *
-_word_wrap_stream_create (cairo_output_stream_t *output, int max_column)
+_word_wrap_stream_create (cairo_output_stream_t *output, cairo_bool_t ps, int max_column)
{
word_wrap_stream_t *stream;
@@ -367,6 +370,7 @@ _word_wrap_stream_create (cairo_output_stream_t *output, int max_column)
_word_wrap_stream_close);
stream->output = output;
stream->max_column = max_column;
+ stream->ps_output = ps;
stream->column = 0;
stream->state = WRAP_STATE_DELIMITER;
stream->in_escape = FALSE;
@@ -502,7 +506,7 @@ _cairo_pdf_operators_emit_path (cairo_pdf_operators_t *pdf_operators,
pdf_path_info_t info;
cairo_box_t box;
- word_wrap = _word_wrap_stream_create (pdf_operators->stream, 72);
+ word_wrap = _word_wrap_stream_create (pdf_operators->stream, pdf_operators->ps_output, 72);
status = _cairo_output_stream_get_status (word_wrap);
if (unlikely (status))
return _cairo_output_stream_destroy (word_wrap);
@@ -510,7 +514,9 @@ _cairo_pdf_operators_emit_path (cairo_pdf_operators_t *pdf_operators,
info.output = word_wrap;
info.path_transform = path_transform;
info.line_cap = line_cap;
- if (_cairo_path_fixed_is_rectangle (path, &box)) {
+ if (_cairo_path_fixed_is_rectangle (path, &box) &&
+ ((path_transform->xx == 0 && path_transform->yy == 0) ||
+ (path_transform->xy == 0 && path_transform->yx == 0))) {
status = _cairo_pdf_path_rectangle (&info, &box);
} else {
status = _cairo_path_fixed_interpret (path,
@@ -828,10 +834,9 @@ _cairo_pdf_operators_emit_stroke (cairo_pdf_operators_t *pdf_operators,
return status;
if (has_ctm) {
- _cairo_output_stream_printf (pdf_operators->stream,
- "q %f %f %f %f %f %f cm\n",
- m.xx, m.yx, m.xy, m.yy,
- m.x0, m.y0);
+ _cairo_output_stream_printf (pdf_operators->stream, "q ");
+ _cairo_output_stream_print_matrix (pdf_operators->stream, &m);
+ _cairo_output_stream_printf (pdf_operators->stream, " cm\n");
} else {
path_transform = pdf_operators->cairo_to_pdf;
}
@@ -1050,7 +1055,7 @@ _cairo_pdf_operators_flush_glyphs (cairo_pdf_operators_t *pdf_operators)
if (pdf_operators->num_glyphs == 0)
return CAIRO_STATUS_SUCCESS;
- word_wrap_stream = _word_wrap_stream_create (pdf_operators->stream, 72);
+ word_wrap_stream = _word_wrap_stream_create (pdf_operators->stream, pdf_operators->ps_output, 72);
status = _cairo_output_stream_get_status (word_wrap_stream);
if (unlikely (status))
return _cairo_output_stream_destroy (word_wrap_stream);
@@ -1120,14 +1125,8 @@ _cairo_pdf_operators_set_text_matrix (cairo_pdf_operators_t *pdf_operators,
pdf_operators->cur_x = 0;
pdf_operators->cur_y = 0;
pdf_operators->glyph_buf_x_pos = 0;
- _cairo_output_stream_printf (pdf_operators->stream,
- "%f %f %f %f %f %f Tm\n",
- pdf_operators->text_matrix.xx,
- pdf_operators->text_matrix.yx,
- pdf_operators->text_matrix.xy,
- pdf_operators->text_matrix.yy,
- pdf_operators->text_matrix.x0,
- pdf_operators->text_matrix.y0);
+ _cairo_output_stream_print_matrix (pdf_operators->stream, &pdf_operators->text_matrix);
+ _cairo_output_stream_printf (pdf_operators->stream, " Tm\n");
pdf_operators->cairo_to_pdftext = *matrix;
status = cairo_matrix_invert (&pdf_operators->cairo_to_pdftext);
@@ -1416,7 +1415,11 @@ _cairo_pdf_operators_emit_cluster (cairo_pdf_operators_t *pdf_operators,
return status;
}
- cur_glyph = glyphs;
+ if (cluster_flags & CAIRO_TEXT_CLUSTER_FLAG_BACKWARD)
+ cur_glyph = glyphs + num_glyphs - 1;
+ else
+ cur_glyph = glyphs;
+
/* XXX
* If no glyphs, we should put *something* here for the text to be selectable. */
for (i = 0; i < num_glyphs; i++) {
diff --git a/src/cairo-pdf-shading-private.h b/src/cairo-pdf-shading-private.h
index 0ca8cb7d5..0ca8cb7d5 100755..100644
--- a/src/cairo-pdf-shading-private.h
+++ b/src/cairo-pdf-shading-private.h
diff --git a/src/cairo-pdf-shading.c b/src/cairo-pdf-shading.c
index 6a2fe3615..6a2fe3615 100755..100644
--- a/src/cairo-pdf-shading.c
+++ b/src/cairo-pdf-shading.c
diff --git a/src/cairo-pdf-surface-private.h b/src/cairo-pdf-surface-private.h
index d9f65d800..618ca4ede 100755..100644
--- a/src/cairo-pdf-surface-private.h
+++ b/src/cairo-pdf-surface-private.h
@@ -70,9 +70,12 @@ typedef struct _cairo_pdf_source_surface_entry {
unsigned int id;
unsigned char *unique_id;
unsigned long unique_id_length;
+ cairo_operator_t operator;
cairo_bool_t interpolate;
cairo_bool_t stencil_mask;
+ cairo_bool_t smask;
cairo_pdf_resource_t surface_res;
+ cairo_pdf_resource_t smask_res;
int width;
int height;
cairo_rectangle_int_t extents;
@@ -92,6 +95,7 @@ typedef struct _cairo_pdf_pattern {
cairo_pattern_t *pattern;
cairo_pdf_resource_t pattern_res;
cairo_pdf_resource_t gstate_res;
+ cairo_operator_t operator;
cairo_bool_t is_shading;
} cairo_pdf_pattern_t;
@@ -127,6 +131,13 @@ typedef struct _cairo_pdf_smask_group {
cairo_scaled_font_t *scaled_font;
} cairo_pdf_smask_group_t;
+typedef struct _cairo_pdf_jbig2_global {
+ unsigned char *id;
+ unsigned long id_length;
+ cairo_pdf_resource_t res;
+ cairo_bool_t emitted;
+} cairo_pdf_jbig2_global_t;
+
typedef struct _cairo_pdf_surface cairo_pdf_surface_t;
struct _cairo_pdf_surface {
@@ -149,6 +160,7 @@ struct _cairo_pdf_surface {
cairo_hash_table_t *all_surfaces;
cairo_array_t smask_groups;
cairo_array_t knockout_group;
+ cairo_array_t jbig2_global;
cairo_scaled_font_subsets_t *font_subsets;
cairo_array_t fonts;
diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c
index a0bf1c1d5..552e4bf4f 100755..100644
--- a/src/cairo-pdf-surface.c
+++ b/src/cairo-pdf-surface.c
@@ -130,6 +130,23 @@
*
* The PDF surface is used to render cairo graphics to Adobe
* PDF files and is a multi-page vector surface backend.
+ *
+ * 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.
+ *
+ * JBIG2 data in PDF must be in the embedded format as descibed 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
+ * 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
+ * %CAIRO_MIME_TYPE_JBIG2_GLOBAL_ID.
**/
static cairo_bool_t
@@ -164,6 +181,9 @@ static const char *_cairo_pdf_supported_mime_types[] =
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,
NULL
};
@@ -198,7 +218,7 @@ _cairo_pdf_surface_clear (cairo_pdf_surface_t *surface);
static void
_cairo_pdf_smask_group_destroy (cairo_pdf_smask_group_t *group);
-static cairo_status_t
+static cairo_int_status_t
_cairo_pdf_surface_add_font (unsigned int font_id,
unsigned int subset_id,
void *closure);
@@ -206,16 +226,16 @@ _cairo_pdf_surface_add_font (unsigned int font_id,
static void
_cairo_pdf_group_resources_init (cairo_pdf_group_resources_t *res);
-static cairo_status_t
+static cairo_int_status_t
_cairo_pdf_surface_open_stream (cairo_pdf_surface_t *surface,
cairo_pdf_resource_t *resource,
cairo_bool_t compressed,
const char *fmt,
...) CAIRO_PRINTF_FORMAT(4, 5);
-static cairo_status_t
+static cairo_int_status_t
_cairo_pdf_surface_close_stream (cairo_pdf_surface_t *surface);
-static cairo_status_t
+static cairo_int_status_t
_cairo_pdf_surface_write_page (cairo_pdf_surface_t *surface);
static void
@@ -230,10 +250,10 @@ _cairo_pdf_surface_write_catalog (cairo_pdf_surface_t *surface);
static long
_cairo_pdf_surface_write_xref (cairo_pdf_surface_t *surface);
-static cairo_status_t
+static cairo_int_status_t
_cairo_pdf_surface_write_page (cairo_pdf_surface_t *surface);
-static cairo_status_t
+static cairo_int_status_t
_cairo_pdf_surface_emit_font_subsets (cairo_pdf_surface_t *surface);
static cairo_bool_t
@@ -246,7 +266,7 @@ static cairo_pdf_resource_t
_cairo_pdf_surface_new_object (cairo_pdf_surface_t *surface)
{
cairo_pdf_resource_t resource;
- cairo_status_t status;
+ cairo_int_status_t status;
cairo_pdf_object_t object;
object.offset = _cairo_output_stream_get_position (surface->output);
@@ -365,6 +385,7 @@ _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->jbig2_global, sizeof (cairo_pdf_jbig2_global_t));
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);
@@ -410,7 +431,8 @@ _cairo_pdf_surface_create_for_stream_internal (cairo_output_stream_t *output,
_cairo_pdf_operators_init (&surface->pdf_operators,
surface->output,
&surface->cairo_to_pdf,
- surface->font_subsets);
+ surface->font_subsets,
+ FALSE);
_cairo_pdf_operators_set_font_subsets_callback (&surface->pdf_operators,
_cairo_pdf_surface_add_font,
surface);
@@ -769,14 +791,14 @@ _cairo_pdf_surface_add_operator (cairo_pdf_surface_t *surface,
res->operators[op] = TRUE;
}
-static cairo_status_t
+static cairo_int_status_t
_cairo_pdf_surface_add_alpha (cairo_pdf_surface_t *surface,
double alpha,
int *index)
{
int num_alphas, i;
double other;
- cairo_status_t status;
+ cairo_int_status_t status;
cairo_pdf_group_resources_t *res = &surface->resources;
num_alphas = _cairo_array_num_elements (&res->alphas);
@@ -797,21 +819,21 @@ _cairo_pdf_surface_add_alpha (cairo_pdf_surface_t *surface,
return CAIRO_STATUS_SUCCESS;
}
-static cairo_status_t
+static cairo_int_status_t
_cairo_pdf_surface_add_smask (cairo_pdf_surface_t *surface,
cairo_pdf_resource_t smask)
{
return _cairo_array_append (&(surface->resources.smasks), &smask);
}
-static cairo_status_t
+static cairo_int_status_t
_cairo_pdf_surface_add_pattern (cairo_pdf_surface_t *surface,
cairo_pdf_resource_t pattern)
{
return _cairo_array_append (&(surface->resources.patterns), &pattern);
}
-static cairo_status_t
+static cairo_int_status_t
_cairo_pdf_surface_add_shading (cairo_pdf_surface_t *surface,
cairo_pdf_resource_t shading)
{
@@ -819,14 +841,14 @@ _cairo_pdf_surface_add_shading (cairo_pdf_surface_t *surface,
}
-static cairo_status_t
+static cairo_int_status_t
_cairo_pdf_surface_add_xobject (cairo_pdf_surface_t *surface,
cairo_pdf_resource_t xobject)
{
return _cairo_array_append (&(surface->resources.xobjects), &xobject);
}
-static cairo_status_t
+static cairo_int_status_t
_cairo_pdf_surface_add_font (unsigned int font_id,
unsigned int subset_id,
void *closure)
@@ -834,7 +856,7 @@ _cairo_pdf_surface_add_font (unsigned int font_id,
cairo_pdf_surface_t *surface = closure;
cairo_pdf_font_t font;
int num_fonts, i;
- cairo_status_t status;
+ cairo_int_status_t status;
cairo_pdf_group_resources_t *res = &surface->resources;
num_fonts = _cairo_array_num_elements (&res->fonts);
@@ -1093,7 +1115,7 @@ _cairo_pdf_smask_group_destroy (cairo_pdf_smask_group_t *group)
free (group);
}
-static cairo_status_t
+static cairo_int_status_t
_cairo_pdf_surface_add_smask_group (cairo_pdf_surface_t *surface,
cairo_pdf_smask_group_t *group)
{
@@ -1187,6 +1209,20 @@ _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,
@@ -1263,6 +1299,15 @@ _get_source_surface_size (cairo_surface_t *source,
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;
@@ -1295,9 +1340,12 @@ _get_source_surface_size (cairo_surface_t *source,
* @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
@@ -1315,13 +1363,16 @@ _get_source_surface_size (cairo_surface_t *source,
* Only one of @source_pattern or @source_surface is to be
* specified. Set the other to NULL.
**/
-static cairo_status_t
+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,
@@ -1332,9 +1383,9 @@ _cairo_pdf_surface_add_source_surface (cairo_pdf_surface_t *surface,
cairo_pdf_source_surface_t src_surface;
cairo_pdf_source_surface_entry_t surface_key;
cairo_pdf_source_surface_entry_t *surface_entry;
- cairo_status_t status;
+ cairo_int_status_t status;
cairo_bool_t interpolate;
- unsigned char *unique_id;
+ unsigned char *unique_id = NULL;
unsigned long unique_id_length = 0;
cairo_image_surface_t *image;
void *image_extra;
@@ -1419,13 +1470,19 @@ release_source:
}
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->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;
_cairo_pdf_source_surface_init_key (surface_entry);
src_surface.hash_entry = surface_entry;
@@ -1476,24 +1533,26 @@ fail1:
return status;
}
-static cairo_status_t
+static cairo_int_status_t
_cairo_pdf_surface_add_pdf_pattern_or_shading (cairo_pdf_surface_t *surface,
const cairo_pattern_t *pattern,
+ cairo_operator_t op,
const cairo_rectangle_int_t *extents,
cairo_bool_t is_shading,
cairo_pdf_resource_t *pattern_res,
cairo_pdf_resource_t *gstate_res)
{
cairo_pdf_pattern_t pdf_pattern;
- cairo_status_t status;
+ cairo_int_status_t status;
pdf_pattern.is_shading = is_shading;
+ pdf_pattern.operator = op;
/* Solid colors are emitted into the content stream */
if (pattern->type == CAIRO_PATTERN_TYPE_SOLID) {
pattern_res->id = 0;
gstate_res->id = 0;
- return CAIRO_STATUS_SUCCESS;
+ return CAIRO_INT_STATUS_SUCCESS;
}
status = _cairo_pattern_create_copy (&pdf_pattern.pattern, pattern);
@@ -1545,7 +1604,7 @@ _cairo_pdf_surface_add_pdf_pattern_or_shading (cairo_pdf_surface_t *surface,
return status;
}
- return CAIRO_STATUS_SUCCESS;
+ return CAIRO_INT_STATUS_SUCCESS;
}
/* Get BBox in PDF coordinates from extents in cairo coordinates */
@@ -1560,37 +1619,41 @@ _get_bbox_from_extents (double surface_height,
bbox->p2.y = surface_height - extents->y;
}
-static cairo_status_t
+static cairo_int_status_t
_cairo_pdf_surface_add_pdf_shading (cairo_pdf_surface_t *surface,
const cairo_pattern_t *pattern,
+ cairo_operator_t op,
const cairo_rectangle_int_t *extents,
cairo_pdf_resource_t *shading_res,
cairo_pdf_resource_t *gstate_res)
{
return _cairo_pdf_surface_add_pdf_pattern_or_shading (surface,
pattern,
+ op,
extents,
TRUE,
shading_res,
gstate_res);
}
-static cairo_status_t
+static cairo_int_status_t
_cairo_pdf_surface_add_pdf_pattern (cairo_pdf_surface_t *surface,
const cairo_pattern_t *pattern,
+ cairo_operator_t op,
const cairo_rectangle_int_t *extents,
cairo_pdf_resource_t *pattern_res,
cairo_pdf_resource_t *gstate_res)
{
return _cairo_pdf_surface_add_pdf_pattern_or_shading (surface,
pattern,
+ op,
extents,
FALSE,
pattern_res,
gstate_res);
}
-static cairo_status_t
+static cairo_int_status_t
_cairo_pdf_surface_open_stream (cairo_pdf_surface_t *surface,
cairo_pdf_resource_t *resource,
cairo_bool_t compressed,
@@ -1659,22 +1722,22 @@ _cairo_pdf_surface_open_stream (cairo_pdf_surface_t *surface,
return _cairo_output_stream_get_status (surface->output);
}
-static cairo_status_t
+static cairo_int_status_t
_cairo_pdf_surface_close_stream (cairo_pdf_surface_t *surface)
{
- cairo_status_t status;
+ cairo_int_status_t status;
long length;
if (! surface->pdf_stream.active)
- return CAIRO_STATUS_SUCCESS;
+ return CAIRO_INT_STATUS_SUCCESS;
status = _cairo_pdf_operators_flush (&surface->pdf_operators);
if (surface->pdf_stream.compressed) {
- cairo_status_t status2;
+ cairo_int_status_t status2;
status2 = _cairo_output_stream_destroy (surface->output);
- if (likely (status == CAIRO_STATUS_SUCCESS))
+ if (likely (status == CAIRO_INT_STATUS_SUCCESS))
status = status2;
surface->output = surface->pdf_stream.old_output;
@@ -1700,7 +1763,7 @@ _cairo_pdf_surface_close_stream (cairo_pdf_surface_t *surface)
surface->pdf_stream.active = FALSE;
- if (likely (status == CAIRO_STATUS_SUCCESS))
+ if (likely (status == CAIRO_INT_STATUS_SUCCESS))
status = _cairo_output_stream_get_status (surface->output);
return status;
@@ -1755,12 +1818,12 @@ _cairo_pdf_surface_write_memory_stream (cairo_pdf_surface_t *surface,
"endobj\n");
}
-static cairo_status_t
+static cairo_int_status_t
_cairo_pdf_surface_open_group (cairo_pdf_surface_t *surface,
const cairo_box_double_t *bbox,
cairo_pdf_resource_t *resource)
{
- cairo_status_t status;
+ cairo_int_status_t status;
assert (surface->pdf_stream.active == FALSE);
assert (surface->group_stream.active == FALSE);
@@ -1798,11 +1861,11 @@ _cairo_pdf_surface_open_group (cairo_pdf_surface_t *surface,
return status;
}
-static cairo_status_t
+static cairo_int_status_t
_cairo_pdf_surface_open_knockout_group (cairo_pdf_surface_t *surface,
const cairo_box_double_t *bbox)
{
- cairo_status_t status;
+ cairo_int_status_t status;
status = _cairo_pdf_surface_open_group (surface, bbox, NULL);
if (unlikely (status))
@@ -1810,14 +1873,14 @@ _cairo_pdf_surface_open_knockout_group (cairo_pdf_surface_t *surface,
surface->group_stream.is_knockout = TRUE;
- return CAIRO_STATUS_SUCCESS;
+ return CAIRO_INT_STATUS_SUCCESS;
}
-static cairo_status_t
+static cairo_int_status_t
_cairo_pdf_surface_close_group (cairo_pdf_surface_t *surface,
cairo_pdf_resource_t *group)
{
- cairo_status_t status = CAIRO_STATUS_SUCCESS, status2;
+ cairo_int_status_t status = CAIRO_INT_STATUS_SUCCESS, status2;
assert (surface->pdf_stream.active == FALSE);
assert (surface->group_stream.active == TRUE);
@@ -1846,7 +1909,7 @@ _cairo_pdf_surface_close_group (cairo_pdf_surface_t *surface,
*group = surface->group_stream.resource;
status2 = _cairo_output_stream_destroy (surface->group_stream.mem_stream);
- if (status == CAIRO_STATUS_SUCCESS)
+ if (status == CAIRO_INT_STATUS_SUCCESS)
status = status2;
surface->group_stream.mem_stream = NULL;
@@ -1855,13 +1918,14 @@ _cairo_pdf_surface_close_group (cairo_pdf_surface_t *surface,
return status;
}
-static cairo_status_t
+static cairo_int_status_t
_cairo_pdf_surface_open_content_stream (cairo_pdf_surface_t *surface,
const cairo_box_double_t *bbox,
cairo_pdf_resource_t *resource,
- cairo_bool_t is_form)
+ cairo_bool_t is_form,
+ cairo_bool_t is_group)
{
- cairo_status_t status;
+ cairo_int_status_t status;
assert (surface->pdf_stream.active == FALSE);
assert (surface->group_stream.active == FALSE);
@@ -1873,25 +1937,41 @@ _cairo_pdf_surface_open_content_stream (cairo_pdf_surface_t *surface,
if (is_form) {
assert (bbox != NULL);
- status =
- _cairo_pdf_surface_open_stream (surface,
- resource,
- surface->compress_content,
- " /Type /XObject\n"
- " /Subtype /Form\n"
- " /BBox [ %f %f %f %f ]\n"
- " /Group <<\n"
- " /Type /Group\n"
- " /S /Transparency\n"
- " /I true\n"
- " /CS /DeviceRGB\n"
- " >>\n"
- " /Resources %d 0 R\n",
- bbox->p1.x,
- bbox->p1.y,
- bbox->p2.x,
- bbox->p2.y,
- surface->content_resources.id);
+ if (is_group) {
+ status =
+ _cairo_pdf_surface_open_stream (surface,
+ resource,
+ surface->compress_content,
+ " /Type /XObject\n"
+ " /Subtype /Form\n"
+ " /BBox [ %f %f %f %f ]\n"
+ " /Group <<\n"
+ " /Type /Group\n"
+ " /S /Transparency\n"
+ " /I true\n"
+ " /CS /DeviceRGB\n"
+ " >>\n"
+ " /Resources %d 0 R\n",
+ bbox->p1.x,
+ bbox->p1.y,
+ bbox->p2.x,
+ bbox->p2.y,
+ surface->content_resources.id);
+ } else {
+ status =
+ _cairo_pdf_surface_open_stream (surface,
+ resource,
+ surface->compress_content,
+ " /Type /XObject\n"
+ " /Subtype /Form\n"
+ " /BBox [ %f %f %f %f ]\n"
+ " /Resources %d 0 R\n",
+ bbox->p1.x,
+ bbox->p1.y,
+ bbox->p2.x,
+ bbox->p2.y,
+ surface->content_resources.id);
+ }
} else {
status =
_cairo_pdf_surface_open_stream (surface,
@@ -1909,10 +1989,10 @@ _cairo_pdf_surface_open_content_stream (cairo_pdf_surface_t *surface,
return _cairo_output_stream_get_status (surface->output);
}
-static cairo_status_t
+static cairo_int_status_t
_cairo_pdf_surface_close_content_stream (cairo_pdf_surface_t *surface)
{
- cairo_status_t status;
+ cairo_int_status_t status;
assert (surface->pdf_stream.active == TRUE);
assert (surface->group_stream.active == FALSE);
@@ -1956,6 +2036,8 @@ _cairo_pdf_surface_finish (void *abstract_surface)
long offset;
cairo_pdf_resource_t info, catalog;
cairo_status_t status, status2;
+ int size, i;
+ cairo_pdf_jbig2_global_t *global;
status = surface->base.status;
if (status == CAIRO_STATUS_SUCCESS)
@@ -2045,6 +2127,17 @@ _cairo_pdf_surface_finish (void *abstract_surface)
surface->font_subsets = NULL;
}
+ size = _cairo_array_num_elements (&surface->jbig2_global);
+ for (i = 0; i < size; i++) {
+ global = (cairo_pdf_jbig2_global_t *) _cairo_array_index (&surface->jbig2_global, i);
+ free(global->id);
+ if (!global->emitted)
+ return _cairo_error (CAIRO_STATUS_JBIG2_GLOBAL_MISSING);
+ }
+ _cairo_array_fini (&surface->jbig2_global);
+
+ _cairo_array_truncate (&surface->page_surfaces, 0);
+
_cairo_surface_clipper_reset (&surface->clipper);
return status;
@@ -2085,7 +2178,7 @@ static cairo_int_status_t
_cairo_pdf_surface_has_fallback_images (void *abstract_surface,
cairo_bool_t has_fallbacks)
{
- cairo_status_t status;
+ cairo_int_status_t status;
cairo_pdf_surface_t *surface = abstract_surface;
cairo_box_double_t bbox;
@@ -2094,7 +2187,7 @@ _cairo_pdf_surface_has_fallback_images (void *abstract_surface,
bbox.p1.y = 0;
bbox.p2.x = surface->width;
bbox.p2.y = surface->height;
- status = _cairo_pdf_surface_open_content_stream (surface, &bbox, NULL, has_fallbacks);
+ status = _cairo_pdf_surface_open_content_stream (surface, &bbox, NULL, has_fallbacks, has_fallbacks);
if (unlikely (status))
return status;
@@ -2107,7 +2200,7 @@ _cairo_pdf_surface_supports_fine_grained_fallbacks (void *abstract_surface)
return TRUE;
}
-static cairo_status_t
+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,
@@ -2144,7 +2237,7 @@ _cairo_pdf_surface_add_padded_image_surface (cairo_pdf_surface_t *surfa
h = image->height;
if (_cairo_fixed_integer_ceil(box.p1.x) < 0 ||
_cairo_fixed_integer_ceil(box.p1.y) < 0 ||
- _cairo_fixed_integer_floor(box.p2.y) > w ||
+ _cairo_fixed_integer_floor(box.p2.x) > w ||
_cairo_fixed_integer_floor(box.p2.y) > h)
{
pad_image = _cairo_image_surface_create_with_content (image->base.content,
@@ -2169,9 +2262,12 @@ _cairo_pdf_surface_add_padded_image_surface (cairo_pdf_surface_t *surfa
status = _cairo_pdf_surface_add_source_surface (surface,
pad_image,
NULL,
+ FALSE,
source->filter,
FALSE,
+ FALSE,
extents,
+ NULL,
surface_res,
width,
height,
@@ -2202,24 +2298,16 @@ BAIL:
return status;
}
-/* Emit alpha channel from the image into the given data, providing
- * an id that can be used to reference the resulting SMask object.
- *
- * In the case that the alpha channel happens to be all opaque, then
- * no SMask object will be emitted and *id_ret will be set to 0.
- *
- * When stencil_mask is TRUE, stream_res is an an input specifying the
- * resource to use. When stencil_mask is FALSE, a new resource will be
- * created and returned in stream_res.
+/* Emit alpha channel from the image into stream_res.
*/
-static cairo_status_t
+static cairo_int_status_t
_cairo_pdf_surface_emit_smask (cairo_pdf_surface_t *surface,
cairo_image_surface_t *image,
cairo_bool_t stencil_mask,
- const char *interpolate,
+ cairo_bool_t interpolate,
cairo_pdf_resource_t *stream_res)
{
- cairo_status_t status = CAIRO_STATUS_SUCCESS;
+ cairo_int_status_t status = CAIRO_STATUS_SUCCESS;
char *alpha;
unsigned long alpha_size;
uint32_t *pixel32;
@@ -2229,6 +2317,7 @@ _cairo_pdf_surface_emit_smask (cairo_pdf_surface_t *surface,
/* This is the only image format we support, which simplifies things. */
assert (image->format == CAIRO_FORMAT_ARGB32 ||
+ image->format == CAIRO_FORMAT_RGB24 ||
image->format == CAIRO_FORMAT_A8 ||
image->format == CAIRO_FORMAT_A1 );
@@ -2237,11 +2326,10 @@ _cairo_pdf_surface_emit_smask (cairo_pdf_surface_t *surface,
assert (transparency == CAIRO_IMAGE_IS_OPAQUE ||
transparency == CAIRO_IMAGE_HAS_BILEVEL_ALPHA);
} else {
- if (transparency == CAIRO_IMAGE_IS_OPAQUE)
- return status;
+ assert (transparency != CAIRO_IMAGE_IS_OPAQUE);
}
- if (transparency == CAIRO_IMAGE_HAS_BILEVEL_ALPHA) {
+ if (transparency == CAIRO_IMAGE_HAS_BILEVEL_ALPHA || transparency == CAIRO_IMAGE_IS_OPAQUE) {
alpha_size = (image->width + 7) / 8 * image->height;
alpha = _cairo_malloc_ab ((image->width+7) / 8, image->height);
} else {
@@ -2256,7 +2344,10 @@ _cairo_pdf_surface_emit_smask (cairo_pdf_surface_t *surface,
i = 0;
for (y = 0; y < image->height; y++) {
- if (image->format == CAIRO_FORMAT_A1) {
+ if (transparency == CAIRO_IMAGE_IS_OPAQUE) {
+ for (x = 0; x < (image->width + 7) / 8; x++)
+ alpha[i++] = 0xff;
+ } else if (image->format == CAIRO_FORMAT_A1) {
pixel8 = (uint8_t *) (image->data + y * image->stride);
for (x = 0; x < (image->width + 7) / 8; x++, pixel8++) {
@@ -2308,11 +2399,11 @@ _cairo_pdf_surface_emit_smask (cairo_pdf_surface_t *surface,
" /Interpolate %s\n"
" /BitsPerComponent 1\n"
" /Decode [1 0]\n",
- image->width, image->height, interpolate);
+ image->width, image->height,
+ interpolate ? "true" : "false");
} else {
- stream_res->id = 0;
status = _cairo_pdf_surface_open_stream (surface,
- NULL,
+ stream_res,
TRUE,
" /Type /XObject\n"
" /Subtype /Image\n"
@@ -2321,15 +2412,13 @@ _cairo_pdf_surface_emit_smask (cairo_pdf_surface_t *surface,
" /ColorSpace /DeviceGray\n"
" /Interpolate %s\n"
" /BitsPerComponent %d\n",
- image->width, image->height, interpolate,
+ image->width, image->height,
+ interpolate ? "true" : "false",
transparency == CAIRO_IMAGE_HAS_ALPHA ? 8 : 1);
}
if (unlikely (status))
goto CLEANUP_ALPHA;
- if (!stencil_mask)
- *stream_res = surface->pdf_stream.self;
-
_cairo_output_stream_write (surface->output, alpha, alpha_size);
status = _cairo_pdf_surface_close_stream (surface);
@@ -2339,25 +2428,33 @@ _cairo_pdf_surface_emit_smask (cairo_pdf_surface_t *surface,
return status;
}
-/* Emit image data into the given surface, providing a resource that
- * can be used to reference the data in image_ret. */
-static cairo_status_t
-_cairo_pdf_surface_emit_image (cairo_pdf_surface_t *surface,
- cairo_image_surface_t *image_surf,
- cairo_pdf_resource_t *image_res,
- cairo_filter_t filter,
- cairo_bool_t stencil_mask)
+/**
+ * _cairo_pdf_surface_emit_image:
+ * @surface: the pdf surface
+ * @image_surf: The image to write
+ * @surface_entry: Contains image resource, smask resource, interpolate and stencil mask parameters.
+ *
+ * Emit an image stream using the @image_res resource and write out
+ * the image data from @image_surf. If @smask_res is not null, @smask_res will
+ * be specified as the smask for the image. Otherwise emit the an smask if
+ * the image is requires one.
+ **/
+static cairo_int_status_t
+_cairo_pdf_surface_emit_image (cairo_pdf_surface_t *surface,
+ cairo_image_surface_t *image_surf,
+ cairo_pdf_source_surface_entry_t *surface_entry)
{
- cairo_status_t status = CAIRO_STATUS_SUCCESS;
+ cairo_int_status_t status = CAIRO_STATUS_SUCCESS;
char *data;
unsigned long data_size;
uint32_t *pixel;
int i, x, y, bit;
cairo_pdf_resource_t smask = {0}; /* squelch bogus compiler warning */
cairo_bool_t need_smask;
- const char *interpolate = "true";
cairo_image_color_t color;
cairo_image_surface_t *image;
+ cairo_image_transparency_t transparency;
+ char smask_buf[30];
image = image_surf;
if (image->format != CAIRO_FORMAT_RGB24 &&
@@ -2386,26 +2483,19 @@ _cairo_pdf_surface_emit_image (cairo_pdf_surface_t *surface,
goto CLEANUP;
}
- switch (filter) {
- 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 (surface_entry->smask || surface_entry->stencil_mask) {
+ return _cairo_pdf_surface_emit_smask (surface, image,
+ surface_entry->stencil_mask,
+ surface_entry->interpolate,
+ &surface_entry->surface_res);
}
- if (stencil_mask)
- return _cairo_pdf_surface_emit_smask (surface, image, stencil_mask, interpolate, image_res);
-
color = _cairo_image_analyze_color (image);
switch (color) {
- case CAIRO_IMAGE_IS_COLOR:
+ default:
case CAIRO_IMAGE_UNKNOWN_COLOR:
+ ASSERT_NOT_REACHED;
+ case CAIRO_IMAGE_IS_COLOR:
data_size = image->height * image->width * 3;
data = _cairo_malloc_abc (image->width, image->height, 3);
break;
@@ -2484,46 +2574,53 @@ _cairo_pdf_surface_emit_image (cairo_pdf_surface_t *surface,
i++;
}
- need_smask = FALSE;
- if (image->format == CAIRO_FORMAT_ARGB32 ||
- image->format == CAIRO_FORMAT_A8 ||
- image->format == CAIRO_FORMAT_A1) {
- status = _cairo_pdf_surface_emit_smask (surface, image, FALSE, interpolate, &smask);
- if (unlikely (status))
- goto CLEANUP_RGB;
+ if (surface_entry->smask_res.id != 0) {
+ need_smask = TRUE;
+ smask = surface_entry->smask_res;
+ } else {
+ need_smask = FALSE;
+ if (image->format == CAIRO_FORMAT_ARGB32 ||
+ image->format == CAIRO_FORMAT_A8 ||
+ image->format == CAIRO_FORMAT_A1)
+ {
+ transparency = _cairo_image_analyze_transparency (image);
+ if (transparency != CAIRO_IMAGE_IS_OPAQUE) {
+ need_smask = TRUE;
+ smask = _cairo_pdf_surface_new_object (surface);
+ if (smask.id == 0) {
+ status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ goto CLEANUP_RGB;
+ }
- if (smask.id)
- need_smask = TRUE;
+ status = _cairo_pdf_surface_emit_smask (surface, image, FALSE, surface_entry->interpolate, &smask);
+ if (unlikely (status))
+ goto CLEANUP_RGB;
+ }
+ }
}
-#define IMAGE_DICTIONARY " /Type /XObject\n" \
- " /Subtype /Image\n" \
- " /Width %d\n" \
- " /Height %d\n" \
- " /ColorSpace %s\n" \
- " /Interpolate %s\n" \
- " /BitsPerComponent %d\n"
-
if (need_smask)
- status = _cairo_pdf_surface_open_stream (surface,
- image_res,
- TRUE,
- IMAGE_DICTIONARY
- " /SMask %d 0 R\n",
- image->width, image->height,
- color == CAIRO_IMAGE_IS_COLOR ? "/DeviceRGB" : "/DeviceGray",
- interpolate,
- color == CAIRO_IMAGE_IS_MONOCHROME? 1 : 8,
- smask.id);
+ snprintf(smask_buf, sizeof(smask_buf), " /SMask %d 0 R\n", smask.id);
else
- status = _cairo_pdf_surface_open_stream (surface,
- image_res,
- TRUE,
- IMAGE_DICTIONARY,
- image->width, image->height,
- color == CAIRO_IMAGE_IS_COLOR ? "/DeviceRGB" : "/DeviceGray",
- interpolate,
- color == CAIRO_IMAGE_IS_MONOCHROME? 1 : 8);
+ smask_buf[0] = 0;
+
+ status = _cairo_pdf_surface_open_stream (surface,
+ &surface_entry->surface_res,
+ TRUE,
+ " /Type /XObject\n"
+ " /Subtype /Image\n"
+ " /Width %d\n"
+ " /Height %d\n"
+ " /ColorSpace %s\n"
+ " /Interpolate %s\n"
+ " /BitsPerComponent %d\n"
+ "%s",
+ image->width,
+ image->height,
+ color == CAIRO_IMAGE_IS_COLOR ? "/DeviceRGB" : "/DeviceGray",
+ surface_entry->interpolate ? "true" : "false",
+ color == CAIRO_IMAGE_IS_MONOCHROME? 1 : 8,
+ smask_buf);
if (unlikely (status))
goto CLEANUP_RGB;
@@ -2542,14 +2639,165 @@ CLEANUP:
}
static cairo_int_status_t
-_cairo_pdf_surface_emit_jpx_image (cairo_pdf_surface_t *surface,
- cairo_surface_t *source,
- cairo_pdf_resource_t res)
+_cairo_pdf_surface_lookup_jbig2_global (cairo_pdf_surface_t *surface,
+ const unsigned char *global_id,
+ unsigned long global_id_length,
+ cairo_pdf_jbig2_global_t **entry)
{
- cairo_status_t status;
+ cairo_pdf_jbig2_global_t global;
+ int size, i;
+ cairo_int_status_t status;
+
+ size = _cairo_array_num_elements (&surface->jbig2_global);
+ for (i = 0; i < size; i++) {
+ *entry = (cairo_pdf_jbig2_global_t *) _cairo_array_index (&surface->jbig2_global, i);
+ if ((*entry)->id && global_id && (*entry)->id_length == global_id_length
+ && memcmp((*entry)->id, global_id, global_id_length) == 0) {
+ return CAIRO_STATUS_SUCCESS;
+ }
+ }
+
+ global.id = malloc(global_id_length);
+ if (unlikely (global.id == NULL)) {
+ return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ }
+
+ memcpy (global.id, global_id, global_id_length);
+ global.id_length = global_id_length;
+ global.res = _cairo_pdf_surface_new_object (surface);
+ if (global.res.id == 0) {
+ free(global.id);
+ return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ }
+
+ global.emitted = FALSE;
+ status = _cairo_array_append (&surface->jbig2_global, &global);
+ if (unlikely(status))
+ return status;
+
+ size = _cairo_array_num_elements (&surface->jbig2_global);
+ *entry = (cairo_pdf_jbig2_global_t *) _cairo_array_index (&surface->jbig2_global, size - 1);
+ return CAIRO_STATUS_SUCCESS;
+}
+
+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_int_status_t status;
const unsigned char *mime_data;
unsigned long mime_data_length;
cairo_image_info_t info;
+ const unsigned char *global_id;
+ unsigned long global_id_length;
+ const unsigned char *global_data;
+ unsigned long global_data_length;
+ cairo_pdf_jbig2_global_t *global_entry = NULL; /* hide compiler warning */
+ char smask_buf[30];
+ char decode_parms_buf[100];
+
+ cairo_surface_get_mime_data (source, CAIRO_MIME_TYPE_JBIG2,
+ &mime_data, &mime_data_length);
+ if (mime_data == NULL)
+ return CAIRO_INT_STATUS_UNSUPPORTED;
+
+ status = _cairo_image_info_get_jbig2_info (&info, mime_data, mime_data_length);
+ if (status)
+ return status;
+
+ cairo_surface_get_mime_data (source, CAIRO_MIME_TYPE_JBIG2_GLOBAL_ID,
+ &global_id, &global_id_length);
+ if (global_id && global_id_length > 0) {
+ status = _cairo_pdf_surface_lookup_jbig2_global (surface, global_id, global_id_length, &global_entry);
+ if (unlikely(status))
+ return status;
+
+ if (!global_entry->emitted) {
+ cairo_surface_get_mime_data (source, CAIRO_MIME_TYPE_JBIG2_GLOBAL,
+ &global_data, &global_data_length);
+ if (global_data) {
+ status = _cairo_pdf_surface_open_stream (surface, &global_entry->res, FALSE, NULL);
+ if (unlikely(status))
+ return status;
+
+ _cairo_output_stream_write (surface->output, global_data, global_data_length);
+ status = _cairo_pdf_surface_close_stream (surface);
+ if (unlikely(status))
+ return status;
+
+ global_entry->emitted = TRUE;
+ }
+ }
+
+ snprintf(decode_parms_buf, sizeof(decode_parms_buf),
+ " /DecodeParms << /JBIG2Globals %d 0 R >>\n", global_entry->res.id);
+ } else {
+ decode_parms_buf[0] = 0;
+ }
+
+ if (surface_entry->smask_res.id)
+ snprintf(smask_buf, sizeof(smask_buf), " /SMask %d 0 R\n", surface_entry->smask_res.id);
+ else
+ smask_buf[0] = 0;
+
+ 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 /JPXDecode\n"
+ "%s",
+ info.width,
+ info.height,
+ surface_entry->interpolate ? "true" : "false",
+ decode_parms_buf);
+ } else {
+ 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"
+ "%s"
+ " /Filter /JBIG2Decode\n"
+ "%s",
+ info.width,
+ info.height,
+ surface_entry->interpolate ? "true" : "false",
+ smask_buf,
+ decode_parms_buf);
+ }
+ if (unlikely(status))
+ return status;
+
+ _cairo_output_stream_write (surface->output, mime_data, mime_data_length);
+ status = _cairo_pdf_surface_close_stream (surface);
+
+ return status;
+}
+
+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_int_status_t status;
+ const unsigned char *mime_data;
+ unsigned long mime_data_length;
+ cairo_image_info_t info;
+ char smask_buf[30];
if (surface->pdf_version < CAIRO_PDF_VERSION_1_5)
return CAIRO_INT_STATUS_UNSUPPORTED;
@@ -2563,16 +2811,49 @@ _cairo_pdf_surface_emit_jpx_image (cairo_pdf_surface_t *surface,
if (status)
return status;
- status = _cairo_pdf_surface_open_stream (surface,
- &res,
- FALSE,
- " /Type /XObject\n"
- " /Subtype /Image\n"
- " /Width %d\n"
- " /Height %d\n"
- " /Filter /JPXDecode\n",
- info.width,
- info.height);
+ if ((surface_entry->smask || surface_entry->stencil_mask) && info.num_components != 1)
+ return CAIRO_INT_STATUS_UNSUPPORTED;
+
+ if ((surface_entry->stencil_mask) && info.bits_per_component != 1)
+ return CAIRO_INT_STATUS_UNSUPPORTED;
+
+ if (surface_entry->smask_res.id)
+ snprintf(smask_buf, sizeof(smask_buf), " /SMask %d 0 R\n", surface_entry->smask_res.id);
+ else
+ smask_buf[0] = 0;
+
+ 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 /JPXDecode\n",
+ info.width,
+ info.height,
+ surface_entry->interpolate ? "true" : "false");
+ } else {
+ status = _cairo_pdf_surface_open_stream (surface,
+ &surface_entry->surface_res,
+ FALSE,
+ " /Type /XObject\n"
+ " /Subtype /Image\n"
+ " /Width %d\n"
+ " /Height %d\n"
+ " /Interpolate %s\n"
+ "%s"
+ " /Filter /JPXDecode\n",
+ info.width,
+ info.height,
+ surface_entry->interpolate ? "true" : "false",
+ smask_buf);
+ }
if (status)
return status;
@@ -2583,15 +2864,16 @@ _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_resource_t res)
+_cairo_pdf_surface_emit_jpeg_image (cairo_pdf_surface_t *surface,
+ cairo_surface_t *source,
+ cairo_pdf_source_surface_entry_t *surface_entry)
{
- cairo_status_t status;
+ cairo_int_status_t status;
const unsigned char *mime_data;
unsigned long mime_data_length;
cairo_image_info_t info;
const char *colorspace;
+ char smask_buf[30];
cairo_surface_get_mime_data (source, CAIRO_MIME_TYPE_JPEG,
&mime_data, &mime_data_length);
@@ -2604,6 +2886,12 @@ _cairo_pdf_surface_emit_jpeg_image (cairo_pdf_surface_t *surface,
if (unlikely (status))
return status;
+ if ((surface_entry->smask || surface_entry->stencil_mask) && info.num_components != 1)
+ return CAIRO_INT_STATUS_UNSUPPORTED;
+
+ if ((surface_entry->stencil_mask) && info.bits_per_component != 1)
+ return CAIRO_INT_STATUS_UNSUPPORTED;
+
switch (info.num_components) {
case 1:
colorspace = "/DeviceGray";
@@ -2618,20 +2906,47 @@ _cairo_pdf_surface_emit_jpeg_image (cairo_pdf_surface_t *surface,
return CAIRO_INT_STATUS_UNSUPPORTED;
}
- status = _cairo_pdf_surface_open_stream (surface,
- &res,
- FALSE,
- " /Type /XObject\n"
- " /Subtype /Image\n"
- " /Width %d\n"
- " /Height %d\n"
- " /ColorSpace %s\n"
- " /BitsPerComponent %d\n"
- " /Filter /DCTDecode\n",
- info.width,
- info.height,
- colorspace,
- info.bits_per_component);
+ if (surface_entry->smask_res.id)
+ snprintf(smask_buf, sizeof(smask_buf), " /SMask %d 0 R\n", surface_entry->smask_res.id);
+ else
+ smask_buf[0] = 0;
+
+ 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 /DCTDecode\n",
+ info.width,
+ info.height,
+ surface_entry->interpolate ? "true" : "false");
+ } else {
+ 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 %s\n"
+ " /Interpolate %s\n"
+ " /BitsPerComponent %d\n"
+ "%s"
+ " /Filter /DCTDecode\n",
+ info.width,
+ info.height,
+ colorspace,
+ surface_entry->interpolate ? "true" : "false",
+ info.bits_per_component,
+ smask_buf);
+ }
if (unlikely (status))
return status;
@@ -2641,7 +2956,7 @@ _cairo_pdf_surface_emit_jpeg_image (cairo_pdf_surface_t *surface,
return status;
}
-static cairo_status_t
+static cairo_int_status_t
_cairo_pdf_surface_emit_image_surface (cairo_pdf_surface_t *surface,
cairo_pdf_source_surface_t *source)
{
@@ -2650,6 +2965,20 @@ _cairo_pdf_surface_emit_image_surface (cairo_pdf_surface_t *surface,
cairo_int_status_t status;
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;
+
+ status = _cairo_pdf_surface_emit_jpx_image (surface, source->surface, source->hash_entry);
+ if (status != CAIRO_INT_STATUS_UNSUPPORTED)
+ return status;
+
+ status = _cairo_pdf_surface_emit_jpeg_image (surface, source->surface, source->hash_entry);
+ if (status != CAIRO_INT_STATUS_UNSUPPORTED)
+ return status;
+ }
+
+ 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,
@@ -2658,22 +2987,10 @@ _cairo_pdf_surface_emit_image_surface (cairo_pdf_surface_t *surface,
if (unlikely (status))
return status;
- if (!source->hash_entry->stencil_mask) {
- status = _cairo_pdf_surface_emit_jpx_image (surface, &image->base, source->hash_entry->surface_res);
- if (status != CAIRO_INT_STATUS_UNSUPPORTED)
- goto release_source;
+ status = _cairo_pdf_surface_emit_image (surface,
+ image,
+ source->hash_entry);
- status = _cairo_pdf_surface_emit_jpeg_image (surface, &image->base, source->hash_entry->surface_res);
- if (status != CAIRO_INT_STATUS_UNSUPPORTED)
- goto release_source;
- }
-
- status = _cairo_pdf_surface_emit_image (surface, image,
- &source->hash_entry->surface_res,
- source->hash_entry->interpolate,
- source->hash_entry->stencil_mask);
-
-release_source:
if (source->type == CAIRO_PATTERN_TYPE_SURFACE)
_cairo_surface_release_source_image (source->surface, image, image_extra);
else
@@ -2683,7 +3000,7 @@ release_source:
return status;
}
-static cairo_status_t
+static cairo_int_status_t
_cairo_pdf_surface_emit_recording_surface (cairo_pdf_surface_t *surface,
cairo_pdf_source_surface_t *pdf_source)
{
@@ -2699,6 +3016,8 @@ _cairo_pdf_surface_emit_recording_surface (cairo_pdf_surface_t *surface,
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;
@@ -2718,6 +3037,9 @@ _cairo_pdf_surface_emit_recording_surface (cairo_pdf_surface_t *surface,
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_paginated_mode = surface->paginated_mode;
@@ -2734,7 +3056,16 @@ _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);
- status = _cairo_pdf_surface_open_content_stream (surface, &bbox, &pdf_source->hash_entry->surface_res, TRUE);
+
+ /* 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.
+ */
+ transparency_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);
if (unlikely (status))
goto err;
@@ -2772,7 +3103,7 @@ err:
return status;
}
-static cairo_status_t
+static cairo_int_status_t
_cairo_pdf_surface_emit_surface (cairo_pdf_surface_t *surface,
cairo_pdf_source_surface_t *src_surface)
{
@@ -2783,12 +3114,12 @@ _cairo_pdf_surface_emit_surface (cairo_pdf_surface_t *surface,
return _cairo_pdf_surface_emit_image_surface (surface, src_surface);
}
-static cairo_status_t
+static cairo_int_status_t
_cairo_pdf_surface_emit_surface_pattern (cairo_pdf_surface_t *surface,
cairo_pdf_pattern_t *pdf_pattern)
{
cairo_pattern_t *pattern = pdf_pattern->pattern;
- cairo_status_t status;
+ 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);
@@ -2818,9 +3149,12 @@ _cairo_pdf_surface_emit_surface_pattern (cairo_pdf_surface_t *surface,
status = _cairo_pdf_surface_add_source_surface (surface,
NULL,
pattern,
+ pdf_pattern->operator,
pattern->filter,
FALSE,
+ FALSE,
&pdf_pattern->extents,
+ NULL,
&pattern_resource,
&pattern_width,
&pattern_height,
@@ -2911,7 +3245,7 @@ _cairo_pdf_surface_emit_surface_pattern (cairo_pdf_surface_t *surface,
cairo_p2d = pattern->matrix;
status = cairo_matrix_invert (&cairo_p2d);
/* cairo_pattern_set_matrix ensures the matrix is invertible */
- assert (status == CAIRO_STATUS_SUCCESS);
+ 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);
@@ -2989,7 +3323,7 @@ typedef struct _cairo_pdf_color_stop {
cairo_pdf_resource_t resource;
} cairo_pdf_color_stop_t;
-static cairo_status_t
+static cairo_int_status_t
cairo_pdf_surface_emit_rgb_linear_function (cairo_pdf_surface_t *surface,
cairo_pdf_color_stop_t *stop1,
cairo_pdf_color_stop_t *stop2,
@@ -2998,7 +3332,7 @@ cairo_pdf_surface_emit_rgb_linear_function (cairo_pdf_surface_t *surface,
int num_elems, i;
cairo_pdf_rgb_linear_function_t elem;
cairo_pdf_resource_t res;
- cairo_status_t status;
+ cairo_int_status_t status;
num_elems = _cairo_array_num_elements (&surface->rgb_linear_functions);
for (i = 0; i < num_elems; i++) {
@@ -3042,7 +3376,7 @@ cairo_pdf_surface_emit_rgb_linear_function (cairo_pdf_surface_t *surface,
return status;
}
-static cairo_status_t
+static cairo_int_status_t
cairo_pdf_surface_emit_alpha_linear_function (cairo_pdf_surface_t *surface,
cairo_pdf_color_stop_t *stop1,
cairo_pdf_color_stop_t *stop2,
@@ -3051,7 +3385,7 @@ cairo_pdf_surface_emit_alpha_linear_function (cairo_pdf_surface_t *surface,
int num_elems, i;
cairo_pdf_alpha_linear_function_t elem;
cairo_pdf_resource_t res;
- cairo_status_t status;
+ cairo_int_status_t status;
num_elems = _cairo_array_num_elements (&surface->alpha_linear_functions);
for (i = 0; i < num_elems; i++) {
@@ -3091,7 +3425,7 @@ cairo_pdf_surface_emit_alpha_linear_function (cairo_pdf_surface_t *surface,
return status;
}
-static cairo_status_t
+static cairo_int_status_t
_cairo_pdf_surface_emit_stitched_colorgradient (cairo_pdf_surface_t *surface,
unsigned int n_stops,
cairo_pdf_color_stop_t *stops,
@@ -3100,7 +3434,7 @@ _cairo_pdf_surface_emit_stitched_colorgradient (cairo_pdf_surface_t *surface,
{
cairo_pdf_resource_t res;
unsigned int i;
- cairo_status_t status;
+ cairo_int_status_t status;
/* emit linear gradients between pairs of subsequent stops... */
for (i = 0; i < n_stops-1; i++) {
@@ -3182,7 +3516,7 @@ calc_gradient_color (cairo_pdf_color_stop_t *new_stop,
#define COLOR_STOP_EPSILON 1e-6
-static cairo_status_t
+static cairo_int_status_t
_cairo_pdf_surface_emit_pattern_stops (cairo_pdf_surface_t *surface,
cairo_gradient_pattern_t *pattern,
cairo_pdf_resource_t *color_function,
@@ -3192,7 +3526,7 @@ _cairo_pdf_surface_emit_pattern_stops (cairo_pdf_surface_t *surface,
unsigned int n_stops;
unsigned int i;
cairo_bool_t emit_alpha = FALSE;
- cairo_status_t status;
+ cairo_int_status_t status;
color_function->id = 0;
alpha_function->id = 0;
@@ -3326,7 +3660,7 @@ BAIL:
return status;
}
-static cairo_status_t
+static cairo_int_status_t
_cairo_pdf_surface_emit_repeating_function (cairo_pdf_surface_t *surface,
cairo_gradient_pattern_t *pattern,
cairo_pdf_resource_t *function,
@@ -3387,14 +3721,14 @@ _cairo_pdf_surface_emit_repeating_function (cairo_pdf_surface_t *surface,
return _cairo_output_stream_get_status (surface->output);
}
-static cairo_status_t
+static cairo_int_status_t
cairo_pdf_surface_emit_transparency_group (cairo_pdf_surface_t *surface,
cairo_pdf_pattern_t *pdf_pattern,
cairo_pdf_resource_t gstate_resource,
cairo_pdf_resource_t gradient_mask)
{
cairo_pdf_resource_t smask_resource;
- cairo_status_t status;
+ cairo_int_status_t status;
char buf[100];
double x1, y1, x2, y2;
@@ -3531,11 +3865,11 @@ _cairo_pdf_surface_output_gradient (cairo_pdf_surface_t *surface,
_cairo_output_stream_printf (surface->output,
"<< /Type /Pattern\n"
" /PatternType 2\n"
- " /Matrix [ %f %f %f %f %f %f ]\n"
- " /Shading\n",
- pat_to_pdf->xx, pat_to_pdf->yx,
- pat_to_pdf->xy, pat_to_pdf->yy,
- pat_to_pdf->x0, pat_to_pdf->y0);
+ " /Matrix [ ");
+ _cairo_output_stream_print_matrix (surface->output, pat_to_pdf);
+ _cairo_output_stream_printf (surface->output,
+ " ]\n"
+ " /Shading\n");
}
if (pdf_pattern->pattern->type == CAIRO_PATTERN_TYPE_LINEAR) {
@@ -3577,12 +3911,14 @@ _cairo_pdf_surface_output_gradient (cairo_pdf_surface_t *surface,
if (!pdf_pattern->is_shading) {
_cairo_output_stream_printf (surface->output,
- ">>\n"
- "endobj\n");
+ ">>\n");
}
+
+ _cairo_output_stream_printf (surface->output,
+ "endobj\n");
}
-static cairo_status_t
+static cairo_int_status_t
_cairo_pdf_surface_emit_gradient (cairo_pdf_surface_t *surface,
cairo_pdf_pattern_t *pdf_pattern)
{
@@ -3591,7 +3927,7 @@ _cairo_pdf_surface_emit_gradient (cairo_pdf_surface_t *surface,
cairo_matrix_t pat_to_pdf;
cairo_circle_double_t start, end;
double domain[2];
- cairo_status_t status;
+ cairo_int_status_t status;
assert (pattern->n_stops != 0);
@@ -3605,7 +3941,7 @@ _cairo_pdf_surface_emit_gradient (cairo_pdf_surface_t *surface,
pat_to_pdf = pattern->base.matrix;
status = cairo_matrix_invert (&pat_to_pdf);
/* cairo_pattern_set_matrix ensures the matrix is invertible */
- assert (status == CAIRO_STATUS_SUCCESS);
+ assert (status == CAIRO_INT_STATUS_SUCCESS);
cairo_matrix_multiply (&pat_to_pdf, &pat_to_pdf, &surface->cairo_to_pdf);
if (pattern->base.extend == CAIRO_EXTEND_REPEAT ||
@@ -3728,12 +4064,12 @@ _cairo_pdf_surface_emit_gradient (cairo_pdf_surface_t *surface,
return _cairo_output_stream_get_status (surface->output);
}
-static cairo_status_t
+static cairo_int_status_t
_cairo_pdf_surface_emit_mesh_pattern (cairo_pdf_surface_t *surface,
cairo_pdf_pattern_t *pdf_pattern)
{
cairo_matrix_t pat_to_pdf;
- cairo_status_t status;
+ cairo_int_status_t status;
cairo_pattern_t *pattern = pdf_pattern->pattern;
cairo_pdf_shading_t shading;
int i;
@@ -3742,7 +4078,7 @@ _cairo_pdf_surface_emit_mesh_pattern (cairo_pdf_surface_t *surface,
pat_to_pdf = pattern->matrix;
status = cairo_matrix_invert (&pat_to_pdf);
/* cairo_pattern_set_matrix ensures the matrix is invertible */
- assert (status == CAIRO_STATUS_SUCCESS);
+ assert (status == CAIRO_INT_STATUS_SUCCESS);
cairo_matrix_multiply (&pat_to_pdf, &pat_to_pdf, &surface->cairo_to_pdf);
@@ -3791,14 +4127,14 @@ _cairo_pdf_surface_emit_mesh_pattern (cairo_pdf_surface_t *surface,
"%d 0 obj\n"
"<< /Type /Pattern\n"
" /PatternType 2\n"
- " /Matrix [ %f %f %f %f %f %f ]\n"
+ " /Matrix [ ",
+ pdf_pattern->pattern_res.id);
+ _cairo_output_stream_print_matrix (surface->output, &pat_to_pdf);
+ _cairo_output_stream_printf (surface->output,
+ " ]\n"
" /Shading %d 0 R\n"
">>\n"
"endobj\n",
- pdf_pattern->pattern_res.id,
- pat_to_pdf.xx, pat_to_pdf.yx,
- pat_to_pdf.xy, pat_to_pdf.yy,
- pat_to_pdf.x0, pat_to_pdf.y0,
res.id);
if (pdf_pattern->gstate_res.id != 0) {
@@ -3852,14 +4188,14 @@ _cairo_pdf_surface_emit_mesh_pattern (cairo_pdf_surface_t *surface,
"%d 0 obj\n"
"<< /Type /Pattern\n"
" /PatternType 2\n"
- " /Matrix [ %f %f %f %f %f %f ]\n"
+ " /Matrix [ ",
+ mask_resource.id);
+ _cairo_output_stream_print_matrix (surface->output, &pat_to_pdf);
+ _cairo_output_stream_printf (surface->output,
+ " ]\n"
" /Shading %d 0 R\n"
">>\n"
"endobj\n",
- mask_resource.id,
- pat_to_pdf.xx, pat_to_pdf.yx,
- pat_to_pdf.xy, pat_to_pdf.yy,
- pat_to_pdf.x0, pat_to_pdf.y0,
res.id);
status = cairo_pdf_surface_emit_transparency_group (surface,
@@ -3873,11 +4209,11 @@ _cairo_pdf_surface_emit_mesh_pattern (cairo_pdf_surface_t *surface,
return _cairo_output_stream_get_status (surface->output);
}
-static cairo_status_t
+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_status_t status;
+ cairo_int_status_t status;
old_width = surface->width;
old_height = surface->height;
@@ -3918,16 +4254,18 @@ _cairo_pdf_surface_emit_pattern (cairo_pdf_surface_t *surface, cairo_pdf_pattern
return status;
}
-static cairo_status_t
+static cairo_int_status_t
_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,
+ 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_status_t status;
+ cairo_int_status_t status;
int alpha;
cairo_rectangle_int_t extents2;
double x_offset;
@@ -3949,9 +4287,12 @@ _cairo_pdf_surface_paint_surface_pattern (cairo_pdf_surface_t *surface,
status = _cairo_pdf_surface_add_source_surface (surface,
NULL,
source,
+ op,
source->filter,
stencil_mask,
+ FALSE,
extents,
+ smask_res,
&surface_res,
&width,
&height,
@@ -3965,7 +4306,7 @@ _cairo_pdf_surface_paint_surface_pattern (cairo_pdf_surface_t *surface,
cairo_p2d = source->matrix;
status = cairo_matrix_invert (&cairo_p2d);
/* cairo_pattern_set_matrix ensures the matrix is invertible */
- assert (status == CAIRO_STATUS_SUCCESS);
+ assert (status == CAIRO_INT_STATUS_SUCCESS);
pdf_p2d = surface->cairo_to_pdf;
cairo_matrix_multiply (&pdf_p2d, &cairo_p2d, &pdf_p2d);
@@ -3983,11 +4324,8 @@ _cairo_pdf_surface_paint_surface_pattern (cairo_pdf_surface_t *surface,
return status;
if (! _cairo_matrix_is_identity (&pdf_p2d)) {
- _cairo_output_stream_printf (surface->output,
- "%f %f %f %f %f %f cm\n",
- pdf_p2d.xx, pdf_p2d.yx,
- pdf_p2d.xy, pdf_p2d.yy,
- pdf_p2d.x0, pdf_p2d.y0);
+ _cairo_output_stream_print_matrix (surface->output, &pdf_p2d);
+ _cairo_output_stream_printf (surface->output, " cm\n");
}
status = _cairo_pdf_surface_add_alpha (surface, 1.0, &alpha);
@@ -4008,28 +4346,29 @@ _cairo_pdf_surface_paint_surface_pattern (cairo_pdf_surface_t *surface,
return _cairo_pdf_surface_add_xobject (surface, surface_res);
}
-static cairo_status_t
+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)
{
cairo_pdf_resource_t shading_res, gstate_res;
cairo_matrix_t pat_to_pdf;
- cairo_status_t status;
+ cairo_int_status_t status;
int alpha;
status = _cairo_pdf_surface_add_pdf_shading (surface, source,
- extents,
+ op, extents,
&shading_res, &gstate_res);
if (unlikely (status == CAIRO_INT_STATUS_NOTHING_TO_DO))
- return CAIRO_STATUS_SUCCESS;
+ return CAIRO_INT_STATUS_SUCCESS;
if (unlikely (status))
return status;
pat_to_pdf = source->matrix;
status = cairo_matrix_invert (&pat_to_pdf);
/* cairo_pattern_set_matrix ensures the matrix is invertible */
- assert (status == CAIRO_STATUS_SUCCESS);
+ assert (status == CAIRO_INT_STATUS_SUCCESS);
cairo_matrix_multiply (&pat_to_pdf, &pat_to_pdf, &surface->cairo_to_pdf);
status = _cairo_pdf_operators_flush (&surface->pdf_operators);
@@ -4037,11 +4376,8 @@ _cairo_pdf_surface_paint_gradient (cairo_pdf_surface_t *surface,
return status;
if (! _cairo_matrix_is_identity (&pat_to_pdf)) {
- _cairo_output_stream_printf (surface->output,
- "%f %f %f %f %f %f cm\n",
- pat_to_pdf.xx, pat_to_pdf.yx,
- pat_to_pdf.xy, pat_to_pdf.yy,
- pat_to_pdf.x0, pat_to_pdf.y0);
+ _cairo_output_stream_print_matrix (surface->output, &pat_to_pdf);
+ _cairo_output_stream_printf (surface->output, " cm\n");
}
status = _cairo_pdf_surface_add_shading (surface, shading_res);
@@ -4071,8 +4407,9 @@ _cairo_pdf_surface_paint_gradient (cairo_pdf_surface_t *surface,
return status;
}
-static cairo_status_t
+static cairo_int_status_t
_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,
cairo_bool_t mask)
@@ -4081,13 +4418,16 @@ _cairo_pdf_surface_paint_pattern (cairo_pdf_surface_t *surface,
case CAIRO_PATTERN_TYPE_SURFACE:
case CAIRO_PATTERN_TYPE_RASTER_SOURCE:
return _cairo_pdf_surface_paint_surface_pattern (surface,
+ op,
source,
extents,
+ NULL,
mask);
case CAIRO_PATTERN_TYPE_LINEAR:
case CAIRO_PATTERN_TYPE_RADIAL:
case CAIRO_PATTERN_TYPE_MESH:
return _cairo_pdf_surface_paint_gradient (surface,
+ op,
source,
extents);
@@ -4123,11 +4463,11 @@ _can_paint_pattern (const cairo_pattern_t *pattern)
}
}
-static cairo_status_t
+static cairo_int_status_t
_cairo_pdf_surface_select_operator (cairo_pdf_surface_t *surface,
cairo_operator_t op)
{
- cairo_status_t status;
+ cairo_int_status_t status;
if (op == surface->current_operator)
return CAIRO_STATUS_SUCCESS;
@@ -4144,13 +4484,13 @@ _cairo_pdf_surface_select_operator (cairo_pdf_surface_t *surface,
return CAIRO_STATUS_SUCCESS;
}
-static cairo_status_t
+static cairo_int_status_t
_cairo_pdf_surface_select_pattern (cairo_pdf_surface_t *surface,
const cairo_pattern_t *pattern,
cairo_pdf_resource_t pattern_res,
cairo_bool_t is_stroke)
{
- cairo_status_t status;
+ cairo_int_status_t status;
int alpha;
const cairo_color_t *solid_color = NULL;
@@ -4366,14 +4706,14 @@ _cairo_pdf_surface_write_pages (cairo_pdf_surface_t *surface)
"endobj\n");
}
-static cairo_status_t
+static cairo_int_status_t
_utf8_to_pdf_string (const char *utf8, char **str_out)
{
int i;
int len;
cairo_bool_t ascii;
char *str;
- cairo_status_t status = CAIRO_STATUS_SUCCESS;
+ cairo_int_status_t status = CAIRO_STATUS_SUCCESS;
ascii = TRUE;
len = strlen (utf8);
@@ -4421,13 +4761,13 @@ _utf8_to_pdf_string (const char *utf8, char **str_out)
return status;
}
-static cairo_status_t
+static cairo_int_status_t
_cairo_pdf_surface_emit_unicode_for_glyph (cairo_pdf_surface_t *surface,
const char *utf8)
{
uint16_t *utf16 = NULL;
int utf16_len = 0;
- cairo_status_t status;
+ cairo_int_status_t status;
int i;
if (utf8 && *utf8) {
@@ -4651,7 +4991,7 @@ _cairo_pdf_surface_emit_to_unicode_stream (cairo_pdf_surface_t *surface,
#define PDF_UNITS_PER_EM 1000
-static cairo_status_t
+static cairo_int_status_t
_cairo_pdf_surface_emit_cff_font (cairo_pdf_surface_t *surface,
cairo_scaled_font_subset_t *font_subset,
cairo_cff_subset_t *subset)
@@ -4660,7 +5000,7 @@ _cairo_pdf_surface_emit_cff_font (cairo_pdf_surface_t *surface,
cairo_pdf_resource_t subset_resource, to_unicode_stream;
cairo_pdf_font_t font;
unsigned int i, last_glyph;
- cairo_status_t status;
+ cairo_int_status_t status;
char tag[10];
_create_font_subset_tag (font_subset, subset->ps_name, tag);
@@ -4690,7 +5030,7 @@ _cairo_pdf_surface_emit_cff_font (cairo_pdf_surface_t *surface,
status = _cairo_pdf_surface_emit_to_unicode_stream (surface,
font_subset,
&to_unicode_stream);
- if (_cairo_status_is_error (status))
+ if (_cairo_int_status_is_error (status))
return status;
descriptor = _cairo_pdf_surface_new_object (surface);
@@ -4848,11 +5188,11 @@ _cairo_pdf_surface_emit_cff_font (cairo_pdf_surface_t *surface,
return status;
}
-static cairo_status_t
+static cairo_int_status_t
_cairo_pdf_surface_emit_cff_font_subset (cairo_pdf_surface_t *surface,
cairo_scaled_font_subset_t *font_subset)
{
- cairo_status_t status;
+ cairo_int_status_t status;
cairo_cff_subset_t subset;
char name[64];
@@ -4869,11 +5209,11 @@ _cairo_pdf_surface_emit_cff_font_subset (cairo_pdf_surface_t *surface,
return status;
}
-static cairo_status_t
+static cairo_int_status_t
_cairo_pdf_surface_emit_cff_fallback_font (cairo_pdf_surface_t *surface,
cairo_scaled_font_subset_t *font_subset)
{
- cairo_status_t status;
+ cairo_int_status_t status;
cairo_cff_subset_t subset;
char name[64];
@@ -4895,14 +5235,14 @@ _cairo_pdf_surface_emit_cff_fallback_font (cairo_pdf_surface_t *surface,
return status;
}
-static cairo_status_t
+static cairo_int_status_t
_cairo_pdf_surface_emit_type1_font (cairo_pdf_surface_t *surface,
cairo_scaled_font_subset_t *font_subset,
cairo_type1_subset_t *subset)
{
cairo_pdf_resource_t stream, descriptor, subset_resource, to_unicode_stream;
cairo_pdf_font_t font;
- cairo_status_t status;
+ cairo_int_status_t status;
unsigned long length;
unsigned int i, last_glyph;
char tag[10];
@@ -4937,7 +5277,7 @@ _cairo_pdf_surface_emit_type1_font (cairo_pdf_surface_t *surface,
status = _cairo_pdf_surface_emit_to_unicode_stream (surface,
font_subset,
&to_unicode_stream);
- if (_cairo_status_is_error (status))
+ if (_cairo_int_status_is_error (status))
return status;
last_glyph = font_subset->num_glyphs - 1;
@@ -5037,11 +5377,11 @@ _cairo_pdf_surface_emit_type1_font (cairo_pdf_surface_t *surface,
return _cairo_array_append (&surface->fonts, &font);
}
-static cairo_status_t
+static cairo_int_status_t
_cairo_pdf_surface_emit_type1_font_subset (cairo_pdf_surface_t *surface,
cairo_scaled_font_subset_t *font_subset)
{
- cairo_status_t status;
+ cairo_int_status_t status;
cairo_type1_subset_t subset;
char name[64];
@@ -5061,11 +5401,11 @@ _cairo_pdf_surface_emit_type1_font_subset (cairo_pdf_surface_t *surface,
return status;
}
-static cairo_status_t
+static cairo_int_status_t
_cairo_pdf_surface_emit_type1_fallback_font (cairo_pdf_surface_t *surface,
cairo_scaled_font_subset_t *font_subset)
{
- cairo_status_t status;
+ cairo_int_status_t status;
cairo_type1_subset_t subset;
char name[64];
@@ -5085,13 +5425,13 @@ _cairo_pdf_surface_emit_type1_fallback_font (cairo_pdf_surface_t *surface,
return status;
}
-static cairo_status_t
+static cairo_int_status_t
_cairo_pdf_surface_emit_truetype_font_subset (cairo_pdf_surface_t *surface,
cairo_scaled_font_subset_t *font_subset)
{
cairo_pdf_resource_t stream, descriptor, cidfont_dict;
cairo_pdf_resource_t subset_resource, to_unicode_stream;
- cairo_status_t status;
+ cairo_int_status_t status;
cairo_pdf_font_t font;
cairo_truetype_subset_t subset;
unsigned int i, last_glyph;
@@ -5131,7 +5471,7 @@ _cairo_pdf_surface_emit_truetype_font_subset (cairo_pdf_surface_t *surface,
status = _cairo_pdf_surface_emit_to_unicode_stream (surface,
font_subset,
&to_unicode_stream);
- if (_cairo_status_is_error (status)) {
+ if (_cairo_int_status_is_error (status)) {
_cairo_truetype_subset_fini (&subset);
return status;
}
@@ -5298,7 +5638,7 @@ _cairo_pdf_surface_emit_truetype_font_subset (cairo_pdf_surface_t *surface,
return status;
}
-static cairo_status_t
+static cairo_int_status_t
_cairo_pdf_emit_imagemask (cairo_image_surface_t *image,
cairo_output_stream_t *stream)
{
@@ -5343,8 +5683,8 @@ _cairo_pdf_surface_analyze_user_font_subset (cairo_scaled_font_subset_t *font_su
void *closure)
{
cairo_pdf_surface_t *surface = closure;
- cairo_status_t status = CAIRO_STATUS_SUCCESS;
- cairo_status_t status2;
+ cairo_int_status_t status = CAIRO_INT_STATUS_SUCCESS;
+ cairo_int_status_t status2;
unsigned int i;
cairo_surface_t *type3_surface;
cairo_output_stream_t *null_stream;
@@ -5353,7 +5693,8 @@ _cairo_pdf_surface_analyze_user_font_subset (cairo_scaled_font_subset_t *font_su
type3_surface = _cairo_type3_glyph_surface_create (font_subset->scaled_font,
null_stream,
_cairo_pdf_emit_imagemask,
- surface->font_subsets);
+ surface->font_subsets,
+ FALSE);
if (unlikely (type3_surface->status)) {
status2 = _cairo_output_stream_destroy (null_stream);
status = type3_surface->status;
@@ -5374,7 +5715,7 @@ _cairo_pdf_surface_analyze_user_font_subset (cairo_scaled_font_subset_t *font_su
cairo_surface_destroy (type3_surface);
status2 = _cairo_output_stream_destroy (null_stream);
- if (status == CAIRO_STATUS_SUCCESS)
+ if (status == CAIRO_INT_STATUS_SUCCESS)
status = status2;
return status;
@@ -5384,7 +5725,7 @@ static cairo_int_status_t
_cairo_pdf_surface_emit_type3_font_subset (cairo_pdf_surface_t *surface,
cairo_scaled_font_subset_t *font_subset)
{
- cairo_status_t status = CAIRO_STATUS_SUCCESS;
+ cairo_int_status_t status = CAIRO_STATUS_SUCCESS;
cairo_pdf_resource_t *glyphs, encoding, char_procs, subset_resource, to_unicode_stream;
cairo_pdf_font_t font;
double *widths;
@@ -5416,7 +5757,8 @@ _cairo_pdf_surface_emit_type3_font_subset (cairo_pdf_surface_t *surface,
type3_surface = _cairo_type3_glyph_surface_create (font_subset->scaled_font,
NULL,
_cairo_pdf_emit_imagemask,
- surface->font_subsets);
+ surface->font_subsets,
+ FALSE);
if (unlikely (type3_surface->status)) {
free (glyphs);
free (widths);
@@ -5515,7 +5857,7 @@ _cairo_pdf_surface_emit_type3_font_subset (cairo_pdf_surface_t *surface,
status = _cairo_pdf_surface_emit_to_unicode_stream (surface,
font_subset,
&to_unicode_stream);
- if (_cairo_status_is_error (status)) {
+ if (_cairo_int_status_is_error (status)) {
free (widths);
return status;
}
@@ -5613,10 +5955,10 @@ _cairo_pdf_surface_emit_scaled_font_subset (cairo_scaled_font_subset_t *font_sub
return CAIRO_INT_STATUS_SUCCESS;
}
-static cairo_status_t
+static cairo_int_status_t
_cairo_pdf_surface_emit_font_subsets (cairo_pdf_surface_t *surface)
{
- cairo_status_t status;
+ cairo_int_status_t status;
status = _cairo_scaled_font_subsets_foreach_user (surface->font_subsets,
_cairo_pdf_surface_analyze_user_font_subset,
@@ -5698,7 +6040,7 @@ _cairo_pdf_surface_write_xref (cairo_pdf_surface_t *surface)
return offset;
}
-static cairo_status_t
+static cairo_int_status_t
_cairo_pdf_surface_write_mask_group (cairo_pdf_surface_t *surface,
cairo_pdf_smask_group_t *group)
{
@@ -5706,7 +6048,7 @@ _cairo_pdf_surface_write_mask_group (cairo_pdf_surface_t *surface,
cairo_pdf_resource_t smask;
cairo_pdf_smask_group_t *smask_group;
cairo_pdf_resource_t pattern_res, gstate_res;
- cairo_status_t status;
+ cairo_int_status_t status;
cairo_box_double_t bbox;
/* Create mask group */
@@ -5718,6 +6060,7 @@ _cairo_pdf_surface_write_mask_group (cairo_pdf_surface_t *surface,
if (_can_paint_pattern (group->mask)) {
_cairo_output_stream_printf (surface->output, "q\n");
status = _cairo_pdf_surface_paint_pattern (surface,
+ CAIRO_OPERATOR_OVER,
group->mask,
&group->extents,
FALSE);
@@ -5728,7 +6071,9 @@ _cairo_pdf_surface_write_mask_group (cairo_pdf_surface_t *surface,
} else {
pattern_res.id = 0;
gstate_res.id = 0;
- status = _cairo_pdf_surface_add_pdf_pattern (surface, group->mask, NULL,
+ status = _cairo_pdf_surface_add_pdf_pattern (surface, group->mask,
+ CAIRO_OPERATOR_OVER,
+ NULL,
&pattern_res, &gstate_res);
if (unlikely (status))
return status;
@@ -5791,6 +6136,7 @@ _cairo_pdf_surface_write_mask_group (cairo_pdf_surface_t *surface,
if (_can_paint_pattern (group->source)) {
_cairo_output_stream_printf (surface->output, "q\n");
status = _cairo_pdf_surface_paint_pattern (surface,
+ CAIRO_OPERATOR_OVER,
group->source,
&group->extents,
FALSE);
@@ -5801,7 +6147,9 @@ _cairo_pdf_surface_write_mask_group (cairo_pdf_surface_t *surface,
} else {
pattern_res.id = 0;
gstate_res.id = 0;
- status = _cairo_pdf_surface_add_pdf_pattern (surface, group->source, NULL,
+ status = _cairo_pdf_surface_add_pdf_pattern (surface, group->source,
+ CAIRO_OPERATOR_OVER,
+ NULL,
&pattern_res, &gstate_res);
if (unlikely (status))
return status;
@@ -5886,12 +6234,12 @@ _cairo_pdf_surface_write_mask_group (cairo_pdf_surface_t *surface,
return _cairo_output_stream_get_status (surface->output);
}
-static cairo_status_t
+static cairo_int_status_t
_cairo_pdf_surface_write_smask_group (cairo_pdf_surface_t *surface,
cairo_pdf_smask_group_t *group)
{
double old_width, old_height;
- cairo_status_t status;
+ cairo_int_status_t status;
cairo_box_double_t bbox;
old_width = surface->width;
@@ -5965,14 +6313,14 @@ RESTORE_SIZE:
return status;
}
-static cairo_status_t
+static cairo_int_status_t
_cairo_pdf_surface_write_patterns_and_smask_groups (cairo_pdf_surface_t *surface)
{
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;
- cairo_status_t status;
+ cairo_int_status_t status;
/* Writing out PDF_MASK groups will cause additional smask groups
* to be appended to surface->smask_groups. Additional patterns
@@ -6013,11 +6361,11 @@ _cairo_pdf_surface_write_patterns_and_smask_groups (cairo_pdf_surface_t *surface
return CAIRO_STATUS_SUCCESS;
}
-static cairo_status_t
+static cairo_int_status_t
_cairo_pdf_surface_write_page (cairo_pdf_surface_t *surface)
{
cairo_pdf_resource_t page, knockout, res;
- cairo_status_t status;
+ cairo_int_status_t status;
unsigned int i, len;
_cairo_pdf_group_resources_clear (&surface->resources);
@@ -6056,7 +6404,7 @@ _cairo_pdf_surface_write_page (cairo_pdf_surface_t *surface)
return status;
_cairo_pdf_group_resources_clear (&surface->resources);
- status = _cairo_pdf_surface_open_content_stream (surface, NULL, NULL, FALSE);
+ status = _cairo_pdf_surface_open_content_stream (surface, NULL, NULL, FALSE, FALSE);
if (unlikely (status))
return status;
@@ -6329,7 +6677,7 @@ static cairo_int_status_t
_cairo_pdf_surface_start_fallback (cairo_pdf_surface_t *surface)
{
cairo_box_double_t bbox;
- cairo_status_t status;
+ cairo_int_status_t status;
status = _cairo_pdf_surface_close_content_stream (surface);
if (unlikely (status))
@@ -6344,17 +6692,194 @@ _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);
+ return _cairo_pdf_surface_open_content_stream (surface, &bbox, NULL, TRUE, TRUE);
+}
+
+/* If source is an opaque image and mask is an image and both images
+ * have the same bounding box we can emit them as a image/smask pair.
+ */
+static cairo_int_status_t
+_cairo_pdf_surface_emit_combined_smask (cairo_pdf_surface_t *surface,
+ cairo_operator_t op,
+ const cairo_pattern_t *source,
+ const cairo_pattern_t *mask,
+ const cairo_rectangle_int_t *extents)
+{
+ cairo_int_status_t status;
+ 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;
+ double mask_x_offset, mask_y_offset;
+ double src_x1, src_y1, src_x2, src_y2;
+ 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;
+
+ /* Check that source and mask are images */
+
+ if (!((source->type == CAIRO_PATTERN_TYPE_SURFACE || source->type == CAIRO_PATTERN_TYPE_RASTER_SOURCE) &&
+ (mask->type == CAIRO_PATTERN_TYPE_SURFACE || mask->type == CAIRO_PATTERN_TYPE_RASTER_SOURCE)))
+ return CAIRO_INT_STATUS_UNSUPPORTED;
+
+ if (source->type == CAIRO_PATTERN_TYPE_SURFACE &&
+ ((cairo_surface_pattern_t *) source)->surface->type == CAIRO_SURFACE_TYPE_RECORDING)
+ {
+ return CAIRO_INT_STATUS_UNSUPPORTED;
+ }
+
+ if (mask->type == CAIRO_PATTERN_TYPE_SURFACE &&
+ ((cairo_surface_pattern_t *) mask)->surface->type == CAIRO_SURFACE_TYPE_RECORDING)
+ {
+ return CAIRO_INT_STATUS_UNSUPPORTED;
+ }
+
+ if (source->extend != CAIRO_EXTEND_NONE || mask->extend != CAIRO_EXTEND_NONE)
+ return CAIRO_INT_STATUS_UNSUPPORTED;
+
+ /* Check that source is opaque and get image sizes */
+
+ status = _cairo_pdf_surface_acquire_source_image_from_pattern (surface, source,
+ &image, &image_extra);
+ if (unlikely (status))
+ return status;
+
+ if (image->base.status)
+ return image->base.status;
+
+ src_width = image->width;
+ src_height = image->height;
+ if (source->type == CAIRO_PATTERN_TYPE_RASTER_SOURCE) {
+ cairo_surface_get_device_offset (&image->base, &src_x_offset, &src_y_offset);
+ } else {
+ src_x_offset = 0;
+ src_y_offset = 0;
+ }
+
+ transparency = _cairo_image_analyze_transparency (image);
+ _cairo_pdf_surface_release_source_image_from_pattern (surface, source, image, image_extra);
+
+ if (transparency != CAIRO_IMAGE_IS_OPAQUE)
+ return CAIRO_INT_STATUS_UNSUPPORTED;
+
+ status = _cairo_pdf_surface_acquire_source_image_from_pattern (surface, mask,
+ &image, &image_extra);
+ if (unlikely (status))
+ return status;
+
+ if (image->base.status)
+ return image->base.status;
+
+ mask_width = image->width;
+ mask_height = image->height;
+ if (mask->type == CAIRO_PATTERN_TYPE_RASTER_SOURCE) {
+ cairo_surface_get_device_offset (&image->base, &mask_x_offset, &mask_y_offset);
+ } else {
+ mask_x_offset = 0;
+ mask_y_offset = 0;
+ }
+
+ transparency = _cairo_image_analyze_transparency (image);
+ need_smask = transparency != CAIRO_IMAGE_IS_OPAQUE;
+
+ _cairo_pdf_surface_release_source_image_from_pattern (surface, mask, image, image_extra);
+
+ /* Check that both images have the same extents with a tolerance
+ * of half the smallest source pixel. */
+
+ p2u = source->matrix;
+ status = cairo_matrix_invert (&p2u);
+ /* cairo_pattern_set_matrix ensures the matrix is invertible */
+ assert (status == CAIRO_INT_STATUS_SUCCESS);
+ src_x1 = 0;
+ src_y1 = 0;
+ src_x2 = src_width;
+ src_y2 = src_height;
+ cairo_matrix_transform_point (&p2u, &src_x1, &src_y1);
+ cairo_matrix_transform_point (&p2u, &src_x2, &src_y2);
+ src_radius = _cairo_matrix_transformed_circle_major_axis (&p2u, 0.5);
+
+ p2u = mask->matrix;
+ status = cairo_matrix_invert (&p2u);
+ /* cairo_pattern_set_matrix ensures the matrix is invertible */
+ assert (status == CAIRO_INT_STATUS_SUCCESS);
+ mask_x1 = 0;
+ mask_y1 = 0;
+ mask_x2 = mask_width;
+ mask_y2 = mask_height;
+ cairo_matrix_transform_point (&p2u, &mask_x1, &mask_y1);
+ cairo_matrix_transform_point (&p2u, &mask_x2, &mask_y2);
+ mask_radius = _cairo_matrix_transformed_circle_major_axis (&p2u, 0.5);
+
+ if (src_radius < mask_radius)
+ e = src_radius;
+ else
+ e = mask_radius;
+
+ if (fabs(src_x1 - mask_x1) > e ||
+ fabs(src_x2 - mask_x2) > e ||
+ fabs(src_y1 - mask_y1) > e ||
+ fabs(src_y2 - mask_y2) > e)
+ return CAIRO_INT_STATUS_UNSUPPORTED;
+
+ /* Check both images have same device offset */
+ if (fabs(src_x_offset - mask_x_offset) > e ||
+ fabs(src_y_offset - mask_y_offset) > e)
+ return CAIRO_INT_STATUS_UNSUPPORTED;
+
+ if (need_smask) {
+ status = _cairo_pdf_surface_add_source_surface (surface,
+ NULL,
+ mask,
+ op,
+ source->filter,
+ FALSE,
+ TRUE,
+ extents,
+ NULL,
+ &smask_res,
+ &mask_width,
+ &mask_height,
+ &mask_x_offset,
+ &mask_y_offset,
+ &extents2);
+ if (unlikely (status))
+ return status;
+ }
+
+ status = _cairo_pdf_operators_flush (&surface->pdf_operators);
+ if (unlikely (status))
+ return status;
+
+ _cairo_output_stream_printf (surface->output, "q\n");
+ status = _cairo_pdf_surface_paint_surface_pattern (surface, op, source, extents,
+ need_smask ? &smask_res : NULL,
+ FALSE);
+ if (unlikely (status))
+ return status;
+
+ _cairo_output_stream_printf (surface->output, "Q\n");
+
+ status = _cairo_output_stream_get_status (surface->output);
+
+
+ return status;
}
/* A PDF stencil mask is an A1 mask used with the current color */
static cairo_int_status_t
_cairo_pdf_surface_emit_stencil_mask (cairo_pdf_surface_t *surface,
+ cairo_operator_t op,
const cairo_pattern_t *source,
const cairo_pattern_t *mask,
const cairo_rectangle_int_t *extents)
{
- cairo_status_t status;
+ cairo_int_status_t status;
cairo_image_surface_t *image;
void *image_extra;
cairo_image_transparency_t transparency;
@@ -6396,7 +6921,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, mask, NULL, TRUE);
+ status = _cairo_pdf_surface_paint_surface_pattern (surface, op, mask, extents, NULL, TRUE);
if (unlikely (status))
return status;
@@ -6472,6 +6997,7 @@ _cairo_pdf_surface_paint (void *abstract_surface,
if (_can_paint_pattern (source)) {
_cairo_output_stream_printf (surface->output, "q\n");
status = _cairo_pdf_surface_paint_pattern (surface,
+ op,
source,
&extents.bounded,
FALSE);
@@ -6485,7 +7011,7 @@ _cairo_pdf_surface_paint (void *abstract_surface,
pattern_res.id = 0;
gstate_res.id = 0;
- status = _cairo_pdf_surface_add_pdf_pattern (surface, source,
+ status = _cairo_pdf_surface_add_pdf_pattern (surface, source, op,
&extents.bounded,
&pattern_res, &gstate_res);
if (unlikely (status))
@@ -6567,7 +7093,7 @@ _cairo_pdf_surface_mask (void *abstract_surface,
return status;
if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) {
- cairo_status_t source_status, mask_status;
+ cairo_int_status_t source_status, mask_status;
status = _cairo_pdf_surface_analyze_operation (surface, op, source, &extents.bounded);
if (_cairo_int_status_is_error (status))
@@ -6625,8 +7151,13 @@ _cairo_pdf_surface_mask (void *abstract_surface,
if (unlikely (status))
goto cleanup;
+ /* Check if we can combine source and mask into a smask image */
+ status = _cairo_pdf_surface_emit_combined_smask (surface, op, source, mask, &extents.bounded);
+ if (status != CAIRO_INT_STATUS_UNSUPPORTED)
+ goto cleanup;
+
/* Check if we can use a stencil mask */
- status = _cairo_pdf_surface_emit_stencil_mask (surface, source, mask, &extents.bounded);
+ status = _cairo_pdf_surface_emit_stencil_mask (surface, op, source, mask, &extents.bounded);
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
goto cleanup;
@@ -6743,7 +7274,7 @@ _cairo_pdf_surface_stroke (void *abstract_surface,
pattern_res.id = 0;
gstate_res.id = 0;
- status = _cairo_pdf_surface_add_pdf_pattern (surface, source,
+ status = _cairo_pdf_surface_add_pdf_pattern (surface, source, op,
&extents.bounded,
&pattern_res, &gstate_res);
if (unlikely (status))
@@ -6896,6 +7427,7 @@ _cairo_pdf_surface_fill (void *abstract_surface,
goto cleanup;
status = _cairo_pdf_surface_paint_pattern (surface,
+ op,
source,
&extents.bounded,
FALSE);
@@ -6909,7 +7441,7 @@ _cairo_pdf_surface_fill (void *abstract_surface,
pattern_res.id = 0;
gstate_res.id = 0;
- status = _cairo_pdf_surface_add_pdf_pattern (surface, source,
+ status = _cairo_pdf_surface_add_pdf_pattern (surface, source, op,
&extents.bounded,
&pattern_res, &gstate_res);
if (unlikely (status))
@@ -7084,6 +7616,7 @@ _cairo_pdf_surface_fill_stroke (void *abstract_surface,
fill_pattern_res.id = 0;
gstate_res.id = 0;
status = _cairo_pdf_surface_add_pdf_pattern (surface, fill_source,
+ fill_op,
&extents.bounded,
&fill_pattern_res,
&gstate_res);
@@ -7096,6 +7629,7 @@ _cairo_pdf_surface_fill_stroke (void *abstract_surface,
gstate_res.id = 0;
status = _cairo_pdf_surface_add_pdf_pattern (surface,
stroke_source,
+ stroke_op,
&extents.bounded,
&stroke_pattern_res,
&gstate_res);
@@ -7187,7 +7721,7 @@ _cairo_pdf_surface_show_text_glyphs (void *abstract_surface,
pattern_res.id = 0;
gstate_res.id = 0;
- status = _cairo_pdf_surface_add_pdf_pattern (surface, source,
+ status = _cairo_pdf_surface_add_pdf_pattern (surface, source, op,
&extents.bounded,
&pattern_res, &gstate_res);
if (unlikely (status))
diff --git a/src/cairo-pdf.h b/src/cairo-pdf.h
index 1bc8524f2..1bc8524f2 100755..100644
--- a/src/cairo-pdf.h
+++ b/src/cairo-pdf.h
diff --git a/src/cairo-pen.c b/src/cairo-pen.c
index 61be0e829..61be0e829 100755..100644
--- a/src/cairo-pen.c
+++ b/src/cairo-pen.c
diff --git a/src/cairo-tg-private.h b/src/cairo-pixman-private.h
index 6e2464ea4..d705025c8 100755..100644
--- a/src/cairo-tg-private.h
+++ b/src/cairo-pixman-private.h
@@ -1,5 +1,7 @@
-/*
- * Copyright © 2012 SCore Corporation
+/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
+/* cairo - a vector graphics library with display and print output
+ *
+ * Copyright ©2013 Intel Corporation
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
@@ -24,34 +26,26 @@
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
* the specific language governing rights and limitations.
*
- * Author: Taekyun Kim (podain77@gmail.com)
+ * The Original Code is the cairo graphics library.
+ *
+ * The Initial Developer of the Original Code is University of Southern
+ * California.
+ *
+ * Contributor(s):
+ * Chris Wilson <chris@chris-wilson.co.uk>
*/
-#ifndef CAIRO_TG_PRIVATE_H
-#define CAIRO_TG_PRIVATE_H
+#ifndef CAIRO_PIXMAN_PRIVATE_H
+#define CAIRO_PIXMAN_PRIVATE_H
-#include "cairo-default-context-private.h"
-#include "cairo-surface-private.h"
-#include "cairo-tg-journal-private.h"
-#include <pixman.h>
+#include "cairo-pixman-private.h" /* keep make check happy */
-#define CAIRO_TG_NUM_MAX_TILES 8
-
-typedef struct _cairo_tg_surface
-{
- cairo_surface_t base;
-
- cairo_format_t format;
- pixman_format_code_t pixman_format;
- unsigned char *data;
- int width;
- int height;
- int stride;
- int bpp;
+#include <pixman.h>
- cairo_surface_t *image_surface;
- cairo_surface_t *tile_surfaces[CAIRO_TG_NUM_MAX_TILES];
- cairo_tg_journal_t journal;
-} cairo_tg_surface_t;
+#if PIXMAN_VERSION < PIXMAN_VERSION_ENCODE(0,22,0)
+#define pixman_image_composite32 pixman_image_composite
+#define pixman_image_get_component_alpha(i) 0
+#define pixman_image_set_component_alpha(i, x) do { } while (0)
+#endif
-#endif /* CAIRO_TG_PRIVATE_H */
+#endif
diff --git a/src/cairo-png.c b/src/cairo-png.c
index e74a4a8bc..068617d58 100755..100644
--- a/src/cairo-png.c
+++ b/src/cairo-png.c
@@ -149,13 +149,13 @@ static void
png_simple_warning_callback (png_structp png,
png_const_charp error_msg)
{
- cairo_status_t *error = png_get_error_ptr (png);
-
- /* default to the most likely error */
- if (*error == CAIRO_STATUS_SUCCESS)
- *error = _cairo_error (CAIRO_STATUS_NO_MEMORY);
-
- /* png does not expect to abort and will try to tidy up after a warning */
+ /* png does not expect to abort and will try to tidy up and continue
+ * loading the image after a warning. So we also want to return the
+ * (incorrect?) surface.
+ *
+ * We use our own warning callback to squelch any attempts by libpng
+ * to write to stderr as we may not be in control of that output.
+ */
}
diff --git a/src/cairo-polygon-intersect.c b/src/cairo-polygon-intersect.c
index 2cd73d2e5..2cd73d2e5 100755..100644
--- a/src/cairo-polygon-intersect.c
+++ b/src/cairo-polygon-intersect.c
diff --git a/src/cairo-polygon-reduce.c b/src/cairo-polygon-reduce.c
index ea457fe4e..ea457fe4e 100755..100644
--- a/src/cairo-polygon-reduce.c
+++ b/src/cairo-polygon-reduce.c
diff --git a/src/cairo-polygon.c b/src/cairo-polygon.c
index b0424f6e7..b0424f6e7 100755..100644
--- a/src/cairo-polygon.c
+++ b/src/cairo-polygon.c
diff --git a/src/cairo-private.h b/src/cairo-private.h
index 9f4f55b7c..9f4f55b7c 100755..100644
--- a/src/cairo-private.h
+++ b/src/cairo-private.h
diff --git a/src/cairo-ps-surface-private.h b/src/cairo-ps-surface-private.h
index 1d5d27d49..1d5d27d49 100755..100644
--- a/src/cairo-ps-surface-private.h
+++ b/src/cairo-ps-surface-private.h
diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c
index 01df6090b..4fc15f632 100755..100644
--- a/src/cairo-ps-surface.c
+++ b/src/cairo-ps-surface.c
@@ -340,14 +340,48 @@ _cairo_ps_surface_emit_header (cairo_ps_surface_t *surface)
"/rg { setrgbcolor } bind def\n"
"/d1 { setcachedevice } bind def\n");
+ if (!surface->eps) {
+ _cairo_output_stream_printf (surface->final_stream,
+ "/cairo_set_page_size {\n"
+ " %% Change paper size, but only if different from previous paper size otherwise\n"
+ " %% duplex fails. PLRM specifies a tolerance of 5 pts when matching paper size\n"
+ " %% so we use the same when checking if the size changes.\n"
+ " /setpagedevice where {\n"
+ " pop currentpagedevice\n"
+ " /PageSize known {\n"
+ " 2 copy\n"
+ " currentpagedevice /PageSize get aload pop\n"
+ " exch 4 1 roll\n"
+ " sub abs 5 gt\n"
+ " 3 1 roll\n"
+ " sub abs 5 gt\n"
+ " or\n"
+ " } {\n"
+ " true\n"
+ " } ifelse\n"
+ " {\n"
+ " 2 array astore\n"
+ " 2 dict begin\n"
+ " /PageSize exch def\n"
+ " /ImagingBBox null def\n"
+ " currentdict end\n"
+ " setpagedevice\n"
+ " } {\n"
+ " pop pop\n"
+ " } ifelse\n"
+ " } {\n"
+ " pop\n"
+ " } ifelse\n"
+ "} 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) {
- _cairo_output_stream_printf (surface->final_stream,
- "%%%%BeginSetup\n");
-
comments = _cairo_array_index (&surface->dsc_setup_comments, 0);
for (i = 0; i < num_comments; i++) {
_cairo_output_stream_printf (surface->final_stream,
@@ -355,9 +389,6 @@ _cairo_ps_surface_emit_header (cairo_ps_surface_t *surface)
free (comments[i]);
comments[i] = NULL;
}
-
- _cairo_output_stream_printf (surface->final_stream,
- "%%%%EndSetup\n");
}
}
@@ -385,8 +416,13 @@ _cairo_ps_surface_emit_type1_font_subset (cairo_ps_surface_t *surface,
"%% _cairo_ps_surface_emit_type1_font_subset\n");
#endif
+ _cairo_output_stream_printf (surface->final_stream,
+ "%%%%BeginResource: font %s\n",
+ subset.base_font);
length = subset.header_length + subset.data_length + subset.trailer_length;
_cairo_output_stream_write (surface->final_stream, subset.data, length);
+ _cairo_output_stream_printf (surface->final_stream,
+ "%%%%EndResource\n");
_cairo_type1_subset_fini (&subset);
@@ -409,15 +445,18 @@ _cairo_ps_surface_emit_type1_font_fallback (cairo_ps_surface_t *surface,
if (unlikely (status))
return status;
- /* FIXME: Figure out document structure convention for fonts */
-
#if DEBUG_PS
_cairo_output_stream_printf (surface->final_stream,
"%% _cairo_ps_surface_emit_type1_font_fallback\n");
#endif
+ _cairo_output_stream_printf (surface->final_stream,
+ "%%%%BeginResource: font %s\n",
+ subset.base_font);
length = subset.header_length + subset.data_length + subset.trailer_length;
_cairo_output_stream_write (surface->final_stream, subset.data, length);
+ _cairo_output_stream_printf (surface->final_stream,
+ "%%%%EndResource\n");
_cairo_type1_fallback_fini (&subset);
@@ -446,6 +485,9 @@ _cairo_ps_surface_emit_truetype_font_subset (cairo_ps_surface_t *surface,
#endif
_cairo_output_stream_printf (surface->final_stream,
+ "%%%%BeginResource: font %s\n",
+ subset.ps_name);
+ _cairo_output_stream_printf (surface->final_stream,
"11 dict begin\n"
"/FontType 42 def\n"
"/FontName /%s def\n"
@@ -527,13 +569,15 @@ _cairo_ps_surface_emit_truetype_font_subset (cairo_ps_surface_t *surface,
"/f-%d-%d currentdict end definefont pop\n",
font_subset->font_id,
font_subset->subset_id);
-
+ _cairo_output_stream_printf (surface->final_stream,
+ "%%%%EndResource\n");
_cairo_truetype_subset_fini (&subset);
+
return CAIRO_STATUS_SUCCESS;
}
-static cairo_status_t
+static cairo_int_status_t
_cairo_ps_emit_imagemask (cairo_image_surface_t *image,
cairo_output_stream_t *stream)
{
@@ -587,7 +631,8 @@ _cairo_ps_surface_analyze_user_font_subset (cairo_scaled_font_subset_t *font_sub
type3_surface = _cairo_type3_glyph_surface_create (font_subset->scaled_font,
NULL,
_cairo_ps_emit_imagemask,
- surface->font_subsets);
+ surface->font_subsets,
+ TRUE);
for (i = 0; i < font_subset->num_glyphs; i++) {
status = _cairo_type3_glyph_surface_analyze_glyph (type3_surface,
@@ -624,6 +669,8 @@ _cairo_ps_surface_emit_type3_font_subset (cairo_ps_surface_t *surface,
#endif
_cairo_output_stream_printf (surface->final_stream,
+ "%%%%BeginResource: font\n");
+ _cairo_output_stream_printf (surface->final_stream,
"8 dict begin\n"
"/FontType 3 def\n"
"/FontMatrix [1 0 0 1 0 0] def\n"
@@ -633,7 +680,8 @@ _cairo_ps_surface_emit_type3_font_subset (cairo_ps_surface_t *surface,
type3_surface = _cairo_type3_glyph_surface_create (font_subset->scaled_font,
NULL,
_cairo_ps_emit_imagemask,
- surface->font_subsets);
+ surface->font_subsets,
+ TRUE);
status = type3_surface->status;
if (unlikely (status)) {
cairo_surface_destroy (type3_surface);
@@ -705,6 +753,8 @@ _cairo_ps_surface_emit_type3_font_subset (cairo_ps_surface_t *surface,
- _cairo_fixed_to_double (font_bbox.p1.y),
font_subset->font_id,
font_subset->subset_id);
+ _cairo_output_stream_printf (surface->final_stream,
+ "%%%%EndResource\n");
return CAIRO_STATUS_SUCCESS;
}
@@ -1025,7 +1075,8 @@ _cairo_ps_surface_create_for_stream_internal (cairo_output_stream_t *stream,
_cairo_pdf_operators_init (&surface->pdf_operators,
surface->stream,
&surface->cairo_to_ps,
- surface->font_subsets);
+ surface->font_subsets,
+ TRUE);
surface->num_pages = 0;
cairo_list_init (&surface->document_media);
@@ -1568,6 +1619,9 @@ _cairo_ps_surface_finish (void *abstract_surface)
if (unlikely (status))
goto CLEANUP;
+ _cairo_output_stream_printf (surface->final_stream,
+ "%%%%EndSetup\n");
+
status = _cairo_ps_surface_emit_body (surface);
if (unlikely (status))
goto CLEANUP;
@@ -2738,11 +2792,9 @@ _cairo_ps_surface_emit_image (cairo_ps_surface_t *surface,
}
_cairo_output_stream_printf (surface->stream,
- " /Interpolate %s def\n"
" /ImageMatrix [ 1 0 0 -1 0 %d ] def\n"
"end\n"
"%s\n",
- interpolate,
ps_image->height,
stencil_mask ? "imagemask" : "image");
}
@@ -3113,6 +3165,16 @@ _cairo_ps_surface_emit_surface (cairo_ps_surface_t *surface,
{
cairo_int_status_t 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;
+
+ status = _cairo_ps_surface_emit_jpeg_image (surface, surf, width, height);
+ if (status != CAIRO_INT_STATUS_UNSUPPORTED)
+ return status;
+ }
+
if (source_surface->type == CAIRO_SURFACE_TYPE_RECORDING) {
if (source_surface->backend->type == CAIRO_SURFACE_TYPE_SUBSURFACE) {
cairo_surface_subsurface_t *sub = (cairo_surface_subsurface_t *) source_surface;
@@ -3122,12 +3184,6 @@ _cairo_ps_surface_emit_surface (cairo_ps_surface_t *surface,
}
} else {
cairo_image_surface_t *image = (cairo_image_surface_t *) source_surface;
- if (source_pattern->extend != CAIRO_EXTEND_PAD) {
- status = _cairo_ps_surface_emit_jpeg_image (surface, source_surface,
- width, height);
- if (status != CAIRO_INT_STATUS_UNSUPPORTED)
- return status;
- }
status = _cairo_ps_surface_emit_image (surface, image,
op, source_pattern->filter, stencil_mask);
@@ -3267,11 +3323,9 @@ _cairo_ps_surface_paint_surface (cairo_ps_surface_t *surface,
cairo_matrix_scale (&ps_p2d, 1.0, -1.0);
if (! _cairo_matrix_is_identity (&ps_p2d)) {
- _cairo_output_stream_printf (surface->stream,
- "[ %f %f %f %f %f %f ] concat\n",
- ps_p2d.xx, ps_p2d.yx,
- ps_p2d.xy, ps_p2d.yy,
- ps_p2d.x0, ps_p2d.y0);
+ _cairo_output_stream_printf (surface->stream, "[ ");
+ _cairo_output_stream_print_matrix (surface->stream, &ps_p2d);
+ _cairo_output_stream_printf (surface->stream, " ] concat\n");
}
status = _cairo_ps_surface_emit_surface (surface,
@@ -3419,7 +3473,7 @@ _cairo_ps_surface_emit_surface_pattern (cairo_ps_surface_t *surface,
_cairo_output_stream_printf (surface->stream,
" /BBox [0 0 %d %d]\n"
" /PaintProc {\n"
- " CairoPattern\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"
@@ -3440,7 +3494,7 @@ _cairo_ps_surface_emit_surface_pattern (cairo_ps_surface_t *surface,
pattern_width, pattern_height);
}
_cairo_output_stream_printf (surface->stream,
- " /PaintProc { CairoPattern }\n");
+ " /PaintProc { pop CairoPattern }\n");
}
_cairo_output_stream_printf (surface->stream,
@@ -3458,12 +3512,10 @@ _cairo_ps_surface_emit_surface_pattern (cairo_ps_surface_t *surface,
cairo_matrix_translate (&ps_p2d, 0.0, pattern_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);
_cairo_output_stream_printf (surface->stream,
- "[ %f %f %f %f %f %f ]\n",
- ps_p2d.xx, ps_p2d.yx,
- ps_p2d.xy, ps_p2d.yy,
- ps_p2d.x0, ps_p2d.y0);
- _cairo_output_stream_printf (surface->stream,
+ " ]\n"
"makepattern setpattern\n");
release_source:
@@ -3837,11 +3889,10 @@ _cairo_ps_surface_emit_gradient (cairo_ps_surface_t *surface,
if (is_ps_pattern) {
_cairo_output_stream_printf (surface->stream,
">>\n"
- "[ %f %f %f %f %f %f ]\n"
- "makepattern setpattern\n",
- pat_to_ps.xx, pat_to_ps.yx,
- pat_to_ps.xy, pat_to_ps.yy,
- pat_to_ps.x0, pat_to_ps.y0);
+ "[ ");
+ _cairo_output_stream_print_matrix (surface->stream, &pat_to_ps);
+ _cairo_output_stream_printf (surface->stream, " ]\n"
+ "makepattern setpattern\n");
} else {
_cairo_output_stream_printf (surface->stream,
"shfill\n");
@@ -3919,11 +3970,10 @@ _cairo_ps_surface_emit_mesh_pattern (cairo_ps_surface_t *surface,
if (is_ps_pattern) {
_cairo_output_stream_printf (surface->stream,
">>\n"
- "[ %f %f %f %f %f %f ]\n",
- pat_to_ps.xx, pat_to_ps.yx,
- pat_to_ps.xy, pat_to_ps.yy,
- pat_to_ps.x0, pat_to_ps.y0);
+ "[ \n");
+ _cairo_output_stream_print_matrix (surface->stream, &pat_to_ps);
_cairo_output_stream_printf (surface->stream,
+ " ]\n"
"makepattern\n"
"setpattern\n");
} else {
@@ -4022,11 +4072,9 @@ _cairo_ps_surface_paint_gradient (cairo_ps_surface_t *surface,
cairo_matrix_multiply (&pat_to_ps, &pat_to_ps, &surface->cairo_to_ps);
if (! _cairo_matrix_is_identity (&pat_to_ps)) {
- _cairo_output_stream_printf (surface->stream,
- "[%f %f %f %f %f %f] concat\n",
- pat_to_ps.xx, pat_to_ps.yx,
- pat_to_ps.xy, pat_to_ps.yy,
- pat_to_ps.x0, pat_to_ps.y0);
+ _cairo_output_stream_printf (surface->stream, "[");
+ _cairo_output_stream_print_matrix (surface->stream, &pat_to_ps);
+ _cairo_output_stream_printf (surface->stream, "] concat\n");
}
if (source->type == CAIRO_PATTERN_TYPE_MESH) {
@@ -4578,6 +4626,13 @@ _cairo_ps_surface_set_bounding_box (void *abstract_surface,
x1, y1, x2, y2);
}
+ if (!surface->eps) {
+ _cairo_output_stream_printf (surface->stream,
+ "%f %f cairo_set_page_size\n",
+ ceil(surface->width),
+ ceil(surface->height));
+ }
+
_cairo_output_stream_printf (surface->stream,
"%%%%EndPageSetup\n"
"q %d %d %d %d rectclip q\n",
diff --git a/src/cairo-ps.h b/src/cairo-ps.h
index 33d0e0d94..33d0e0d94 100755..100644
--- a/src/cairo-ps.h
+++ b/src/cairo-ps.h
diff --git a/src/cairo-qt-surface.cpp b/src/cairo-qt-surface.cpp
index ce05dba7e..7ddad77df 100755..100644
--- a/src/cairo-qt-surface.cpp
+++ b/src/cairo-qt-surface.cpp
@@ -306,6 +306,8 @@ _qimage_format_from_cairo_format (cairo_format_t fmt)
#else
return QImage::Format_MonoLSB;
#endif
+ case CAIRO_FORMAT_RGB30:
+ return QImage::Format_Mono;
}
return QImage::Format_Mono;
@@ -386,7 +388,7 @@ _cairo_path_to_qpainterpath_close_path (void *closure)
return CAIRO_STATUS_SUCCESS;
}
-static inline QPainterPath
+static QPainterPath
path_to_qt (const cairo_path_fixed_t *path,
const cairo_matrix_t *ctm_inverse = NULL)
{
@@ -849,7 +851,8 @@ _cairo_qt_surface_set_clip (cairo_qt_surface_t *qs,
*/
struct PatternToBrushConverter {
- PatternToBrushConverter (const cairo_pattern_t *pattern) :
+ PatternToBrushConverter (const cairo_pattern_t *pattern)
+ __attribute__ ((noinline)) :
mAcquiredImageParent(0),
mAcquiredImage(0),
mAcquiredImageExtra(0)
@@ -1048,7 +1051,7 @@ struct PatternToBrushConverter {
}
}
- ~PatternToBrushConverter () {
+ ~PatternToBrushConverter () __attribute__ ((noinline)){
if (mAcquiredImageParent)
_cairo_surface_release_source_image (mAcquiredImageParent, mAcquiredImage, mAcquiredImageExtra);
}
@@ -1657,13 +1660,30 @@ cairo_qt_surface_create_with_qpixmap (cairo_content_t content,
return &qs->base;
}
+/**
+ * _cairo_surface_is_qt:
+ * @surface: a #cairo_surface_t
+ *
+ * Checks if a surface is a #cairo_qt_surface_t
+ *
+ * Return value: True if the surface is an qt surface
+ **/
+static inline cairo_bool_t
+_cairo_surface_is_qt (cairo_surface_t *surface)
+{
+ return surface->backend == &cairo_qt_surface_backend;
+}
+
QPainter *
cairo_qt_surface_get_qpainter (cairo_surface_t *surface)
{
cairo_qt_surface_t *qs = (cairo_qt_surface_t*) surface;
- if (surface->type != CAIRO_SURFACE_TYPE_QT)
+ /* Throw an error for a non-qt surface */
+ if (! _cairo_surface_is_qt (surface)) {
+ _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
return NULL;
+ }
return qs->p;
}
@@ -1673,8 +1693,11 @@ cairo_qt_surface_get_qimage (cairo_surface_t *surface)
{
cairo_qt_surface_t *qs = (cairo_qt_surface_t*) surface;
- if (surface->type != CAIRO_SURFACE_TYPE_QT)
+ /* Throw an error for a non-qt surface */
+ if (! _cairo_surface_is_qt (surface)) {
+ _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
return NULL;
+ }
return qs->image;
}
@@ -1684,8 +1707,10 @@ cairo_qt_surface_get_image (cairo_surface_t *surface)
{
cairo_qt_surface_t *qs = (cairo_qt_surface_t*) surface;
- if (surface->type != CAIRO_SURFACE_TYPE_QT)
- return NULL;
+ /* Throw an error for a non-qt surface */
+ if (! _cairo_surface_is_qt (surface)) {
+ return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH));
+ }
return qs->image_equiv;
}
diff --git a/src/cairo-qt.h b/src/cairo-qt.h
index c20bbb18d..c20bbb18d 100755..100644
--- a/src/cairo-qt.h
+++ b/src/cairo-qt.h
diff --git a/src/cairo-quartz-filters.c b/src/cairo-quartz-filters.c
index 804cddfde..aafceaf68 100755..100644
--- a/src/cairo-quartz-filters.c
+++ b/src/cairo-quartz-filters.c
@@ -363,7 +363,7 @@ _cairo_quartz_gaussian_filter (const cairo_pattern_t *src,
if (! image_ctx) {
free (kernel);
*out_image = NULL;
- return CAIRO_INT_STATUS_NO_MEMORY;
+ return CAIRO_INT_STATUS_NO_MEMORY;
}
#else
image_provider = CGImageGetDataProvider (resized_image);
diff --git a/src/cairo-quartz-font.c b/src/cairo-quartz-font.c
index a9bbbdc7a..02f34267b 100755..100644
--- a/src/cairo-quartz-font.c
+++ b/src/cairo-quartz-font.c
@@ -81,9 +81,6 @@ 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;
-
/* CGFontGetHMetrics isn't public, but the other functions are public/present in 10.5 */
typedef struct {
int ascent;
@@ -127,7 +124,6 @@ quartz_font_ensure_symbols(void)
/* These have the same name in 10.4 and 10.5 */
CGFontGetUnitsPerEmPtr = dlsym(RTLD_DEFAULT, "CGFontGetUnitsPerEm");
CGFontGetGlyphAdvancesPtr = dlsym(RTLD_DEFAULT, "CGFontGetGlyphAdvances");
- CGFontGetGlyphPathPtr = dlsym(RTLD_DEFAULT, "CGFontGetGlyphPath");
CGFontGetHMetricsPtr = dlsym(RTLD_DEFAULT, "CGFontGetHMetrics");
CGFontGetAscentPtr = dlsym(RTLD_DEFAULT, "CGFontGetAscent");
@@ -144,7 +140,6 @@ quartz_font_ensure_symbols(void)
CGFontGetGlyphsForUnicharsPtr &&
CGFontGetUnitsPerEmPtr &&
CGFontGetGlyphAdvancesPtr &&
- CGFontGetGlyphPathPtr &&
(CGFontGetHMetricsPtr || (CGFontGetAscentPtr && CGFontGetDescentPtr && CGFontGetLeadingPtr)))
_cairo_quartz_font_symbols_present = TRUE;
@@ -241,12 +236,13 @@ _cairo_quartz_font_face_create_for_toy (cairo_toy_font_face_t *toy_face,
return CAIRO_STATUS_SUCCESS;
}
-static void
+static cairo_bool_t
_cairo_quartz_font_face_destroy (void *abstract_face)
{
cairo_quartz_font_face_t *font_face = (cairo_quartz_font_face_t*) abstract_face;
CGFontRelease (font_face->cgFont);
+ return TRUE;
}
static const cairo_scaled_font_backend_t _cairo_quartz_scaled_font_backend;
@@ -549,6 +545,7 @@ _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) {
@@ -563,7 +560,9 @@ _cairo_quartz_init_glyph_path (cairo_quartz_scaled_font_t *font,
-font->base.scale.yy,
0, 0);
- glyphPath = CGFontGetGlyphPathPtr (font_face->cgFont, &textMatrix, 0, glyph);
+ ctFont = CTFontCreateWithGraphicsFont (font_face->cgFont, 0.0, NULL, NULL);
+ glyphPath = CTFontCreatePathForGlyph (ctFont, glyph, &textMatrix);
+ CFRelease (ctFont);
if (!glyphPath)
return CAIRO_INT_STATUS_UNSUPPORTED;
diff --git a/src/cairo-quartz-image-surface.c b/src/cairo-quartz-image-surface.c
index 2715abd06..498a7b064 100755..100644
--- a/src/cairo-quartz-image-surface.c
+++ b/src/cairo-quartz-image-surface.c
@@ -378,8 +378,10 @@ cairo_quartz_image_surface_get_image (cairo_surface_t *asurface)
{
cairo_quartz_image_surface_t *surface = (cairo_quartz_image_surface_t*) asurface;
- if (asurface->type != CAIRO_SURFACE_TYPE_QUARTZ_IMAGE)
- return NULL;
+ /* Throw an error for a non-quartz surface */
+ if (! _cairo_surface_is_quartz (asurface)) {
+ return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH));
+ }
return (cairo_surface_t*) surface->imageSurface;
}
diff --git a/src/cairo-quartz-image.h b/src/cairo-quartz-image.h
index dae234dac..dae234dac 100755..100644
--- a/src/cairo-quartz-image.h
+++ b/src/cairo-quartz-image.h
diff --git a/src/cairo-quartz-private.h b/src/cairo-quartz-private.h
index 58b97ac99..5e97392db 100755..100644
--- a/src/cairo-quartz-private.h
+++ b/src/cairo-quartz-private.h
@@ -83,6 +83,9 @@ typedef struct cairo_quartz_image_surface {
cairo_private cairo_bool_t
_cairo_quartz_verify_surface_size(int width, int height);
+cairo_private cairo_bool_t
+_cairo_surface_is_quartz (const cairo_surface_t *surface);
+
cairo_private CGImageRef
CairoQuartzCreateCGImage (cairo_format_t format,
unsigned int width,
diff --git a/src/cairo-quartz-surface.c b/src/cairo-quartz-surface.c
index 6d0a0c079..a27128150 100755..100644
--- a/src/cairo-quartz-surface.c
+++ b/src/cairo-quartz-surface.c
@@ -257,9 +257,6 @@ _cairo_quartz_surface_create_internal (CGContextRef cgContext,
unsigned int width,
unsigned int height);
-static cairo_bool_t
-_cairo_surface_is_quartz (const cairo_surface_t *surface);
-
/* Load all extra symbols */
static void quartz_ensure_symbols (void)
{
@@ -1521,7 +1518,6 @@ _cairo_quartz_teardown_state (cairo_quartz_drawing_state_t *state,
CGContextDrawLayerInRect (surface->cgContext,
state->clipRect,
state->layer);
- CGContextRelease (state->cgDrawContext);
CGLayerRelease (state->layer);
}
@@ -1805,7 +1801,7 @@ _cairo_quartz_cg_mask_with_surface (cairo_composite_rectangles_t *extents,
cairo_matrix_t m = *mask_mat;
_cairo_surface_get_extents (extents->surface, &dest_extents);
- status = _cairo_surface_to_cgimage (&extents->mask_pattern.base,
+ status = _cairo_surface_to_cgimage (&extents->mask_pattern.base,
mask_surf, &dest_extents, format,
&m, extents->clip, &img);
if (unlikely (status))
@@ -2791,7 +2787,15 @@ cairo_quartz_surface_get_cg_context (cairo_surface_t *surface)
return NULL;
}
-static cairo_bool_t
+/**
+ * _cairo_surface_is_quartz:
+ * @surface: a #cairo_surface_t
+ *
+ * Checks if a surface is a #cairo_quartz_surface_t
+ *
+ * Return value: True if the surface is an quartz surface
+ **/
+cairo_bool_t
_cairo_surface_is_quartz (const cairo_surface_t *surface)
{
return surface->backend == &cairo_quartz_surface_backend;
diff --git a/src/cairo-quartz.h b/src/cairo-quartz.h
index 9be5f9ae5..9be5f9ae5 100755..100644
--- a/src/cairo-quartz.h
+++ b/src/cairo-quartz.h
diff --git a/src/cairo-raster-source-pattern.c b/src/cairo-raster-source-pattern.c
index 2fd8bdb63..bcaa29dc9 100755..100644
--- a/src/cairo-raster-source-pattern.c
+++ b/src/cairo-raster-source-pattern.c
@@ -57,8 +57,6 @@
* Other callbacks are provided for when the pattern is copied temporarily
* during rasterisation, or more permanently as a snapshot in order to keep
* the pixel data available for printing.
- *
- * Since: 1.12
**/
cairo_surface_t *
diff --git a/src/cairo-recording-surface-inline.h b/src/cairo-recording-surface-inline.h
index 9002ccd69..9002ccd69 100755..100644
--- a/src/cairo-recording-surface-inline.h
+++ b/src/cairo-recording-surface-inline.h
diff --git a/src/cairo-recording-surface-private.h b/src/cairo-recording-surface-private.h
index 0235b0f3f..456c63389 100755..100644
--- a/src/cairo-recording-surface-private.h
+++ b/src/cairo-recording-surface-private.h
@@ -133,9 +133,11 @@ typedef struct _cairo_recording_surface {
cairo_bool_t unbounded;
cairo_array_t commands;
- int *indices;
- int num_indices;
+ unsigned int *indices;
+ unsigned int num_indices;
cairo_bool_t optimize_clears;
+ cairo_bool_t has_bilevel_alpha;
+ cairo_bool_t has_only_op_over;
struct bbtree {
cairo_box_t extents;
@@ -184,4 +186,10 @@ _cairo_recording_surface_get_ink_bbox (cairo_recording_surface_t *surface,
cairo_box_t *bbox,
const cairo_matrix_t *transform);
+cairo_private cairo_bool_t
+_cairo_recording_surface_has_only_bilevel_alpha (cairo_recording_surface_t *surface);
+
+cairo_private cairo_bool_t
+_cairo_recording_surface_has_only_op_over (cairo_recording_surface_t *surface);
+
#endif /* CAIRO_RECORDING_SURFACE_H */
diff --git a/src/cairo-recording-surface.c b/src/cairo-recording-surface.c
index 9e672df2c..ee9304746 100755..100644
--- a/src/cairo-recording-surface.c
+++ b/src/cairo-recording-surface.c
@@ -87,6 +87,7 @@
#include "cairo-error-private.h"
#include "cairo-image-surface-private.h"
#include "cairo-recording-surface-inline.h"
+#include "cairo-surface-snapshot-inline.h"
#include "cairo-surface-wrapper-private.h"
#include "cairo-traps-private.h"
@@ -257,7 +258,7 @@ static cairo_bool_t box_outside (const cairo_box_t *a, const cairo_box_t *b)
static void
bbtree_foreach_mark_visible (struct bbtree *bbt,
const cairo_box_t *box,
- int **indices)
+ unsigned int **indices)
{
cairo_command_header_t *chain;
@@ -270,13 +271,13 @@ bbtree_foreach_mark_visible (struct bbtree *bbt,
bbtree_foreach_mark_visible (bbt->right, box, indices);
}
-static inline int intcmp (const int a, const int b)
+static inline int intcmp (const unsigned int a, const unsigned int b)
{
return a - b;
}
-CAIRO_COMBSORT_DECLARE (sort_indices, int, intcmp)
+CAIRO_COMBSORT_DECLARE (sort_indices, unsigned int, intcmp)
-static inline int sizecmp (int a, int b, cairo_command_header_t **elements)
+static inline int sizecmp (unsigned int a, unsigned int b, cairo_command_header_t **elements)
{
const cairo_rectangle_int_t *r;
@@ -288,7 +289,7 @@ static inline int sizecmp (int a, int b, cairo_command_header_t **elements)
return b - a;
}
-CAIRO_COMBSORT_DECLARE_WITH_DATA (sort_commands, int, sizecmp)
+CAIRO_COMBSORT_DECLARE_WITH_DATA (sort_commands, unsigned int, sizecmp)
static void
_cairo_recording_surface_destroy_bbtree (cairo_recording_surface_t *surface)
@@ -323,9 +324,9 @@ _cairo_recording_surface_create_bbtree (cairo_recording_surface_t *surface)
if (unlikely (elements == NULL))
return _cairo_error (CAIRO_STATUS_NULL_POINTER);
+ unsigned int *indices;
cairo_status_t status;
- int i, count;
- int *indices;
+ unsigned int i, count;
count = surface->commands.num_elements;
if (count > surface->num_indices) {
@@ -423,6 +424,8 @@ cairo_recording_surface_create (cairo_content_t content,
surface->indices = NULL;
surface->num_indices = 0;
surface->optimize_clears = TRUE;
+ surface->has_bilevel_alpha = FALSE;
+ surface->has_only_op_over = FALSE;
return &surface->base;
}
@@ -1589,9 +1592,12 @@ static int
_cairo_recording_surface_get_visible_commands (cairo_recording_surface_t *surface,
const cairo_rectangle_int_t *extents)
{
- int num_visible, *indices;
+ unsigned int num_visible, *indices;
cairo_box_t box;
+ if (surface->commands.num_elements == 0)
+ return 0;
+
_cairo_box_from_rectangle (&box, extents);
if (surface->bbtree.chain == INVALID_CHAIN)
@@ -1606,6 +1612,68 @@ _cairo_recording_surface_get_visible_commands (cairo_recording_surface_t *surfac
return num_visible;
}
+static void
+_cairo_recording_surface_merge_source_attributes (cairo_recording_surface_t *surface,
+ cairo_operator_t op,
+ const cairo_pattern_t *source)
+{
+ if (op != CAIRO_OPERATOR_OVER)
+ surface->has_only_op_over = FALSE;
+
+ if (source->type == CAIRO_PATTERN_TYPE_SURFACE) {
+ cairo_surface_pattern_t *surf_pat = (cairo_surface_pattern_t *) source;
+ cairo_surface_t *surf = surf_pat->surface;
+ cairo_surface_t *free_me = NULL;
+
+ if (_cairo_surface_is_snapshot (surf))
+ free_me = surf = _cairo_surface_snapshot_get_target (surf);
+
+ if (surf->type == CAIRO_SURFACE_TYPE_RECORDING) {
+ cairo_recording_surface_t *rec_surf = (cairo_recording_surface_t *) surf;
+
+ if (! _cairo_recording_surface_has_only_bilevel_alpha (rec_surf))
+ surface->has_bilevel_alpha = FALSE;
+
+ if (! _cairo_recording_surface_has_only_op_over (rec_surf))
+ surface->has_only_op_over = FALSE;
+
+ } else if (surf->type == CAIRO_SURFACE_TYPE_IMAGE) {
+ cairo_image_surface_t *img_surf = (cairo_image_surface_t *) surf;
+
+ if (_cairo_image_analyze_transparency (img_surf) == CAIRO_IMAGE_HAS_ALPHA)
+ surface->has_bilevel_alpha = FALSE;
+
+ } else {
+ if (!_cairo_pattern_is_clear (source) && !_cairo_pattern_is_opaque (source, NULL))
+ surface->has_bilevel_alpha = FALSE;
+ }
+
+ cairo_surface_destroy (free_me);
+ return;
+
+ } else if (source->type == CAIRO_PATTERN_TYPE_RASTER_SOURCE) {
+ cairo_surface_t *image;
+ cairo_surface_t *raster;
+
+ image = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 1, 1);
+ raster = _cairo_raster_source_pattern_acquire (source, image, NULL);
+ cairo_surface_destroy (image);
+ if (raster) {
+ if (raster->type == CAIRO_SURFACE_TYPE_IMAGE) {
+ if (_cairo_image_analyze_transparency ((cairo_image_surface_t *)raster) == CAIRO_IMAGE_HAS_ALPHA)
+ surface->has_bilevel_alpha = FALSE;
+ }
+
+ _cairo_raster_source_pattern_release (source, raster);
+ if (raster->type == CAIRO_SURFACE_TYPE_IMAGE)
+ return;
+ }
+ }
+
+ if (!_cairo_pattern_is_clear (source) && !_cairo_pattern_is_opaque (source, NULL))
+ surface->has_bilevel_alpha = FALSE;
+}
+
static cairo_status_t
_cairo_recording_surface_replay_internal (cairo_recording_surface_t *surface,
const cairo_rectangle_int_t *surface_extents,
@@ -1624,7 +1692,7 @@ _cairo_recording_surface_replay_internal (cairo_recording_surface_t *surface,
cairo_rectangle_int_t extents;
cairo_bool_t use_indices = FALSE;
const cairo_rectangle_int_t *r;
- int i, num_elements;
+ unsigned int i, num_elements;
if (unlikely (surface->base.status))
return surface->base.status;
@@ -1655,6 +1723,9 @@ _cairo_recording_surface_replay_internal (cairo_recording_surface_t *surface,
if (! _cairo_surface_wrapper_get_target_extents (&wrapper, &extents))
goto done;
+ surface->has_bilevel_alpha = TRUE;
+ surface->has_only_op_over = TRUE;
+
num_elements = surface->commands.num_elements;
elements = _cairo_array_index (&surface->commands, 0);
if (elements == NULL) {
@@ -1665,7 +1736,7 @@ _cairo_recording_surface_replay_internal (cairo_recording_surface_t *surface,
if (extents.width < r->width || extents.height < r->height) {
num_elements =
_cairo_recording_surface_get_visible_commands (surface, &extents);
- use_indices = TRUE;
+ use_indices = num_elements != surface->commands.num_elements;
}
for (i = 0; i < num_elements; i++) {
@@ -1683,6 +1754,11 @@ _cairo_recording_surface_replay_internal (cairo_recording_surface_t *surface,
command->header.op,
&command->paint.source.base,
command->header.clip);
+ if (type == CAIRO_RECORDING_CREATE_REGIONS) {
+ _cairo_recording_surface_merge_source_attributes (surface,
+ command->header.op,
+ &command->paint.source.base);
+ }
break;
case CAIRO_COMMAND_MASK:
@@ -1691,6 +1767,14 @@ _cairo_recording_surface_replay_internal (cairo_recording_surface_t *surface,
&command->mask.source.base,
&command->mask.mask.base,
command->header.clip);
+ if (type == CAIRO_RECORDING_CREATE_REGIONS) {
+ _cairo_recording_surface_merge_source_attributes (surface,
+ command->header.op,
+ &command->mask.source.base);
+ _cairo_recording_surface_merge_source_attributes (surface,
+ command->header.op,
+ &command->mask.mask.base);
+ }
break;
case CAIRO_COMMAND_STROKE:
@@ -1704,6 +1788,11 @@ _cairo_recording_surface_replay_internal (cairo_recording_surface_t *surface,
command->stroke.tolerance,
command->stroke.antialias,
command->header.clip);
+ if (type == CAIRO_RECORDING_CREATE_REGIONS) {
+ _cairo_recording_surface_merge_source_attributes (surface,
+ command->header.op,
+ &command->stroke.source.base);
+ }
break;
case CAIRO_COMMAND_FILL:
@@ -1745,6 +1834,14 @@ _cairo_recording_surface_replay_internal (cairo_recording_surface_t *surface,
stroke_command->stroke.tolerance,
stroke_command->stroke.antialias,
command->header.clip);
+ if (type == CAIRO_RECORDING_CREATE_REGIONS) {
+ _cairo_recording_surface_merge_source_attributes (surface,
+ command->header.op,
+ &command->fill.source.base);
+ _cairo_recording_surface_merge_source_attributes (surface,
+ command->header.op,
+ &command->stroke.source.base);
+ }
i++;
}
}
@@ -1757,6 +1854,11 @@ _cairo_recording_surface_replay_internal (cairo_recording_surface_t *surface,
command->fill.tolerance,
command->fill.antialias,
command->header.clip);
+ if (type == CAIRO_RECORDING_CREATE_REGIONS) {
+ _cairo_recording_surface_merge_source_attributes (surface,
+ command->header.op,
+ &command->fill.source.base);
+ }
}
break;
@@ -1770,6 +1872,11 @@ _cairo_recording_surface_replay_internal (cairo_recording_surface_t *surface,
command->show_text_glyphs.cluster_flags,
command->show_text_glyphs.scaled_font,
command->header.clip);
+ if (type == CAIRO_RECORDING_CREATE_REGIONS) {
+ _cairo_recording_surface_merge_source_attributes (surface,
+ command->header.op,
+ &command->show_text_glyphs.source.base);
+ }
break;
default:
@@ -2083,3 +2190,15 @@ cairo_recording_surface_get_extents (cairo_surface_t *surface,
*extents = record->extents_pixels;
return TRUE;
}
+
+cairo_bool_t
+_cairo_recording_surface_has_only_bilevel_alpha (cairo_recording_surface_t *surface)
+{
+ return surface->has_bilevel_alpha;
+}
+
+cairo_bool_t
+_cairo_recording_surface_has_only_op_over (cairo_recording_surface_t *surface)
+{
+ return surface->has_only_op_over;
+}
diff --git a/src/cairo-rectangle.c b/src/cairo-rectangle.c
index c8f90e671..c8f90e671 100755..100644
--- a/src/cairo-rectangle.c
+++ b/src/cairo-rectangle.c
diff --git a/src/cairo-rectangular-scan-converter.c b/src/cairo-rectangular-scan-converter.c
index e353b34e8..e353b34e8 100755..100644
--- a/src/cairo-rectangular-scan-converter.c
+++ b/src/cairo-rectangular-scan-converter.c
diff --git a/src/cairo-reference-count-private.h b/src/cairo-reference-count-private.h
index 75fdf3538..75fdf3538 100755..100644
--- a/src/cairo-reference-count-private.h
+++ b/src/cairo-reference-count-private.h
diff --git a/src/cairo-region-private.h b/src/cairo-region-private.h
index 549e50878..549e50878 100755..100644
--- a/src/cairo-region-private.h
+++ b/src/cairo-region-private.h
diff --git a/src/cairo-region.c b/src/cairo-region.c
index a51e2247f..ccfb2200e 100755..100644
--- a/src/cairo-region.c
+++ b/src/cairo-region.c
@@ -106,6 +106,7 @@ _cairo_region_create_in_error (cairo_status_t status)
case CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED:
case CAIRO_STATUS_INVALID_MESH_CONSTRUCTION:
case CAIRO_STATUS_DEVICE_FINISHED:
+ case CAIRO_STATUS_JBIG2_GLOBAL_MISSING:
default:
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return (cairo_region_t *) &_cairo_region_nil;
@@ -841,18 +842,6 @@ cairo_region_translate (cairo_region_t *region,
slim_hidden_def (cairo_region_translate);
/**
- * cairo_region_overlap_t:
- * @CAIRO_REGION_OVERLAP_IN: The contents are entirely inside the region. (Since 1.10)
- * @CAIRO_REGION_OVERLAP_OUT: The contents are entirely outside the region. (Since 1.10)
- * @CAIRO_REGION_OVERLAP_PART: The contents are partially inside and
- * partially outside the region. (Since 1.10)
- *
- * Used as the return value for cairo_region_contains_rectangle().
- *
- * Since: 1.10
- **/
-
-/**
* cairo_region_contains_rectangle:
* @region: a #cairo_region_t
* @rectangle: a #cairo_rectangle_int_t
diff --git a/src/cairo-rtree-private.h b/src/cairo-rtree-private.h
index 27806cab6..27806cab6 100755..100644
--- a/src/cairo-rtree-private.h
+++ b/src/cairo-rtree-private.h
diff --git a/src/cairo-rtree.c b/src/cairo-rtree.c
index dbc040929..dbc040929 100755..100644
--- a/src/cairo-rtree.c
+++ b/src/cairo-rtree.c
diff --git a/src/cairo-scaled-font-private.h b/src/cairo-scaled-font-private.h
index da7b34698..da7b34698 100755..100644
--- a/src/cairo-scaled-font-private.h
+++ b/src/cairo-scaled-font-private.h
diff --git a/src/cairo-scaled-font-subsets-private.h b/src/cairo-scaled-font-subsets-private.h
index dd1996258..866e63d7b 100755..100644
--- a/src/cairo-scaled-font-subsets-private.h
+++ b/src/cairo-scaled-font-subsets-private.h
@@ -715,6 +715,21 @@ _cairo_truetype_get_style (cairo_scaled_font_t *scaled_font,
cairo_bool_t *bold,
cairo_bool_t *italic);
+/**
+ * _cairo_escape_ps_name:
+ * @ps_name: returns the PostScript name with all invalid characters escaped
+ *
+ * Ensure that PostSript name is a valid PDF/PostSript name object.
+ * In PDF names are treated as UTF8 and non ASCII bytes, ' ',
+ * and '#' are encoded as '#' followed by 2 hex digits that
+ * encode the byte.
+ *
+ * Return value: %CAIRO_STATUS_SUCCESS if successful. Possible errors include
+ * %CAIRO_STATUS_NO_MEMORY.
+ **/
+cairo_private cairo_int_status_t
+_cairo_escape_ps_name (char **ps_name);
+
#endif /* CAIRO_HAS_FONT_SUBSET */
#endif /* CAIRO_SCALED_FONT_SUBSETS_PRIVATE_H */
diff --git a/src/cairo-scaled-font-subsets.c b/src/cairo-scaled-font-subsets.c
index e78e0c283..212176183 100755..100644
--- a/src/cairo-scaled-font-subsets.c
+++ b/src/cairo-scaled-font-subsets.c
@@ -1256,4 +1256,44 @@ CLEANUP_HASH:
return status;
}
+cairo_int_status_t
+_cairo_escape_ps_name (char **ps_name)
+{
+ cairo_status_t status = CAIRO_STATUS_SUCCESS;
+
+ /* Ensure PS name is a valid PDF/PS name object. In PDF names are
+ * treated as UTF8 and non ASCII bytes, ' ', and '#' are encoded
+ * as '#' followed by 2 hex digits that encode the byte. By also
+ * encoding the characters in the reserved string we ensure the
+ * name is also PS compatible. */
+ if (*ps_name) {
+ static const char *reserved = "()<>[]{}/%#\\";
+ char buf[128]; /* max name length is 127 bytes */
+ char *src = *ps_name;
+ char *dst = buf;
+
+ while (*src && dst < buf + 127) {
+ unsigned char c = *src;
+ if (c < 0x21 || c > 0x7e || strchr (reserved, c)) {
+ if (dst + 4 > buf + 127)
+ break;
+
+ snprintf (dst, 4, "#%02X", c);
+ src++;
+ dst += 3;
+ } else {
+ *dst++ = *src++;
+ }
+ }
+ *dst = 0;
+ free (*ps_name);
+ *ps_name = strdup (buf);
+ if (*ps_name == NULL) {
+ status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ }
+ }
+
+ return status;
+}
+
#endif /* CAIRO_HAS_FONT_SUBSET */
diff --git a/src/cairo-scaled-font.c b/src/cairo-scaled-font.c
index ea4435aff..660ff7ce0 100755..100644
--- a/src/cairo-scaled-font.c
+++ b/src/cairo-scaled-font.c
@@ -2938,8 +2938,12 @@ _cairo_scaled_font_free_last_glyph (cairo_scaled_font_t *scaled_font,
if (--page->num_glyphs == 0) {
CAIRO_MUTEX_LOCK (_cairo_scaled_glyph_page_cache_mutex);
+ /* Temporarily disconnect callback to avoid recursive locking */
+ cairo_scaled_glyph_page_cache.entry_destroy = NULL;
_cairo_cache_remove (&cairo_scaled_glyph_page_cache,
&page->cache_entry);
+ _cairo_scaled_glyph_page_destroy (scaled_font, page);
+ cairo_scaled_glyph_page_cache.entry_destroy = _cairo_scaled_glyph_page_pluck;
CAIRO_MUTEX_UNLOCK (_cairo_scaled_glyph_page_cache_mutex);
}
}
diff --git a/src/cairo-script-private.h b/src/cairo-script-private.h
index 5b506f500..5b506f500 100755..100644
--- a/src/cairo-script-private.h
+++ b/src/cairo-script-private.h
diff --git a/src/cairo-script-surface.c b/src/cairo-script-surface.c
index 68c1528f6..68c1528f6 100755..100644
--- a/src/cairo-script-surface.c
+++ b/src/cairo-script-surface.c
diff --git a/src/cairo-script.h b/src/cairo-script.h
index b5a8cf32d..b5a8cf32d 100755..100644
--- a/src/cairo-script.h
+++ b/src/cairo-script.h
diff --git a/src/cairo-shape-mask-compositor.c b/src/cairo-shape-mask-compositor.c
index c2425b08c..3117267cc 100755..100644
--- a/src/cairo-shape-mask-compositor.c
+++ b/src/cairo-shape-mask-compositor.c
@@ -62,10 +62,11 @@ _cairo_shape_mask_compositor_stroke (const cairo_compositor_t *_compositor,
return CAIRO_INT_STATUS_UNSUPPORTED;
TRACE ((stderr, "%s\n", __FUNCTION__));
- mask = _cairo_surface_create_similar_scratch (extents->surface,
- CAIRO_CONTENT_ALPHA,
- extents->bounded.width,
- extents->bounded.height);
+ mask = _cairo_surface_create_scratch (extents->surface,
+ CAIRO_CONTENT_ALPHA,
+ extents->bounded.width,
+ extents->bounded.height,
+ NULL);
if (unlikely (mask->status))
return mask->status;
@@ -156,10 +157,11 @@ _cairo_shape_mask_compositor_fill (const cairo_compositor_t *_compositor,
if (! extents->is_bounded)
return CAIRO_INT_STATUS_UNSUPPORTED;
- mask = _cairo_surface_create_similar_scratch (extents->surface,
- CAIRO_CONTENT_ALPHA,
- extents->bounded.width,
- extents->bounded.height);
+ mask = _cairo_surface_create_scratch (extents->surface,
+ CAIRO_CONTENT_ALPHA,
+ extents->bounded.width,
+ extents->bounded.height,
+ NULL);
if (unlikely (mask->status))
return mask->status;
@@ -248,10 +250,11 @@ _cairo_shape_mask_compositor_glyphs (const cairo_compositor_t *_compositor,
return CAIRO_INT_STATUS_UNSUPPORTED;
TRACE ((stderr, "%s\n", __FUNCTION__));
- mask = _cairo_surface_create_similar_scratch (extents->surface,
- CAIRO_CONTENT_ALPHA,
- extents->bounded.width,
- extents->bounded.height);
+ mask = _cairo_surface_create_scratch (extents->surface,
+ CAIRO_CONTENT_ALPHA,
+ extents->bounded.width,
+ extents->bounded.height,
+ NULL);
if (unlikely (mask->status))
return mask->status;
diff --git a/src/cairo-skia-surface.cpp b/src/cairo-skia-surface.cpp
index bf6b14a5e..0282c2b51 100755..100644
--- a/src/cairo-skia-surface.cpp
+++ b/src/cairo-skia-surface.cpp
@@ -51,6 +51,27 @@
#include <SkGradientShader.h>
#include <SkDashPathEffect.h>
+/**
+ * SECTION:cairo-skia
+ * @Title: Skia Surfaces
+ * @Short_Description: Rendering to Skia surfaces
+ * @See_Also: #cairo_surface_t
+ *
+ * Originally written by Vladimir Vukicevic to investigate using Skia for
+ * Mozilla, it provides a nice integration with a rather interesting code
+ * base. By hooking Skia underneath Cairo it allows us to directly compare
+ * code paths... which is interesting.
+ **/
+
+/**
+ * CAIRO_HAS_SKIA_SURFACE:
+ *
+ * Defined if the Skia surface backend is available.
+ * This macro can be used to conditionally compile backend-specific code.
+ *
+ * Since: 1.10
+ **/
+
#if (CAIRO_FIXED_BITS == 32) && (CAIRO_FIXED_FRAC_BITS == 16) && defined(SK_SCALAR_IS_FIXED)
# define CAIRO_FIXED_TO_SK_SCALAR(x) (x)
#elif defined(SK_SCALAR_IS_FIXED)
@@ -64,13 +85,20 @@
# define CAIRO_INT_STATUS_SUCCESS ((cairo_int_status_t) CAIRO_STATUS_SUCCESS)
#endif
-#define CAIRO_MAYBE_UNSUPPORTED CAIRO_INT_STATUS_UNSUPPORTED
-//#define CAIRO_MAYBE_UNSUPPORTED _skia_unsupported ()
+#define DEBUG_SKIA 0
+
+#if DEBUG_SKIA
+#define UNSUPPORTED(reason) ({ \
+ fprintf (stderr, \
+ "cairo-skia : hit unsupported operation in %s(), line %d: %s\n", \
+ __FUNCTION__, __LINE__, reason); \
+ return CAIRO_INT_STATUS_UNSUPPORTED; \
+})
+#else
+#define UNSUPPORTED(reason) ({ \
+ return CAIRO_INT_STATUS_UNSUPPORTED; \
+})#endif
-static cairo_int_status_t _skia_unsupported () {
- printf ("unsupported!\n");
- return CAIRO_INT_STATUS_UNSUPPORTED;
-}
typedef struct cairo_skia_surface {
cairo_surface_t base;
@@ -542,8 +570,7 @@ _cairo_skia_surface_create_similar (void *asurface,
if (! format_to_sk_config (_cairo_format_from_content (content),
config, opaque))
{
- _skia_unsupported ();
- return NULL;
+ return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_FORMAT));
}
return &_cairo_skia_surface_create_internal (config, opaque,
@@ -781,7 +808,7 @@ _cairo_skia_surface_paint (void *asurface,
shader = pattern_to_sk_shader (surface, source, &image, &image_extra);
if (!bitmap && !shader)
- return CAIRO_MAYBE_UNSUPPORTED;
+ return UNSUPPORTED("pattern to bitmap and shader conversion");
SkPaint paint;
paint.setFilterBitmap (pattern_filter_to_sk (source));
@@ -838,7 +865,7 @@ _cairo_skia_surface_stroke (void *asurface,
SkShader *shader = pattern_to_sk_shader (surface,
source, &image, &image_extra);
if (shader == NULL)
- return CAIRO_MAYBE_UNSUPPORTED;
+ return UNSUPPORTED("pattern to shader conversion");
paint.setShader (shader);
shader->unref ();
@@ -941,7 +968,7 @@ _cairo_skia_surface_fill (void *asurface,
SkShader *shader = pattern_to_sk_shader (surface,
source, &image, &image_extra);
if (shader == NULL)
- return CAIRO_MAYBE_UNSUPPORTED;
+ return UNSUPPORTED("pattern to shader conversion");
paint.setShader (shader);
shader->unref ();
diff --git a/src/cairo-skia.h b/src/cairo-skia.h
index 99b928656..99b928656 100755..100644
--- a/src/cairo-skia.h
+++ b/src/cairo-skia.h
diff --git a/src/cairo-slope-private.h b/src/cairo-slope-private.h
index 6a58c9f45..6a58c9f45 100755..100644
--- a/src/cairo-slope-private.h
+++ b/src/cairo-slope-private.h
diff --git a/src/cairo-slope.c b/src/cairo-slope.c
index cc5f30cb0..cc5f30cb0 100755..100644
--- a/src/cairo-slope.c
+++ b/src/cairo-slope.c
diff --git a/src/cairo-spans-compositor-private.h b/src/cairo-spans-compositor-private.h
index 0babebd26..0babebd26 100755..100644
--- a/src/cairo-spans-compositor-private.h
+++ b/src/cairo-spans-compositor-private.h
diff --git a/src/cairo-spans-compositor.c b/src/cairo-spans-compositor.c
index 8580da383..ef213b491 100755..100644
--- a/src/cairo-spans-compositor.c
+++ b/src/cairo-spans-compositor.c
@@ -95,11 +95,11 @@ get_clip_surface (const cairo_spans_compositor_t *compositor,
assert (clip->path);
- surface = _cairo_surface_create_similar_solid (dst,
- CAIRO_CONTENT_ALPHA,
- extents->width,
- extents->height,
- CAIRO_COLOR_TRANSPARENT);
+ surface = _cairo_surface_create_scratch (dst,
+ CAIRO_CONTENT_ALPHA,
+ extents->width,
+ extents->height,
+ CAIRO_COLOR_TRANSPARENT);
_cairo_box_from_rectangle (&box, extents);
_cairo_polygon_init (&polygon, &box, 1);
@@ -588,20 +588,34 @@ composite_aligned_boxes (const cairo_spans_compositor_t *compositor,
{
cairo_clip_t *recording_clip;
const cairo_pattern_t *source = &extents->source_pattern.base;
+ const cairo_matrix_t *m;
+ cairo_matrix_t matrix;
/* XXX could also do tiling repeat modes... */
/* first clear the area about to be overwritten */
- if (! dst->is_clear)
+ if (! dst->is_clear) {
status = compositor->fill_boxes (dst,
CAIRO_OPERATOR_CLEAR,
CAIRO_COLOR_TRANSPARENT,
boxes);
+ if (unlikely (status))
+ return status;
+
+ dst->is_clear = TRUE;
+ }
+
+ m = &source->matrix;
+ if (_cairo_surface_has_device_transform (dst)) {
+ cairo_matrix_multiply (&matrix,
+ &source->matrix,
+ &dst->device_transform);
+ m = &matrix;
+ }
recording_clip = _cairo_clip_from_boxes (boxes);
status = _cairo_recording_surface_replay_with_clip (unwrap_source (source),
- &source->matrix,
- dst, recording_clip);
+ m, dst, recording_clip);
_cairo_clip_destroy (recording_clip);
return status;
diff --git a/src/cairo-spans-private.h b/src/cairo-spans-private.h
index c42b5afa7..b158f4d36 100755..100644
--- a/src/cairo-spans-private.h
+++ b/src/cairo-spans-private.h
@@ -53,7 +53,7 @@ struct _cairo_span_renderer {
/* Render the spans on row y of the destination by whatever compositing
* method is required. */
- cairo_warn cairo_status_t
+ cairo_status_t
(*render_rows) (void *abstract_renderer,
int y, int height,
const cairo_half_open_span_t *coverages,
diff --git a/src/cairo-spans.c b/src/cairo-spans.c
index b8d41800e..182390c20 100755..100644
--- a/src/cairo-spans.c
+++ b/src/cairo-spans.c
@@ -127,6 +127,7 @@ _cairo_scan_converter_create_in_error (cairo_status_t status)
case CAIRO_STATUS_DEVICE_ERROR: RETURN_NIL;
case CAIRO_STATUS_INVALID_MESH_CONSTRUCTION: RETURN_NIL;
case CAIRO_STATUS_DEVICE_FINISHED: RETURN_NIL;
+ case CAIRO_STATUS_JBIG2_GLOBAL_MISSING:
default:
break;
}
@@ -239,6 +240,7 @@ _cairo_span_renderer_create_in_error (cairo_status_t status)
case CAIRO_STATUS_DEVICE_ERROR: RETURN_NIL;
case CAIRO_STATUS_INVALID_MESH_CONSTRUCTION: RETURN_NIL;
case CAIRO_STATUS_DEVICE_FINISHED: RETURN_NIL;
+ case CAIRO_STATUS_JBIG2_GLOBAL_MISSING: RETURN_NIL;
default:
break;
}
diff --git a/src/cairo-spline.c b/src/cairo-spline.c
index 9ebb949c7..6341d71b3 100755..100644
--- a/src/cairo-spline.c
+++ b/src/cairo-spline.c
@@ -38,6 +38,7 @@
#include "cairo-box-inline.h"
#include "cairo-slope-private.h"
+#include "cairo-convex-fill-private.h"
cairo_bool_t
_cairo_spline_intersects (const cairo_point_t *a,
diff --git a/src/cairo-stroke-dash-private.h b/src/cairo-stroke-dash-private.h
index 75c000cd7..75c000cd7 100755..100644
--- a/src/cairo-stroke-dash-private.h
+++ b/src/cairo-stroke-dash-private.h
diff --git a/src/cairo-stroke-dash.c b/src/cairo-stroke-dash.c
index 9494010f5..9494010f5 100755..100644
--- a/src/cairo-stroke-dash.c
+++ b/src/cairo-stroke-dash.c
diff --git a/src/cairo-stroke-style.c b/src/cairo-stroke-style.c
index 51c9414c0..51c9414c0 100755..100644
--- a/src/cairo-stroke-style.c
+++ b/src/cairo-stroke-style.c
diff --git a/src/cairo-surface-backend-private.h b/src/cairo-surface-backend-private.h
index be624dfbe..be624dfbe 100755..100644
--- a/src/cairo-surface-backend-private.h
+++ b/src/cairo-surface-backend-private.h
diff --git a/src/cairo-surface-clipper-private.h b/src/cairo-surface-clipper-private.h
index e5b00af7c..e5b00af7c 100755..100644
--- a/src/cairo-surface-clipper-private.h
+++ b/src/cairo-surface-clipper-private.h
diff --git a/src/cairo-surface-clipper.c b/src/cairo-surface-clipper.c
index 5309362c6..5309362c6 100755..100644
--- a/src/cairo-surface-clipper.c
+++ b/src/cairo-surface-clipper.c
diff --git a/src/cairo-surface-fallback-private.h b/src/cairo-surface-fallback-private.h
index ecf7b0edf..ecf7b0edf 100755..100644
--- a/src/cairo-surface-fallback-private.h
+++ b/src/cairo-surface-fallback-private.h
diff --git a/src/cairo-surface-fallback.c b/src/cairo-surface-fallback.c
index a0af15969..a0af15969 100755..100644
--- a/src/cairo-surface-fallback.c
+++ b/src/cairo-surface-fallback.c
diff --git a/src/cairo-surface-inline.h b/src/cairo-surface-inline.h
index 85fbc9192..85fbc9192 100755..100644
--- a/src/cairo-surface-inline.h
+++ b/src/cairo-surface-inline.h
diff --git a/src/cairo-surface-observer-inline.h b/src/cairo-surface-observer-inline.h
index 07b94770d..07b94770d 100755..100644
--- a/src/cairo-surface-observer-inline.h
+++ b/src/cairo-surface-observer-inline.h
diff --git a/src/cairo-surface-observer-private.h b/src/cairo-surface-observer-private.h
index 6ed0c18d1..6ed0c18d1 100755..100644
--- a/src/cairo-surface-observer-private.h
+++ b/src/cairo-surface-observer-private.h
diff --git a/src/cairo-surface-observer.c b/src/cairo-surface-observer.c
index 8bbd6109c..ee65b72d1 100755..100644
--- a/src/cairo-surface-observer.c
+++ b/src/cairo-surface-observer.c
@@ -653,7 +653,7 @@ add_record (cairo_observation_t *log,
}
static void
-sync (cairo_surface_t *target, int x, int y)
+_cairo_surface_sync (cairo_surface_t *target, int x, int y)
{
cairo_rectangle_int_t extents;
@@ -751,7 +751,7 @@ _cairo_surface_observer_paint (void *abstract_surface,
if (unlikely (status))
return status;
- sync (surface->target, x, y);
+ _cairo_surface_sync (surface->target, x, y);
t = _cairo_time_get_delta (t);
add_record_paint (&surface->log, surface->target, op, source, clip, t);
@@ -837,7 +837,7 @@ _cairo_surface_observer_mask (void *abstract_surface,
if (unlikely (status))
return status;
- sync (surface->target, x, y);
+ _cairo_surface_sync (surface->target, x, y);
t = _cairo_time_get_delta (t);
add_record_mask (&surface->log,
@@ -944,7 +944,7 @@ _cairo_surface_observer_fill (void *abstract_surface,
if (unlikely (status))
return status;
- sync (surface->target, x, y);
+ _cairo_surface_sync (surface->target, x, y);
t = _cairo_time_get_delta (t);
add_record_fill (&surface->log,
@@ -1063,7 +1063,7 @@ _cairo_surface_observer_stroke (void *abstract_surface,
if (unlikely (status))
return status;
- sync (surface->target, x, y);
+ _cairo_surface_sync (surface->target, x, y);
t = _cairo_time_get_delta (t);
add_record_stroke (&surface->log,
@@ -1183,7 +1183,7 @@ _cairo_surface_observer_glyphs (void *abstract_surface,
if (unlikely (status))
return status;
- sync (surface->target, x, y);
+ _cairo_surface_sync (surface->target, x, y);
t = _cairo_time_get_delta (t);
add_record_glyphs (&surface->log,
@@ -1368,11 +1368,16 @@ static const cairo_surface_backend_t _cairo_surface_observer_backend = {
/**
* cairo_surface_create_observer:
* @target: an existing surface for which the observer will watch
+ * @mode: sets the mode of operation (normal vs. record)
*
* Create a new surface that exists solely to watch another is doing. In
* the process it will log operations and times, which are fast, which are
* slow, which are frequent, etc.
*
+ * The @mode parameter can be set to either CAIRO_SURFACE_OBSERVER_NORMAL
+ * or CAIRO_SURFACE_OBSERVER_RECORD_OPERATIONS, to control whether or not
+ * the internal observer should record operations.
+ *
* Return value: a pointer to the newly allocated surface. The caller
* owns the surface and should call cairo_surface_destroy() when done
* with it.
diff --git a/src/cairo-surface-offset-private.h b/src/cairo-surface-offset-private.h
index 310ba5691..310ba5691 100755..100644
--- a/src/cairo-surface-offset-private.h
+++ b/src/cairo-surface-offset-private.h
diff --git a/src/cairo-surface-offset.c b/src/cairo-surface-offset.c
index 98f57f298..98f57f298 100755..100644
--- a/src/cairo-surface-offset.c
+++ b/src/cairo-surface-offset.c
diff --git a/src/cairo-surface-private.h b/src/cairo-surface-private.h
index f20ab0739..f20ab0739 100755..100644
--- a/src/cairo-surface-private.h
+++ b/src/cairo-surface-private.h
diff --git a/src/cairo-surface-scale-translate-private.h b/src/cairo-surface-scale-translate-private.h
index b13d3366d..b13d3366d 100755..100644
--- a/src/cairo-surface-scale-translate-private.h
+++ b/src/cairo-surface-scale-translate-private.h
diff --git a/src/cairo-surface-scale-translate.c b/src/cairo-surface-scale-translate.c
index 1729b81ad..1729b81ad 100755..100644
--- a/src/cairo-surface-scale-translate.c
+++ b/src/cairo-surface-scale-translate.c
diff --git a/src/cairo-surface-shadow-private.h b/src/cairo-surface-shadow-private.h
index 43c7e6d2a..43c7e6d2a 100755..100644
--- a/src/cairo-surface-shadow-private.h
+++ b/src/cairo-surface-shadow-private.h
diff --git a/src/cairo-surface-shadow.c b/src/cairo-surface-shadow.c
index 5224bee40..921258ec3 100755..100644
--- a/src/cairo-surface-shadow.c
+++ b/src/cairo-surface-shadow.c
@@ -319,7 +319,8 @@ _cairo_ensure_shadow_surface (cairo_surface_t *target,
content,
width_out,
height_out);
- _cairo_surface_release_device_reference (shadow_surface);
+ if (shadow_surface->device)
+ _cairo_surface_release_device_reference (shadow_surface);
}
shadow_surface_extents->x = 0;
@@ -407,13 +408,13 @@ _cairo_surface_shadow_paint (cairo_surface_t *target,
&shadow_source.base,
&shadow_extents,
&bounded);
- if (unlikely (status))
+ if (unlikely (status))
goto FINISH;
if (shadow_extents.width == 0 || shadow_extents.height == 0)
goto FINISH;
- x_offset = shadow_extents.x - x_blur;
+ x_offset = shadow_extents.x - x_blur;
y_offset = shadow_extents.y - y_blur;
cairo_matrix_init_scale (&m, shadow_cache->scale, shadow_cache->scale);
@@ -678,13 +679,13 @@ _cairo_surface_shadow_mask (cairo_surface_t *target,
&shadow_mask.base,
&shadow_extents,
&bounded);
- if (unlikely (status))
+ if (unlikely (status))
goto FINISH;
if (shadow_extents.width == 0 || shadow_extents.height == 0)
goto FINISH;
- x_offset = shadow_extents.x - x_blur;
+ x_offset = shadow_extents.x - x_blur;
y_offset = shadow_extents.y - y_blur;
cairo_matrix_init_scale (&m, shadow_cache->scale, shadow_cache->scale);
@@ -918,13 +919,13 @@ _cairo_surface_inset_shadow_stroke (cairo_surface_t *target,
&shadow_ctm,
&shadow_ctm_inverse,
&shadow_extents);
- if (unlikely (status))
+ if (unlikely (status))
goto FINISH;
if (shadow_extents.width == 0 || shadow_extents.height == 0)
goto FINISH;
- x_offset = shadow_extents.x - x_blur;
+ x_offset = shadow_extents.x - x_blur;
y_offset = shadow_extents.y - y_blur;
cairo_matrix_init_scale (&m, shadow_cache->scale, shadow_cache->scale);
@@ -1205,13 +1206,13 @@ _cairo_surface_shadow_stroke (cairo_surface_t *target,
&shadow_ctm,
&shadow_ctm_inverse,
&shadow_extents);
- if (unlikely (status))
+ if (unlikely (status))
goto FINISH;
if (shadow_extents.width == 0 || shadow_extents.height == 0)
goto FINISH;
- x_offset = shadow_extents.x - x_blur;
+ x_offset = shadow_extents.x - x_blur;
y_offset = shadow_extents.y - y_blur;
cairo_matrix_init_scale (&m, shadow_cache->scale, shadow_cache->scale);
@@ -1437,7 +1438,7 @@ _cairo_surface_inset_shadow_fill (cairo_surface_t *target,
if (shadow_cache != NULL) {
/* paint the shadow surface to target */
- color_pattern = cairo_pattern_create_rgba (shadow_copy.color.red,
+ color_pattern = cairo_pattern_create_rgba (shadow_copy.color.red,
shadow_copy.color.green,
shadow_copy.color.blue,
1.0);
@@ -1455,13 +1456,13 @@ _cairo_surface_inset_shadow_fill (cairo_surface_t *target,
&shadow_source.base,
&shadow_path,
&shadow_extents);
- if (unlikely (status))
+ if (unlikely (status))
goto FINISH;
if (shadow_extents.width == 0 || shadow_extents.height == 0)
goto FINISH;
- x_offset = shadow_extents.x - x_blur;
+ x_offset = shadow_extents.x - x_blur;
y_offset = shadow_extents.y - y_blur;
cairo_matrix_init_scale (&m, shadow_cache->scale, shadow_cache->scale);
@@ -1533,7 +1534,7 @@ _cairo_surface_inset_shadow_fill (cairo_surface_t *target,
cache_surface = cairo_surface_create_similar (target, content,
shadow_surface_extents.width,
shadow_surface_extents.height);
- if (unlikely (cache_surface->status))
+ if (unlikely (cache_surface->status))
goto FINISH;
if (device)
@@ -1587,7 +1588,7 @@ _cairo_surface_inset_shadow_fill (cairo_surface_t *target,
if (unlikely (status))
goto FINISH;
- cairo_pattern_destroy (shadow_pattern);
+ cairo_pattern_destroy (shadow_pattern);
size = shadow_surface_extents.width * shadow_surface_extents.height;
_cairo_shadow_cache_list_shrink_to_accomodate (&shadow_cache_list,
@@ -1755,7 +1756,7 @@ _cairo_surface_shadow_fill (cairo_surface_t *target,
if (shadow_cache != NULL) {
/* paint the shadow surface to target */
- color_pattern = cairo_pattern_create_rgba (shadow_copy.color.red,
+ color_pattern = cairo_pattern_create_rgba (shadow_copy.color.red,
shadow_copy.color.green,
shadow_copy.color.blue,
1.0);
@@ -1773,13 +1774,13 @@ _cairo_surface_shadow_fill (cairo_surface_t *target,
&shadow_source.base,
&shadow_path,
&shadow_extents);
- if (unlikely (status))
+ if (unlikely (status))
goto FINISH;
if (shadow_extents.width == 0 || shadow_extents.height == 0)
goto FINISH;
- x_offset = shadow_extents.x - x_blur;
+ x_offset = shadow_extents.x - x_blur;
y_offset = shadow_extents.y - y_blur;
cairo_matrix_init_scale (&m, shadow_cache->scale, shadow_cache->scale);
@@ -1843,7 +1844,7 @@ _cairo_surface_shadow_fill (cairo_surface_t *target,
cache_surface = cairo_surface_create_similar (target, content,
shadow_surface_extents.width,
shadow_surface_extents.height);
- if (unlikely (cache_surface->status))
+ if (unlikely (cache_surface->status))
goto FINISH;
if (device)
@@ -1889,7 +1890,7 @@ _cairo_surface_shadow_fill (cairo_surface_t *target,
if (unlikely (status))
goto FINISH;
- cairo_pattern_destroy (shadow_pattern);
+ cairo_pattern_destroy (shadow_pattern);
size = shadow_surface_extents.width * shadow_surface_extents.height;
_cairo_shadow_cache_list_shrink_to_accomodate (&shadow_cache_list,
@@ -2026,7 +2027,8 @@ _cairo_surface_inset_shadow_glyphs (cairo_surface_t *target,
content,
shadow_width,
shadow_height);
- _cairo_surface_release_device_reference (shadow_surface);
+ if (shadow_surface->device)
+ _cairo_surface_release_device_reference (shadow_surface);
}
if (! shadow_surface || unlikely (shadow_surface->status))
goto FINISH;
@@ -2045,7 +2047,8 @@ _cairo_surface_inset_shadow_glyphs (cairo_surface_t *target,
CAIRO_CONTENT_COLOR_ALPHA,
shadow_surface_extents.width,
shadow_surface_extents.height);
- _cairo_surface_release_device_reference (mask_surface);
+ if (mask_surface->device)
+ _cairo_surface_release_device_reference (mask_surface);
}
if (! mask_surface || unlikely (mask_surface->status))
goto FINISH;
@@ -2230,7 +2233,8 @@ _cairo_surface_shadow_glyphs (cairo_surface_t *target,
content,
shadow_width,
shadow_height);
- _cairo_surface_release_device_reference (shadow_surface);
+ if (shadow_surface->device)
+ _cairo_surface_release_device_reference (shadow_surface);
}
if (! shadow_surface || unlikely (shadow_surface->status))
goto FINISH;
diff --git a/src/cairo-surface-snapshot-inline.h b/src/cairo-surface-snapshot-inline.h
index bf89c772b..bf89c772b 100755..100644
--- a/src/cairo-surface-snapshot-inline.h
+++ b/src/cairo-surface-snapshot-inline.h
diff --git a/src/cairo-surface-snapshot-private.h b/src/cairo-surface-snapshot-private.h
index 58bee7b49..58bee7b49 100755..100644
--- a/src/cairo-surface-snapshot-private.h
+++ b/src/cairo-surface-snapshot-private.h
diff --git a/src/cairo-surface-snapshot.c b/src/cairo-surface-snapshot.c
index 68bf9054e..68bf9054e 100755..100644
--- a/src/cairo-surface-snapshot.c
+++ b/src/cairo-surface-snapshot.c
diff --git a/src/cairo-surface-subsurface-inline.h b/src/cairo-surface-subsurface-inline.h
index 0cd09e63e..0cd09e63e 100755..100644
--- a/src/cairo-surface-subsurface-inline.h
+++ b/src/cairo-surface-subsurface-inline.h
diff --git a/src/cairo-surface-subsurface-private.h b/src/cairo-surface-subsurface-private.h
index 89c5cc01b..89c5cc01b 100755..100644
--- a/src/cairo-surface-subsurface-private.h
+++ b/src/cairo-surface-subsurface-private.h
diff --git a/src/cairo-surface-subsurface.c b/src/cairo-surface-subsurface.c
index 0b4915e7e..5c55ac12f 100755..100644
--- a/src/cairo-surface-subsurface.c
+++ b/src/cairo-surface-subsurface.c
@@ -354,10 +354,11 @@ _cairo_surface_subsurface_snapshot (void *abstract_surface)
TRACE ((stderr, "%s: target=%d\n", __FUNCTION__, surface->target->unique_id));
- clone = _cairo_surface_create_similar_scratch (surface->target,
- surface->target->content,
- surface->extents.width,
- surface->extents.height);
+ clone = _cairo_surface_create_scratch (surface->target,
+ surface->target->content,
+ surface->extents.width,
+ surface->extents.height,
+ NULL);
if (unlikely (clone->status))
return clone;
@@ -468,7 +469,12 @@ cairo_surface_create_for_rectangle (cairo_surface_t *target,
if (unlikely (surface == NULL))
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
- assert (_cairo_matrix_is_translation (&target->device_transform));
+ x *= target->device_transform.xx;
+ y *= target->device_transform.yy;
+
+ width *= target->device_transform.xx;
+ height *= target->device_transform.yy;
+
x += target->device_transform.x0;
y += target->device_transform.y0;
@@ -498,6 +504,10 @@ cairo_surface_create_for_rectangle (cairo_surface_t *target,
surface->snapshot = NULL;
+ cairo_surface_set_device_scale (&surface->base,
+ target->device_transform.xx,
+ target->device_transform.yy);
+
return &surface->base;
}
@@ -518,14 +528,16 @@ _cairo_surface_create_for_rectangle_int (cairo_surface_t *target,
if (unlikely (surface == NULL))
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
- assert (_cairo_matrix_is_translation (&target->device_transform));
-
_cairo_surface_init (&surface->base,
&_cairo_surface_subsurface_backend,
NULL, /* device */
target->content);
surface->extents = *extents;
+ surface->extents.x *= target->device_transform.xx;
+ surface->extents.y *= target->device_transform.yy;
+ surface->extents.width *= target->device_transform.xx;
+ surface->extents.height *= target->device_transform.yy;
surface->extents.x += target->device_transform.x0;
surface->extents.y += target->device_transform.y0;
@@ -534,6 +546,10 @@ _cairo_surface_create_for_rectangle_int (cairo_surface_t *target,
surface->snapshot = NULL;
+ cairo_surface_set_device_scale (&surface->base,
+ target->device_transform.xx,
+ target->device_transform.yy);
+
return &surface->base;
}
/* XXX observe mark-dirty */
diff --git a/src/cairo-surface-wrapper-private.h b/src/cairo-surface-wrapper-private.h
index 6529ebc11..6529ebc11 100755..100644
--- a/src/cairo-surface-wrapper-private.h
+++ b/src/cairo-surface-wrapper-private.h
diff --git a/src/cairo-surface-wrapper.c b/src/cairo-surface-wrapper.c
index 578e8e2be..9236c8bf4 100755..100644
--- a/src/cairo-surface-wrapper.c
+++ b/src/cairo-surface-wrapper.c
@@ -437,12 +437,11 @@ _cairo_surface_wrapper_show_text_glyphs (cairo_surface_wrapper_t *wrapper,
_cairo_surface_wrapper_get_transform (wrapper, &m);
- if (! _cairo_matrix_is_translation (&wrapper->transform)) {
+ if (! _cairo_matrix_is_translation (&m)) {
cairo_matrix_t ctm;
- /* XXX No device-transform? A bug in the tangle of layers? */
_cairo_matrix_multiply (&ctm,
- &wrapper->transform,
+ &m,
&scaled_font->ctm);
dev_scaled_font = cairo_scaled_font_create (scaled_font->font_face,
&scaled_font->font_matrix,
@@ -514,8 +513,8 @@ _cairo_surface_wrapper_create_similar (cairo_surface_wrapper_t *wrapper,
int width,
int height)
{
- return _cairo_surface_create_similar_scratch (wrapper->target,
- content, width, height);
+ return _cairo_surface_create_scratch (wrapper->target,
+ content, width, height, NULL);
}
cairo_bool_t
diff --git a/src/cairo-surface.c b/src/cairo-surface.c
index 5c6969c8a..24ad24901 100755..100644
--- a/src/cairo-surface.c
+++ b/src/cairo-surface.c
@@ -454,33 +454,6 @@ _cairo_surface_copy_similar_properties (cairo_surface_t *surface,
other->y_fallback_resolution);
}
-cairo_surface_t *
-_cairo_surface_create_similar_scratch (cairo_surface_t *other,
- cairo_content_t content,
- int width,
- int height)
-{
- cairo_surface_t *surface;
-
- if (unlikely (other->status))
- return _cairo_surface_create_in_error (other->status);
-
- surface = NULL;
- if (other->backend->create_similar)
- surface = other->backend->create_similar (other, content, width, height);
- if (surface == NULL)
- surface = cairo_surface_create_similar_image (other,
- _cairo_format_from_content (content),
- width, height);
-
- if (unlikely (surface->status))
- return surface;
-
- _cairo_surface_copy_similar_properties (surface, other);
-
- return surface;
-}
-
/**
* cairo_surface_create_similar:
* @other: an existing surface used to select the backend of the new surface
@@ -518,6 +491,8 @@ cairo_surface_create_similar (cairo_surface_t *other,
int height)
{
cairo_surface_t *surface;
+ cairo_status_t status;
+ cairo_solid_pattern_t pattern;
if (unlikely (other->status))
return _cairo_surface_create_in_error (other->status);
@@ -529,9 +504,41 @@ cairo_surface_create_similar (cairo_surface_t *other,
if (unlikely (! CAIRO_CONTENT_VALID (content)))
return _cairo_surface_create_in_error (CAIRO_STATUS_INVALID_CONTENT);
- surface = _cairo_surface_create_similar_solid (other,
- content, width, height,
- CAIRO_COLOR_TRANSPARENT);
+ 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;
+
+ surface = NULL;
+ if (other->backend->create_similar)
+ surface = other->backend->create_similar (other, content, width, height);
+ if (surface == NULL)
+ surface = cairo_surface_create_similar_image (other,
+ _cairo_format_from_content (content),
+ width, height);
+
+ if (unlikely (surface->status))
+ return surface;
+
+ _cairo_surface_copy_similar_properties (surface, other);
+ cairo_surface_set_device_scale (surface,
+ other->device_transform.xx,
+ other->device_transform.yy);
+
+ if (unlikely (surface->status))
+ return surface;
+
+ _cairo_pattern_init_solid (&pattern, CAIRO_COLOR_TRANSPARENT);
+ status = _cairo_surface_paint (surface,
+ CAIRO_OPERATOR_CLEAR,
+ &pattern.base, NULL);
+ if (unlikely (status)) {
+ cairo_surface_destroy (surface);
+ surface = _cairo_surface_create_in_error (status);
+ }
+
assert (surface->is_clear);
return surface;
@@ -852,34 +859,78 @@ error:
}
cairo_surface_t *
-_cairo_surface_create_similar_solid (cairo_surface_t *other,
- cairo_content_t content,
- int width,
- int height,
- const cairo_color_t *color)
+_cairo_surface_create_scratch (cairo_surface_t *other,
+ cairo_content_t content,
+ int width,
+ int height,
+ const cairo_color_t *color)
{
- cairo_status_t status;
cairo_surface_t *surface;
+ cairo_status_t status;
cairo_solid_pattern_t pattern;
- surface = _cairo_surface_create_similar_scratch (other, content,
- width, height);
+ if (unlikely (other->status))
+ return _cairo_surface_create_in_error (other->status);
+
+ surface = NULL;
+ if (other->backend->create_similar)
+ surface = other->backend->create_similar (other, content, width, height);
+ if (surface == NULL)
+ surface = cairo_surface_create_similar_image (other,
+ _cairo_format_from_content (content),
+ width, height);
+
if (unlikely (surface->status))
return surface;
- _cairo_pattern_init_solid (&pattern, color);
- status = _cairo_surface_paint (surface,
- color == CAIRO_COLOR_TRANSPARENT ?
- CAIRO_OPERATOR_CLEAR : CAIRO_OPERATOR_SOURCE,
- &pattern.base, NULL);
- if (unlikely (status)) {
- cairo_surface_destroy (surface);
- surface = _cairo_surface_create_in_error (status);
+ _cairo_surface_copy_similar_properties (surface, other);
+
+ if (unlikely (surface->status))
+ return surface;
+
+ if (color) {
+ _cairo_pattern_init_solid (&pattern, color);
+ status = _cairo_surface_paint (surface,
+ color == CAIRO_COLOR_TRANSPARENT ?
+ CAIRO_OPERATOR_CLEAR : CAIRO_OPERATOR_SOURCE,
+ &pattern.base, NULL);
+ if (unlikely (status)) {
+ cairo_surface_destroy (surface);
+ surface = _cairo_surface_create_in_error (status);
+ }
}
return surface;
}
+cairo_surface_t *
+_cairo_surface_create_similar_scratch (cairo_surface_t *other,
+ cairo_content_t content,
+ int width,
+ int height)
+{
+ cairo_surface_t *surface;
+
+ if (unlikely (other->status))
+ return _cairo_surface_create_in_error (other->status);
+
+ surface = NULL;
+ if (other->backend->create_similar)
+ surface = other->backend->create_similar (other, content, width, height);
+ if (surface == NULL)
+ surface = cairo_surface_create_similar_image (other,
+ _cairo_format_from_content (content),
+ width, height);
+
+ if (unlikely (surface->status))
+ return surface;
+
+ _cairo_surface_copy_similar_properties (surface, other);
+
+ return surface;
+}
+
+
/**
* cairo_surface_reference:
* @surface: a #cairo_surface_t
@@ -1200,6 +1251,31 @@ _cairo_mime_data_destroy (void *ptr)
}
/**
+ * CAIRO_MIME_TYPE_JBIG2:
+ *
+ * Joint Bi-level Image Experts Group image coding standard (ISO/IEC 11544).
+ *
+ * Since: 1.14
+ **/
+
+/**
+ * CAIRO_MIME_TYPE_JBIG2_GLOBAL:
+ *
+ * Joint Bi-level Image Experts Group image coding standard (ISO/IEC 11544) global segment.
+ *
+ * Since: 1.14
+ **/
+
+/**
+ * CAIRO_MIME_TYPE_JBIG2_GLOBAL_ID:
+ *
+ * An unique identifier shared by a JBIG2 global segment and all JBIG2 images
+ * that depend on the global segment.
+ *
+ * Since: 1.14
+ **/
+
+/**
* CAIRO_MIME_TYPE_JP2:
*
* The Joint Photographic Experts Group (JPEG) 2000 image coding standard (ISO/IEC 15444-1).
@@ -1234,7 +1310,8 @@ _cairo_mime_data_destroy (void *ptr)
/**
* CAIRO_MIME_TYPE_UNIQUE_ID:
*
- * Unique identifier for a surface (cairo specific MIME type).
+ * Unique identifier for a surface (cairo specific MIME type). All surfaces with
+ * the same unique identifier will only be embedded once.
*
* Since: 1.12
**/
@@ -1262,13 +1339,24 @@ _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_UNIQUE_ID, %CAIRO_MIME_TYPE_JBIG2,
+ * %CAIRO_MIME_TYPE_JBIG2_GLOBAL, %CAIRO_MIME_TYPE_JBIG2_GLOBAL_ID.
*
* See corresponding backend surface docs for details about which MIME
* types it can handle. Caution: the associated MIME data will be
* discarded if you draw on the surface afterwards. Use this function
* with care.
*
+ * Even if a backend supports a MIME type, that does not mean cairo
+ * will always be able to use the attached MIME data. For example, if
+ * the backend does not natively support the compositing operation used
+ * to apply the MIME data to the backend. In that case, the MIME data
+ * will be ignored. Therefore, to apply an image in all cases, it is best
+ * to create an image surface which contains the decoded image data and
+ * then attach the MIME data to that. This ensures the image will always
+ * be used while still allowing the MIME data to be used whenever
+ * possible.
+ *
* Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY if a
* slot could not be allocated for the user data.
*
@@ -1346,6 +1434,13 @@ cairo_surface_supports_mime_type (cairo_surface_t *surface,
{
const char **types;
+ if (unlikely (surface->status))
+ return FALSE;
+ if (unlikely (surface->finished)) {
+ _cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
+ return FALSE;
+ }
+
if (surface->backend->get_supported_mime_types) {
types = surface->backend->get_supported_mime_types (surface);
if (types) {
@@ -1617,26 +1712,28 @@ cairo_surface_mark_dirty_rectangle (cairo_surface_t *surface,
slim_hidden_def (cairo_surface_mark_dirty_rectangle);
/**
- * _cairo_surface_set_device_scale:
+ * cairo_surface_set_device_scale:
* @surface: a #cairo_surface_t
- * @sx: a scale factor in the X direction
- * @sy: a scale factor in the Y direction
- *
- * Private function for setting an extra scale factor to affect all
- * drawing to a surface. This is used, for example, when replaying a
- * recording surface to an image fallback intended for an eventual
- * vector-oriented backend. Since the recording surface will record
- * coordinates in one backend space, but the image fallback uses a
- * different backend space, (differing by the fallback resolution
- * scale factors), we need a scale factor correction.
- *
- * Caution: Not all places we use device transform correctly handle
- * both a translate and a scale. An audit would be nice.
+ * @x_scale: a scale factor in the X direction
+ * @y_scale: a scale factor in the Y direction
+ *
+ * Sets a scale that is multiplied to the device coordinates determined
+ * by the CTM when drawing to @surface. One common use for this is to
+ * render to very high resolution display devices at a scale factor, so
+ * that code that assumes 1 pixel will be a certain size will still work.
+ * Setting a transformation via cairo_translate() isn't
+ * sufficient to do this, since functions like
+ * cairo_device_to_user() will expose the hidden scale.
+ *
+ * Note that the scale affects drawing to the surface as well as
+ * using the surface in a source pattern.
+ *
+ * Since: 1.14
**/
void
-_cairo_surface_set_device_scale (cairo_surface_t *surface,
- double sx,
- double sy)
+cairo_surface_set_device_scale (cairo_surface_t *surface,
+ double x_scale,
+ double y_scale)
{
cairo_status_t status;
@@ -1656,8 +1753,8 @@ _cairo_surface_set_device_scale (cairo_surface_t *surface,
return;
}
- surface->device_transform.xx = sx;
- surface->device_transform.yy = sy;
+ surface->device_transform.xx = x_scale;
+ surface->device_transform.yy = y_scale;
surface->device_transform.xy = 0.0;
surface->device_transform.yx = 0.0;
@@ -1668,6 +1765,30 @@ _cairo_surface_set_device_scale (cairo_surface_t *surface,
_cairo_observers_notify (&surface->device_transform_observers, surface);
}
+slim_hidden_def (cairo_surface_set_device_scale);
+
+/**
+ * cairo_surface_get_device_scale:
+ * @surface: a #cairo_surface_t
+ * @x_scale: the scale in the X direction, in device units
+ * @y_scale: the scale in the Y direction, in device units
+ *
+ * This function returns the previous device offset set by
+ * cairo_surface_set_device_scale().
+ *
+ * Since: 1.14
+ **/
+void
+cairo_surface_get_device_scale (cairo_surface_t *surface,
+ double *x_scale,
+ double *y_scale)
+{
+ if (x_scale)
+ *x_scale = surface->device_transform.xx;
+ if (y_scale)
+ *y_scale = surface->device_transform.yy;
+}
+slim_hidden_def (cairo_surface_get_device_scale);
/**
* cairo_surface_set_device_offset:
@@ -2004,6 +2125,8 @@ _cairo_surface_paint (cairo_surface_t *surface,
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 (_cairo_clip_is_all_clipped (clip))
return CAIRO_STATUS_SUCCESS;
@@ -2040,6 +2163,8 @@ _cairo_surface_mask (cairo_surface_t *surface,
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 (_cairo_clip_is_all_clipped (clip))
return CAIRO_STATUS_SUCCESS;
@@ -2097,6 +2222,8 @@ _cairo_surface_fill_stroke (cairo_surface_t *surface,
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 (_cairo_clip_is_all_clipped (clip))
return CAIRO_STATUS_SUCCESS;
@@ -2177,6 +2304,8 @@ _cairo_surface_stroke (cairo_surface_t *surface,
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 (_cairo_clip_is_all_clipped (clip))
return CAIRO_STATUS_SUCCESS;
@@ -2220,6 +2349,8 @@ _cairo_surface_fill (cairo_surface_t *surface,
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 (_cairo_clip_is_all_clipped (clip))
return CAIRO_STATUS_SUCCESS;
@@ -2351,6 +2482,13 @@ _cairo_surface_get_extents (cairo_surface_t *surface,
{
cairo_bool_t bounded;
+ if (unlikely (surface->status))
+ goto zero_extents;
+ if (unlikely (surface->finished)) {
+ _cairo_surface_set_error(surface, CAIRO_STATUS_SURFACE_FINISHED);
+ goto zero_extents;
+ }
+
bounded = FALSE;
if (surface->backend->get_extents != NULL)
bounded = surface->backend->get_extents (surface, extents);
@@ -2359,6 +2497,11 @@ _cairo_surface_get_extents (cairo_surface_t *surface,
_cairo_unbounded_rectangle_init (extents);
return bounded;
+
+zero_extents:
+ extents->x = extents->y = 0;
+ extents->width = extents->height = 0;
+ return TRUE;
}
/**
@@ -2430,11 +2573,12 @@ _cairo_surface_show_text_glyphs (cairo_surface_t *surface,
const cairo_clip_t *clip)
{
cairo_int_status_t status;
- cairo_scaled_font_t *dev_scaled_font = scaled_font;
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 (num_glyphs == 0 && utf8_len == 0)
return CAIRO_STATUS_SUCCESS;
@@ -2453,25 +2597,6 @@ _cairo_surface_show_text_glyphs (cairo_surface_t *surface,
if (unlikely (status))
return status;
- if (_cairo_surface_has_device_transform (surface) &&
- ! _cairo_matrix_is_integer_translation (&surface->device_transform, NULL, NULL))
- {
- cairo_font_options_t font_options;
- cairo_matrix_t dev_ctm, font_matrix;
-
- cairo_scaled_font_get_font_matrix (scaled_font, &font_matrix);
- cairo_scaled_font_get_ctm (scaled_font, &dev_ctm);
- cairo_matrix_multiply (&dev_ctm, &dev_ctm, &surface->device_transform);
- cairo_scaled_font_get_font_options (scaled_font, &font_options);
- dev_scaled_font = cairo_scaled_font_create (cairo_scaled_font_get_font_face (scaled_font),
- &font_matrix,
- &dev_ctm,
- &font_options);
- }
- status = cairo_scaled_font_status (dev_scaled_font);
- if (unlikely (status))
- return _cairo_surface_set_error (surface, status);
-
status = CAIRO_INT_STATUS_UNSUPPORTED;
/* The logic here is duplicated in _cairo_analysis_surface show_glyphs and
@@ -2485,7 +2610,7 @@ _cairo_surface_show_text_glyphs (cairo_surface_t *surface,
utf8, utf8_len,
glyphs, num_glyphs,
clusters, num_clusters, cluster_flags,
- dev_scaled_font,
+ scaled_font,
clip);
}
if (status == CAIRO_INT_STATUS_UNSUPPORTED &&
@@ -2494,7 +2619,7 @@ _cairo_surface_show_text_glyphs (cairo_surface_t *surface,
status = surface->backend->show_glyphs (surface, op,
source,
glyphs, num_glyphs,
- dev_scaled_font,
+ scaled_font,
clip);
}
} else {
@@ -2503,7 +2628,7 @@ _cairo_surface_show_text_glyphs (cairo_surface_t *surface,
status = surface->backend->show_glyphs (surface, op,
source,
glyphs, num_glyphs,
- dev_scaled_font,
+ scaled_font,
clip);
} else if (surface->backend->show_text_glyphs != NULL) {
/* Intentionally only try show_text_glyphs method for show_glyphs
@@ -2519,14 +2644,11 @@ _cairo_surface_show_text_glyphs (cairo_surface_t *surface,
utf8, utf8_len,
glyphs, num_glyphs,
clusters, num_clusters, cluster_flags,
- dev_scaled_font,
+ scaled_font,
clip);
}
}
- if (dev_scaled_font != scaled_font)
- cairo_scaled_font_destroy (dev_scaled_font);
-
if (status != CAIRO_INT_STATUS_NOTHING_TO_DO) {
surface->is_clear = FALSE;
surface->serial++;
@@ -2557,6 +2679,16 @@ _cairo_surface_set_resolution (cairo_surface_t *surface,
surface->y_resolution = y_res;
}
+/**
+ * _cairo_surface_create_in_error:
+ * @status: the error status
+ *
+ * Return an appropriate static error surface for the error status.
+ * On error, surface creation functions should always return a surface
+ * created with _cairo_surface_create_in_error() instead of a new surface
+ * in an error state. This simplifies internal code as no refcounting has
+ * to be done.
+ **/
cairo_surface_t *
_cairo_surface_create_in_error (cairo_status_t status)
{
@@ -2617,6 +2749,7 @@ _cairo_surface_create_in_error (cairo_status_t status)
case CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED:
case CAIRO_STATUS_INVALID_MESH_CONSTRUCTION:
case CAIRO_STATUS_DEVICE_FINISHED:
+ case CAIRO_STATUS_JBIG2_GLOBAL_MISSING:
default:
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return (cairo_surface_t *) &_cairo_surface_nil;
diff --git a/src/cairo-svg-surface-private.h b/src/cairo-svg-surface-private.h
index ddbf464b1..ddbf464b1 100755..100644
--- a/src/cairo-svg-surface-private.h
+++ b/src/cairo-svg-surface-private.h
diff --git a/src/cairo-svg-surface.c b/src/cairo-svg-surface.c
index e2d99499d..04bb7a093 100755..100644
--- a/src/cairo-svg-surface.c
+++ b/src/cairo-svg-surface.c
@@ -56,6 +56,7 @@
#include "cairo-paginated-private.h"
#include "cairo-scaled-font-subsets-private.h"
#include "cairo-surface-clipper-private.h"
+#include "cairo-surface-snapshot-inline.h"
#include "cairo-svg-surface-private.h"
/**
@@ -810,7 +811,7 @@ _cairo_svg_document_emit_bitmap_glyph_data (cairo_svg_document_t *document,
_cairo_output_stream_printf (document->xml_node_glyphs, "<g");
_cairo_svg_surface_emit_transform (document->xml_node_glyphs, " transform",
&image->base.device_transform_inverse, NULL);
- _cairo_output_stream_printf (document->xml_node_glyphs, ">/n");
+ _cairo_output_stream_printf (document->xml_node_glyphs, ">\n");
for (y = 0, row = image->data, rows = image->height; rows; row += image->stride, rows--, y++) {
for (x = 0, byte = row, cols = (image->width + 7) / 8; cols; byte++, cols--) {
@@ -1120,6 +1121,9 @@ _cairo_surface_base64_encode_jpeg (cairo_surface_t *surface,
if (unlikely (status))
return status;
+ if (image_info.num_components == 4)
+ return CAIRO_INT_STATUS_UNSUPPORTED;
+
_cairo_output_stream_printf (output, "data:image/jpeg;base64,");
info.output = output;
@@ -1493,6 +1497,17 @@ _cairo_svg_surface_emit_recording_surface (cairo_svg_document_t *document,
document, NULL);
}
+static cairo_recording_surface_t *
+to_recording_surface (const cairo_surface_pattern_t *pattern)
+{
+ cairo_surface_t *surface = pattern->surface;
+ if (_cairo_surface_is_paginated (surface))
+ surface = _cairo_paginated_surface_get_recording (surface);
+ if (_cairo_surface_is_snapshot (surface))
+ surface = _cairo_surface_snapshot_get_target (surface);
+ return (cairo_recording_surface_t *) surface;
+}
+
static cairo_status_t
_cairo_svg_surface_emit_composite_recording_pattern (cairo_output_stream_t *output,
cairo_svg_surface_t *surface,
@@ -1512,7 +1527,7 @@ _cairo_svg_surface_emit_composite_recording_pattern (cairo_output_stream_t *outp
/* cairo_pattern_set_matrix ensures the matrix is invertible */
assert (status == CAIRO_STATUS_SUCCESS);
- recording_surface = (cairo_recording_surface_t *) pattern->surface;
+ recording_surface = to_recording_surface (pattern);
status = _cairo_svg_surface_emit_recording_surface (document, recording_surface);
if (unlikely (status))
return status;
@@ -1559,7 +1574,7 @@ _cairo_svg_surface_emit_composite_pattern (cairo_output_stream_t *output,
const char *extra_attributes)
{
- if (_cairo_surface_is_recording (pattern->surface)) {
+ if (pattern->surface->type == CAIRO_SURFACE_TYPE_RECORDING) {
return _cairo_svg_surface_emit_composite_recording_pattern (output, surface,
op, pattern,
pattern_id,
diff --git a/src/cairo-svg.h b/src/cairo-svg.h
index 592c645f6..592c645f6 100755..100644
--- a/src/cairo-svg.h
+++ b/src/cairo-svg.h
diff --git a/src/cairo-tee-surface-private.h b/src/cairo-tee-surface-private.h
index a83cfc959..a83cfc959 100755..100644
--- a/src/cairo-tee-surface-private.h
+++ b/src/cairo-tee-surface-private.h
diff --git a/src/cairo-tee-surface.c b/src/cairo-tee-surface.c
index 294e5f162..294e5f162 100755..100644
--- a/src/cairo-tee-surface.c
+++ b/src/cairo-tee-surface.c
diff --git a/src/cairo-tee.h b/src/cairo-tee.h
index 9125a3a4a..9125a3a4a 100755..100644
--- a/src/cairo-tee.h
+++ b/src/cairo-tee.h
diff --git a/src/cairo-tg-allocator-private.h b/src/cairo-tg-allocator-private.h
deleted file mode 100755
index f62b2e211..000000000
--- a/src/cairo-tg-allocator-private.h
+++ /dev/null
@@ -1,134 +0,0 @@
-#ifndef CAIRO_TG_ALLOCATOR_H
-#define CAIRO_TG_ALLOCATOR_H
-
-#include "cairoint.h"
-
-typedef struct _cairo_tg_mem_chunk cairo_tg_mem_chunk_t;
-
-struct _cairo_tg_mem_chunk
-{
- cairo_tg_mem_chunk_t *next;
- uint8_t *buffer;
- int chunk_size;
- int remaining_size;
-};
-
-typedef struct _cairo_tg_mono_allocator
-{
- cairo_tg_mem_chunk_t *chunk_head;
- int chunk_size;
-} cairo_tg_mono_allocator_t;
-
-static inline cairo_tg_mem_chunk_t *
-_cairo_tg_mem_chunk_create (int chunk_size)
-{
- cairo_tg_mem_chunk_t *chunk;
-
- chunk = (cairo_tg_mem_chunk_t *) malloc (sizeof (cairo_tg_mem_chunk_t) + chunk_size);
-
- if (chunk)
- {
- chunk->next = NULL;
- chunk->buffer = (uint8_t *) chunk + sizeof (cairo_tg_mem_chunk_t);
- chunk->chunk_size = chunk_size;
- chunk->remaining_size = chunk_size;
- }
-
- return chunk;
-}
-
-static inline void
-_cairo_tg_mem_chunk_destroy (cairo_tg_mem_chunk_t *chunk)
-{
- free (chunk);
-}
-
-static inline cairo_status_t
-_cairo_tg_mono_allocator_init (cairo_tg_mono_allocator_t *allocator, int chunk_size)
-{
- cairo_tg_mem_chunk_t *chunk;
-
- chunk = _cairo_tg_mem_chunk_create (chunk_size);
-
- if (! chunk)
- return CAIRO_STATUS_NO_MEMORY;
-
- allocator->chunk_size = chunk_size;
- allocator->chunk_head = chunk;
-
- return CAIRO_STATUS_SUCCESS;
-}
-
-static inline void
-_cairo_tg_mono_allocator_fini (cairo_tg_mono_allocator_t *allocator)
-{
- cairo_tg_mem_chunk_t *chunk = allocator->chunk_head, *next;
-
- while (chunk != NULL)
- {
- next = chunk->next;
- _cairo_tg_mem_chunk_destroy (chunk);
- chunk = next;
- }
-
- allocator->chunk_head = NULL;
-}
-
-static inline void *
-_cairo_tg_mono_allocator_alloc (cairo_tg_mono_allocator_t *allocator, int size)
-{
- cairo_tg_mem_chunk_t *chunk = allocator->chunk_head;
- int chunk_size;
-
- if (chunk && chunk->remaining_size >= size)
- {
- void *buffer = (void*)(chunk->buffer + chunk->chunk_size - chunk->remaining_size);
- chunk->remaining_size -= size;
- return buffer;
- }
-
- chunk_size = MAX (allocator->chunk_size, size);
-
- chunk = _cairo_tg_mem_chunk_create (chunk_size);
-
- if (chunk == NULL)
- return NULL;
-
- chunk->next = allocator->chunk_head;
- chunk->buffer = (uint8_t *) chunk + sizeof (cairo_tg_mem_chunk_t);
- chunk->chunk_size = chunk_size;
- chunk->remaining_size = chunk_size - size;
-
- allocator->chunk_head = chunk;
-
- return (void *) chunk->buffer;
-}
-
-static inline void
-_cairo_tg_mono_allocator_reset (cairo_tg_mono_allocator_t *allocator)
-{
- cairo_tg_mem_chunk_t *chunk = allocator->chunk_head, *next;
- cairo_tg_mem_chunk_t *stock = NULL;
-
- while (chunk != NULL)
- {
- next = chunk->next;
-
- if (stock)
- _cairo_tg_mem_chunk_destroy (chunk);
- else
- stock = chunk;
-
- chunk = next;
- }
-
- if (stock)
- {
- stock->next = NULL;
- stock->remaining_size = stock->chunk_size;
- }
-
- allocator->chunk_head = stock;
-}
-
-#endif /* CAIRO_TG_ALLOCATOR_H */
diff --git a/src/cairo-tg-composite-extents-private.h b/src/cairo-tg-composite-extents-private.h
deleted file mode 100755
index 22de139bf..000000000
--- a/src/cairo-tg-composite-extents-private.h
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright © 2012 SCore Corporation
- *
- * 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.
- *
- * Author: Taekyun Kim (podain77@gmail.com)
- */
-
-#ifndef CAIRO_TG_COMPOSITE_EXTENTS_PRIVATE_H
-#define CAIRO_TG_COMPOSITE_EXTENTS_PRIVATE_H
-
-#include "cairoint.h"
-#include "cairo-pattern-private.h"
-#include "cairo-clip-private.h"
-#include "cairo-surface-private.h"
-
-static inline void
-_cairo_tg_approximate_paint_extents (cairo_rectangle_int_t *extents,
- cairo_operator_t op,
- const cairo_pattern_t *source,
- const cairo_clip_t *clip)
-{
- *extents = * (_cairo_clip_get_extents (clip));
-}
-
-static inline void
-_cairo_tg_approximate_mask_extents (cairo_rectangle_int_t *extents,
- cairo_operator_t op,
- const cairo_pattern_t *source,
- const cairo_pattern_t *mask,
- const cairo_clip_t *clip)
-{
- *extents = * (_cairo_clip_get_extents (clip));
-}
-
-static inline void
-_cairo_tg_approximate_stroke_extents (cairo_rectangle_int_t *extents,
- 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_rectangle_int_t rect;
-
- *extents = * (_cairo_clip_get_extents (clip));
-
- if (_cairo_operator_bounded_by_either (op))
- {
- _cairo_path_fixed_approximate_stroke_extents (path, style, ctm, &rect);
- _cairo_rectangle_intersect (extents, &rect);
- }
-}
-
-static inline void
-_cairo_tg_approximate_fill_extents (cairo_rectangle_int_t *extents,
- 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_rectangle_int_t rect;
-
- *extents = * (_cairo_clip_get_extents (clip));
-
- if (_cairo_operator_bounded_by_either (op))
- {
- _cairo_path_fixed_approximate_fill_extents (path, &rect);
- _cairo_rectangle_intersect (extents, &rect);
- }
-}
-
-static inline void
-_cairo_tg_approximate_glyphs_extents (cairo_rectangle_int_t *extents,
- cairo_operator_t op,
- const cairo_pattern_t *source,
- cairo_glyph_t *glyphs,
- int num_glyphs,
- cairo_scaled_font_t *scaled_font,
- const cairo_clip_t *clip)
-{
- cairo_rectangle_int_t rect;
-
- *extents = * (_cairo_clip_get_extents (clip));
-
- if (_cairo_operator_bounded_by_either (op))
- {
- if (_cairo_scaled_font_glyph_approximate_extents (scaled_font, glyphs, num_glyphs, &rect))
- _cairo_rectangle_intersect (extents, &rect);
- }
-}
-
-#endif /* CAIRO_TG_COMPOSITE_EXTENTS_PRIVATE_H */
diff --git a/src/cairo-tg-journal-private.h b/src/cairo-tg-journal-private.h
deleted file mode 100755
index 694f77cfd..000000000
--- a/src/cairo-tg-journal-private.h
+++ /dev/null
@@ -1,229 +0,0 @@
-/*
- * Copyright © 2012 SCore Corporation
- *
- * 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.
- *
- * Author: Taekyun Kim (podain77@gmail.com)
- */
-
-#ifndef CAIRO_TG_JOURNAL_PRIVATE_H
-#define CAIRO_TG_JOURNAL_PRIVATE_H
-
-#include "cairoint.h"
-#include "cairo-pattern-private.h"
-#include "cairo-clip-private.h"
-#include "cairo-surface-private.h"
-#include "cairo-list-private.h"
-#include "cairo-list-inline.h"
-#include "cairo-tg-allocator-private.h"
-#include "cairo-mutex-private.h"
-
-typedef enum
-{
- CAIRO_TG_JOURNAL_ENTRY_PAINT,
- CAIRO_TG_JOURNAL_ENTRY_MASK,
- CAIRO_TG_JOURNAL_ENTRY_FILL,
- CAIRO_TG_JOURNAL_ENTRY_STROKE,
- CAIRO_TG_JOURNAL_ENTRY_GLYPHS,
-} cairo_tg_journal_entry_type_t;
-
-typedef struct _cairo_tg_journal_entry cairo_tg_journal_entry_t;
-
-struct _cairo_tg_journal_entry
-{
- cairo_list_t link;
- cairo_tg_journal_entry_type_t type;
-
- cairo_rectangle_int_t extents;
-
- cairo_operator_t op;
- cairo_pattern_union_t source;
- cairo_clip_t *clip;
-};
-
-typedef struct _cairo_tg_journal_entry_paint
-{
- cairo_tg_journal_entry_t base;
-} cairo_tg_journal_entry_paint_t;
-
-typedef struct _cairo_tg_journal_entry_mask
-{
- cairo_tg_journal_entry_t base;
-
- cairo_pattern_union_t mask;
-} cairo_tg_journal_entry_mask_t;
-
-typedef struct _cairo_tg_journal_entry_stroke
-{
- cairo_tg_journal_entry_t base;
-
- cairo_path_fixed_t path;
- cairo_stroke_style_t style;
- cairo_matrix_t ctm;
- cairo_matrix_t ctm_inverse;
- double tolerance;
- cairo_antialias_t antialias;
-} cairo_tg_journal_entry_stroke_t;
-
-typedef struct _cairo_tg_journal_entry_fill
-{
- cairo_tg_journal_entry_t base;
-
- cairo_path_fixed_t path;
- cairo_fill_rule_t fill_rule;
- double tolerance;
- cairo_antialias_t antialias;
-} cairo_tg_journal_entry_fill_t;
-
-typedef struct _cairo_tg_journal_entry_glyphs
-{
- cairo_tg_journal_entry_t base;
-
- cairo_glyph_t *glyphs;
- int num_glyphs;
- cairo_scaled_font_t *scaled_font;
-} cairo_tg_journal_entry_glyphs_t;
-
-typedef struct _cairo_tg_journal
-{
- cairo_rectangle_int_t extents;
- cairo_list_t entry_list;
- int num_entries;
- cairo_tg_mono_allocator_t allocator;
- cairo_mutex_t mutex;
-} cairo_tg_journal_t;
-
-typedef struct _cairo_tg_journal_replay_funcs
-{
- cairo_int_status_t
- (*paint) (void *closure,
- cairo_operator_t op,
- const cairo_pattern_t *source,
- const cairo_clip_t *clip);
-
- cairo_int_status_t
- (*mask) (void *closure,
- cairo_operator_t op,
- const cairo_pattern_t *source,
- const cairo_pattern_t *mask,
- const cairo_clip_t *clip);
-
- cairo_int_status_t
- (*stroke) (void *closure,
- 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_int_status_t
- (*fill) (void *closure,
- 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_int_status_t
- (*glyphs) (void *closure,
- cairo_operator_t op,
- const cairo_pattern_t *source,
- cairo_glyph_t *glyphs,
- int num_glyphs,
- cairo_scaled_font_t *scaled_font,
- const cairo_clip_t *clip);
-} cairo_tg_journal_replay_funcs_t;
-
-cairo_int_status_t
-_cairo_tg_journal_init (cairo_tg_journal_t *journal);
-
-void
-_cairo_tg_journal_fini (cairo_tg_journal_t *journal);
-
-void
-_cairo_tg_journal_lock (cairo_tg_journal_t *journal);
-
-void
-_cairo_tg_journal_unlock (cairo_tg_journal_t *journal);
-
-cairo_int_status_t
-_cairo_tg_journal_log_paint (cairo_tg_journal_t *journal,
- cairo_operator_t op,
- const cairo_pattern_t *source,
- const cairo_clip_t *clip);
-
-cairo_int_status_t
-_cairo_tg_journal_log_mask (cairo_tg_journal_t *journal,
- cairo_operator_t op,
- const cairo_pattern_t *source,
- const cairo_pattern_t *mask,
- const cairo_clip_t *clip);
-
-cairo_int_status_t
-_cairo_tg_journal_log_stroke (cairo_tg_journal_t *journal,
- 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_int_status_t
-_cairo_tg_journal_log_fill (cairo_tg_journal_t *journal,
- 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_int_status_t
-_cairo_tg_journal_log_glyphs (cairo_tg_journal_t *journal,
- cairo_operator_t op,
- const cairo_pattern_t *source,
- cairo_glyph_t *glyphs,
- int num_glyphs,
- cairo_scaled_font_t *scaled_font,
- const cairo_clip_t *clip);
-
-void
-_cairo_tg_journal_clear (cairo_tg_journal_t *journal);
-
-cairo_int_status_t
-_cairo_tg_journal_replay (const cairo_tg_journal_t *journal,
- void *closure,
- const cairo_rectangle_int_t *extents,
- const cairo_tg_journal_replay_funcs_t *funcs);
-
-#endif /* CAIRO_TG_JOURNAL_PRIVATE_H */
diff --git a/src/cairo-tg-journal.c b/src/cairo-tg-journal.c
deleted file mode 100755
index 1d3902134..000000000
--- a/src/cairo-tg-journal.c
+++ /dev/null
@@ -1,520 +0,0 @@
-/*
- * Copyright © 2012 SCore Corporation
- *
- * 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.
- *
- * Author: Taekyun Kim (podain77@gmail.com)
- */
-
-#include "cairo-tg.h"
-#include "cairo-tg-private.h"
-#include "cairo-tg-journal-private.h"
-#include "cairo-tg-allocator-private.h"
-#include "cairo-tg-composite-extents-private.h"
-
-static inline cairo_int_status_t
-_cairo_tg_journal_pattern_snapshot (cairo_pattern_t *dst,
- const cairo_pattern_t *src)
-{
- return _cairo_pattern_init_snapshot (dst, src);
-}
-
-/* Allocator for various types of journal entries. */
-static cairo_tg_journal_entry_t *
-_cairo_tg_journal_entry_alloc (cairo_tg_mono_allocator_t *allocator,
- cairo_tg_journal_entry_type_t type)
-{
- cairo_tg_journal_entry_t *entry = NULL;
-
- switch (type)
- {
- case CAIRO_TG_JOURNAL_ENTRY_PAINT:
- entry = _cairo_tg_mono_allocator_alloc (allocator,
- sizeof (cairo_tg_journal_entry_paint_t));
- break;
- case CAIRO_TG_JOURNAL_ENTRY_MASK:
- entry = _cairo_tg_mono_allocator_alloc (allocator,
- sizeof (cairo_tg_journal_entry_mask_t));
- break;
- case CAIRO_TG_JOURNAL_ENTRY_STROKE:
- entry = _cairo_tg_mono_allocator_alloc (allocator,
- sizeof (cairo_tg_journal_entry_stroke_t));
- break;
- case CAIRO_TG_JOURNAL_ENTRY_FILL:
- entry = _cairo_tg_mono_allocator_alloc (allocator,
- sizeof (cairo_tg_journal_entry_fill_t));
- break;
- case CAIRO_TG_JOURNAL_ENTRY_GLYPHS:
- entry = _cairo_tg_mono_allocator_alloc (allocator,
- sizeof (cairo_tg_journal_entry_glyphs_t));
- break;
- default:
- ASSERT_NOT_REACHED;
- return NULL;
- }
-
- /* One should not change the type of an entry.
- * It is determined at the moment of allocation. */
- entry->type = type;
-
- return entry;
-}
-
-static void
-_cairo_tg_journal_entry_fini (cairo_tg_journal_entry_t *entry)
-{
- /* common part. */
- _cairo_pattern_fini (&entry->source.base);
-
- if (entry->clip)
- _cairo_clip_destroy (entry->clip);
-
- /* For each entry types... */
- switch (entry->type)
- {
- case CAIRO_TG_JOURNAL_ENTRY_PAINT:
- break;
- case CAIRO_TG_JOURNAL_ENTRY_MASK:
- {
- cairo_tg_journal_entry_mask_t *entry_mask =
- (cairo_tg_journal_entry_mask_t *) entry;
-
- _cairo_pattern_fini (&entry_mask->mask.base);
- }
- break;
- case CAIRO_TG_JOURNAL_ENTRY_STROKE:
- {
- cairo_tg_journal_entry_stroke_t *entry_stroke =
- (cairo_tg_journal_entry_stroke_t *) entry;
-
- _cairo_path_fixed_fini (&entry_stroke->path);
- _cairo_stroke_style_fini (&entry_stroke->style);
- }
- break;
- case CAIRO_TG_JOURNAL_ENTRY_FILL:
- {
- cairo_tg_journal_entry_fill_t *entry_fill =
- (cairo_tg_journal_entry_fill_t *) entry;
-
- _cairo_path_fixed_fini (&entry_fill->path);
- }
- break;
- case CAIRO_TG_JOURNAL_ENTRY_GLYPHS:
- {
- cairo_tg_journal_entry_glyphs_t *entry_glyphs =
- (cairo_tg_journal_entry_glyphs_t *) entry;
-
- free (entry_glyphs->glyphs);
- cairo_scaled_font_destroy (entry_glyphs->scaled_font);
- }
- break;
- default:
- ASSERT_NOT_REACHED;
- }
-}
-
-cairo_int_status_t
-_cairo_tg_journal_init (cairo_tg_journal_t *journal)
-{
- cairo_int_status_t status;
-
- CAIRO_MUTEX_INIT (journal->mutex);
- journal->num_entries = 0;
- cairo_list_init (&journal->entry_list);
- journal->extents = _cairo_empty_rectangle;
-
- status = _cairo_tg_mono_allocator_init (&journal->allocator, 4096 -
- sizeof (cairo_tg_mem_chunk_t));
-
- return status;
-}
-
-void
-_cairo_tg_journal_fini (cairo_tg_journal_t *journal)
-{
- cairo_tg_journal_entry_t *entry;
- cairo_tg_journal_entry_t *next;
-
- CAIRO_MUTEX_FINI (journal->mutex);
- cairo_list_foreach_entry_safe (entry, next, cairo_tg_journal_entry_t,
- &journal->entry_list, link)
- {
- _cairo_tg_journal_entry_fini (entry);
- }
-
- _cairo_tg_mono_allocator_fini (&journal->allocator);
-}
-
-void
-_cairo_tg_journal_lock (cairo_tg_journal_t *journal)
-{
- CAIRO_MUTEX_LOCK (journal->mutex);
-}
-
-void
-_cairo_tg_journal_unlock (cairo_tg_journal_t *journal)
-{
- CAIRO_MUTEX_UNLOCK (journal->mutex);
-}
-
-cairo_int_status_t
-_cairo_tg_journal_log_paint (cairo_tg_journal_t *journal,
- cairo_operator_t op,
- const cairo_pattern_t *source,
- const cairo_clip_t *clip)
-{
- cairo_int_status_t status;
- cairo_tg_journal_entry_paint_t *entry;
-
- entry = (cairo_tg_journal_entry_paint_t *)
- _cairo_tg_journal_entry_alloc (&journal->allocator, CAIRO_TG_JOURNAL_ENTRY_PAINT);
-
- if (unlikely (entry == NULL))
- return CAIRO_INT_STATUS_NO_MEMORY;
-
- status = _cairo_tg_journal_pattern_snapshot (&entry->base.source.base, source);
-
- if (unlikely (status))
- return status;
-
- entry->base.op = op;
- entry->base.clip = _cairo_clip_copy (clip);
- _cairo_tg_approximate_paint_extents (&entry->base.extents, op, source, clip);
- _cairo_rectangle_union (&journal->extents, &entry->base.extents);
-
- cairo_list_add_tail (&entry->base.link, &journal->entry_list);
- journal->num_entries++;
-
- return CAIRO_INT_STATUS_SUCCESS;
-}
-
-cairo_int_status_t
-_cairo_tg_journal_log_mask (cairo_tg_journal_t *journal,
- cairo_operator_t op,
- const cairo_pattern_t *source,
- const cairo_pattern_t *mask,
- const cairo_clip_t *clip)
-{
- cairo_int_status_t status;
- cairo_tg_journal_entry_mask_t *entry;
-
- entry = (cairo_tg_journal_entry_mask_t *)
- _cairo_tg_journal_entry_alloc (&journal->allocator, CAIRO_TG_JOURNAL_ENTRY_MASK);
-
- if (unlikely (entry == NULL))
- return CAIRO_INT_STATUS_NO_MEMORY;
-
- status = _cairo_tg_journal_pattern_snapshot (&entry->base.source.base, source);
-
- if (unlikely (status))
- return status;
-
- status = _cairo_tg_journal_pattern_snapshot (&entry->mask.base, mask);
-
- if (unlikely (status))
- {
- _cairo_pattern_fini (&entry->base.source.base);
- return status;
- }
-
- entry->base.op = op;
- entry->base.clip = _cairo_clip_copy (clip);
- _cairo_tg_approximate_mask_extents (&entry->base.extents, op, source, mask, clip);
- _cairo_rectangle_union (&journal->extents, &entry->base.extents);
-
- cairo_list_add_tail (&entry->base.link, &journal->entry_list);
- journal->num_entries++;
-
- return CAIRO_INT_STATUS_SUCCESS;
-}
-
-cairo_int_status_t
-_cairo_tg_journal_log_stroke (cairo_tg_journal_t *journal,
- 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_int_status_t status;
- cairo_tg_journal_entry_stroke_t *entry;
-
- entry = (cairo_tg_journal_entry_stroke_t *)
- _cairo_tg_journal_entry_alloc (&journal->allocator, CAIRO_TG_JOURNAL_ENTRY_STROKE);
-
- if (unlikely (entry == NULL))
- return CAIRO_INT_STATUS_NO_MEMORY;
-
- status = _cairo_tg_journal_pattern_snapshot (&entry->base.source.base, source);
-
- if (unlikely (status))
- return status;
-
- status = _cairo_path_fixed_init_copy (&entry->path, path);
-
- if (unlikely (status))
- {
- _cairo_pattern_fini (&entry->base.source.base);
- return status;
- }
-
- status = _cairo_stroke_style_init_copy (&entry->style, style);
-
- if (unlikely (status))
- {
- _cairo_path_fixed_fini (&entry->path);
- _cairo_pattern_fini (&entry->base.source.base);
- return status;
- }
-
- entry->base.op = op;
- entry->base.clip = _cairo_clip_copy (clip);
- entry->ctm = *ctm;
- entry->ctm_inverse = *ctm_inverse;
- entry->tolerance = tolerance;
- entry->antialias = antialias;
- _cairo_tg_approximate_stroke_extents (&entry->base.extents, op, source,
- path, style, ctm, ctm_inverse,
- tolerance, antialias, clip);
- _cairo_rectangle_union (&journal->extents, &entry->base.extents);
-
- cairo_list_add_tail (&entry->base.link, &journal->entry_list);
- journal->num_entries++;
-
- return CAIRO_INT_STATUS_SUCCESS;
-}
-
-cairo_int_status_t
-_cairo_tg_journal_log_fill (cairo_tg_journal_t *journal,
- 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_int_status_t status;
- cairo_tg_journal_entry_fill_t *entry;
-
- entry = (cairo_tg_journal_entry_fill_t *)
- _cairo_tg_journal_entry_alloc (&journal->allocator, CAIRO_TG_JOURNAL_ENTRY_FILL);
-
- if (unlikely (entry == NULL))
- return CAIRO_INT_STATUS_NO_MEMORY;
-
- status = _cairo_tg_journal_pattern_snapshot (&entry->base.source.base, source);
-
- if (unlikely (status))
- return status;
-
- status = _cairo_path_fixed_init_copy (&entry->path, path);
-
- if (unlikely (status))
- {
- _cairo_pattern_fini (&entry->base.source.base);
- return status;
- }
-
- entry->base.op = op;
- entry->base.clip = _cairo_clip_copy (clip);
- entry->fill_rule = fill_rule;
- entry->tolerance = tolerance;
- entry->antialias = antialias;
- _cairo_tg_approximate_fill_extents (&entry->base.extents, op, source,
- path, fill_rule, tolerance, antialias, clip);
- _cairo_rectangle_union (&journal->extents, &entry->base.extents);
-
- cairo_list_add_tail (&entry->base.link, &journal->entry_list);
- journal->num_entries++;
-
- return CAIRO_INT_STATUS_SUCCESS;
-}
-
-cairo_int_status_t
-_cairo_tg_journal_log_glyphs (cairo_tg_journal_t *journal,
- cairo_operator_t op,
- const cairo_pattern_t *source,
- cairo_glyph_t *glyphs,
- int num_glyphs,
- cairo_scaled_font_t *scaled_font,
- const cairo_clip_t *clip)
-{
- cairo_int_status_t status;
- cairo_tg_journal_entry_glyphs_t *entry;
-
- entry = (cairo_tg_journal_entry_glyphs_t *)
- _cairo_tg_journal_entry_alloc (&journal->allocator, CAIRO_TG_JOURNAL_ENTRY_GLYPHS);
-
- if (unlikely (entry == NULL))
- return CAIRO_INT_STATUS_NO_MEMORY;
-
- status = _cairo_tg_journal_pattern_snapshot (&entry->base.source.base, source);
-
- if (unlikely (status))
- return status;
-
- entry->scaled_font = cairo_scaled_font_reference (scaled_font);
-
- if (unlikely (entry->scaled_font == NULL))
- {
- _cairo_pattern_fini (&entry->base.source.base);
- return CAIRO_INT_STATUS_NO_MEMORY;
- }
-
- if (num_glyphs)
- {
- entry->glyphs = malloc (sizeof (cairo_glyph_t) * num_glyphs);
-
- if (unlikely (entry->glyphs == NULL))
- {
- cairo_scaled_font_destroy (entry->scaled_font);
- _cairo_pattern_fini (&entry->base.source.base);
- return CAIRO_INT_STATUS_NO_MEMORY;
- }
-
- memcpy (entry->glyphs, glyphs, sizeof (cairo_glyph_t) * num_glyphs);
- }
- else
- {
- entry->glyphs = NULL;
- }
-
- entry->num_glyphs = num_glyphs;
- entry->base.op = op;
- entry->base.clip = _cairo_clip_copy (clip);
- _cairo_tg_approximate_glyphs_extents (&entry->base.extents, op, source,
- glyphs, num_glyphs, scaled_font, clip);
- _cairo_rectangle_union (&journal->extents, &entry->base.extents);
-
- cairo_list_add_tail (&entry->base.link, &journal->entry_list);
- journal->num_entries++;
-
- return CAIRO_INT_STATUS_SUCCESS;
-}
-
-void
-_cairo_tg_journal_clear (cairo_tg_journal_t *journal)
-{
- cairo_tg_journal_entry_t *entry;
- cairo_tg_journal_entry_t *next;
-
- cairo_list_foreach_entry_safe (entry, next, cairo_tg_journal_entry_t,
- &journal->entry_list, link)
- {
- _cairo_tg_journal_entry_fini (entry);
- }
-
- journal->num_entries = 0;
- cairo_list_init (&journal->entry_list);
- _cairo_tg_mono_allocator_reset(&journal->allocator);
- journal->extents = _cairo_empty_rectangle;
-}
-
-cairo_int_status_t
-_cairo_tg_journal_replay (const cairo_tg_journal_t *journal,
- void *closure,
- const cairo_rectangle_int_t *extents,
- const cairo_tg_journal_replay_funcs_t *funcs)
-{
- const cairo_tg_journal_entry_t *entry;
- const cairo_tg_journal_entry_t *next;
- cairo_int_status_t status;
-
- cairo_list_foreach_entry_safe (entry, next, cairo_tg_journal_entry_t,
- &journal->entry_list, link)
- {
- if (extents && ! _cairo_rectangle_intersects (extents, &entry->extents))
- {
- continue;
- }
-
- switch (entry->type)
- {
- case CAIRO_TG_JOURNAL_ENTRY_PAINT:
- {
- cairo_tg_journal_entry_paint_t *e =
- (cairo_tg_journal_entry_paint_t *) entry;
-
- status = funcs->paint (closure, e->base.op, &e->base.source.base,
- e->base.clip);
- }
- break;
- case CAIRO_TG_JOURNAL_ENTRY_MASK:
- {
- cairo_tg_journal_entry_mask_t *e =
- (cairo_tg_journal_entry_mask_t *) entry;
-
- status = funcs->mask (closure, e->base.op, &e->base.source.base,
- &e->mask.base, e->base.clip);
- }
- break;
- case CAIRO_TG_JOURNAL_ENTRY_STROKE:
- {
- cairo_tg_journal_entry_stroke_t *e =
- (cairo_tg_journal_entry_stroke_t *) entry;
-
- status = funcs->stroke (closure, e->base.op, &e->base.source.base,
- &e->path, &e->style, &e->ctm, &e->ctm_inverse,
- e->tolerance, e->antialias, e->base.clip);
- }
- break;
- case CAIRO_TG_JOURNAL_ENTRY_FILL:
- {
- cairo_tg_journal_entry_fill_t *e =
- (cairo_tg_journal_entry_fill_t *) entry;
-
- status = funcs->fill (closure, e->base.op, &e->base.source.base,
- &e->path, e->fill_rule,
- e->tolerance, e->antialias, e->base.clip);
- }
- break;
- case CAIRO_TG_JOURNAL_ENTRY_GLYPHS:
- {
- cairo_tg_journal_entry_glyphs_t *e =
- (cairo_tg_journal_entry_glyphs_t *) entry;
-
- status = funcs->glyphs (closure, e->base.op, &e->base.source.base,
- e->glyphs, e->num_glyphs,
- e->scaled_font, e->base.clip);
- }
- break;
- default:
- ASSERT_NOT_REACHED;
- break;
- }
-
- if (unlikely (status) && status != CAIRO_INT_STATUS_NOTHING_TO_DO)
- {
- assert (0);
- return status;
- }
- }
-
- return CAIRO_INT_STATUS_SUCCESS;
-}
diff --git a/src/cairo-tg-surface.c b/src/cairo-tg-surface.c
deleted file mode 100755
index c32799fa4..000000000
--- a/src/cairo-tg-surface.c
+++ /dev/null
@@ -1,1372 +0,0 @@
-/*
- * Copyright © 2012 SCore Corporation
- *
- * 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.
- *
- * Author: Taekyun Kim (podain77@gmail.com)
- */
-
-#include "cairoint.h"
-#include "cairo-surface-fallback-private.h"
-#include "cairo-tg.h"
-#include "cairo-tg-private.h"
-#include "cairo-image-surface-inline.h"
-#include "cairo-surface-subsurface-inline.h"
-#include "cairo-compositor-private.h"
-#include "cairo-clip-inline.h"
-#include "cairo-recording-surface-inline.h"
-
-#if CAIRO_HAS_OPENMP
-#include <omp.h>
-#endif
-
-#define CAIRO_TG_THREAD_POOL_BUSY_WAIT
-#define CAIRO_TG_NUM_MIN_ENTRIES_FOR_PARALLEL_FLUSH 2
-
-static inline int
-get_num_cpu_cores (void)
-{
- static int num_cpu_cores = 0;
-
- if (num_cpu_cores == 0)
- {
-#if CAIRO_HAS_OPENMP
- num_cpu_cores = omp_get_num_procs ();
-#elif defined (__WIN32)
- SYSTEM_INFO sysinfo;
-
- GetSystemInfo (&sysinfo);
- num_cpu_cores = sysinfo.dwNumberOfProcessors;
-#elif defined (__linux__)
- cpu_set_t cs;
- int i;
-
- CPU_ZERO (&cs);
-
- if (sched_getaffinity (0, sizeof (cs), &cs) != 0)
- num_cpu_cores = 1;
-
- for (i = 0; i < 8; i++)
- {
- if (CPU_ISSET (i, &cs))
- num_cpu_cores++;
- }
-#else
- num_cpu_cores = 1;
-#endif
- }
-
- return num_cpu_cores;
-}
-
-static inline int
-get_bpp_for_format (cairo_format_t format)
-{
- switch (format)
- {
- case CAIRO_FORMAT_ARGB32:
- case CAIRO_FORMAT_RGB24:
- case CAIRO_FORMAT_RGB30:
- return 32;
- case CAIRO_FORMAT_RGB16_565:
- return 16;
- case CAIRO_FORMAT_A8:
- return 8;
- case CAIRO_FORMAT_A1:
- return 1;
- case CAIRO_FORMAT_INVALID:
- default:
- ASSERT_NOT_REACHED;
- return 0;
- }
-}
-
-static inline cairo_bool_t
-_cairo_surface_is_tg(const cairo_surface_t *surface)
-{
- return surface->backend && surface->backend->type == CAIRO_SURFACE_TYPE_TG;
-}
-
-static inline cairo_bool_t
-_cairo_tg_surface_is_size_valid (int width, int height)
-{
- if (width < 0 || height < 0)
- return FALSE;
-
- /* TODO: Check for upper limit of surface size. */
-
- return TRUE;
-}
-
-static inline cairo_bool_t
-_cairo_pattern_is_self_copy (cairo_surface_t *surface,
- const cairo_pattern_t *pattern)
-{
- if (unlikely (surface == NULL))
- return FALSE;
-
- if (unlikely (pattern == NULL))
- return FALSE;
-
- if (pattern->type == CAIRO_PATTERN_TYPE_SURFACE )
- {
- cairo_surface_t *pattern_surface =
- ((cairo_surface_pattern_t *) pattern)->surface;
-
- while (_cairo_surface_is_subsurface (pattern_surface))
- {
- pattern_surface =
- _cairo_surface_subsurface_get_target (pattern_surface);
- }
-
- return pattern_surface == surface;
- }
-
- return FALSE;
-}
-
-static inline cairo_bool_t
-_cairo_pattern_is_recording (const cairo_pattern_t *pattern)
-{
- cairo_surface_t *surface;
-
- if (pattern->type != CAIRO_PATTERN_TYPE_SURFACE)
- return FALSE;
-
- surface = ((const cairo_surface_pattern_t *) pattern)->surface;
- return _cairo_surface_is_recording (surface);
-}
-
-static inline cairo_bool_t
-_cairo_tg_surface_owns_data (cairo_tg_surface_t *surface)
-{
- return ((cairo_image_surface_t *) surface->image_surface)->owns_data;
-}
-
-static inline cairo_int_status_t
-_cairo_tg_image_surface_paint (void *closure,
- cairo_operator_t op,
- const cairo_pattern_t *source,
- const cairo_clip_t *clip)
-{
- cairo_image_surface_t *surface = (cairo_image_surface_t *) closure;
- cairo_int_status_t status;
-
- status = _cairo_surface_begin_modification (&surface->base);
-
- if (unlikely (status))
- return status;
-
- status = _cairo_compositor_paint (surface->compositor, &surface->base,
- op, source, clip);
-
- if (status != CAIRO_INT_STATUS_NOTHING_TO_DO)
- {
- surface->base.is_clear = op == CAIRO_OPERATOR_CLEAR && clip == NULL;
- surface->base.serial++;
- }
-
- return status;
-}
-
-static inline cairo_int_status_t
-_cairo_tg_image_surface_mask (void *closure,
- cairo_operator_t op,
- const cairo_pattern_t *source,
- const cairo_pattern_t *mask,
- const cairo_clip_t *clip)
-{
- cairo_image_surface_t *surface = (cairo_image_surface_t *) closure;
- cairo_int_status_t status;
-
- status = _cairo_surface_begin_modification (&surface->base);
-
- if (unlikely (status))
- return status;
-
- status = _cairo_compositor_mask (surface->compositor, &surface->base,
- op, source, mask, clip);
-
- if (status != CAIRO_INT_STATUS_NOTHING_TO_DO)
- {
- surface->base.is_clear = FALSE;
- surface->base.serial++;
- }
-
- return status;
-}
-
-static inline cairo_int_status_t
-_cairo_tg_image_surface_stroke (void *closure,
- 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_image_surface_t *surface = (cairo_image_surface_t *) closure;
- cairo_int_status_t status;
-
- status = _cairo_surface_begin_modification (&surface->base);
-
- if (unlikely (status))
- return status;
-
- status = _cairo_compositor_stroke (surface->compositor, &surface->base,
- op, source, path,
- style, ctm, ctm_inverse,
- tolerance, antialias, clip);
-
- if (status != CAIRO_INT_STATUS_NOTHING_TO_DO)
- {
- surface->base.is_clear = FALSE;
- surface->base.serial++;
- }
-
- return status;
-}
-
-
-static inline cairo_int_status_t
-_cairo_tg_image_surface_fill (void *closure,
- 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_image_surface_t *surface = (cairo_image_surface_t *) closure;
- cairo_int_status_t status;
-
- status = _cairo_surface_begin_modification (&surface->base);
-
- if (unlikely (status))
- return status;
-
- status = _cairo_compositor_fill (surface->compositor, &surface->base,
- op, source, path,
- fill_rule, tolerance, antialias, clip);
-
- if (status != CAIRO_INT_STATUS_NOTHING_TO_DO)
- {
- surface->base.is_clear = FALSE;
- surface->base.serial++;
- }
-
- return status;
-}
-
-static inline cairo_int_status_t
-_cairo_tg_image_surface_glyphs (void *closure,
- cairo_operator_t op,
- const cairo_pattern_t *source,
- cairo_glyph_t *glyphs,
- int num_glyphs,
- cairo_scaled_font_t *scaled_font,
- const cairo_clip_t *clip)
-{
- cairo_image_surface_t *surface = (cairo_image_surface_t *) closure;
- cairo_int_status_t status;
-
- status = _cairo_surface_begin_modification (&surface->base);
-
- if (unlikely (status))
- return status;
-
- status = _cairo_compositor_glyphs (surface->compositor, &surface->base,
- op, source,
- glyphs, num_glyphs, scaled_font,
- clip);
-
- if (status != CAIRO_INT_STATUS_NOTHING_TO_DO)
- {
- surface->base.is_clear = FALSE;
- surface->base.serial++;
- }
-
- return status;
-}
-
-const cairo_tg_journal_replay_funcs_t replay_funcs_image_fallback =
-{
- _cairo_tg_image_surface_paint,
- _cairo_tg_image_surface_mask,
- _cairo_tg_image_surface_stroke,
- _cairo_tg_image_surface_fill,
- _cairo_tg_image_surface_glyphs,
-};
-
-typedef struct _cairo_tg_surface_tile
-{
- cairo_surface_t *surface;
- cairo_rectangle_int_t tile_rect;
-} cairo_tg_surface_tile_t;
-
-static inline int
-_cairo_tg_surface_tiles_init (cairo_tg_surface_t *surface,
- const cairo_rectangle_int_t *extents,
- int num_tiles,
- cairo_tg_surface_tile_t *tiles)
-{
- int tile_height;
- int i;
-
- if (extents->height <= 0)
- return 0;
-
- if (extents->height <= num_tiles)
- num_tiles = extents->height;
-
- tile_height = extents->height / num_tiles;
-
- for (i = 0; i < num_tiles; i++)
- {
- tiles[i].surface = surface->tile_surfaces[i];
- tiles[i].tile_rect.x = extents->x;
- tiles[i].tile_rect.y = extents->y + i * tile_height;
- tiles[i].tile_rect.width = extents->width;
- tiles[i].tile_rect.height = tile_height;
- }
-
- tiles[num_tiles - 1].tile_rect.height = extents->height - i * (num_tiles - 1);
-
- return num_tiles;
-}
-
-static cairo_int_status_t
-_cairo_tg_surface_tile_paint (void *closure,
- cairo_operator_t op,
- const cairo_pattern_t *source,
- const cairo_clip_t *clip)
-{
- cairo_tg_surface_tile_t *tile = (cairo_tg_surface_tile_t *) closure;
- cairo_clip_t *tile_clip;
- cairo_int_status_t status = CAIRO_INT_STATUS_SUCCESS;
-
- tile_clip = _cairo_clip_copy_intersect_rectangle (clip, &tile->tile_rect);
-
- if (! _cairo_clip_is_all_clipped (tile_clip))
- status = _cairo_tg_image_surface_paint (tile->surface, op, source, tile_clip);
-
- _cairo_clip_destroy (tile_clip);
-
- return status;
-}
-
-static cairo_int_status_t
-_cairo_tg_surface_tile_mask (void *closure,
- cairo_operator_t op,
- const cairo_pattern_t *source,
- const cairo_pattern_t *mask,
- const cairo_clip_t *clip)
-{
- cairo_tg_surface_tile_t *tile = (cairo_tg_surface_tile_t *) closure;
- cairo_clip_t *tile_clip;
- cairo_int_status_t status = CAIRO_INT_STATUS_SUCCESS;
-
- tile_clip = _cairo_clip_copy_intersect_rectangle (clip, &tile->tile_rect);
-
- if (! _cairo_clip_is_all_clipped (tile_clip))
- {
- status = _cairo_tg_image_surface_mask (tile->surface, op, source,
- mask, tile_clip);
- }
-
- _cairo_clip_destroy (tile_clip);
-
- return status;
-}
-
-static cairo_int_status_t
-_cairo_tg_surface_tile_stroke (void *closure,
- 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_tg_surface_tile_t *tile = (cairo_tg_surface_tile_t *) closure;
- cairo_clip_t *tile_clip;
- cairo_int_status_t status = CAIRO_INT_STATUS_SUCCESS;
-
- tile_clip = _cairo_clip_copy_intersect_rectangle (clip, &tile->tile_rect);
-
- if (! _cairo_clip_is_all_clipped (tile_clip))
- {
- status = _cairo_tg_image_surface_stroke (tile->surface, op, source,
- path, style, ctm, ctm_inverse,
- tolerance, antialias, tile_clip);
- }
-
- _cairo_clip_destroy (tile_clip);
-
- return status;
-}
-
-static cairo_int_status_t
-_cairo_tg_surface_tile_fill (void *closure,
- 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_tg_surface_tile_t *tile = (cairo_tg_surface_tile_t *) closure;
- cairo_clip_t *tile_clip;
- cairo_int_status_t status = CAIRO_INT_STATUS_SUCCESS;
-
- tile_clip = _cairo_clip_copy_intersect_rectangle (clip, &tile->tile_rect);
-
- if (! _cairo_clip_is_all_clipped (tile_clip))
- {
- status = _cairo_tg_image_surface_fill (tile->surface, op, source,
- path, fill_rule, tolerance,
- antialias, tile_clip);
- }
-
- _cairo_clip_destroy (tile_clip);
-
- return status;
-}
-
-static cairo_int_status_t
-_cairo_tg_surface_tile_glyphs (void *closure,
- cairo_operator_t op,
- const cairo_pattern_t *source,
- cairo_glyph_t *glyphs,
- int num_glyphs,
- cairo_scaled_font_t *scaled_font,
- const cairo_clip_t *clip)
-{
- cairo_tg_surface_tile_t *tile = (cairo_tg_surface_tile_t *) closure;
- cairo_clip_t *tile_clip;
- cairo_int_status_t status = CAIRO_INT_STATUS_SUCCESS;
-
- tile_clip = _cairo_clip_copy_intersect_rectangle (clip, &tile->tile_rect);
-
- if (! _cairo_clip_is_all_clipped (tile_clip))
- {
- status = _cairo_tg_image_surface_glyphs (tile->surface, op, source,
- glyphs, num_glyphs, scaled_font,
- tile_clip);
- }
-
- _cairo_clip_destroy (tile_clip);
-
- return status;
-}
-
-const cairo_tg_journal_replay_funcs_t replay_funcs_tile =
-{
- _cairo_tg_surface_tile_paint,
- _cairo_tg_surface_tile_mask,
- _cairo_tg_surface_tile_stroke,
- _cairo_tg_surface_tile_fill,
- _cairo_tg_surface_tile_glyphs,
-};
-
-#if ! CAIRO_HAS_OPENMP
-#define CAIRO_TG_NUM_MAX_WORKERS CAIRO_TG_NUM_MAX_TILES
-
-typedef enum _cairo_tg_worker_status
-{
- CAIRO_TG_WORKER_STATUS_IDLE, /* can transit to either OCCUPIED or KILLED */
- CAIRO_TG_WORKER_STATUS_TO_DO, /* only can transit to IDLE state */
- CAIRO_TG_WORKER_STATUS_KILLED, /* worker will be no longer valid */
-} cairo_tg_worker_status_t;
-
-typedef struct _cairo_tg_worker
-{
- cairo_tg_journal_t *journal;
- cairo_tg_surface_tile_t *tile;
-
- pthread_t thread;
- pthread_mutex_t lock;
- pthread_cond_t cond_wake_up;
- cairo_tg_worker_status_t status;
-
-#ifdef CAIRO_TG_THREAD_POOL_BUSY_WAIT
- pthread_spinlock_t spinlock;
-#else
- pthread_cond_t cond_done;
-#endif
-} cairo_tg_worker_t;
-
-cairo_tg_worker_t workers[CAIRO_TG_NUM_MAX_WORKERS];
-
-pthread_mutex_t workers_lock;
-cairo_bool_t workers_occupied;
-
-static void *
-_cairo_tg_worker_mainloop (void *arg)
-{
- cairo_tg_worker_t *worker = (cairo_tg_worker_t *) arg;
-
- while (1)
- {
- pthread_mutex_lock (&worker->lock);
-
- while (worker->status == CAIRO_TG_WORKER_STATUS_IDLE)
- pthread_cond_wait (&worker->cond_wake_up, &worker->lock);
-
- /* Here, worker is kicked off to do some action. */
-
- if (worker->status == CAIRO_TG_WORKER_STATUS_KILLED)
- {
- /* Worker is killed, so release mutex and exit. */
- pthread_mutex_unlock (&worker->lock);
- pthread_exit (NULL);
- }
-
- assert (worker->status == CAIRO_TG_WORKER_STATUS_TO_DO);
-
- _cairo_tg_journal_replay (worker->journal, (void *)worker->tile,
- &worker->tile->tile_rect, &replay_funcs_tile);
-
- worker->status = CAIRO_TG_WORKER_STATUS_IDLE;
-
-#ifndef CAIRO_TG_THREAD_POOL_BUSY_WAIT
- pthread_cond_signal (&worker->cond_done);
-#endif
-
- pthread_mutex_unlock (&worker->lock);
- }
-
- return NULL;
-}
-
-static void
-_cairo_tg_workers_init (void)
-{
- int i;
-
- for (i = 0; i < CAIRO_TG_NUM_MAX_WORKERS; i++)
- {
- workers[i].status = CAIRO_TG_WORKER_STATUS_IDLE;
-
- pthread_mutex_init (&workers[i].lock, NULL);
- pthread_cond_init (&workers[i].cond_wake_up, NULL);
-
-#ifdef CAIRO_TG_THREAD_POOL_BUSY_WAIT
- pthread_spin_init (&workers[i].spinlock, 0);
-#else
- pthread_cond_init (&workers[i].cond_done, NULL);
-#endif
-
- pthread_create (&workers[i].thread, NULL, _cairo_tg_worker_mainloop, (void *) &workers[i]);
- }
-
- pthread_mutex_init (&workers_lock, NULL);
- workers_occupied = FALSE;
-}
-
-static void
-_cairo_tg_workers_fini (void)
-{
- int i;
-
- for (i = 0; i < CAIRO_TG_NUM_MAX_WORKERS; i++)
- {
- pthread_mutex_lock (&workers[i].lock);
-
- workers[i].status = CAIRO_TG_WORKER_STATUS_KILLED;
- pthread_cond_signal (&workers[i].cond_wake_up);
- pthread_mutex_unlock (&workers[i].lock);
- }
-
- for (i = 0; i < CAIRO_TG_NUM_MAX_WORKERS; i++)
- pthread_join (workers[i].thread, NULL);
-
- for (i = 0; i < CAIRO_TG_NUM_MAX_WORKERS; i++)
- {
- pthread_mutex_destroy (&workers[i].lock);
- pthread_cond_destroy (&workers[i].cond_wake_up);
-
-#ifdef CAIRO_TG_THREAD_POOL_BUSY_WAIT
- pthread_spin_destroy (&workers[i].spinlock);
-#else
- pthread_cond_destroy (&workers[i].cond_done);
-#endif
- }
-}
-
-static void __attribute__((constructor))
-_cairo_tg_constructor (void)
-{
- pthread_atfork (NULL, NULL, _cairo_tg_workers_init);
- _cairo_tg_workers_init ();
-}
-
-static void __attribute__((destructor))
-_cairo_tg_destructor (void)
-{
- _cairo_tg_workers_fini ();
-}
-
-#endif /* ! CAIRO_HAS_OPENMP */
-
-static void
-_cairo_tg_surface_prepare_flush_parallel (cairo_tg_surface_t *surface)
-{
- const cairo_tg_journal_entry_t *entry;
- const cairo_tg_journal_entry_t *next;
-
- cairo_list_foreach_entry_safe (entry, next, cairo_tg_journal_entry_t,
- &surface->journal.entry_list, link)
- {
- if (entry->source.base.type == CAIRO_PATTERN_TYPE_SURFACE)
- {
- cairo_surface_pattern_t *pattern = (cairo_surface_pattern_t *) (&entry->source.base);
- cairo_surface_flush (pattern->surface);
- }
-
- if (entry->type == CAIRO_TG_JOURNAL_ENTRY_MASK)
- {
- cairo_tg_journal_entry_mask_t *e =
- (cairo_tg_journal_entry_mask_t *) entry;
-
- if (e->mask.base.type == CAIRO_PATTERN_TYPE_SURFACE)
- {
- cairo_surface_pattern_t *pattern = (cairo_surface_pattern_t *) (&e->mask.base);
- cairo_surface_flush (pattern->surface);
- }
- }
- }
-}
-
-static cairo_int_status_t
-_cairo_tg_surface_flush_parallel (cairo_tg_surface_t *surface)
-{
- int num_tiles, i;
- cairo_tg_surface_tile_t tiles[CAIRO_TG_NUM_MAX_TILES];
- cairo_rectangle_int_t extents;
-
- if (surface->journal.num_entries < CAIRO_TG_NUM_MIN_ENTRIES_FOR_PARALLEL_FLUSH)
- return CAIRO_INT_STATUS_UNSUPPORTED;
-
- _cairo_tg_surface_prepare_flush_parallel (surface);
-
- extents.x = 0;
- extents.y = 0;
- extents.width = surface->width;
- extents.height = surface->height;
-
- _cairo_rectangle_intersect (&extents, &surface->journal.extents);
-
- num_tiles = get_num_cpu_cores ();
-
-#if ! CAIRO_HAS_OPENMP
- if (num_tiles > CAIRO_TG_NUM_MAX_WORKERS)
- num_tiles = CAIRO_TG_NUM_MAX_WORKERS;
-#endif
-
- num_tiles = _cairo_tg_surface_tiles_init (surface, &extents, num_tiles, &tiles[0]);
-
-#if CAIRO_HAS_OPENMP
- #pragma omp parallel for
- for (i = 0; i < num_tiles; i++)
- {
- _cairo_tg_journal_replay (&surface->journal, (void *) &tiles[i],
- &tiles[i].tile_rect, &replay_funcs_tile);
- }
-#else
- pthread_mutex_lock (&workers_lock);
-
- if (workers_occupied)
- {
- pthread_mutex_unlock (&workers_lock);
- return CAIRO_INT_STATUS_UNSUPPORTED;
- }
-
- workers_occupied = TRUE;
- pthread_mutex_unlock (&workers_lock);
-
- /* Kick workers to start. */
- for (i = 0; i < num_tiles - 1; i++)
- {
- pthread_mutex_lock (&workers[i].lock);
-
- workers[i].status = CAIRO_TG_WORKER_STATUS_TO_DO;
- workers[i].journal = &surface->journal;
- workers[i].tile = &tiles[i];
-
- pthread_cond_signal (&workers[i].cond_wake_up);
- pthread_mutex_unlock (&workers[i].lock);
- }
-
- _cairo_tg_journal_replay (&surface->journal, &tiles[num_tiles - 1],
- &tiles[num_tiles - 1].tile_rect, &replay_funcs_tile);
-
- /* Wait for workers to finish. */
- for (i = 0; i < num_tiles - 1; i++)
- {
-#ifdef CAIRO_TG_THREAD_POOL_BUSY_WAIT
- pthread_spin_lock (&workers[i].spinlock);
-
- while (workers[i].status == CAIRO_TG_WORKER_STATUS_TO_DO)
- {
- pthread_spin_unlock (&workers[i].spinlock);
- pthread_spin_lock (&workers[i].spinlock);
- }
-
- pthread_spin_unlock (&workers[i].spinlock);
-#else
- pthread_mutex_lock (&workers[i].lock);
-
- while (workers[i].status == CAIRO_TG_WORKER_STATUS_TO_DO)
- pthread_cond_wait (&workers[i].cond_done, &workers[i].lock);
-
- pthread_mutex_unlock (&workers[i].lock);
-#endif
- }
-
- /* Release thread pool. */
- pthread_mutex_lock (&workers_lock);
- workers_occupied = FALSE;
- pthread_mutex_unlock (&workers_lock);
-#endif
-
- return CAIRO_INT_STATUS_SUCCESS;
-}
-
-static cairo_status_t
-_cairo_tg_surface_flush (void *abstract_surface,
- unsigned flags)
-{
- cairo_tg_surface_t *surface = abstract_surface;
- cairo_int_status_t status = CAIRO_INT_STATUS_SUCCESS;
-
- if (flags)
- return CAIRO_STATUS_SUCCESS;
-
- _cairo_tg_journal_lock (&surface->journal);
-
- if (surface->journal.num_entries)
- {
- status = _cairo_tg_surface_flush_parallel (surface);
-
- if (status)
- {
- status = _cairo_tg_journal_replay (&surface->journal,
- (void *) surface->image_surface,
- NULL, &replay_funcs_image_fallback);
- }
-
- _cairo_tg_journal_clear (&surface->journal);
- }
-
- _cairo_tg_journal_unlock (&surface->journal);
-
- return status;
-}
-
-static cairo_image_surface_t *
-_cairo_tg_surface_map_to_image (void *abstract_surface,
- const cairo_rectangle_int_t *extents)
-{
- cairo_tg_surface_t *other = abstract_surface;
- cairo_surface_t *surface;
- uint8_t *buffer;
-
- _cairo_tg_surface_flush (other, 0);
-
- buffer = other->data;
- buffer += extents->y * other->stride;
- buffer += extents->x * other->bpp / 8;
-
- surface =
- _cairo_image_surface_create_with_pixman_format (buffer,
- other->pixman_format,
- extents->width,
- extents->height,
- other->stride);
-
- if (unlikely (surface == NULL))
- return NULL;
-
- cairo_surface_set_device_offset (surface, -extents->x, extents->y);
-
- return (cairo_image_surface_t *) surface;
-}
-
-static cairo_int_status_t
-_cairo_tg_surface_unmap_image (void *abstract_surface,
- cairo_image_surface_t *image)
-{
- cairo_surface_finish (&image->base);
- cairo_surface_destroy (&image->base);
-
- return CAIRO_INT_STATUS_SUCCESS;
-}
-
-static cairo_bool_t
-_cairo_tg_surface_get_extents (void *abstract_surface,
- cairo_rectangle_int_t *extents)
-{
- cairo_tg_surface_t *surface = abstract_surface;
-
- extents->x = 0;
- extents->y = 0;
- extents->width = surface->width;
- extents->height = surface->height;
-
- return TRUE;
-}
-
-static cairo_int_status_t
-_cairo_tg_surface_paint (void *abstract_surface,
- cairo_operator_t op,
- const cairo_pattern_t *source,
- const cairo_clip_t *clip)
-{
- cairo_tg_surface_t *surface = abstract_surface;
- cairo_int_status_t status = CAIRO_INT_STATUS_UNSUPPORTED;
-
- if (! _cairo_pattern_is_self_copy (&surface->base, source) &&
- ! _cairo_pattern_is_recording (source))
- status = _cairo_tg_journal_log_paint (&surface->journal, op, source, clip);
-
- if (status)
- {
- status = _cairo_tg_surface_flush (surface, 0);
-
- if (unlikely (status))
- return status;
-
- status = _cairo_tg_image_surface_paint (surface->image_surface, op, source, clip);
- }
-
- return status;
-}
-
-static cairo_int_status_t
-_cairo_tg_surface_mask (void *abstract_surface,
- cairo_operator_t op,
- const cairo_pattern_t *source,
- const cairo_pattern_t *mask,
- const cairo_clip_t *clip)
-{
- cairo_tg_surface_t *surface = abstract_surface;
- cairo_int_status_t status = CAIRO_INT_STATUS_UNSUPPORTED;
-
- if (! _cairo_pattern_is_self_copy (&surface->base, source) &&
- ! _cairo_pattern_is_self_copy (&surface->base, mask) &&
- ! _cairo_pattern_is_recording (source))
- status = _cairo_tg_journal_log_mask (&surface->journal, op, source, mask, clip);
-
- if (status)
- {
- status = _cairo_tg_surface_flush (surface, 0);
-
- if (unlikely (status))
- return status;
-
- status = _cairo_tg_image_surface_mask (surface->image_surface, op, source,
- mask, clip);
- }
-
- return status;
-}
-
-static cairo_int_status_t
-_cairo_tg_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_tg_surface_t *surface = abstract_surface;
- cairo_int_status_t status = CAIRO_INT_STATUS_UNSUPPORTED;
-
- if (! _cairo_pattern_is_self_copy (&surface->base, source) &&
- ! _cairo_pattern_is_recording (source))
- {
- status = _cairo_tg_journal_log_stroke (&surface->journal, op, source,
- path, style, ctm, ctm_inverse,
- tolerance, antialias, clip);
- }
-
- if (status)
- {
- status = _cairo_tg_surface_flush (surface, 0);
-
- if (unlikely (status))
- return status;
-
- status = _cairo_tg_image_surface_stroke (surface->image_surface, op, source,
- path, style, ctm, ctm_inverse,
- tolerance, antialias, clip);
- }
-
- return status;
-}
-
-static cairo_int_status_t
-_cairo_tg_surface_fill (void *abstract_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_tg_surface_t *surface = abstract_surface;
- cairo_int_status_t status = CAIRO_INT_STATUS_UNSUPPORTED;
-
- if (! _cairo_pattern_is_self_copy (&surface->base, source) &&
- ! _cairo_pattern_is_recording (source))
- {
- status = _cairo_tg_journal_log_fill (&surface->journal, op, source,
- path, fill_rule, tolerance, antialias, clip);
- }
-
- if (status)
- {
- status = _cairo_tg_surface_flush (surface, 0);
-
- if (unlikely (status))
- return status;
-
- status = _cairo_tg_image_surface_fill (surface->image_surface, op, source,
- path, fill_rule, tolerance, antialias, clip);
- }
-
- return status;
-}
-
-static cairo_int_status_t
-_cairo_tg_surface_glyphs (void *abstract_surface,
- cairo_operator_t op,
- const cairo_pattern_t *source,
- cairo_glyph_t *glyphs,
- int num_glyphs,
- cairo_scaled_font_t *scaled_font,
- const cairo_clip_t *clip)
-{
- cairo_tg_surface_t *surface = abstract_surface;
- cairo_int_status_t status = CAIRO_INT_STATUS_UNSUPPORTED;
-
- if (! _cairo_pattern_is_self_copy (&surface->base, source) &&
- ! _cairo_pattern_is_recording (source))
- {
- status = _cairo_tg_journal_log_glyphs (&surface->journal, op, source,
- glyphs, num_glyphs, scaled_font, clip);
- }
-
- if (status)
- {
- status = _cairo_tg_surface_flush (surface, 0);
-
- if (unlikely (status))
- return status;
-
- status = _cairo_tg_image_surface_glyphs (surface->image_surface, op, source,
- glyphs, num_glyphs, scaled_font, clip);
- }
-
- return status;
-}
-
-static cairo_surface_t *
-_cairo_tg_surface_create_similar (void *abstract_other,
- cairo_content_t content,
- int width,
- int height)
-{
- cairo_tg_surface_t *other = abstract_other;
-
- if (! _cairo_tg_surface_is_size_valid (width, height))
- return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_SIZE));
-
- if (content == other->base.content)
- return cairo_tg_surface_create (other->format, width, height);
-
- return cairo_tg_surface_create (_cairo_format_from_content (content), width, height);
-}
-
-static cairo_surface_t *
-_cairo_tg_surface_source (void *abstract_surface,
- cairo_rectangle_int_t *extents)
-{
- cairo_tg_surface_t *surface = abstract_surface;
-
- if (extents)
- {
- extents->x = extents->y = 0;
- extents->width = surface->width;
- extents->height = surface->height;
- }
-
- return &surface->base;
-}
-
-static cairo_status_t
-_cairo_tg_surface_acquire_source_image (void *abstract_surface,
- cairo_image_surface_t **image_out,
- void **image_extra)
-{
- cairo_tg_surface_t *surface = abstract_surface;
-
- _cairo_tg_surface_flush (surface, 0);
-
- *image_out = (cairo_image_surface_t *) surface->image_surface;
- *image_extra = NULL;
-
- return CAIRO_STATUS_SUCCESS;
-}
-
-static void
-_cairo_tg_surface_release_source_image (void *abstract_surface,
- cairo_image_surface_t *image,
- void *image_extra)
-{
- /* Do nothing */
-}
-
-static cairo_surface_t *
-_cairo_tg_surface_snapshot (void *abstract_surface)
-{
- cairo_tg_surface_t *surface = abstract_surface;
- cairo_tg_surface_t *clone;
-
- _cairo_tg_surface_flush (surface, 0);
-
- if (_cairo_tg_surface_owns_data (surface) && surface->base._finishing)
- {
- return cairo_tg_surface_create_for_data (surface->data, surface->format,
- surface->width, surface->height,
- surface->stride);
- }
-
- clone = (cairo_tg_surface_t *)
- cairo_tg_surface_create (surface->format, surface->width, surface->height);
-
- if (unlikely (clone->base.status))
- return &clone->base;
-
- if (surface->stride == clone->stride)
- {
- memcpy (clone->data, surface->data, clone->stride * clone->height);
- }
- else
- {
- unsigned char *dst = clone->data;
- unsigned char *src = surface->data;
- int i;
- int stride = clone->stride < surface->stride ? clone->stride : surface->stride;
-
- for (i = 0; i < clone->height; i++)
- {
- memcpy (dst, src, stride);
- dst += clone->stride;
- src += surface->stride;
- }
- }
-
- clone->base.is_clear = FALSE;
-
- return &clone->base;
-}
-
-static cairo_int_status_t
-_cairo_tg_surface_init_tile_surfaces (cairo_tg_surface_t *surface)
-{
- int i;
- cairo_int_status_t status = CAIRO_INT_STATUS_SUCCESS;
-
- memset (&surface->tile_surfaces[0], 0x00,
- sizeof (cairo_surface_t *) * CAIRO_TG_NUM_MAX_TILES);
-
- for (i = 0; i < CAIRO_TG_NUM_MAX_TILES; i++)
- {
- surface->tile_surfaces[i] = cairo_image_surface_create_for_data (surface->data,
- surface->format,
- surface->width,
- surface->height,
- surface->stride);
-
- if (surface->tile_surfaces[i] == NULL)
- {
- status = CAIRO_INT_STATUS_NO_MEMORY;
- break;
- }
- }
-
- if (unlikely (status))
- {
- for (i = 0; i < CAIRO_TG_NUM_MAX_TILES; i++)
- {
- if (surface->tile_surfaces[i])
- cairo_surface_destroy (surface->tile_surfaces[i]);
- else
- break;
- }
- }
-
- return status;
-}
-
-static void
-_cairo_tg_surface_fini_tile_surfaces (cairo_tg_surface_t *surface)
-{
- int i;
-
- for (i = 0; i < CAIRO_TG_NUM_MAX_TILES; i++)
- {
- if (surface->tile_surfaces[i])
- cairo_surface_destroy (surface->tile_surfaces[i]);
- else
- break;
- }
-}
-
-static cairo_status_t
-_cairo_tg_surface_finish (void *abstract_surface)
-{
- cairo_tg_surface_t *surface = abstract_surface;
-
- _cairo_tg_surface_flush (surface, 0);
- _cairo_tg_journal_fini (&surface->journal);
- _cairo_tg_surface_fini_tile_surfaces (surface);
- cairo_surface_destroy (surface->image_surface);
-
- return CAIRO_STATUS_SUCCESS;
-}
-
-static const cairo_surface_backend_t _cairo_tg_surface_backend =
-{
- CAIRO_SURFACE_TYPE_TG,
- _cairo_tg_surface_finish,
-
- _cairo_default_context_create,
-
- _cairo_tg_surface_create_similar,
- NULL, /* create_similar image */
- _cairo_tg_surface_map_to_image,
- _cairo_tg_surface_unmap_image,
-
- _cairo_tg_surface_source,
- _cairo_tg_surface_acquire_source_image,
- _cairo_tg_surface_release_source_image,
- _cairo_tg_surface_snapshot,
-
- NULL, /* copy_page */
- NULL, /* show_page */
-
- _cairo_tg_surface_get_extents,
- NULL, /* get_font_options */
-
- _cairo_tg_surface_flush,
- NULL, /* mark_dirty_rectangle */
-
- _cairo_tg_surface_paint,
- _cairo_tg_surface_mask,
- _cairo_tg_surface_stroke,
- _cairo_tg_surface_fill,
- NULL, /* fill_stroke */
- _cairo_tg_surface_glyphs,
-};
-
-cairo_surface_t *
-cairo_tg_surface_create (cairo_format_t format,
- int width,
- int height)
-{
- cairo_tg_surface_t *surface;
- cairo_surface_t *image_surface;
-
- image_surface = cairo_image_surface_create (format, width, height);
-
- if (unlikely (image_surface == NULL))
- return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
-
- surface = malloc (sizeof (cairo_tg_surface_t));
-
- if (unlikely (surface == NULL))
- {
- cairo_surface_destroy (image_surface);
-
- return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
- }
-
- _cairo_surface_init (&surface->base,
- &_cairo_tg_surface_backend,
- NULL, image_surface->content);
-
- surface->format = format;
- surface->pixman_format = ((cairo_image_surface_t *) image_surface)->pixman_format;
- surface->data = (unsigned char *) cairo_image_surface_get_data (image_surface);
- surface->width = width;
- surface->height = height;
- surface->stride = cairo_image_surface_get_stride (image_surface);
- surface->bpp = get_bpp_for_format (format);
- surface->image_surface = image_surface;
- surface->base.is_clear = image_surface->is_clear;
-
- _cairo_tg_journal_init (&surface->journal);
-
- if (_cairo_tg_surface_init_tile_surfaces (surface))
- {
- cairo_surface_destroy (image_surface);
- _cairo_tg_journal_fini (&surface->journal);
-
- return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
- }
-
- return &surface->base;
-}
-
-cairo_surface_t *
-cairo_tg_surface_create_for_data (unsigned char *data,
- cairo_format_t format,
- int width,
- int height,
- int stride)
-{
- cairo_tg_surface_t *surface;
- cairo_surface_t *image_surface;
-
- image_surface = cairo_image_surface_create_for_data (data, format, width, height, stride);
-
- if (unlikely (image_surface == NULL))
- return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
-
- surface = malloc (sizeof (cairo_tg_surface_t));
-
- if (unlikely (surface == NULL))
- {
- cairo_surface_destroy (image_surface);
-
- return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
- }
-
- _cairo_surface_init (&surface->base,
- &_cairo_tg_surface_backend,
- NULL, image_surface->content);
-
- surface->format = format;
- surface->pixman_format = ((cairo_image_surface_t *) image_surface)->pixman_format;
- surface->data = (unsigned char *) cairo_image_surface_get_data (image_surface);
- surface->width = width;
- surface->height = height;
- surface->stride = cairo_image_surface_get_stride (image_surface);
- surface->bpp = get_bpp_for_format (format);
- surface->image_surface = image_surface;
- surface->base.is_clear = image_surface->is_clear;
-
- _cairo_tg_journal_init (&surface->journal);
-
- if (_cairo_tg_surface_init_tile_surfaces (surface))
- {
- cairo_surface_destroy (image_surface);
- _cairo_tg_journal_fini (&surface->journal);
-
- return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
- }
-
- return &surface->base;
-}
-
-unsigned char *
-cairo_tg_surface_get_data (cairo_surface_t *surface)
-{
- cairo_tg_surface_t *tg_surface = (cairo_tg_surface_t *) surface;
-
- if (! _cairo_surface_is_tg (surface)) {
- _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
- return NULL;
- }
-
- return tg_surface->data;
-}
-
-cairo_format_t
-cairo_tg_surface_get_format (cairo_surface_t *surface)
-{
- cairo_tg_surface_t *tg_surface = (cairo_tg_surface_t *) surface;
-
- if (! _cairo_surface_is_tg (surface)) {
- _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
- return CAIRO_FORMAT_INVALID;
- }
-
- return tg_surface->format;
-}
-
-int
-cairo_tg_surface_get_width (cairo_surface_t *surface)
-{
- cairo_tg_surface_t *tg_surface = (cairo_tg_surface_t *) surface;
-
- if (! _cairo_surface_is_tg (surface)) {
- _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
- return 0;
- }
-
- return tg_surface->width;
-}
-
-int
-cairo_tg_surface_get_height (cairo_surface_t *surface)
-{
- cairo_tg_surface_t *tg_surface = (cairo_tg_surface_t *) surface;
-
- if (! _cairo_surface_is_tg (surface)) {
- _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
- return 0;
- }
-
- return tg_surface->height;
-}
-
-int
-cairo_tg_surface_get_stride (cairo_surface_t *surface)
-{
- cairo_tg_surface_t *tg_surface = (cairo_tg_surface_t *) surface;
-
- if (! _cairo_surface_is_tg (surface)) {
- _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
- return 0;
- }
-
- return tg_surface->stride;
-}
diff --git a/src/cairo-thread-local-private.h b/src/cairo-thread-local-private.h
deleted file mode 100755
index 994c049c7..000000000
--- a/src/cairo-thread-local-private.h
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * Copyright © 2012 SCore Corporation
- *
- * 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.
- *
- * Author: Taekyun Kim (podain77@gmail.com)
- */
-
-#ifndef CAIRO_THREAD_LOCAL_PRIVATE_H
-#define CAIRO_THREAD_LOCAL_PRIVATE_H
-
-#if CAIRO_HAS_TLS || CAIRO_HAS_PTHREAD_SETSPECIFIC
-#define CAIRO_HAS_THREAD_LOCAL 1
-#endif
-
-#if CAIRO_HAS_THREAD_LOCAL
-#if defined(TLS)
-
-# define CAIRO_DEFINE_THREAD_LOCAL(type, name) \
- static TLS type name
-
-# define CAIRO_GET_THREAD_LOCAL(name) \
- (&name)
-
-#elif defined(__MINGW32__)
-
-# define _NO_W32_PSEUDO_MODIFIERS
-# include <windows.h>
-
-# define CAIRO_DEFINE_THREAD_LOCAL(type, name) \
- static volatile int tls_ ## name ## _initialized = 0; \
- static void *tls_ ## name ## _mutex = NULL; \
- static unsigned tls_ ## name ## _index; \
- \
- static type * \
- tls_ ## name ## _alloc (void) \
- { \
- type *value = calloc (1, sizeof (type)); \
- if (value) \
- TlsSetValue (tls_ ## name ## _index, value); \
- return value; \
- } \
- \
- static inline type * \
- tls_ ## name ## _get (void) \
- { \
- type *value; \
- if (!tls_ ## name ## _initialized) \
- { \
- if (!tls_ ## name ## _mutex) \
- { \
- void *mutex = CreateMutexA (NULL, 0, NULL); \
- if (InterlockedCompareExchangePointer ( \
- &tls_ ## name ## _mutex, mutex, NULL) != NULL) \
- { \
- CloseHandle (mutex); \
- } \
- } \
- WaitForSingleObject (tls_ ## name ## _mutex, 0xFFFFFFFF); \
- if (!tls_ ## name ## _initialized) \
- { \
- tls_ ## name ## _index = TlsAlloc (); \
- tls_ ## name ## _initialized = 1; \
- } \
- ReleaseMutex (tls_ ## name ## _mutex); \
- } \
- if (tls_ ## name ## _index == 0xFFFFFFFF) \
- return NULL; \
- value = TlsGetValue (tls_ ## name ## _index); \
- if (!value) \
- value = tls_ ## name ## _alloc (); \
- return value; \
- }
-
-# define CAIRO_GET_THREAD_LOCAL(name) \
- tls_ ## name ## _get ()
-
-#elif defined(_MSC_VER)
-
-# define CAIRO_DEFINE_THREAD_LOCAL(type, name) \
- static __declspec(thread) type name
-
-# define CAIRO_GET_THREAD_LOCAL(name) \
- (&name)
-
-#elif defined(CAIRO_HAS_PTHREAD_SETSPECIFIC)
-
-#include <pthread.h>
-
-# define CAIRO_DEFINE_THREAD_LOCAL(type, name) \
- static pthread_once_t tls_ ## name ## _once_control = PTHREAD_ONCE_INIT; \
- static pthread_key_t tls_ ## name ## _key; \
- \
- static void \
- tls_ ## name ## _destroy_value (void *value) \
- { \
- free (value); \
- } \
- \
- static void \
- tls_ ## name ## _make_key (void) \
- { \
- pthread_key_create (&tls_ ## name ## _key, \
- tls_ ## name ## _destroy_value); \
- } \
- \
- static type * \
- tls_ ## name ## _alloc (void) \
- { \
- type *value = calloc (1, sizeof (type)); \
- if (value) \
- pthread_setspecific (tls_ ## name ## _key, value); \
- return value; \
- } \
- \
- static inline type * \
- tls_ ## name ## _get (void) \
- { \
- type *value = NULL; \
- if (pthread_once (&tls_ ## name ## _once_control, \
- tls_ ## name ## _make_key) == 0) \
- { \
- value = pthread_getspecific (tls_ ## name ## _key); \
- if (!value) \
- value = tls_ ## name ## _alloc (); \
- } \
- return value; \
- }
-
-# define CAIRO_GET_THREAD_LOCAL(name) \
- tls_ ## name ## _get ()
-
-#else
-
-# error "Unknown thread local support for this system."
-
-#endif
-#endif /* CAIRO_HAS_THREAD_LOCAL */
-
-#endif /* CAIRO_THREAD_LOCAL_PRIVATE_H */
diff --git a/src/cairo-time-private.h b/src/cairo-time-private.h
index 06dc912b4..06dc912b4 100755..100644
--- a/src/cairo-time-private.h
+++ b/src/cairo-time-private.h
diff --git a/src/cairo-time.c b/src/cairo-time.c
index a0003fbfc..a0003fbfc 100755..100644
--- a/src/cairo-time.c
+++ b/src/cairo-time.c
diff --git a/src/cairo-tor-scan-converter.c b/src/cairo-tor-scan-converter.c
index 89ef20f09..b1b51872b 100755..100644
--- a/src/cairo-tor-scan-converter.c
+++ b/src/cairo-tor-scan-converter.c
@@ -262,7 +262,7 @@ typedef int grid_scaled_y_t;
struct quorem {
int32_t quo;
- int32_t rem;
+ int64_t rem;
};
/* Header for a chunk of memory in a memory pool. */
@@ -277,9 +277,14 @@ struct _pool_chunk {
* chunk in the pool header. */
struct _pool_chunk *prev_chunk;
- /* Actual data starts here. Well aligned for pointers. */
+ /* Actual data starts here. Well aligned even for 64 bit types. */
+ int64_t data;
};
+/* The int64_t data member of _pool_chunk just exists to enforce alignment,
+ * it shouldn't be included in the allocated size for the struct. */
+#define SIZEOF_POOL_CHUNK (sizeof(struct _pool_chunk) - sizeof(int64_t))
+
/* A memory pool. This is supposed to be embedded on the stack or
* within some other structure. It may optionally be followed by an
* embedded array from which requests are fulfilled until
@@ -299,8 +304,11 @@ struct pool {
/* Header for the sentinel chunk. Directly following the pool
* struct should be some space for embedded elements from which
- * the sentinel chunk allocates from. */
- struct _pool_chunk sentinel[1];
+ * the sentinel chunk allocates from. This is expressed as a char
+ * array so that the 'int64_t data' member of _pool_chunk isn't
+ * included. This way embedding struct pool in other structs works
+ * without wasting space. */
+ char sentinel[SIZEOF_POOL_CHUNK];
};
/* A polygon edge. */
@@ -308,6 +316,9 @@ struct edge {
/* Next in y-bucket or active list. */
struct edge *next, *prev;
+ /* The clipped y of the top of the edge. */
+ grid_scaled_y_t ytop;
+
/* Number of subsample rows remaining to scan convert of this
* edge. */
grid_scaled_y_t height_left;
@@ -315,7 +326,7 @@ struct edge {
/* Original sign of the edge: +1 for downwards, -1 for upwards
* edges. */
int dir;
- int vertical;
+ int cell;
/* Current x coordinate while the edge is on the active
* list. Initialised to the x coordinate of the top of the
@@ -332,11 +343,8 @@ struct edge {
* full row's worth of subsample rows at a time. */
struct quorem dxdy_full;
- /* The clipped y of the top of the edge. */
- grid_scaled_y_t ytop;
-
/* y2-y1 after orienting the edge downwards. */
- grid_scaled_y_t dy;
+ int64_t dy;
};
#define EDGE_Y_BUCKET_INDEX(y, ymin) (((y) - (ymin))/GRID_Y)
@@ -458,37 +466,6 @@ struct glitter_scan_converter {
grid_scaled_y_t ymin, ymax;
};
-/* Compute the floored division a/b. Assumes / and % perform symmetric
- * division. */
-inline static struct quorem
-floored_divrem(int a, int b)
-{
- struct quorem qr;
- qr.quo = a/b;
- qr.rem = a%b;
- if ((a^b)<0 && qr.rem) {
- qr.quo -= 1;
- qr.rem += b;
- }
- return qr;
-}
-
-/* Compute the floored division (x*a)/b. Assumes / and % perform symmetric
- * division. */
-static struct quorem
-floored_muldivrem(int x, int a, int b)
-{
- struct quorem qr;
- long long xa = (long long)x*a;
- qr.quo = xa/b;
- qr.rem = xa%b;
- if ((xa>=0) != (b>=0) && qr.rem) {
- qr.quo -= 1;
- qr.rem += b;
- }
- return qr;
-}
-
static struct _pool_chunk *
_pool_chunk_init(
struct _pool_chunk *p,
@@ -506,7 +483,7 @@ _pool_chunk_create(struct pool *pool, size_t size)
{
struct _pool_chunk *p;
- p = malloc(size + sizeof(struct _pool_chunk));
+ p = malloc(SIZEOF_POOL_CHUNK + size);
if (unlikely (NULL == p))
longjmp (*pool->jmp, _cairo_error (CAIRO_STATUS_NO_MEMORY));
@@ -520,10 +497,10 @@ pool_init(struct pool *pool,
size_t embedded_capacity)
{
pool->jmp = jmp;
- pool->current = pool->sentinel;
+ pool->current = (void*) pool->sentinel;
pool->first_free = NULL;
pool->default_capacity = default_capacity;
- _pool_chunk_init(pool->sentinel, NULL, embedded_capacity);
+ _pool_chunk_init(pool->current, NULL, embedded_capacity);
}
static void
@@ -533,7 +510,7 @@ pool_fini(struct pool *pool)
do {
while (NULL != p) {
struct _pool_chunk *prev = p->prev_chunk;
- if (p != pool->sentinel)
+ if (p != (void *) pool->sentinel)
free(p);
p = prev;
}
@@ -573,14 +550,14 @@ _pool_alloc_from_new_chunk(
chunk = _pool_chunk_create (pool, capacity);
pool->current = chunk;
- obj = ((unsigned char*)chunk + sizeof(*chunk) + chunk->size);
+ obj = ((unsigned char*)&chunk->data + chunk->size);
chunk->size += size;
return obj;
}
/* Allocate size bytes from the pool. The first allocated address
- * returned from a pool is aligned to sizeof(void*). Subsequent
- * addresses will maintain alignment as long as multiples of void* are
+ * returned from a pool is aligned to 8 bytes. Subsequent
+ * addresses will maintain alignment as long as multiples of 8 are
* allocated. Returns the address of a new memory area or %NULL on
* allocation failures. The pool retains ownership of the returned
* memory. */
@@ -590,7 +567,7 @@ pool_alloc (struct pool *pool, size_t size)
struct _pool_chunk *chunk = pool->current;
if (size <= chunk->capacity - chunk->size) {
- void *obj = ((unsigned char*)chunk + sizeof(*chunk) + chunk->size);
+ void *obj = ((unsigned char*)&chunk->data + chunk->size);
chunk->size += size;
return obj;
} else {
@@ -604,16 +581,16 @@ pool_reset (struct pool *pool)
{
/* Transfer all used chunks to the chunk free list. */
struct _pool_chunk *chunk = pool->current;
- if (chunk != pool->sentinel) {
- while (chunk->prev_chunk != pool->sentinel) {
+ if (chunk != (void *) pool->sentinel) {
+ while (chunk->prev_chunk != (void *) pool->sentinel) {
chunk = chunk->prev_chunk;
}
chunk->prev_chunk = pool->first_free;
pool->first_free = pool->current;
}
/* Reset the sentinel as the current chunk. */
- pool->current = pool->sentinel;
- pool->sentinel->size = 0;
+ pool->current = (void *) pool->sentinel;
+ pool->current->size = 0;
}
/* Rewinds the cell list's cursor to the beginning. After rewinding
@@ -778,6 +755,25 @@ cell_list_add_subspan(struct cell_list *cells,
}
}
+inline static void full_step (struct edge *e)
+{
+ if (e->dy == 0)
+ return;
+
+ e->x.quo += e->dxdy_full.quo;
+ e->x.rem += e->dxdy_full.rem;
+ if (e->x.rem < 0) {
+ e->x.quo--;
+ e->x.rem += e->dy;
+ } else if (e->x.rem >= e->dy) {
+ ++e->x.quo;
+ e->x.rem -= e->dy;
+ }
+
+ e->cell = e->x.quo + (e->x.rem >= e->dy/2);
+}
+
+
/* Adds the analytical coverage of an edge crossing the current pixel
* row to the coverage cells and advances the edge's x position to the
* following row.
@@ -800,28 +796,42 @@ cell_list_render_edge(struct cell_list *cells,
struct edge *edge,
int sign)
{
- grid_scaled_y_t y1, y2, dy;
- grid_scaled_x_t dx;
- int ix1, ix2;
+ struct quorem x1, x2;
grid_scaled_x_t fx1, fx2;
+ int ix1, ix2;
- struct quorem x1 = edge->x;
- struct quorem x2 = x1;
+ x1 = edge->x;
+ full_step (edge);
+ x2 = edge->x;
+
+ /* Step back from the sample location (half-subrow) to the pixel origin */
+ if (edge->dy) {
+ x1.quo -= edge->dxdy.quo / 2;
+ x1.rem -= edge->dxdy.rem / 2;
+ if (x1.rem < 0) {
+ --x1.quo;
+ x1.rem += edge->dy;
+ } else if (x1.rem >= edge->dy) {
+ ++x1.quo;
+ x1.rem -= edge->dy;
+ }
- if (! edge->vertical) {
- x2.quo += edge->dxdy_full.quo;
- x2.rem += edge->dxdy_full.rem;
- if (x2.rem >= 0) {
+ x2.quo -= edge->dxdy.quo / 2;
+ x2.rem -= edge->dxdy.rem / 2;
+ if (x2.rem < 0) {
+ --x2.quo;
+ x2.rem += edge->dy;
+ } else if (x2.rem >= edge->dy) {
++x2.quo;
x2.rem -= edge->dy;
}
-
- edge->x = x2;
}
GRID_X_TO_INT_FRAC(x1.quo, ix1, fx1);
GRID_X_TO_INT_FRAC(x2.quo, ix2, fx2);
+ cell_list_maybe_rewind(cells, MIN(ix1, ix2));
+
/* Edge is entirely within a column? */
if (ix1 == ix2) {
/* We always know that ix1 is >= the cell list cursor in this
@@ -833,26 +843,39 @@ cell_list_render_edge(struct cell_list *cells,
}
/* Orient the edge left-to-right. */
- dx = x2.quo - x1.quo;
- if (dx >= 0) {
- y1 = 0;
- y2 = GRID_Y;
- } else {
- int tmp;
- tmp = ix1; ix1 = ix2; ix2 = tmp;
- tmp = fx1; fx1 = fx2; fx2 = tmp;
- dx = -dx;
- sign = -sign;
- y1 = GRID_Y;
- y2 = 0;
+ if (ix2 < ix1) {
+ struct quorem tx;
+ int t;
+
+ t = ix1;
+ ix1 = ix2;
+ ix2 = t;
+
+ t = fx1;
+ fx1 = fx2;
+ fx2 = t;
+
+ tx = x1;
+ x1 = x2;
+ x2 = tx;
}
- dy = y2 - y1;
/* Add coverage for all pixels [ix1,ix2] on this row crossed
* by the edge. */
{
struct cell_pair pair;
- struct quorem y = floored_divrem((GRID_X - fx1)*dy, dx);
+ struct quorem y;
+ int64_t tmp, dx;
+ int y_last;
+
+ dx = (x2.quo - x1.quo) * edge->dy + (x2.rem - x1.rem);
+
+ tmp = (ix1 + 1) * GRID_X * edge->dy;
+ tmp -= x1.quo * edge->dy + x1.rem;
+ tmp *= GRID_Y;
+
+ y.quo = tmp / dx;
+ y.rem = tmp % dx;
/* When rendering a previous edge on the active list we may
* advance the cell list cursor past the leftmost pixel of the
@@ -868,35 +891,32 @@ cell_list_render_edge(struct cell_list *cells,
*
* The left edge touches cells past the starting cell of the
* right edge. Fortunately such cases are rare.
- *
- * The rewinding is never necessary if the current edge stays
- * within a single column because we've checked before calling
- * this function that the active list order won't change. */
- cell_list_maybe_rewind(cells, ix1);
+ */
pair = cell_list_find_pair(cells, ix1, ix1+1);
pair.cell1->uncovered_area += sign*y.quo*(GRID_X + fx1);
pair.cell1->covered_height += sign*y.quo;
- y.quo += y1;
+ y_last = y.quo;
if (ix1+1 < ix2) {
- struct quorem dydx_full = floored_divrem(GRID_X*dy, dx);
struct cell *cell = pair.cell2;
+ struct quorem dydx_full;
+
+ dydx_full.quo = GRID_Y * GRID_X * edge->dy / dx;
+ dydx_full.rem = GRID_Y * GRID_X * edge->dy % dx;
++ix1;
do {
- grid_scaled_y_t y_skip = dydx_full.quo;
+ y.quo += dydx_full.quo;
y.rem += dydx_full.rem;
if (y.rem >= dx) {
- ++y_skip;
+ y.quo++;
y.rem -= dx;
}
- y.quo += y_skip;
-
- y_skip *= sign;
- cell->uncovered_area += y_skip*GRID_X;
- cell->covered_height += y_skip;
+ cell->uncovered_area += sign*(y.quo - y_last)*GRID_X;
+ cell->covered_height += sign*(y.quo - y_last);
+ y_last = y.quo;
++ix1;
cell = cell_list_find(cells, ix1);
@@ -904,8 +924,8 @@ cell_list_render_edge(struct cell_list *cells,
pair.cell2 = cell;
}
- pair.cell2->uncovered_area += sign*(y2 - y.quo)*fx2;
- pair.cell2->covered_height += sign*(y2 - y.quo);
+ pair.cell2->uncovered_area += sign*(GRID_Y - y_last)*fx2;
+ pair.cell2->covered_height += sign*(GRID_Y - y_last);
}
}
@@ -976,78 +996,19 @@ _polygon_insert_edge_into_its_y_bucket(struct polygon *polygon,
*ptail = e;
}
-inline static void
-polygon_add_edge (struct polygon *polygon,
- const cairo_edge_t *edge)
-{
- struct edge *e;
- grid_scaled_x_t dx;
- grid_scaled_y_t dy;
- grid_scaled_y_t ytop, ybot;
- grid_scaled_y_t ymin = polygon->ymin;
- grid_scaled_y_t ymax = polygon->ymax;
-
- if (unlikely (edge->top >= ymax || edge->bottom <= ymin))
- return;
-
- e = pool_alloc (polygon->edge_pool.base, sizeof (struct edge));
-
- dx = edge->line.p2.x - edge->line.p1.x;
- dy = edge->line.p2.y - edge->line.p1.y;
- e->dy = dy;
- e->dir = edge->dir;
-
- ytop = edge->top >= ymin ? edge->top : ymin;
- ybot = edge->bottom <= ymax ? edge->bottom : ymax;
- e->ytop = ytop;
- e->height_left = ybot - ytop;
-
- if (dx == 0) {
- e->vertical = TRUE;
- e->x.quo = edge->line.p1.x;
- e->x.rem = 0;
- e->dxdy.quo = 0;
- e->dxdy.rem = 0;
- e->dxdy_full.quo = 0;
- e->dxdy_full.rem = 0;
- } else {
- e->vertical = FALSE;
- e->dxdy = floored_divrem (dx, dy);
- if (ytop == edge->line.p1.y) {
- e->x.quo = edge->line.p1.x;
- e->x.rem = 0;
- } else {
- e->x = floored_muldivrem (ytop - edge->line.p1.y, dx, dy);
- e->x.quo += edge->line.p1.x;
- }
-
- if (e->height_left >= GRID_Y) {
- e->dxdy_full = floored_muldivrem (GRID_Y, dx, dy);
- } else {
- e->dxdy_full.quo = 0;
- e->dxdy_full.rem = 0;
- }
- }
-
- _polygon_insert_edge_into_its_y_bucket (polygon, e);
-
- e->x.rem -= dy; /* Bias the remainder for faster
- * edge advancement. */
-}
-
static void
active_list_reset (struct active_list *active)
{
- active->head.vertical = 1;
active->head.height_left = INT_MAX;
- active->head.x.quo = INT_MIN;
+ active->head.dy = 0;
+ active->head.cell = INT_MIN;
active->head.prev = NULL;
active->head.next = &active->tail;
active->tail.prev = &active->head;
active->tail.next = NULL;
- active->tail.x.quo = INT_MAX;
+ active->tail.cell = INT_MAX;
active->tail.height_left = INT_MAX;
- active->tail.vertical = 1;
+ active->tail.dy = 0;
active->min_height = 0;
active->is_vertical = 1;
}
@@ -1084,7 +1045,7 @@ merge_sorted_edges (struct edge *head_a, struct edge *head_b)
prev = head_a->prev;
next = &head;
- if (head_a->x.quo <= head_b->x.quo) {
+ if (head_a->cell <= head_b->cell) {
head = head_a;
} else {
head = head_b;
@@ -1093,8 +1054,8 @@ merge_sorted_edges (struct edge *head_a, struct edge *head_b)
}
do {
- x = head_b->x.quo;
- while (head_a != NULL && head_a->x.quo <= x) {
+ x = head_b->cell;
+ while (head_a != NULL && head_a->cell <= x) {
prev = head_a;
next = &head_a->next;
head_a = head_a->next;
@@ -1106,8 +1067,8 @@ merge_sorted_edges (struct edge *head_a, struct edge *head_b)
return head;
start_with_b:
- x = head_a->x.quo;
- while (head_b != NULL && head_b->x.quo <= x) {
+ x = head_a->cell;
+ while (head_b != NULL && head_b->cell <= x) {
prev = head_b;
next = &head_b->next;
head_b = head_b->next;
@@ -1153,7 +1114,7 @@ sort_edges (struct edge *list,
}
remaining = head_other->next;
- if (list->x.quo <= head_other->x.quo) {
+ if (list->cell <= head_other->cell) {
*head_out = list;
head_other->next = NULL;
} else {
@@ -1197,7 +1158,7 @@ can_do_full_row (struct active_list *active)
while (NULL != e) {
if (e->height_left < min_height)
min_height = e->height_left;
- is_vertical &= e->vertical;
+ is_vertical &= e->dy == 0;
e = e->next;
}
@@ -1210,19 +1171,27 @@ can_do_full_row (struct active_list *active)
/* Check for intersections as no edges end during the next row. */
for (e = active->head.next; e != &active->tail; e = e->next) {
- struct quorem x = e->x;
+ int cell;
- if (! e->vertical) {
+ if (e->dy) {
+ struct quorem x = e->x;
x.quo += e->dxdy_full.quo;
x.rem += e->dxdy_full.rem;
- if (x.rem >= 0)
- ++x.quo;
- }
+ if (x.rem < 0) {
+ x.quo--;
+ x.rem += e->dy;
+ } else if (x.rem >= e->dy) {
+ x.quo++;
+ x.rem -= e->dy;
+ }
+ cell = x.quo + (x.rem >= e->dy/2);
+ } else
+ cell = e->cell;
- if (x.quo < prev_x)
+ if (cell < prev_x)
return 0;
- prev_x = x.quo;
+ prev_x = cell;
}
return 1;
@@ -1237,7 +1206,7 @@ active_list_merge_edges_from_bucket(struct active_list *active,
active->head.next = merge_unsorted_edges (active->head.next, edges);
}
-inline static void
+inline static int
polygon_fill_buckets (struct active_list *active,
struct edge *edge,
int y,
@@ -1245,6 +1214,7 @@ polygon_fill_buckets (struct active_list *active,
{
grid_scaled_y_t min_height = active->min_height;
int is_vertical = active->is_vertical;
+ int max_suby = 0;
while (edge) {
struct edge *next = edge->next;
@@ -1256,12 +1226,34 @@ polygon_fill_buckets (struct active_list *active,
buckets[suby] = edge;
if (edge->height_left < min_height)
min_height = edge->height_left;
- is_vertical &= edge->vertical;
+ is_vertical &= edge->dy == 0;
edge = next;
+ if (suby > max_suby)
+ max_suby = suby;
}
active->is_vertical = is_vertical;
active->min_height = min_height;
+
+ return max_suby;
+}
+
+static void step (struct edge *edge)
+{
+ if (edge->dy == 0)
+ return;
+
+ edge->x.quo += edge->dxdy.quo;
+ edge->x.rem += edge->dxdy.rem;
+ if (edge->x.rem < 0) {
+ --edge->x.quo;
+ edge->x.rem += edge->dy;
+ } else if (edge->x.rem >= edge->dy) {
+ ++edge->x.quo;
+ edge->x.rem -= edge->dy;
+ }
+
+ edge->cell = edge->x.quo + (edge->x.rem >= edge->dy/2);
}
inline static void
@@ -1277,29 +1269,24 @@ sub_row (struct active_list *active,
while (&active->tail != edge) {
struct edge *next = edge->next;
- int xend = edge->x.quo;
+ int xend = edge->cell;
if (--edge->height_left) {
- edge->x.quo += edge->dxdy.quo;
- edge->x.rem += edge->dxdy.rem;
- if (edge->x.rem >= 0) {
- ++edge->x.quo;
- edge->x.rem -= edge->dy;
- }
+ step (edge);
- if (edge->x.quo < prev_x) {
+ if (edge->cell < prev_x) {
struct edge *pos = edge->prev;
pos->next = next;
next->prev = pos;
do {
pos = pos->prev;
- } while (edge->x.quo < pos->x.quo);
+ } while (edge->cell < pos->cell);
pos->next->prev = edge;
edge->next = pos->next;
edge->prev = pos;
pos->next = edge;
} else
- prev_x = edge->x.quo;
+ prev_x = edge->cell;
active->min_height = -1;
} else {
edge->prev->next = next;
@@ -1308,7 +1295,7 @@ sub_row (struct active_list *active,
winding += edge->dir;
if ((winding & mask) == 0) {
- if (next->x.quo != xend) {
+ if (next->cell != xend) {
cell_list_add_subspan (coverages, xstart, xend);
xstart = INT_MIN;
}
@@ -1329,18 +1316,6 @@ inline static void dec (struct active_list *a, struct edge *e, int h)
}
}
-inline static void full_step (struct edge *e)
-{
- if (! e->vertical) {
- e->x.quo += e->dxdy_full.quo;
- e->x.rem += e->dxdy_full.rem;
- if (e->x.rem >= 0) {
- ++e->x.quo;
- e->x.rem -= e->dy;
- }
- }
-}
-
static void
full_row (struct active_list *active,
struct cell_list *coverages,
@@ -1360,7 +1335,7 @@ full_row (struct active_list *active,
dec (active, right, GRID_Y);
winding += right->dir;
- if ((winding & mask) == 0 && right->next->x.quo != right->x.quo)
+ if ((winding & mask) == 0 && right->next->cell != right->cell)
break;
full_step (right);
@@ -1482,10 +1457,96 @@ glitter_scan_converter_reset(
#define INPUT_TO_GRID_general(in, out, grid_scale) do { \
long long tmp__ = (long long)(grid_scale) * (in); \
+ tmp__ += 1 << (GLITTER_INPUT_BITS-1); \
tmp__ >>= GLITTER_INPUT_BITS; \
(out) = tmp__; \
} while (0)
+inline static void
+polygon_add_edge (struct polygon *polygon,
+ const cairo_edge_t *edge)
+{
+ struct edge *e;
+ grid_scaled_y_t ytop, ybot;
+ const cairo_point_t *p1, *p2;
+
+ INPUT_TO_GRID_Y (edge->top, ytop);
+ if (ytop < polygon->ymin)
+ ytop = polygon->ymin;
+
+ INPUT_TO_GRID_Y (edge->bottom, ybot);
+ if (ybot > polygon->ymax)
+ ybot = polygon->ymax;
+
+ if (ybot <= ytop)
+ return;
+
+ e = pool_alloc (polygon->edge_pool.base, sizeof (struct edge));
+
+ e->ytop = ytop;
+ e->height_left = ybot - ytop;
+ if (edge->line.p2.y > edge->line.p1.y) {
+ e->dir = edge->dir;
+ p1 = &edge->line.p1;
+ p2 = &edge->line.p2;
+ } else {
+ e->dir = -edge->dir;
+ p1 = &edge->line.p2;
+ p2 = &edge->line.p1;
+ }
+
+ if (p2->x == p1->x) {
+ e->cell = p1->x;
+ e->x.quo = p1->x;
+ e->x.rem = 0;
+ e->dxdy.quo = e->dxdy.rem = 0;
+ e->dxdy_full.quo = e->dxdy_full.rem = 0;
+ e->dy = 0;
+ } else {
+ int64_t Ex, Ey, tmp;
+
+ Ex = (int64_t)(p2->x - p1->x) * GRID_X;
+ Ey = (int64_t)(p2->y - p1->y) * GRID_Y * (2 << GLITTER_INPUT_BITS);
+
+ e->dxdy.quo = Ex * (2 << GLITTER_INPUT_BITS) / Ey;
+ e->dxdy.rem = Ex * (2 << GLITTER_INPUT_BITS) % Ey;
+
+ tmp = (int64_t)(2*ytop + 1) << GLITTER_INPUT_BITS;
+ tmp -= (int64_t)p1->y * GRID_Y * 2;
+ tmp *= Ex;
+ e->x.quo = tmp / Ey;
+ e->x.rem = tmp % Ey;
+
+#if GRID_X_BITS == GLITTER_INPUT_BITS
+ e->x.quo += p1->x;
+#else
+ tmp = (int64_t)p1->x * GRID_X;
+ e->x.quo += tmp >> GLITTER_INPUT_BITS;
+ e->x.rem += ((tmp & ((1 << GLITTER_INPUT_BITS) - 1)) * Ey) / (1 << GLITTER_INPUT_BITS);
+#endif
+
+ if (e->x.rem < 0) {
+ e->x.quo--;
+ e->x.rem += Ey;
+ } else if (e->x.rem >= Ey) {
+ e->x.quo++;
+ e->x.rem -= Ey;
+ }
+
+ if (e->height_left >= GRID_Y) {
+ tmp = Ex * (2 * GRID_Y << GLITTER_INPUT_BITS);
+ e->dxdy_full.quo = tmp / Ey;
+ e->dxdy_full.rem = tmp % Ey;
+ } else
+ e->dxdy_full.quo = e->dxdy_full.rem = 0;
+
+ e->cell = e->x.quo + (e->x.rem >= Ey/2);
+ e->dy = Ey;
+ }
+
+ _polygon_insert_edge_into_its_y_bucket (polygon, e);
+}
+
/* Add a new polygon edge from pixel (x1,y1) to (x2,y2) to the scan
* converter. The coordinates represent pixel positions scaled by
* 2**GLITTER_PIXEL_BITS. If this function fails then the scan
@@ -1495,25 +1556,7 @@ I void
glitter_scan_converter_add_edge (glitter_scan_converter_t *converter,
const cairo_edge_t *edge)
{
- cairo_edge_t e;
-
- INPUT_TO_GRID_Y (edge->top, e.top);
- INPUT_TO_GRID_Y (edge->bottom, e.bottom);
- if (e.top >= e.bottom)
- return;
-
- /* XXX: possible overflows if GRID_X/Y > 2**GLITTER_INPUT_BITS */
- INPUT_TO_GRID_Y (edge->line.p1.y, e.line.p1.y);
- INPUT_TO_GRID_Y (edge->line.p2.y, e.line.p2.y);
- if (e.line.p1.y == e.line.p2.y)
- e.line.p2.y++; /* little fudge to prevent a div-by-zero */
-
- INPUT_TO_GRID_X (edge->line.p1.x, e.line.p1.x);
- INPUT_TO_GRID_X (edge->line.p2.x, e.line.p2.x);
-
- e.dir = edge->dir;
-
- polygon_add_edge (converter->polygon, &e);
+ polygon_add_edge (converter->polygon, edge);
}
static void
@@ -1699,7 +1742,15 @@ glitter_scan_converter_render(glitter_scan_converter_t *converter,
/* Determine if we can ignore this row or use the full pixel
* stepper. */
- if (! polygon->y_buckets[i]) {
+ if (polygon_fill_buckets (active,
+ polygon->y_buckets[i],
+ (i+ymin_i)*GRID_Y,
+ buckets) == 0) {
+ if (buckets[0]) {
+ active_list_merge_edges_from_bucket (active, buckets[0]);
+ buckets[0] = NULL;
+ }
+
if (active->head.next == &active->tail) {
active->min_height = INT_MAX;
active->is_vertical = 1;
@@ -1729,18 +1780,12 @@ glitter_scan_converter_render(glitter_scan_converter_t *converter,
} else {
int sub;
- polygon_fill_buckets (active,
- polygon->y_buckets[i],
- (i+ymin_i)*GRID_Y,
- buckets);
-
/* Subsample this row. */
for (sub = 0; sub < GRID_Y; sub++) {
if (buckets[sub]) {
active_list_merge_edges_from_bucket (active, buckets[sub]);
buckets[sub] = NULL;
}
-
sub_row (active, coverages, winding_mask);
}
}
diff --git a/src/cairo-tor22-scan-converter.c b/src/cairo-tor22-scan-converter.c
index 4cec5ee4f..4cec5ee4f 100755..100644
--- a/src/cairo-tor22-scan-converter.c
+++ b/src/cairo-tor22-scan-converter.c
diff --git a/src/cairo-toy-font-face.c b/src/cairo-toy-font-face.c
index 363b9a284..4fe94ab09 100755..100644
--- a/src/cairo-toy-font-face.c
+++ b/src/cairo-toy-font-face.c
@@ -342,7 +342,7 @@ cairo_toy_font_face_create (const char *family,
}
slim_hidden_def (cairo_toy_font_face_create);
-static void
+static cairo_bool_t
_cairo_toy_font_face_destroy (void *abstract_face)
{
cairo_toy_font_face_t *font_face = abstract_face;
@@ -352,10 +352,10 @@ _cairo_toy_font_face_destroy (void *abstract_face)
/* All created objects must have been mapped in the hash table. */
assert (hash_table != NULL);
- if (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&font_face->base.ref_count)) {
+ if (! _cairo_reference_count_dec_and_test (&font_face->base.ref_count)) {
/* somebody recreated the font whilst we waited for the lock */
_cairo_toy_font_face_hash_table_unlock ();
- return;
+ return FALSE;
}
/* Font faces in SUCCESS status are guaranteed to be in the
@@ -369,6 +369,7 @@ _cairo_toy_font_face_destroy (void *abstract_face)
_cairo_toy_font_face_hash_table_unlock ();
_cairo_toy_font_face_fini (font_face);
+ return TRUE;
}
static cairo_status_t
diff --git a/src/cairo-traps-compositor.c b/src/cairo-traps-compositor.c
index 5d561f2be..c26a5df6f 100755..100644
--- a/src/cairo-traps-compositor.c
+++ b/src/cairo-traps-compositor.c
@@ -209,18 +209,18 @@ combine_clip_as_traps (const cairo_traps_compositor_t *compositor,
return src->status;
}
- if (draw_color_glyph)
- status = compositor->composite_traps (mask, CAIRO_OPERATOR_IN, mask,
- 0, 0,
- extents->x, extents->y,
- extents,
- antialias, &traps);
- else
+ if (draw_color_glyph)
+ status = compositor->composite_traps (mask, CAIRO_OPERATOR_IN, mask,
+ 0, 0,
+ extents->x, extents->y,
+ extents,
+ antialias, &traps);
+ else
status = compositor->composite_traps (mask, CAIRO_OPERATOR_IN, src,
- src_x, src_y,
- extents->x, extents->y,
- extents,
- antialias, &traps);
+ src_x, src_y,
+ extents->x, extents->y,
+ extents,
+ antialias, &traps);
_cairo_traps_extents (&traps, &box);
_cairo_box_round_to_rectangle (&box, &fixup);
@@ -315,10 +315,11 @@ __clip_to_surface (const cairo_traps_compositor_t *compositor,
if (unlikely (status))
return status;
- mask = _cairo_surface_create_similar_scratch (composite->surface,
- CAIRO_CONTENT_ALPHA,
- extents->width,
- extents->height);
+ mask = _cairo_surface_create_scratch (composite->surface,
+ CAIRO_CONTENT_ALPHA,
+ extents->width,
+ extents->height,
+ NULL);
if (unlikely (mask->status)) {
_cairo_traps_fini (&traps);
return status;
@@ -379,11 +380,11 @@ traps_get_clip_surface (const cairo_traps_compositor_t *compositor,
status = __clip_to_surface (compositor, composite, extents, &surface);
if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
- surface = _cairo_surface_create_similar_solid (composite->surface,
- CAIRO_CONTENT_ALPHA,
- extents->width,
- extents->height,
- CAIRO_COLOR_WHITE);
+ surface = _cairo_surface_create_scratch (composite->surface,
+ CAIRO_CONTENT_ALPHA,
+ extents->width,
+ extents->height,
+ CAIRO_COLOR_WHITE);
if (unlikely (surface->status))
return surface;
@@ -435,21 +436,22 @@ create_composite_mask (const cairo_traps_compositor_t *compositor,
cairo_surface_t *surface, *src;
cairo_int_status_t status;
int src_x, src_y;
- cairo_bool_t draw_color_glyph = FALSE;
+ cairo_bool_t draw_color_glyph = FALSE;
TRACE ((stderr, "%s\n", __FUNCTION__));
- surface = _cairo_surface_create_similar_scratch (dst, CAIRO_CONTENT_ALPHA,
- extents->bounded.width,
- extents->bounded.height);
+ surface = _cairo_surface_create_scratch (dst, CAIRO_CONTENT_ALPHA,
+ extents->bounded.width,
+ extents->bounded.height,
+ NULL);
if (unlikely (surface->status))
return surface;
- /* FIXME: This is more like an ugly hack and wasteful. Reason
- for this code is that we don't know whether the mask surface
- should alpha-only or argb32 before we render a glyph.
- */
- redo:
+ /* FIXME: This is more like an ugly hack and wasteful. Reason
+ for this code is that we don't know whether the mask surface
+ should alpha-only or argb32 before we render a glyph.
+ */
+redo:
src = compositor->pattern_to_surface (surface,
&_cairo_pattern_white.base,
FALSE,
@@ -503,22 +505,22 @@ create_composite_mask (const cairo_traps_compositor_t *compositor,
CAIRO_OPERATOR_ADD, src, src_x, src_y,
extents->bounded.x, extents->bounded.y,
&extents->bounded, NULL);
- if (unlikely (status)){
- if (cairo_surface_get_content (surface) == CAIRO_CONTENT_COLOR_ALPHA)
- goto error;
- else {
- compositor->release (surface);
- cairo_surface_destroy (surface);
- cairo_surface_destroy (src);
- surface = _cairo_surface_create_similar_scratch (dst, CAIRO_CONTENT_COLOR_ALPHA,
- extents->bounded.width,
- extents->bounded.height);
- if (unlikely (surface->status))
- return surface;
- /* we are drawing color glyph */
- draw_color_glyph = TRUE;
- goto redo;
- }
+ if (unlikely (status)) {
+ if (cairo_surface_get_content (surface) == CAIRO_CONTENT_COLOR_ALPHA)
+ goto error;
+ else {
+ compositor->release (surface);
+ cairo_surface_destroy (surface);
+ cairo_surface_destroy (src);
+ surface = _cairo_surface_create_similar_scratch (dst, CAIRO_CONTENT_COLOR_ALPHA,
+ extents->bounded.width,
+ extents->bounded.height);
+ if (unlikely (surface->status))
+ return surface;
+ /* we are drawing color glyph */
+ draw_color_glyph = TRUE;
+ goto redo;
+ }
}
surface->is_clear = FALSE;
@@ -582,30 +584,31 @@ clip_and_composite_with_mask (const cairo_traps_compositor_t *compositor,
if (mask->is_clear)
goto skip;
- if (mask->content == CAIRO_CONTENT_ALPHA) {
- /* This is real mask */
- if (src != NULL || dst->content != CAIRO_CONTENT_ALPHA) {
- compositor->composite (dst, op, src, mask,
- extents->bounded.x + src_x,
- extents->bounded.y + src_y,
- 0, 0,
- extents->bounded.x, extents->bounded.y,
- extents->bounded.width, extents->bounded.height);
- } else {
- compositor->composite (dst, op, mask, NULL,
- 0, 0,
- 0, 0,
- extents->bounded.x, extents->bounded.y,
- extents->bounded.width, extents->bounded.height);
- }
+ if (mask->content == CAIRO_CONTENT_ALPHA) {
+ /* This is real mask */
+ if (src != NULL || dst->content != CAIRO_CONTENT_ALPHA) {
+ compositor->composite (dst, op, src, mask,
+ extents->bounded.x + src_x,
+ extents->bounded.y + src_y,
+ 0, 0,
+ extents->bounded.x, extents->bounded.y,
+ extents->bounded.width, extents->bounded.height);
} else {
- compositor->composite (dst, op, mask, NULL,
- 0, 0,
- extents->bounded.x + src_x,
- extents->bounded.y + src_y,
- extents->bounded.x, extents->bounded.y,
- extents->bounded.width, extents->bounded.height);
+ compositor->composite (dst, op, mask, NULL,
+ 0, 0,
+ 0, 0,
+ extents->bounded.x, extents->bounded.y,
+ extents->bounded.width, extents->bounded.height);
}
+ }
+ else {
+ compositor->composite (dst, op, mask, NULL,
+ 0, 0,
+ extents->bounded.x + src_x,
+ extents->bounded.y + src_y,
+ extents->bounded.x, extents->bounded.y,
+ extents->bounded.width, extents->bounded.height);
+ }
skip:
cairo_surface_destroy (mask);
return CAIRO_STATUS_SUCCESS;
@@ -629,9 +632,10 @@ clip_and_composite_combine (const cairo_traps_compositor_t *compositor,
TRACE ((stderr, "%s\n", __FUNCTION__));
- tmp = _cairo_surface_create_similar_scratch (dst, dst->content,
- extents->bounded.width,
- extents->bounded.height);
+ tmp = _cairo_surface_create_scratch (dst, dst->content,
+ extents->bounded.width,
+ extents->bounded.height,
+ NULL);
if (unlikely (tmp->status)) {
status = tmp->status;
cairo_surface_destroy (tmp);
@@ -701,15 +705,15 @@ clip_and_composite_source (const cairo_traps_compositor_t *compositor,
const cairo_composite_rectangles_t *extents)
{
cairo_surface_t *mask = NULL;
- /* create a white color pattern */
- cairo_pattern_t *white_pattern = _cairo_pattern_create_solid (CAIRO_COLOR_WHITE);
- cairo_surface_t *white_mask =
- compositor->pattern_to_surface (dst, white_pattern, TRUE,
- &extents->bounded,
- &extents->source_sample_area,
- &src_x, &src_y);
- if (unlikely (white_mask->status))
- goto skip;
+ /* create a white color pattern */
+ cairo_pattern_t *white_pattern = _cairo_pattern_create_solid (CAIRO_COLOR_WHITE);
+ cairo_surface_t *white_mask =
+ compositor->pattern_to_surface (dst, white_pattern, TRUE,
+ &extents->bounded,
+ &extents->source_sample_area,
+ &src_x, &src_y);
+ if (unlikely (white_mask->status))
+ goto skip;
TRACE ((stderr, "%s\n", __FUNCTION__));
@@ -731,22 +735,22 @@ clip_and_composite_source (const cairo_traps_compositor_t *compositor,
extents->bounded.width, extents->bounded.height);
} else {
if (mask->content == CAIRO_CONTENT_ALPHA)
- compositor->lerp (dst, src, mask,
- extents->bounded.x + src_x, extents->bounded.y + src_y,
+ compositor->lerp (dst, src, mask,
+ extents->bounded.x + src_x, extents->bounded.y + src_y,
+ 0, 0,
+ extents->bounded.x, extents->bounded.y,
+ extents->bounded.width, extents->bounded.height);
+ else
+ compositor->lerp_color_glyph (dst, mask, white_mask,
0, 0,
+ extents->bounded.x + src_x, extents->bounded.y + src_y,
extents->bounded.x, extents->bounded.y,
extents->bounded.width, extents->bounded.height);
- else
- compositor->lerp_color_glyph (dst, mask, white_mask,
- 0, 0,
- extents->bounded.x + src_x, extents->bounded.y + src_y,
- extents->bounded.x, extents->bounded.y,
- extents->bounded.width, extents->bounded.height);
- }
+ }
skip:
cairo_surface_destroy (mask);
- cairo_surface_destroy (white_mask);
+ cairo_surface_destroy (white_mask);
cairo_pattern_destroy (white_pattern);
return CAIRO_STATUS_SUCCESS;
@@ -988,12 +992,20 @@ need_bounded_clip (cairo_composite_rectangles_t *extents)
{
unsigned int flags = 0;
- if (extents->unbounded.width < extents->destination.width ||
- extents->unbounded.height < extents->destination.height)
+ if (extents->clip->num_boxes > 1 ||
+ extents->mask.width > extents->unbounded.width ||
+ extents->mask.height > extents->unbounded.height)
{
flags |= NEED_CLIP_REGION;
}
+ if (extents->clip->num_boxes > 1 ||
+ extents->mask.width > extents->bounded.width ||
+ extents->mask.height > extents->bounded.height)
+ {
+ flags |= FORCE_CLIP_REGION;
+ }
+
if (! _cairo_clip_is_region (extents->clip))
flags |= NEED_CLIP_SURFACE;
@@ -1258,7 +1270,9 @@ composite_aligned_boxes (const cairo_traps_compositor_t *compositor,
&extents->source_sample_area))
{
cairo_clip_t *recording_clip;
- cairo_pattern_t *source = &extents->source_pattern.base;
+ const cairo_pattern_t *source = &extents->source_pattern.base;
+ const cairo_matrix_t *m;
+ cairo_matrix_t matrix;
/* XXX could also do tiling repeat modes... */
@@ -1277,10 +1291,17 @@ composite_aligned_boxes (const cairo_traps_compositor_t *compositor,
return status;
}
+ m = &source->matrix;
+ if (_cairo_surface_has_device_transform (dst)) {
+ cairo_matrix_multiply (&matrix,
+ &source->matrix,
+ &dst->device_transform);
+ m = &matrix;
+ }
+
recording_clip = _cairo_clip_from_boxes (boxes);
status = _cairo_recording_surface_replay_with_clip (recording_pattern_get_surface (source),
- &source->matrix,
- dst, recording_clip);
+ m, dst, recording_clip);
_cairo_clip_destroy (recording_clip);
return status;
@@ -1433,7 +1454,7 @@ boxes_for_traps (cairo_boxes_t *boxes,
cairo_traps_t *traps,
cairo_antialias_t antialias)
{
- int i;
+ int i, j;
/* first check that the traps are rectilinear */
if (antialias == CAIRO_ANTIALIAS_NONE) {
@@ -1457,23 +1478,25 @@ boxes_for_traps (cairo_boxes_t *boxes,
_cairo_boxes_init (boxes);
- boxes->num_boxes = traps->num_traps;
boxes->chunks.base = (cairo_box_t *) traps->traps;
- boxes->chunks.count = traps->num_traps;
boxes->chunks.size = traps->num_traps;
if (antialias != CAIRO_ANTIALIAS_NONE) {
- for (i = 0; i < traps->num_traps; i++) {
+ for (i = j = 0; i < traps->num_traps; i++) {
/* Note the traps and boxes alias so we need to take the local copies first. */
cairo_fixed_t x1 = traps->traps[i].left.p1.x;
cairo_fixed_t x2 = traps->traps[i].right.p1.x;
cairo_fixed_t y1 = traps->traps[i].top;
cairo_fixed_t y2 = traps->traps[i].bottom;
- boxes->chunks.base[i].p1.x = x1;
- boxes->chunks.base[i].p1.y = y1;
- boxes->chunks.base[i].p2.x = x2;
- boxes->chunks.base[i].p2.y = y2;
+ if (x1 == x2 || y1 == y2)
+ continue;
+
+ boxes->chunks.base[j].p1.x = x1;
+ boxes->chunks.base[j].p1.y = y1;
+ boxes->chunks.base[j].p2.x = x2;
+ boxes->chunks.base[j].p2.y = y2;
+ j++;
if (boxes->is_pixel_aligned) {
boxes->is_pixel_aligned =
@@ -1484,7 +1507,7 @@ boxes_for_traps (cairo_boxes_t *boxes,
} else {
boxes->is_pixel_aligned = TRUE;
- for (i = 0; i < traps->num_traps; i++) {
+ for (i = j = 0; i < traps->num_traps; i++) {
/* Note the traps and boxes alias so we need to take the local copies first. */
cairo_fixed_t x1 = traps->traps[i].left.p1.x;
cairo_fixed_t x2 = traps->traps[i].right.p1.x;
@@ -1492,12 +1515,16 @@ boxes_for_traps (cairo_boxes_t *boxes,
cairo_fixed_t y2 = traps->traps[i].bottom;
/* round down here to match Pixman's behavior when using traps. */
- boxes->chunks.base[i].p1.x = _cairo_fixed_round_down (x1);
- boxes->chunks.base[i].p1.y = _cairo_fixed_round_down (y1);
- boxes->chunks.base[i].p2.x = _cairo_fixed_round_down (x2);
- boxes->chunks.base[i].p2.y = _cairo_fixed_round_down (y2);
+ boxes->chunks.base[j].p1.x = _cairo_fixed_round_down (x1);
+ boxes->chunks.base[j].p1.y = _cairo_fixed_round_down (y1);
+ boxes->chunks.base[j].p2.x = _cairo_fixed_round_down (x2);
+ boxes->chunks.base[j].p2.y = _cairo_fixed_round_down (y2);
+ j += (boxes->chunks.base[j].p1.x != boxes->chunks.base[j].p2.x &&
+ boxes->chunks.base[j].p1.y != boxes->chunks.base[j].p2.y);
}
}
+ boxes->chunks.count = j;
+ boxes->num_boxes = j;
return CAIRO_INT_STATUS_SUCCESS;
}
@@ -2220,18 +2247,14 @@ _cairo_traps_compositor_stroke (const cairo_compositor_t *_compositor,
double tolerance,
cairo_traps_t *traps);
composite_traps_info_t info;
- unsigned flags = 0;
+ unsigned flags;
if (antialias == CAIRO_ANTIALIAS_BEST || antialias == CAIRO_ANTIALIAS_GOOD) {
func = _cairo_path_fixed_stroke_polygon_to_traps;
+ flags = 0;
} else {
func = _cairo_path_fixed_stroke_to_traps;
- if (extents->clip->num_boxes > 1 ||
- extents->mask.width > extents->unbounded.width ||
- extents->mask.height > extents->unbounded.height)
- {
- flags = NEED_CLIP_REGION | FORCE_CLIP_REGION;
- }
+ flags = need_bounded_clip (extents) & ~NEED_CLIP_SURFACE;
}
info.antialias = antialias;
@@ -2353,16 +2376,12 @@ _cairo_traps_compositor_glyphs (const cairo_compositor_t *_compositor,
if (unlikely (status))
return status;
-#if ! CAIRO_HAS_TG_SURFACE
_cairo_scaled_font_freeze_cache (scaled_font);
-#endif
-
status = compositor->check_composite_glyphs (extents,
scaled_font, glyphs,
&num_glyphs);
if (likely (status == CAIRO_INT_STATUS_SUCCESS)) {
cairo_composite_glyphs_info_t info;
- unsigned flags = 0;
info.font = scaled_font;
info.glyphs = glyphs;
@@ -2370,21 +2389,11 @@ _cairo_traps_compositor_glyphs (const cairo_compositor_t *_compositor,
info.use_mask = overlap || ! extents->is_bounded;
info.extents = extents->bounded;
- if (extents->mask.width > extents->bounded.width ||
- extents->mask.height > extents->bounded.height)
- {
- flags |= FORCE_CLIP_REGION;
- }
-
status = clip_and_composite (compositor, extents,
composite_glyphs, NULL, &info,
- need_bounded_clip (extents) |
- flags);
+ need_bounded_clip (extents) | FORCE_CLIP_REGION);
}
-
-#if ! CAIRO_HAS_TG_SURFACE
_cairo_scaled_font_thaw_cache (scaled_font);
-#endif
return status;
}
diff --git a/src/cairo-traps-private.h b/src/cairo-traps-private.h
index 7fef062a4..dcaf40d18 100755..100644
--- a/src/cairo-traps-private.h
+++ b/src/cairo-traps-private.h
@@ -91,8 +91,9 @@ cairo_private void
_cairo_traps_translate (cairo_traps_t *traps, int x, int y);
cairo_private void
-_cairo_traps_tessellate_triangle (cairo_traps_t *traps,
- const cairo_point_t t[3]);
+_cairo_traps_tessellate_triangle_with_edges (cairo_traps_t *traps,
+ const cairo_point_t t[3],
+ const cairo_point_t edges[4]);
cairo_private void
_cairo_traps_tessellate_convex_quad (cairo_traps_t *traps,
@@ -106,7 +107,8 @@ _cairo_traps_tessellate_rectangle (cairo_traps_t *traps,
cairo_private void
_cairo_traps_add_trap (cairo_traps_t *traps,
cairo_fixed_t top, cairo_fixed_t bottom,
- cairo_line_t *left, cairo_line_t *right);
+ const cairo_line_t *left,
+ const cairo_line_t *right);
cairo_private int
_cairo_traps_contain (const cairo_traps_t *traps,
diff --git a/src/cairo-traps.c b/src/cairo-traps.c
index 8bdac45ab..92abe4496 100755..100644
--- a/src/cairo-traps.c
+++ b/src/cairo-traps.c
@@ -42,6 +42,7 @@
#include "cairo-box-inline.h"
#include "cairo-boxes-private.h"
#include "cairo-error-private.h"
+#include "cairo-line-private.h"
#include "cairo-region-private.h"
#include "cairo-slope-private.h"
#include "cairo-traps-private.h"
@@ -150,10 +151,20 @@ _cairo_traps_grow (cairo_traps_t *traps)
void
_cairo_traps_add_trap (cairo_traps_t *traps,
cairo_fixed_t top, cairo_fixed_t bottom,
- cairo_line_t *left, cairo_line_t *right)
+ const cairo_line_t *left,
+ const cairo_line_t *right)
{
cairo_trapezoid_t *trap;
+ /* These asserts cause reporting of unreal crashes
+ in the case of gl/msaa.
+ Temporarily removed */
+ /*
+ assert (left->p1.y != left->p2.y);
+ assert (right->p1.y != right->p2.y);
+ assert (bottom > top);
+ */
+
if (unlikely (traps->num_traps == traps->traps_size)) {
if (unlikely (! _cairo_traps_grow (traps)))
return;
@@ -169,7 +180,8 @@ _cairo_traps_add_trap (cairo_traps_t *traps,
static void
_cairo_traps_add_clipped_trap (cairo_traps_t *traps,
cairo_fixed_t _top, cairo_fixed_t _bottom,
- cairo_line_t *_left, cairo_line_t *_right)
+ const cairo_line_t *_left,
+ const cairo_line_t *_right)
{
/* Note: With the goofy trapezoid specification, (where an
* arbitrary two points on the lines can specified for the left
@@ -387,23 +399,73 @@ _cairo_traps_tessellate_convex_quad (cairo_traps_t *traps,
}
}
-/* A triangle is simply a degenerate case of a convex
- * quadrilateral. We would not benefit from having any distinct
- * implementation of triangle vs. quadrilateral tessellation here. */
-void
-_cairo_traps_tessellate_triangle (cairo_traps_t *traps,
- const cairo_point_t t[3])
+static void add_tri (cairo_traps_t *traps,
+ int y1, int y2,
+ const cairo_line_t *left,
+ const cairo_line_t *right)
{
- cairo_point_t quad[4];
+ if (y2 < y1) {
+ int tmp = y1;
+ y1 = y2;
+ y2 = tmp;
+ }
- quad[0] = t[0];
- quad[1] = t[0];
- quad[2] = t[1];
- quad[3] = t[2];
+ if (cairo_lines_compare_at_y (left, right, y1) > 0) {
+ const cairo_line_t *tmp = left;
+ left = right;
+ right = tmp;
+ }
- _cairo_traps_tessellate_convex_quad (traps, quad);
+ _cairo_traps_add_clipped_trap (traps, y1, y2, left, right);
}
+void
+_cairo_traps_tessellate_triangle_with_edges (cairo_traps_t *traps,
+ const cairo_point_t t[3],
+ const cairo_point_t edges[4])
+{
+ cairo_line_t lines[3];
+
+ if (edges[0].y <= edges[1].y) {
+ lines[0].p1 = edges[0];
+ lines[0].p2 = edges[1];
+ } else {
+ lines[0].p1 = edges[1];
+ lines[0].p2 = edges[0];
+ }
+
+ if (edges[2].y <= edges[3].y) {
+ lines[1].p1 = edges[2];
+ lines[1].p2 = edges[3];
+ } else {
+ lines[1].p1 = edges[3];
+ lines[1].p2 = edges[2];
+ }
+
+ if (t[1].y == t[2].y) {
+ add_tri (traps, t[0].y, t[1].y, &lines[0], &lines[1]);
+ return;
+ }
+
+ if (t[1].y <= t[2].y) {
+ lines[2].p1 = t[1];
+ lines[2].p2 = t[2];
+ } else {
+ lines[2].p1 = t[2];
+ lines[2].p2 = t[1];
+ }
+
+ if (((t[1].y - t[0].y) < 0) ^ ((t[2].y - t[0].y) < 0)) {
+ add_tri (traps, t[0].y, t[1].y, &lines[0], &lines[2]);
+ add_tri (traps, t[0].y, t[2].y, &lines[1], &lines[2]);
+ } else if (abs(t[1].y - t[0].y) < abs(t[2].y - t[0].y)) {
+ add_tri (traps, t[0].y, t[1].y, &lines[0], &lines[1]);
+ add_tri (traps, t[1].y, t[2].y, &lines[2], &lines[1]);
+ } else {
+ add_tri (traps, t[0].y, t[2].y, &lines[1], &lines[0]);
+ add_tri (traps, t[1].y, t[2].y, &lines[2], &lines[0]);
+ }
+}
/**
* _cairo_traps_init_boxes:
diff --git a/src/cairo-tristrip-private.h b/src/cairo-tristrip-private.h
index ccd28799e..ccd28799e 100755..100644
--- a/src/cairo-tristrip-private.h
+++ b/src/cairo-tristrip-private.h
diff --git a/src/cairo-tristrip.c b/src/cairo-tristrip.c
index bb4972f50..bb4972f50 100755..100644
--- a/src/cairo-tristrip.c
+++ b/src/cairo-tristrip.c
diff --git a/src/cairo-truetype-subset-private.h b/src/cairo-truetype-subset-private.h
index dc9573216..dc9573216 100755..100644
--- a/src/cairo-truetype-subset-private.h
+++ b/src/cairo-truetype-subset-private.h
diff --git a/src/cairo-truetype-subset.c b/src/cairo-truetype-subset.c
index 44d7f60f5..fa33d63e4 100755..100644
--- a/src/cairo-truetype-subset.c
+++ b/src/cairo-truetype-subset.c
@@ -1572,40 +1572,11 @@ _cairo_truetype_read_font_name (cairo_scaled_font_t *scaled_font,
goto fail;
}
- free (name);
+ status = _cairo_escape_ps_name (&ps_name);
+ if (unlikely(status))
+ goto fail;
- /* Ensure PS name is a valid PDF/PS name object. In PDF names are
- * treated as UTF8 and non ASCII bytes, ' ', and '#' are encoded
- * as '#' followed by 2 hex digits that encode the byte. By also
- * encoding the characters in the reserved string we ensure the
- * name is also PS compatible. */
- if (ps_name) {
- static const char *reserved = "()<>[]{}/%#\\";
- char buf[128]; /* max name length is 127 bytes */
- char *src = ps_name;
- char *dst = buf;
-
- while (*src && dst < buf + 127) {
- unsigned char c = *src;
- if (c < 0x21 || c > 0x7e || strchr (reserved, c)) {
- if (dst + 4 > buf + 127)
- break;
-
- snprintf (dst, 4, "#%02X", c);
- src++;
- dst += 3;
- } else {
- *dst++ = *src++;
- }
- }
- *dst = 0;
- free (ps_name);
- ps_name = strdup (buf);
- if (ps_name == NULL) {
- status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
- goto fail;
- }
- }
+ free (name);
*ps_name_out = ps_name;
*font_name_out = family_name;
diff --git a/src/cairo-type1-fallback.c b/src/cairo-type1-fallback.c
index d7d6eae12..d7d6eae12 100755..100644
--- a/src/cairo-type1-fallback.c
+++ b/src/cairo-type1-fallback.c
diff --git a/src/cairo-type1-glyph-names.c b/src/cairo-type1-glyph-names.c
index 80ccb9626..80ccb9626 100755..100644
--- a/src/cairo-type1-glyph-names.c
+++ b/src/cairo-type1-glyph-names.c
diff --git a/src/cairo-type1-private.h b/src/cairo-type1-private.h
index 1630397bc..1630397bc 100755..100644
--- a/src/cairo-type1-private.h
+++ b/src/cairo-type1-private.h
diff --git a/src/cairo-type1-subset.c b/src/cairo-type1-subset.c
index 8453cbd7d..81a1bdbc1 100755..100644
--- a/src/cairo-type1-subset.c
+++ b/src/cairo-type1-subset.c
@@ -53,7 +53,6 @@
#include "cairo-output-stream-private.h"
#include <ctype.h>
-#include <locale.h>
#define TYPE1_STACKSIZE 24 /* Defined in Type 1 Font Format */
@@ -309,12 +308,10 @@ cairo_type1_font_subset_get_matrix (cairo_type1_font_subset_t *font,
const char *start, *end, *segment_end;
int ret, s_max, i, j;
char *s;
- struct lconv *locale_data;
const char *decimal_point;
int decimal_point_len;
- locale_data = localeconv ();
- decimal_point = locale_data->decimal_point;
+ decimal_point = cairo_get_locale_decimal_point ();
decimal_point_len = strlen (decimal_point);
assert (decimal_point_len != 0);
@@ -407,6 +404,7 @@ cairo_type1_font_subset_get_fontname (cairo_type1_font_subset_t *font)
const char *start, *end, *segment_end;
char *s;
int i;
+ cairo_status_t status;
segment_end = font->header_segment + font->header_segment_size;
start = find_token (font->header_segment, segment_end, "/FontName");
@@ -419,6 +417,9 @@ cairo_type1_font_subset_get_fontname (cairo_type1_font_subset_t *font)
if (end == NULL)
return CAIRO_INT_STATUS_UNSUPPORTED;
+ while (end > start && _cairo_isspace(end[-1]))
+ end--;
+
s = malloc (end - start + 1);
if (unlikely (s == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
@@ -447,13 +448,9 @@ cairo_type1_font_subset_get_fontname (cairo_type1_font_subset_t *font)
if (unlikely (font->base.base_font == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
- s = font->base.base_font;
- while (*s && !is_ps_delimiter(*s))
- s++;
-
- *s = 0;
+ status = _cairo_escape_ps_name (&font->base.base_font);
- return CAIRO_STATUS_SUCCESS;
+ return status;
}
static cairo_status_t
@@ -1133,8 +1130,9 @@ write_used_glyphs (cairo_type1_font_subset_t *font,
cairo_status_t status;
char buffer[256];
int length;
- int subset_id;
+ unsigned int subset_id;
int ch;
+ const char *wa_name;
if (font->glyphs[glyph_number].subset_index < 0)
return CAIRO_STATUS_SUCCESS;
@@ -1146,12 +1144,18 @@ write_used_glyphs (cairo_type1_font_subset_t *font,
* font with the standard name.
**/
subset_id = font->glyphs[glyph_number].subset_index;
- if (subset_id > 0) {
+ /* Any additional glyph included for use by the seac operator
+ * will either have subset_id >= font->scaled_font_subset->num_glyphs
+ * or will not map to a winansi name (wa_name = NULL). In this
+ * case the original name is used.
+ */
+ if (subset_id > 0 && subset_id < font->scaled_font_subset->num_glyphs) {
ch = font->scaled_font_subset->to_latin_char[subset_id];
- name = _cairo_winansi_to_glyphname (ch);
- if (name == NULL)
- return CAIRO_STATUS_NULL_POINTER;
- name_length = strlen(name);
+ wa_name = _cairo_winansi_to_glyphname (ch);
+ if (wa_name) {
+ name = wa_name;
+ name_length = strlen(name);
+ }
}
}
@@ -1263,21 +1267,21 @@ cairo_type1_font_subset_write_private_dict (cairo_type1_font_subset_t *font,
* the actual glyph definitions (charstrings).
*
* What we do here is scan directly to the /Subrs token, which
- * marks the beginning of the subroutines. We then read in all the
- * subroutines then move on to the /CharString token, which marks
- * the beginning of the glyph definitions, and read in the chastrings.
+ * marks the beginning of the subroutines. We read in all the
+ * subroutines, then move on to the /CharString token, which marks
+ * the beginning of the glyph definitions, and read in the charstrings.
*
- * The charstrings are parsed to extracts glyph widths, work out
- * which subroutines are called, and too see if any extra glyphs
+ * The charstrings are parsed to extract glyph widths, work out
+ * which subroutines are called, and to see if any extra glyphs
* need to be included due to the use of the seac glyph combining
* operator.
*
- * Finally the private dict is copied to the subset font minus the
+ * Finally, the private dict is copied to the subset font minus the
* subroutines and charstrings not required.
*/
/* Determine lenIV, the number of random characters at the start of
- each encrypted charstring. The defaults is 4, but this can be
+ each encrypted charstring. The default is 4, but this can be
overridden in the private dict. */
font->lenIV = 4;
if ((lenIV_start = find_token (font->cleartext, font->cleartext_end, "/lenIV")) != NULL) {
@@ -1313,6 +1317,7 @@ cairo_type1_font_subset_write_private_dict (cairo_type1_font_subset_t *font,
if (subrs == NULL) {
font->subset_subrs = FALSE;
p = font->cleartext;
+ array_start = NULL;
goto skip_subrs;
}
diff --git a/src/cairo-type3-glyph-surface-private.h b/src/cairo-type3-glyph-surface-private.h
index b4abcf604..6f40f1c25 100755..100644
--- a/src/cairo-type3-glyph-surface-private.h
+++ b/src/cairo-type3-glyph-surface-private.h
@@ -45,8 +45,9 @@
#include "cairo-surface-clipper-private.h"
#include "cairo-pdf-operators-private.h"
-typedef cairo_status_t (*cairo_type3_glyph_surface_emit_image_t) (cairo_image_surface_t *image,
- cairo_output_stream_t *stream);
+typedef cairo_int_status_t
+(*cairo_type3_glyph_surface_emit_image_t) (cairo_image_surface_t *image,
+ cairo_output_stream_t *stream);
typedef struct cairo_type3_glyph_surface {
cairo_surface_t base;
@@ -64,7 +65,8 @@ cairo_private cairo_surface_t *
_cairo_type3_glyph_surface_create (cairo_scaled_font_t *scaled_font,
cairo_output_stream_t *stream,
cairo_type3_glyph_surface_emit_image_t emit_image,
- cairo_scaled_font_subsets_t *font_subsets);
+ cairo_scaled_font_subsets_t *font_subsets,
+ cairo_bool_t ps_output);
cairo_private void
_cairo_type3_glyph_surface_set_font_subsets_callback (void *abstract_surface,
diff --git a/src/cairo-type3-glyph-surface.c b/src/cairo-type3-glyph-surface.c
index dc5dbdf61..63d2bd74c 100755..100644
--- a/src/cairo-type3-glyph-surface.c
+++ b/src/cairo-type3-glyph-surface.c
@@ -74,7 +74,8 @@ cairo_surface_t *
_cairo_type3_glyph_surface_create (cairo_scaled_font_t *scaled_font,
cairo_output_stream_t *stream,
cairo_type3_glyph_surface_emit_image_t emit_image,
- cairo_scaled_font_subsets_t *font_subsets)
+ cairo_scaled_font_subsets_t *font_subsets,
+ cairo_bool_t ps)
{
cairo_type3_glyph_surface_t *surface;
cairo_matrix_t invert_y_axis;
@@ -106,7 +107,8 @@ _cairo_type3_glyph_surface_create (cairo_scaled_font_t *scaled_font,
_cairo_pdf_operators_init (&surface->pdf_operators,
surface->stream,
&surface->cairo_to_pdf,
- font_subsets);
+ font_subsets,
+ ps);
_cairo_surface_clipper_init (&surface->clipper,
_cairo_type3_glyph_surface_clipper_intersect_clip_path);
diff --git a/src/cairo-types-private.h b/src/cairo-types-private.h
index 5050fd552..9e2fd37e0 100755..100644
--- a/src/cairo-types-private.h
+++ b/src/cairo-types-private.h
@@ -113,7 +113,7 @@ struct _cairo_observer {
};
/**
- * cairo_hash_entry_t:
+ * _cairo_hash_entry:
*
* A #cairo_hash_entry_t contains both a key and a value for
* #cairo_hash_table_t. User-derived types for #cairo_hash_entry_t must
@@ -158,7 +158,7 @@ struct _cairo_array {
};
/**
- * cairo_lcd_filter_t:
+ * _cairo_lcd_filter:
* @CAIRO_LCD_FILTER_DEFAULT: Use the default LCD filter for
* font backend and target device
* @CAIRO_LCD_FILTER_NONE: Do not perform LCD filtering
@@ -194,7 +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;
- cairo_font_color_t color;
+ cairo_font_color_t color;
};
struct _cairo_glyph_text_info {
@@ -447,7 +447,7 @@ typedef struct _cairo_shadow_cache {
double scale;
cairo_list_t link;
} cairo_shadow_cache_t;
-
+
CAIRO_END_DECLS
#endif /* CAIRO_TYPES_PRIVATE_H */
diff --git a/src/cairo-unicode.c b/src/cairo-unicode.c
index 88de39516..88de39516 100755..100644
--- a/src/cairo-unicode.c
+++ b/src/cairo-unicode.c
diff --git a/src/cairo-uninstalled.pc.in b/src/cairo-uninstalled.pc.in
index 9dc3231ae..9dc3231ae 100755..100644
--- a/src/cairo-uninstalled.pc.in
+++ b/src/cairo-uninstalled.pc.in
diff --git a/src/cairo-user-font-private.h b/src/cairo-user-font-private.h
index d54ef78b4..d54ef78b4 100755..100644
--- a/src/cairo-user-font-private.h
+++ b/src/cairo-user-font-private.h
diff --git a/src/cairo-user-font.c b/src/cairo-user-font.c
index 297f21c91..6d2de2097 100755..100644
--- a/src/cairo-user-font.c
+++ b/src/cairo-user-font.c
@@ -507,7 +507,7 @@ _cairo_user_font_face_scaled_font_create (void *abstract_
const cairo_font_face_backend_t _cairo_user_font_face_backend = {
CAIRO_FONT_TYPE_USER,
_cairo_user_font_face_create_for_toy,
- NULL, /* destroy */
+ _cairo_font_face_destroy,
_cairo_user_font_face_scaled_font_create
};
diff --git a/src/cairo-version.c b/src/cairo-version.c
index d9ad240bf..a94cef681 100755..100644
--- a/src/cairo-version.c
+++ b/src/cairo-version.c
@@ -79,10 +79,10 @@
* 1.0.1 - Development on a maintenance branch (toward 1.0.2 release)
* 1.1.1 - Development on head (toward 1.1.2 snapshot and 1.2.0 release)
* </screen></informalexample>
- * </para>
+ *
* <refsect2>
* <title>Compatibility</title>
- * <para>
+ *
* The API/ABI compatibility guarantees for various versions are as
* follows. First, let's assume some cairo-using application code that is
* successfully using the API/ABI "from" one version of cairo. Then let's
@@ -102,11 +102,11 @@
* with the same in-development version number. This is because these
* numbers don't correspond to any fixed state of the software, but
* rather the many states between snapshots and releases.
- * </para>
+ *
* </refsect2>
* <refsect2>
* <title>Examining the version</title>
- * <para>
+ *
* Cairo provides the ability to examine the version at either
* compile-time or run-time and in both a human-readable form as well as
* an encoded form suitable for direct comparison. Cairo also provides the
@@ -135,8 +135,9 @@
* if (cairo_version() >= CAIRO_VERSION_ENCODE(1, 0, 0))
* printf ("Running with suitable cairo version: %s\n", cairo_version_string ());
* </programlisting></informalexample>
- * </para>
+ *
* </refsect2>
+ *
**/
/**
diff --git a/src/cairo-version.h b/src/cairo-version.h
index 51008003f..51008003f 100755..100644
--- a/src/cairo-version.h
+++ b/src/cairo-version.h
diff --git a/src/cairo-vg-surface.c b/src/cairo-vg-surface.c
index 6e0d9a0ed..6e0d9a0ed 100755..100644
--- a/src/cairo-vg-surface.c
+++ b/src/cairo-vg-surface.c
diff --git a/src/cairo-vg.h b/src/cairo-vg.h
index f9a62e51c..f9a62e51c 100755..100644
--- a/src/cairo-vg.h
+++ b/src/cairo-vg.h
diff --git a/src/cairo-wgl-context.c b/src/cairo-wgl-context.c
index 31cbcfe07..31cbcfe07 100755..100644
--- a/src/cairo-wgl-context.c
+++ b/src/cairo-wgl-context.c
diff --git a/src/cairo-wideint-private.h b/src/cairo-wideint-private.h
index 3f5491bb1..3f5491bb1 100755..100644
--- a/src/cairo-wideint-private.h
+++ b/src/cairo-wideint-private.h
diff --git a/src/cairo-wideint-type-private.h b/src/cairo-wideint-type-private.h
index 84a3cbab0..84a3cbab0 100755..100644
--- a/src/cairo-wideint-type-private.h
+++ b/src/cairo-wideint-type-private.h
diff --git a/src/cairo-wideint.c b/src/cairo-wideint.c
index bba266b24..2e056fa36 100755..100644
--- a/src/cairo-wideint.c
+++ b/src/cairo-wideint.c
@@ -654,16 +654,16 @@ _cairo_uint128_divrem (cairo_uint128_t num, cairo_uint128_t den)
return qr;
}
-cairo_int128_t
-_cairo_int128_negate (cairo_int128_t a)
+cairo_uint128_t
+_cairo_uint128_negate (cairo_uint128_t a)
{
a.lo = _cairo_uint64_not (a.lo);
a.hi = _cairo_uint64_not (a.hi);
return _cairo_uint128_add (a, _cairo_uint32_to_uint128 (1));
}
-cairo_int128_t
-_cairo_int128_not (cairo_int128_t a)
+cairo_uint128_t
+_cairo_uint128_not (cairo_uint128_t a)
{
a.lo = _cairo_uint64_not (a.lo);
a.hi = _cairo_uint64_not (a.hi);
diff --git a/src/cairo-win32.h b/src/cairo-win32.h
index 3d2e1c601..3d2e1c601 100755..100644
--- a/src/cairo-win32.h
+++ b/src/cairo-win32.h
diff --git a/src/cairo-xcb-connection-core.c b/src/cairo-xcb-connection-core.c
index ae7c023e1..e01dc1a83 100755..100644
--- a/src/cairo-xcb-connection-core.c
+++ b/src/cairo-xcb-connection-core.c
@@ -268,8 +268,6 @@ _cairo_xcb_connection_put_subimage (cairo_xcb_connection_t *connection,
if (rows > height)
rows = height;
- length = rows * cpp * width;
-
_cairo_xcb_connection_do_put_subimage (connection, dst, gc, src_x, src_y,
width, rows, cpp, stride, dst_x, dst_y, depth, _data);
@@ -283,32 +281,20 @@ _cairo_xcb_connection_put_subimage (cairo_xcb_connection_t *connection,
}
}
-cairo_status_t
+xcb_get_image_reply_t *
_cairo_xcb_connection_get_image (cairo_xcb_connection_t *connection,
xcb_drawable_t src,
int16_t src_x,
int16_t src_y,
uint16_t width,
- uint16_t height,
- xcb_get_image_reply_t **reply)
+ uint16_t height)
{
- xcb_generic_error_t *error;
-
- *reply = xcb_get_image_reply (connection->xcb_connection,
- xcb_get_image (connection->xcb_connection,
- XCB_IMAGE_FORMAT_Z_PIXMAP,
- src,
- src_x, src_y,
- width, height,
- (uint32_t) -1),
-
- &error);
- if (error) {
- free (error);
-
- free (*reply);
- *reply = NULL;
- }
-
- return CAIRO_STATUS_SUCCESS;
+ return xcb_get_image_reply (connection->xcb_connection,
+ xcb_get_image (connection->xcb_connection,
+ XCB_IMAGE_FORMAT_Z_PIXMAP,
+ src,
+ src_x, src_y,
+ width, height,
+ (uint32_t) -1),
+ NULL);
}
diff --git a/src/cairo-xcb-connection-render.c b/src/cairo-xcb-connection-render.c
index 83f1d482e..83f1d482e 100755..100644
--- a/src/cairo-xcb-connection-render.c
+++ b/src/cairo-xcb-connection-render.c
diff --git a/src/cairo-xcb-connection-shm.c b/src/cairo-xcb-connection-shm.c
index 8c1d50698..7720bbbd2 100755..100644
--- a/src/cairo-xcb-connection-shm.c
+++ b/src/cairo-xcb-connection-shm.c
@@ -82,7 +82,6 @@ _cairo_xcb_connection_shm_get_image (cairo_xcb_connection_t *connection,
uint32_t offset)
{
xcb_shm_get_image_reply_t *reply;
- xcb_generic_error_t *error;
assert (connection->flags & CAIRO_XCB_HAS_SHM);
reply = xcb_shm_get_image_reply (connection->xcb_connection,
@@ -93,12 +92,11 @@ _cairo_xcb_connection_shm_get_image (cairo_xcb_connection_t *connection,
(uint32_t) -1,
XCB_IMAGE_FORMAT_Z_PIXMAP,
shmseg, offset),
- &error);
+ NULL);
free (reply);
- if (error) {
+ if (!reply) {
/* an error here should be impossible */
- free (error);
return _cairo_error (CAIRO_STATUS_READ_ERROR);
}
diff --git a/src/cairo-xcb-connection.c b/src/cairo-xcb-connection.c
index 78bc9a101..a070720fd 100755..100644
--- a/src/cairo-xcb-connection.c
+++ b/src/cairo-xcb-connection.c
@@ -77,6 +77,9 @@ typedef struct _cairo_xcb_xid {
#define XCB_RENDER_HAS_PICTURE_TRANSFORM(surface) XCB_RENDER_AT_LEAST((surface), 0, 6)
#define XCB_RENDER_HAS_FILTERS(surface) XCB_RENDER_AT_LEAST((surface), 0, 6)
+#define XCB_RENDER_HAS_FILTER_GOOD(surface) FALSE
+#define XCB_RENDER_HAS_FILTER_BEST(surface) FALSE
+#define XCB_RENDER_HAS_SUBPIXEL_ORDER(surface) XCB_RENDER_AT_LEAST((surface), 0, 6)
#define XCB_RENDER_HAS_EXTENDED_REPEAT(surface) XCB_RENDER_AT_LEAST((surface), 0, 10)
#define XCB_RENDER_HAS_GRADIENTS(surface) XCB_RENDER_AT_LEAST((surface), 0, 10)
@@ -390,6 +393,12 @@ _cairo_xcb_connection_query_render (cairo_xcb_connection_t *connection)
if (XCB_RENDER_HAS_FILTERS (version))
connection->flags |= CAIRO_XCB_RENDER_HAS_FILTERS;
+ if (XCB_RENDER_HAS_FILTER_GOOD (version))
+ connection->flags |= CAIRO_XCB_RENDER_HAS_FILTER_GOOD;
+
+ if (XCB_RENDER_HAS_FILTER_BEST (version))
+ connection->flags |= CAIRO_XCB_RENDER_HAS_FILTER_BEST;
+
if (XCB_RENDER_HAS_PDF_OPERATORS (version))
connection->flags |= CAIRO_XCB_RENDER_HAS_PDF_OPERATORS;
@@ -399,6 +408,15 @@ _cairo_xcb_connection_query_render (cairo_xcb_connection_t *connection)
if (XCB_RENDER_HAS_GRADIENTS (version))
connection->flags |= CAIRO_XCB_RENDER_HAS_GRADIENTS;
+ if (XCB_RENDER_HAS_SUBPIXEL_ORDER (version)) {
+ uint32_t screen;
+ uint32_t *subpixel = xcb_render_query_pict_formats_subpixels(formats);
+
+ /* The spec explicitly allows to have too few entries in the reply... */
+ for (screen = 0; screen < formats->num_subpixel && screen < connection->root->roots_len; screen++)
+ connection->subpixel_orders[screen] = subpixel[screen];
+ }
+
free (version);
status = _cairo_xcb_connection_parse_xrender_formats (connection, formats);
@@ -573,6 +591,7 @@ _device_destroy (void *device)
CAIRO_MUTEX_FINI (connection->shm_mutex);
CAIRO_MUTEX_FINI (connection->screens_mutex);
+ free (connection->subpixel_orders);
free (connection);
}
@@ -684,6 +703,14 @@ _cairo_xcb_connection_get (xcb_connection_t *xcb_connection)
}
connection->render = NULL;
+ connection->subpixel_orders = calloc (connection->root->roots_len, sizeof(*connection->subpixel_orders));
+ if (unlikely (connection->subpixel_orders == NULL)) {
+ CAIRO_MUTEX_UNLOCK (connection->device.mutex);
+ _cairo_xcb_connection_destroy (connection);
+ connection = NULL;
+ goto unlock;
+ }
+
ext = xcb_get_extension_data (xcb_connection, &xcb_render_id);
if (ext != NULL && ext->present) {
status = _cairo_xcb_connection_query_render (connection);
@@ -890,6 +917,8 @@ cairo_xcb_device_debug_cap_xrender_version (cairo_device_t *device,
CAIRO_XCB_RENDER_HAS_COMPOSITE_TRAPEZOIDS |
CAIRO_XCB_RENDER_HAS_PICTURE_TRANSFORM |
CAIRO_XCB_RENDER_HAS_FILTERS |
+ CAIRO_XCB_RENDER_HAS_FILTER_GOOD |
+ CAIRO_XCB_RENDER_HAS_FILTER_BEST |
CAIRO_XCB_RENDER_HAS_PDF_OPERATORS |
CAIRO_XCB_RENDER_HAS_EXTENDED_REPEAT |
CAIRO_XCB_RENDER_HAS_GRADIENTS);
diff --git a/src/cairo-xcb-private.h b/src/cairo-xcb-private.h
index d162d73d4..1ede8c716 100755..100644
--- a/src/cairo-xcb-private.h
+++ b/src/cairo-xcb-private.h
@@ -37,10 +37,10 @@
#ifndef CAIRO_XCB_PRIVATE_H
#define CAIRO_XCB_PRIVATE_H
-#include "cairo-xcb.h"
-
#include "cairoint.h"
+#include "cairo-xcb.h"
+
#include "cairo-cache-private.h"
#include "cairo-compiler-private.h"
#include "cairo-device-private.h"
@@ -75,6 +75,7 @@ typedef struct _cairo_xcb_surface cairo_xcb_surface_t;
typedef struct _cairo_xcb_picture cairo_xcb_picture_t;
typedef struct _cairo_xcb_shm_mem_pool cairo_xcb_shm_mem_pool_t;
typedef struct _cairo_xcb_shm_info cairo_xcb_shm_info_t;
+typedef struct _cairo_xcb_resources cairo_xcb_resources_t;
struct _cairo_xcb_shm_info {
cairo_xcb_connection_t *connection;
@@ -180,7 +181,8 @@ struct _cairo_xcb_font {
struct _cairo_xcb_screen {
cairo_xcb_connection_t *connection;
- xcb_screen_t *xcb_screen;
+ xcb_screen_t *xcb_screen;
+ xcb_render_sub_pixel_t subpixel_order;
xcb_gcontext_t gc[GC_CACHE_SIZE];
uint8_t gc_depths[GC_CACHE_SIZE];
@@ -199,6 +201,9 @@ struct _cairo_xcb_screen {
cairo_list_t link;
cairo_list_t surfaces;
cairo_list_t pictures;
+
+ cairo_bool_t has_font_options;
+ cairo_font_options_t font_options;
};
struct _cairo_xcb_connection {
@@ -219,6 +224,7 @@ struct _cairo_xcb_connection {
const xcb_setup_t *root;
const xcb_query_extension_reply_t *render;
const xcb_query_extension_reply_t *shm;
+ xcb_render_sub_pixel_t *subpixel_orders;
cairo_list_t free_xids;
cairo_freepool_t xid_pool;
@@ -236,6 +242,14 @@ struct _cairo_xcb_connection {
cairo_list_t link;
};
+struct _cairo_xcb_resources {
+ cairo_bool_t xft_antialias;
+ int xft_lcdfilter;
+ cairo_bool_t xft_hinting;
+ int xft_hintstyle;
+ int xft_rgba;
+};
+
enum {
CAIRO_XCB_HAS_RENDER = 0x0001,
CAIRO_XCB_RENDER_HAS_FILL_RECTANGLES = 0x0002,
@@ -247,6 +261,8 @@ enum {
CAIRO_XCB_RENDER_HAS_PDF_OPERATORS = 0x0080,
CAIRO_XCB_RENDER_HAS_EXTENDED_REPEAT = 0x0100,
CAIRO_XCB_RENDER_HAS_GRADIENTS = 0x0200,
+ CAIRO_XCB_RENDER_HAS_FILTER_GOOD = 0x0400,
+ CAIRO_XCB_RENDER_HAS_FILTER_BEST = 0x0800,
CAIRO_XCB_HAS_SHM = 0x80000000,
@@ -259,7 +275,9 @@ enum {
CAIRO_XCB_RENDER_HAS_FILTERS |
CAIRO_XCB_RENDER_HAS_PDF_OPERATORS |
CAIRO_XCB_RENDER_HAS_EXTENDED_REPEAT |
- CAIRO_XCB_RENDER_HAS_GRADIENTS,
+ CAIRO_XCB_RENDER_HAS_GRADIENTS |
+ CAIRO_XCB_RENDER_HAS_FILTER_GOOD |
+ CAIRO_XCB_RENDER_HAS_FILTER_BEST,
CAIRO_XCB_SHM_MASK = CAIRO_XCB_HAS_SHM
};
@@ -267,6 +285,21 @@ enum {
cairo_private extern const cairo_surface_backend_t _cairo_xcb_surface_backend;
+/**
+ * _cairo_surface_is_xcb:
+ * @surface: a #cairo_surface_t
+ *
+ * Checks if a surface is an #cairo_xcb_surface_t
+ *
+ * Return value: %TRUE if the surface is an xcb surface
+ **/
+static inline cairo_bool_t
+_cairo_surface_is_xcb (const cairo_surface_t *surface)
+{
+ /* _cairo_surface_nil sets a NULL backend so be safe */
+ return surface->backend && surface->backend->type == CAIRO_SURFACE_TYPE_XCB;
+}
+
cairo_private cairo_xcb_connection_t *
_cairo_xcb_connection_get (xcb_connection_t *connection);
@@ -342,6 +375,9 @@ _cairo_xcb_screen_get_gc (cairo_xcb_screen_t *screen,
cairo_private void
_cairo_xcb_screen_put_gc (cairo_xcb_screen_t *screen, int depth, xcb_gcontext_t gc);
+cairo_private cairo_font_options_t *
+_cairo_xcb_screen_get_font_options (cairo_xcb_screen_t *screen);
+
cairo_private cairo_status_t
_cairo_xcb_screen_store_linear_picture (cairo_xcb_screen_t *screen,
const cairo_linear_pattern_t *linear,
@@ -505,14 +541,13 @@ _cairo_xcb_connection_put_subimage (cairo_xcb_connection_t *connection,
uint8_t depth,
void *data);
-cairo_private cairo_status_t
+cairo_private xcb_get_image_reply_t *
_cairo_xcb_connection_get_image (cairo_xcb_connection_t *connection,
xcb_drawable_t src,
int16_t src_x,
int16_t src_y,
uint16_t width,
- uint16_t height,
- xcb_get_image_reply_t **reply);
+ uint16_t height);
cairo_private void
_cairo_xcb_connection_poly_fill_rectangle (cairo_xcb_connection_t *connection,
@@ -767,4 +802,8 @@ slim_hidden_proto_no_warn (cairo_xcb_device_debug_set_precision);
slim_hidden_proto_no_warn (cairo_xcb_device_debug_cap_xrender_version);
#endif
+cairo_private void
+_cairo_xcb_resources_get (cairo_xcb_screen_t *screen,
+ cairo_xcb_resources_t *resources);
+
#endif /* CAIRO_XCB_PRIVATE_H */
diff --git a/src/cairo-xcb-resources.c b/src/cairo-xcb-resources.c
new file mode 100644
index 000000000..1877758c2
--- /dev/null
+++ b/src/cairo-xcb-resources.c
@@ -0,0 +1,281 @@
+/* Cairo - a vector graphics library with display and print output
+ *
+ * Copyright © 2014 Lukas Lalinsky
+ * Copyright © 2005 Red Hat, Inc.
+ *
+ * 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.
+ *
+ * Authors:
+ * Lukas Lalinsky <lukas@oxygene.sk>
+ *
+ * Partially on code from xftdpy.c
+ *
+ * Copyright © 2000 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "cairoint.h"
+
+#include "cairo-xcb-private.h"
+
+#include "cairo-fontconfig-private.h"
+
+static void
+parse_boolean (const char *v, cairo_bool_t *out)
+{
+ char c0, c1;
+
+ c0 = *v;
+ if (c0 == 't' || c0 == 'T' || c0 == 'y' || c0 == 'Y' || c0 == '1')
+ *out = TRUE;
+ if (c0 == 'f' || c0 == 'F' || c0 == 'n' || c0 == 'N' || c0 == '0')
+ *out = FALSE;
+ if (c0 == 'o') {
+ c1 = v[1];
+ if (c1 == 'n' || c1 == 'N')
+ *out = TRUE;
+ if (c1 == 'f' || c1 == 'F')
+ *out = FALSE;
+ }
+}
+
+static void
+parse_integer (const char *v, int *out)
+{
+ char *e;
+ int value;
+
+#if CAIRO_HAS_FC_FONT
+ if (FcNameConstant ((FcChar8 *) v, out))
+ return;
+#endif
+
+ value = strtol (v, &e, 0);
+ if (e != v)
+ *out = value;
+}
+
+static char *
+skip_spaces(char *str)
+{
+ while (*str == ' ' || *str == '\t' || *str == '\n')
+ str++;
+ return str;
+}
+
+struct resource_parser {
+ int buffer_size;
+ int bytes_in_buffer;
+ char* buffer;
+ cairo_xcb_resources_t *resources;
+};
+
+static cairo_bool_t
+resource_parse_line (char *name, cairo_xcb_resources_t *resources)
+{
+ char *value;
+
+ value = strchr (name, ':');
+ if (value == NULL)
+ return FALSE;
+
+ *value++ = 0;
+
+ name = skip_spaces (name);
+ value = skip_spaces (value);
+
+ if (strcmp (name, "Xft.antialias") == 0)
+ parse_boolean (value, &(resources->xft_antialias));
+ else if (strcmp (name, "Xft.lcdfilter") == 0)
+ parse_integer (value, &(resources->xft_lcdfilter));
+ else if (strcmp (name, "Xft.rgba") == 0)
+ parse_integer (value, &(resources->xft_rgba));
+ else if (strcmp (name, "Xft.hinting") == 0)
+ parse_boolean (value, &(resources->xft_hinting));
+ else if (strcmp (name, "Xft.hintstyle") == 0)
+ parse_integer (value, &(resources->xft_hintstyle));
+
+ return TRUE;
+}
+
+static int
+resource_parse_lines (struct resource_parser *parser)
+{
+ char *line, *newline;
+
+ line = parser->buffer;
+ while (1) {
+ newline = strchr (line, '\n');
+ if (newline == NULL)
+ break;
+
+ *newline++ = 0;
+
+ if (! resource_parse_line (line, parser->resources))
+ break;
+
+ line = newline;
+ }
+
+ return line - parser->buffer;
+}
+
+static void
+resource_parser_init (struct resource_parser *parser, cairo_xcb_resources_t *resources)
+{
+ parser->buffer_size = 0;
+ parser->bytes_in_buffer = 0;
+ parser->buffer = NULL;
+ parser->resources = resources;
+}
+
+static cairo_bool_t
+resource_parser_update (struct resource_parser *parser, const char *data, int length)
+{
+ int bytes_parsed;
+
+ if (parser->bytes_in_buffer + length + 1 > parser->buffer_size) {
+ parser->buffer_size = parser->bytes_in_buffer + length + 1;
+ parser->buffer = realloc(parser->buffer, parser->buffer_size);
+ if (! parser->buffer) {
+ parser->buffer_size = 0;
+ parser->bytes_in_buffer = 0;
+ return FALSE;
+ }
+ }
+
+ memmove (parser->buffer + parser->bytes_in_buffer, data, length);
+ parser->bytes_in_buffer += length;
+ parser->buffer[parser->bytes_in_buffer] = 0;
+
+ bytes_parsed = resource_parse_lines (parser);
+
+ if (parser->bytes_in_buffer > bytes_parsed) {
+ memmove (parser->buffer, parser->buffer + bytes_parsed, parser->bytes_in_buffer - bytes_parsed);
+ parser->bytes_in_buffer -= bytes_parsed;
+ } else {
+ parser->bytes_in_buffer = 0;
+ }
+
+ return TRUE;
+}
+
+static void
+resource_parser_done (struct resource_parser *parser)
+{
+ if (parser->bytes_in_buffer > 0) {
+ parser->buffer[parser->bytes_in_buffer] = 0;
+ resource_parse_line (parser->buffer, parser->resources);
+ }
+
+ free (parser->buffer);
+}
+
+static void
+get_resources(xcb_connection_t *connection, xcb_screen_t *screen, cairo_xcb_resources_t *resources)
+{
+ xcb_get_property_cookie_t cookie;
+ xcb_get_property_reply_t *reply;
+ struct resource_parser parser;
+ int offset;
+ cairo_bool_t has_more_data;
+
+ resources->xft_antialias = TRUE;
+ resources->xft_lcdfilter = -1;
+ resources->xft_hinting = TRUE;
+ resources->xft_hintstyle = FC_HINT_FULL;
+ resources->xft_rgba = FC_RGBA_UNKNOWN;
+
+ resource_parser_init (&parser, resources);
+
+ offset = 0;
+ has_more_data = FALSE;
+ do {
+ cookie = xcb_get_property (connection, 0, screen->root, XCB_ATOM_RESOURCE_MANAGER, XCB_ATOM_STRING, offset, 1024);
+ reply = xcb_get_property_reply (connection, cookie, NULL);
+
+ if (reply) {
+ if (reply->format == 8 && reply->type == XCB_ATOM_STRING) {
+ char *value = (char *) xcb_get_property_value (reply);
+ int length = xcb_get_property_value_length (reply);
+
+ offset += length / 4; /* X needs the offset in 'long' units */
+ has_more_data = reply->bytes_after > 0;
+
+ if (! resource_parser_update (&parser, value, length))
+ has_more_data = FALSE; /* early exit on error */
+ }
+
+ free (reply);
+ }
+ } while (has_more_data);
+
+ resource_parser_done (&parser);
+}
+
+void
+_cairo_xcb_resources_get (cairo_xcb_screen_t *screen, cairo_xcb_resources_t *resources)
+{
+ get_resources (screen->connection->xcb_connection, screen->xcb_screen, resources);
+
+ if (resources->xft_rgba == FC_RGBA_UNKNOWN) {
+ switch (screen->subpixel_order) {
+ case XCB_RENDER_SUB_PIXEL_UNKNOWN:
+ resources->xft_rgba = FC_RGBA_UNKNOWN;
+ break;
+ case XCB_RENDER_SUB_PIXEL_HORIZONTAL_RGB:
+ resources->xft_rgba = FC_RGBA_RGB;
+ break;
+ case XCB_RENDER_SUB_PIXEL_HORIZONTAL_BGR:
+ resources->xft_rgba = FC_RGBA_BGR;
+ break;
+ case XCB_RENDER_SUB_PIXEL_VERTICAL_RGB:
+ resources->xft_rgba = FC_RGBA_VRGB;
+ break;
+ case XCB_RENDER_SUB_PIXEL_VERTICAL_BGR:
+ resources->xft_rgba = FC_RGBA_VBGR;
+ break;
+ case XCB_RENDER_SUB_PIXEL_NONE:
+ resources->xft_rgba = FC_RGBA_NONE;
+ break;
+ }
+ }
+}
diff --git a/src/cairo-xcb-screen.c b/src/cairo-xcb-screen.c
index 2858d23fb..d0019f9cd 100755..100644
--- a/src/cairo-xcb-screen.c
+++ b/src/cairo-xcb-screen.c
@@ -35,6 +35,96 @@
#include "cairo-xcb-private.h"
#include "cairo-list-inline.h"
+#include "cairo-fontconfig-private.h"
+
+static void
+_cairo_xcb_init_screen_font_options (cairo_xcb_screen_t *screen)
+{
+ cairo_xcb_resources_t res;
+ cairo_antialias_t antialias;
+ cairo_subpixel_order_t subpixel_order;
+ cairo_lcd_filter_t lcd_filter;
+ cairo_hint_style_t hint_style;
+
+ _cairo_xcb_resources_get (screen, &res);
+
+ /* the rest of the code in this function is copied from
+ _cairo_xlib_init_screen_font_options in cairo-xlib-screen.c */
+
+ if (res.xft_hinting) {
+ switch (res.xft_hintstyle) {
+ case FC_HINT_NONE:
+ hint_style = CAIRO_HINT_STYLE_NONE;
+ break;
+ case FC_HINT_SLIGHT:
+ hint_style = CAIRO_HINT_STYLE_SLIGHT;
+ break;
+ case FC_HINT_MEDIUM:
+ hint_style = CAIRO_HINT_STYLE_MEDIUM;
+ break;
+ case FC_HINT_FULL:
+ hint_style = CAIRO_HINT_STYLE_FULL;
+ break;
+ default:
+ hint_style = CAIRO_HINT_STYLE_DEFAULT;
+ }
+ } else {
+ hint_style = CAIRO_HINT_STYLE_NONE;
+ }
+
+ switch (res.xft_rgba) {
+ case FC_RGBA_RGB:
+ subpixel_order = CAIRO_SUBPIXEL_ORDER_RGB;
+ break;
+ case FC_RGBA_BGR:
+ subpixel_order = CAIRO_SUBPIXEL_ORDER_BGR;
+ break;
+ case FC_RGBA_VRGB:
+ subpixel_order = CAIRO_SUBPIXEL_ORDER_VRGB;
+ break;
+ case FC_RGBA_VBGR:
+ subpixel_order = CAIRO_SUBPIXEL_ORDER_VBGR;
+ break;
+ case FC_RGBA_UNKNOWN:
+ case FC_RGBA_NONE:
+ default:
+ subpixel_order = CAIRO_SUBPIXEL_ORDER_DEFAULT;
+ }
+
+ switch (res.xft_lcdfilter) {
+ case FC_LCD_NONE:
+ lcd_filter = CAIRO_LCD_FILTER_NONE;
+ break;
+ case FC_LCD_DEFAULT:
+ lcd_filter = CAIRO_LCD_FILTER_FIR5;
+ break;
+ case FC_LCD_LIGHT:
+ lcd_filter = CAIRO_LCD_FILTER_FIR3;
+ break;
+ case FC_LCD_LEGACY:
+ lcd_filter = CAIRO_LCD_FILTER_INTRA_PIXEL;
+ break;
+ default:
+ lcd_filter = CAIRO_LCD_FILTER_DEFAULT;
+ break;
+ }
+
+ if (res.xft_antialias) {
+ if (subpixel_order == CAIRO_SUBPIXEL_ORDER_DEFAULT)
+ antialias = CAIRO_ANTIALIAS_GRAY;
+ else
+ antialias = CAIRO_ANTIALIAS_SUBPIXEL;
+ } else {
+ antialias = CAIRO_ANTIALIAS_NONE;
+ }
+
+ cairo_font_options_set_hint_style (&screen->font_options, hint_style);
+ cairo_font_options_set_antialias (&screen->font_options, antialias);
+ cairo_font_options_set_subpixel_order (&screen->font_options, subpixel_order);
+ _cairo_font_options_set_lcd_filter (&screen->font_options, lcd_filter);
+ cairo_font_options_set_hint_metrics (&screen->font_options, CAIRO_HINT_METRICS_ON);
+}
+
struct pattern_cache_entry {
cairo_cache_entry_t key;
cairo_xcb_screen_t *screen;
@@ -117,6 +207,18 @@ _pattern_cache_entry_destroy (void *closure)
_cairo_freelist_free (&entry->screen->pattern_cache_entry_freelist, entry);
}
+static int _get_screen_index(cairo_xcb_connection_t *xcb_connection,
+ xcb_screen_t *xcb_screen)
+{
+ int idx = 0;
+ xcb_screen_iterator_t iter = xcb_setup_roots_iterator(xcb_connection->root);
+ for (; iter.rem; xcb_screen_next(&iter), idx++)
+ if (iter.data->root == xcb_screen->root)
+ return idx;
+
+ ASSERT_NOT_REACHED;
+}
+
cairo_xcb_screen_t *
_cairo_xcb_screen_get (xcb_connection_t *xcb_connection,
xcb_screen_t *xcb_screen)
@@ -124,6 +226,7 @@ _cairo_xcb_screen_get (xcb_connection_t *xcb_connection,
cairo_xcb_connection_t *connection;
cairo_xcb_screen_t *screen;
cairo_status_t status;
+ int screen_idx;
int i;
connection = _cairo_xcb_connection_get (xcb_connection);
@@ -150,8 +253,12 @@ _cairo_xcb_screen_get (xcb_connection_t *xcb_connection,
if (unlikely (screen == NULL))
goto unlock;
+ screen_idx = _get_screen_index(connection, xcb_screen);
+
screen->connection = connection;
screen->xcb_screen = xcb_screen;
+ screen->has_font_options = FALSE;
+ screen->subpixel_order = connection->subpixel_orders[screen_idx];
_cairo_freelist_init (&screen->pattern_cache_entry_freelist,
sizeof (struct pattern_cache_entry));
@@ -362,3 +469,26 @@ _cairo_xcb_screen_lookup_radial_picture (cairo_xcb_screen_t *screen,
return picture;
}
+
+cairo_font_options_t *
+_cairo_xcb_screen_get_font_options (cairo_xcb_screen_t *screen)
+{
+ if (! screen->has_font_options) {
+ _cairo_font_options_init_default (&screen->font_options);
+ _cairo_font_options_set_round_glyph_positions (&screen->font_options, CAIRO_ROUND_GLYPH_POS_ON);
+
+ /* XXX: This is disabled because something seems to be merging
+ font options incorrectly for xcb. This effectively reverts
+ the changes brought in git e691d242, and restores ~150 tests
+ to resume passing. See mailing list archives for Sep 17,
+ 2014 for more discussion. */
+ if (0 && ! _cairo_xcb_connection_acquire (screen->connection)) {
+ _cairo_xcb_init_screen_font_options (screen);
+ _cairo_xcb_connection_release (screen->connection);
+ }
+
+ screen->has_font_options = TRUE;
+ }
+
+ return &screen->font_options;
+}
diff --git a/src/cairo-xcb-shm.c b/src/cairo-xcb-shm.c
index 2be2dac5b..2be2dac5b 100755..100644
--- a/src/cairo-xcb-shm.c
+++ b/src/cairo-xcb-shm.c
diff --git a/src/cairo-xcb-surface-core.c b/src/cairo-xcb-surface-core.c
index db775cd17..e78cd80c2 100755..100644
--- a/src/cairo-xcb-surface-core.c
+++ b/src/cairo-xcb-surface-core.c
@@ -409,7 +409,7 @@ _cairo_xcb_surface_pixmap (cairo_xcb_surface_t *target,
if (pixmap != NULL && pixmap->screen == target->screen)
return (cairo_xcb_pixmap_t *) cairo_surface_reference (&pixmap->base);
- if (source->type == CAIRO_SURFACE_TYPE_XCB &&
+ if (_cairo_surface_is_xcb(source) &&
((cairo_xcb_surface_t *) source)->screen == target->screen)
{
cairo_xcb_surface_t *xcb_source = (cairo_xcb_surface_t *) source;
@@ -576,7 +576,7 @@ _cairo_xcb_surface_core_copy_boxes (cairo_xcb_surface_t *dst,
src->x0 + x1,
src->y0 + y1,
x1, y1,
- x2 - x2, y2 - x2);
+ x2 - x1, y2 - y1);
}
}
}
diff --git a/src/cairo-xcb-surface-render.c b/src/cairo-xcb-surface-render.c
index c6393a809..eec45c7f3 100755..100644
--- a/src/cairo-xcb-surface-render.c
+++ b/src/cairo-xcb-surface-render.c
@@ -39,6 +39,7 @@
#include "cairo-clip-inline.h"
#include "cairo-clip-private.h"
#include "cairo-composite-rectangles-private.h"
+#include "cairo-image-surface-inline.h"
#include "cairo-image-surface-private.h"
#include "cairo-list-inline.h"
#include "cairo-region-private.h"
@@ -396,11 +397,6 @@ _pattern_is_supported (uint32_t flags,
if (pattern->type == CAIRO_PATTERN_TYPE_SOLID)
return TRUE;
- if (! _cairo_matrix_is_integer_translation (&pattern->matrix, NULL, NULL)) {
- if ((flags & CAIRO_XCB_RENDER_HAS_PICTURE_TRANSFORM) == 0)
- return FALSE;
- }
-
switch (pattern->extend) {
default:
ASSERT_NOT_REACHED;
@@ -414,19 +410,22 @@ _pattern_is_supported (uint32_t flags,
}
if (pattern->type == CAIRO_PATTERN_TYPE_SURFACE) {
- cairo_filter_t filter;
-
- filter = pattern->filter;
- if (_cairo_matrix_has_unity_scale (&pattern->matrix) &&
- _cairo_matrix_is_integer_translation (&pattern->matrix, NULL, NULL))
- {
- filter = CAIRO_FILTER_NEAREST;
- }
-
- if (! (filter == CAIRO_FILTER_NEAREST || filter == CAIRO_FILTER_FAST)) {
- if ((flags & CAIRO_XCB_RENDER_HAS_FILTERS) == 0)
- return FALSE;
+ switch (pattern->filter) {
+ case CAIRO_FILTER_FAST:
+ case CAIRO_FILTER_NEAREST:
+ return (flags & CAIRO_XCB_RENDER_HAS_PICTURE_TRANSFORM) ||
+ _cairo_matrix_is_integer_translation (&pattern->matrix, NULL, NULL);
+ case CAIRO_FILTER_GOOD:
+ return flags & CAIRO_XCB_RENDER_HAS_FILTER_GOOD;
+ case CAIRO_FILTER_BEST:
+ return flags & CAIRO_XCB_RENDER_HAS_FILTER_BEST;
+ case CAIRO_FILTER_BILINEAR:
+ case CAIRO_FILTER_GAUSSIAN:
+ default:
+ return flags & CAIRO_XCB_RENDER_HAS_FILTERS;
}
+ } else if (pattern->type == CAIRO_PATTERN_TYPE_MESH) {
+ return FALSE;
} else { /* gradient */
if ((flags & CAIRO_XCB_RENDER_HAS_GRADIENTS) == 0)
return FALSE;
@@ -438,9 +437,8 @@ _pattern_is_supported (uint32_t flags,
{
return FALSE;
}
+ return TRUE;
}
-
- return pattern->type != CAIRO_PATTERN_TYPE_MESH;
}
static void
@@ -519,7 +517,7 @@ _cairo_xcb_picture_set_filter (cairo_xcb_picture_t *picture,
render_filter = "best";
len = strlen ("best");
}
- else {
+ else {
render_filter = "convolution";
len = strlen ("convolution");
}
@@ -1045,9 +1043,7 @@ _cairo_xcb_surface_setup_surface_picture(cairo_xcb_picture_t *picture,
filter = pattern->base.filter;
if (filter != CAIRO_FILTER_NEAREST &&
- _cairo_matrix_has_unity_scale (&pattern->base.matrix) &&
- _cairo_fixed_is_integer (_cairo_fixed_from_double (pattern->base.matrix.x0)) &&
- _cairo_fixed_is_integer (_cairo_fixed_from_double (pattern->base.matrix.y0)))
+ _cairo_matrix_is_pixel_exact (&pattern->base.matrix))
{
filter = CAIRO_FILTER_NEAREST;
}
@@ -1113,10 +1109,11 @@ record_to_picture (cairo_surface_t *target,
return _cairo_xcb_transparent_picture ((cairo_xcb_surface_t *) target);
/* Now draw the recording surface to an xcb surface */
- tmp = _cairo_surface_create_similar_scratch (target,
- source->content,
- limit.width,
- limit.height);
+ tmp = _cairo_surface_create_scratch (target,
+ source->content,
+ limit.width,
+ limit.height,
+ CAIRO_COLOR_TRANSPARENT);
if (tmp->status != CAIRO_STATUS_SUCCESS) {
return (cairo_xcb_picture_t *) tmp;
}
@@ -1176,13 +1173,13 @@ _cairo_xcb_surface_picture (cairo_xcb_surface_t *target,
/* restore transform */
if (filtered_picture != picture) {
- _cairo_xcb_picture_set_matrix (filtered_picture,
+ _cairo_xcb_picture_set_matrix (filtered_picture,
&pattern->base.matrix,
pattern->base.filter,
extents->x + extents->width/2.,
extents->y + extents->height/2.);
- _cairo_xcb_picture_set_matrix (picture,
+ _cairo_xcb_picture_set_matrix (picture,
&pattern->base.matrix,
pattern->base.filter,
extents->x + extents->width/2.,
@@ -1199,7 +1196,7 @@ _cairo_xcb_surface_picture (cairo_xcb_surface_t *target,
if (source->type == CAIRO_SURFACE_TYPE_XCB)
{
- if (source->backend->type == CAIRO_SURFACE_TYPE_XCB) {
+ if (_cairo_surface_is_xcb(source)) {
cairo_xcb_surface_t *xcb = (cairo_xcb_surface_t *) source;
if (xcb->screen == target->screen && xcb->fallback == NULL) {
picture = _copy_to_picture ((cairo_xcb_surface_t *) source);
@@ -1360,13 +1357,13 @@ _cairo_xcb_surface_picture (cairo_xcb_surface_t *target,
/* restore transform */
if (filtered_picture != picture) {
- _cairo_xcb_picture_set_matrix (filtered_picture,
+ _cairo_xcb_picture_set_matrix (filtered_picture,
&pattern->base.matrix,
pattern->base.filter,
extents->x + extents->width/2.,
extents->y + extents->height/2.);
- _cairo_xcb_picture_set_matrix (picture,
+ _cairo_xcb_picture_set_matrix (picture,
&pattern->base.matrix,
pattern->base.filter,
extents->x + extents->width/2.,
@@ -1425,7 +1422,7 @@ _render_fill_boxes (void *abstract_dst,
cairo_boxes_t *boxes)
{
cairo_xcb_surface_t *dst = abstract_dst;
- xcb_rectangle_t stack_xrects[CAIRO_STACK_ARRAY_LENGTH (sizeof (xcb_rectangle_t))];
+ xcb_rectangle_t stack_xrects[CAIRO_STACK_ARRAY_LENGTH (xcb_rectangle_t)];
xcb_rectangle_t *xrects = stack_xrects;
xcb_render_color_t render_color;
int render_op = _render_operator (op);
@@ -1581,7 +1578,7 @@ _render_composite_boxes (cairo_xcb_surface_t *dst,
src->x + extents->x, src->y + extents->y,
0, 0,
extents->x, extents->y,
- extents->width, extents->height);
+ extents->width, extents->height);
}
@@ -1770,11 +1767,11 @@ get_clip_surface (const cairo_clip_t *clip,
cairo_surface_t *surface;
cairo_status_t status;
- surface = _cairo_surface_create_similar_solid (&target->base,
- CAIRO_CONTENT_ALPHA,
- clip->extents.width,
- clip->extents.height,
- CAIRO_COLOR_WHITE);
+ surface = _cairo_surface_create_scratch (&target->base,
+ CAIRO_CONTENT_ALPHA,
+ clip->extents.width,
+ clip->extents.height,
+ CAIRO_COLOR_WHITE);
if (unlikely (surface->status))
return (cairo_xcb_surface_t *) surface;
@@ -2033,7 +2030,7 @@ _clip_and_composite_combine (cairo_clip_t *clip,
{
cairo_xcb_surface_t *tmp;
cairo_xcb_surface_t *clip_surface;
- int clip_x, clip_y;
+ int clip_x = 0, clip_y = 0;
xcb_render_picture_t clip_picture;
cairo_status_t status;
@@ -2336,7 +2333,7 @@ _cairo_xcb_surface_fixup_unbounded_with_mask (cairo_xcb_surface_t *dst,
cairo_clip_t *clip)
{
cairo_xcb_surface_t *mask;
- int mask_x, mask_y;
+ int mask_x = 0, mask_y = 0;
mask = get_clip_surface (clip, dst, &mask_x, &mask_y);
if (unlikely (mask->base.status))
@@ -2739,7 +2736,7 @@ _composite_boxes (cairo_xcb_surface_t *dst,
if (need_clip_mask) {
cairo_xcb_surface_t *clip_surface;
- int clip_x, clip_y;
+ int clip_x = 0, clip_y = 0;
clip_surface = get_clip_surface (extents->clip, dst,
&clip_x, &clip_y);
@@ -2877,7 +2874,7 @@ _upload_image_inplace (cairo_xcb_surface_t *surface,
return CAIRO_INT_STATUS_UNSUPPORTED;
pattern = (const cairo_surface_pattern_t *) source;
- if (pattern->surface->type != CAIRO_SURFACE_TYPE_IMAGE)
+ if (! _cairo_surface_is_image (pattern->surface))
return CAIRO_INT_STATUS_UNSUPPORTED;
/* Have we already upload this image to a pixmap? */
@@ -2992,27 +2989,29 @@ _boxes_for_traps (cairo_boxes_t *boxes,
cairo_traps_t *traps,
cairo_antialias_t antialias)
{
- int i;
+ int i, j;
_cairo_boxes_init (boxes);
- boxes->num_boxes = traps->num_traps;
boxes->chunks.base = (cairo_box_t *) traps->traps;
- boxes->chunks.count = traps->num_traps;
boxes->chunks.size = traps->num_traps;
if (antialias != CAIRO_ANTIALIAS_NONE) {
- for (i = 0; i < traps->num_traps; i++) {
+ for (i = j = 0; i < traps->num_traps; i++) {
/* Note the traps and boxes alias so we need to take the local copies first. */
cairo_fixed_t x1 = traps->traps[i].left.p1.x;
cairo_fixed_t x2 = traps->traps[i].right.p1.x;
cairo_fixed_t y1 = traps->traps[i].top;
cairo_fixed_t y2 = traps->traps[i].bottom;
- boxes->chunks.base[i].p1.x = x1;
- boxes->chunks.base[i].p1.y = y1;
- boxes->chunks.base[i].p2.x = x2;
- boxes->chunks.base[i].p2.y = y2;
+ if (x1 == x2 || y1 == y2)
+ continue;
+
+ boxes->chunks.base[j].p1.x = x1;
+ boxes->chunks.base[j].p1.y = y1;
+ boxes->chunks.base[j].p2.x = x2;
+ boxes->chunks.base[j].p2.y = y2;
+ j++;
if (boxes->is_pixel_aligned) {
boxes->is_pixel_aligned =
@@ -3023,7 +3022,7 @@ _boxes_for_traps (cairo_boxes_t *boxes,
} else {
boxes->is_pixel_aligned = TRUE;
- for (i = 0; i < traps->num_traps; i++) {
+ for (i = j = 0; i < traps->num_traps; i++) {
/* Note the traps and boxes alias so we need to take the local copies first. */
cairo_fixed_t x1 = traps->traps[i].left.p1.x;
cairo_fixed_t x2 = traps->traps[i].right.p1.x;
@@ -3031,12 +3030,18 @@ _boxes_for_traps (cairo_boxes_t *boxes,
cairo_fixed_t y2 = traps->traps[i].bottom;
/* round down here to match Pixman's behavior when using traps. */
- boxes->chunks.base[i].p1.x = _cairo_fixed_round_down (x1);
- boxes->chunks.base[i].p1.y = _cairo_fixed_round_down (y1);
- boxes->chunks.base[i].p2.x = _cairo_fixed_round_down (x2);
- boxes->chunks.base[i].p2.y = _cairo_fixed_round_down (y2);
+ boxes->chunks.base[j].p1.x = _cairo_fixed_round_down (x1);
+ boxes->chunks.base[j].p1.y = _cairo_fixed_round_down (y1);
+ boxes->chunks.base[j].p2.x = _cairo_fixed_round_down (x2);
+ boxes->chunks.base[j].p2.y = _cairo_fixed_round_down (y2);
+
+ j += (boxes->chunks.base[j].p1.x != boxes->chunks.base[j].p2.x &&
+ boxes->chunks.base[j].p1.y != boxes->chunks.base[j].p2.y);
}
}
+
+ boxes->num_boxes = j;
+ boxes->chunks.count = j;
}
static cairo_status_t
@@ -3209,6 +3214,9 @@ _clip_and_composite_boxes (cairo_xcb_surface_t *dst,
clip = _cairo_clip_copy (extents->clip);
clip = _cairo_clip_intersect_boxes (clip, boxes);
+ if (_cairo_clip_is_all_clipped (clip))
+ return CAIRO_INT_STATUS_NOTHING_TO_DO;
+
status = _cairo_clip_get_polygon (clip, &polygon,
&fill_rule, &antialias);
_cairo_clip_path_destroy (clip->path);
@@ -4561,6 +4569,9 @@ _cairo_xcb_surface_add_glyph (cairo_xcb_connection_t *connection,
const uint8_t *d;
uint8_t *new, *n;
+ if (c == 0)
+ break;
+
new = malloc (c);
if (unlikely (new == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
@@ -4589,6 +4600,9 @@ _cairo_xcb_surface_add_glyph (cairo_xcb_connection_t *connection,
const uint32_t *d;
uint32_t *new, *n;
+ if (c == 0)
+ break;
+
new = malloc (4 * c);
if (unlikely (new == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
@@ -4979,36 +4993,36 @@ _create_convolution_coef (double *convolution_matrix,
return NULL;
if (is_x_pass) {
- length = col;
+ length = col;
values = _cairo_malloc_ab (length + 2, sizeof (xcb_render_fixed_t));
if (values == NULL)
return NULL;
- v = col;
- values[0] = _cairo_fixed_16_16_from_double (v);
- values[1] = _cairo_fixed_16_16_from_double (1.0);
+ v = col;
+ values[0] = _cairo_fixed_16_16_from_double (v);
+ values[1] = _cairo_fixed_16_16_from_double (1.0);
coef = _cairo_malloc_ab (length, sizeof (double));
if (coef == NULL) {
free (values);
return NULL;
}
memset (coef, 0, sizeof (double) * length);
- compute_x_coef_to_double (convolution_matrix, row, col, coef);
+ compute_x_coef_to_double (convolution_matrix, row, col, coef);
}
else {
- length = row;
+ length = row;
values = _cairo_malloc_ab (length + 2, sizeof (xcb_render_fixed_t));
if (values == NULL)
return NULL;
- values[0] = _cairo_fixed_16_16_from_double (1.0);
- v = row;
- values[1] = _cairo_fixed_16_16_from_double (v);
+ values[0] = _cairo_fixed_16_16_from_double (1.0);
+ v = row;
+ values[1] = _cairo_fixed_16_16_from_double (v);
coef = _cairo_malloc_ab (length, sizeof (double));
if (coef == NULL) {
free (values);
return NULL;
}
memset (coef, 0, sizeof (double) * length);
- compute_y_coef_to_double (convolution_matrix, row, col, coef);
+ compute_y_coef_to_double (convolution_matrix, row, col, coef);
}
for (i = 0; i < length; i++)
@@ -5102,7 +5116,7 @@ _cairo_xcb_gaussian_filter (cairo_xcb_surface_t *source,
pixmap,
xrender_format,
0, 0);
- _cairo_xcb_connection_free_pixmap (source->connection, pixmap);
+ _cairo_xcb_connection_free_pixmap (source->connection, pixmap);
}
if (width != src_width || height != src_height) {
diff --git a/src/cairo-xcb-surface.c b/src/cairo-xcb-surface.c
index 7b74027d1..41e16f0db 100755..100644
--- a/src/cairo-xcb-surface.c
+++ b/src/cairo-xcb-surface.c
@@ -383,13 +383,10 @@ _get_image (cairo_xcb_surface_t *surface,
}
}
- status = _cairo_xcb_connection_get_image (connection,
- surface->drawable,
- x, y,
- width, height,
- &reply);
- if (unlikely (status))
- goto FAIL;
+ reply =_cairo_xcb_connection_get_image (connection,
+ surface->drawable,
+ x, y,
+ width, height);
if (reply == NULL && ! surface->owns_pixmap) {
/* xcb_get_image_t from a window is dangerous because it can
@@ -423,15 +420,11 @@ _get_image (cairo_xcb_surface_t *surface,
_cairo_xcb_screen_put_gc (surface->screen, surface->depth, gc);
- status = _cairo_xcb_connection_get_image (connection,
- pixmap,
- 0, 0,
- width, height,
- &reply);
+ reply = _cairo_xcb_connection_get_image (connection,
+ pixmap,
+ 0, 0,
+ width, height);
_cairo_xcb_connection_free_pixmap (connection, pixmap);
-
- if (unlikely (status))
- goto FAIL;
}
if (unlikely (reply == NULL)) {
@@ -543,9 +536,9 @@ static void
_cairo_xcb_surface_get_font_options (void *abstract_surface,
cairo_font_options_t *options)
{
- /* XXX copy from xlib */
- _cairo_font_options_init_default (options);
- _cairo_font_options_set_round_glyph_positions (options, CAIRO_ROUND_GLYPH_POS_ON);
+ cairo_xcb_surface_t *surface = abstract_surface;
+
+ *options = *_cairo_xcb_screen_get_font_options (surface->screen);
}
static cairo_status_t
@@ -1163,8 +1156,8 @@ _cairo_xcb_surface_glyphs (void *abstract_surface,
if (shadow_type != CAIRO_SHADOW_INSET)
status = _cairo_surface_shadow_glyphs (surface, op, source,
- scaled_font,
- glyphs, num_glyphs,
+ scaled_font,
+ glyphs, num_glyphs,
clip,
&source->shadow);
if (unlikely (status)) {
@@ -1190,8 +1183,8 @@ _cairo_xcb_surface_glyphs (void *abstract_surface,
if (shadow_type == CAIRO_SHADOW_INSET)
status = _cairo_surface_shadow_glyphs (surface, op, source,
- scaled_font,
- glyphs, num_glyphs,
+ scaled_font,
+ glyphs, num_glyphs,
clip,
&source->shadow);
cairo_device_release (surface->device);
@@ -1604,7 +1597,7 @@ cairo_xcb_surface_set_size (cairo_surface_t *abstract_surface,
}
- if (abstract_surface->type != CAIRO_SURFACE_TYPE_XCB) {
+ if ( !_cairo_surface_is_xcb(abstract_surface)) {
_cairo_surface_set_error (abstract_surface,
_cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH));
return;
@@ -1658,7 +1651,7 @@ cairo_xcb_surface_set_drawable (cairo_surface_t *abstract_surface,
}
- if (abstract_surface->type != CAIRO_SURFACE_TYPE_XCB) {
+ if ( !_cairo_surface_is_xcb(abstract_surface)) {
_cairo_surface_set_error (abstract_surface,
_cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH));
return;
diff --git a/src/cairo-xcb.h b/src/cairo-xcb.h
index e321d8482..e321d8482 100755..100644
--- a/src/cairo-xcb.h
+++ b/src/cairo-xcb.h
diff --git a/src/cairo-xlib-core-compositor.c b/src/cairo-xlib-core-compositor.c
index 9398079b4..5babcc81b 100755..100644
--- a/src/cairo-xlib-core-compositor.c
+++ b/src/cairo-xlib-core-compositor.c
@@ -292,9 +292,7 @@ render_boxes (cairo_xlib_surface_t *dst,
const cairo_pattern_t *pattern,
cairo_boxes_t *boxes)
{
- double pad;
-
- if (_cairo_pattern_analyze_filter (pattern, &pad) != CAIRO_FILTER_NEAREST)
+ if (pattern->filter != CAIRO_FILTER_NEAREST)
return fallback_boxes (dst, pattern, boxes);
switch (pattern->extend) {
diff --git a/src/cairo-xlib-display.c b/src/cairo-xlib-display.c
index cc82b3a99..88efe9c0e 100755..100644
--- a/src/cairo-xlib-display.c
+++ b/src/cairo-xlib-display.c
@@ -292,7 +292,7 @@ _cairo_xlib_device_create (Display *dpy)
*
* 1. The original bug that led to the buggy_repeat
* workaround. This was a bug that Owen Taylor investigated,
- * understood well, and characterized against carious X
+ * understood well, and characterized against various X
* servers. Confirmed X servers with this bug include:
*
* "XFree86" <= 40500000
@@ -484,7 +484,7 @@ _cairo_xlib_display_get_xrender_format_for_pixman(cairo_xlib_display_t *display,
#undef MASK
/* XXX caching? */
- return XRenderFindFormat(dpy, mask, &tmpl, 1);
+ return XRenderFindFormat(dpy, mask, &tmpl, 0);
}
XRenderPictFormat *
@@ -493,12 +493,6 @@ _cairo_xlib_display_get_xrender_format (cairo_xlib_display_t *display,
{
XRenderPictFormat *xrender_format;
-#if ! ATOMIC_OP_NEEDS_MEMORY_BARRIER
- xrender_format = display->cached_xrender_formats[format];
- if (likely (xrender_format != NULL))
- return xrender_format;
-#endif
-
xrender_format = display->cached_xrender_formats[format];
if (xrender_format == NULL) {
int pict_format = PictStandardNUM;
@@ -576,7 +570,7 @@ _cairo_xlib_display_has_gradients (cairo_device_t *device)
*
* Restricts all future Xlib surfaces for this devices to the specified version
* of the RENDER extension. This function exists solely for debugging purpose.
- * It let's you find out how cairo would behave with an older version of
+ * It lets you find out how cairo would behave with an older version of
* the RENDER extension.
*
* Use the special values -1 and -1 for disabling the RENDER extension.
diff --git a/src/cairo-xlib-fallback-compositor.c b/src/cairo-xlib-fallback-compositor.c
index ed2845db5..ed2845db5 100755..100644
--- a/src/cairo-xlib-fallback-compositor.c
+++ b/src/cairo-xlib-fallback-compositor.c
diff --git a/src/cairo-xlib-private.h b/src/cairo-xlib-private.h
index 4fd725f93..0f2f2e1fa 100755..100644
--- a/src/cairo-xlib-private.h
+++ b/src/cairo-xlib-private.h
@@ -37,8 +37,8 @@
#ifndef CAIRO_XLIB_PRIVATE_H
#define CAIRO_XLIB_PRIVATE_H
-#include "cairo-xlib.h"
#include "cairo-xlib-xrender-private.h"
+#include "cairo-xlib.h"
#include "cairo-compiler-private.h"
#include "cairo-device-private.h"
@@ -81,7 +81,7 @@ struct _cairo_xlib_display {
int render_major;
int render_minor;
- XRenderPictFormat *cached_xrender_formats[CAIRO_FORMAT_RGB16_565 + 1];
+ XRenderPictFormat *cached_xrender_formats[CAIRO_FORMAT_RGB30 + 1];
int force_precision;
@@ -373,6 +373,8 @@ _cairo_xlib_font_close (cairo_xlib_font_t *font);
#define CAIRO_RENDER_HAS_PICTURE_TRANSFORM(surface) CAIRO_RENDER_AT_LEAST((surface), 0, 6)
#define CAIRO_RENDER_HAS_FILTERS(surface) CAIRO_RENDER_AT_LEAST((surface), 0, 6)
+#define CAIRO_RENDER_HAS_FILTER_GOOD(surface) FALSE
+#define CAIRO_RENDER_HAS_FILTER_BEST(surface) FALSE
#define CAIRO_RENDER_HAS_EXTENDED_REPEAT(surface) CAIRO_RENDER_AT_LEAST((surface), 0, 10)
#define CAIRO_RENDER_HAS_GRADIENTS(surface) CAIRO_RENDER_AT_LEAST((surface), 0, 10)
diff --git a/src/cairo-xlib-render-compositor.c b/src/cairo-xlib-render-compositor.c
index 05cde708b..82ed26af7 100755..100644
--- a/src/cairo-xlib-render-compositor.c
+++ b/src/cairo-xlib-render-compositor.c
@@ -51,6 +51,7 @@
#include "cairo-image-surface-private.h"
#include "cairo-list-inline.h"
#include "cairo-pattern-private.h"
+#include "cairo-pixman-private.h"
#include "cairo-traps-private.h"
#include "cairo-tristrip-private.h"
@@ -99,7 +100,7 @@ set_clip_region (void *_surface,
_cairo_xlib_surface_ensure_picture (surface);
if (region != NULL) {
- XRectangle stack_rects[CAIRO_STACK_ARRAY_LENGTH (sizeof (XRectangle))];
+ XRectangle stack_rects[CAIRO_STACK_ARRAY_LENGTH (XRectangle)];
XRectangle *rects = stack_rects;
int n_rects, i;
@@ -1295,6 +1296,9 @@ _cairo_xlib_surface_add_glyph (cairo_xlib_display_t *display,
unsigned char *d;
unsigned char *new, *n;
+ if (c == 0)
+ break;
+
new = malloc (c);
if (!new) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
@@ -1320,6 +1324,9 @@ _cairo_xlib_surface_add_glyph (cairo_xlib_display_t *display,
const uint32_t *d;
uint32_t *new, *n;
+ if (c == 0)
+ break;
+
new = malloc (4 * c);
if (unlikely (new == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
@@ -1478,14 +1485,14 @@ _emit_glyphs_chunk (cairo_xlib_display_t *display,
*/
if (_start_new_glyph_elt (j, &glyphs[i])) {
if (j) {
- elts[nelt].nchars = n;
- nelt++;
- n = 0;
+ elts[nelt].nchars = n;
+ nelt++;
+ n = 0;
}
elts[nelt].chars = char8 + size * j;
elts[nelt].glyphset = info->glyphset;
- elts[nelt].xOff = glyphs[i].i.x - dst_x;
- elts[nelt].yOff = glyphs[i].i.y - dst_y;
+ elts[nelt].xOff = glyphs[i].i.x;
+ elts[nelt].yOff = glyphs[i].i.y;
}
switch (width) {
@@ -1588,7 +1595,7 @@ composite_glyphs (void *surface,
cairo_xlib_display_t *display = dst->display;
cairo_int_status_t status = CAIRO_INT_STATUS_SUCCESS;
cairo_scaled_glyph_t *glyph;
- cairo_fixed_t x = 0, y = 0;
+ cairo_fixed_t x = dst_x, y = dst_y;
cairo_xlib_font_glyphset_t *glyphset = NULL, *this_glyphset_info;
unsigned long max_index = 0;
@@ -1606,11 +1613,6 @@ composite_glyphs (void *surface,
op = _render_operator (op),
_cairo_xlib_surface_ensure_picture (dst);
-
-#if CAIRO_HAS_TG_SURFACE
- _cairo_scaled_font_freeze_cache(info->font);
-#endif
-
for (i = 0; i < num_glyphs; i++) {
int this_x, this_y;
int old_width;
@@ -1620,7 +1622,7 @@ composite_glyphs (void *surface,
CAIRO_SCALED_GLYPH_INFO_METRICS,
&glyph);
if (unlikely (status))
- goto done;
+ return status;
this_x = _cairo_lround (glyphs[i].d.x);
this_y = _cairo_lround (glyphs[i].d.y);
@@ -1629,7 +1631,7 @@ composite_glyphs (void *surface,
if (glyph->dev_private_key != display) {
status = _cairo_xlib_surface_add_glyph (display, info->font, &glyph);
if (unlikely (status))
- goto done;
+ return status;
}
this_glyphset_info = glyph->dev_private;
@@ -1681,7 +1683,7 @@ composite_glyphs (void *surface,
op, src, src_x, src_y,
num_elts, old_width, glyphset);
if (unlikely (status))
- goto done;
+ return status;
glyphs += i;
num_glyphs -= i;
@@ -1726,11 +1728,6 @@ composite_glyphs (void *surface,
num_elts, width, glyphset);
}
-done:
-#if CAIRO_HAS_TG_SURFACE
- _cairo_scaled_font_thaw_cache(info->font);
-#endif
-
return status;
}
@@ -2001,7 +1998,7 @@ _cairo_xlib_traps_compositor_get (void)
compositor.check_composite = check_composite;
compositor.composite = composite;
compositor.lerp = lerp;
- //FIXME:
+ // FIXME:
compositor.lerp_color_glyph = lerp;
//compositor.check_composite_boxes = check_composite_boxes;
compositor.composite_boxes = composite_boxes;
diff --git a/src/cairo-xlib-screen.c b/src/cairo-xlib-screen.c
index 119603e9a..119603e9a 100755..100644
--- a/src/cairo-xlib-screen.c
+++ b/src/cairo-xlib-screen.c
diff --git a/src/cairo-xlib-source.c b/src/cairo-xlib-source.c
index 4e9babd79..d5752ba99 100755..100644
--- a/src/cairo-xlib-source.c
+++ b/src/cairo-xlib-source.c
@@ -288,13 +288,14 @@ render_pattern (cairo_xlib_surface_t *dst,
cairo_rectangle_int_t map_extents;
src = (cairo_xlib_surface_t *)
- _cairo_surface_create_similar_scratch (&dst->base,
- is_mask ? CAIRO_CONTENT_ALPHA : CAIRO_CONTENT_COLOR_ALPHA,
- extents->width,
- extents->height);
+ _cairo_surface_create_scratch (&dst->base,
+ is_mask ? CAIRO_CONTENT_ALPHA : CAIRO_CONTENT_COLOR_ALPHA,
+ extents->width,
+ extents->height,
+ NULL);
if (src->base.type != CAIRO_SURFACE_TYPE_XLIB) {
cairo_surface_destroy (&src->base);
- return None;
+ return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
}
map_extents = *extents;
@@ -750,10 +751,11 @@ subsurface_source (cairo_xlib_surface_t *dst,
source = &src->embedded_source;
} else {
src = (cairo_xlib_surface_t *)
- _cairo_surface_create_similar_scratch (&dst->base,
- sub->base.content,
- sub->extents.width,
- sub->extents.height);
+ _cairo_surface_create_scratch (&dst->base,
+ sub->base.content,
+ sub->extents.width,
+ sub->extents.height,
+ NULL);
if (src->base.type != CAIRO_SURFACE_TYPE_XLIB) {
cairo_surface_destroy (&src->base);
return _cairo_surface_create_in_error (CAIRO_STATUS_NO_MEMORY);
@@ -867,11 +869,14 @@ recording_pattern_get_surface (const cairo_pattern_t *pattern)
cairo_surface_t *surface;
surface = ((const cairo_surface_pattern_t *) pattern)->surface;
+
if (_cairo_surface_is_paginated (surface))
- surface = _cairo_paginated_surface_get_recording (surface);
+ return cairo_surface_reference (_cairo_paginated_surface_get_recording (surface));
+
if (_cairo_surface_is_snapshot (surface))
- surface = _cairo_surface_snapshot_get_target (surface);
- return surface;
+ return _cairo_surface_snapshot_get_target (surface);
+
+ return cairo_surface_reference (surface);
}
static cairo_surface_t *
@@ -883,6 +888,7 @@ record_source (cairo_xlib_surface_t *dst,
int *src_x, int *src_y)
{
cairo_xlib_surface_t *src;
+ cairo_surface_t *recording;
cairo_matrix_t matrix, m;
cairo_status_t status;
cairo_rectangle_int_t upload, limit;
@@ -898,19 +904,22 @@ record_source (cairo_xlib_surface_t *dst,
}
src = (cairo_xlib_surface_t *)
- _cairo_surface_create_similar_scratch (&dst->base,
- pattern->surface->content,
- upload.width,
- upload.height);
+ _cairo_surface_create_scratch (&dst->base,
+ pattern->surface->content,
+ upload.width,
+ upload.height,
+ NULL);
if (src->base.type != CAIRO_SURFACE_TYPE_XLIB) {
cairo_surface_destroy (&src->base);
return _cairo_surface_create_in_error (CAIRO_STATUS_NO_MEMORY);
}
cairo_matrix_init_translate (&matrix, upload.x, upload.y);
- status = _cairo_recording_surface_replay_with_clip (recording_pattern_get_surface (&pattern->base),
+ recording = recording_pattern_get_surface (&pattern->base),
+ status = _cairo_recording_surface_replay_with_clip (recording,
&matrix, &src->base,
NULL);
+ cairo_surface_destroy (recording);
if (unlikely (status)) {
cairo_surface_destroy (&src->base);
return _cairo_surface_create_in_error (status);
@@ -993,6 +1002,9 @@ surface_source (cairo_xlib_surface_t *dst,
if (pattern->base.extend == CAIRO_EXTEND_NONE) {
if (! _cairo_rectangle_intersect (&upload, &limit))
return alpha_source (dst, 0);
+ } else if (pattern->base.extend == CAIRO_EXTEND_PAD) {
+ if (! _cairo_rectangle_intersect (&upload, &limit))
+ upload = limit;
} else {
if (upload.x < limit.x ||
upload.x + upload.width > limit.x + limit.width ||
@@ -1005,14 +1017,15 @@ surface_source (cairo_xlib_surface_t *dst,
}
xsrc = (cairo_xlib_surface_t *)
- _cairo_surface_create_similar_scratch (&dst->base,
- src->content,
- upload.width,
- upload.height);
+ _cairo_surface_create_scratch (&dst->base,
+ src->content,
+ upload.width,
+ upload.height,
+ NULL);
if (xsrc->base.type != CAIRO_SURFACE_TYPE_XLIB) {
cairo_surface_destroy (src);
cairo_surface_destroy (&xsrc->base);
- return None;
+ return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
}
if (_cairo_surface_is_image (src)) {
@@ -1093,17 +1106,22 @@ pattern_is_supported (cairo_xlib_display_t *display,
return FALSE;
}
- if (! CAIRO_RENDER_HAS_PICTURE_TRANSFORM (display)) {
- if (!_cairo_matrix_is_integer_translation (&pattern->matrix, NULL, NULL))
- return FALSE;
- }
-
- if (! CAIRO_RENDER_HAS_FILTERS (display)) {
- /* No filters implies no transforms, so we optimise away BILINEAR */
+ switch (pattern->filter) {
+ case CAIRO_FILTER_FAST:
+ case CAIRO_FILTER_NEAREST:
+ return CAIRO_RENDER_HAS_PICTURE_TRANSFORM (display) ||
+ _cairo_matrix_is_integer_translation (&pattern->matrix, NULL, NULL);
+ case CAIRO_FILTER_GOOD:
+ return CAIRO_RENDER_HAS_FILTER_GOOD (display);
+ case CAIRO_FILTER_BEST:
+ return CAIRO_RENDER_HAS_FILTER_BEST (display);
+ case CAIRO_FILTER_BILINEAR:
+ case CAIRO_FILTER_GAUSSIAN:
+ default:
+ return CAIRO_RENDER_HAS_FILTERS (display);
}
-
- return TRUE;
}
+
cairo_surface_t *
_cairo_xlib_source_create_for_pattern (cairo_surface_t *_dst,
const cairo_pattern_t *pattern,
diff --git a/src/cairo-xlib-surface-private.h b/src/cairo-xlib-surface-private.h
index 87db6962b..83d9b63cc 100755..100644
--- a/src/cairo-xlib-surface-private.h
+++ b/src/cairo-xlib-surface-private.h
@@ -33,9 +33,9 @@
#ifndef CAIRO_XLIB_SURFACE_PRIVATE_H
#define CAIRO_XLIB_SURFACE_PRIVATE_H
+#include "cairo-xlib-xrender-private.h"
#include "cairo-xlib.h"
#include "cairo-xlib-private.h"
-#include "cairo-xlib-xrender-private.h"
#include "cairo-surface-private.h"
#include "cairo-surface-backend-private.h"
diff --git a/src/cairo-xlib-surface-shm.c b/src/cairo-xlib-surface-shm.c
index fa7d3eb9b..9b4dea5e5 100755..100644
--- a/src/cairo-xlib-surface-shm.c
+++ b/src/cairo-xlib-surface-shm.c
@@ -453,7 +453,7 @@ static void send_event(cairo_xlib_display_t *display,
display->shm->last_event = ev.serial;
}
-static void sync (cairo_xlib_display_t *display)
+static void _cairo_xlib_display_sync (cairo_xlib_display_t *display)
{
cairo_xlib_shm_info_t *info;
struct pqueue *pq = &display->shm->info;
@@ -670,6 +670,7 @@ _cairo_xlib_shm_surface_flush (void *abstract_surface, unsigned flags)
cairo_xlib_shm_surface_t *shm = abstract_surface;
cairo_xlib_display_t *display;
Display *dpy;
+ _XQEvent *qev;
cairo_status_t status;
if (shm->active == 0)
@@ -694,6 +695,10 @@ _cairo_xlib_shm_surface_flush (void *abstract_surface, unsigned flags)
while (! seqno_passed (shm->active, LastKnownRequestProcessed (dpy))) {
LockDisplay(dpy);
_XReadEvents(dpy);
+ while (dpy->head) {
+ qev = dpy->head;
+ _XDeq (dpy, NULL, qev);
+ }
UnlockDisplay(dpy);
}
@@ -893,7 +898,7 @@ _cairo_xlib_surface_update_shm (cairo_xlib_surface_t *surface)
}
if (damage->region) {
- XRectangle stack_rects[CAIRO_STACK_ARRAY_LENGTH (sizeof (XRectangle))];
+ XRectangle stack_rects[CAIRO_STACK_ARRAY_LENGTH (XRectangle)];
XRectangle *rects = stack_rects;
cairo_rectangle_int_t r;
int n_rects, i;
@@ -949,7 +954,7 @@ _cairo_xlib_surface_update_shm (cairo_xlib_surface_t *surface)
XChangeGC (display->display, gc, GCSubwindowMode, &gcv);
}
- sync (display);
+ _cairo_xlib_display_sync (display);
shm->active = 0;
shm->idle--;
@@ -1081,7 +1086,7 @@ _cairo_xlib_surface_put_shm (cairo_xlib_surface_t *surface)
TRACE ((stderr, "%s: flushing damage x %d\n", __FUNCTION__,
damage->region ? cairo_region_num_rectangles (damage->region) : 0));
if (damage->status == CAIRO_STATUS_SUCCESS && damage->region) {
- XRectangle stack_rects[CAIRO_STACK_ARRAY_LENGTH (sizeof (XRectangle))];
+ XRectangle stack_rects[CAIRO_STACK_ARRAY_LENGTH (XRectangle)];
XRectangle *rects = stack_rects;
cairo_rectangle_int_t r;
int n_rects, i;
diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c
index 2fb29e3d4..8128ebc05 100755..100644
--- a/src/cairo-xlib-surface.c
+++ b/src/cairo-xlib-surface.c
@@ -60,6 +60,7 @@
#include "cairo-image-surface-private.h"
#include "cairo-list-inline.h"
#include "cairo-pattern-private.h"
+#include "cairo-pixman-private.h"
#include "cairo-region-private.h"
#include "cairo-scaled-font-private.h"
#include "cairo-surface-snapshot-private.h"
@@ -385,14 +386,14 @@ _cairo_xlib_surface_finish (void *abstract_surface)
cairo_status_t status;
cairo_xlib_display_t *display;
- X_DEBUG ((display->display, "finish (drawable=%x)", (unsigned int) surface->drawable));
-
cairo_list_del (&surface->link);
status = _cairo_xlib_display_acquire (surface->base.device, &display);
if (unlikely (status))
return status;
+ X_DEBUG ((display->display, "finish (drawable=%x)", (unsigned int) surface->drawable));
+
if (surface->embedded_source.picture)
XRenderFreePicture (display->display, surface->embedded_source.picture);
if (surface->picture)
diff --git a/src/cairo-xlib-visual.c b/src/cairo-xlib-visual.c
index d9aac44ca..863822eeb 100755..100644
--- a/src/cairo-xlib-visual.c
+++ b/src/cairo-xlib-visual.c
@@ -40,6 +40,7 @@
#include "cairo-xlib-private.h"
#include "cairo-error-private.h"
+#include "cairo-list-inline.h"
/* A perceptual distance metric between two colors. No sqrt needed
* since the square of the distance is still a valid metric. */
@@ -85,6 +86,7 @@ _cairo_xlib_visual_info_create (Display *dpy,
if (unlikely (info == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ cairo_list_init (&info->link);
info->visualid = visualid;
/* Allocate a gray ramp and a color cube.
@@ -185,6 +187,7 @@ void
_cairo_xlib_visual_info_destroy (cairo_xlib_visual_info_t *info)
{
/* No need for XFreeColors() whilst using DefaultColormap */
+ _cairo_list_del (&info->link);
free (info);
}
diff --git a/src/cairo-xlib-xcb-surface.c b/src/cairo-xlib-xcb-surface.c
index 9c0d4b413..af3e15578 100755..100644
--- a/src/cairo-xlib-xcb-surface.c
+++ b/src/cairo-xlib-xcb-surface.c
@@ -519,21 +519,6 @@ cairo_xlib_surface_create (Display *dpy,
width, height));
}
-cairo_surface_t *
-cairo_xlib_surface_create_for_bitmap (Display *dpy,
- Pixmap bitmap,
- Screen *scr,
- int width,
- int height)
-{
- return _cairo_xlib_xcb_surface_create (dpy, scr, NULL, NULL,
- cairo_xcb_surface_create_for_bitmap (XGetXCBConnection (dpy),
- (xcb_screen_t *) scr,
- bitmap,
- width, height));
-}
-
-#if CAIRO_HAS_XLIB_XRENDER_SURFACE
static xcb_screen_t *
_cairo_xcb_screen_from_root (xcb_connection_t *connection,
xcb_window_t id)
@@ -548,6 +533,24 @@ _cairo_xcb_screen_from_root (xcb_connection_t *connection,
return NULL;
}
+
+cairo_surface_t *
+cairo_xlib_surface_create_for_bitmap (Display *dpy,
+ Pixmap bitmap,
+ Screen *scr,
+ int width,
+ int height)
+{
+ xcb_connection_t *connection = XGetXCBConnection (dpy);
+ xcb_screen_t *screen = _cairo_xcb_screen_from_root (connection, (xcb_window_t) scr->root);
+ return _cairo_xlib_xcb_surface_create (dpy, scr, NULL, NULL,
+ cairo_xcb_surface_create_for_bitmap (connection,
+ screen,
+ bitmap,
+ width, height));
+}
+
+#if CAIRO_HAS_XLIB_XRENDER_SURFACE
cairo_surface_t *
cairo_xlib_surface_create_with_xrender_format (Display *dpy,
Drawable drawable,
diff --git a/src/cairo-xlib-xrender-private.h b/src/cairo-xlib-xrender-private.h
index bf3199c4c..90769467b 100755..100644
--- a/src/cairo-xlib-xrender-private.h
+++ b/src/cairo-xlib-xrender-private.h
@@ -96,6 +96,10 @@ __attribute__((__unused__)) static void _void_consume_free (Display *p, XID
#define PictOpBlendMaximum 0x3e
#endif
+#if !HAVE_XRENDERCREATESOLIDFILL
+#define XRenderCreateSolidFill _int_consume
+#endif
+
#if !HAVE_XRENDERCREATELINEARGRADIENT
#define XRenderCreateLinearGradient _int_consume
diff --git a/src/cairo-xlib-xrender.h b/src/cairo-xlib-xrender.h
index b34b057de..b34b057de 100755..100644
--- a/src/cairo-xlib-xrender.h
+++ b/src/cairo-xlib-xrender.h
diff --git a/src/cairo-xlib.h b/src/cairo-xlib.h
index ecf8d6c86..ecf8d6c86 100755..100644
--- a/src/cairo-xlib.h
+++ b/src/cairo-xlib.h
diff --git a/src/cairo-xml-surface.c b/src/cairo-xml-surface.c
index 777d47089..6dbafdba2 100755..100644
--- a/src/cairo-xml-surface.c
+++ b/src/cairo-xml-surface.c
@@ -459,19 +459,79 @@ to_xml (cairo_xml_surface_t *surface)
}
static cairo_status_t
+_cairo_xml_surface_emit_clip_boxes (cairo_xml_surface_t *surface,
+ const cairo_clip_t *clip)
+{
+ cairo_box_t *box;
+ cairo_xml_t *xml;
+ int n;
+
+ if (clip->num_boxes == 0)
+ return CAIRO_STATUS_SUCCESS;
+
+ /* skip the trivial clip covering the surface extents */
+ if (surface->width >= 0 && surface->height >= 0 && clip->num_boxes == 1) {
+ box = &clip->boxes[0];
+ if (box->p1.x <= 0 && box->p1.y <= 0 &&
+ box->p2.x - box->p1.x >= _cairo_fixed_from_double (surface->width) &&
+ box->p2.y - box->p1.y >= _cairo_fixed_from_double (surface->height))
+ {
+ return CAIRO_STATUS_SUCCESS;
+ }
+ }
+
+ xml = to_xml (surface);
+
+ _cairo_xml_printf (xml, "<clip>");
+ _cairo_xml_indent (xml, 2);
+
+ _cairo_xml_printf (xml, "<path>");
+ _cairo_xml_indent (xml, 2);
+ for (n = 0; n < clip->num_boxes; n++) {
+ box = &clip->boxes[n];
+
+ _cairo_xml_printf_start (xml, "%f %f m",
+ _cairo_fixed_to_double (box->p1.x),
+ _cairo_fixed_to_double (box->p1.y));
+ _cairo_xml_printf_continue (xml, " %f %f l",
+ _cairo_fixed_to_double (box->p2.x),
+ _cairo_fixed_to_double (box->p1.y));
+ _cairo_xml_printf_continue (xml, " %f %f l",
+ _cairo_fixed_to_double (box->p2.x),
+ _cairo_fixed_to_double (box->p2.y));
+ _cairo_xml_printf_continue (xml, " %f %f l",
+ _cairo_fixed_to_double (box->p1.x),
+ _cairo_fixed_to_double (box->p2.y));
+ _cairo_xml_printf_end (xml, " h");
+ }
+ _cairo_xml_indent (xml, -2);
+ _cairo_xml_printf (xml, "</path>");
+ _cairo_xml_emit_double (xml, "tolerance", 1.0);
+ _cairo_xml_emit_string (xml, "antialias",
+ _antialias_to_string (CAIRO_ANTIALIAS_NONE));
+ _cairo_xml_emit_string (xml, "fill-rule",
+ _fill_rule_to_string (CAIRO_FILL_RULE_WINDING));
+
+ _cairo_xml_indent (xml, -2);
+ _cairo_xml_printf (xml, "</clip>");
+
+ return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_status_t
_cairo_xml_surface_emit_clip_path (cairo_xml_surface_t *surface,
- cairo_clip_path_t *clip_path)
+ const cairo_clip_path_t *clip_path)
{
cairo_box_t box;
cairo_status_t status;
cairo_xml_t *xml;
- if (clip_path->prev != NULL) {
- status = _cairo_xml_surface_emit_clip_path (surface, clip_path->prev);
- if (unlikely (status))
- return status;
- }
+ if (clip_path == NULL)
+ return CAIRO_STATUS_SUCCESS;
+ status = _cairo_xml_surface_emit_clip_path (surface, clip_path->prev);
+ if (unlikely (status))
+ return status;
/* skip the trivial clip covering the surface extents */
if (surface->width >= 0 && surface->height >= 0 &&
@@ -507,9 +567,15 @@ static cairo_status_t
_cairo_xml_surface_emit_clip (cairo_xml_surface_t *surface,
const cairo_clip_t *clip)
{
+ cairo_status_t status;
+
if (clip == NULL)
return CAIRO_STATUS_SUCCESS;
+ status = _cairo_xml_surface_emit_clip_boxes (surface, clip);
+ if (unlikely (status))
+ return status;
+
return _cairo_xml_surface_emit_clip_path (surface, clip->path);
}
diff --git a/src/cairo-xml.h b/src/cairo-xml.h
index 9ae76e90a..9ae76e90a 100755..100644
--- a/src/cairo-xml.h
+++ b/src/cairo-xml.h
diff --git a/src/cairo.c b/src/cairo.c
index 3a6607b1b..983f02cea 100755..100644
--- a/src/cairo.c
+++ b/src/cairo.c
@@ -152,7 +152,9 @@ static const cairo_t _cairo_nil[] = {
DEFINE_NIL_CONTEXT (CAIRO_STATUS_DEVICE_TYPE_MISMATCH),
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_DEVICE_FINISHED),
+ DEFINE_NIL_CONTEXT (CAIRO_STATUS_JBIG2_GLOBAL_MISSING)
+
};
COMPILE_TIME_ASSERT (ARRAY_LENGTH (_cairo_nil) == CAIRO_STATUS_LAST_STATUS - 1);
@@ -228,6 +230,8 @@ cairo_create (cairo_surface_t *target)
return _cairo_create_in_error (_cairo_error (CAIRO_STATUS_NULL_POINTER));
if (unlikely (target->status))
return _cairo_create_in_error (target->status);
+ if (unlikely (target->finished))
+ return _cairo_create_in_error (_cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
if (target->backend->create_context == NULL)
return _cairo_create_in_error (_cairo_error (CAIRO_STATUS_WRITE_ERROR));
@@ -1635,7 +1639,6 @@ cairo_arc (cairo_t *cr,
angle2 += 2 * M_PI;
angle2 += angle1;
}
-
status = cr->backend->arc (cr, xc, yc, radius, angle1, angle2, TRUE);
if (unlikely (status))
_cairo_set_error (cr, status);
@@ -1868,6 +1871,53 @@ cairo_rectangle (cairo_t *cr,
_cairo_set_error (cr, status);
}
+/**
+ * cairo_rounded_rectangle:
+ * @cr: a cairo context
+ * @x: the X coordinate of the top left corner of the rectangle
+ * @y: the Y coordinate to the top left corner of the rectangle
+ * @width: the width of the rectangle
+ * @height: the height of the rectangle
+ * @r_top_left: top left corner radius
+ * @r_top_right: top right corner radius
+ * @r_bottom_left: bottom left corner radius
+ * @r_bottom_left: top left corner radius
+ *
+ * Adds a closed sub-path roundedrectangle of the given size to the current
+ * path at position (@x, @y) in user-space coordinates.
+ *
+ * This function is logically equivalent to:
+ * <informalexample><programlisting>
+ * cairo_move_to (cr, x, y + r_top_left)
+ * cairo_rel_curve_to (cr, ....)
+ * cairo_rel_line_to (cr, ....)
+ * cairo_rel_curve_to (cr, ....)
+ * cairo_line_to (cr, ....)
+ * cairo_rel_curve_to (cr, ....)
+ * cairo_close_path (cr)
+ * </programlisting></informalexample>
+ *
+ * Since: 1.12
+ **/
+void
+cairo_rounded_rectangle (cairo_t *cr,
+ double x, double y,
+ double width, double height,
+ double r_top_left, double r_top_right,
+ double r_bottom_left, double r_bottom_right)
+{
+ cairo_status_t status;
+
+ if (unlikely (cr->status))
+ return;
+
+ status = cr->backend->rounded_rectangle (cr, x, y, width, height,
+ r_top_left, r_top_right,
+ r_bottom_left, r_bottom_right);
+ if (unlikely (status))
+ _cairo_set_error (cr, status);
+}
+
#if 0
/* XXX: NYI */
void
diff --git a/src/cairo.h b/src/cairo.h
index 2b03e77ec..c1649dbe5 100755..100644
--- a/src/cairo.h
+++ b/src/cairo.h
@@ -290,6 +290,8 @@ typedef struct _cairo_user_data_key {
* cairo_mesh_pattern_begin_patch()/cairo_mesh_pattern_end_patch()
* pair (Since 1.12)
* @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_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
@@ -345,6 +347,7 @@ typedef enum _cairo_status {
CAIRO_STATUS_DEVICE_ERROR,
CAIRO_STATUS_INVALID_MESH_CONSTRUCTION,
CAIRO_STATUS_DEVICE_FINISHED,
+ CAIRO_STATUS_JBIG2_GLOBAL_MISSING,
CAIRO_STATUS_LAST_STATUS
} cairo_status_t;
@@ -892,6 +895,13 @@ cairo_rectangle (cairo_t *cr,
double x, double y,
double width, double height);
+cairo_public void
+cairo_rounded_rectangle (cairo_t *cr,
+ double x, double y,
+ double width, double height,
+ double r_top_left, double r_top_right,
+ double r_bottom_left, double r_bottom_right);
+
/* XXX: NYI
cairo_public void
cairo_stroke_to_path (cairo_t *cr);
@@ -1341,7 +1351,7 @@ typedef enum _cairo_hint_metrics {
/**
* cairo_font_color_t:
* @CAIRO_FONT_COLOR_DEFAULT: default color, if the font has color,
- * use font's color, otherwise, use user specified, since 1.12.14
+ * use font's color, otherwise, use user specified, since 1.12.14
* @CAIRO_FONT_COLOR_USER: always uses user's color, since 1.0
*
* When rendering text, specifies whether to use user's color set
@@ -1349,12 +1359,12 @@ typedef enum _cairo_hint_metrics {
*
* Since: 1.4
**/
- typedef enum _cairo_font_color {
- CAIRO_FONT_COLOR_DEFAULT,
- CAIRO_FONT_COLOR_USER
- } cairo_font_color_t;
+typedef enum _cairo_font_color {
+ CAIRO_FONT_COLOR_DEFAULT,
+ CAIRO_FONT_COLOR_USER
+} cairo_font_color_t;
- /**
+/**
* cairo_font_options_t:
*
* An opaque structure holding all options that are used when
@@ -1426,8 +1436,7 @@ cairo_font_options_get_hint_metrics (const cairo_font_options_t *options);
cairo_public void
cairo_font_options_set_font_color (cairo_font_options_t *options,
-cairo_font_color_t font_color);
-
+ cairo_font_color_t font_color);
cairo_public cairo_font_color_t
cairo_font_options_get_font_color (const cairo_font_options_t *options);
@@ -2095,6 +2104,7 @@ typedef struct cairo_path {
cairo_status_t status;
cairo_path_data_t *data;
int num_data;
+ unsigned int is_convex : 1;
} cairo_path_t;
cairo_public cairo_path_t *
@@ -2231,6 +2241,15 @@ cairo_surface_create_for_rectangle (cairo_surface_t *target,
double width,
double height);
+/**
+ * cairo_surface_observer_mode_t:
+ * @CAIRO_SURFACE_OBSERVER_NORMAL: no recording is done
+ * @CAIRO_SURFACE_OBSERVER_RECORD_OPERATIONS: operations are recorded
+ *
+ * Whether operations should be recorded.
+ *
+ * Since: 1.12
+ **/
typedef enum {
CAIRO_SURFACE_OBSERVER_NORMAL = 0,
CAIRO_SURFACE_OBSERVER_RECORD_OPERATIONS = 0x1
@@ -2405,8 +2424,7 @@ typedef enum _cairo_surface_type {
CAIRO_SURFACE_TYPE_XML,
CAIRO_SURFACE_TYPE_SKIA,
CAIRO_SURFACE_TYPE_SUBSURFACE,
- CAIRO_SURFACE_TYPE_COGL,
- CAIRO_SURFACE_TYPE_TG,
+ CAIRO_SURFACE_TYPE_COGL
} cairo_surface_type_t;
cairo_public cairo_surface_type_t
@@ -2443,6 +2461,9 @@ cairo_surface_set_user_data (cairo_surface_t *surface,
#define CAIRO_MIME_TYPE_JP2 "image/jp2"
#define CAIRO_MIME_TYPE_URI "text/x-uri"
#define CAIRO_MIME_TYPE_UNIQUE_ID "application/x-cairo.uuid"
+#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"
cairo_public void
cairo_surface_get_mime_data (cairo_surface_t *surface,
@@ -2480,6 +2501,16 @@ cairo_surface_mark_dirty_rectangle (cairo_surface_t *surface,
int height);
cairo_public void
+cairo_surface_set_device_scale (cairo_surface_t *surface,
+ double x_scale,
+ double y_scale);
+
+cairo_public void
+cairo_surface_get_device_scale (cairo_surface_t *surface,
+ double *x_scale,
+ double *y_scale);
+
+cairo_public void
cairo_surface_set_device_offset (cairo_surface_t *surface,
double x_offset,
double y_offset);
@@ -2961,10 +2992,10 @@ cairo_public void
cairo_set_shadow_rgba (cairo_t *cr, double red, double green,
double blue, double alpha);
-cairo_public void
+cairo_public void
cairo_set_shadow_blur (cairo_t *cr, double x_blur, double y_blur);
-cairo_public void
+cairo_public void
cairo_set_draw_shadow_only (cairo_t *cr, cairo_bool_t draw_shadow_only);
cairo_public void
@@ -3090,6 +3121,17 @@ cairo_matrix_transform_point (const cairo_matrix_t *matrix,
**/
typedef struct _cairo_region cairo_region_t;
+/**
+ * cairo_region_overlap_t:
+ * @CAIRO_REGION_OVERLAP_IN: The contents are entirely inside the region. (Since 1.10)
+ * @CAIRO_REGION_OVERLAP_OUT: The contents are entirely outside the region. (Since 1.10)
+ * @CAIRO_REGION_OVERLAP_PART: The contents are partially inside and
+ * partially outside the region. (Since 1.10)
+ *
+ * Used as the return value for cairo_region_contains_rectangle().
+ *
+ * Since: 1.10
+ **/
typedef enum _cairo_region_overlap {
CAIRO_REGION_OVERLAP_IN, /* completely inside region */
CAIRO_REGION_OVERLAP_OUT, /* completely outside region */
diff --git a/src/cairo.pc.in b/src/cairo.pc.in
index b361edf18..b361edf18 100755..100644
--- a/src/cairo.pc.in
+++ b/src/cairo.pc.in
diff --git a/src/cairoint.h b/src/cairoint.h
index e4f483a3a..7c73c3d13 100755..100644
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -229,7 +229,7 @@ be16_to_cpu(uint16_t v)
static inline uint32_t cairo_const
cpu_to_be32(uint32_t v)
{
- return (cpu_to_be16 (v) << 16) | cpu_to_be16 (v >> 16);
+ return (v >> 24) | ((v >> 8) & 0xff00) | ((v << 8) & 0xff0000) | (v << 24);
}
static inline uint32_t cairo_const
@@ -240,6 +240,32 @@ be32_to_cpu(uint32_t v)
#endif
+/* Unaligned big endian access
+ */
+
+static inline uint16_t get_unaligned_be16 (const unsigned char *p)
+{
+ return p[0] << 8 | p[1];
+}
+
+static inline uint32_t get_unaligned_be32 (const unsigned char *p)
+{
+ return p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3];
+}
+
+static inline void put_unaligned_be16 (uint16_t v, unsigned char *p)
+{
+ p[0] = (v >> 8) & 0xff;
+ p[1] = v & 0xff;
+}
+
+static inline void put_unaligned_be32 (uint32_t v, unsigned char *p)
+{
+ p[0] = (v >> 24) & 0xff;
+ p[1] = (v >> 16) & 0xff;
+ p[2] = (v >> 8) & 0xff;
+ p[3] = v & 0xff;
+}
/* The glibc versions of ispace() and isdigit() are slow in UTF-8 locales.
*/
@@ -428,7 +454,7 @@ _cairo_cogl_context_reset_static_data (void);
/* the font backend interface */
struct _cairo_unscaled_font_backend {
- void (*destroy) (void *unscaled_font);
+ cairo_bool_t (*destroy) (void *unscaled_font);
};
/* #cairo_toy_font_face_t - simple family/slant/weight font faces used for
@@ -587,7 +613,7 @@ struct _cairo_font_face_backend {
/* The destroy() function is allowed to resurrect the font face
* by re-referencing. This is needed for the FreeType backend.
*/
- void
+ cairo_bool_t
(*destroy) (void *font_face);
cairo_warn cairo_status_t
@@ -797,6 +823,9 @@ cairo_private void
_cairo_font_face_init (cairo_font_face_t *font_face,
const cairo_font_face_backend_t *backend);
+cairo_private cairo_bool_t
+_cairo_font_face_destroy (void *abstract_face);
+
cairo_private cairo_status_t
_cairo_font_face_set_error (cairo_font_face_t *font_face,
cairo_status_t status);
@@ -872,6 +901,9 @@ _cairo_intern_string (const char **str_inout, int len);
cairo_private void
_cairo_intern_string_reset_static_data (void);
+cairo_private const char *
+cairo_get_locale_decimal_point (void);
+
/* cairo-path-fixed.c */
cairo_private cairo_path_fixed_t *
_cairo_path_fixed_create (void);
@@ -1034,6 +1066,9 @@ cairo_private cairo_bool_t
_cairo_path_fixed_is_single_arc (const cairo_path_fixed_t *path);
cairo_private cairo_bool_t
+_cairo_path_fixed_is_empty (const cairo_path_fixed_t *path);
+
+cairo_private cairo_bool_t
_cairo_path_fixed_is_single_line (const cairo_path_fixed_t *path);
cairo_private cairo_bool_t
@@ -1323,20 +1358,21 @@ _cairo_surface_set_resolution (cairo_surface_t *surface,
cairo_private cairo_surface_t *
_cairo_surface_create_similar_scratch (cairo_surface_t *other,
- cairo_content_t content,
- int width,
- int height);
+ cairo_content_t content,
+ int width,
+ int height);
+
cairo_private cairo_surface_t *
_cairo_surface_create_for_rectangle_int (cairo_surface_t *target,
const cairo_rectangle_int_t *extents);
cairo_private cairo_surface_t *
-_cairo_surface_create_similar_solid (cairo_surface_t *other,
- cairo_content_t content,
- int width,
- int height,
- const cairo_color_t *color);
+_cairo_surface_create_scratch (cairo_surface_t *other,
+ cairo_content_t content,
+ int width,
+ int height,
+ const cairo_color_t *color);
cairo_private void
_cairo_surface_init (cairo_surface_t *surface,
@@ -1358,7 +1394,7 @@ cairo_private cairo_image_surface_t *
_cairo_surface_map_to_image (cairo_surface_t *surface,
const cairo_rectangle_int_t *extents);
-cairo_private cairo_int_status_t
+cairo_private_no_warn cairo_int_status_t
_cairo_surface_unmap_image (cairo_surface_t *surface,
cairo_image_surface_t *image);
@@ -1454,11 +1490,6 @@ cairo_private_no_warn cairo_bool_t
_cairo_surface_get_extents (cairo_surface_t *surface,
cairo_rectangle_int_t *extents);
-cairo_private void
-_cairo_surface_set_device_scale (cairo_surface_t *surface,
- double sx,
- double sy);
-
cairo_private cairo_bool_t
_cairo_surface_has_device_transform (cairo_surface_t *surface) cairo_pure;
@@ -1651,18 +1682,18 @@ _cairo_polygon_limit_to_clip (cairo_polygon_t *polygon,
cairo_private void
_cairo_polygon_fini (cairo_polygon_t *polygon);
-cairo_private cairo_status_t
+cairo_private_no_warn cairo_status_t
_cairo_polygon_add_line (cairo_polygon_t *polygon,
const cairo_line_t *line,
int top, int bottom,
int dir);
-cairo_private cairo_status_t
+cairo_private_no_warn cairo_status_t
_cairo_polygon_add_external_edge (void *polygon,
const cairo_point_t *p1,
const cairo_point_t *p2);
-cairo_private cairo_status_t
+cairo_private_no_warn cairo_status_t
_cairo_polygon_add_contour (cairo_polygon_t *polygon,
const cairo_contour_t *contour);
@@ -1990,6 +2021,7 @@ slim_hidden_proto (cairo_surface_destroy);
slim_hidden_proto (cairo_surface_finish);
slim_hidden_proto (cairo_surface_flush);
slim_hidden_proto (cairo_surface_get_device_offset);
+slim_hidden_proto (cairo_surface_get_device_scale);
slim_hidden_proto (cairo_surface_get_font_options);
slim_hidden_proto (cairo_surface_get_mime_data);
slim_hidden_proto (cairo_surface_has_show_text_glyphs);
@@ -1997,6 +2029,7 @@ slim_hidden_proto (cairo_surface_mark_dirty);
slim_hidden_proto (cairo_surface_mark_dirty_rectangle);
slim_hidden_proto_no_warn (cairo_surface_reference);
slim_hidden_proto (cairo_surface_set_device_offset);
+slim_hidden_proto (cairo_surface_set_device_scale);
slim_hidden_proto (cairo_surface_set_fallback_resolution);
slim_hidden_proto (cairo_surface_set_mime_data);
slim_hidden_proto (cairo_surface_show_page);
@@ -2055,10 +2088,6 @@ slim_hidden_proto (cairo_surface_write_to_png_stream);
#endif
-cairo_private_no_warn cairo_filter_t
-_cairo_pattern_analyze_filter (const cairo_pattern_t *pattern,
- double *pad_out);
-
CAIRO_END_DECLS
#include "cairo-mutex-private.h"
diff --git a/src/check-def.sh b/src/check-def.sh
index 9008c5871..beefb46a3 100755
--- a/src/check-def.sh
+++ b/src/check-def.sh
@@ -39,7 +39,7 @@ for def in $defs; do
{
echo EXPORTS
- eval $get_cairo_syms | c++filt --no-params | grep -v '^_cairo_test_\|^_fini\|^_init\|^_save[fg]pr\|^_rest[fg]pr\|^_Z\|^__gnu' | sort -u
+ eval $get_cairo_syms | c++filt --no-params | grep -v '^_cairo_test_\|^_fini\|^_init\|^_save[fg]pr\|^_rest[fg]pr\|^_Z\|^__gnu\|^__bss\|^_edata\|^_end' | sort -u
# cheat: copy the last line from the def file!
tail -n1 "$def"
} | diff "$def" - >&2 || stat=1
diff --git a/src/check-doc-syntax.awk b/src/check-doc-syntax.awk
index 5fdabdac9..1fa8b8d22 100755..100644
--- a/src/check-doc-syntax.awk
+++ b/src/check-doc-syntax.awk
@@ -1,5 +1,3 @@
-#!/usr/bin/awk -f
-
BEGIN {
name_found = 1
SECTION_DOC = 0
diff --git a/src/check-doc-syntax.sh b/src/check-doc-syntax.sh
index c74fb875d..762a48429 100755
--- a/src/check-doc-syntax.sh
+++ b/src/check-doc-syntax.sh
@@ -72,7 +72,7 @@ fi >&2
# Only run the syntax checker on the source files (not doc/)
if test -e ./check-doc-syntax.awk; then
- if echo $FILES | xargs ./check-doc-syntax.awk ; then
+ if echo $FILES | xargs awk -f ./check-doc-syntax.awk ; then
:
else
stat=1
diff --git a/src/check-has-hidden-symbols.c b/src/check-has-hidden-symbols.c
index 120412776..120412776 100755..100644
--- a/src/check-has-hidden-symbols.c
+++ b/src/check-has-hidden-symbols.c
diff --git a/src/check-link.c b/src/check-link.c
index 66ca1b241..66ca1b241 100755..100644
--- a/src/check-link.c
+++ b/src/check-link.c
diff --git a/src/check-preprocessor-syntax.sh b/src/check-preprocessor-syntax.sh
index c4154151d..b718f604e 100755
--- a/src/check-preprocessor-syntax.sh
+++ b/src/check-preprocessor-syntax.sh
@@ -9,10 +9,10 @@ stat=0
HEADERS=$all_cairo_headers
-test "x$HEADERS" = x && HEADERS=`find . -name 'cairo*.h' ! -name 'cairo*-private.h' ! -name 'cairoint.h'`
+test "x$HEADERS" = x && HEADERS=`find . -name 'cairo*.h' ! -name 'cairo*-private.h' ! -name 'cairo*-inline.h' ! -name 'cairoint.h'`
PRIVATE=$all_cairo_private
-test "x$PRIVATE" = x && PRIVATE=`find . -name 'cairo*-private.h' -or -name 'cairoint.h'`
+test "x$PRIVATE" = x && PRIVATE=`find . -name 'cairo*-private.h' -or -name 'cairo*-inline.h' -or -name 'cairoint.h'`
SOURCES=$all_cairo_sources
test "x$SOURCES" = x && SOURCES=`find . -name 'cairo*.c' -or -name 'cairo*.cpp'`
diff --git a/src/drm/cairo-drm-bo.c b/src/drm/cairo-drm-bo.c
index a5b59f2c9..a5b59f2c9 100755..100644
--- a/src/drm/cairo-drm-bo.c
+++ b/src/drm/cairo-drm-bo.c
diff --git a/src/drm/cairo-drm-gallium-surface.c b/src/drm/cairo-drm-gallium-surface.c
index 164ab03ce..164ab03ce 100755..100644
--- a/src/drm/cairo-drm-gallium-surface.c
+++ b/src/drm/cairo-drm-gallium-surface.c
diff --git a/src/drm/cairo-drm-i915-glyphs.c b/src/drm/cairo-drm-i915-glyphs.c
index 9944f15a4..9944f15a4 100755..100644
--- a/src/drm/cairo-drm-i915-glyphs.c
+++ b/src/drm/cairo-drm-i915-glyphs.c
diff --git a/src/drm/cairo-drm-i915-private.h b/src/drm/cairo-drm-i915-private.h
index c750cf4cf..c750cf4cf 100755..100644
--- a/src/drm/cairo-drm-i915-private.h
+++ b/src/drm/cairo-drm-i915-private.h
diff --git a/src/drm/cairo-drm-i915-shader.c b/src/drm/cairo-drm-i915-shader.c
index a1911d0a4..85aa98433 100755..100644
--- a/src/drm/cairo-drm-i915-shader.c
+++ b/src/drm/cairo-drm-i915-shader.c
@@ -1467,42 +1467,6 @@ i915_shader_acquire_solid_surface (i915_shader_t *shader,
return CAIRO_STATUS_SUCCESS;
}
-static cairo_filter_t
-sampled_area (const cairo_surface_pattern_t *pattern,
- const cairo_rectangle_int_t *extents,
- cairo_rectangle_int_t *sample)
-{
- cairo_rectangle_int_t surface_extents;
- cairo_filter_t filter;
- double x1, x2, y1, y2;
- double pad;
-
- x1 = extents->x;
- y1 = extents->y;
- x2 = extents->x + (int) extents->width;
- y2 = extents->y + (int) extents->height;
-
- if (_cairo_matrix_is_translation (&pattern->base.matrix)) {
- x1 += pattern->base.matrix.x0; x2 += pattern->base.matrix.x0;
- y1 += pattern->base.matrix.y0; y2 += pattern->base.matrix.y0;
- } else {
- _cairo_matrix_transform_bounding_box (&pattern->base.matrix,
- &x1, &y1, &x2, &y2,
- NULL);
- }
-
- filter = _cairo_pattern_analyze_filter (&pattern->base, &pad);
- sample->x = floor (x1 - pad);
- sample->y = floor (y1 - pad);
- sample->width = ceil (x2 + pad) - sample->x;
- sample->height = ceil (y2 + pad) - sample->y;
-
- if (_cairo_surface_get_extents (pattern->surface, &surface_extents))
- _cairo_rectangle_intersect (sample, &surface_extents);
-
- return filter;
-}
-
static cairo_status_t
i915_shader_acquire_surface (i915_shader_t *shader,
union i915_shader_channel *src,
@@ -1524,7 +1488,8 @@ i915_shader_acquire_surface (i915_shader_t *shader,
extend = pattern->base.extend;
src->base.matrix = pattern->base.matrix;
- filter = sampled_area (pattern, extents, &sample);
+ filter = pattern->base.filter;
+ _cairo_pattern_sampled_area(&pattern->base, extents, sample);
if (surface->type == CAIRO_SURFACE_TYPE_DRM) {
if (surface->backend->type == CAIRO_SURFACE_TYPE_SUBSURFACE) {
diff --git a/src/drm/cairo-drm-i915-spans.c b/src/drm/cairo-drm-i915-spans.c
index b3f4e0afd..b3f4e0afd 100755..100644
--- a/src/drm/cairo-drm-i915-spans.c
+++ b/src/drm/cairo-drm-i915-spans.c
diff --git a/src/drm/cairo-drm-i915-surface.c b/src/drm/cairo-drm-i915-surface.c
index c1a04529f..c1a04529f 100755..100644
--- a/src/drm/cairo-drm-i915-surface.c
+++ b/src/drm/cairo-drm-i915-surface.c
diff --git a/src/drm/cairo-drm-i965-glyphs.c b/src/drm/cairo-drm-i965-glyphs.c
index c66a63d73..c66a63d73 100755..100644
--- a/src/drm/cairo-drm-i965-glyphs.c
+++ b/src/drm/cairo-drm-i965-glyphs.c
diff --git a/src/drm/cairo-drm-i965-private.h b/src/drm/cairo-drm-i965-private.h
index 79568a63d..79568a63d 100755..100644
--- a/src/drm/cairo-drm-i965-private.h
+++ b/src/drm/cairo-drm-i965-private.h
diff --git a/src/drm/cairo-drm-i965-shader.c b/src/drm/cairo-drm-i965-shader.c
index eed5f5f09..eed5f5f09 100755..100644
--- a/src/drm/cairo-drm-i965-shader.c
+++ b/src/drm/cairo-drm-i965-shader.c
diff --git a/src/drm/cairo-drm-i965-spans.c b/src/drm/cairo-drm-i965-spans.c
index 5cba7cec8..5cba7cec8 100755..100644
--- a/src/drm/cairo-drm-i965-spans.c
+++ b/src/drm/cairo-drm-i965-spans.c
diff --git a/src/drm/cairo-drm-i965-surface.c b/src/drm/cairo-drm-i965-surface.c
index ec7b5954c..ec7b5954c 100755..100644
--- a/src/drm/cairo-drm-i965-surface.c
+++ b/src/drm/cairo-drm-i965-surface.c
diff --git a/src/drm/cairo-drm-intel-brw-defines.h b/src/drm/cairo-drm-intel-brw-defines.h
index b2be36f18..b2be36f18 100755..100644
--- a/src/drm/cairo-drm-intel-brw-defines.h
+++ b/src/drm/cairo-drm-intel-brw-defines.h
diff --git a/src/drm/cairo-drm-intel-brw-eu-emit.c b/src/drm/cairo-drm-intel-brw-eu-emit.c
index f27b23804..f27b23804 100755..100644
--- a/src/drm/cairo-drm-intel-brw-eu-emit.c
+++ b/src/drm/cairo-drm-intel-brw-eu-emit.c
diff --git a/src/drm/cairo-drm-intel-brw-eu-util.c b/src/drm/cairo-drm-intel-brw-eu-util.c
index 592235b12..592235b12 100755..100644
--- a/src/drm/cairo-drm-intel-brw-eu-util.c
+++ b/src/drm/cairo-drm-intel-brw-eu-util.c
diff --git a/src/drm/cairo-drm-intel-brw-eu.c b/src/drm/cairo-drm-intel-brw-eu.c
index 2b47d8c37..2b47d8c37 100755..100644
--- a/src/drm/cairo-drm-intel-brw-eu.c
+++ b/src/drm/cairo-drm-intel-brw-eu.c
diff --git a/src/drm/cairo-drm-intel-brw-eu.h b/src/drm/cairo-drm-intel-brw-eu.h
index 2662a2e7f..2662a2e7f 100755..100644
--- a/src/drm/cairo-drm-intel-brw-eu.h
+++ b/src/drm/cairo-drm-intel-brw-eu.h
diff --git a/src/drm/cairo-drm-intel-brw-structs.h b/src/drm/cairo-drm-intel-brw-structs.h
index f42483ed1..f42483ed1 100755..100644
--- a/src/drm/cairo-drm-intel-brw-structs.h
+++ b/src/drm/cairo-drm-intel-brw-structs.h
diff --git a/src/drm/cairo-drm-intel-command-private.h b/src/drm/cairo-drm-intel-command-private.h
index a93ac12ab..a93ac12ab 100755..100644
--- a/src/drm/cairo-drm-intel-command-private.h
+++ b/src/drm/cairo-drm-intel-command-private.h
diff --git a/src/drm/cairo-drm-intel-debug.c b/src/drm/cairo-drm-intel-debug.c
index 7068c933e..7068c933e 100755..100644
--- a/src/drm/cairo-drm-intel-debug.c
+++ b/src/drm/cairo-drm-intel-debug.c
diff --git a/src/drm/cairo-drm-intel-ioctl-private.h b/src/drm/cairo-drm-intel-ioctl-private.h
index 004d3bfd7..004d3bfd7 100755..100644
--- a/src/drm/cairo-drm-intel-ioctl-private.h
+++ b/src/drm/cairo-drm-intel-ioctl-private.h
diff --git a/src/drm/cairo-drm-intel-private.h b/src/drm/cairo-drm-intel-private.h
index 343270a3c..343270a3c 100755..100644
--- a/src/drm/cairo-drm-intel-private.h
+++ b/src/drm/cairo-drm-intel-private.h
diff --git a/src/drm/cairo-drm-intel-surface.c b/src/drm/cairo-drm-intel-surface.c
index 88f5b8f0c..88f5b8f0c 100755..100644
--- a/src/drm/cairo-drm-intel-surface.c
+++ b/src/drm/cairo-drm-intel-surface.c
diff --git a/src/drm/cairo-drm-intel.c b/src/drm/cairo-drm-intel.c
index d45155ebe..d45155ebe 100755..100644
--- a/src/drm/cairo-drm-intel.c
+++ b/src/drm/cairo-drm-intel.c
diff --git a/src/drm/cairo-drm-ioctl-private.h b/src/drm/cairo-drm-ioctl-private.h
index 4294de2d5..4294de2d5 100755..100644
--- a/src/drm/cairo-drm-ioctl-private.h
+++ b/src/drm/cairo-drm-ioctl-private.h
diff --git a/src/drm/cairo-drm-private.h b/src/drm/cairo-drm-private.h
index 2db7f38d6..2db7f38d6 100755..100644
--- a/src/drm/cairo-drm-private.h
+++ b/src/drm/cairo-drm-private.h
diff --git a/src/drm/cairo-drm-radeon-private.h b/src/drm/cairo-drm-radeon-private.h
index 546126c6f..546126c6f 100755..100644
--- a/src/drm/cairo-drm-radeon-private.h
+++ b/src/drm/cairo-drm-radeon-private.h
diff --git a/src/drm/cairo-drm-radeon-surface.c b/src/drm/cairo-drm-radeon-surface.c
index 6dbddaae4..6dbddaae4 100755..100644
--- a/src/drm/cairo-drm-radeon-surface.c
+++ b/src/drm/cairo-drm-radeon-surface.c
diff --git a/src/drm/cairo-drm-radeon.c b/src/drm/cairo-drm-radeon.c
index a6d22089b..a6d22089b 100755..100644
--- a/src/drm/cairo-drm-radeon.c
+++ b/src/drm/cairo-drm-radeon.c
diff --git a/src/drm/cairo-drm-surface.c b/src/drm/cairo-drm-surface.c
index 8c4dd0ee8..8c4dd0ee8 100755..100644
--- a/src/drm/cairo-drm-surface.c
+++ b/src/drm/cairo-drm-surface.c
diff --git a/src/drm/cairo-drm.c b/src/drm/cairo-drm.c
index 051b79e4f..661e181b6 100755..100644
--- a/src/drm/cairo-drm.c
+++ b/src/drm/cairo-drm.c
@@ -202,8 +202,7 @@ cairo_drm_device_get (struct udev_device *device)
parent = udev_device_get_parent (device);
pci_id = get_udev_property (parent, "PCI_ID");
if (pci_id == NULL || sscanf (pci_id, "%x:%x", &vendor_id, &chip_id) != 2) {
- dev = (cairo_drm_device_t *)
- _cairo_device_create_in_error (CAIRO_STATUS_DEVICE_ERROR);
+ dev = NULL;
goto DONE;
}
@@ -239,6 +238,7 @@ cairo_drm_device_get (struct udev_device *device)
if (fd == -1) {
/* XXX more likely to be a permissions issue... */
_cairo_error_throw (CAIRO_STATUS_FILE_NOT_FOUND);
+ dev = NULL;
goto DONE;
}
@@ -249,7 +249,10 @@ cairo_drm_device_get (struct udev_device *device)
DONE:
CAIRO_MUTEX_UNLOCK (_cairo_drm_device_mutex);
- return &dev->base;
+ if (dev == NULL)
+ return _cairo_device_create_in_error (CAIRO_STATUS_DEVICE_ERROR);
+ else
+ return &dev->base;
}
slim_hidden_def (cairo_drm_device_get);
diff --git a/src/skia/cairo-skia-context.cpp b/src/skia/cairo-skia-context.cpp
index bbe5507f6..9ffb8f6a2 100755..100644
--- a/src/skia/cairo-skia-context.cpp
+++ b/src/skia/cairo-skia-context.cpp
@@ -53,6 +53,7 @@
#include "cairo-skia-private.h"
#include "cairo-surface-backend-private.h"
+#include <SkPaint.h>
#include <SkShader.h>
#include <SkColorShader.h>
#include <SkGradientShader.h>
@@ -236,16 +237,19 @@ surface_to_sk_bitmap (cairo_surface_t *surface, SkBitmap& bitmap)
{
cairo_image_surface_t *img = (cairo_image_surface_t *) surface;
SkBitmap::Config config;
+ SkColorType colorType;
bool opaque;
if (unlikely (! format_to_sk_config (img->format, config, opaque)))
return false;
bitmap.reset ();
- bitmap.setConfig (config, img->width, img->height, img->stride);
- bitmap.setIsOpaque (opaque);
+ bitmap.setAlphaType (opaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType);
+ colorType = SkBitmapConfigToColorType(config);
+ bitmap.setInfo (SkImageInfo::Make(img->width, img->height, colorType, kPremul_SkAlphaType), img->stride);
bitmap.setPixels (img->data);
+
return true;
}
@@ -330,9 +334,18 @@ source_to_sk_shader (cairo_skia_context_t *cr,
if (surface->type == CAIRO_SURFACE_TYPE_SKIA) {
cairo_skia_surface_t *esurf = (cairo_skia_surface_t *) surface;
- shader = SkShader::CreateBitmapShader (*esurf->bitmap,
- extend_to_sk (pattern->extend),
- extend_to_sk (pattern->extend));
+ if (! _cairo_matrix_is_identity (&pattern->matrix))
+ {
+ SkMatrix localMatrix = matrix_inverse_to_sk (pattern->matrix);
+ shader = SkShader::CreateBitmapShader (*esurf->bitmap,
+ extend_to_sk (pattern->extend),
+ extend_to_sk (pattern->extend),
+ &localMatrix);
+ } else {
+ shader = SkShader::CreateBitmapShader (*esurf->bitmap,
+ extend_to_sk (pattern->extend),
+ extend_to_sk (pattern->extend));
+ }
} else {
SkBitmap bitmap;
@@ -351,9 +364,18 @@ source_to_sk_shader (cairo_skia_context_t *cr,
if (unlikely (! surface_to_sk_bitmap (surface, bitmap)))
return NULL;
- shader = SkShader::CreateBitmapShader (bitmap,
- extend_to_sk (pattern->extend),
- extend_to_sk (pattern->extend));
+ if (! _cairo_matrix_is_identity (&pattern->matrix))
+ {
+ SkMatrix localMatrix = matrix_inverse_to_sk (pattern->matrix);
+ shader = SkShader::CreateBitmapShader (bitmap,
+ extend_to_sk (pattern->extend),
+ extend_to_sk (pattern->extend),
+ &localMatrix);
+ } else {
+ shader = SkShader::CreateBitmapShader (bitmap,
+ extend_to_sk (pattern->extend),
+ extend_to_sk (pattern->extend));
+ }
}
} else if (pattern->type == CAIRO_PATTERN_TYPE_LINEAR
/* || pattern->type == CAIRO_PATTERN_TYPE_RADIAL */)
@@ -382,8 +404,17 @@ source_to_sk_shader (cairo_skia_context_t *cr,
SkFloatToScalar (linear->pd1.y));
points[1].set (SkFloatToScalar (linear->pd2.x),
SkFloatToScalar (linear->pd2.y));
- shader = SkGradientShader::CreateLinear (points, colors, pos, gradient->n_stops,
- extend_to_sk (pattern->extend));
+
+ if(! _cairo_matrix_is_identity (&pattern->matrix))
+ {
+ SkMatrix localMatrix = matrix_inverse_to_sk (pattern->matrix);
+ shader = SkGradientShader::CreateLinear (points, colors, pos, gradient->n_stops,
+ extend_to_sk (pattern->extend),
+ 0, &localMatrix);
+ } else {
+ shader = SkGradientShader::CreateLinear (points, colors, pos, gradient->n_stops,
+ extend_to_sk (pattern->extend));
+ }
} else {
// XXX todo -- implement real radial shaders in Skia
}
@@ -394,9 +425,6 @@ source_to_sk_shader (cairo_skia_context_t *cr,
}
}
- if (shader && ! _cairo_matrix_is_identity (&pattern->matrix))
- shader->setLocalMatrix (matrix_inverse_to_sk (pattern->matrix));
-
return shader;
}
@@ -446,6 +474,7 @@ _cairo_skia_context_set_source (void *abstract_cr,
cr->paint->setColor (color);
} else {
SkShader *shader = source_to_sk_shader (cr, source);
+ bool fLevel = pattern_filter_to_sk (source);
if (shader == NULL) {
UNSUPPORTED;
return CAIRO_STATUS_SUCCESS;
@@ -454,7 +483,8 @@ _cairo_skia_context_set_source (void *abstract_cr,
cr->paint->setShader (shader);
shader->unref ();
- cr->paint->setFilterBitmap (pattern_filter_to_sk (source));
+ cr->paint->setFilterLevel (fLevel ?
+ (SkPaint::kLow_FilterLevel) : (SkPaint::kNone_FilterLevel));
}
/* XXX change notification */
@@ -496,7 +526,8 @@ _cairo_skia_context_set_source_surface (void *abstract_cr,
cr->paint->setShader (shader);
shader->unref ();
- cr->paint->setFilterBitmap (true);
+ cr->paint->setFilterLevel (true ?
+ (SkPaint::kLow_FilterLevel) : (SkPaint::kNone_FilterLevel));
return CAIRO_STATUS_SUCCESS;
}
@@ -682,7 +713,7 @@ _cairo_skia_context_set_dash (void *abstract_cr,
intervals[i++] = SkFloatToScalar (dashes[j]);
} while (loop--);
- SkDashPathEffect *dash = new SkDashPathEffect (intervals, num_dashes, SkFloatToScalar (offset));
+ SkDashPathEffect *dash = SkDashPathEffect::Create (intervals, num_dashes, SkFloatToScalar (offset));
cr->paint->setPathEffect (dash);
dash->unref ();
@@ -1264,7 +1295,7 @@ _cairo_skia_context_paint_with_alpha (void *abstract_cr,
if (CAIRO_ALPHA_IS_OPAQUE (alpha))
return _cairo_skia_context_paint (cr);
- cr->paint->setAlpha(SkScalarRound(255*alpha));
+ cr->paint->setAlpha(SkScalarRoundToInt(255*alpha));
status = _cairo_skia_context_paint (cr);
cr->paint->setAlpha(255);
diff --git a/src/skia/cairo-skia-private.h b/src/skia/cairo-skia-private.h
index cbd8c888d..f538b486b 100755..100644
--- a/src/skia/cairo-skia-private.h
+++ b/src/skia/cairo-skia-private.h
@@ -44,7 +44,26 @@
#include <SkPaint.h>
#include <SkPath.h>
+/**
+ * cairo_skia_context_t:
+ *
+ * A #cairo_skia_context_t includes handles to Skia's canvas,
+ * paint, and path objects along with the Cairo source surfaces
+ * and matrix, and the original and target #cairo_skia_surface_t
+ * objects.
+ *
+ * Since: 1.10
+ **/
typedef struct _cairo_skia_context cairo_skia_context_t;
+
+/**
+ * cairo_skia_surface_t:
+ *
+ * A #cairo_skia_surface_t is a container for the underlying
+ * #SkBitmap and the corresponding Cairo image surface.
+ *
+ * Since: 1.10
+ **/
typedef struct _cairo_skia_surface cairo_skia_surface_t;
struct _cairo_skia_context {
@@ -92,11 +111,9 @@ format_to_sk_config (cairo_format_t format,
case CAIRO_FORMAT_A8:
config = SkBitmap::kA8_Config;
break;
- case CAIRO_FORMAT_A1:
- config = SkBitmap::kA1_Config;
- break;
case CAIRO_FORMAT_RGB30:
case CAIRO_FORMAT_INVALID:
+ case CAIRO_FORMAT_A1:
default:
return false;
}
diff --git a/src/skia/cairo-skia-surface.cpp b/src/skia/cairo-skia-surface.cpp
index bb785e192..834a2f13b 100755..100644
--- a/src/skia/cairo-skia-surface.cpp
+++ b/src/skia/cairo-skia-surface.cpp
@@ -64,7 +64,7 @@ _cairo_skia_surface_create_similar (void *asurface,
if (content == surface->image.base.content)
{
- config = surface->bitmap->getConfig ();
+ config = surface->bitmap->config ();
opaque = surface->bitmap->isOpaque ();
}
else if (! format_to_sk_config (_cairo_format_from_content (content),
@@ -207,9 +207,6 @@ sk_config_to_pixman_format_code (SkBitmap::Config config,
case SkBitmap::kA8_Config:
return PIXMAN_a8;
-
- case SkBitmap::kA1_Config:
- return PIXMAN_a1;
case SkBitmap::kRGB_565_Config:
return PIXMAN_r5g6b5;
case SkBitmap::kARGB_4444_Config:
@@ -217,8 +214,6 @@ sk_config_to_pixman_format_code (SkBitmap::Config config,
case SkBitmap::kNo_Config:
case SkBitmap::kIndex8_Config:
- case SkBitmap::kRLE_Index8_Config:
- case SkBitmap::kConfigCount:
default:
ASSERT_NOT_REACHED;
return (pixman_format_code_t) -1;
@@ -236,6 +231,7 @@ _cairo_skia_surface_create_internal (SkBitmap::Config config,
cairo_skia_surface_t *surface;
pixman_image_t *pixman_image;
pixman_format_code_t pixman_format;
+ SkColorType colorType;
surface = (cairo_skia_surface_t *) malloc (sizeof (cairo_skia_surface_t));
if (unlikely (surface == NULL))
@@ -245,8 +241,10 @@ _cairo_skia_surface_create_internal (SkBitmap::Config config,
pixman_image = pixman_image_create_bits (pixman_format,
width, height,
(uint32_t *) data, stride);
- if (unlikely (pixman_image == NULL))
+ if (unlikely (pixman_image == NULL)) {
+ free (surface);
return (cairo_skia_surface_t *) _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
+ }
_cairo_surface_init (&surface->image.base,
&cairo_skia_surface_backend,
@@ -256,8 +254,9 @@ _cairo_skia_surface_create_internal (SkBitmap::Config config,
_cairo_image_surface_init (&surface->image, pixman_image, pixman_format);
surface->bitmap = new SkBitmap;
- surface->bitmap->setConfig (config, width, height, surface->image.stride);
- surface->bitmap->setIsOpaque (opaque);
+ colorType = SkBitmapConfigToColorType(config);
+ surface->bitmap->setAlphaType (opaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType);
+ surface->bitmap->setInfo (SkImageInfo::Make(width, height, colorType, kPremul_SkAlphaType), surface->image.stride);
surface->bitmap->setPixels (surface->image.data);
surface->image.base.is_clear = data == NULL;
diff --git a/src/test-base-compositor-surface.c b/src/test-base-compositor-surface.c
index ff84b10af..ff84b10af 100755..100644
--- a/src/test-base-compositor-surface.c
+++ b/src/test-base-compositor-surface.c
diff --git a/src/test-compositor-surface-private.h b/src/test-compositor-surface-private.h
index 491f241ba..491f241ba 100755..100644
--- a/src/test-compositor-surface-private.h
+++ b/src/test-compositor-surface-private.h
diff --git a/src/test-compositor-surface.c b/src/test-compositor-surface.c
index ddee06f3e..1cc5f6921 100755..100644
--- a/src/test-compositor-surface.c
+++ b/src/test-compositor-surface.c
@@ -145,6 +145,8 @@ test_compositor_surface_stroke (void *_surface,
const cairo_clip_t *clip)
{
test_compositor_surface_t *surface = _surface;
+ if (antialias == CAIRO_ANTIALIAS_DEFAULT)
+ antialias = CAIRO_ANTIALIAS_BEST;
return _cairo_compositor_stroke (surface->base.compositor,
_surface, op, source,
path, style, ctm, ctm_inverse,
@@ -163,6 +165,8 @@ test_compositor_surface_fill (void *_surface,
const cairo_clip_t *clip)
{
test_compositor_surface_t *surface = _surface;
+ if (antialias == CAIRO_ANTIALIAS_DEFAULT)
+ antialias = CAIRO_ANTIALIAS_BEST;
return _cairo_compositor_fill (surface->base.compositor,
_surface, op, source,
path, fill_rule, tolerance, antialias,
diff --git a/src/test-compositor-surface.h b/src/test-compositor-surface.h
index 8d8af2d54..8d8af2d54 100755..100644
--- a/src/test-compositor-surface.h
+++ b/src/test-compositor-surface.h
diff --git a/src/test-null-compositor-surface.c b/src/test-null-compositor-surface.c
index 4fdaac4a3..395a5f4a6 100755..100644
--- a/src/test-null-compositor-surface.c
+++ b/src/test-null-compositor-surface.c
@@ -419,7 +419,7 @@ no_traps_compositor_get (void)
compositor.check_composite = check_composite;
compositor.composite = composite;
compositor.lerp = lerp;
- //FIXME:
+ // FIXME:
compositor.lerp_color_glyph = lerp;
//compositor.check_composite_boxes = check_composite_boxes;
compositor.composite_boxes = composite_boxes;
diff --git a/src/test-null-compositor-surface.h b/src/test-null-compositor-surface.h
index 52d864b28..52d864b28 100755..100644
--- a/src/test-null-compositor-surface.h
+++ b/src/test-null-compositor-surface.h
diff --git a/src/test-paginated-surface.c b/src/test-paginated-surface.c
index 0a7c79b37..0a7c79b37 100755..100644
--- a/src/test-paginated-surface.c
+++ b/src/test-paginated-surface.c
diff --git a/src/test-paginated-surface.h b/src/test-paginated-surface.h
index 2bd98aa5e..2bd98aa5e 100755..100644
--- a/src/test-paginated-surface.h
+++ b/src/test-paginated-surface.h
diff --git a/src/win32/cairo-win32-debug.c b/src/win32/cairo-win32-debug.c
index ff7aeaf1f..ff7aeaf1f 100755..100644
--- a/src/win32/cairo-win32-debug.c
+++ b/src/win32/cairo-win32-debug.c
diff --git a/src/win32/cairo-win32-device.c b/src/win32/cairo-win32-device.c
index 741e49e33..741e49e33 100755..100644
--- a/src/win32/cairo-win32-device.c
+++ b/src/win32/cairo-win32-device.c
diff --git a/src/win32/cairo-win32-display-surface.c b/src/win32/cairo-win32-display-surface.c
index ccd285d7d..965f2c45d 100755..100644
--- a/src/win32/cairo-win32-display-surface.c
+++ b/src/win32/cairo-win32-display-surface.c
@@ -415,7 +415,8 @@ _cairo_win32_display_surface_finish (void *abstract_surface)
{
cairo_win32_display_surface_t *surface = abstract_surface;
- if (surface->image) {
+ if (surface->image && to_image_surface(surface->image)->parent) {
+ assert (to_image_surface(surface->image)->parent == &surface->win32.base);
/* Unhook ourselves first to avoid the double-unref from the image */
to_image_surface(surface->image)->parent = NULL;
cairo_surface_finish (surface->image);
@@ -429,6 +430,8 @@ _cairo_win32_display_surface_finish (void *abstract_surface)
DeleteDC (surface->win32.dc);
}
+ _cairo_win32_display_surface_discard_fallback (surface);
+
if (surface->initial_clip_rgn)
DeleteObject (surface->initial_clip_rgn);
@@ -452,17 +455,17 @@ _cairo_win32_display_surface_map_to_image (void *abstract_sur
surface->fallback =
_cairo_win32_display_surface_create_for_dc (surface->win32.dc,
surface->win32.format,
- surface->win32.extents.width,
- surface->win32.extents.height);
+ surface->win32.extents.x + surface->win32.extents.width,
+ surface->win32.extents.y + surface->win32.extents.height);
if (unlikely (status = surface->fallback->status))
goto err;
if (!BitBlt (to_win32_surface(surface->fallback)->dc,
- 0, 0,
+ surface->win32.extents.x, surface->win32.extents.y,
surface->win32.extents.width,
surface->win32.extents.height,
surface->win32.dc,
- 0, 0,
+ surface->win32.extents.x, surface->win32.extents.y,
SRCCOPY)) {
status = _cairo_error (CAIRO_STATUS_DEVICE_ERROR);
goto err;
@@ -758,6 +761,7 @@ _cairo_win32_display_surface_discard_fallback (cairo_win32_display_surface_t *su
TRACE ((stderr, "%s (surface=%d)\n",
__FUNCTION__, surface->win32.base.unique_id));
+ cairo_surface_finish (surface->fallback);
cairo_surface_destroy (surface->fallback);
surface->fallback = NULL;
}
diff --git a/src/win32/cairo-win32-font.c b/src/win32/cairo-win32-font.c
index a65d81b1a..1599b0751 100755..100644
--- a/src/win32/cairo-win32-font.c
+++ b/src/win32/cairo-win32-font.c
@@ -157,10 +157,6 @@ static cairo_status_t
_cairo_win32_scaled_font_init_glyph_path (cairo_win32_scaled_font_t *scaled_font,
cairo_scaled_glyph_t *scaled_glyph);
-static void
-_cairo_win32_font_face_destroy (void *abstract_face);
-
-
#define NEARLY_ZERO(d) (fabs(d) < (1. / 65536.))
static HDC
@@ -1847,49 +1843,6 @@ struct _cairo_win32_font_face {
HFONT hfont;
};
-/* implement the platform-specific interface */
-
-static cairo_bool_t
-_is_scale (const cairo_matrix_t *matrix, double scale)
-{
- return matrix->xx == scale && matrix->yy == scale &&
- matrix->xy == 0. && matrix->yx == 0. &&
- matrix->x0 == 0. && matrix->y0 == 0.;
-}
-
-static cairo_status_t
-_cairo_win32_font_face_scaled_font_create (void *abstract_face,
- const cairo_matrix_t *font_matrix,
- const cairo_matrix_t *ctm,
- const cairo_font_options_t *options,
- cairo_scaled_font_t **font)
-{
- HFONT hfont = NULL;
-
- cairo_win32_font_face_t *font_face = abstract_face;
-
- if (font_face->hfont) {
- /* Check whether it's OK to go ahead and use the font-face's HFONT. */
- if (_is_scale (ctm, 1.) &&
- _is_scale (font_matrix, -font_face->logfont.lfHeight)) {
- hfont = font_face->hfont;
- }
- }
-
- return _win32_scaled_font_create (&font_face->logfont,
- hfont,
- &font_face->base,
- font_matrix, ctm, options,
- font);
-}
-
-const cairo_font_face_backend_t _cairo_win32_font_face_backend = {
- CAIRO_FONT_TYPE_WIN32,
- _cairo_win32_font_face_create_for_toy,
- _cairo_win32_font_face_destroy,
- _cairo_win32_font_face_scaled_font_create
-};
-
/* We maintain a hash table from LOGFONT,HFONT => #cairo_font_face_t.
* The primary purpose of this mapping is to provide unique
* #cairo_font_face_t values so that our cache and mapping from
@@ -1950,7 +1903,7 @@ _cairo_win32_font_face_hash_table_unlock (void)
CAIRO_MUTEX_UNLOCK (_cairo_win32_font_face_mutex);
}
-static void
+static cairo_bool_t
_cairo_win32_font_face_destroy (void *abstract_face)
{
cairo_win32_font_face_t *font_face = abstract_face;
@@ -1960,10 +1913,10 @@ _cairo_win32_font_face_destroy (void *abstract_face)
/* All created objects must have been mapped in the hash table. */
assert (hash_table != NULL);
- if (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&font_face->base.ref_count)) {
+ if (! _cairo_reference_count_dec_and_test (&font_face->base.ref_count)) {
/* somebody recreated the font whilst we waited for the lock */
_cairo_win32_font_face_hash_table_unlock ();
- return;
+ return FALSE;
}
/* Font faces in SUCCESS status are guaranteed to be in the
@@ -1975,6 +1928,7 @@ _cairo_win32_font_face_destroy (void *abstract_face)
_cairo_hash_table_remove (hash_table, &font_face->base.hash_entry);
_cairo_win32_font_face_hash_table_unlock ();
+ return TRUE;
}
static void
@@ -2015,6 +1969,49 @@ _cairo_win32_font_face_keys_equal (const void *key_a,
return FALSE;
}
+/* implement the platform-specific interface */
+
+static cairo_bool_t
+_is_scale (const cairo_matrix_t *matrix, double scale)
+{
+ return matrix->xx == scale && matrix->yy == scale &&
+ matrix->xy == 0. && matrix->yx == 0. &&
+ matrix->x0 == 0. && matrix->y0 == 0.;
+}
+
+static cairo_status_t
+_cairo_win32_font_face_scaled_font_create (void *abstract_face,
+ const cairo_matrix_t *font_matrix,
+ const cairo_matrix_t *ctm,
+ const cairo_font_options_t *options,
+ cairo_scaled_font_t **font)
+{
+ HFONT hfont = NULL;
+
+ cairo_win32_font_face_t *font_face = abstract_face;
+
+ if (font_face->hfont) {
+ /* Check whether it's OK to go ahead and use the font-face's HFONT. */
+ if (_is_scale (ctm, 1.) &&
+ _is_scale (font_matrix, -font_face->logfont.lfHeight)) {
+ hfont = font_face->hfont;
+ }
+ }
+
+ return _win32_scaled_font_create (&font_face->logfont,
+ hfont,
+ &font_face->base,
+ font_matrix, ctm, options,
+ font);
+}
+
+const cairo_font_face_backend_t _cairo_win32_font_face_backend = {
+ CAIRO_FONT_TYPE_WIN32,
+ _cairo_win32_font_face_create_for_toy,
+ _cairo_win32_font_face_destroy,
+ _cairo_win32_font_face_scaled_font_create
+};
+
/**
* cairo_win32_font_face_create_for_logfontw_hfont:
* @logfont: A #LOGFONTW structure specifying the font to use.
diff --git a/src/win32/cairo-win32-gdi-compositor.c b/src/win32/cairo-win32-gdi-compositor.c
index c70b0f90a..073e889ab 100755..100644
--- a/src/win32/cairo-win32-gdi-compositor.c
+++ b/src/win32/cairo-win32-gdi-compositor.c
@@ -151,10 +151,11 @@ static cairo_bool_t upload_box (cairo_box_t *box, void *closure)
int y = _cairo_fixed_integer_part (box->p1.y);
int width = _cairo_fixed_integer_part (box->p2.x - box->p1.x);
int height = _cairo_fixed_integer_part (box->p2.y - box->p1.y);
+ int src_height = -cb->bi.bmiHeader.biHeight;
TRACE ((stderr, "%s\n", __FUNCTION__));
return StretchDIBits (cb->dst, x, y + height - 1, width, -height,
- x + cb->tx, height - (y + cb->ty - 1),
+ x + cb->tx, src_height - (y + cb->ty - 1),
width, -height,
cb->data, &cb->bi,
DIB_RGB_COLORS, SRCCOPY);
diff --git a/src/win32/cairo-win32-printing-surface.c b/src/win32/cairo-win32-printing-surface.c
index be91445cf..6005cb53d 100755..100644
--- a/src/win32/cairo-win32-printing-surface.c
+++ b/src/win32/cairo-win32-printing-surface.c
@@ -726,6 +726,7 @@ _cairo_win32_printing_surface_paint_image_pattern (cairo_win32_printing_surface_
/* _cairo_pattern_set_matrix guarantees invertibility */
assert (status == CAIRO_STATUS_SUCCESS);
+ cairo_matrix_multiply (&m, &m, &surface->ctm);
cairo_matrix_multiply (&m, &m, &surface->gdi_ctm);
SaveDC (surface->win32.dc);
_cairo_matrix_to_win32_xform (&m, &xform);
@@ -1578,14 +1579,18 @@ _cairo_win32_printing_surface_show_glyphs (void *abstract_surfac
* CAIRO_INT_STATUS_UNSUPPORTED and a fallback image will be
* used.
*/
+ _cairo_scaled_font_freeze_cache (scaled_font);
for (i = 0; i < num_glyphs; i++) {
status = _cairo_scaled_glyph_lookup (scaled_font,
glyphs[i].index,
CAIRO_SCALED_GLYPH_INFO_PATH,
&scaled_glyph);
if (status)
- return status;
+ break;
}
+ _cairo_scaled_font_thaw_cache (scaled_font);
+ if (status)
+ return status;
return _cairo_win32_printing_surface_analyze_operation (surface, op, source);
}
@@ -1623,6 +1628,7 @@ _cairo_win32_printing_surface_show_glyphs (void *abstract_surfac
old_has_ctm = surface->has_ctm;
surface->has_ctm = TRUE;
surface->path_empty = TRUE;
+ _cairo_scaled_font_freeze_cache (scaled_font);
BeginPath (surface->win32.dc);
for (i = 0; i < num_glyphs; i++) {
status = _cairo_scaled_glyph_lookup (scaled_font,
@@ -1636,6 +1642,7 @@ _cairo_win32_printing_surface_show_glyphs (void *abstract_surfac
status = _cairo_win32_printing_surface_emit_path (surface, scaled_glyph->path);
}
EndPath (surface->win32.dc);
+ _cairo_scaled_font_thaw_cache (scaled_font);
surface->ctm = old_ctm;
surface->has_ctm = old_has_ctm;
if (status == CAIRO_STATUS_SUCCESS && surface->path_empty == FALSE) {
diff --git a/src/win32/cairo-win32-private.h b/src/win32/cairo-win32-private.h
index b6c24311a..b6c24311a 100755..100644
--- a/src/win32/cairo-win32-private.h
+++ b/src/win32/cairo-win32-private.h
diff --git a/src/win32/cairo-win32-surface.c b/src/win32/cairo-win32-surface.c
index 7cd46fc60..e6862bd10 100755..100644
--- a/src/win32/cairo-win32-surface.c
+++ b/src/win32/cairo-win32-surface.c
@@ -172,6 +172,21 @@ cairo_win32_surface_get_dc (cairo_surface_t *surface)
}
/**
+ * _cairo_surface_is_win32:
+ * @surface: a #cairo_surface_t
+ *
+ * Checks if a surface is an #cairo_win32_surface_t
+ *
+ * Return value: %TRUE if the surface is an win32 surface
+ **/
+static inline cairo_bool_t
+_cairo_surface_is_win32 (const cairo_surface_t *surface)
+{
+ /* _cairo_surface_nil sets a NULL backend so be safe */
+ return surface->backend && surface->backend->type == CAIRO_SURFACE_TYPE_WIN32;
+}
+
+/**
* cairo_win32_surface_get_image:
* @surface: a #cairo_surface_t
*
@@ -187,8 +202,10 @@ cairo_win32_surface_get_dc (cairo_surface_t *surface)
cairo_surface_t *
cairo_win32_surface_get_image (cairo_surface_t *surface)
{
- if (surface->backend->type != CAIRO_SURFACE_TYPE_WIN32)
- return NULL;
+
+ if (! _cairo_surface_is_win32 (surface)) {
+ return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH));
+ }
GdiFlush();
return to_win32_display_surface(surface)->image;
diff --git a/src/win32/cairo-win32-system.c b/src/win32/cairo-win32-system.c
index 878553009..878553009 100755..100644
--- a/src/win32/cairo-win32-system.c
+++ b/src/win32/cairo-win32-system.c
diff --git a/test/.gitignore b/test/.gitignore
new file mode 100644
index 000000000..bc78ef3ec
--- /dev/null
+++ b/test/.gitignore
@@ -0,0 +1,37 @@
+TAGS
+tags
+.deps
+.libs
+output
+Makefile
+Makefile.in
+ref.hash
+ref.list
+any2ppm
+.any2ppm
+.any2ppm.pid
+.any2ppm.errors
+cairo-test-constructors.c
+cairo-test-trace
+cairo-test-suite
+pdf2png
+ps2png
+svg2png
+callgrind.out.*
+valgrind-log
+*.manifest
+*.gcda
+*.gcno
+*.exe
+*.exe.so
+*.obj
+*.ilk
+*.pdb
+*.la
+*.lo
+*.log
+*.suo
+*.o
+*~
+.*.sw?
+make-cairo-test-constructors
diff --git a/test/.valgrind-suppressions b/test/.valgrind-suppressions
new file mode 100644
index 000000000..f481a2f00
--- /dev/null
+++ b/test/.valgrind-suppressions
@@ -0,0 +1,577 @@
+{
+ in dl.so
+ Memcheck:Cond
+ fun:_dl_relocate_object
+ }
+{
+ bugs in libpng/libz
+ Memcheck:Cond
+ obj:/usr/lib/libz.so.1.2.2.2
+ obj:/usr/lib/libz.so.1.2.2.2
+ fun:deflate
+ }
+{
+ bugs in libpng/libz
+ Memcheck:Cond
+ obj:/usr/lib/libz.so.1.2.3
+ obj:/usr/lib/libz.so.1.2.3
+ fun:deflate
+ }
+{
+ bugs in libpng/libz
+ Memcheck:Cond
+ obj:/usr/lib/libz.so.1.2.3.3
+ }
+{
+ bugs in libpng/libz
+ Memcheck:Value8
+ obj:/usr/lib/libz.so.1.2.3.3
+ }
+{
+ cairo's write_png triggers apparent bugs in libpng/libz
+ Memcheck:Cond
+ obj:/usr/lib/libz.so.1.2.2.2
+ obj:/usr/lib/libz.so.1.2.2.2
+ fun:deflate
+ fun:png_write_finish_row
+ fun:png_write_filtered_row
+ fun:png_write_find_filter
+ fun:png_write_row
+ fun:png_write_image
+ fun:write_png
+ }
+{
+ cairo's write_png_argb32 triggers apparent bugs in libpng/libz
+ Memcheck:Cond
+ obj:/usr/lib/libz.so.1.2.3
+ obj:/usr/lib/libz.so.1.2.3
+ fun:deflate
+ obj:/usr/lib/libpng12.so.0.1.2.8
+ obj:/usr/lib/libpng12.so.0.1.2.8
+ obj:/usr/lib/libpng12.so.0.1.2.8
+ fun:png_write_row
+ fun:png_write_image
+ fun:write_png
+}
+{
+ cairo's write_png_argb32 triggers apparent bugs in libpng/libz
+ Memcheck:Cond
+ obj:/usr/lib/libz.so.1.2.2.2
+ obj:/usr/lib/libz.so.1.2.2.2
+ fun:deflate
+ fun:png_write_finish_row
+ fun:png_write_filtered_row
+ fun:png_write_find_filter
+ fun:png_write_row
+ fun:png_write_image
+ fun:write_png_argb32
+ }
+{
+ cairo's _cairo_pdf_surface_paint triggers apparent bugs in libz
+ Memcheck:Cond
+ obj:/usr/lib/libz.so.1.2.3
+ obj:/usr/lib/libz.so.1.2.3
+ fun:deflate
+ fun:compress2
+ fun:compress
+ fun:compress_dup
+ fun:emit_image
+ fun:emit_surface_pattern
+ fun:emit_pattern
+ fun:_cairo_pdf_surface_paint
+}
+{
+ cairo's _cairo_pdf_surface_paint triggers apparent bugs in libz
+ Memcheck:Cond
+ obj:/usr/lib/libz.so.1.2.3
+ obj:/usr/lib/libz.so.1.2.3
+ fun:deflate
+ fun:compress2
+ fun:compress
+ fun:compress_dup
+ fun:emit_pattern
+ fun:_cairo_pdf_surface_paint
+}
+{
+ cairo's _cairo_pdf_surface_paint triggers apparent bugs in libz
+ Memcheck:Cond
+ fun:deflate_slow
+ fun:deflate
+}
+{
+ cairo's _cairo_pdf_surface_paint triggers apparent bugs in libz
+ Memcheck:Value4
+ fun:deflate_slow
+ fun:deflate
+}
+{
+ cairo's _cairo_pdf_surface_paint triggers apparent bugs in libz
+ Memcheck:Value4
+ fun:compress_block
+ fun:_tr_flush_block
+ fun:deflate_slow
+ fun:deflate
+}
+{
+ cairo's _cairo_pdf_surface_paint triggers apparent bugs in libz
+ Memcheck:Value4
+ fun:crc32
+ obj:/usr/lib/libpng12.so.0.15.0
+ fun:png_write_chunk_data
+ fun:png_write_chunk
+}
+{
+ cairo's _cairo_pdf_surface_paint triggers apparent bugs in libz
+ Memcheck:Value4
+ fun:base64_write_func
+ fun:stream_write_func
+ obj:/usr/lib/libpng12.so.0.15.0
+ fun:png_write_chunk_data
+ fun:png_write_chunk
+}
+{
+ pthread initialization strstr bug
+ Memcheck:Cond
+ fun:strstr
+ fun:__pthread_initialize_minimal
+ obj:/lib/libpthread-2.3.5.so
+ obj:/lib/libpthread-2.3.5.so
+ fun:call_init
+ fun:_dl_init
+ obj:/lib/ld-2.3.5.so
+}
+{
+ Pixman reads padding bytes that are never initialized
+ Memcheck:Cond
+ fun:fbBltOne
+ fun:fbCompositeSolidMask_nx1xn
+ fun:_cairo_pixman_composite
+ fun:_cairo_image_surface_composite
+ fun:_cairo_surface_composite
+ fun:_cairo_ft_scaled_font_show_glyphs
+ fun:_cairo_scaled_font_show_glyphs
+ fun:_cairo_gstate_show_glyphs_draw_func
+ fun:_cairo_gstate_clip_and_composite
+ fun:_cairo_gstate_show_glyphs
+ fun:cairo_show_text
+ fun:draw
+}
+{
+ XXX: I have no idea what might be causing this
+ Memcheck:Free
+ fun:free
+ fun:free_mem
+ fun:__libc_freeres
+ fun:_vgw_freeres
+ fun:exit
+ fun:__libc_start_main
+}
+{
+ XrmGetStringDatabase is fairly obnoxious about leaving reachable memory around
+ Memcheck:Leak
+ fun:malloc
+ fun:_XlcAddCT
+ fun:_XlcInitCTInfo
+ fun:initialize
+ fun:initialize
+ fun:_XlcCreateLC
+ fun:_XlcUtf8Loader
+ fun:_XOpenLC
+ fun:_XrmInitParseInfo
+ fun:NewDatabase
+ fun:XrmGetStringDatabase
+}
+{
+ XrmGetStringDatabase is fairly obnoxious about leaving reachable memory around
+ Memcheck:Leak
+ fun:malloc
+ fun:PutEntry
+ fun:GetDatabase
+ fun:XrmGetStringDatabase
+}
+{
+ XrmGetStringDatabase is fairly obnoxious about leaving reachable memory around
+ Memcheck:Leak
+ fun:malloc
+ fun:initialize
+ fun:_XlcCreateLC
+ fun:_XlcDefaultLoader
+ fun:_XOpenLC
+ fun:_XrmInitParseInfo
+ fun:NewDatabase
+ fun:XrmGetStringDatabase
+}
+{
+ XrmGetStringDatabase is fairly obnoxious about leaving reachable memory around
+ Memcheck:Leak
+ fun:malloc
+ fun:add_codeset
+ fun:initialize
+ fun:_XlcCreateLC
+ fun:_XlcDefaultLoader
+ fun:_XOpenLC
+ fun:_XrmInitParseInfo
+ fun:NewDatabase
+ fun:XrmGetStringDatabase
+}
+{
+ XrmInitialize is fairly obnoxious about leaving reachable memory around
+ Memcheck:Leak
+ fun:malloc
+ fun:_XrmInternalStringToQuark
+}
+{
+ XrmInitialize is fairly obnoxious about leaving reachable memory around
+ Memcheck:Leak
+ fun:malloc
+ obj:/usr/lib/libX11.so.6.2.0
+ fun:_XrmInternalStringToQuark
+ fun:XrmInitialize
+}
+{
+ XrmInitialize is fairly obnoxious about leaving reachable memory around
+ Memcheck:Leak
+ fun:malloc
+ fun:permalloc
+ fun:_XrmInternalStringToQuark
+}
+{
+ XrmGetStringDatabase is fairly obnoxious about leaving reachable memory around
+ Memcheck:Leak
+ fun:malloc
+ fun:_XlcSetConverter
+ fun:_XlcDefaultLoader
+ fun:_XOpenLC
+ fun:_XrmInitParseInfo
+ fun:NewDatabase
+ fun:XrmGetStringDatabase
+}
+{
+ XrmGetStringDatabase is fairly obnoxious about leaving reachable memory around
+ Memcheck:Leak
+ fun:malloc
+ fun:_XlcCreateDefaultCharSet
+ fun:_XlcAddCT
+ fun:_XlcInitCTInfo
+ fun:initialize
+ fun:initialize
+ fun:_XlcCreateLC
+ fun:_XlcUtf8Loader
+ fun:_XOpenLC
+ fun:_XrmInitParseInfo
+ fun:NewDatabase
+ fun:XrmGetStringDatabase
+}
+{
+ XrmGetStringDatabase is fairly obnoxious about leaving reachable memory around
+ Memcheck:Leak
+ fun:realloc
+ fun:add_codeset
+ fun:initialize
+ fun:_XlcCreateLC
+ fun:_XlcDefaultLoader
+ fun:_XOpenLC
+ fun:_XrmInitParseInfo
+ fun:NewDatabase
+ fun:XrmGetStringDatabase
+}
+{
+ XrmGetStringDatabase is fairly obnoxious about leaving reachable memory around
+ Memcheck:Leak
+ fun:realloc
+ fun:add_codeset
+ fun:load_generic
+ fun:initialize
+ fun:_XlcCreateLC
+ fun:_XlcDefaultLoader
+ fun:_XOpenLC
+}
+{
+ XrmGetStringDatabase is fairly obnoxious about leaving reachable memory around
+ Memcheck:Leak
+ fun:malloc
+ fun:add_codeset
+ fun:load_generic
+ fun:initialize
+ fun:_XlcCreateLC
+ fun:_XlcDefaultLoader
+ fun:_XOpenLC
+}
+{
+ XrmGetStringDatabase is fairly obnoxious about leaving reachable memory around
+ Memcheck:Leak
+ fun:malloc
+ fun:load_generic
+ fun:initialize
+ fun:_XlcCreateLC
+ fun:_XlcDefaultLoader
+ fun:_XOpenLC
+}
+{
+ XrmGetStringDatabase is fairly obnoxious about leaving reachable memory around
+ Memcheck:Leak
+ fun:malloc
+ fun:_XlcAddCharSet
+ fun:_XlcAddCT
+ fun:_XlcInitCTInfo
+ fun:initialize
+ fun:initialize
+ fun:_XlcCreateLC
+ fun:_XlcUtf8Loader
+ fun:_XOpenLC
+ fun:_XrmInitParseInfo
+ fun:NewDatabase
+ fun:XrmGetStringDatabase
+}
+{
+ XrmGetStringDatabase is fairly obnoxious about leaving reachable memory around
+ Memcheck:Leak
+ fun:malloc
+ fun:_XlcCreateLocaleDataBase
+ fun:initialize
+ fun:initialize
+ fun:_XlcCreateLC
+ fun:_XlcUtf8Loader
+ fun:_XOpenLC
+ fun:_XrmInitParseInfo
+ fun:NewDatabase
+ fun:XrmGetStringDatabase
+}
+{
+ XrmGetStringDatabase is fairly obnoxious about leaving reachable memory around
+ Memcheck:Leak
+ fun:malloc
+ fun:_XlcSetConverter
+ fun:_XlcInitCTInfo
+ fun:initialize
+ fun:initialize
+ fun:_XlcCreateLC
+ fun:_XlcUtf8Loader
+ fun:_XOpenLC
+ fun:_XrmInitParseInfo
+ fun:NewDatabase
+ fun:XrmGetStringDatabase
+}
+{
+ pthread initialization seems to leave some memory possibly lost
+ Memcheck:Leak
+ fun:calloc
+ obj:/lib/ld-2.3.6.so
+ obj:/lib/ld-2.3.6.so
+ fun:_dl_allocate_tls
+ fun:__pthread_initialize_minimal
+ obj:/usr/lib/debug/libpthread-0.10.so
+ obj:/usr/lib/debug/libpthread-0.10.so
+ obj:/lib/ld-2.3.6.so
+ obj:/lib/ld-2.3.6.so
+ obj:/lib/ld-2.3.6.so
+}
+{
+ pthread initialization seems to leave some memory still reachable
+ Memcheck:Leak
+ fun:calloc
+ fun:_dl_tls_setup
+ fun:__pthread_initialize_minimal
+ obj:/usr/lib/debug/libpthread-0.10.so
+ obj:/usr/lib/debug/libpthread-0.10.so
+ obj:/lib/ld-2.3.6.so
+ obj:/lib/ld-2.3.6.so
+ obj:/lib/ld-2.3.6.so
+}
+{
+ pthread initialization seems to leave some memory possibly lost
+ Memcheck:Leak
+ fun:memalign
+ obj:/lib/ld-2.3.6.so
+ fun:_dl_allocate_tls
+ fun:__pthread_initialize_minimal
+ obj:/usr/lib/debug/libpthread-0.10.so
+ obj:/usr/lib/debug/libpthread-0.10.so
+ obj:/lib/ld-2.3.6.so
+ obj:/lib/ld-2.3.6.so
+ obj:/lib/ld-2.3.6.so
+}
+{
+ XrmGet*Database is fairly obnoxious about leaving reachable memory around
+ Memcheck:Leak
+ fun:malloc
+ fun:_XlcAddCT
+ fun:_XlcInitCTInfo
+ fun:initialize
+ fun:initialize
+ fun:_XlcCreateLC
+ fun:_XlcUtf8Loader
+ fun:_XOpenLC
+ fun:_XrmInitParseInfo
+ fun:NewDatabase
+}
+{
+ XrmGet*Database is fairly obnoxious about leaving reachable memory around
+ Memcheck:Leak
+ fun:malloc
+ fun:PutEntry
+ fun:GetDatabase
+}
+{
+ XrmGet*Database is fairly obnoxious about leaving reachable memory around
+ Memcheck:Leak
+ fun:malloc
+ fun:initialize
+ fun:_XlcCreateLC
+ fun:_XlcDefaultLoader
+ fun:_XOpenLC
+ fun:_XrmInitParseInfo
+ fun:NewDatabase
+}
+{
+ XrmGet*Database is fairly obnoxious about leaving reachable memory around
+ Memcheck:Leak
+ fun:malloc
+ fun:add_codeset
+ fun:initialize
+ fun:_XlcCreateLC
+ fun:_XlcDefaultLoader
+ fun:_XOpenLC
+ fun:_XrmInitParseInfo
+ fun:NewDatabase
+}
+{
+ XrmGet*Database is fairly obnoxious about leaving reachable memory around
+ Memcheck:Leak
+ fun:malloc
+ fun:_XlcAddCharSet
+ fun:_XlcAddCT
+ fun:_XlcInitCTInfo
+ fun:initialize
+ fun:initialize
+ fun:_XlcCreateLC
+ fun:_XlcUtf8Loader
+ fun:_XOpenLC
+ fun:_XrmInitParseInfo
+ fun:NewDatabase
+}
+{
+ XrmGet*Database is fairly obnoxious about leaving reachable memory around
+ Memcheck:Leak
+ fun:realloc
+ fun:add_codeset
+ fun:initialize
+ fun:_XlcCreateLC
+ fun:_XlcDefaultLoader
+ fun:_XOpenLC
+ fun:_XrmInitParseInfo
+ fun:NewDatabase
+}
+{
+ XrmGet*Database is fairly obnoxious about leaving reachable memory around
+ Memcheck:Leak
+ fun:malloc
+ fun:_XlcCreateDefaultCharSet
+ fun:_XlcAddCT
+ fun:_XlcInitCTInfo
+ fun:initialize
+ fun:initialize
+ fun:_XlcCreateLC
+ fun:_XlcUtf8Loader
+ fun:_XOpenLC
+ fun:_XrmInitParseInfo
+ fun:NewDatabase
+}
+{
+ XrmGet*Database is fairly obnoxious about leaving reachable memory around
+ Memcheck:Leak
+ fun:malloc
+ fun:_XlcCreateDefaultCharSet
+ fun:_XlcAddCT
+ fun:_XlcInitCTInfo
+ fun:initialize
+ fun:initialize
+ fun:_XlcCreateLC
+ fun:_XlcUtf8Loader
+ fun:_XOpenLC
+ fun:_XrmInitParseInfo
+ fun:NewDatabase
+}
+{
+ XrmGet*Database is fairly obnoxious about leaving reachable memory around
+ Memcheck:Leak
+ fun:malloc
+ fun:_XlcAddCT
+ fun:_XlcInitCTInfo
+ fun:initialize
+ fun:initialize
+ fun:_XlcCreateLC
+ fun:_XlcUtf8Loader
+ fun:_XOpenLC
+ fun:_XrmInitParseInfo
+ fun:NewDatabase
+}
+{
+ XrmGet*Database is fairly obnoxious about leaving reachable memory around
+ Memcheck:Leak
+ fun:malloc
+ fun:_XlcCreateLocaleDataBase
+ fun:initialize
+ fun:initialize
+ fun:_XlcCreateLC
+ fun:_XlcUtf8Loader
+ fun:_XOpenLC
+ fun:_XrmInitParseInfo
+ fun:NewDatabase
+}
+{
+ XrmGet*Database is fairly obnoxious about leaving reachable memory around
+ Memcheck:Leak
+ fun:malloc
+ fun:_XlcCreateDefaultCharSet
+ fun:_XlcAddCT
+ fun:_XlcInitCTInfo
+ fun:initialize
+ fun:initialize
+ fun:_XlcCreateLC
+ fun:_XlcUtf8Loader
+ fun:_XOpenLC
+ fun:_XrmInitParseInfo
+ fun:NewDatabase
+}
+{
+ XrmGet*Database is fairly obnoxious about leaving reachable memory around
+ Memcheck:Leak
+ fun:malloc
+ fun:_XlcSetConverter
+ fun:_XlcInitCTInfo
+ fun:initialize
+ fun:initialize
+ fun:_XlcCreateLC
+ fun:_XlcUtf8Loader
+ fun:_XOpenLC
+ fun:_XrmInitParseInfo
+ fun:NewDatabase
+}
+{
+ XrmGet*Database is fairly obnoxious about leaving reachable memory around
+ Memcheck:Leak
+ fun:malloc
+ fun:_XlcSetConverter
+ fun:_XlcDefaultLoader
+ fun:_XOpenLC
+ fun:_XrmInitParseInfo
+ fun:NewDatabase
+}
+{
+ XrmGet*Database is fairly obnoxious about leaving reachable memory around
+ Memcheck:Leak
+ fun:malloc
+ fun:_XlcSetConverter
+ fun:_XlcAddUtf8Converters
+ fun:_XlcDefaultLoader
+ fun:_XOpenLC
+ fun:_XrmInitParseInfo
+ fun:NewDatabase
+}
+{
+ Xau chooses not to free its static data...
+ Memcheck:Leak
+ fun:malloc
+ fun:XauFileName
+}
diff --git a/test/6x13.pcf b/test/6x13.pcf
new file mode 100644
index 000000000..1325ae64f
--- /dev/null
+++ b/test/6x13.pcf
Binary files differ
diff --git a/test/COPYING b/test/COPYING
new file mode 100644
index 000000000..3db71fb08
--- /dev/null
+++ b/test/COPYING
@@ -0,0 +1,26 @@
+Cairo is free software.
+
+These tests are mainly available under a liberal MIT license to simplify
+any use of the code for reference purposes. Please check the opening comment
+of each file for copyright and licensing information.
+
+The test suite also bundles some fonts for use by the test suite. The
+fonts included, their licenses, and why we use them in the test suite
+are as follows:
+
+ Font License Distinguishing feature
+ -------- ------------- ----------------------
+ 6x13.pcf Public Domain Bitmap font
+
+
+The test suite also bundles some images for use by the test suite. The
+images included, their licenses, and why we use them in the test suite
+are as follows:
+
+ Image License Distinguishing feature
+ ------------- ------------- -------------------------
+ romedalen.jpg Public Domain Bitmap image (image/jpeg)
+ romedalen.png Public Domain Bitmap image (image/png)
+
+The kind contributors of the bundled files are (in alphabetical order):
+Øyvind Kolås <pippin@freedesktop.org> Author of the original romedalen shot.
diff --git a/test/Makefile.am b/test/Makefile.am
new file mode 100644
index 000000000..be5741acf
--- /dev/null
+++ b/test/Makefile.am
@@ -0,0 +1,403 @@
+include $(top_srcdir)/build/Makefile.am.common
+
+include $(top_srcdir)/test/Makefile.sources
+
+SUBDIRS=pdiff .
+
+# Then we have a collection of tests that are only run if certain
+# features are compiled into cairo
+if HAVE_REAL_PTHREAD
+test_sources += $(pthread_test_sources)
+endif
+
+if CAIRO_HAS_FT_FONT
+if CAIRO_HAS_FC_FONT
+test_sources += $(ft_font_test_sources)
+endif
+endif
+
+if CAIRO_HAS_EGL_FUNCTIONS
+test_sources += $(egl_surface_test_sources)
+endif
+
+# Need to add quartz-surface-source
+if CAIRO_HAS_QUARTZ_SURFACE
+test_sources += $(quartz_surface_test_sources)
+endif
+
+if CAIRO_HAS_PDF_SURFACE
+test_sources += $(pdf_surface_test_sources)
+endif
+
+if CAIRO_HAS_PS_SURFACE
+test_sources += $(ps_surface_test_sources)
+endif
+
+if CAIRO_HAS_SVG_SURFACE
+test_sources += $(svg_surface_test_sources)
+endif
+
+if CAIRO_HAS_TEST_SURFACES
+test_sources += $(test_fallback16_surface_test_sources)
+endif
+
+if CAIRO_HAS_XCB_SURFACE
+test_sources += $(xcb_surface_test_sources)
+endif
+
+if CAIRO_HAS_XLIB_SURFACE
+test_sources += $(xlib_surface_test_sources)
+endif
+
+if CAIRO_HAS_XLIB_XRENDER_SURFACE
+test_sources += $(xlib_xrender_surface_test_sources)
+endif
+
+if CAIRO_HAS_MULTI_PAGE_SURFACES
+test_sources += $(multi_page_surface_test_sources)
+endif
+
+# Include fallback-resolution (once!) if we have any of the vector surfaces
+if BUILD_ANY2PPM
+if CAIRO_HAS_SVG_SURFACE
+test = $(fallback_resolution_test_sources)
+endif
+if CAIRO_HAS_PDF_SURFACE
+test = $(fallback_resolution_test_sources)
+endif
+if CAIRO_HAS_PS_SURFACE
+test = $(fallback_resolution_test_sources)
+endif
+endif
+test_sources += $(test)
+
+noinst_PROGRAMS = cairo-test-suite$(EXEEXT) # always build
+noinst_SCRIPTS = check-refs.sh
+
+TESTS += cairo-test-suite$(EXEEXT)
+
+cairo-test-constructors.c: Makefile $(test_sources) make-cairo-test-constructors.sh
+ (cd $(srcdir) && sh ./make-cairo-test-constructors.sh $(test_sources)) > $@
+
+cairo_test_suite_SOURCES = \
+ $(cairo_test_suite_sources) \
+ $(cairo_test_suite_headers) \
+ $(test_sources) \
+ cairo-test-constructors.c
+cairo_test_suite_CFLAGS = $(AM_CFLAGS) $(real_pthread_CFLAGS)
+cairo_test_suite_LDADD = \
+ $(real_pthread_LIBS) \
+ $(top_builddir)/test/pdiff/libpdiff.la \
+ $(top_builddir)/boilerplate/libcairoboilerplate.la \
+ $(top_builddir)/src/libcairo.la \
+ $(CAIRO_LDADD)
+cairo_test_suite_DEPENDENCIES = \
+ $(top_builddir)/test/pdiff/libpdiff.la \
+ $(top_builddir)/boilerplate/libcairoboilerplate.la \
+ $(top_builddir)/src/libcairo.la
+if BUILD_ANY2PPM
+cairo_test_suite_DEPENDENCIES += \
+ any2ppm$(EXEEXT)
+endif
+
+if HAVE_SHM
+EXTRA_PROGRAMS += cairo-test-trace
+cairo_test_trace_SOURCES = \
+ cairo-test-trace.c \
+ buffer-diff.c \
+ buffer-diff.h
+cairo_test_trace_CFLAGS = $(AM_CFLAGS) $(real_pthread_CFLAGS)
+cairo_test_trace_LDADD = \
+ $(real_pthread_LIBS) \
+ $(top_builddir)/test/pdiff/libpdiff.la \
+ $(top_builddir)/util/cairo-script/libcairo-script-interpreter.la \
+ $(top_builddir)/boilerplate/libcairoboilerplate.la \
+ $(top_builddir)/src/libcairo.la \
+ $(top_builddir)/util/cairo-missing/libcairo-missing.la \
+ $(CAIRO_LDADD) \
+ $(SHM_LIBS)
+cairo_test_trace_DEPENDENCIES = \
+ $(top_builddir)/test/pdiff/libpdiff.la \
+ $(top_builddir)/util/cairo-script/libcairo-script-interpreter.la \
+ $(top_builddir)/boilerplate/libcairoboilerplate.la \
+ $(top_builddir)/src/libcairo.la \
+ $(top_builddir)/util/cairo-missing/libcairo-missing.la \
+ $(NULL)
+endif
+
+BUILT_SOURCES += cairo-test-constructors.c
+EXTRA_DIST += $(BUILT_SOURCES) $(noinst_SCRIPTS) COPYING make-cairo-test-constructors.sh run-cairo-test-suite.sh generate_refs.sh tiger.inc
+CLEANFILES += $(BUILT_SOURCES)
+
+EXTRA_DIST += \
+6x13.pcf \
+index.html \
+jp2.jp2 \
+jpeg.jpg \
+png.png \
+romedalen.jpg \
+romedalen.png \
+scarab.jpg \
+surface-source.c \
+testtable.js \
+reference
+
+# Any test that doesn't generate a log file goes here
+NOLOG_TESTS = \
+fallback-resolution \
+font-options \
+multi-page \
+pdf-features \
+png \
+ps-eps \
+ps-features \
+svg-clip \
+svg-surface \
+toy-font-face \
+user-data
+
+# A target to summarise the failures
+check-summary:
+ @FAILED_TESTS=""; \
+ for t in output/*.log; do \
+ if grep -e '\<FAIL\>' $$t >/dev/null 2>&1; then \
+ FAILED_TESTS="$$FAILED_TESTS $$t"; \
+ fi; \
+ done; \
+ if test -n "$$FAILED_TESTS"; then \
+ echo "Failed tests:"; \
+ surfaces=""; \
+ for t in $$FAILED_TESTS; do \
+ name="$${t##output/}"; name="$${name%.log}"; \
+ echo -n " $$name: "; \
+ grep -e '\<FAIL\>' $$t | sed -e 's/.*TARGET: \([^ ]*\).*/\1/' | sort | uniq | tr '\n' ' '; \
+ echo; \
+ for s in `grep -e '\<FAIL\>' $$t | sed -e 's/.*TARGET: \([^ ]*\).*/\1/' | sort | uniq`; do \
+ ss=`echo $$s | tr '-' '_'`; \
+ tt=`echo $$name | tr '-' '_'`; \
+ eval $$ss=\""$${!ss} $$tt"\"; \
+ echo $$surfaces | grep $$ss >/dev/null || surfaces="$$surfaces $$ss"; \
+ done; \
+ done; \
+ echo -n "Failures per surface - "; \
+ first=""; \
+ for s in $$surfaces; do \
+ ss=`echo $$s | tr '_' '-'`; \
+ test -n "$$first" && echo -n ", "; \
+ cnt=`echo $${!s} | wc -w`; \
+ echo -n "$$ss: $$cnt"; \
+ first="false"; \
+ done; \
+ echo "."; \
+ for s in $$surfaces; do \
+ ss=`echo $$s | tr '_' '-'`; \
+ cnt=`echo $${!s} | wc -w`; \
+ echo -n " $$ss [$$cnt]: "; \
+ echo $${!s} | tr '_' '-'; \
+ done; \
+ fi
+
+AM_CPPFLAGS = \
+ -I$(srcdir) \
+ -I$(srcdir)/pdiff \
+ -I$(top_srcdir)/boilerplate \
+ -I$(top_srcdir)/util/cairo-missing \
+ -I$(top_srcdir)/util/cairo-script \
+ -I$(top_srcdir)/src \
+ -I$(top_builddir)/src \
+ $(CAIRO_CFLAGS)
+AM_LDFLAGS = $(CAIRO_LDFLAGS)
+
+$(top_builddir)/boilerplate/libcairoboilerplate.la: $(top_builddir)/src/libcairo.la
+ cd $(top_builddir)/boilerplate && $(MAKE) $(AM_MAKEFLAGS) libcairoboilerplate.la
+
+$(top_builddir)/src/libcairo.la:
+ cd $(top_builddir)/src && $(MAKE) $(AM_MAKEFLAGS) libcairo.la
+
+$(top_builddir)/test/pdiff/libpdiff.la:
+ cd $(top_builddir)/test/pdiff && $(MAKE) $(AM_MAKEFLAGS) libpdiff.la
+
+$(top_builddir)/test/pdiff/perceptualdiff:
+ cd $(top_builddir)/test/pdiff && $(MAKE) $(AM_MAKEFLAGS) perceptualdiff
+
+$(top_builddir)/util/cairo-script/libcairo-script-interpreter.la: $(top_builddir)/src/libcairo.la
+ cd $(top_builddir)/util/cairo-script && $(MAKE) $(AM_MAKEFLAGS) libcairo-script-interpreter.la
+
+EXTRA_PROGRAMS += imagediff png-flatten
+
+imagediff_SOURCES = \
+ imagediff.c \
+ buffer-diff.c \
+ buffer-diff.h
+imagediff_LDADD = \
+ $(top_builddir)/test/pdiff/libpdiff.la \
+ $(top_builddir)/src/libcairo.la
+
+png_flatten_SOURCES = png-flatten.c
+png_flatten_LDADD = $(top_builddir)/src/libcairo.la \
+ $(CAIRO_LDADD)
+
+if BUILD_ANY2PPM
+check_PROGRAMS += any2ppm
+any2ppm_CFLAGS = $(AM_CFLAGS) $(POPPLER_CFLAGS) $(LIBRSVG_CFLAGS) $(LIBSPECTRE_CFLAGS)
+# add LDADD, so poppler/librsvg uses "our" cairo
+any2ppm_LDFLAGS = $(AM_LDFLAGS) $(CAIRO_TEST_UNDEFINED_LDFLAGS)
+any2ppm_LDADD = \
+ $(top_builddir)/util/cairo-script/libcairo-script-interpreter.la \
+ $(top_builddir)/src/libcairo.la \
+ $(CAIRO_LDADD) \
+ $(CAIROBOILERPLATE_LIBS) \
+ $(POPPLER_LIBS) \
+ $(LIBRSVG_LIBS) \
+ $(LIBSPECTRE_LIBS)
+endif
+
+if CAIRO_CAN_TEST_PDF_SURFACE
+check_PROGRAMS += pdf2png
+pdf2png_CFLAGS = $(AM_CFLAGS) $(POPPLER_CFLAGS)
+# add LDADD, so poppler uses "our" cairo
+pdf2png_LDFLAGS = $(AM_LDFLAGS) $(CAIRO_TEST_UNDEFINED_LDFLAGS)
+pdf2png_LDADD = $(top_builddir)/src/libcairo.la \
+ $(CAIRO_LDADD) \
+ $(POPPLER_LIBS)
+endif
+
+if CAIRO_CAN_TEST_SVG_SURFACE
+check_PROGRAMS += svg2png
+svg2png_CFLAGS = $(AM_CFLAGS) $(LIBRSVG_CFLAGS)
+# add LDADD, so librsvg uses "our" cairo
+svg2png_LDFLAGS = $(AM_LDFLAGS) $(CAIRO_TEST_UNDEFINED_LDFLAGS)
+svg2png_LDADD = $(top_builddir)/src/libcairo.la \
+ $(CAIRO_LDADD) \
+ $(LIBRSVG_LIBS)
+endif
+
+if CAIRO_HAS_SPECTRE
+check_PROGRAMS += ps2png
+ps2png_CFLAGS = $(AM_CFLAGS) $(LIBSPECTRE_CFLAGS)
+# add LDADD, so ps2png uses "our" cairo
+ps2png_LDFLAGS = $(AM_LDFLAGS) $(CAIRO_TEST_UNDEFINED_LDFLAGS)
+ps2png_LDADD = $(top_builddir)/src/libcairo.la \
+ $(CAIRO_LDADD) \
+ $(LIBSPECTRE_LIBS)
+endif
+
+EXTRA_PROGRAMS += $(TESTS)
+
+# Do a funny transition of CAIRO_TEST_TARGET through TARGETS such that
+# one can limit tested targets both through CAIRO_TEST_TARGET env var
+# and TARGETS make var on the command line. Same for the rest.
+TARGETS = $(CAIRO_TEST_TARGET)
+TARGETS_EXCLUDE = $(CAIRO_TEST_TARGET_EXCLUDE)
+FORMAT = $(CAIRO_TEST_TARGET_FORMAT)
+NUM_THREADS = $(CAIRO_TEST_NUM_THREADS)
+MODE = $(CAIRO_TEST_MODE)
+
+# Same about ENV vs CAIRO_TEST_ENV. ENV is used with "make run" only
+ENV = $(CAIRO_TEST_ENV)
+
+TESTS_ENVIRONMENT = CAIRO_TEST_MODE="$(MODE)" CAIRO_TEST_TARGET="$(TARGETS)" CAIRO_TEST_TARGET_FORMAT="$(FORMAT)" CAIRO_TEST_TARGET_EXCLUDE="$(TARGETS_EXCLUDE)" CAIRO_TEST_NUM_THREADS="$(NUM_THREADS)" $(ENV)
+
+EXTRA_VALGRIND_FLAGS = $(CAIRO_EXTRA_VALGRIND_FLAGS)
+VALGRIND_FLAGS = \
+ --tool=memcheck --suppressions=$(srcdir)/.valgrind-suppressions \
+ --track-origins=yes \
+ --leak-check=yes --show-reachable=yes \
+ $(EXTRA_VALGRIND_FLAGS)
+
+CLEANFILES += \
+ valgrind-log \
+ ref.hash \
+ ref.list \
+ png-test.png \
+ png.out.png \
+ create-for-stream.pdf \
+ create-for-stream.ps \
+ create-for-stream.svg \
+ svg-surface-source.out.svg \
+ pdf-surface-source.out.pdf \
+ ps-surface-source.out.ps \
+ pdf-features.pdf \
+ pdf-mime-data.out* \
+ ps-features.ps \
+ svg-clip.svg \
+ svg-surface.svg \
+ multi-page.pdf \
+ multi-page.ps \
+ $(NULL)
+
+# This used to be a simple 'echo ${RM} *.ps *.pdf *.svg *.etc', but
+# most systems cannot handle all of our clean files together.
+# Then it became a fancy find using many GNU extensions, but then the ugly
+# reality of portability was raised and it became....
+clean-local:
+ rm -rf output
+ -${FIND} . -name '*.log' -print | ${XARGS} ${RM}
+ -${FIND} . -name '*.[is]' -print | ${XARGS} ${RM}
+clean-caches:
+ -${FIND} output -name '*.fail.*' -print | ${XARGS} ${RM}
+ -${FIND} output -name '*.pass.*' -print | ${XARGS} ${RM}
+
+# The following definitions both should work.
+#FAILED_TESTS = `grep -l '\<FAIL\>' $(test_sources:.c=.log) 2>/dev/null | sed -e 's/[.]log$$//' | xargs echo`
+FAILED_TESTS = `grep -l '\<FAIL\>' $(test_sources:.c=.log) 2>/dev/null | tr '\n' ' ' | sed -e 's/[.]log */ /g; s/^ //; s/ $$//'`
+
+recheck = check CAIRO_TESTS="$(FAILED_TESTS)"
+
+# Re-checks all failed tests, i.e. tests with a log file that has a failure
+recheck:
+ @echo Re-checking failed tests
+ @$(MAKE) $(AM_MAKEFLAGS) $(recheck)
+
+# Checks tests.
+# Target doesn't fail if tests fail.
+test:
+ @$(MAKE) $(AM_MAKEFLAGS) check
+
+# Re-checks tests.
+# Target doesn't fail if tests fail.
+retest:
+ @CAIRO_TESTS="$(FAILED_TESTS)"; \
+ $(MAKE) $(AM_MAKEFLAGS) check
+
+# Run tests under a tool specified by TOOL. For example, make run TOOL=gdb
+run:
+ $(MAKE) $(AM_MAKEFLAGS) check TESTS_ENVIRONMENT='$(TESTS_ENVIRONMENT) $(top_builddir)/libtool --mode=execute env $(TOOL)'
+
+# Check tests under valgrind. Saves log to valgrind-log
+check-valgrind:
+ $(MAKE) $(AM_MAKEFLAGS) check TESTS_ENVIRONMENT='$(TESTS_ENVIRONMENT) CAIRO_TEST_MODE="$(MODE),foreground CAIRO_TEST_TIMEOUT=0" $(top_builddir)/libtool --mode=execute valgrind $(VALGRIND_FLAGS)' 2>&1 | tee valgrind-log
+
+#%.log: %.c cairo-test-suite
+#-./cairo-test-suite $(<:.c=)
+
+NOLOG_TESTS_LOG = $(NOLOG_TESTS:=.log)
+
+$(NOLOG_TESTS_LOG):
+ @echo dummy > $@
+
+# Identify identical reference images
+check-ref-dups: check-refs.sh $(top_builddir)/test/pdiff/perceptualdiff
+ sh $(srcdir)/check-refs.sh $(top_builddir)/test/pdiff/perceptualdiff
+
+# Remove identical reference images (DANGEROUS)
+clean-ref-dups: check-refs.sh $(top_builddir)/test/pdiff/perceptualdiff
+ sh $(srcdir)/check-refs.sh | cut -d' ' -f2 | while read f; do git rm "reference/$$f"; done
+
+results.tar:
+ @tar cf $@ index.html testtable.js *.log output/*.log; \
+ for i in output/*.fail.png ; do \
+ testname=$${i#output/} ; \
+ testname=$${testname%%.*} ; \
+ echo tar uf $@ reference/$${testname}*.ref.png $${i%fail.png}out.png $${i%fail.png}diff.png ; \
+ tar uf $@ reference/$${testname}*.ref.png $${i%fail.png}out.png $${i%fail.png}diff.png ; \
+ done
+
+results.tar.gz: results.tar
+ gzip -c $< > $@
+
+release-verify-sane-tests:
+
+.PHONY: check-valgrind test recheck retest check-ref-dups release-verify-sane-tests
+
+EXTRA_DIST += Makefile.win32
diff --git a/test/Makefile.sources b/test/Makefile.sources
new file mode 100644
index 000000000..ccf1a8410
--- /dev/null
+++ b/test/Makefile.sources
@@ -0,0 +1,446 @@
+test_sources = \
+ a1-bug.c \
+ a1-clip.c \
+ a1-fill.c \
+ a1-image-sample.c \
+ a1-mask.c \
+ a1-mask-sample.c \
+ a1-sample.c \
+ a1-traps-sample.c \
+ a1-rasterisation.c \
+ a8-clear.c \
+ a8-mask.c \
+ aliasing.c \
+ alpha-similar.c \
+ arc-direction.c \
+ arc-infinite-loop.c \
+ arc-looping-dash.c \
+ api-special-cases.c \
+ big-line.c \
+ big-empty-box.c \
+ big-empty-triangle.c \
+ big-little-box.c \
+ big-little-triangle.c \
+ bug-spline.c \
+ big-trap.c \
+ bilevel-image.c \
+ blur.c \
+ bug-40410.c \
+ bug-51910.c \
+ bug-84115.c \
+ bug-bo-rectangular.c \
+ bug-bo-collins.c \
+ bug-bo-ricotz.c \
+ bug-source-cu.c \
+ bug-extents.c \
+ bug-seams.c \
+ caps.c \
+ checkerboard.c \
+ caps-joins.c \
+ caps-joins-alpha.c \
+ caps-joins-curve.c \
+ caps-tails-curve.c \
+ caps-sub-paths.c \
+ clear.c \
+ clear-source.c \
+ clip-all.c \
+ clip-complex-bug61592.c \
+ clip-complex-shape.c \
+ clip-contexts.c \
+ clip-disjoint.c \
+ clip-disjoint-hatching.c \
+ clip-disjoint-quad.c \
+ clip-device-offset.c \
+ clip-double-free.c \
+ clip-draw-unbounded.c \
+ clip-empty.c \
+ clip-empty-group.c \
+ clip-empty-save.c \
+ clip-fill.c \
+ clip-fill-no-op.c \
+ clip-fill-rule.c \
+ clip-fill-rule-pixel-aligned.c \
+ clip-group-shapes.c \
+ clip-image.c \
+ clip-intersect.c \
+ clip-mixed-antialias.c \
+ clip-nesting.c \
+ clip-operator.c \
+ clip-push-group.c \
+ clip-polygons.c \
+ clip-rectilinear.c \
+ clip-shape.c \
+ clip-stroke.c \
+ clip-stroke-no-op.c \
+ clip-text.c \
+ clip-twice.c \
+ clip-twice-rectangle.c \
+ clip-unbounded.c \
+ clip-zero.c \
+ clipped-group.c \
+ clipped-surface.c \
+ close-path.c \
+ close-path-current-point.c \
+ composite-integer-translate-source.c \
+ composite-integer-translate-over.c \
+ composite-integer-translate-over-repeat.c \
+ copy-disjoint.c \
+ copy-path.c \
+ coverage.c \
+ create-for-stream.c \
+ create-from-png.c \
+ create-from-png-stream.c \
+ culled-glyphs.c \
+ curve-to-as-line-to.c \
+ dash-caps-joins.c \
+ dash-curve.c \
+ dash-infinite-loop.c \
+ dash-no-dash.c \
+ dash-offset.c \
+ dash-offset-negative.c \
+ dash-scale.c \
+ dash-state.c \
+ dash-zero-length.c \
+ degenerate-arc.c \
+ degenerate-arcs.c \
+ degenerate-curve-to.c \
+ degenerate-dash.c \
+ degenerate-linear-gradient.c \
+ degenerate-path.c \
+ degenerate-pen.c \
+ degenerate-radial-gradient.c \
+ degenerate-rel-curve-to.c \
+ degenerate-solid-dash.c \
+ drunkard-tails.c \
+ device-offset.c \
+ device-offset-fractional.c \
+ device-offset-positive.c \
+ device-offset-scale.c \
+ error-setters.c \
+ extend-pad.c \
+ extend-pad-border.c \
+ extend-pad-similar.c \
+ extend-reflect.c \
+ extend-reflect-similar.c \
+ extend-repeat.c \
+ extend-repeat-similar.c \
+ extended-blend.c \
+ fallback.c \
+ fill-alpha.c \
+ fill-alpha-pattern.c \
+ fill-and-stroke.c \
+ fill-and-stroke-alpha.c \
+ fill-and-stroke-alpha-add.c \
+ fill-degenerate-sort-order.c \
+ fill-disjoint.c \
+ fill-empty.c \
+ fill-image.c \
+ fill-missed-stop.c \
+ fill-rule.c \
+ filter-bilinear-extents.c \
+ filter-nearest-offset.c \
+ filter-nearest-transformed.c \
+ finer-grained-fallbacks.c \
+ font-face-get-type.c \
+ font-matrix-translation.c \
+ font-options.c \
+ glyph-cache-pressure.c \
+ get-and-set.c \
+ get-clip.c \
+ get-group-target.c \
+ get-path-extents.c \
+ gradient-alpha.c \
+ gradient-constant-alpha.c \
+ gradient-zero-stops.c \
+ gradient-zero-stops-mask.c \
+ group-clip.c \
+ group-paint.c \
+ group-state.c \
+ group-unaligned.c \
+ half-coverage.c \
+ halo.c \
+ hatchings.c \
+ horizontal-clip.c \
+ huge-linear.c \
+ huge-radial.c \
+ image-surface-source.c \
+ image-bug-710072.c \
+ implicit-close.c \
+ infinite-join.c \
+ in-fill-empty-trapezoid.c \
+ in-fill-trapezoid.c \
+ invalid-matrix.c \
+ inverse-text.c \
+ inverted-clip.c \
+ joins.c \
+ joins-loop.c \
+ joins-star.c \
+ joins-retrace.c \
+ large-clip.c \
+ large-font.c \
+ large-source.c \
+ large-source-roi.c \
+ large-twin-antialias-mixed.c \
+ leaky-dash.c \
+ leaky-dashed-rectangle.c \
+ leaky-dashed-stroke.c \
+ leaky-polygon.c \
+ line-width.c \
+ line-width-large-overlap.c \
+ line-width-overlap.c \
+ line-width-scale.c \
+ line-width-tolerance.c \
+ line-width-zero.c \
+ linear-gradient.c \
+ linear-gradient-extend.c \
+ linear-gradient-large.c \
+ linear-gradient-one-stop.c \
+ linear-gradient-reflect.c \
+ linear-gradient-subset.c \
+ linear-step-function.c \
+ linear-uniform.c \
+ long-dashed-lines.c \
+ long-lines.c \
+ map-to-image.c \
+ mask.c \
+ mask-alpha.c \
+ mask-ctm.c \
+ mask-glyphs.c \
+ mask-surface-ctm.c \
+ mask-transformed-image.c \
+ mask-transformed-similar.c \
+ mesh-pattern.c \
+ mesh-pattern-accuracy.c \
+ mesh-pattern-conical.c \
+ mesh-pattern-control-points.c \
+ mesh-pattern-fold.c \
+ mesh-pattern-overlap.c \
+ mesh-pattern-transformed.c \
+ mime-data.c \
+ mime-surface-api.c \
+ miter-precision.c \
+ move-to-show-surface.c \
+ negative-stride-image.c \
+ new-sub-path.c \
+ nil-surface.c \
+ operator.c \
+ operator-alpha.c \
+ operator-alpha-alpha.c \
+ operator-clear.c \
+ operator-source.c \
+ outline-tolerance.c \
+ over-above-source.c \
+ over-around-source.c \
+ over-below-source.c \
+ over-between-source.c \
+ overlapping-boxes.c \
+ overlapping-glyphs.c \
+ overlapping-dash-caps.c \
+ paint.c \
+ paint-clip-fill.c \
+ paint-repeat.c \
+ paint-source-alpha.c \
+ paint-with-alpha.c \
+ paint-with-alpha-group-clip.c \
+ partial-clip-text.c \
+ partial-coverage.c \
+ pass-through.c \
+ path-append.c \
+ path-currentpoint.c \
+ path-stroke-twice.c \
+ path-precision.c \
+ pattern-get-type.c \
+ pattern-getters.c \
+ pdf-isolated-group.c \
+ pixman-downscale.c \
+ pixman-rotate.c \
+ png.c \
+ push-group.c \
+ push-group-color.c \
+ push-group-path-offset.c \
+ radial-gradient.c \
+ radial-gradient-extend.c \
+ radial-outer-focus.c \
+ random-clips.c \
+ random-intersections-eo.c \
+ random-intersections-nonzero.c \
+ random-intersections-curves-eo.c \
+ random-intersections-curves-nz.c \
+ raster-source.c \
+ record.c \
+ record1414x.c \
+ record2x.c \
+ record90.c \
+ recordflip.c \
+ record-extend.c \
+ record-mesh.c \
+ recording-surface-pattern.c \
+ recording-surface-extend.c \
+ rectangle-rounding-error.c \
+ rectilinear-fill.c \
+ rectilinear-grid.c \
+ rectilinear-miter-limit.c \
+ rectilinear-dash.c \
+ rectilinear-dash-scale.c \
+ rectilinear-stroke.c \
+ reflected-stroke.c \
+ rel-path.c \
+ rgb24-ignore-alpha.c \
+ rotate-image-surface-paint.c \
+ rotate-stroke-box.c \
+ rotated-clip.c \
+ rounded-rectangle-fill.c \
+ rounded-rectangle-stroke.c \
+ sample.c \
+ scale-down-source-surface-paint.c \
+ scale-offset-image.c \
+ scale-offset-similar.c \
+ scale-source-surface-paint.c \
+ scaled-font-zero-matrix.c \
+ stroke-ctm-caps.c \
+ stroke-clipped.c \
+ stroke-image.c \
+ stroke-open-box.c \
+ select-font-face.c \
+ select-font-no-show-text.c \
+ self-copy.c \
+ self-copy-overlap.c \
+ self-intersecting.c \
+ set-source.c \
+ show-glyphs-advance.c \
+ show-glyphs-many.c \
+ show-text-current-point.c \
+ shape-general-convex.c \
+ shape-sierpinski.c \
+ simple.c \
+ skew-extreme.c \
+ smask.c \
+ smask-fill.c \
+ smask-image-mask.c \
+ smask-mask.c \
+ smask-paint.c \
+ smask-stroke.c \
+ smask-text.c \
+ solid-pattern-cache-stress.c \
+ source-clip.c \
+ source-clip-scale.c \
+ source-surface-scale-paint.c \
+ spline-decomposition.c \
+ stride-12-image.c \
+ stroke-pattern.c \
+ subsurface.c \
+ subsurface-image-repeat.c \
+ subsurface-repeat.c \
+ subsurface-reflect.c \
+ subsurface-pad.c \
+ subsurface-modify-child.c \
+ subsurface-modify-parent.c \
+ subsurface-outside-target.c \
+ subsurface-scale.c \
+ subsurface-similar-repeat.c \
+ surface-finish-twice.c \
+ surface-pattern.c \
+ surface-pattern-big-scale-down.c \
+ surface-pattern-operator.c \
+ surface-pattern-scale-down.c \
+ surface-pattern-scale-down-extend.c \
+ surface-pattern-scale-up.c \
+ text-antialias.c \
+ text-antialias-subpixel.c \
+ text-cache-crash.c \
+ text-glyph-range.c \
+ text-pattern.c \
+ text-rotate.c \
+ text-transform.c \
+ text-zero-len.c \
+ tighten-bounds.c \
+ tiger.c \
+ toy-font-face.c \
+ transforms.c \
+ translate-show-surface.c \
+ trap-clip.c \
+ twin.c \
+ twin-antialias-gray.c \
+ twin-antialias-mixed.c \
+ twin-antialias-none.c \
+ twin-antialias-subpixel.c \
+ unaligned-box.c \
+ unantialiased-shapes.c \
+ unbounded-operator.c \
+ unclosed-strokes.c \
+ user-data.c \
+ user-font.c \
+ user-font-mask.c \
+ user-font-proxy.c \
+ user-font-rescale.c \
+ world-map.c \
+ white-in-noop.c \
+ xcb-huge-image-shm.c \
+ xcb-huge-subimage.c \
+ xcb-stress-cache.c \
+ xcb-snapshot-assert.c \
+ xcomposite-projection.c \
+ xlib-expose-event.c \
+ zero-alpha.c \
+ zero-mask.c
+
+pthread_test_sources = \
+ pthread-same-source.c \
+ pthread-show-text.c \
+ pthread-similar.c \
+ $(NULL)
+
+ft_font_test_sources = \
+ bitmap-font.c \
+ ft-font-create-for-ft-face.c \
+ ft-show-glyphs-positioning.c \
+ ft-show-glyphs-table.c \
+ ft-text-vertical-layout-type1.c \
+ ft-text-vertical-layout-type3.c \
+ ft-text-antialias-none.c
+
+egl_surface_test_sources = \
+ egl-oversized-surface.c \
+ egl-surface-source.c
+
+quartz_surface_test_sources = quartz-surface-source.c
+
+pdf_surface_test_sources = \
+ pdf-features.c \
+ pdf-mime-data.c \
+ pdf-surface-source.c
+
+ps_surface_test_sources = \
+ ps-eps.c \
+ ps-features.c \
+ ps-surface-source.c
+
+svg_surface_test_sources = \
+ svg-surface.c \
+ svg-clip.c \
+ svg-surface-source.c
+
+xcb_surface_test_sources = \
+ xcb-surface-source.c
+
+xlib_surface_test_sources = \
+ xlib-surface.c \
+ xlib-surface-source.c
+
+xlib_xrender_surface_test_sources = get-xrender-format.c
+
+multi_page_surface_test_sources = multi-page.c
+
+fallback_resolution_test_sources = fallback-resolution.c
+
+cairo_test_suite_headers = \
+ buffer-diff.h \
+ cairo-test.h \
+ cairo-test-private.h \
+ world-map.h \
+ $(NULL)
+
+cairo_test_suite_sources = \
+ buffer-diff.c \
+ cairo-test.c \
+ cairo-test-runner.c
diff --git a/test/Makefile.win32 b/test/Makefile.win32
new file mode 100644
index 000000000..ba8ea5b86
--- /dev/null
+++ b/test/Makefile.win32
@@ -0,0 +1,55 @@
+top_srcdir = ..
+include $(top_srcdir)/build/Makefile.win32.common
+include $(top_srcdir)/test/Makefile.sources
+
+CFLAGS += \
+ -I$(top_srcdir)/boilerplate \
+ -I$(top_srcdir)/util/cairo-script/ \
+ -I./pdiff \
+ $(NULL)
+
+TEST_LIBS = \
+ ./pdiff/$(CFG)/pdiff.lib \
+ $(top_builddir)/boilerplate/$(CFG)/boiler.lib \
+ $(top_builddir)/src/$(CFG)/cairo-static.lib \
+ $(NULL)
+
+all: inform $(CFG)/cairo-test-suite.exe
+
+cairo-test-constructors.c: Makefile.sources Makefile.win32 $(test_sources) make-cairo-test-constructors.sh
+ sh ./make-cairo-test-constructors.sh $(test_sources) > $@
+
+SOURCES = $(cairo_test_suite_sources) $(test_sources) cairo-test-constructors.c
+
+OBJECTS = $(patsubst %.c, $(CFG)/%-static.obj, $(SOURCES))
+
+ANY2PPM_OBJS = \
+ $(CFG)/any2ppm-static.obj \
+ $(top_builddir)/util/cairo-script/$(CFG)/libcairo-script-interpreter.lib \
+ $(top_builddir)/src/$(CFG)/cairo-static.lib \
+ $(NULL)
+
+$(CFG)/cairo-test-suite.exe: $(OBJECTS) $(TEST_LIBS)
+ @$(LD) $(CAIRO_LDFLAGS) -OUT:$@ $(OBJECTS) $(TEST_LIBS) $(CAIRO_LIBS)
+
+$(CFG)/any2ppm.exe: $(ANY2PPM_OBJS)
+ $(LD) $(CAIRO_LDFLAGS) -OUT:$@ $^ $(CAIRO_LIBS)
+
+./pdiff/$(CFG)/pdiff.lib:
+ $(MAKE) -C pdiff -f Makefile.win32
+
+$(top_builddir)/src/$(CFG)/cairo-static.lib:
+ $(MAKE) -C $(top_srcdir)/src -f Makefile.win32
+
+$(top_builddir)/boilerplate/$(CFG)/boiler.lib:
+ $(MAKE) -C $(top_srcdir)/boilerplate -f Makefile.win32
+
+$(top_builddir)/util/cairo-script/$(CFG)/libcairo-script-interpreter.lib:
+ $(MAKE) -C $(top_srcdir)/util/cairo-script -f Makefile.win32
+
+.PHONY: check test
+
+check: inform $(CFG)/any2ppm.exe $(CFG)/cairo-test-suite.exe
+ @ANY2PPM=$(CFG)\\any2ppm.exe $(CFG)/cairo-test-suite.exe
+
+test: inform check
diff --git a/test/README b/test/README
new file mode 100644
index 000000000..f1433944b
--- /dev/null
+++ b/test/README
@@ -0,0 +1,319 @@
+Regression test suite for cairo.
+
+How to use cairo's test suite
+=============================
+Using this test should be as simple as running:
+
+ make test
+
+assuming that the cairo distribution in the directory above has been
+configured and built. The test suite here goes through some effort to
+run against the locally compiled library rather than any installed
+version, but those efforts may fall short depending on the level of your
+libtool madness.
+
+The results of the test suite run are summarized in an index.html
+file, which, when viewed in a web browser makes it quite easy to
+visually see any failed renderings alongside the corresponding
+reference image, (and a diff image as well).
+
+The test suite needs to be run before any code is committed and before
+any release. See below for hints and rules governing the use of the suite.
+
+The test suite is built as a single binary, which allows you to choose
+individual or categories of tests to run. For example, if you want to
+run all text related tests you can use:
+ ./cairo-test-suite text
+Or if you want to check the current status of known failures:
+ ./cairo-test-suite XFAIL
+Or to run a subset of tests, use the -k option to run only the tests
+that include the given keyword:
+ ./cairo-test-suite -k downscale
+The binary also permits controlling which backend is used via the
+CAIRO_TEST_TARGET environment variable, so for instance:
+ CAIRO_TEST_TARGET=gl ./cairo-test-suite -k blur
+This binary should be backwards-compatible with all library versions,
+allowing you to compare current versus past behaviour for any test.
+
+Tailoring tests running
+-----------------------
+There are some mechanisms to limit the tests run during "make test".
+These come very handy when doing development, but should not be used
+to circumvent the "pass" requirements listed below.
+
+make's TARGETS environment variable can be used to limit the backends when
+running the tests. It should contain a (space-, comma-separated) list of
+backends. CAIRO_TESTS environment variable, which is a comma-, space-seperated
+lists, can be used to limit the tests run.
+For example:
+
+ CAIRO_TESTS="zero-alpha" make test TARGETS=image,ps
+
+make's FORMAT variable can also be used to limit the content formats when
+running the tests. It should contain a (space-, comma-separated) list of
+content formats to test.
+For example:
+
+ CAIRO_TESTS="zero-alpha" make test TARGETS=image,ps FORMAT="rgb,rgba"
+
+Another very handy mechanism when trying to fix bugs is:
+
+ make retest
+
+This will re-run the test suite, but only on tests that failed on the
+last run. So this is a much faster way of checking if changes actually
+fix bugs rather than running the entire test suite again.
+
+The test suite first compares the output from the current run against the
+previous in order to skip more expensive image comparisons . If you think
+this is interfering with the results, you can clear the cached results using:
+
+ make clean-caches
+
+Running tests under modified environments or tools
+-------------------------------------------------
+To run tests under a tool like gdb, one can use the run target and
+the TOOL variable. For example:
+
+ CAIRO_TESTS=user-font make run TOOL=gdb TARGETS=pdf
+
+If you want to run under valgrind, there is a specific target for that
+that also sets a bunch of useful valgrind options. Try:
+
+ CAIRO_TESTS=user-font make check-valgrind
+
+You can run tests under a modified environment you can use the ENV
+make variable. However, that environment will also affect the libtool
+wrapper of the tests. To only affect the actual test binaries, pass
+such environment as TOOL:
+
+ CAIRO_TESTS=user-font make run TOOL="LD_PRELOAD=/path/to/something.so"
+
+Getting the elusive zero failures
+---------------------------------
+It's generally been very difficult to achieve a test run with zero
+failures. The difficulties stem from the various versions of the many
+libraries that the test suite depends on, (it depends on a lot more
+than cairo itself), as well as fonts and other system-specific
+settings. If your system differs significantly from the system on
+which the reference images were generated, then you will likely see
+the test suite reporting "failures", (even if cairo is working just
+fine).
+
+We are constantly working to reduce the number of variables that need
+to be tweaked to get a clean run, (for example, by bundling fonts with
+the test suite itself), and also working to more carefully document
+the software configuration used to generate the reference images.
+
+Here are some of the relevant details:
+
+ * Your system must have a copy of the DejaVu font, the sha1sum of
+ the version used are listed in [...]. These are
+ "DejaVu Sans" (DejaVuSans.ttf) [1cd336329f45f241002ded61893d91e3acd04436];
+ "DejaVu Sans Mono" (DejaVuSansMono.ttf) [0458c0f0fb57f3eb8ced62f26fe7c5ed4e6a9a68];
+ "DejaVu Serif" (DejaVuSerif.ttf) [93502d0d0445d1fe1c9f51e51b3e0169266346ce];
+ [the DejaVu fonts can be installed from the ttf-dejavu 2.33-2 Debian package]
+ and also
+ "Nimbus Sans L" (n019003l.pfb)
+ [which can be found in the gsfonts Debian package].
+
+ * Currently, you must be using a build of cairo using freetype
+ (cairo-ft) as the default font backend. Otherwise all tests
+ involving text are likely to fail.
+
+ * To test the pdf backend, you will want the very latest version of
+ poppler as made available via git:
+
+ git clone git://anongit.freedesktop.org/git/poppler/poppler
+
+ As of this writing, no released version of poppler contains all
+ the fixes you will need to avoid false negatives from the test
+ suite.
+
+ * To test the ps backend, you will need ghostscript version 9.04.
+
+ * Testing the xlib backend is problematic since many X server
+ drivers have bugs that are exercised by the test suite. (Or, if
+ not actual bugs, differ slightly in their output in such a way
+ that the test suite will report errors.) This can be quite handy
+ if you want to debug an X server driver, but since most people
+ don't want to do that, another option is to run against a headless
+ X server that uses only software for all rendering. One such X
+ server is Xvfb which can be started like this:
+
+ Xvfb -screen 0 1680x1024x24 -ac -nolisten tcp :2
+
+ after which the test suite can be run against it like so:
+
+ DISPLAY=:2 make test
+
+ We have been using Xvfb for testing cairo releases and ensuring
+ that all tests behave as expected with this X server.
+
+What if I can't make my system match?
+-------------------------------------
+For one reason or another, you may be unable to get a clean run of the
+test suite even if cairo is working properly, (for example, you might
+be on a system without freetype). In this case, it's still useful to
+be able to determine if code changes you make to cairo result in any
+regressions to the test suite. But it's hard to notice regressions if
+there are many failures both before and after your changes.
+
+For this scenario, you can capture the output of a run of the test
+suite before your changes, and then use the CAIRO_REF_DIR environment
+variable to use that output as the reference images for a run after
+your changes. The process looks like this:
+
+ # Before code change there may be failures we don't care about
+ make test
+
+ # Let's save those output images
+ mkdir /some/directory/
+ cp -r test/output /some/directory/
+
+ # hack, hack, hack
+
+ # Now to see if nothing changed:
+ CAIRO_REF_DIR=/some/directory/ make test
+
+Best practices for cairo developers
+===================================
+If we all follow the guidelines below, then both the test suite and
+cairo itself will stay much healthier, and we'll all have a lot more
+fun hacking on cairo.
+
+Before committing
+-----------------
+All tests should return a result of PASS or XFAIL. The XFAIL results
+indicate known bugs. The final message should be one of the following:
+
+ All XX tests behaved as expected (YY expected failures)
+ All XX tests passed
+
+If any tests have a status of FAIL, then the new code has caused a
+regression error which should be fixed before the code is committed.
+
+When a new bug is found
+-----------------------
+A new test case should be added by imitating the style of an existing
+test. This means adding the following files:
+
+ new-bug.c
+ reference/new-bug.ref.png
+ reference/new-bug.xfail.png
+
+Where new-bug.c is a minimal program to demonstrate the bug, following
+the style of existing tests. The new-bug.ref.png image should contain
+the desired result of new-bug.c if the bug were fixed while
+new-bug.xfail.png contains the current results of the test.
+
+Makefile.sources should be edited by adding new-bug.c to test_sources.
+And last but not least, don't forget to "git add" the new files.
+
+When a new feature is added
+---------------------------
+It's important for the regression suite to keep pace with development
+of the library. So a new test should be added for each new feature.
+The work involved is similar the work described above for new bugs.
+The only distinction is that the test is expected to pass so it
+should not need a new-bug.xfail.png file.
+
+While working on a test
+-----------------------
+Before a bugfix or feature is ready, it may be useful to compare
+output from different builds. For convenience, you can set
+CAIRO_REF_DIR to point at a previous test directory, relative
+to the current test directory, and any previous output will be
+used by preference as reference images.
+
+When a bug is fixed
+-------------------
+The fix should be verified by running the test suite which should
+result in an "unexpected pass" for the test of interest. Rejoice as
+appropriate, then remove the relevant xfail.png file from git.
+
+Before releasing
+----------------
+All tests should return a result of PASS for all supported (those enabled by
+default) backends, meaning all known bugs are fixed, resulting in the happy
+message:
+
+ All XX tests passed
+
+Some notes on limitations in poppler
+====================================
+One of the difficulties of our current test infrastructure is that we
+rely on external tools to convert cairo's vector output (PDF,
+PostScript, and SVG), into an image that can be used for the image
+comparison. This means that any bugs in that conversion tool will
+result in false negatives in the test suite.
+
+We've identified several such bugs in the poppler library which is
+used to convert PDF to an image. This is particularly discouraging
+because 1) poppler is free software that will be used by *many* cairo
+users, and 2) poppler calls into cairo for its rendering so it should
+be able to do a 100% faithful conversion.
+
+So we have an interest in ensuring that these poppler bugs get fixed
+sooner rather than later. As such, we're trying to be good citizens by
+reporting all such poppler bugs that we identify to the poppler
+bugzilla. Here's a tracking bug explaining the situation:
+
+ Poppler does not yet handle everything in the cairo test suite
+ https://bugs.freedesktop.org/show_bug.cgi?id=12143
+
+Here's the rule: If a cairo-pdf test reports a failure, but viewing
+the resulting PDF file with acroread suggests that the PDF itself is
+correct, then there's likely a bug in poppler. In this case, we can
+simply report the poppler bug, (making it block 12143 above), post the
+PDF result from the test suite, and list the bug in this file. Once
+we've done this, we can capture poppler's buggy output as a
+pdf-specific reference image (as reference/*.xfail.png) so that the
+test suite will regard the test as passing, (and we'll ensure there
+is no regression).
+
+Once the poppler bug gets fixed, the test suite will start reporting a
+false negative again, and this will be easy to fix by simply removing
+the pdf-specific reference image.
+
+Here are the reported poppler bugs and the tests they affect:
+
+Poppler doesn't correctly handle gradients with transparency
+https://bugs.freedesktop.org/show_bug.cgi?id=12144
+--------------------------------------------------
+fill-alpha-pattern
+gradient-alpha
+gradient-constant-alpha
+linear-gradient
+linear-gradient-reflect
+radial-gradient
+trap-clip
+
+Poppler should paint images with CAIRO_EXTEND_PAD
+https://bugs.freedesktop.org/show_bug.cgi?id=14578
+--------------------------------------------------
+paint-source-alpha
+paint-with-alpha
+rotate-image-surface-paint
+scale-source-surface-paint
+
+Incorrect clipping of group object (regression?)
+https://bugs.freedesktop.org/show_bug.cgi?id=14580
+--------------------------------------------------
+push-group
+
+spurious horizontal stripes in color gradients
+https://bugs.freedesktop.org/show_bug.cgi?id=10942
+--------------------------------------------------
+smask
+smask-fill
+smask-image-mask
+smask-mask
+smask-paint
+smask-stroke
+smask-text
+
+Ghostscript does not correctly render small miters
+http://bugs.ghostscript.com/show_bug.cgi?id=690098
+--------------------------------------------------
+miter-precision
diff --git a/test/a1-bug.c b/test/a1-bug.c
new file mode 100644
index 000000000..8e00d40e3
--- /dev/null
+++ b/test/a1-bug.c
@@ -0,0 +1,61 @@
+/*
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include "cairo-test.h"
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ static const struct point {
+ double x;
+ double y;
+ } xy[] = {
+ { 627.016212, 221.749777 },
+ { 756.120787, 221.749777 },
+ { 756.120787, 557.602766 },
+ { 626.952721, 557.602766 },
+ { 626.548456, 493.315729 },
+ };
+ unsigned int i;
+
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ cairo_paint (cr);
+
+ for (i = 0; i < ARRAY_LENGTH (xy); i++)
+ cairo_line_to (cr, xy[i].x, xy[i].y);
+
+ cairo_set_source_rgb (cr, 1, 0, 0);
+ cairo_fill_preserve (cr);
+
+ cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE);
+ cairo_set_source_rgb (cr, 0, 1, 0);
+ cairo_fill (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (a1_bug,
+ "Check the fidelity of the rasterisation.",
+ "a1, raster", /* keywords */
+ "target=raster", /* requirements */
+ 1000, 800,
+ NULL, draw)
diff --git a/test/a1-clip.c b/test/a1-clip.c
new file mode 100644
index 000000000..0e84cd39b
--- /dev/null
+++ b/test/a1-clip.c
@@ -0,0 +1,175 @@
+/*
+ * Copyright © 2008 Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+#include "cairo-test.h"
+
+#define POINTS 10
+#define STEP (1.0 / POINTS)
+#define PAD 1
+#define WIDTH (PAD + POINTS * 2 + PAD)
+#define HEIGHT (WIDTH)
+
+static cairo_test_status_t
+paint (cairo_t *cr, int width, int height)
+{
+ int i, j;
+
+ /* Fill background white */
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+ /* Draw in black */
+ cairo_set_source_rgb (cr, 0, 0, 0);
+
+ cairo_translate (cr, PAD, PAD);
+ cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE);
+
+ for (i = 0; i < POINTS; i++)
+ for (j = 0; j < POINTS; j++) {
+ cairo_save (cr);
+ cairo_rectangle (cr, 2 * i + i * STEP, 2 * j + j * STEP, 1, 1);
+ cairo_clip (cr);
+ cairo_paint (cr);
+ cairo_restore (cr);
+ }
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+fill_equal (cairo_t *cr, int width, int height)
+{
+ int i, j;
+
+ /* Fill background white */
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+ /* Draw in black */
+ cairo_set_source_rgb (cr, 0, 0, 0);
+
+ cairo_translate (cr, PAD, PAD);
+ cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE);
+
+ for (i = 0; i < POINTS; i++)
+ for (j = 0; j < POINTS; j++) {
+ cairo_save (cr);
+ cairo_rectangle (cr, 2 * i + i * STEP, 2 * j + j * STEP, 1, 1);
+ cairo_clip_preserve (cr);
+ cairo_fill (cr);
+ cairo_restore (cr);
+ }
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+fill (cairo_t *cr, int width, int height)
+{
+ int i, j;
+
+ /* Fill background white */
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+ /* Draw in black */
+ cairo_set_source_rgb (cr, 0, 0, 0);
+
+ cairo_translate (cr, PAD, PAD);
+ cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE);
+
+ for (i = 0; i < POINTS; i++)
+ for (j = 0; j < POINTS; j++) {
+ cairo_save (cr);
+ cairo_rectangle (cr, 2 * i + i * STEP, 2 * j + j * STEP, 1, 1);
+ cairo_clip (cr);
+ cairo_rectangle (cr, 2 * i, 2 * j, 2, 2);
+ cairo_fill (cr);
+ cairo_restore (cr);
+ }
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+stroke (cairo_t *cr, int width, int height)
+{
+ int i, j;
+
+ /* Fill background white */
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+ /* Draw in black */
+ cairo_set_source_rgb (cr, 0, 0, 0);
+
+ cairo_translate (cr, PAD, PAD);
+ cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE);
+
+ cairo_set_line_width (cr, 2);
+ cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT);
+
+ for (i = 0; i < POINTS; i++)
+ for (j = 0; j < POINTS; j++) {
+ cairo_save (cr);
+ cairo_rectangle (cr, 2 * i + i * STEP, 2 * j + j * STEP, 1, 1);
+ cairo_clip (cr);
+ cairo_move_to (cr, 2 * i, 2 * j + 1);
+ cairo_line_to (cr, 2 * i + 2, 2 * j + 1);
+ cairo_stroke (cr);
+ cairo_restore (cr);
+ }
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (a1_clip_paint,
+ "Test sample position when drawing trapezoids with ANTIALIAS_NONE",
+ "alpha, clip", /* keywords */
+ "target=raster", /* requirements */
+ WIDTH, HEIGHT,
+ NULL, paint)
+
+CAIRO_TEST (a1_clip_fill,
+ "Test sample position when drawing trapezoids with ANTIALIAS_NONE",
+ "alpha, clip", /* keywords */
+ "target=raster", /* requirements */
+ WIDTH, HEIGHT,
+ NULL, fill)
+
+CAIRO_TEST (a1_clip_fill_equal,
+ "Test sample position when drawing trapezoids with ANTIALIAS_NONE",
+ "alpha, clip", /* keywords */
+ "target=raster", /* requirements */
+ WIDTH, HEIGHT,
+ NULL, fill_equal)
+
+CAIRO_TEST (a1_clip_stroke,
+ "Test sample position when drawing trapezoids with ANTIALIAS_NONE",
+ "alpha, clip", /* keywords */
+ "target=raster", /* requirements */
+ WIDTH, HEIGHT,
+ NULL, stroke)
diff --git a/test/a1-fill.c b/test/a1-fill.c
new file mode 100644
index 000000000..8c8b8c8ae
--- /dev/null
+++ b/test/a1-fill.c
@@ -0,0 +1,67 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+/* Exercise https://bugs.freedesktop.org/show_bug.cgi?id=31604 */
+
+#include "cairo-test.h"
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_surface_t *a1;
+ cairo_t *cr2;
+
+ a1 = cairo_image_surface_create (CAIRO_FORMAT_A1, 100, 100);
+ cr2 = cairo_create (a1);
+ cairo_surface_destroy (a1);
+
+ cairo_set_operator (cr2, CAIRO_OPERATOR_SOURCE);
+ cairo_rectangle (cr2, 10, 10, 80, 80);
+ cairo_set_source_rgb (cr2, 1, 1, 1);
+ cairo_fill (cr2);
+ cairo_rectangle (cr2, 20, 20, 60, 60);
+ cairo_set_source_rgb (cr2, 0, 0, 0);
+ cairo_fill (cr2);
+
+ a1 = cairo_surface_reference (cairo_get_target (cr2));
+ cairo_destroy (cr2);
+
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+ cairo_set_source_rgb (cr, 1, 0, 0);
+ cairo_mask_surface (cr, a1, 0, 0);
+ cairo_surface_destroy (a1);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (a1_fill,
+ "Test filling of an a1-surface and use as mask",
+ "a1, alpha, fill, mask", /* keywords */
+ "target=raster", /* requirements */
+ 100, 100,
+ NULL, draw)
diff --git a/test/a1-image-sample.c b/test/a1-image-sample.c
new file mode 100644
index 000000000..3c349af81
--- /dev/null
+++ b/test/a1-image-sample.c
@@ -0,0 +1,73 @@
+/*
+ * Copyright © 2008 Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+#include "cairo-test.h"
+
+#define POINTS 10
+#define STEP (1.0 / POINTS)
+#define PAD 1
+#define WIDTH (PAD + POINTS * 2 + PAD)
+#define HEIGHT (WIDTH)
+
+/* A single, black pixel */
+static const uint32_t black_pixel = 0xff000000;
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ int i, j;
+ cairo_surface_t *surface;
+
+ surface = cairo_image_surface_create_for_data ((unsigned char *) &black_pixel,
+ CAIRO_FORMAT_ARGB32,
+ 1, 1, 4);
+
+ /* Fill background white */
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+ cairo_translate (cr, PAD, PAD);
+
+ for (i = 0; i < POINTS; i++)
+ for (j = 0; j < POINTS; j++) {
+ cairo_set_source_surface (cr, surface,
+ 2 * i + i * STEP, 2 * j + j * STEP);
+ cairo_pattern_set_filter (cairo_get_source (cr),
+ CAIRO_FILTER_NEAREST);
+ cairo_paint (cr);
+ }
+
+ cairo_surface_destroy (surface);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (a1_image_sample,
+ "Test sample position when drawing images with FILTER_NEAREST",
+ "image, alpha", /* keywords */
+ "target=raster", /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw)
diff --git a/test/a1-mask-sample.c b/test/a1-mask-sample.c
new file mode 100644
index 000000000..4214e8f40
--- /dev/null
+++ b/test/a1-mask-sample.c
@@ -0,0 +1,83 @@
+/*
+ * Copyright © 2008 Red Hat, Inc.
+ * Copyright © 2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ * Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+#define POINTS 10
+#define STEP (1.0 / POINTS)
+#define PAD 1
+#define WIDTH (PAD + POINTS * 2 + PAD)
+#define HEIGHT (WIDTH)
+
+/* A single, opaque pixel */
+static const uint32_t black_pixel = 0xffffffff;
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_surface_t *surface;
+ cairo_pattern_t *mask;
+ int i, j;
+
+ surface = cairo_image_surface_create_for_data ((unsigned char *) &black_pixel,
+ CAIRO_FORMAT_A8,
+ 1, 1, 4);
+ mask = cairo_pattern_create_for_surface (surface);
+ cairo_pattern_set_filter (mask, CAIRO_FILTER_NEAREST);
+ cairo_surface_destroy (surface);
+
+ /* Fill background white */
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+ cairo_translate (cr, PAD, PAD);
+
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ for (i = 0; i < POINTS; i++) {
+ for (j = 0; j < POINTS; j++) {
+ cairo_matrix_t m;
+
+ cairo_matrix_init_translate (&m,
+ -(2 * i + i * STEP),
+ -(2 * j + j * STEP));
+ cairo_pattern_set_matrix (mask, &m);
+ cairo_mask (cr, mask);
+ }
+ }
+
+ cairo_pattern_destroy (mask);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (a1_mask_sample,
+ "Test sample position when masking with FILTER_NEAREST",
+ "image, alpha", /* keywords */
+ "target=raster", /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw)
diff --git a/test/a1-mask.c b/test/a1-mask.c
new file mode 100644
index 000000000..c52aa9dd9
--- /dev/null
+++ b/test/a1-mask.c
@@ -0,0 +1,202 @@
+/*
+ * Copyright © Jeff Muizelaar
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * JEFF MUIZELAAR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Jeff Muizelaar <jeff@infidigm.net>
+ * Carl Worth <cworth@cworth.org>
+ * Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+#define MASK_WIDTH 10
+#define MASK_HEIGHT 8
+
+#ifdef WORDS_BIGENDIAN
+#define MASK 0x28, 0x55
+#else
+#define MASK 0x14, 0xAA
+#endif
+static unsigned char mask[(MASK_WIDTH + 7) / 8 * MASK_HEIGHT] = {
+ MASK,
+ MASK,
+ MASK,
+ MASK,
+ MASK,
+ MASK,
+ MASK,
+ MASK,
+};
+
+static cairo_test_status_t
+check_status (const cairo_test_context_t *ctx,
+ cairo_status_t status,
+ cairo_status_t expected)
+{
+ if (status == expected)
+ return CAIRO_TEST_SUCCESS;
+
+ cairo_test_log (ctx,
+ "Error: Expected status value %d (%s), received %d (%s)\n",
+ expected,
+ cairo_status_to_string (expected),
+ status,
+ cairo_status_to_string (status));
+ return CAIRO_TEST_FAILURE;
+}
+
+static cairo_test_status_t
+test_surface_with_width_and_stride (const cairo_test_context_t *ctx,
+ int width, int stride,
+ cairo_status_t expected)
+{
+ cairo_test_status_t status;
+ cairo_surface_t *surface;
+ cairo_t *cr;
+ int len;
+ unsigned char *data;
+
+ cairo_test_log (ctx,
+ "Creating surface with width %d and stride %d\n",
+ width, stride);
+
+ len = stride;
+ if (len < 0)
+ len = -len;
+ data = xmalloc (len);
+
+ surface = cairo_image_surface_create_for_data (data, CAIRO_FORMAT_A1,
+ width, 1, stride);
+ cr = cairo_create (surface);
+
+ cairo_paint (cr);
+
+ status = check_status (ctx, cairo_surface_status (surface), expected);
+ if (status)
+ goto BAIL;
+
+ status = check_status (ctx, cairo_status (cr), expected);
+ if (status)
+ goto BAIL;
+
+ BAIL:
+ cairo_destroy (cr);
+ cairo_surface_destroy (surface);
+ free (data);
+ return status;
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int dst_width, int dst_height)
+{
+ unsigned char *mask_aligned;
+ cairo_surface_t *surface;
+
+ surface = cairo_image_surface_create (CAIRO_FORMAT_A1,
+ MASK_WIDTH,
+ MASK_HEIGHT);
+
+ mask_aligned = cairo_image_surface_get_data (surface);
+ if (mask_aligned != NULL) {
+ int stride = cairo_image_surface_get_stride (surface), row;
+ const unsigned char *src = mask;
+ unsigned char *dst = mask_aligned;
+ for (row = 0; row < MASK_HEIGHT; row++) {
+ memcpy (dst, src, (MASK_WIDTH + 7) / 8);
+ src += (MASK_WIDTH + 7) / 8;
+ dst += stride;
+ }
+ }
+ cairo_surface_mark_dirty (surface);
+
+ /* Paint background blue */
+ cairo_set_source_rgb (cr, 0, 0, 1); /* blue */
+ cairo_paint (cr);
+
+ /* Then paint red through our mask */
+ cairo_set_source_rgb (cr, 1, 0, 0); /* red */
+ cairo_mask_surface (cr, surface, 0, 0);
+ cairo_surface_destroy (surface);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+preamble (cairo_test_context_t *ctx)
+{
+ cairo_test_status_t status = CAIRO_TEST_SUCCESS;
+ int test_width;
+
+ /* first check the API strictness */
+ for (test_width = 0; test_width < 40; test_width++) {
+ int test_stride = (test_width + 7) / 8;
+ int stride = cairo_format_stride_for_width (CAIRO_FORMAT_A1,
+ test_width);
+ cairo_status_t expected;
+
+ /* First create a surface using the width as the stride,
+ * (most of these should fail).
+ */
+ expected = (stride == test_stride) ?
+ CAIRO_STATUS_SUCCESS : CAIRO_STATUS_INVALID_STRIDE;
+
+ status = test_surface_with_width_and_stride (ctx,
+ test_width,
+ test_stride,
+ expected);
+ if (status)
+ return status;
+
+ status = test_surface_with_width_and_stride (ctx,
+ test_width,
+ -test_stride,
+ expected);
+ if (status)
+ return status;
+
+
+ /* Then create a surface using the correct stride,
+ * (should always succeed).
+ */
+ status = test_surface_with_width_and_stride (ctx,
+ test_width,
+ stride,
+ CAIRO_STATUS_SUCCESS);
+ if (status)
+ return status;
+
+ status = test_surface_with_width_and_stride (ctx,
+ test_width,
+ -stride,
+ CAIRO_STATUS_SUCCESS);
+ if (status)
+ return status;
+ }
+
+ return status;
+}
+
+CAIRO_TEST (a1_mask,
+ "test masks of CAIRO_FORMAT_A1",
+ "alpha, mask", /* keywords */
+ NULL, /* requirements */
+ MASK_WIDTH, MASK_HEIGHT,
+ preamble, draw)
diff --git a/test/a1-rasterisation.c b/test/a1-rasterisation.c
new file mode 100644
index 000000000..b59090ab5
--- /dev/null
+++ b/test/a1-rasterisation.c
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+/*
+ * Test the fidelity of the rasterisation, paying careful attention to rounding.
+ */
+
+#include "../src/cairo-fixed-type-private.h"
+#define PRECISION (int)(1 << CAIRO_FIXED_FRAC_BITS)
+
+#define WIDTH ((PRECISION/2+1)*3)
+#define HEIGHT ((PRECISION/2+1)*3)
+
+#define SUBPIXEL(v) ((v)/(double)(PRECISION/2))
+
+static cairo_test_status_t
+rectangles (cairo_t *cr, int width, int height)
+{
+ int x, y;
+
+ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
+ cairo_paint (cr);
+
+ cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
+ cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE);
+
+ for (x = 0; x < WIDTH; x += 3) {
+ for (y = 0; y < HEIGHT; y += 3) {
+ cairo_rectangle (cr, x + SUBPIXEL (y/3) - .5, y + SUBPIXEL (x/3) - .5, .5, .5);
+ }
+ }
+ cairo_fill (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+triangles (cairo_t *cr, int width, int height)
+{
+ int x, y;
+
+ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
+ cairo_paint (cr);
+
+ cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
+ cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE);
+
+ for (x = 0; x < WIDTH; x += 3) {
+ for (y = 0; y < HEIGHT; y += 3) {
+ /* a rectangle with a diagonal to force tessellation */
+ cairo_move_to (cr, x + SUBPIXEL (y/3) - .5, y + SUBPIXEL (x/3) - .5);
+ cairo_rel_line_to (cr, .5, .5);
+ cairo_rel_line_to (cr, 0, -.5);
+ cairo_rel_line_to (cr, -.5, 0);
+ cairo_rel_line_to (cr, 0, .5);
+ cairo_rel_line_to (cr, .5, 0);
+ }
+ }
+ cairo_fill (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (a1_rasterisation_rectangles,
+ "Check the fidelity of the rasterisation.",
+ "rasterisation", /* keywords */
+ "target=raster", /* requirements */
+ WIDTH, HEIGHT,
+ NULL, rectangles)
+
+CAIRO_TEST (a1_rasterisation_triangles,
+ "Check the fidelity of the rasterisation.",
+ "rasterisation", /* keywords */
+ "target=raster", /* requirements */
+ WIDTH, HEIGHT,
+ NULL, triangles)
diff --git a/test/a1-sample.c b/test/a1-sample.c
new file mode 100644
index 000000000..977dfc832
--- /dev/null
+++ b/test/a1-sample.c
@@ -0,0 +1,59 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+#define WIDTH (256) //CAIRO_FIXED_ONE
+#define HEIGHT (WIDTH)
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ int i, j;
+
+ /* Fill background white */
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+ cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE);
+ cairo_set_source_rgb (cr, 0, 0, 0);
+
+ /* Only the single rectangle that covers the centre pixel should be filled*/
+ for (i = 0; i < 256; i++)
+ for (j = 0; j < 256; j++) {
+ cairo_rectangle (cr, i + i/256., j + j/256., 1/256., 1/256.);
+ cairo_fill (cr);
+ }
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (a1_sample,
+ "Tests unantialiased rendering of a quantum box",
+ " alpha", /* keywords */
+ "target=raster", /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw)
diff --git a/test/a1-traps-sample.c b/test/a1-traps-sample.c
new file mode 100644
index 000000000..5bb97bb4c
--- /dev/null
+++ b/test/a1-traps-sample.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright © 2008 Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+#include "cairo-test.h"
+
+#define POINTS 10
+#define STEP (1.0 / POINTS)
+#define PAD 1
+#define WIDTH (PAD + POINTS * 2 + PAD)
+#define HEIGHT (WIDTH)
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ int i, j;
+
+ /* Fill background white */
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+ /* Draw in black */
+ cairo_set_source_rgb (cr, 0, 0, 0);
+
+ cairo_translate (cr, PAD, PAD);
+ cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE);
+
+ for (i = 0; i < POINTS; i++)
+ for (j = 0; j < POINTS; j++) {
+ cairo_rectangle (cr, 2 * i + i * STEP, 2 * j + j * STEP, 1, 1);
+ cairo_fill (cr);
+ }
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (a1_traps_sample,
+ "Test sample position when drawing trapezoids with ANTIALIAS_NONE",
+ "alpha, traps", /* keywords */
+ "target=raster", /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw)
diff --git a/test/a8-clear.c b/test/a8-clear.c
new file mode 100644
index 000000000..1459f833e
--- /dev/null
+++ b/test/a8-clear.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright © 2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ *
+ * Based on a bug snippet by Jeremy Moles <jeremy@emperorlinux.com>
+ */
+
+#include "cairo-test.h"
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_pattern_t *mask;
+
+ cairo_set_source_rgb (cr, 1, 0, 0);
+ cairo_paint (cr);
+
+ cairo_push_group_with_content (cr, CAIRO_CONTENT_ALPHA);
+ {
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+ cairo_move_to (cr, 0, 0);
+ cairo_line_to (cr, width, height);
+ cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
+ cairo_set_line_width (cr, 10);
+ cairo_stroke (cr);
+ }
+ mask = cairo_pop_group (cr);
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_mask (cr, mask);
+ cairo_pattern_destroy (mask);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (a8_clear,
+ "Test clear on an a8 surface",
+ "a8, clear", /* keywords */
+ NULL, /* requirements */
+ 40, 40,
+ NULL, draw)
+
diff --git a/test/a8-mask.c b/test/a8-mask.c
new file mode 100644
index 000000000..ec708121e
--- /dev/null
+++ b/test/a8-mask.c
@@ -0,0 +1,201 @@
+/*
+ * Copyright © Jeff Muizelaar
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * JEFF MUIZELAAR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Jeff Muizelaar <jeff@infidigm.net>
+ * Carl Worth <cworth@cworth.org>
+ */
+
+#include "cairo-test.h"
+
+#define MASK_WIDTH 8
+#define MASK_HEIGHT 8
+
+static unsigned char mask[MASK_WIDTH * MASK_HEIGHT] = {
+ 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0x0, 0x0,
+};
+
+static cairo_test_status_t
+check_status (const cairo_test_context_t *ctx,
+ cairo_status_t status,
+ cairo_status_t expected)
+{
+ if (status == expected)
+ return CAIRO_TEST_SUCCESS;
+
+ cairo_test_log (ctx,
+ "Error: Expected status value %d (%s), received %d (%s)\n",
+ expected,
+ cairo_status_to_string (expected),
+ status,
+ cairo_status_to_string (status));
+ return CAIRO_TEST_FAILURE;
+}
+
+static cairo_test_status_t
+test_surface_with_width_and_stride (const cairo_test_context_t *ctx,
+ int width, int stride,
+ cairo_status_t expected)
+{
+ cairo_test_status_t status;
+ cairo_surface_t *surface;
+ cairo_t *cr;
+ int len;
+ unsigned char *data;
+
+ cairo_test_log (ctx,
+ "Creating surface with width %d and stride %d\n",
+ width, stride);
+
+ len = stride;
+ if (len < 0)
+ len = -len;
+ data = xmalloc (len);
+
+ surface = cairo_image_surface_create_for_data (data, CAIRO_FORMAT_A8,
+ width, 1, stride);
+ cr = cairo_create (surface);
+
+ cairo_paint (cr);
+
+ status = check_status (ctx, cairo_surface_status (surface), expected);
+ if (status)
+ goto BAIL;
+
+ status = check_status (ctx, cairo_status (cr), expected);
+ if (status)
+ goto BAIL;
+
+ BAIL:
+ cairo_destroy (cr);
+ cairo_surface_destroy (surface);
+ free (data);
+ return status;
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int dst_width, int dst_height)
+{
+ int stride, row;
+ unsigned char *src, *dst, *mask_aligned;
+ cairo_surface_t *surface;
+
+ /* Now test actually drawing through our mask data, allocating and
+ * copying with the proper stride. */
+ stride = cairo_format_stride_for_width (CAIRO_FORMAT_A8,
+ MASK_WIDTH);
+
+ mask_aligned = xmalloc (stride * MASK_HEIGHT);
+
+ src = mask;
+ dst = mask_aligned;
+ for (row = 0; row < MASK_HEIGHT; row++) {
+ memcpy (dst, src, MASK_WIDTH);
+ src += MASK_WIDTH;
+ dst += stride;
+ }
+
+ surface = cairo_image_surface_create_for_data (mask_aligned,
+ CAIRO_FORMAT_A8,
+ MASK_WIDTH,
+ MASK_HEIGHT,
+ stride);
+
+ /* Paint background blue */
+ cairo_set_source_rgb (cr, 0, 0, 1); /* blue */
+ cairo_paint (cr);
+
+ /* Then paint red through our mask */
+ cairo_set_source_rgb (cr, 1, 0, 0); /* red */
+ cairo_mask_surface (cr, surface, 0, 0);
+ cairo_surface_destroy (surface);
+
+ free (mask_aligned);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+preamble (cairo_test_context_t *ctx)
+{
+ cairo_test_status_t status = CAIRO_TEST_SUCCESS;
+ int test_width;
+
+ for (test_width = 0; test_width < 40; test_width++) {
+ int stride = cairo_format_stride_for_width (CAIRO_FORMAT_A8,
+ test_width);
+ cairo_status_t expected;
+
+ /* First create a surface using the width as the stride,
+ * (most of these should fail).
+ */
+ expected = (stride == test_width) ?
+ CAIRO_STATUS_SUCCESS : CAIRO_STATUS_INVALID_STRIDE;
+
+ status = test_surface_with_width_and_stride (ctx,
+ test_width,
+ test_width,
+ expected);
+ if (status)
+ return status;
+
+ status = test_surface_with_width_and_stride (ctx,
+ test_width,
+ -test_width,
+ expected);
+ if (status)
+ return status;
+
+
+ /* Then create a surface using the correct stride,
+ * (should always succeed).
+ */
+ status = test_surface_with_width_and_stride (ctx,
+ test_width,
+ stride,
+ CAIRO_STATUS_SUCCESS);
+ if (status)
+ return status;
+
+ status = test_surface_with_width_and_stride (ctx,
+ test_width,
+ -stride,
+ CAIRO_STATUS_SUCCESS);
+ if (status)
+ return status;
+ }
+
+ return status;
+}
+
+CAIRO_TEST (a8_mask,
+ "test masks of CAIRO_FORMAT_A8",
+ "alpha, mask", /* keywords */
+ NULL, /* requirements */
+ 8, 8,
+ preamble, draw)
diff --git a/test/aliasing.c b/test/aliasing.c
new file mode 100644
index 000000000..73c1f1ae2
--- /dev/null
+++ b/test/aliasing.c
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+/* A fun little test to explore color fringing in various experimental
+ * subpixel rasterisation techniques.
+ */
+
+#define WIDTH 60
+#define HEIGHT 40
+
+static const struct color {
+ double red, green, blue;
+} color[] = {
+ { 1, 1, 1 },
+ { 0, 0, 0 },
+ { 1, 0, 0 },
+ { 0, 1, 0 },
+ { 0, 0, 1 },
+ { 1, 1, 0 },
+ { 0, 1, 1 },
+ { 1, 0, 1 },
+ { .5, .5, .5 },
+};
+
+#define NUM_COLORS ARRAY_LENGTH (color)
+
+static void
+object (cairo_t *cr, const struct color *fg, const struct color *bg)
+{
+ cairo_set_source_rgb (cr, bg->red, bg->green, bg->blue);
+ cairo_rectangle (cr, 0, 0, WIDTH, HEIGHT);
+ cairo_fill (cr);
+
+ cairo_set_source_rgb (cr, fg->red, fg->green, fg->blue);
+ cairo_save (cr);
+ cairo_scale (cr, WIDTH, HEIGHT);
+ cairo_arc (cr, .5, .5, .5 - 4. / MAX (WIDTH, HEIGHT), 0, 2 * M_PI);
+ cairo_fill (cr);
+ cairo_arc (cr, .5, .5, .5 - 2. / MAX (WIDTH, HEIGHT), 0, 2 * M_PI);
+ cairo_restore (cr);
+ cairo_set_line_width (cr, 1.);
+ cairo_stroke (cr);
+
+ cairo_set_source_rgb (cr, bg->red, bg->green, bg->blue);
+ cairo_set_line_width (cr, 4.);
+ cairo_move_to (cr, 4, HEIGHT-4);
+ cairo_line_to (cr, WIDTH-12, 4);
+ cairo_move_to (cr, 12, HEIGHT-4);
+ cairo_line_to (cr, WIDTH-4, 4);
+ cairo_stroke (cr);
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ unsigned int i, j;
+
+ for (i = 0; i < NUM_COLORS; i++) {
+ for (j = 0; j < NUM_COLORS; j++) {
+ cairo_save (cr);
+ cairo_translate (cr, i * WIDTH, j * HEIGHT);
+ object (cr, &color[i], &color[j]);
+ cairo_restore (cr);
+ }
+ }
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (aliasing,
+ "Check for subpixel aliasing and color fringing",
+ "rasterisation", /* keywords */
+ "target=raster", /* requirements */
+ NUM_COLORS * WIDTH, NUM_COLORS * HEIGHT,
+ NULL, draw)
diff --git a/test/alpha-similar.c b/test/alpha-similar.c
new file mode 100644
index 000000000..86c6ae39d
--- /dev/null
+++ b/test/alpha-similar.c
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2008 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Chris Wilson not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Chris Wilson makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+static cairo_surface_t *
+create_source (cairo_surface_t *target, int width, int height)
+{
+ cairo_surface_t *similar;
+ cairo_t *cr;
+
+ similar = cairo_surface_create_similar (target,
+ CAIRO_CONTENT_ALPHA,
+ width, height);
+ cr = cairo_create (similar);
+ cairo_surface_destroy (similar);
+
+ cairo_set_source_rgba (cr, 1, 0, 0, .5);
+ cairo_paint (cr);
+
+ similar = cairo_surface_reference (cairo_get_target (cr));
+ cairo_destroy (cr);
+
+ return similar;
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_surface_t *source;
+
+ source = create_source (cairo_get_target (cr), width, height);
+ cairo_set_source_surface (cr, source, 0, 0);
+ cairo_surface_destroy (source);
+
+ cairo_paint (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+/*
+ * XFAIL: discrepancy between backends in applying color components of a pure
+ * alpha surface
+ */
+CAIRO_TEST (alpha_similar,
+ "Tests creation of similar alpha surfaces"
+ "\nApplication of a pure-alpha similar source is inconsistent across backends.",
+ "alpha, similar", /* keywords */
+ NULL, /* requirements */
+ 10, 10,
+ NULL, draw)
+
diff --git a/test/any2ppm.c b/test/any2ppm.c
new file mode 100644
index 000000000..b60b4d959
--- /dev/null
+++ b/test/any2ppm.c
@@ -0,0 +1,894 @@
+/*
+ * Copyright © 2008 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Chris Wilson not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Chris Wilson makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ *
+ * Contributor(s):
+ * Carlos Garcia Campos <carlosgc@gnome.org>
+ *
+ * Adapted from pdf2png.c:
+ * Copyright © 2005 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Kristian Høgsberg <krh@redhat.com>
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <cairo.h>
+#include <cairo-script-interpreter.h>
+
+#if CAIRO_CAN_TEST_PDF_SURFACE
+#include <poppler.h>
+#endif
+
+#if CAIRO_CAN_TEST_SVG_SURFACE
+#include <librsvg/rsvg.h>
+#ifndef RSVG_CAIRO_H
+#include <librsvg/rsvg-cairo.h>
+#endif
+#endif
+
+#if CAIRO_HAS_SPECTRE
+#include <libspectre/spectre.h>
+#endif
+
+#include <errno.h>
+
+#if HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
+#if HAVE_UNISTD_H && HAVE_SIGNAL_H && HAVE_SYS_STAT_H && HAVE_SYS_SOCKET_H && HAVE_SYS_POLL_H && HAVE_SYS_UN_H
+#include <signal.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <sys/poll.h>
+#include <sys/un.h>
+
+#define SOCKET_PATH "./.any2ppm"
+#define TIMEOUT 60000 /* 60 seconds */
+
+#if HAVE_FORK
+#define CAN_RUN_AS_DAEMON 1
+#endif
+#endif
+
+#define ARRAY_LENGTH(__array) ((int) (sizeof (__array) / sizeof (__array[0])))
+
+static int
+_cairo_writen (int fd, char *buf, int len)
+{
+ while (len) {
+ int ret;
+
+ ret = write (fd, buf, len);
+ if (ret == -1) {
+ int err = errno;
+ switch (err) {
+ case EINTR:
+ case EAGAIN:
+ continue;
+ default:
+ return 0;
+ }
+ }
+ len -= ret;
+ buf += ret;
+ }
+
+ return 1;
+}
+
+static int
+_cairo_write (int fd,
+ char *buf, int maxlen, int buflen,
+ const unsigned char *src, int srclen)
+{
+ if (buflen < 0)
+ return buflen;
+
+ while (srclen) {
+ int len;
+
+ len = buflen + srclen;
+ if (len > maxlen)
+ len = maxlen;
+ len -= buflen;
+
+ memcpy (buf + buflen, src, len);
+ buflen += len;
+ srclen -= len;
+ src += len;
+
+ if (buflen == maxlen) {
+ if (! _cairo_writen (fd, buf, buflen))
+ return -1;
+
+ buflen = 0;
+ }
+ }
+
+ return buflen;
+}
+
+static const char *
+write_ppm (cairo_surface_t *surface, int fd)
+{
+ char buf[4096];
+ cairo_format_t format;
+ const char *format_str;
+ const unsigned char *data;
+ int len;
+ int width, height, stride;
+ int i, j;
+
+ data = cairo_image_surface_get_data (surface);
+ height = cairo_image_surface_get_height (surface);
+ width = cairo_image_surface_get_width (surface);
+ stride = cairo_image_surface_get_stride (surface);
+ format = cairo_image_surface_get_format (surface);
+ if (format == CAIRO_FORMAT_ARGB32) {
+ /* see if we can convert to a standard ppm type and trim a few bytes */
+ const unsigned char *alpha = data;
+ for (j = height; j--; alpha += stride) {
+ for (i = 0; i < width; i++) {
+ if ((*(unsigned int *) (alpha+4*i) & 0xff000000) != 0xff000000)
+ goto done;
+ }
+ }
+ format = CAIRO_FORMAT_RGB24;
+ done: ;
+ }
+
+ switch (format) {
+ case CAIRO_FORMAT_ARGB32:
+ /* XXX need true alpha for svg */
+ format_str = "P7";
+ break;
+ case CAIRO_FORMAT_RGB24:
+ format_str = "P6";
+ break;
+ case CAIRO_FORMAT_A8:
+ format_str = "P5";
+ break;
+ case CAIRO_FORMAT_A1:
+ case CAIRO_FORMAT_RGB16_565:
+ case CAIRO_FORMAT_RGB30:
+ case CAIRO_FORMAT_INVALID:
+ default:
+ return "unhandled image format";
+ }
+
+ len = sprintf (buf, "%s %d %d 255\n", format_str, width, height);
+ for (j = 0; j < height; j++) {
+ const unsigned int *row = (unsigned int *) (data + stride * j);
+
+ switch ((int) format) {
+ case CAIRO_FORMAT_ARGB32:
+ len = _cairo_write (fd,
+ buf, sizeof (buf), len,
+ (unsigned char *) row, 4 * width);
+ break;
+ case CAIRO_FORMAT_RGB24:
+ for (i = 0; i < width; i++) {
+ unsigned char rgb[3];
+ unsigned int p = *row++;
+ rgb[0] = (p & 0xff0000) >> 16;
+ rgb[1] = (p & 0x00ff00) >> 8;
+ rgb[2] = (p & 0x0000ff) >> 0;
+ len = _cairo_write (fd,
+ buf, sizeof (buf), len,
+ rgb, 3);
+ }
+ break;
+ case CAIRO_FORMAT_A8:
+ len = _cairo_write (fd,
+ buf, sizeof (buf), len,
+ (unsigned char *) row, width);
+ break;
+ }
+ if (len < 0)
+ return "write failed";
+ }
+
+ if (len && ! _cairo_writen (fd, buf, len))
+ return "write failed";
+
+ return NULL;
+}
+
+static cairo_surface_t *
+_create_image (void *closure,
+ cairo_content_t content,
+ double width, double height,
+ long uid)
+{
+ cairo_surface_t **out = closure;
+ cairo_format_t format;
+ switch (content) {
+ case CAIRO_CONTENT_ALPHA:
+ format = CAIRO_FORMAT_A8;
+ break;
+ case CAIRO_CONTENT_COLOR:
+ format = CAIRO_FORMAT_RGB24;
+ break;
+ default:
+ case CAIRO_CONTENT_COLOR_ALPHA:
+ format = CAIRO_FORMAT_ARGB32;
+ break;
+ }
+ *out = cairo_image_surface_create (format, width, height);
+ return cairo_surface_reference (*out);
+}
+
+#if CAIRO_HAS_INTERPRETER
+static const char *
+_cairo_script_render_page (const char *filename,
+ cairo_surface_t **surface_out)
+{
+ cairo_script_interpreter_t *csi;
+ cairo_surface_t *surface = NULL;
+ cairo_status_t status;
+ const cairo_script_interpreter_hooks_t hooks = {
+ &surface,
+ _create_image,
+ NULL, /* surface_destroy */
+ NULL, /* context_create */
+ NULL, /* context_destroy */
+ NULL, /* show_page */
+ NULL /* copy_page */
+ };
+
+ csi = cairo_script_interpreter_create ();
+ cairo_script_interpreter_install_hooks (csi, &hooks);
+ status = cairo_script_interpreter_run (csi, filename);
+ if (status) {
+ cairo_surface_destroy (surface);
+ surface = NULL;
+ }
+ status = cairo_script_interpreter_destroy (csi);
+ if (surface == NULL)
+ return "cairo-script interpreter failed";
+
+ if (status == CAIRO_STATUS_SUCCESS)
+ status = cairo_surface_status (surface);
+ if (status) {
+ cairo_surface_destroy (surface);
+ return cairo_status_to_string (status);
+ }
+
+ *surface_out = surface;
+ return NULL;
+}
+
+static const char *
+cs_convert (char **argv, int fd)
+{
+ const char *err;
+ cairo_surface_t *surface = NULL; /* silence compiler warning */
+
+ err = _cairo_script_render_page (argv[0], &surface);
+ if (err != NULL)
+ return err;
+
+ err = write_ppm (surface, fd);
+ cairo_surface_destroy (surface);
+
+ return err;
+}
+#else
+static const char *
+cs_convert (char **argv, int fd)
+{
+ return "compiled without CairoScript support.";
+}
+#endif
+
+#if CAIRO_CAN_TEST_PDF_SURFACE
+/* adapted from pdf2png.c */
+static const char *
+_poppler_render_page (const char *filename,
+ const char *page_label,
+ cairo_surface_t **surface_out)
+{
+ PopplerDocument *document;
+ PopplerPage *page;
+ double width, height;
+ GError *error = NULL;
+ gchar *absolute, *uri;
+ cairo_surface_t *surface;
+ cairo_t *cr;
+ cairo_status_t status;
+
+ if (g_path_is_absolute (filename)) {
+ absolute = g_strdup (filename);
+ } else {
+ gchar *dir = g_get_current_dir ();
+ absolute = g_build_filename (dir, filename, (gchar *) 0);
+ g_free (dir);
+ }
+
+ uri = g_filename_to_uri (absolute, NULL, &error);
+ g_free (absolute);
+ if (uri == NULL)
+ return error->message; /* XXX g_error_free (error) */
+
+ document = poppler_document_new_from_file (uri, NULL, &error);
+ g_free (uri);
+ if (document == NULL)
+ return error->message; /* XXX g_error_free (error) */
+
+ page = poppler_document_get_page_by_label (document, page_label);
+ g_object_unref (document);
+ if (page == NULL)
+ return "page not found";
+
+ poppler_page_get_size (page, &width, &height);
+
+ surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, width, height);
+ cr = cairo_create (surface);
+
+ cairo_set_source_rgb (cr, 1., 1., 1.);
+ cairo_paint (cr);
+ cairo_push_group_with_content (cr, CAIRO_CONTENT_COLOR_ALPHA);
+
+ poppler_page_render (page, cr);
+ g_object_unref (page);
+
+ cairo_pop_group_to_source (cr);
+ cairo_paint (cr);
+
+ status = cairo_status (cr);
+ cairo_destroy (cr);
+
+ if (status) {
+ cairo_surface_destroy (surface);
+ return cairo_status_to_string (status);
+ }
+
+ *surface_out = surface;
+ return NULL;
+}
+
+static const char *
+pdf_convert (char **argv, int fd)
+{
+ const char *err;
+ cairo_surface_t *surface = NULL; /* silence compiler warning */
+
+ err = _poppler_render_page (argv[0], argv[1], &surface);
+ if (err != NULL)
+ return err;
+
+ err = write_ppm (surface, fd);
+ cairo_surface_destroy (surface);
+
+ return err;
+}
+#else
+static const char *
+pdf_convert (char **argv, int fd)
+{
+ return "compiled without PDF support.";
+}
+#endif
+
+#if CAIRO_CAN_TEST_SVG_SURFACE
+static const char *
+_rsvg_render_page (const char *filename,
+ cairo_surface_t **surface_out)
+{
+ RsvgHandle *handle;
+ RsvgDimensionData dimensions;
+ GError *error = NULL;
+ cairo_surface_t *surface;
+ cairo_t *cr;
+ cairo_status_t status;
+
+ handle = rsvg_handle_new_from_file (filename, &error);
+ if (handle == NULL)
+ return error->message; /* XXX g_error_free */
+
+ rsvg_handle_get_dimensions (handle, &dimensions);
+ surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
+ dimensions.width,
+ dimensions.height);
+ cr = cairo_create (surface);
+
+ rsvg_handle_render_cairo (handle, cr);
+ g_object_unref (handle);
+
+ status = cairo_status (cr);
+ cairo_destroy (cr);
+
+ if (status) {
+ cairo_surface_destroy (surface);
+ return cairo_status_to_string (status);
+ }
+
+ *surface_out = surface;
+ return NULL;
+}
+
+static const char *
+svg_convert (char **argv, int fd)
+{
+ const char *err;
+ cairo_surface_t *surface = NULL; /* silence compiler warning */
+
+ err = _rsvg_render_page (argv[0], &surface);
+ if (err != NULL)
+ return err;
+
+ err = write_ppm (surface, fd);
+ cairo_surface_destroy (surface);
+
+ return err;
+}
+#else
+static const char *
+svg_convert (char **argv, int fd)
+{
+ return "compiled without SVG support.";
+}
+#endif
+
+#if CAIRO_HAS_SPECTRE
+static const char *
+_spectre_render_page (const char *filename,
+ const char *page_label,
+ cairo_surface_t **surface_out)
+{
+ static const cairo_user_data_key_t key;
+
+ SpectreDocument *document;
+ SpectreStatus status;
+ int width, height, stride;
+ unsigned char *pixels;
+ cairo_surface_t *surface;
+
+ document = spectre_document_new ();
+ spectre_document_load (document, filename);
+ status = spectre_document_status (document);
+ if (status) {
+ spectre_document_free (document);
+ return spectre_status_to_string (status);
+ }
+
+ if (page_label) {
+ SpectrePage *page;
+ SpectreRenderContext *rc;
+
+ page = spectre_document_get_page_by_label (document, page_label);
+ spectre_document_free (document);
+ if (page == NULL)
+ return "page not found";
+
+ spectre_page_get_size (page, &width, &height);
+ rc = spectre_render_context_new ();
+ spectre_render_context_set_page_size (rc, width, height);
+ spectre_page_render (page, rc, &pixels, &stride);
+ spectre_render_context_free (rc);
+ status = spectre_page_status (page);
+ spectre_page_free (page);
+ if (status) {
+ free (pixels);
+ return spectre_status_to_string (status);
+ }
+ } else {
+ spectre_document_get_page_size (document, &width, &height);
+ spectre_document_render (document, &pixels, &stride);
+ spectre_document_free (document);
+ }
+
+ surface = cairo_image_surface_create_for_data (pixels,
+ CAIRO_FORMAT_RGB24,
+ width, height,
+ stride);
+ cairo_surface_set_user_data (surface, &key,
+ pixels, (cairo_destroy_func_t) free);
+ *surface_out = surface;
+ return NULL;
+}
+
+static const char *
+ps_convert (char **argv, int fd)
+{
+ const char *err;
+ cairo_surface_t *surface = NULL; /* silence compiler warning */
+
+ err = _spectre_render_page (argv[0], argv[1], &surface);
+ if (err != NULL)
+ return err;
+
+ err = write_ppm (surface, fd);
+ cairo_surface_destroy (surface);
+
+ return err;
+}
+#else
+static const char *
+ps_convert (char **argv, int fd)
+{
+ return "compiled without PostScript support.";
+}
+#endif
+
+static const char *
+convert (char **argv, int fd)
+{
+ static const struct converter {
+ const char *type;
+ const char *(*func) (char **, int);
+ } converters[] = {
+ { "cs", cs_convert },
+ { "pdf", pdf_convert },
+ { "ps", ps_convert },
+ { "svg", svg_convert },
+ { NULL, NULL }
+ };
+ const struct converter *converter = converters;
+ char *type;
+
+ type = strrchr (argv[0], '.');
+ if (type == NULL)
+ return "no file extension";
+ type++;
+
+ while (converter->type) {
+ if (strcmp (type, converter->type) == 0)
+ return converter->func (argv, fd);
+ converter++;
+ }
+ return "no converter";
+}
+
+#if CAN_RUN_AS_DAEMON
+static int
+_getline (int fd, char **linep, size_t *lenp)
+{
+ char *line;
+ size_t len, i;
+ ssize_t ret;
+
+ line = *linep;
+ if (line == NULL) {
+ line = malloc (1024);
+ if (line == NULL)
+ return -1;
+ line[0] = '\0';
+ len = 1024;
+ } else
+ len = *lenp;
+
+ /* XXX simple, but ugly! */
+ i = 0;
+ do {
+ if (i == len - 1) {
+ char *nline;
+
+ nline = realloc (line, len + 1024);
+ if (nline == NULL)
+ goto out;
+
+ line = nline;
+ len += 1024;
+ }
+
+ ret = read (fd, line + i, 1);
+ if (ret == -1 || ret == 0)
+ goto out;
+ } while (line[i++] != '\n');
+
+out:
+ line[i] = '\0';
+ *linep = line;
+ *lenp = len;
+ return i-1;
+}
+
+static int
+split_line (char *line, char *argv[], int max_argc)
+{
+ int i = 0;
+
+ max_argc--; /* leave one spare for the trailing NULL */
+
+ argv[i++] = line;
+ while (i < max_argc && (line = strchr (line, ' ')) != NULL) {
+ *line++ = '\0';
+ argv[i++] = line;
+ }
+
+ /* chomp the newline */
+ line = strchr (argv[i-1], '\n');
+ if (line != NULL)
+ *line = '\0';
+
+ argv[i] = NULL;
+
+ return i;
+}
+
+static int
+any2ppm_daemon_exists (void)
+{
+ struct stat st;
+ int fd;
+ char buf[80];
+ int pid;
+ int ret;
+
+ if (stat (SOCKET_PATH, &st) < 0)
+ return 0;
+
+ fd = open (SOCKET_PATH ".pid", O_RDONLY);
+ if (fd < 0)
+ return 0;
+
+ pid = 0;
+ ret = read (fd, buf, sizeof (buf) - 1);
+ if (ret > 0) {
+ buf[ret] = '\0';
+ pid = atoi (buf);
+ }
+ close (fd);
+
+ return pid > 0 && kill (pid, 0) == 0;
+}
+
+static int
+write_pid_file (void)
+{
+ int fd;
+ char buf[80];
+ int ret;
+
+ fd = open (SOCKET_PATH ".pid", O_CREAT | O_TRUNC | O_WRONLY, 0666);
+ if (fd < 0)
+ return 0;
+
+ ret = sprintf (buf, "%d\n", getpid ());
+ ret = write (fd, buf, ret) == ret;
+ close (fd);
+
+ return ret;
+}
+
+static int
+open_devnull_to_fd (int want_fd, int flags)
+{
+ int error;
+ int got_fd;
+
+ close (want_fd);
+
+ got_fd = open("/dev/null", flags | O_CREAT, 0700);
+ if (got_fd == -1)
+ return -1;
+
+ error = dup2 (got_fd, want_fd);
+ close (got_fd);
+
+ return error;
+}
+
+static int
+daemonize (void)
+{
+ void (*oldhup) (int);
+
+ /* Let the parent go. */
+ switch (fork ()) {
+ case -1: return -1;
+ case 0: break;
+ default: _exit (0);
+ }
+
+ /* Become session leader. */
+ if (setsid () == -1)
+ return -1;
+
+ /* Refork to yield session leadership. */
+ oldhup = signal (SIGHUP, SIG_IGN);
+
+ switch (fork ()) { /* refork to yield session leadership. */
+ case -1: return -1;
+ case 0: break;
+ default: _exit (0);
+ }
+
+ signal (SIGHUP, oldhup);
+
+ /* Establish stdio. */
+ if (open_devnull_to_fd (0, O_RDONLY) == -1)
+ return -1;
+ if (open_devnull_to_fd (1, O_WRONLY | O_APPEND) == -1)
+ return -1;
+ if (dup2 (1, 2) == -1)
+ return -1;
+
+ return 0;
+}
+
+static const char *
+any2ppm_daemon (void)
+{
+ int timeout = TIMEOUT;
+ struct pollfd pfd;
+ int sk, fd;
+ long flags;
+ struct sockaddr_un addr;
+ char *line = NULL;
+ size_t len = 0;
+
+#ifdef SIGPIPE
+ signal (SIGPIPE, SIG_IGN);
+#endif
+
+ /* XXX racy! */
+ if (getenv ("ANY2PPM_FORCE") == NULL && any2ppm_daemon_exists ())
+ return "any2ppm daemon already running";
+
+ unlink (SOCKET_PATH);
+
+ sk = socket (PF_UNIX, SOCK_STREAM, 0);
+ if (sk == -1)
+ return "unable to create socket";
+
+ memset (&addr, 0, sizeof (addr));
+ addr.sun_family = AF_UNIX;
+ strcpy (addr.sun_path, SOCKET_PATH);
+ if (bind (sk, (struct sockaddr *) &addr, sizeof (addr)) == -1) {
+ close (sk);
+ return "unable to bind socket";
+ }
+
+ flags = fcntl (sk, F_GETFL);
+ if (flags == -1 || fcntl (sk, F_SETFL, flags | O_NONBLOCK) == -1) {
+ close (sk);
+ return "unable to set socket to non-blocking";
+ }
+
+ if (listen (sk, 5) == -1) {
+ close (sk);
+ return "unable to listen on socket";
+ }
+
+ /* ready for client connection - detach from parent/terminal */
+ if (getenv ("ANY2PPM_NODAEMON") == NULL && daemonize () == -1) {
+ close (sk);
+ return "unable to detach from parent";
+ }
+
+ if (! write_pid_file ()) {
+ close (sk);
+ return "unable to write pid file";
+ }
+
+ if (getenv ("ANY2PPM_TIMEOUT") != NULL) {
+ timeout = atoi (getenv ("ANY2PPM_TIMEOUT"));
+ if (timeout == 0)
+ timeout = -1;
+ if (timeout > 0)
+ timeout *= 1000; /* convert env (in seconds) to milliseconds */
+ }
+
+ pfd.fd = sk;
+ pfd.events = POLLIN;
+ pfd.revents = 0; /* valgrind */
+ while (poll (&pfd, 1, timeout) > 0) {
+ while ((fd = accept (sk, NULL, NULL)) != -1) {
+ if (_getline (fd, &line, &len) != -1) {
+ char *argv[10];
+
+ if (split_line (line, argv, ARRAY_LENGTH (argv)) > 0) {
+ const char *err;
+
+ err = convert (argv, fd);
+ if (err != NULL) {
+ FILE *file = fopen (".any2ppm.errors", "a");
+ if (file != NULL) {
+ fprintf (file,
+ "Failed to convert '%s': %s\n",
+ argv[0], err);
+ fclose (file);
+ }
+ }
+ }
+ }
+ close (fd);
+ }
+ }
+ close (sk);
+ unlink (SOCKET_PATH);
+ unlink (SOCKET_PATH ".pid");
+
+ free (line);
+ return NULL;
+}
+#else
+static const char *
+any2ppm_daemon (void)
+{
+ return "daemon not compiled in.";
+}
+#endif
+
+int
+main (int argc, char **argv)
+{
+ const char *err;
+
+#if CAIRO_CAN_TEST_PDF_SURFACE || CAIRO_CAN_TEST_SVG_SURFACE
+#if GLIB_MAJOR_VERSION <= 2 && GLIB_MINOR_VERSION <= 34
+ g_type_init ();
+#endif
+#endif
+
+#if CAIRO_CAN_TEST_SVG_SURFACE
+ rsvg_set_default_dpi (72.0);
+#endif
+
+#if defined(_WIN32) && !defined (__CYGWIN__)
+ _setmode (1, _O_BINARY);
+#endif
+
+ if (argc == 1)
+ err = any2ppm_daemon ();
+ else
+ err = convert (argv + 1, 1);
+ if (err != NULL) {
+ fprintf (stderr, "Failed to run converter: %s\n", err);
+ return EXIT_FAILURE;
+ }
+
+ return EXIT_SUCCESS;
+}
diff --git a/test/api-special-cases.c b/test/api-special-cases.c
new file mode 100644
index 000000000..c4a754dee
--- /dev/null
+++ b/test/api-special-cases.c
@@ -0,0 +1,1989 @@
+/*
+ * Copyright © 2010 Red Hat Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Benjamin Otte <otte@redhat.com>
+ */
+
+/*
+ * WHAT THIS TEST DOES
+ *
+ * This test tests that for all public APIs Cairo behaves correct, consistent
+ * and most of all doesn't crash. It does this by calling all APIs that take
+ * surfaces or contexts and calling them on specially prepared arguments that
+ * should fail when called on this function.
+ *
+ * ADDING NEW FUNCTIONS
+ *
+ * You need (for adding the function cairo_surface_foo):
+ * 1) A surface_test_func_t named test_cairo_surface_foo that gets passed the
+ * prepared surface and has the job of calling the function and checking
+ * the return value (if one exists) for correctness. The top of this file
+ * contains all these shim functions.
+ * 2) Knowledge if the function behaves like a setter or like a getter. A
+ * setter should set an error status on the surface, a getter does not
+ * modify the function.
+ * 3) Knowledge if the function only works for a specific surface type and for
+ * which one.
+ * 4) An entry in the tests array using the TEST() macro. It takes as arguments:
+ * - The function name
+ * - TRUE if the function modifies the surface, FALSE otherwise
+ * - the surface type for which the function is valid or -1 if it is valid
+ * for all surface types.
+ *
+ * FIXING FAILURES
+ *
+ * The test will dump failures notices into the api-special-cases.log file (when
+ * it doesn't crash). These should be pretty self-explanatory. Usually it is
+ * enough to just add a new check to the function it complained about.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <assert.h>
+#include <limits.h>
+
+#include "cairo-test.h"
+
+#if CAIRO_HAS_GL_SURFACE
+#include <cairo-gl.h>
+#endif
+#if CAIRO_HAS_OS2_SURFACE
+#include <cairo-os2.h>
+#endif
+#if CAIRO_HAS_PDF_SURFACE
+#include <cairo-pdf.h>
+#endif
+#if CAIRO_HAS_PS_SURFACE
+#include <cairo-ps.h>
+#endif
+#if CAIRO_HAS_QUARTZ_SURFACE
+#define Cursor QuartzCursor
+#include <cairo-quartz.h>
+#undef Cursor
+#endif
+#if CAIRO_HAS_SVG_SURFACE
+#include <cairo-svg.h>
+#endif
+#if CAIRO_HAS_TEE_SURFACE
+#include <cairo-tee.h>
+#endif
+#if CAIRO_HAS_XCB_SURFACE
+#include <cairo-xcb.h>
+#endif
+#if CAIRO_HAS_XLIB_SURFACE
+#define Cursor XCursor
+#include <cairo-xlib.h>
+#undef Cursor
+#endif
+
+#define surface_has_type(surface,type) (cairo_surface_get_type (surface) == (type))
+
+typedef cairo_test_status_t (* surface_test_func_t) (cairo_surface_t *surface);
+typedef cairo_test_status_t (* context_test_func_t) (cairo_t *cr);
+
+static cairo_test_status_t
+test_cairo_reference (cairo_t *cr)
+{
+ cairo_destroy (cairo_reference (cr));
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_get_reference_count (cairo_t *cr)
+{
+ unsigned int refcount = cairo_get_reference_count (cr);
+ if (refcount > 0)
+ return CAIRO_TEST_SUCCESS;
+ /* inert error context have a refcount of 0 */
+ return cairo_status (cr) ? CAIRO_TEST_SUCCESS : CAIRO_TEST_ERROR;
+}
+
+static cairo_test_status_t
+test_cairo_set_user_data (cairo_t *cr)
+{
+ static cairo_user_data_key_t key;
+ cairo_status_t status;
+
+ status = cairo_set_user_data (cr, &key, &key, NULL);
+ if (status == CAIRO_STATUS_NO_MEMORY)
+ return CAIRO_TEST_NO_MEMORY;
+ else if (status)
+ return CAIRO_TEST_SUCCESS;
+
+ if (cairo_get_user_data (cr, &key) != &key)
+ return CAIRO_TEST_ERROR;
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_save (cairo_t *cr)
+{
+ cairo_save (cr);
+ cairo_restore (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_push_group (cairo_t *cr)
+{
+ cairo_pattern_t *pattern;
+ cairo_status_t status;
+
+ cairo_push_group (cr);
+ pattern = cairo_pop_group (cr);
+ status = cairo_pattern_status (pattern);
+ cairo_pattern_destroy (pattern);
+
+ return status == CAIRO_STATUS_SUCCESS || status == cairo_status (cr) ? CAIRO_TEST_SUCCESS : CAIRO_TEST_ERROR;
+}
+
+static cairo_test_status_t
+test_cairo_push_group_with_content (cairo_t *cr)
+{
+ cairo_push_group_with_content (cr, CAIRO_CONTENT_COLOR_ALPHA);
+ cairo_pop_group_to_source (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_set_operator (cairo_t *cr)
+{
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_set_source (cairo_t *cr)
+{
+ cairo_pattern_t *source = cairo_pattern_create_rgb (0, 0, 0);
+ cairo_set_source (cr, source);
+ cairo_pattern_destroy (source);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_set_source_rgb (cairo_t *cr)
+{
+ cairo_set_source_rgb (cr, 0, 0, 0);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_set_source_rgba (cairo_t *cr)
+{
+ cairo_set_source_rgba (cr, 0, 0, 0, 1);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_set_source_surface (cairo_t *cr)
+{
+ cairo_surface_t *surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 1, 1);
+ cairo_set_source_surface (cr, surface, 0, 0);
+ cairo_surface_destroy (surface);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_set_tolerance (cairo_t *cr)
+{
+ cairo_set_tolerance (cr, 42);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_set_antialias (cairo_t *cr)
+{
+ cairo_set_antialias (cr, CAIRO_ANTIALIAS_BEST);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_set_fill_rule (cairo_t *cr)
+{
+ cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_set_line_width (cairo_t *cr)
+{
+ cairo_set_line_width (cr, 42);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_set_line_cap (cairo_t *cr)
+{
+ cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_set_line_join (cairo_t *cr)
+{
+ cairo_set_line_join (cr, CAIRO_LINE_JOIN_BEVEL);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_set_dash (cairo_t *cr)
+{
+ cairo_set_dash (cr, NULL, 0, 0);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_set_miter_limit (cairo_t *cr)
+{
+ cairo_set_miter_limit (cr, 2);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_translate (cairo_t *cr)
+{
+ cairo_translate (cr, 2, 2);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_scale (cairo_t *cr)
+{
+ cairo_scale (cr, 2, 2);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_rotate (cairo_t *cr)
+{
+ cairo_rotate (cr, 2);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_transform (cairo_t *cr)
+{
+ cairo_matrix_t matrix;
+
+ cairo_matrix_init_translate (&matrix, 1, 1);
+ cairo_transform (cr, &matrix);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_set_matrix (cairo_t *cr)
+{
+ cairo_matrix_t matrix;
+
+ cairo_matrix_init_translate (&matrix, 1, 1);
+ cairo_set_matrix (cr, &matrix);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_identity_matrix (cairo_t *cr)
+{
+ cairo_identity_matrix (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_user_to_device (cairo_t *cr)
+{
+ double x = 42, y = 42;
+
+ cairo_user_to_device (cr, &x, &y);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_user_to_device_distance (cairo_t *cr)
+{
+ double x = 42, y = 42;
+
+ cairo_user_to_device_distance (cr, &x, &y);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_device_to_user (cairo_t *cr)
+{
+ double x = 42, y = 42;
+
+ cairo_device_to_user (cr, &x, &y);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_device_to_user_distance (cairo_t *cr)
+{
+ double x = 42, y = 42;
+
+ cairo_device_to_user_distance (cr, &x, &y);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_new_path (cairo_t *cr)
+{
+ cairo_new_path (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_move_to (cairo_t *cr)
+{
+ cairo_move_to (cr, 2, 2);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_new_sub_path (cairo_t *cr)
+{
+ cairo_new_sub_path (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_line_to (cairo_t *cr)
+{
+ cairo_line_to (cr, 2, 2);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_curve_to (cairo_t *cr)
+{
+ cairo_curve_to (cr, 2, 2, 3, 3, 4, 4);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_arc (cairo_t *cr)
+{
+ cairo_arc (cr, 2, 2, 3, 0, 2 * M_PI);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_arc_negative (cairo_t *cr)
+{
+ cairo_arc_negative (cr, 2, 2, 3, 0, 2 * M_PI);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_rel_move_to (cairo_t *cr)
+{
+ cairo_rel_move_to (cr, 2, 2);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_rel_line_to (cairo_t *cr)
+{
+ cairo_rel_line_to (cr, 2, 2);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_rel_curve_to (cairo_t *cr)
+{
+ cairo_rel_curve_to (cr, 2, 2, 3, 3, 4, 4);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_rectangle (cairo_t *cr)
+{
+ cairo_rectangle (cr, 2, 2, 3, 3);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_close_path (cairo_t *cr)
+{
+ cairo_close_path (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_path_extents (cairo_t *cr)
+{
+ double x1, y1, x2, y2;
+ cairo_path_extents (cr, &x1, &y1, &x2, &y2);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_paint (cairo_t *cr)
+{
+ cairo_paint (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_paint_with_alpha (cairo_t *cr)
+{
+ cairo_paint_with_alpha (cr, 0.5);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_mask (cairo_t *cr)
+{
+ cairo_pattern_t *pattern;
+
+ pattern = cairo_pattern_create_rgb (0.5, 0.5, 0.5);
+ cairo_mask (cr, pattern);
+
+ cairo_pattern_destroy (pattern);
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_mask_surface (cairo_t *cr)
+{
+ cairo_surface_t *surface;
+
+ surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 1, 1);
+ cairo_mask_surface (cr, surface, 0, 0);
+
+ cairo_surface_destroy (surface);
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_stroke (cairo_t *cr)
+{
+ cairo_stroke (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_stroke_preserve (cairo_t *cr)
+{
+ cairo_stroke_preserve (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_fill (cairo_t *cr)
+{
+ cairo_fill (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_fill_preserve (cairo_t *cr)
+{
+ cairo_fill_preserve (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_copy_page (cairo_t *cr)
+{
+ cairo_copy_page (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_show_page (cairo_t *cr)
+{
+ cairo_show_page (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_in_stroke (cairo_t *cr)
+{
+ cairo_in_stroke (cr, 1, 1);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_in_fill (cairo_t *cr)
+{
+ cairo_in_fill (cr, 1, 1);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_in_clip (cairo_t *cr)
+{
+ cairo_in_clip (cr, 1, 1);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_stroke_extents (cairo_t *cr)
+{
+ double x1, y1, x2, y2;
+ cairo_stroke_extents (cr, &x1, &y1, &x2, &y2);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_fill_extents (cairo_t *cr)
+{
+ double x1, y1, x2, y2;
+ cairo_fill_extents (cr, &x1, &y1, &x2, &y2);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_reset_clip (cairo_t *cr)
+{
+ cairo_reset_clip (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_clip (cairo_t *cr)
+{
+ cairo_clip (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_clip_preserve (cairo_t *cr)
+{
+ cairo_clip_preserve (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_clip_extents (cairo_t *cr)
+{
+ double x1, y1, x2, y2;
+ cairo_clip_extents (cr, &x1, &y1, &x2, &y2);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_copy_clip_rectangle_list (cairo_t *cr)
+{
+ cairo_rectangle_list_destroy (cairo_copy_clip_rectangle_list (cr));
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_select_font_face (cairo_t *cr)
+{
+ cairo_select_font_face (cr, "Arial", CAIRO_FONT_SLANT_ITALIC, CAIRO_FONT_WEIGHT_BOLD);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_set_font_size (cairo_t *cr)
+{
+ cairo_set_font_size (cr, 42);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_set_font_matrix (cairo_t *cr)
+{
+ cairo_matrix_t matrix;
+
+ cairo_matrix_init_translate (&matrix, 1, 1);
+ cairo_set_font_matrix (cr, &matrix);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_get_font_matrix (cairo_t *cr)
+{
+ cairo_matrix_t matrix;
+
+ cairo_get_font_matrix (cr, &matrix);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_set_font_options (cairo_t *cr)
+{
+ cairo_font_options_t *opt = cairo_font_options_create ();
+ cairo_set_font_options (cr, opt);
+ cairo_font_options_destroy (opt);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_get_font_options (cairo_t *cr)
+{
+ cairo_font_options_t *opt = cairo_font_options_create ();
+ cairo_get_font_options (cr, opt);
+ cairo_font_options_destroy (opt);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_set_font_face (cairo_t *cr)
+{
+ cairo_set_font_face (cr, cairo_get_font_face (cr));
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_set_scaled_font (cairo_t *cr)
+{
+ cairo_set_scaled_font (cr, cairo_get_scaled_font (cr));
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_show_text (cairo_t *cr)
+{
+ cairo_show_text (cr, "Cairo");
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_show_glyphs (cairo_t *cr)
+{
+ cairo_glyph_t glyph;
+
+ glyph.index = 65;
+ glyph.x = 0;
+ glyph.y = 0;
+
+ cairo_show_glyphs (cr, &glyph, 1);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_show_text_glyphs (cairo_t *cr)
+{
+ cairo_glyph_t glyph;
+ cairo_text_cluster_t cluster;
+
+ glyph.index = 65;
+ glyph.x = 0;
+ glyph.y = 0;
+
+ cluster.num_bytes = 1;
+ cluster.num_glyphs = 1;
+
+ cairo_show_text_glyphs (cr, "a", -1, &glyph, 1, &cluster, 1, 0);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_text_path (cairo_t *cr)
+{
+ cairo_text_path (cr, "Cairo");
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_glyph_path (cairo_t *cr)
+{
+ cairo_glyph_t glyph;
+
+ glyph.index = 65;
+ glyph.x = 0;
+ glyph.y = 0;
+
+ cairo_glyph_path (cr, &glyph, 1);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_text_extents (cairo_t *cr)
+{
+ cairo_text_extents_t extents;
+
+ cairo_text_extents (cr, "Cairo", &extents);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_glyph_extents (cairo_t *cr)
+{
+ cairo_glyph_t glyph;
+ cairo_text_extents_t extents;
+
+ glyph.index = 65;
+ glyph.x = 0;
+ glyph.y = 0;
+
+ cairo_glyph_extents (cr, &glyph, 1, &extents);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_font_extents (cairo_t *cr)
+{
+ cairo_font_extents_t extents;
+
+ cairo_font_extents (cr, &extents);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_get_operator (cairo_t *cr)
+{
+ cairo_get_operator (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_get_source (cairo_t *cr)
+{
+ cairo_get_source (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_get_tolerance (cairo_t *cr)
+{
+ cairo_get_tolerance (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_get_antialias (cairo_t *cr)
+{
+ cairo_get_antialias (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_has_current_point (cairo_t *cr)
+{
+ cairo_has_current_point (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_get_current_point (cairo_t *cr)
+{
+ double x, y;
+
+ cairo_get_current_point (cr, &x, &y);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_get_fill_rule (cairo_t *cr)
+{
+ cairo_get_fill_rule (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_get_line_width (cairo_t *cr)
+{
+ cairo_get_line_width (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_get_line_cap (cairo_t *cr)
+{
+ cairo_get_line_cap (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_get_line_join (cairo_t *cr)
+{
+ cairo_get_line_join (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_get_miter_limit (cairo_t *cr)
+{
+ cairo_get_miter_limit (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_get_dash_count (cairo_t *cr)
+{
+ cairo_get_dash_count (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_get_dash (cairo_t *cr)
+{
+ double dashes[42];
+ double offset;
+
+ cairo_get_dash (cr, &dashes[0], &offset);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_get_matrix (cairo_t *cr)
+{
+ cairo_matrix_t matrix;
+
+ cairo_get_matrix (cr, &matrix);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_get_target (cairo_t *cr)
+{
+ cairo_get_target (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_get_group_target (cairo_t *cr)
+{
+ cairo_get_group_target (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_copy_path (cairo_t *cr)
+{
+ cairo_path_destroy (cairo_copy_path (cr));
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_copy_path_flat (cairo_t *cr)
+{
+ cairo_path_destroy (cairo_copy_path_flat (cr));
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_append_path (cairo_t *cr)
+{
+ cairo_path_data_t data[3];
+ cairo_path_t path;
+
+ path.status = CAIRO_STATUS_SUCCESS;
+ path.data = &data[0];
+ path.num_data = ARRAY_LENGTH(data);
+
+ data[0].header.type = CAIRO_PATH_MOVE_TO;
+ data[0].header.length = 2;
+ data[1].point.x = 1;
+ data[1].point.y = 2;
+ data[2].header.type = CAIRO_PATH_CLOSE_PATH;
+ data[2].header.length = 1;
+
+ cairo_append_path (cr, &path);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_surface_create_similar (cairo_surface_t *surface)
+{
+ cairo_surface_t *similar;
+
+ similar = cairo_surface_create_similar (surface, CAIRO_CONTENT_ALPHA, 100, 100);
+
+ cairo_surface_destroy (similar);
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_surface_create_for_rectangle (cairo_surface_t *surface)
+{
+ cairo_surface_t *similar;
+
+ similar = cairo_surface_create_for_rectangle (surface, 1, 1, 8, 8);
+
+ cairo_surface_destroy (similar);
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_surface_reference (cairo_surface_t *surface)
+{
+ cairo_surface_destroy (cairo_surface_reference (surface));
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_surface_finish (cairo_surface_t *surface)
+{
+ cairo_surface_finish (surface);
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_surface_get_device (cairo_surface_t *surface)
+{
+ /* cairo_device_t *device = */cairo_surface_get_device (surface);
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_surface_get_reference_count (cairo_surface_t *surface)
+{
+ unsigned int refcount = cairo_surface_get_reference_count (surface);
+ if (refcount > 0)
+ return CAIRO_TEST_SUCCESS;
+ /* inert error surfaces have a refcount of 0 */
+ return cairo_surface_status (surface) ? CAIRO_TEST_SUCCESS : CAIRO_TEST_ERROR;
+}
+
+static cairo_test_status_t
+test_cairo_surface_status (cairo_surface_t *surface)
+{
+ cairo_status_t status = cairo_surface_status (surface);
+ return status < CAIRO_STATUS_LAST_STATUS ? CAIRO_TEST_SUCCESS : CAIRO_TEST_ERROR;
+}
+
+static cairo_test_status_t
+test_cairo_surface_get_type (cairo_surface_t *surface)
+{
+ /* cairo_surface_type_t type = */cairo_surface_get_type (surface);
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_surface_get_content (cairo_surface_t *surface)
+{
+ cairo_content_t content = cairo_surface_get_content (surface);
+
+ switch (content) {
+ case CAIRO_CONTENT_COLOR:
+ case CAIRO_CONTENT_ALPHA:
+ case CAIRO_CONTENT_COLOR_ALPHA:
+ return CAIRO_TEST_SUCCESS;
+ default:
+ return CAIRO_TEST_ERROR;
+ }
+}
+
+static cairo_test_status_t
+test_cairo_surface_set_user_data (cairo_surface_t *surface)
+{
+ static cairo_user_data_key_t key;
+ cairo_status_t status;
+
+ status = cairo_surface_set_user_data (surface, &key, &key, NULL);
+ if (status == CAIRO_STATUS_NO_MEMORY)
+ return CAIRO_TEST_NO_MEMORY;
+ else if (status)
+ return CAIRO_TEST_SUCCESS;
+
+ if (cairo_surface_get_user_data (surface, &key) != &key)
+ return CAIRO_TEST_ERROR;
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_surface_set_mime_data (cairo_surface_t *surface)
+{
+ const char *mimetype = "text/x-uri";
+ const char *data = "http://www.cairographics.org";
+ cairo_status_t status;
+
+ status = cairo_surface_set_mime_data (surface,
+ mimetype,
+ (const unsigned char *) data,
+ strlen (data),
+ NULL, NULL);
+ return status ? CAIRO_TEST_SUCCESS : CAIRO_TEST_ERROR;
+}
+
+static cairo_test_status_t
+test_cairo_surface_get_mime_data (cairo_surface_t *surface)
+{
+ const char *mimetype = "text/x-uri";
+ const unsigned char *data;
+ unsigned long length;
+
+ cairo_surface_get_mime_data (surface, mimetype, &data, &length);
+ return data == NULL && length == 0 ? CAIRO_TEST_SUCCESS : CAIRO_TEST_ERROR;
+}
+
+static cairo_test_status_t
+test_cairo_surface_get_font_options (cairo_surface_t *surface)
+{
+ cairo_font_options_t *options;
+ cairo_status_t status;
+
+ options = cairo_font_options_create ();
+ if (likely (!cairo_font_options_status (options)))
+ cairo_surface_get_font_options (surface, options);
+ status = cairo_font_options_status (options);
+ cairo_font_options_destroy (options);
+ return status ? CAIRO_TEST_ERROR : CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_surface_flush (cairo_surface_t *surface)
+{
+ cairo_surface_flush (surface);
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_surface_mark_dirty (cairo_surface_t *surface)
+{
+ cairo_surface_mark_dirty (surface);
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_surface_mark_dirty_rectangle (cairo_surface_t *surface)
+{
+ cairo_surface_mark_dirty_rectangle (surface, 1, 1, 8, 8);
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_surface_set_device_offset (cairo_surface_t *surface)
+{
+ cairo_surface_set_device_offset (surface, 5, 5);
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_surface_get_device_offset (cairo_surface_t *surface)
+{
+ double x, y;
+
+ cairo_surface_get_device_offset (surface, &x, &y);
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_surface_set_fallback_resolution (cairo_surface_t *surface)
+{
+ cairo_surface_set_fallback_resolution (surface, 42, 42);
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_surface_get_fallback_resolution (cairo_surface_t *surface)
+{
+ double x, y;
+
+ cairo_surface_get_fallback_resolution (surface, &x, &y);
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_surface_copy_page (cairo_surface_t *surface)
+{
+ cairo_surface_copy_page (surface);
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_surface_show_page (cairo_surface_t *surface)
+{
+ cairo_surface_show_page (surface);
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_surface_has_show_text_glyphs (cairo_surface_t *surface)
+{
+ cairo_surface_has_show_text_glyphs (surface);
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_image_surface_get_data (cairo_surface_t *surface)
+{
+ unsigned char *data = cairo_image_surface_get_data (surface);
+ return data == NULL || surface_has_type (surface, CAIRO_SURFACE_TYPE_IMAGE) ? CAIRO_TEST_SUCCESS : CAIRO_TEST_ERROR;
+}
+
+static cairo_test_status_t
+test_cairo_image_surface_get_format (cairo_surface_t *surface)
+{
+ cairo_format_t format = cairo_image_surface_get_format (surface);
+ return format == CAIRO_FORMAT_INVALID || surface_has_type (surface, CAIRO_SURFACE_TYPE_IMAGE) ? CAIRO_TEST_SUCCESS : CAIRO_TEST_ERROR;
+}
+
+static cairo_test_status_t
+test_cairo_image_surface_get_width (cairo_surface_t *surface)
+{
+ unsigned int width = cairo_image_surface_get_width (surface);
+ return width == 0 || surface_has_type (surface, CAIRO_SURFACE_TYPE_IMAGE) ? CAIRO_TEST_SUCCESS : CAIRO_TEST_ERROR;
+}
+
+static cairo_test_status_t
+test_cairo_image_surface_get_height (cairo_surface_t *surface)
+{
+ unsigned int height = cairo_image_surface_get_height (surface);
+ return height == 0 || surface_has_type (surface, CAIRO_SURFACE_TYPE_IMAGE) ? CAIRO_TEST_SUCCESS : CAIRO_TEST_ERROR;
+}
+
+static cairo_test_status_t
+test_cairo_image_surface_get_stride (cairo_surface_t *surface)
+{
+ unsigned int stride = cairo_image_surface_get_stride (surface);
+ return stride == 0 || surface_has_type (surface, CAIRO_SURFACE_TYPE_IMAGE) ? CAIRO_TEST_SUCCESS : CAIRO_TEST_ERROR;
+}
+
+#if CAIRO_HAS_PNG_FUNCTIONS
+
+static cairo_test_status_t
+test_cairo_surface_write_to_png (cairo_surface_t *surface)
+{
+ cairo_status_t status;
+
+ status = cairo_surface_write_to_png (surface, "/this/file/will/definitely/not/exist.png");
+
+ return status ? CAIRO_TEST_SUCCESS : CAIRO_TEST_ERROR;
+}
+
+static cairo_status_t
+write_func_that_always_fails (void *closure, const unsigned char *data, unsigned int length)
+{
+ return CAIRO_STATUS_WRITE_ERROR;
+}
+
+static cairo_test_status_t
+test_cairo_surface_write_to_png_stream (cairo_surface_t *surface)
+{
+ cairo_status_t status;
+
+ status = cairo_surface_write_to_png_stream (surface,
+ write_func_that_always_fails,
+ NULL);
+
+ return status && status != CAIRO_STATUS_WRITE_ERROR ? CAIRO_TEST_SUCCESS : CAIRO_TEST_ERROR;
+}
+
+#endif /* CAIRO_HAS_PNG_FUNCTIONS */
+
+static cairo_test_status_t
+test_cairo_recording_surface_ink_extents (cairo_surface_t *surface)
+{
+ double x, y, w, h;
+
+ cairo_recording_surface_ink_extents (surface, &x, &y, &w, &h);
+ return x == 0 && y == 0 && w == 0 && h == 0 ? CAIRO_TEST_SUCCESS : CAIRO_TEST_ERROR;
+}
+
+#if CAIRO_HAS_TEE_SURFACE
+
+static cairo_test_status_t
+test_cairo_tee_surface_add (cairo_surface_t *surface)
+{
+ cairo_surface_t *image = cairo_image_surface_create (CAIRO_FORMAT_A8, 10, 10);
+
+ cairo_tee_surface_add (surface, image);
+ cairo_surface_destroy (image);
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_tee_surface_remove (cairo_surface_t *surface)
+{
+ cairo_surface_t *image = cairo_image_surface_create (CAIRO_FORMAT_A8, 10, 10);
+
+ cairo_tee_surface_remove (surface, image);
+ cairo_surface_destroy (image);
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_tee_surface_index (cairo_surface_t *surface)
+{
+ cairo_surface_t *master;
+ cairo_status_t status;
+
+ master = cairo_tee_surface_index (surface, 0);
+ status = cairo_surface_status (master);
+ cairo_surface_destroy (master);
+ return status ? CAIRO_TEST_SUCCESS : CAIRO_TEST_ERROR;
+}
+
+#endif /* CAIRO_HAS_TEE_SURFACE */
+
+#if CAIRO_HAS_GL_SURFACE
+
+static cairo_test_status_t
+test_cairo_gl_surface_set_size (cairo_surface_t *surface)
+{
+ cairo_gl_surface_set_size (surface, 5, 5);
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_gl_surface_get_width (cairo_surface_t *surface)
+{
+ unsigned int width = cairo_gl_surface_get_width (surface);
+ return width == 0 || surface_has_type (surface, CAIRO_SURFACE_TYPE_GL) ? CAIRO_TEST_SUCCESS : CAIRO_TEST_ERROR;
+}
+
+static cairo_test_status_t
+test_cairo_gl_surface_get_height (cairo_surface_t *surface)
+{
+ unsigned int height = cairo_gl_surface_get_height (surface);
+ return height == 0 || surface_has_type (surface, CAIRO_SURFACE_TYPE_GL) ? CAIRO_TEST_SUCCESS : CAIRO_TEST_ERROR;
+}
+
+static cairo_test_status_t
+test_cairo_gl_surface_swapbuffers (cairo_surface_t *surface)
+{
+ cairo_gl_surface_swapbuffers (surface);
+ return CAIRO_TEST_SUCCESS;
+}
+
+#endif /* CAIRO_HAS_GL_SURFACE */
+
+#if CAIRO_HAS_PDF_SURFACE
+
+static cairo_test_status_t
+test_cairo_pdf_surface_restrict_to_version (cairo_surface_t *surface)
+{
+ cairo_pdf_surface_restrict_to_version (surface, CAIRO_PDF_VERSION_1_4);
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_pdf_surface_set_size (cairo_surface_t *surface)
+{
+ cairo_pdf_surface_set_size (surface, 5, 5);
+ return CAIRO_TEST_SUCCESS;
+}
+
+#endif /* CAIRO_HAS_PDF_SURFACE */
+
+#if CAIRO_HAS_PS_SURFACE
+
+static cairo_test_status_t
+test_cairo_ps_surface_restrict_to_level (cairo_surface_t *surface)
+{
+ cairo_ps_surface_restrict_to_level (surface, CAIRO_PS_LEVEL_2);
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_ps_surface_set_eps (cairo_surface_t *surface)
+{
+ cairo_ps_surface_set_eps (surface, TRUE);
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_ps_surface_get_eps (cairo_surface_t *surface)
+{
+ cairo_bool_t eps = cairo_ps_surface_get_eps (surface);
+ return eps ? CAIRO_TEST_ERROR : CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_ps_surface_set_size (cairo_surface_t *surface)
+{
+ cairo_ps_surface_set_size (surface, 5, 5);
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_ps_surface_dsc_comment (cairo_surface_t *surface)
+{
+ cairo_ps_surface_dsc_comment (surface, "54, 74, 90, 2010");
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_ps_surface_dsc_begin_setup (cairo_surface_t *surface)
+{
+ cairo_ps_surface_dsc_begin_setup (surface);
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_ps_surface_dsc_begin_page_setup (cairo_surface_t *surface)
+{
+ cairo_ps_surface_dsc_begin_page_setup (surface);
+ return CAIRO_TEST_SUCCESS;
+}
+
+#endif /* CAIRO_HAS_PS_SURFACE */
+
+#if CAIRO_HAS_QUARTZ_SURFACE
+
+static cairo_test_status_t
+test_cairo_quartz_surface_get_cg_context (cairo_surface_t *surface)
+{
+ CGContextRef context = cairo_quartz_surface_get_cg_context (surface);
+ return context == NULL || surface_has_type (surface, CAIRO_SURFACE_TYPE_QUARTZ) ? CAIRO_TEST_SUCCESS : CAIRO_TEST_ERROR;
+}
+
+#endif /* CAIRO_HAS_QUARTZ_SURFACE */
+
+#if CAIRO_HAS_SVG_SURFACE
+
+static cairo_test_status_t
+test_cairo_svg_surface_restrict_to_version (cairo_surface_t *surface)
+{
+ cairo_svg_surface_restrict_to_version (surface, CAIRO_SVG_VERSION_1_1);
+ return CAIRO_TEST_SUCCESS;
+}
+
+#endif /* CAIRO_HAS_SVG_SURFACE */
+
+#if CAIRO_HAS_XCB_SURFACE
+
+static cairo_test_status_t
+test_cairo_xcb_surface_set_size (cairo_surface_t *surface)
+{
+ cairo_xcb_surface_set_size (surface, 5, 5);
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_xcb_surface_set_drawable (cairo_surface_t *surface)
+{
+ cairo_xcb_surface_set_drawable (surface, 0, 5, 5);
+ return CAIRO_TEST_SUCCESS;
+}
+
+#endif
+
+#if CAIRO_HAS_XLIB_SURFACE
+
+static cairo_test_status_t
+test_cairo_xlib_surface_set_size (cairo_surface_t *surface)
+{
+ cairo_xlib_surface_set_size (surface, 5, 5);
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_xlib_surface_set_drawable (cairo_surface_t *surface)
+{
+ cairo_xlib_surface_set_drawable (surface, 0, 5, 5);
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_cairo_xlib_surface_get_display (cairo_surface_t *surface)
+{
+ Display *display = cairo_xlib_surface_get_display (surface);
+ return display == NULL || surface_has_type (surface, CAIRO_SURFACE_TYPE_XLIB) ? CAIRO_TEST_SUCCESS : CAIRO_TEST_ERROR;
+}
+
+static cairo_test_status_t
+test_cairo_xlib_surface_get_screen (cairo_surface_t *surface)
+{
+ Screen *screen = cairo_xlib_surface_get_screen (surface);
+ return screen == NULL || surface_has_type (surface, CAIRO_SURFACE_TYPE_XLIB) ? CAIRO_TEST_SUCCESS : CAIRO_TEST_ERROR;
+}
+
+static cairo_test_status_t
+test_cairo_xlib_surface_get_visual (cairo_surface_t *surface)
+{
+ Visual *visual = cairo_xlib_surface_get_visual (surface);
+ return visual == NULL || surface_has_type (surface, CAIRO_SURFACE_TYPE_XLIB) ? CAIRO_TEST_SUCCESS : CAIRO_TEST_ERROR;
+}
+
+static cairo_test_status_t
+test_cairo_xlib_surface_get_drawable (cairo_surface_t *surface)
+{
+ Drawable drawable = cairo_xlib_surface_get_drawable (surface);
+ return drawable == 0 || surface_has_type (surface, CAIRO_SURFACE_TYPE_XLIB) ? CAIRO_TEST_SUCCESS : CAIRO_TEST_ERROR;
+}
+
+static cairo_test_status_t
+test_cairo_xlib_surface_get_depth (cairo_surface_t *surface)
+{
+ int depth = cairo_xlib_surface_get_depth (surface);
+ return depth == 0 || surface_has_type (surface, CAIRO_SURFACE_TYPE_XLIB) ? CAIRO_TEST_SUCCESS : CAIRO_TEST_ERROR;
+}
+
+static cairo_test_status_t
+test_cairo_xlib_surface_get_width (cairo_surface_t *surface)
+{
+ int width = cairo_xlib_surface_get_width (surface);
+ return width == 0 || surface_has_type (surface, CAIRO_SURFACE_TYPE_XLIB) ? CAIRO_TEST_SUCCESS : CAIRO_TEST_ERROR;
+}
+
+static cairo_test_status_t
+test_cairo_xlib_surface_get_height (cairo_surface_t *surface)
+{
+ int height = cairo_xlib_surface_get_height (surface);
+ return height == 0 || surface_has_type (surface, CAIRO_SURFACE_TYPE_XLIB) ? CAIRO_TEST_SUCCESS : CAIRO_TEST_ERROR;
+}
+
+#endif
+
+#define TEST(name) { #name, test_ ## name }
+
+struct {
+ const char *name;
+ context_test_func_t func;
+} context_tests[] = {
+ TEST (cairo_reference),
+ TEST (cairo_get_reference_count),
+ TEST (cairo_set_user_data),
+ TEST (cairo_save),
+ TEST (cairo_push_group),
+ TEST (cairo_push_group_with_content),
+ TEST (cairo_set_operator),
+ TEST (cairo_set_source),
+ TEST (cairo_set_source_rgb),
+ TEST (cairo_set_source_rgba),
+ TEST (cairo_set_source_surface),
+ TEST (cairo_set_tolerance),
+ TEST (cairo_set_antialias),
+ TEST (cairo_set_fill_rule),
+ TEST (cairo_set_line_width),
+ TEST (cairo_set_line_cap),
+ TEST (cairo_set_line_join),
+ TEST (cairo_set_dash),
+ TEST (cairo_set_miter_limit),
+ TEST (cairo_translate),
+ TEST (cairo_scale),
+ TEST (cairo_rotate),
+ TEST (cairo_transform),
+ TEST (cairo_set_matrix),
+ TEST (cairo_identity_matrix),
+ TEST (cairo_user_to_device),
+ TEST (cairo_user_to_device_distance),
+ TEST (cairo_device_to_user),
+ TEST (cairo_device_to_user_distance),
+ TEST (cairo_new_path),
+ TEST (cairo_move_to),
+ TEST (cairo_new_sub_path),
+ TEST (cairo_line_to),
+ TEST (cairo_curve_to),
+ TEST (cairo_arc),
+ TEST (cairo_arc_negative),
+ TEST (cairo_rel_move_to),
+ TEST (cairo_rel_line_to),
+ TEST (cairo_rel_curve_to),
+ TEST (cairo_rectangle),
+ TEST (cairo_close_path),
+ TEST (cairo_path_extents),
+ TEST (cairo_paint),
+ TEST (cairo_paint_with_alpha),
+ TEST (cairo_mask),
+ TEST (cairo_mask_surface),
+ TEST (cairo_stroke),
+ TEST (cairo_stroke_preserve),
+ TEST (cairo_fill),
+ TEST (cairo_fill_preserve),
+ TEST (cairo_copy_page),
+ TEST (cairo_show_page),
+ TEST (cairo_in_stroke),
+ TEST (cairo_in_fill),
+ TEST (cairo_in_clip),
+ TEST (cairo_stroke_extents),
+ TEST (cairo_fill_extents),
+ TEST (cairo_reset_clip),
+ TEST (cairo_clip),
+ TEST (cairo_clip_preserve),
+ TEST (cairo_clip_extents),
+ TEST (cairo_copy_clip_rectangle_list),
+ TEST (cairo_select_font_face),
+ TEST (cairo_set_font_size),
+ TEST (cairo_set_font_matrix),
+ TEST (cairo_get_font_matrix),
+ TEST (cairo_set_font_options),
+ TEST (cairo_get_font_options),
+ TEST (cairo_set_font_face),
+ TEST (cairo_set_scaled_font),
+ TEST (cairo_show_text),
+ TEST (cairo_show_glyphs),
+ TEST (cairo_show_text_glyphs),
+ TEST (cairo_text_path),
+ TEST (cairo_glyph_path),
+ TEST (cairo_text_extents),
+ TEST (cairo_glyph_extents),
+ TEST (cairo_font_extents),
+ TEST (cairo_get_operator),
+ TEST (cairo_get_source),
+ TEST (cairo_get_tolerance),
+ TEST (cairo_get_antialias),
+ TEST (cairo_has_current_point),
+ TEST (cairo_get_current_point),
+ TEST (cairo_get_fill_rule),
+ TEST (cairo_get_line_width),
+ TEST (cairo_get_line_cap),
+ TEST (cairo_get_line_join),
+ TEST (cairo_get_miter_limit),
+ TEST (cairo_get_dash_count),
+ TEST (cairo_get_dash),
+ TEST (cairo_get_matrix),
+ TEST (cairo_get_target),
+ TEST (cairo_get_group_target),
+ TEST (cairo_copy_path),
+ TEST (cairo_copy_path_flat),
+ TEST (cairo_append_path),
+};
+
+#undef TEST
+
+#define TEST(name, surface_type, sets_status) { #name, test_ ## name, surface_type, sets_status }
+
+struct {
+ const char *name;
+ surface_test_func_t func;
+ int surface_type; /* cairo_surface_type_t or -1 */
+ cairo_bool_t modifies_surface;
+} surface_tests[] = {
+ TEST (cairo_surface_create_similar, -1, FALSE),
+ TEST (cairo_surface_create_for_rectangle, -1, FALSE),
+ TEST (cairo_surface_reference, -1, FALSE),
+ TEST (cairo_surface_finish, -1, TRUE),
+ TEST (cairo_surface_get_device, -1, FALSE),
+ TEST (cairo_surface_get_reference_count, -1, FALSE),
+ TEST (cairo_surface_status, -1, FALSE),
+ TEST (cairo_surface_get_type, -1, FALSE),
+ TEST (cairo_surface_get_content, -1, FALSE),
+ TEST (cairo_surface_set_user_data, -1, FALSE),
+ TEST (cairo_surface_set_mime_data, -1, TRUE),
+ TEST (cairo_surface_get_mime_data, -1, FALSE),
+ TEST (cairo_surface_get_font_options, -1, FALSE),
+ TEST (cairo_surface_flush, -1, TRUE),
+ TEST (cairo_surface_mark_dirty, -1, TRUE),
+ TEST (cairo_surface_mark_dirty_rectangle, -1, TRUE),
+ TEST (cairo_surface_set_device_offset, -1, TRUE),
+ TEST (cairo_surface_get_device_offset, -1, FALSE),
+ TEST (cairo_surface_set_fallback_resolution, -1, TRUE),
+ TEST (cairo_surface_get_fallback_resolution, -1, FALSE),
+ TEST (cairo_surface_copy_page, -1, TRUE),
+ TEST (cairo_surface_show_page, -1, TRUE),
+ TEST (cairo_surface_has_show_text_glyphs, -1, FALSE),
+ TEST (cairo_image_surface_get_data, CAIRO_SURFACE_TYPE_IMAGE, FALSE),
+ TEST (cairo_image_surface_get_format, CAIRO_SURFACE_TYPE_IMAGE, FALSE),
+ TEST (cairo_image_surface_get_width, CAIRO_SURFACE_TYPE_IMAGE, FALSE),
+ TEST (cairo_image_surface_get_height, CAIRO_SURFACE_TYPE_IMAGE, FALSE),
+ TEST (cairo_image_surface_get_stride, CAIRO_SURFACE_TYPE_IMAGE, FALSE),
+#if CAIRO_HAS_PNG_FUNCTIONS
+ TEST (cairo_surface_write_to_png, -1, FALSE),
+ TEST (cairo_surface_write_to_png_stream, -1, FALSE),
+#endif
+ TEST (cairo_recording_surface_ink_extents, CAIRO_SURFACE_TYPE_RECORDING, FALSE),
+#if CAIRO_HAS_TEE_SURFACE
+ TEST (cairo_tee_surface_add, CAIRO_SURFACE_TYPE_TEE, TRUE),
+ TEST (cairo_tee_surface_remove, CAIRO_SURFACE_TYPE_TEE, TRUE),
+ TEST (cairo_tee_surface_index, CAIRO_SURFACE_TYPE_TEE, FALSE),
+#endif
+#if CAIRO_HAS_GL_SURFACE
+ TEST (cairo_gl_surface_set_size, CAIRO_SURFACE_TYPE_GL, TRUE),
+ TEST (cairo_gl_surface_get_width, CAIRO_SURFACE_TYPE_GL, FALSE),
+ TEST (cairo_gl_surface_get_height, CAIRO_SURFACE_TYPE_GL, FALSE),
+ TEST (cairo_gl_surface_swapbuffers, CAIRO_SURFACE_TYPE_GL, TRUE),
+#endif
+#if CAIRO_HAS_PDF_SURFACE
+ TEST (cairo_pdf_surface_restrict_to_version, CAIRO_SURFACE_TYPE_PDF, TRUE),
+ TEST (cairo_pdf_surface_set_size, CAIRO_SURFACE_TYPE_PDF, TRUE),
+#endif
+#if CAIRO_HAS_PS_SURFACE
+ TEST (cairo_ps_surface_restrict_to_level, CAIRO_SURFACE_TYPE_PS, TRUE),
+ TEST (cairo_ps_surface_set_eps, CAIRO_SURFACE_TYPE_PS, TRUE),
+ TEST (cairo_ps_surface_get_eps, CAIRO_SURFACE_TYPE_PS, FALSE),
+ TEST (cairo_ps_surface_set_size, CAIRO_SURFACE_TYPE_PS, TRUE),
+ TEST (cairo_ps_surface_dsc_comment, CAIRO_SURFACE_TYPE_PS, TRUE),
+ TEST (cairo_ps_surface_dsc_begin_setup, CAIRO_SURFACE_TYPE_PS, TRUE),
+ TEST (cairo_ps_surface_dsc_begin_page_setup, CAIRO_SURFACE_TYPE_PS, TRUE),
+#endif
+#if CAIRO_HAS_QUARTZ_SURFACE
+ TEST (cairo_quartz_surface_get_cg_context, CAIRO_SURFACE_TYPE_QUARTZ, FALSE),
+#endif
+#if CAIRO_HAS_SVG_SURFACE
+ TEST (cairo_svg_surface_restrict_to_version, CAIRO_SURFACE_TYPE_SVG, TRUE),
+#endif
+#if CAIRO_HAS_XCB_SURFACE
+ TEST (cairo_xcb_surface_set_size, CAIRO_SURFACE_TYPE_XCB, TRUE),
+ TEST (cairo_xcb_surface_set_drawable, CAIRO_SURFACE_TYPE_XCB, TRUE),
+#endif
+#if CAIRO_HAS_XLIB_SURFACE
+ TEST (cairo_xlib_surface_set_size, CAIRO_SURFACE_TYPE_XLIB, TRUE),
+ TEST (cairo_xlib_surface_set_drawable, CAIRO_SURFACE_TYPE_XLIB, TRUE),
+ TEST (cairo_xlib_surface_get_display, CAIRO_SURFACE_TYPE_XLIB, FALSE),
+ TEST (cairo_xlib_surface_get_drawable, CAIRO_SURFACE_TYPE_XLIB, FALSE),
+ TEST (cairo_xlib_surface_get_screen, CAIRO_SURFACE_TYPE_XLIB, FALSE),
+ TEST (cairo_xlib_surface_get_visual, CAIRO_SURFACE_TYPE_XLIB, FALSE),
+ TEST (cairo_xlib_surface_get_depth, CAIRO_SURFACE_TYPE_XLIB, FALSE),
+ TEST (cairo_xlib_surface_get_width, CAIRO_SURFACE_TYPE_XLIB, FALSE),
+ TEST (cairo_xlib_surface_get_height, CAIRO_SURFACE_TYPE_XLIB, FALSE),
+#endif
+};
+
+static cairo_test_status_t
+preamble (cairo_test_context_t *ctx)
+{
+ cairo_surface_t *surface;
+ cairo_t *cr;
+ cairo_test_status_t test_status;
+ cairo_status_t status_before, status_after;
+ unsigned int i;
+
+ /* Test an error surface */
+ for (i = 0; i < ARRAY_LENGTH (surface_tests); i++) {
+ surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, INT_MAX, INT_MAX);
+ status_before = cairo_surface_status (surface);
+ assert (status_before);
+
+ test_status = surface_tests[i].func (surface);
+
+ status_after = cairo_surface_status (surface);
+ cairo_surface_destroy (surface);
+
+ if (test_status != CAIRO_TEST_SUCCESS) {
+ cairo_test_log (ctx,
+ "Failed test %s with %d\n",
+ surface_tests[i].name, (int) test_status);
+ return test_status;
+ }
+
+ if (status_before != status_after) {
+ cairo_test_log (ctx,
+ "Failed test %s: Modified surface status from %u (%s) to %u (%s)\n",
+ surface_tests[i].name,
+ status_before, cairo_status_to_string (status_before),
+ status_after, cairo_status_to_string (status_after));
+ return CAIRO_TEST_ERROR;
+ }
+ }
+
+ /* Test an error context */
+ for (i = 0; i < ARRAY_LENGTH (context_tests); i++) {
+ cr = cairo_create (NULL);
+ status_before = cairo_status (cr);
+ assert (status_before);
+
+ test_status = context_tests[i].func (cr);
+
+ status_after = cairo_status (cr);
+ cairo_destroy (cr);
+
+ if (test_status != CAIRO_TEST_SUCCESS) {
+ cairo_test_log (ctx,
+ "Failed test %s with %d\n",
+ context_tests[i].name, (int) test_status);
+ return test_status;
+ }
+
+ if (status_before != status_after) {
+ cairo_test_log (ctx,
+ "Failed test %s: Modified context status from %u (%s) to %u (%s)\n",
+ context_tests[i].name,
+ status_before, cairo_status_to_string (status_before),
+ status_after, cairo_status_to_string (status_after));
+ return CAIRO_TEST_ERROR;
+ }
+ }
+
+ /* Test a context for an error surface */
+ for (i = 0; i < ARRAY_LENGTH (context_tests); i++) {
+ surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, INT_MAX, INT_MAX);
+ cr = cairo_create (surface);
+ cairo_surface_destroy (surface);
+ status_before = cairo_status (cr);
+ assert (status_before);
+
+ test_status = context_tests[i].func (cr);
+
+ status_after = cairo_status (cr);
+ cairo_destroy (cr);
+
+ if (test_status != CAIRO_TEST_SUCCESS) {
+ cairo_test_log (ctx,
+ "Failed test %s with %d\n",
+ context_tests[i].name, (int) test_status);
+ return test_status;
+ }
+
+ if (status_before != status_after) {
+ cairo_test_log (ctx,
+ "Failed test %s: Modified context status from %u (%s) to %u (%s)\n",
+ context_tests[i].name,
+ status_before, cairo_status_to_string (status_before),
+ status_after, cairo_status_to_string (status_after));
+ return CAIRO_TEST_ERROR;
+ }
+ }
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+test_context (const cairo_test_context_t *ctx, cairo_t *cr, const char *name, unsigned int i)
+{
+ cairo_test_status_t test_status;
+ cairo_status_t status_before, status_after;
+
+ /* Make sure that there is a current point */
+ cairo_move_to (cr, 0, 0);
+
+ status_before = cairo_status (cr);
+ test_status = context_tests[i].func (cr);
+ status_after = cairo_status (cr);
+
+ if (test_status != CAIRO_TEST_SUCCESS) {
+ cairo_test_log (ctx,
+ "Failed test %s on %s with %d\n",
+ context_tests[i].name, name, (int) test_status);
+ return test_status;
+ }
+
+ if (status_after != CAIRO_STATUS_SURFACE_FINISHED && status_before != status_after) {
+ cairo_test_log (ctx,
+ "Failed test %s on %s: Modified context status from %u (%s) to %u (%s)\n",
+ context_tests[i].name, name,
+ status_before, cairo_status_to_string (status_before),
+ status_after, cairo_status_to_string (status_after));
+ return CAIRO_TEST_ERROR;
+ }
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ const cairo_test_context_t *ctx = cairo_test_get_context (cr);
+ cairo_surface_t *similar, *target;
+ cairo_test_status_t test_status;
+ cairo_status_t status;
+ cairo_t *cr2;
+ unsigned int i;
+
+ target = cairo_get_target (cr);
+
+ /* Test a finished similar surface */
+ for (i = 0; i < ARRAY_LENGTH (surface_tests); i++) {
+ similar = cairo_surface_create_similar (target,
+ cairo_surface_get_content (target),
+ 10, 10);
+ cairo_surface_finish (similar);
+ test_status = surface_tests[i].func (similar);
+ status = cairo_surface_status (similar);
+ cairo_surface_destroy (similar);
+
+ if (test_status != CAIRO_TEST_SUCCESS) {
+ cairo_test_log (ctx,
+ "Failed test %s with %d\n",
+ surface_tests[i].name, (int) test_status);
+ return test_status;
+ }
+
+ if (surface_tests[i].modifies_surface &&
+ strcmp (surface_tests[i].name, "cairo_surface_finish") &&
+ strcmp (surface_tests[i].name, "cairo_surface_flush") &&
+ status != CAIRO_STATUS_SURFACE_FINISHED) {
+ cairo_test_log (ctx,
+ "Failed test %s: Finished surface not set into error state\n",
+ surface_tests[i].name);
+ return CAIRO_TEST_ERROR;
+ }
+ }
+
+ /* Test a context for a finished similar surface */
+ for (i = 0; i < ARRAY_LENGTH (context_tests); i++) {
+ similar = cairo_surface_create_similar (target,
+ cairo_surface_get_content (target),
+ 10, 10);
+ cairo_surface_finish (similar);
+ cr2 = cairo_create (similar);
+ test_status = test_context (ctx, cr2, "finished surface", i);
+ cairo_surface_destroy (similar);
+ cairo_destroy (cr2);
+
+ if (test_status != CAIRO_TEST_SUCCESS)
+ return test_status;
+ }
+
+ /* Test a context for a similar surface finished later */
+ for (i = 0; i < ARRAY_LENGTH (context_tests); i++) {
+ similar = cairo_surface_create_similar (target,
+ cairo_surface_get_content (target),
+ 10, 10);
+ cr2 = cairo_create (similar);
+ cairo_surface_finish (similar);
+ test_status = test_context (ctx, cr2, "finished surface after create", i);
+ cairo_surface_destroy (similar);
+ cairo_destroy (cr2);
+
+ if (test_status != CAIRO_TEST_SUCCESS)
+ return test_status;
+ }
+
+ /* Test a context for a similar surface finished later with a path */
+ for (i = 0; i < ARRAY_LENGTH (context_tests); i++) {
+ similar = cairo_surface_create_similar (target,
+ cairo_surface_get_content (target),
+ 10, 10);
+ cr2 = cairo_create (similar);
+ cairo_rectangle (cr2, 2, 2, 4, 4);
+ cairo_surface_finish (similar);
+ test_status = test_context (ctx, cr2, "finished surface with path", i);
+ cairo_surface_destroy (similar);
+ cairo_destroy (cr2);
+
+ if (test_status != CAIRO_TEST_SUCCESS)
+ return test_status;
+ }
+
+ /* Test a normal surface for functions that have the wrong type */
+ for (i = 0; i < ARRAY_LENGTH (surface_tests); i++) {
+ cairo_status_t desired_status;
+
+ if (surface_tests[i].surface_type == -1)
+ continue;
+ similar = cairo_surface_create_similar (target,
+ cairo_surface_get_content (target),
+ 10, 10);
+ if (cairo_surface_get_type (similar) == (cairo_surface_type_t) surface_tests[i].surface_type) {
+ cairo_surface_destroy (similar);
+ continue;
+ }
+
+ test_status = surface_tests[i].func (similar);
+ status = cairo_surface_status (similar);
+ cairo_surface_destroy (similar);
+
+ if (test_status != CAIRO_TEST_SUCCESS) {
+ cairo_test_log (ctx,
+ "Failed test %s with %d\n",
+ surface_tests[i].name, (int) test_status);
+ return test_status;
+ }
+
+ desired_status = surface_tests[i].modifies_surface ? CAIRO_STATUS_SURFACE_TYPE_MISMATCH : CAIRO_STATUS_SUCCESS;
+ if (status != desired_status) {
+ cairo_test_log (ctx,
+ "Failed test %s: Surface status should be %u (%s), but is %u (%s)\n",
+ surface_tests[i].name,
+ desired_status, cairo_status_to_string (desired_status),
+ status, cairo_status_to_string (status));
+ return CAIRO_TEST_ERROR;
+ }
+ }
+
+ /* 565-compatible gray background */
+ cairo_set_source_rgb (cr, 0.51613, 0.55555, 0.51613);
+ cairo_paint (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (api_special_cases,
+ "Check surface functions properly handle wrong surface arguments",
+ "api", /* keywords */
+ NULL, /* requirements */
+ 10, 10,
+ preamble, draw)
diff --git a/test/arc-direction.c b/test/arc-direction.c
new file mode 100644
index 000000000..92c1a8d36
--- /dev/null
+++ b/test/arc-direction.c
@@ -0,0 +1,105 @@
+/*
+ * Copyright © 2012 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+#define SIZE (2 * 20)
+#define PAD (2)
+
+static cairo_test_status_t
+draw_arcs (cairo_t *cr)
+{
+ double start = M_PI/12, stop = 2*start;
+
+ cairo_move_to (cr, SIZE/2, SIZE/2);
+ cairo_arc (cr, SIZE/2, SIZE/2, SIZE/2, start, stop);
+ cairo_fill (cr);
+
+ cairo_translate (cr, SIZE+PAD, 0);
+ cairo_move_to (cr, SIZE/2, SIZE/2);
+ cairo_arc (cr, SIZE/2, SIZE/2, SIZE/2, 2*M_PI-stop, 2*M_PI-start);
+ cairo_fill (cr);
+
+ cairo_translate (cr, 0, SIZE+PAD);
+ cairo_move_to (cr, SIZE/2, SIZE/2);
+ cairo_arc_negative (cr, SIZE/2, SIZE/2, SIZE/2, 2*M_PI-stop, 2*M_PI-start);
+ cairo_fill (cr);
+
+ cairo_translate (cr, -SIZE-PAD, 0);
+ cairo_move_to (cr, SIZE/2, SIZE/2);
+ cairo_arc_negative (cr, SIZE/2, SIZE/2, SIZE/2, start, stop);
+ cairo_fill (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_save (cr);
+ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */
+ cairo_paint (cr);
+ cairo_restore (cr);
+
+ cairo_save (cr);
+ cairo_translate (cr, PAD, PAD);
+ draw_arcs(cr);
+ cairo_restore (cr);
+
+ cairo_set_source_rgb (cr, 1, 0, 0);
+ cairo_translate (cr, 2*SIZE+3*PAD, 0);
+ cairo_save (cr);
+ cairo_translate (cr, 2*SIZE+2*PAD, PAD);
+ cairo_scale (cr, -1, 1);
+ draw_arcs(cr);
+ cairo_restore (cr);
+
+ cairo_set_source_rgb (cr, 1, 0, 1);
+ cairo_translate (cr, 0, 2*SIZE+3*PAD);
+ cairo_save (cr);
+ cairo_translate (cr, 2*SIZE+2*PAD, 2*SIZE+2*PAD);
+ cairo_scale (cr, -1, -1);
+ draw_arcs(cr);
+ cairo_restore (cr);
+
+ cairo_set_source_rgb (cr, 0, 0, 1);
+ cairo_translate (cr, -(2*SIZE+3*PAD), 0);
+ cairo_save (cr);
+ cairo_translate (cr, PAD, 2*SIZE+2*PAD);
+ cairo_scale (cr, 1, -1);
+ draw_arcs(cr);
+ cairo_restore (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (arc_direction,
+ "Test drawing positive/negative arcs",
+ "arc, fill", /* keywords */
+ NULL, /* requirements */
+ 2*(3*PAD + 2*SIZE), 2*(3*PAD + 2*SIZE),
+ NULL, draw)
+
diff --git a/test/arc-infinite-loop.c b/test/arc-infinite-loop.c
new file mode 100644
index 000000000..8b469eacf
--- /dev/null
+++ b/test/arc-infinite-loop.c
@@ -0,0 +1,61 @@
+/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */
+/*
+ * Copyright 2010 Andrea Canciani
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Andrea Canciani <ranma42@gmail.com>
+ */
+
+#include "cairo-test.h"
+#include <float.h>
+
+#define SIZE 8
+
+/*
+ cairo_arc can hang in an infinite loop if given huge (so big that
+ adding/subtracting 4*M_PI to them doesn't change the value because
+ of floating point rounding).
+
+ The purpose of this test is to check that cairo doesn't hang or crash.
+*/
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+ /* Check if the code that guarantees start <= end hangs */
+ cairo_arc (cr, 0, 0, 1, 1024 / DBL_EPSILON * M_PI, 0);
+
+ /* Check if the code that handles huge angles hangs */
+ cairo_arc (cr, 0, 0, 1, 0, 1024 / DBL_EPSILON * M_PI);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (arc_infinite_loop,
+ "Test cairo_arc with huge angles",
+ "arc", /* keywords */
+ NULL, /* requirements */
+ SIZE, SIZE,
+ NULL, draw)
diff --git a/test/arc-looping-dash.c b/test/arc-looping-dash.c
new file mode 100644
index 000000000..ff5556a54
--- /dev/null
+++ b/test/arc-looping-dash.c
@@ -0,0 +1,79 @@
+/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */
+/*
+ * Copyright 2010 Andrea Canciani
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Andrea Canciani <ranma42@gmail.com>
+ */
+
+#include "cairo-test.h"
+
+#define SIZE 32
+
+/*
+ When cairo_arc is used to draw an arc of more than 2pi radians
+ (i.e. a circle "looping over itself"), various different behaviors
+ are possible:
+
+ - draw exactly a circle (an arc of 2pi radians)
+
+ - draw an arc such that the current point is the expected one and
+ that does at least a complete circle (an arc of [2pi, 4pi)
+ radians)
+
+ - draw an arc with the original number of loops
+
+ This test produces different results for each of these three cases.
+*/
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ double dashes[] = { 0.3, 7 };
+
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+ cairo_save (cr);
+
+ cairo_translate (cr, SIZE * .5, SIZE * .5);
+ cairo_scale (cr, SIZE * 3 / 8., SIZE * 3 / 8.);
+
+ cairo_arc (cr, 0, 0, 1, 0, 11 * M_PI);
+
+ cairo_set_line_width (cr, 8. / SIZE);
+
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ cairo_set_dash (cr, dashes, 2, 0);
+ cairo_stroke (cr);
+
+ cairo_restore (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (arc_looping_dash,
+ "Test cairo_arc for angles describing more than a complete circle",
+ "arc", /* keywords */
+ NULL, /* requirements */
+ SIZE, SIZE,
+ NULL, draw)
diff --git a/test/big-empty-box.c b/test/big-empty-box.c
new file mode 100644
index 000000000..4ea91a1ba
--- /dev/null
+++ b/test/big-empty-box.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+/*
+ * The mystery of the disappearing box, similar to big-little-box.
+ *
+ * The issue is that we failed to tighten the initial approximated bounds
+ * after tessellating the path.
+ */
+
+#include "cairo-test.h"
+
+#define SIZE 60
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_set_source_rgb (cr, 1, 0, 1);
+ cairo_paint (cr);
+
+ /* Set an unbounded operator so that we can see how accurate the bounded
+ * extents were.
+ */
+ cairo_set_operator (cr, CAIRO_OPERATOR_IN);
+ cairo_set_source_rgb (cr, 1, 1, 1);
+
+ /* Wind several boxes together that reduce to nothing */
+ cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
+ cairo_rectangle (cr, 0, 0, SIZE, SIZE);
+ cairo_rectangle (cr, 0, 0, SIZE, SIZE);
+ cairo_fill (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (big_empty_box,
+ "Tests that we tighten the bounds after tessellation.",
+ "fill", /* keywords */
+ NULL, /* requirements */
+ SIZE, SIZE,
+ NULL, draw)
diff --git a/test/big-empty-triangle.c b/test/big-empty-triangle.c
new file mode 100644
index 000000000..4c02c87a5
--- /dev/null
+++ b/test/big-empty-triangle.c
@@ -0,0 +1,75 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+/*
+ * A variation on
+ *
+ * https://bugzilla.mozilla.org/show_bug.cgi?id=668921
+ *
+ * The issue is that we failed to tighten the initial approximated bounds
+ * after tessellating the path.
+ */
+
+#include "cairo-test.h"
+
+#define SIZE 60
+
+static void
+triangle (cairo_t *cr, double x, double y, double h)
+{
+ cairo_move_to (cr, x, y);
+ cairo_line_to (cr, x+h/2, y+h);
+ cairo_line_to (cr, x+h, y);
+ cairo_close_path (cr);
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_set_source_rgb (cr, 1, 0, 1);
+ cairo_paint (cr);
+
+ /* Set an unbounded operator so that we can see how accurate the bounded
+ * extents were.
+ */
+ cairo_set_operator (cr, CAIRO_OPERATOR_IN);
+ cairo_set_source_rgb (cr, 1, 1, 1);
+
+ /* Wind several triangles together that reduce to nothing */
+ cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
+ triangle (cr, 0, 0, SIZE);
+ triangle (cr, 0, 0, SIZE);
+ cairo_fill (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (big_empty_triangle,
+ "Tests that we tighten the bounds after tessellation.",
+ "fill", /* keywords */
+ NULL, /* requirements */
+ SIZE, SIZE,
+ NULL, draw)
diff --git a/test/big-line.c b/test/big-line.c
new file mode 100644
index 000000000..6260fba12
--- /dev/null
+++ b/test/big-line.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright © 2008 Novell, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Novell, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Novell, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * NOVELL, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL NOVELL, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Larry Ewing <lewing@novell.com>
+ */
+
+#include "cairo-test.h"
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+ cairo_set_source_rgb (cr, 1, 1, 0);
+ cairo_move_to (cr, 50, 50);
+ cairo_rel_line_to (cr, 50000, 50000);
+ cairo_stroke (cr);
+
+ cairo_set_source_rgb (cr, 1, 0, 0);
+ cairo_move_to (cr, 50, 50);
+ cairo_rel_line_to (cr, -50000, 50000);
+ cairo_stroke (cr);
+
+ cairo_set_source_rgb (cr, 0, 1, 0);
+ cairo_move_to (cr, 50, 50);
+ cairo_rel_line_to (cr, 50000, -50000);
+ cairo_stroke (cr);
+
+ cairo_set_source_rgb (cr, 0, 0, 1);
+ cairo_move_to (cr, 50, 50);
+ cairo_rel_line_to (cr, -50000, -50000);
+ cairo_stroke (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (big_line,
+ "Test drawing of simple lines with positive and negative coordinates > 2^16",
+ "stroke, line", /* keywords */
+ NULL, /* requirements */
+ 100, 100,
+ NULL, draw)
diff --git a/test/big-little-box.c b/test/big-little-box.c
new file mode 100644
index 000000000..1787ee539
--- /dev/null
+++ b/test/big-little-box.c
@@ -0,0 +1,69 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+/*
+ * This attempts to exercise the bug found in
+ *
+ * https://bugzilla.mozilla.org/show_bug.cgi?id=668921
+ *
+ * and also identified by Taekyun Kim.
+ *
+ * The issue is that we failed to tighten the initial approximated bounds
+ * after tessellating the path.
+ */
+
+#include "cairo-test.h"
+
+#define SIZE 60
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_set_source_rgb (cr, 1, 0, 1);
+ cairo_paint (cr);
+
+ /* Set an unbounded operator so that we can see how accurate the bounded
+ * extents were.
+ */
+ cairo_set_operator (cr, CAIRO_OPERATOR_IN);
+ cairo_set_source_rgb (cr, 1, 1, 1);
+
+ /* Wind several boxes together that reduce to just one */
+ cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
+ cairo_rectangle (cr, 0, 0, SIZE, SIZE);
+ cairo_rectangle (cr, 0, 0, SIZE, SIZE);
+ cairo_rectangle (cr, SIZE/2 - 20, SIZE/2 - 20, 40, 40);
+ cairo_fill (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (big_little_box,
+ "Tests that we tighten the bounds after tessellation.",
+ "fill", /* keywords */
+ NULL, /* requirements */
+ SIZE, SIZE,
+ NULL, draw)
diff --git a/test/big-little-triangle.c b/test/big-little-triangle.c
new file mode 100644
index 000000000..27eb2325e
--- /dev/null
+++ b/test/big-little-triangle.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+/*
+ * A variation on
+ *
+ * https://bugzilla.mozilla.org/show_bug.cgi?id=668921
+ *
+ * The issue is that we failed to tighten the initial approximated bounds
+ * after tessellating the path.
+ */
+
+#include "cairo-test.h"
+
+#define SIZE 60
+
+static void
+triangle (cairo_t *cr, double x, double y, double h)
+{
+ cairo_move_to (cr, x, y);
+ cairo_line_to (cr, x+h/2, y+h);
+ cairo_line_to (cr, x+h, y);
+ cairo_close_path (cr);
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_set_source_rgb (cr, 1, 0, 1);
+ cairo_paint (cr);
+
+ /* Set an unbounded operator so that we can see how accurate the bounded
+ * extents were.
+ */
+ cairo_set_operator (cr, CAIRO_OPERATOR_IN);
+ cairo_set_source_rgb (cr, 1, 1, 1);
+
+ /* Wind several triangles together that reduce to just one */
+ cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
+ triangle (cr, 0, 0, SIZE);
+ triangle (cr, 0, 0, SIZE);
+ triangle (cr, SIZE/2-20, SIZE/2 - 20, 40);
+ cairo_fill (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (big_little_triangle,
+ "Tests that we tighten the bounds after tessellation.",
+ "fill", /* keywords */
+ NULL, /* requirements */
+ SIZE, SIZE,
+ NULL, draw)
diff --git a/test/big-trap.c b/test/big-trap.c
new file mode 100644
index 000000000..5e11237a8
--- /dev/null
+++ b/test/big-trap.c
@@ -0,0 +1,92 @@
+/*
+ * Copyright © 2006 Mozilla Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Mozilla Corporation not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Mozilla Corporation makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * MOZILLA CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL MOZILLA CORPORATION BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Vladimir Vukicevic <vladimir@pobox.com>
+ */
+
+#include "cairo-test.h"
+
+/* This test was originally written to exercise a bug in pixman in
+ * which it would scribble all over memory when given a particular
+ * (and bogus) trapezoid. However, a recent change to
+ * _cairo_fixed_from_double changed the details of the bogus trapezoid
+ * (it overflows in a different way now), so the bug is being masked.
+ *
+ * According to Vladimir, (http://lists.freedesktop.org/archives/cairo/2006-November/008482.html):
+ *
+ * Before the change, the two trapezoids that were generated were:
+ *
+ * Trap[0]: T: 0x80000000 B: 0x80000003
+ * L: [(0x000a0000, 0x80000000) (0x00080000, 0x00080000)]
+ * R: [(0x01360000, 0x80000000) (0x01380000, 0x00080000)]
+ * Trap[1]: T: 0x80000003 B: 0x00080000
+ * L: [(0x000a0000, 0x80000000) (0x00080000, 0x00080000)]
+ * R: [(0x01360000, 0x80000000) (0x01380000, 0x00080000)]
+ *
+ * After the change, the L/R coordinates are identical for both traps, but
+ * the top and bottom change:
+ *
+ * Trap[0]: t: 0x80000000 b: 0xfda80003
+ * l: [(0x000a0000, 0x80000000) (0x00080000, 0x00080000)]
+ * r: [(0x01360000, 0x80000000) (0x01380000, 0x00080000)]
+ * Trap[1]: t: 0xfda80003 b: 0x00080000
+ * l: [(0x000a0000, 0x80000000) (0x00080000, 0x00080000)]
+ * r: [(0x01360000, 0x80000000) (0x01380000, 0x00080000)]
+ *
+ * I think the fix we want here is to rewrite this test to call
+ * directly into pixman with the trapezoid of interest, (which will
+ * require adding a new way to configure cairo for "testing" which
+ * will prevent the hiding of internal library symbols.
+ */
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_set_source_rgb (cr, 1,1,1);
+ cairo_paint (cr);
+
+ cairo_set_source_rgb (cr, 0,0,0);
+
+ /* Note that without the clip, this doesn't crash... */
+ cairo_new_path (cr);
+ cairo_rectangle (cr, 0, 0, width, height);
+ cairo_clip (cr);
+
+ cairo_new_path (cr);
+ cairo_line_to (cr, 8.0, 8.0);
+ cairo_line_to (cr, 312.0, 8.0);
+ cairo_line_to (cr, 310.0, 31378756.2666666666);
+ cairo_line_to (cr, 10.0, 31378756.2666666666);
+ cairo_line_to (cr, 8.0, 8.0);
+ cairo_fill (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+/* XFAIL: range overflow of fixed-point */
+CAIRO_TEST (big_trap,
+ "Test oversize trapezoid with a clip region"
+ "\nTest needs to be adjusted to trigger the original bug",
+ "trap", /* keywords */
+ NULL, /* requirements */
+ 100, 100,
+ NULL, draw)
diff --git a/test/bilevel-image.c b/test/bilevel-image.c
new file mode 100644
index 000000000..4feff0e7a
--- /dev/null
+++ b/test/bilevel-image.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright © 2008 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Chris Wilson not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Chris Wilson makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+#define RGBx 0xffff0000, 0xff00ff00, 0xff0000ff, 0x00000000
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ uint32_t data[] = {
+ RGBx, RGBx, RGBx,
+ RGBx, RGBx, RGBx,
+ RGBx, RGBx, RGBx,
+ RGBx, RGBx, RGBx,
+ };
+ cairo_surface_t *mask;
+
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+ mask = cairo_image_surface_create_for_data ((unsigned char *) data,
+ CAIRO_FORMAT_ARGB32, 12, 4, 48);
+
+ cairo_set_source_surface (cr, mask, 0, 0);
+ cairo_pattern_set_filter (cairo_get_source (cr), CAIRO_FILTER_NEAREST);
+
+ cairo_paint (cr);
+
+ cairo_surface_finish (mask); /* data goes out of scope */
+ cairo_surface_destroy (mask);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (bilevel_image,
+ "Test that PS can embed an RGB image with a bilevel alpha channel.",
+ "alpha, ps", /* keywords */
+ NULL, /* requirements */
+ 12, 4,
+ NULL, draw)
diff --git a/test/bitmap-font.c b/test/bitmap-font.c
new file mode 100644
index 000000000..0ec9b3de5
--- /dev/null
+++ b/test/bitmap-font.c
@@ -0,0 +1,218 @@
+/*
+ * Copyright © 2005 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+#include "cairo-test.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <cairo-ft.h>
+#include <fontconfig/fontconfig.h>
+#include <fontconfig/fcfreetype.h>
+
+#define FONT "6x13.pcf"
+#define TEXT_SIZE 13
+
+static cairo_bool_t
+font_extents_equal (const cairo_font_extents_t *A,
+ const cairo_font_extents_t *B)
+{
+ return
+ CAIRO_TEST_DOUBLE_EQUALS (A->ascent, B->ascent) &&
+ CAIRO_TEST_DOUBLE_EQUALS (A->descent, B->descent) &&
+ CAIRO_TEST_DOUBLE_EQUALS (A->height, B->height) &&
+ CAIRO_TEST_DOUBLE_EQUALS (A->max_x_advance, B->max_x_advance) &&
+ CAIRO_TEST_DOUBLE_EQUALS (A->max_y_advance, B->max_y_advance);
+}
+
+static cairo_test_status_t
+check_font_extents (const cairo_test_context_t *ctx, cairo_t *cr, const char *comment)
+{
+ cairo_font_extents_t font_extents, ref_font_extents = {11, 2, 13, 6, 0};
+ cairo_status_t status;
+
+ memset (&font_extents, 0xff, sizeof (cairo_font_extents_t));
+ cairo_font_extents (cr, &font_extents);
+
+ status = cairo_status (cr);
+ if (status)
+ return cairo_test_status_from_status (ctx, status);
+
+ if (! font_extents_equal (&font_extents, &ref_font_extents)) {
+ cairo_test_log (ctx, "Error: %s: cairo_font_extents(); extents (%g, %g, %g, %g, %g)\n",
+ comment,
+ font_extents.ascent, font_extents.descent,
+ font_extents.height,
+ font_extents.max_x_advance, font_extents.max_y_advance);
+ return CAIRO_TEST_FAILURE;
+ }
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ const cairo_test_context_t *ctx = cairo_test_get_context (cr);
+ FcPattern *pattern;
+ cairo_font_face_t *font_face;
+ cairo_font_extents_t font_extents;
+ cairo_font_options_t *font_options;
+ cairo_status_t status;
+ char *filename;
+ int face_count;
+ struct stat stat_buf;
+
+ xasprintf (&filename, "%s/%s", ctx->srcdir, FONT);
+
+ if (stat (filename, &stat_buf) || ! S_ISREG (stat_buf.st_mode)) {
+ cairo_test_log (ctx, "Error finding font: %s: file not found?\n", filename);
+ return CAIRO_TEST_FAILURE;
+ }
+
+ pattern = FcFreeTypeQuery ((unsigned char *)filename, 0, NULL, &face_count);
+ free (filename);
+ if (! pattern) {
+ cairo_test_log (ctx, "FcFreeTypeQuery failed.\n");
+ return cairo_test_status_from_status (ctx, CAIRO_STATUS_NO_MEMORY);
+ }
+
+ font_face = cairo_ft_font_face_create_for_pattern (pattern);
+ FcPatternDestroy (pattern);
+
+ status = cairo_font_face_status (font_face);
+ if (status) {
+ cairo_test_log (ctx, "Error creating font face for %s: %s\n",
+ filename,
+ cairo_status_to_string (status));
+ return cairo_test_status_from_status (ctx, status);
+ }
+
+ if (cairo_font_face_get_type (font_face) != CAIRO_FONT_TYPE_FT) {
+ cairo_test_log (ctx, "Unexpected value from cairo_font_face_get_type: %d (expected %d)\n",
+ cairo_font_face_get_type (font_face), CAIRO_FONT_TYPE_FT);
+ cairo_font_face_destroy (font_face);
+ return CAIRO_TEST_FAILURE;
+ }
+
+ cairo_set_font_face (cr, font_face);
+ cairo_font_face_destroy (font_face);
+ cairo_set_font_size (cr, 13);
+
+ font_options = cairo_font_options_create ();
+
+#define CHECK_FONT_EXTENTS(comment) do {\
+ cairo_test_status_t test_status; \
+ test_status = check_font_extents (ctx, cr, (comment)); \
+ if (test_status != CAIRO_TEST_SUCCESS) { \
+ cairo_font_options_destroy (font_options); \
+ return test_status; \
+ } \
+} while (0)
+
+ cairo_font_extents (cr, &font_extents);
+ CHECK_FONT_EXTENTS ("default");
+
+ cairo_font_options_set_hint_metrics (font_options, CAIRO_HINT_METRICS_ON);
+ cairo_set_font_options (cr, font_options);
+
+ CHECK_FONT_EXTENTS ("HINT_METRICS_ON");
+
+ cairo_move_to (cr, 1, font_extents.ascent - 1);
+ cairo_set_source_rgb (cr, 0.0, 0.0, 1.0); /* blue */
+
+ cairo_font_options_set_hint_style (font_options, CAIRO_HINT_STYLE_NONE);
+ cairo_set_font_options (cr, font_options);
+ CHECK_FONT_EXTENTS ("HINT_METRICS_ON HINT_STYLE_NONE");
+ cairo_show_text (cr, "the ");
+
+ cairo_font_options_set_hint_style (font_options, CAIRO_HINT_STYLE_SLIGHT);
+ cairo_set_font_options (cr, font_options);
+ CHECK_FONT_EXTENTS ("HINT_METRICS_ON HINT_STYLE_SLIGHT");
+ cairo_show_text (cr, "quick ");
+
+ cairo_font_options_set_hint_style (font_options, CAIRO_HINT_STYLE_MEDIUM);
+ cairo_set_font_options (cr, font_options);
+ CHECK_FONT_EXTENTS ("HINT_METRICS_ON HINT_STYLE_MEDIUM");
+ cairo_show_text (cr, "brown");
+
+ cairo_font_options_set_hint_style (font_options, CAIRO_HINT_STYLE_FULL);
+ cairo_set_font_options (cr, font_options);
+ CHECK_FONT_EXTENTS ("HINT_METRICS_ON HINT_STYLE_FULL");
+ cairo_show_text (cr, " fox");
+
+ /* Switch from show_text to text_path/fill to exercise bug #7889 */
+ cairo_text_path (cr, " jumps over a lazy dog");
+ cairo_fill (cr);
+
+ /* And test it rotated as well for the sake of bug #7888 */
+
+ cairo_translate (cr, width, height);
+ cairo_rotate (cr, M_PI);
+
+ cairo_font_options_set_hint_style (font_options, CAIRO_HINT_STYLE_DEFAULT);
+ cairo_font_options_set_hint_metrics (font_options, CAIRO_HINT_METRICS_OFF);
+ cairo_set_font_options (cr, font_options);
+ CHECK_FONT_EXTENTS ("HINT_METRICS_OFF");
+
+ cairo_move_to (cr, 1, font_extents.height - font_extents.descent - 1);
+
+ cairo_font_options_set_hint_style (font_options, CAIRO_HINT_STYLE_NONE);
+ cairo_set_font_options (cr, font_options);
+ CHECK_FONT_EXTENTS ("HINT_METRICS_OFF HINT_STYLE_NONE");
+ cairo_show_text (cr, "the ");
+
+ cairo_font_options_set_hint_style (font_options, CAIRO_HINT_STYLE_SLIGHT);
+ cairo_set_font_options (cr, font_options);
+ CHECK_FONT_EXTENTS ("HINT_METRICS_OFF HINT_STYLE_SLIGHT");
+ cairo_show_text (cr, "quick");
+
+ cairo_font_options_set_hint_style (font_options, CAIRO_HINT_STYLE_MEDIUM);
+ cairo_set_font_options (cr, font_options);
+ CHECK_FONT_EXTENTS ("HINT_METRICS_OFF HINT_STYLE_MEDIUM");
+ cairo_show_text (cr, " brown");
+
+ cairo_font_options_set_hint_style (font_options, CAIRO_HINT_STYLE_FULL);
+ cairo_set_font_options (cr, font_options);
+ CHECK_FONT_EXTENTS ("HINT_METRICS_OFF HINT_STYLE_FULL");
+ cairo_show_text (cr, " fox");
+
+ cairo_text_path (cr, " jumps over");
+ cairo_text_path (cr, " a lazy dog");
+ cairo_fill (cr);
+
+ cairo_font_options_destroy (font_options);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (bitmap_font,
+ "Test drawing with a font consisting only of bitmaps"
+ "\nThe PDF and PS backends embed a slightly distorted font for the rotated case.",
+ "text", /* keywords */
+ "ft", /* requirements */
+ 246 + 1, 2 * TEXT_SIZE,
+ NULL, draw)
diff --git a/test/blur.c b/test/blur.c
new file mode 100644
index 000000000..92b536712
--- /dev/null
+++ b/test/blur.c
@@ -0,0 +1,105 @@
+/*
+ * Copyright © 2013 Samsung Electronics
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ * Bryce Harrington <b.harrington@samsung.com>
+ * Henry Song <henry.song@samsung.com>
+ */
+
+/* This test exercises gaussian blur rendering
+ */
+
+/* When we build only for backends other than gl,
+ include <cairo-gl.h> in blur.c will give errors.
+*/
+#if 0
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+
+#include <cairo.h>
+#include <cairo-gl.h>
+#endif
+
+#include "cairo-test.h"
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ const cairo_test_context_t *ctx = cairo_test_get_context (cr);
+
+ int line_width = 20;
+ int x = width / 2;
+ int y = height / 2;
+ int radius = width / 4;
+
+ cairo_save (cr);
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+ cairo_restore (cr);
+
+ cairo_save (cr);
+
+ /* drop shadow */
+ cairo_arc (cr, x, y, radius, 0, 2 * M_PI);
+ cairo_set_line_width (cr, line_width);
+ cairo_set_draw_shadow_only (cr, 1);
+ cairo_set_shadow (cr, CAIRO_SHADOW_DROP);
+ cairo_set_shadow_rgba (cr, 0, 0, 0, 0.8);
+ cairo_set_shadow_blur (cr, 10, 10);
+ cairo_set_shadow_offset (cr, -42, -7);
+ cairo_stroke (cr);
+
+ /* ring with inset shadow */
+ cairo_arc (cr, x, y, radius, 0, 2 * M_PI);
+ cairo_set_line_width (cr, line_width);
+ cairo_set_source_rgb (cr, 0, 0.5, 0);
+ cairo_set_draw_shadow_only (cr, 0);
+ cairo_set_shadow (cr, CAIRO_SHADOW_INSET);
+ cairo_set_shadow_rgba (cr, 0, 0, 0, 1);
+ cairo_set_shadow_blur (cr, 5, 2);
+ cairo_set_shadow_offset (cr, 6, 1);
+ cairo_stroke (cr);
+
+ /* draw spread */
+ cairo_set_draw_shadow_only (cr, 1);
+ cairo_set_shadow (cr, CAIRO_SHADOW_DROP);
+ cairo_set_shadow_rgba (cr, 1, 1, 1, 1);
+ cairo_set_shadow_blur (cr, 5, 2);
+ cairo_set_line_width (cr, line_width/5);
+ cairo_set_source_rgb (cr, 0, 0.5, 0);
+ cairo_set_shadow_offset (cr, 6, 1);
+ cairo_arc (cr, x, y, radius, 0, 2 * M_PI);
+ cairo_stroke (cr);
+
+ cairo_restore (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (blur,
+ "Tests gaussian blur of a drawn image",
+ "gl, blur, operator", /* keywords */
+ NULL, /* requirements */
+ 256, 256,
+ NULL, draw)
diff --git a/test/buffer-diff.c b/test/buffer-diff.c
new file mode 100644
index 000000000..f3d90ca0d
--- /dev/null
+++ b/test/buffer-diff.c
@@ -0,0 +1,268 @@
+/* imagediff - Compare two images
+ *
+ * Copyright © 2004 Richard D. Worth
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of Richard Worth
+ * not be used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * Richard Worth makes no representations about the suitability of this
+ * software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ *
+ * RICHARD WORTH DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
+ * NO EVENT SHALL RICHARD WORTH BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+ * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Richard D. Worth <richard@theworths.org> */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <errno.h>
+#include <string.h>
+#include <pixman.h>
+
+#include "cairo-test.h"
+
+#include "pdiff.h"
+#include "buffer-diff.h"
+
+/* Don't allow any differences greater than this value, even if pdiff
+ * claims that the images are identical */
+#define PERCEPTUAL_DIFF_THRESHOLD 256
+
+/* Compare two buffers, returning the number of pixels that are
+ * different and the maximum difference of any single color channel in
+ * result_ret.
+ *
+ * This function should be rewritten to compare all formats supported by
+ * cairo_format_t instead of taking a mask as a parameter.
+ */
+static void
+buffer_diff_core (const unsigned char *_buf_a, int stride_a,
+ const unsigned char *_buf_b, int stride_b,
+ unsigned char *_buf_diff, int stride_diff,
+ int width,
+ int height,
+ uint32_t mask,
+ buffer_diff_result_t *result_ret)
+{
+ const uint32_t *buf_a = (const uint32_t*) _buf_a;
+ const uint32_t *buf_b = (const uint32_t*) _buf_b;
+ uint32_t *buf_diff = (uint32_t*) _buf_diff;
+ int x, y;
+ buffer_diff_result_t result = {0, 0};
+
+ stride_a /= sizeof (uint32_t);
+ stride_b /= sizeof (uint32_t);
+ stride_diff /= sizeof (uint32_t);
+ for (y = 0; y < height; y++) {
+ const uint32_t *row_a = buf_a + y * stride_a;
+ const uint32_t *row_b = buf_b + y * stride_b;
+ uint32_t *row = buf_diff + y * stride_diff;
+
+ for (x = 0; x < width; x++) {
+ /* check if the pixels are the same */
+ if ((row_a[x] & mask) != (row_b[x] & mask)) {
+ int channel;
+ uint32_t diff_pixel = 0;
+
+ /* calculate a difference value for all 4 channels */
+ for (channel = 0; channel < 4; channel++) {
+ int value_a = (row_a[x] >> (channel*8)) & 0xff;
+ int value_b = (row_b[x] >> (channel*8)) & 0xff;
+ unsigned int diff;
+ diff = abs (value_a - value_b);
+ if (diff > result.max_diff)
+ result.max_diff = diff;
+ diff *= 4; /* emphasize */
+ if (diff)
+ diff += 128; /* make sure it's visible */
+ if (diff > 255)
+ diff = 255;
+ diff_pixel |= diff << (channel*8);
+ }
+
+ result.pixels_changed++;
+ if ((diff_pixel & 0x00ffffff) == 0) {
+ /* alpha only difference, convert to luminance */
+ uint8_t alpha = diff_pixel >> 24;
+ diff_pixel = alpha * 0x010101;
+ }
+ row[x] = diff_pixel;
+ } else {
+ row[x] = 0;
+ }
+ row[x] |= 0xff000000; /* Set ALPHA to 100% (opaque) */
+ }
+ }
+
+ *result_ret = result;
+}
+
+/* Compares two image surfaces
+ *
+ * Provides number of pixels changed and maximum single-channel
+ * difference in result.
+ *
+ * Also fills in a "diff" surface intended to visually show where the
+ * images differ.
+ */
+static void
+compare_surfaces (const cairo_test_context_t *ctx,
+ cairo_surface_t *surface_a,
+ cairo_surface_t *surface_b,
+ cairo_surface_t *surface_diff,
+ buffer_diff_result_t *result)
+{
+ /* These default values were taken straight from the
+ * perceptualdiff program. We'll probably want to tune these as
+ * necessary. */
+ double gamma = 2.2;
+ double luminance = 100.0;
+ double field_of_view = 45.0;
+ float pixels_changed_percentage = 0.05;
+ int discernible_pixels_changed;
+ int pixels_tolerance;
+ int width, height;
+
+ /* First, we run cairo's old buffer_diff algorithm which looks for
+ * pixel-perfect images, (we do this first since the test suite
+ * runs about 3x slower if we run pdiff_compare first).
+ */
+ buffer_diff_core (cairo_image_surface_get_data (surface_a),
+ cairo_image_surface_get_stride (surface_a),
+ cairo_image_surface_get_data (surface_b),
+ cairo_image_surface_get_stride (surface_b),
+ cairo_image_surface_get_data (surface_diff),
+ cairo_image_surface_get_stride (surface_diff),
+ cairo_image_surface_get_width (surface_a),
+ cairo_image_surface_get_height (surface_a),
+ cairo_surface_get_content (surface_a) & CAIRO_CONTENT_ALPHA ? 0xffffffff : 0x00ffffff,
+ result);
+ if (result->pixels_changed == 0)
+ return;
+
+ cairo_test_log (ctx,
+ "%d pixels differ (with maximum difference of %d) from reference image\n",
+ result->pixels_changed, result->max_diff);
+
+ /* Then, if there are any different pixels, we give the pdiff code
+ * a crack at the images. If it decides that there are no visually
+ * discernible differences in any pixels, then we accept this
+ * result as good enough.
+ *
+ * Only let pdiff have a crack at the comparison if the max difference
+ * is lower than a threshold, otherwise some problems could be masked.
+ */
+ if (result->max_diff < PERCEPTUAL_DIFF_THRESHOLD) {
+ width = cairo_image_surface_get_width (surface_a);
+ height = cairo_image_surface_get_height (surface_a);
+ pixels_tolerance = width * height * pixels_changed_percentage;
+ discernible_pixels_changed = pdiff_compare (surface_a, surface_b,
+ gamma, luminance, field_of_view);
+ if (discernible_pixels_changed <= pixels_tolerance) {
+ result->pixels_changed = 0;
+ cairo_test_log (ctx,
+ "But perceptual diff finds no visually discernible difference.\n"
+ "Accepting result.\n");
+ }
+ }
+}
+
+void
+buffer_diff_noalpha (const unsigned char *buf_a,
+ const unsigned char *buf_b,
+ unsigned char *buf_diff,
+ int width,
+ int height,
+ int stride,
+ buffer_diff_result_t *result)
+{
+ buffer_diff_core(buf_a, stride,
+ buf_b, stride,
+ buf_diff, stride,
+ width, height,
+ 0x00ffffff,
+ result);
+}
+
+static cairo_bool_t
+same_size (cairo_surface_t *a, cairo_surface_t *b)
+{
+ unsigned int width_a, height_a;
+ unsigned int width_b, height_b;
+
+ width_a = cairo_image_surface_get_width (a);
+ height_a = cairo_image_surface_get_height (a);
+
+ width_b = cairo_image_surface_get_width (b);
+ height_b = cairo_image_surface_get_height (b);
+
+ return width_a == width_b && height_a == height_b;
+}
+
+/* Image comparison code courtesy of Richard Worth <richard@theworths.org>
+ * Returns number of pixels changed, (or -1 on error).
+ * Also saves a "diff" image intended to visually show where the
+ * images differ.
+ *
+ * The return value simply indicates whether a check was successfully
+ * made, (as opposed to a file-not-found condition or similar). It
+ * does not indicate anything about how much the images differ. For
+ * that, see result.
+ *
+ * One failure mode is if the two images provided do not have the same
+ * dimensions. In this case, this function will return
+ * CAIRO_STATUS_SURFACE_TYPE_MISMATCH (which is a bit of an abuse, but
+ * oh well).
+ */
+cairo_status_t
+image_diff (const cairo_test_context_t *ctx,
+ cairo_surface_t *surface_a,
+ cairo_surface_t *surface_b,
+ cairo_surface_t *surface_diff,
+ buffer_diff_result_t *result)
+{
+ if (cairo_surface_status (surface_a))
+ return cairo_surface_status (surface_a);
+
+ if (cairo_surface_status (surface_b))
+ return cairo_surface_status (surface_b);
+
+ if (cairo_surface_status (surface_diff))
+ return cairo_surface_status (surface_diff);
+
+ if (! same_size (surface_a, surface_b) ||
+ ! same_size (surface_a, surface_diff))
+ {
+ cairo_test_log (ctx, "Error: Image size mismatch\n");
+ return CAIRO_STATUS_SURFACE_TYPE_MISMATCH;
+ }
+
+ compare_surfaces (ctx, surface_a, surface_b, surface_diff, result);
+
+ return CAIRO_STATUS_SUCCESS;
+}
+
+cairo_bool_t
+image_diff_is_failure (const buffer_diff_result_t *result,
+ unsigned int tolerance)
+{
+ return result->pixels_changed &&
+ result->max_diff > tolerance;
+}
diff --git a/test/buffer-diff.h b/test/buffer-diff.h
new file mode 100644
index 000000000..2cbb8959c
--- /dev/null
+++ b/test/buffer-diff.h
@@ -0,0 +1,73 @@
+/* imagediff - Compare two images
+ *
+ * Copyright © 2004 Richard D. Worth
+ * Copyright © 2006 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of the authors
+ * not be used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * The authors make no representations about the suitability of this
+ * software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ *
+ * THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
+ * NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+ * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Richard D. Worth <richard@theworths.org>
+ * Carl Worth <cworth@cworth.org>
+ */
+
+#ifndef BUFFER_DIFF_H
+#define BUFFER_DIFF_H
+
+#include "cairo-test.h"
+
+typedef struct _buffer_diff_result {
+ unsigned int pixels_changed;
+ unsigned int max_diff;
+} buffer_diff_result_t;
+
+/* Compares two image buffers ignoring the alpha channel.
+ *
+ * Provides number of pixels changed and maximum single-channel
+ * difference in result.
+ *
+ * Also fills in a "diff" buffer intended to visually show where the
+ * images differ.
+ */
+void
+buffer_diff_noalpha (const unsigned char *buf_a,
+ const unsigned char *buf_b,
+ unsigned char *buf_diff,
+ int width,
+ int height,
+ int stride,
+ buffer_diff_result_t *result);
+
+/* The central algorithm to compare two images, and return the differences
+ * in the surface_diff.
+ *
+ * Provides number of pixels changed and maximum single-channel
+ * difference in result.
+ */
+cairo_status_t
+image_diff (const cairo_test_context_t *ctx,
+ cairo_surface_t *surface_a,
+ cairo_surface_t *surface_b,
+ cairo_surface_t *surface_diff,
+ buffer_diff_result_t *result);
+
+cairo_bool_t
+image_diff_is_failure (const buffer_diff_result_t *result,
+ unsigned int tolerance);
+
+#endif
diff --git a/test/bug-40410.c b/test/bug-40410.c
new file mode 100644
index 000000000..2d6e512c0
--- /dev/null
+++ b/test/bug-40410.c
@@ -0,0 +1,72 @@
+/*
+ * Copyright © 2011 Krzysztof Kosiński
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Krzysztof Kosiński <tweenk.pl@gmail.com>
+ */
+
+#include "cairo-test.h"
+
+#define WIDTH 300
+#define HEIGHT 100
+
+/*
+ * The bug appears to be triggered if:
+ * 1. There is more than one subpath
+ * 2. All subpaths are axis-aligned rectangles
+ * 3. Only one of the subpaths is within surface bounds
+ *
+ * Tweaking any of the coordinates so that there is at least one
+ * non-axis-aligned segment or removing the second subpath (the one that is
+ * outside the surface bounds) causes the bug to disappear.
+ */
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_set_source_rgb (cr, 1,1,1);
+ cairo_paint (cr);
+
+ cairo_move_to (cr, 10.3, 10.6);
+ cairo_line_to (cr, 10.3, 150.2);
+ cairo_line_to (cr, 290.1, 150.2);
+ cairo_line_to (cr, 290.1, 10.6);
+ cairo_close_path (cr);
+
+ cairo_move_to (cr, 10.3, 180.7);
+ cairo_line_to (cr, 10.3, 230.2);
+ cairo_line_to (cr, 290.1, 230.2);
+ cairo_line_to (cr, 290.1, 180.7);
+ cairo_close_path (cr);
+
+ cairo_set_source_rgb (cr, 1, 0, 0);
+ cairo_fill (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (bug_40410,
+ "Exercises a bug found in 1.10.2 (and never again!)",
+ "fill", /* keywords */
+ "target=raster", /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw)
diff --git a/test/bug-51910.c b/test/bug-51910.c
new file mode 100644
index 000000000..37881de3e
--- /dev/null
+++ b/test/bug-51910.c
@@ -0,0 +1,91 @@
+/*
+ * Copyright © 2012 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include "cairo-test.h"
+
+/* An error in xlib pattern transformation discovered by Albertas Vyšniauskas */
+
+static cairo_pattern_t *
+source(void)
+{
+ cairo_surface_t *surface;
+ cairo_pattern_t *pattern;
+ cairo_matrix_t matrix;
+ cairo_t *cr;
+ int i;
+
+ surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, 32, 32);
+ cr = cairo_create (surface);
+ cairo_surface_destroy (surface);
+
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+ cairo_set_source_rgb (cr, .5, .5, .5);
+ cairo_set_line_width (cr, 2);
+
+ for (i = -1; i <= 8; i++) {
+ cairo_move_to (cr, -34 + 8*i, 34);
+ cairo_rel_line_to (cr, 36, -36);
+ cairo_stroke (cr);
+ }
+
+ pattern = cairo_pattern_create_for_surface (cairo_get_target (cr));
+ cairo_destroy (cr);
+
+ cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT);
+
+ cairo_matrix_init_translate(&matrix, 14.1, 0);
+ cairo_pattern_set_matrix(pattern, &matrix);
+
+ return pattern;
+}
+
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_pattern_t *pattern;
+ int i;
+
+ cairo_paint (cr);
+
+ pattern = source ();
+ cairo_set_source (cr, pattern);
+ cairo_pattern_destroy (pattern);
+
+ for (i = 0; i < 8; i++) {
+ cairo_rectangle (cr, 3.5*i, 32*i, 256, 32);
+ cairo_fill (cr);
+ }
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (bug_51910,
+ "A bug in the xlib pattern transformation",
+ " paint", /* keywords */
+ NULL, /* requirements */
+ 256, 256,
+ NULL, draw)
diff --git a/test/bug-84115.c b/test/bug-84115.c
new file mode 100644
index 000000000..4db113c5c
--- /dev/null
+++ b/test/bug-84115.c
@@ -0,0 +1,61 @@
+/*
+ * Copyright © 2011 Krzysztof Kosiński
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Krzysztof Kosiński <tweenk.pl@gmail.com>
+ */
+
+#include "cairo-test.h"
+
+#define WIDTH 800
+#define HEIGHT 800
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ double lw = 800;
+ int n = 0;
+
+ cairo_set_source_rgb (cr, 1,1,1);
+ cairo_paint (cr);
+
+ cairo_set_source_rgba (cr, 0, 0, 0, .4);
+ cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT);
+ do {
+ cairo_set_line_width(cr, lw);
+ cairo_arc(cr, WIDTH/2, HEIGHT/2, lw/2,
+ 2*M_PI*(13*n + 1) / 130, 2*M_PI*(13*n + 12) / 130);
+ cairo_stroke(cr);
+
+ n++;
+ lw /= 1.1;
+ } while (lw > 0.5);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (bug_84115,
+ "Exercises a bug found in stroke generation using trapezoids",
+ "stroke", /* keywords */
+ NULL, /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw)
diff --git a/test/bug-bo-collins.c b/test/bug-bo-collins.c
new file mode 100644
index 000000000..cf6d688e3
--- /dev/null
+++ b/test/bug-bo-collins.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright © 2012 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+ cairo_set_source_rgb (cr, 0, 0, 0);
+
+ cairo_translate (cr, 0, 0);
+ cairo_save (cr);
+ cairo_rectangle (cr, 10, 10, 20, 20);
+ cairo_rectangle (cr, 20, 10, -10, 10);
+ cairo_clip (cr);
+ cairo_paint (cr);
+ cairo_restore (cr);
+
+ cairo_translate (cr, 40, 0);
+ cairo_save (cr);
+ cairo_rectangle (cr, 10, 10, 20, 20);
+ cairo_rectangle (cr, 30, 10, -10, 10);
+ cairo_clip (cr);
+ cairo_paint (cr);
+ cairo_restore (cr);
+
+ cairo_translate (cr, 0, 40);
+ cairo_save (cr);
+ cairo_rectangle (cr, 10, 10, 20, 20);
+ cairo_rectangle (cr, 30, 20, -10, 10);
+ cairo_clip (cr);
+ cairo_paint (cr);
+ cairo_restore (cr);
+
+ cairo_translate (cr, -40, 0);
+ cairo_save (cr);
+ cairo_rectangle (cr, 10, 10, 20, 20);
+ cairo_rectangle (cr, 20, 20, -10, 10);
+ cairo_clip (cr);
+ cairo_paint (cr);
+ cairo_restore (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (bug_bo_collins,
+ "Exercises a bug discovered by S. Christian Collins",
+ "clip, rectangular", /* keywords */
+ NULL, /* requirements */
+ 80, 80,
+ NULL, draw)
diff --git a/test/bug-bo-rectangular.c b/test/bug-bo-rectangular.c
new file mode 100644
index 000000000..08e2e494a
--- /dev/null
+++ b/test/bug-bo-rectangular.c
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2010 Red Hat
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Intel not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Intel makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Benjamin Otte <otte@gnome.com>
+ */
+
+#include "cairo-test.h"
+
+static void
+rect (cairo_t *cr, int x1, int y1, int x2, int y2)
+{
+ cairo_rectangle (cr, x1, y1, x2 - x1, y2 - y1);
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+ cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
+
+ cairo_scale (cr, 1./256, 1./256);
+
+ rect (cr, 0, 0, 29696, 7680);
+ rect (cr, 0, 0, -15360, 15360);
+ cairo_clip (cr);
+
+ cairo_set_source_rgb (cr, 1, 0.5, 0);
+ cairo_paint (cr);
+
+ rect (cr, 9984, 0, 2969, 3840);
+ rect (cr, 0, 3840, 9472, 7680);
+ cairo_clip (cr);
+
+ rect (cr, 0, 3840, 3584, 7680);
+ cairo_set_source_rgb (cr, 1, 0, 0.5);
+ cairo_fill (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (bug_bo_rectangular,
+ "Tests a bug found by Benjamin Otte in the rectangular tessellator",
+ "tessellator", /* keywords */
+ NULL, /* requirements */
+ 300, 300,
+ NULL, draw)
diff --git a/test/bug-bo-ricotz.c b/test/bug-bo-ricotz.c
new file mode 100644
index 000000000..9524d208d
--- /dev/null
+++ b/test/bug-bo-ricotz.c
@@ -0,0 +1,74 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+/* An assertion failure found by Rico Tzschichholz */
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+ cairo_set_source_rgb (cr, 0, 0, 0);
+
+ cairo_rectangle (cr, 10, 55,165, 1);
+ cairo_rectangle (cr, 174, 55,1, 413);
+ cairo_rectangle (cr, 10, 56, 1, 413);
+ cairo_rectangle (cr, 10, 469, 165, 1);
+ cairo_clip (cr);
+
+ cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
+
+ cairo_move_to (cr, 10, 57);
+ cairo_curve_to (cr, 10, 55.894531, 10.894531, 55, 12, 55);
+ cairo_line_to (cr, 173, 55);
+ cairo_curve_to (cr, 174.105469, 55, 175, 55.894531, 175, 57);
+ cairo_line_to (cr, 175, 468);
+ cairo_curve_to (cr, 175, 469.105469, 174.105469, 470, 173, 470);
+ cairo_line_to (cr, 12, 470);
+ cairo_curve_to (cr, 10.894531, 470, 10, 469.105469, 10, 468);
+
+ cairo_move_to (cr, 11, 57);
+ cairo_curve_to (cr, 11, 56.449219, 11.449219, 56, 12, 56);
+ cairo_line_to (cr, 173, 56);
+ cairo_curve_to (cr, 173.550781, 56, 174, 56.449219, 174, 57);
+ cairo_line_to (cr, 174, 468);
+ cairo_curve_to (cr, 174, 468.550781, 173.550781, 469, 173, 469);
+ cairo_line_to (cr, 12, 469);
+ cairo_curve_to (cr, 11.449219, 469, 11, 468.550781, 11, 468);
+
+ cairo_fill (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (bug_bo_ricotz,
+ "Exercises a bug discovered by Rico Tzschichholz",
+ "clip, fill", /* keywords */
+ NULL, /* requirements */
+ 649, 480,
+ NULL, draw)
diff --git a/test/bug-extents.c b/test/bug-extents.c
new file mode 100644
index 000000000..4edb4a548
--- /dev/null
+++ b/test/bug-extents.c
@@ -0,0 +1,59 @@
+/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */
+/*
+ * Copyright 2010 Andrea Canciani
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Andrea Canciani <ranma42@gmail.com>
+ */
+
+#include "cairo-test.h"
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+ cairo_translate (cr, 0, -25);
+
+ cairo_move_to (cr, 50, 200);
+ cairo_curve_to (cr, 50, 150, 100, 50, 150, 50);
+ cairo_curve_to (cr, 200, 50, 250, 250, 200, 250);
+ cairo_curve_to (cr, 150, 250, 200, 50, 50, 100);
+ cairo_curve_to (cr, -100, 150, 200, 150, 200, 200);
+ cairo_curve_to (cr, 200, 250, 50, 250, 50, 200);
+
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ cairo_fill_preserve (cr);
+
+ cairo_set_source_rgb (cr, 1, 0, 0);
+ cairo_stroke (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (bug_extents,
+ "Tests a bug in the computation of approximate extents",
+ "extents", /* keywords */
+ NULL, /* requirements */
+ 250, 250,
+ NULL, draw)
diff --git a/test/bug-seams.c b/test/bug-seams.c
new file mode 100644
index 000000000..01e84ff06
--- /dev/null
+++ b/test/bug-seams.c
@@ -0,0 +1,120 @@
+/*
+ * Copyright 2010 Soeren Sandmann Pedersen
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Soeren Sandmann <sandmann@daimi.au.dk>
+ */
+
+/* Exercises a case of seam appearing between two polygons in the image
+ * backend but not in xlib [using pixman].
+ *
+ * The test case draws two abutting quads both individually on the
+ * leftm combining them with operator ADD, and in one go on the right.
+ * Both methods should show no signs of seaming at the common edge
+ * between the two quads, but the individually drawn ones have a
+ * slight seam.
+ *
+ * The cause of the seam is that there are slight differences in the
+ * output of the analytical coverage rasterization and the
+ * supersampling rasterization methods, both employed by
+ * cairo-tor-scan-converter. When drawn individually, the scan
+ * converter gets a partial view of the geometry at a time, so it ends
+ * up making different decisions about which scanlines it rasterizes
+ * with which method, compared to when the geometry is draw all at
+ * once. Though both methods produce seamless results individually
+ * (where applicable), they don't produce bit-exact identical results,
+ * and hence we get seaming where they meet.
+ */
+
+#include "cairo-test.h"
+
+static void
+draw_quad (cairo_t *cr,
+ double x1, double y1, double x2, double y2,
+ double x3, double y3, double x4, double y4)
+{
+ cairo_move_to (cr, x1, y1);
+ cairo_line_to (cr, x2, y2);
+ cairo_line_to (cr, x3, y3);
+ cairo_line_to (cr, x4, y4);
+ cairo_close_path (cr);
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ cairo_paint (cr);
+
+ cairo_scale (cr, 20, 20);
+ cairo_translate (cr, 5, 1);
+
+ /* On the left side, we have two quads drawn one at a time and
+ * combined with OPERATOR_ADD. This should be seamless, but
+ * isn't. */
+ cairo_push_group (cr);
+ cairo_set_operator (cr, CAIRO_OPERATOR_ADD);
+
+ cairo_set_source_rgb (cr, 0, 0.6, 0);
+ draw_quad (cr,
+ 1.50, 1.50,
+ 2.64, 1.63,
+ 1.75, 2.75,
+ 0.55, 2.63);
+ cairo_fill (cr);
+ draw_quad (cr,
+ 0.55, 2.63,
+ 1.75, 2.75,
+ 0.98, 4.11,
+ -0.35, 4.05);
+ cairo_fill (cr);
+
+ cairo_pop_group_to_source (cr);
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+ cairo_paint (cr);
+
+ /* On the right side, we have the same two quads drawn both at the
+ * same time. This is seamless. */
+ cairo_translate (cr, 10, 0);
+
+ cairo_set_source_rgb (cr, 0, 0.6, 0);
+ draw_quad (cr,
+ 1.50, 1.50,
+ 2.64, 1.63,
+ 1.75, 2.75,
+ 0.55, 2.63);
+ draw_quad (cr,
+ 0.55, 2.63,
+ 1.75, 2.75,
+ 0.98, 4.11,
+ -0.35, 4.05);
+ cairo_fill (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (bug_seams,
+ "Check the fidelity of the rasterisation.",
+ "raster", /* keywords */
+ "target=raster", /* requirements */
+ 500, 300,
+ NULL, draw)
diff --git a/test/bug-source-cu.c b/test/bug-source-cu.c
new file mode 100644
index 000000000..4c1e2bc63
--- /dev/null
+++ b/test/bug-source-cu.c
@@ -0,0 +1,81 @@
+/*
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include "cairo-test.h"
+
+static cairo_pattern_t *
+create_pattern (cairo_surface_t *target)
+{
+ cairo_surface_t *surface;
+ cairo_pattern_t *pattern;
+ cairo_t *cr;
+ cairo_matrix_t m;
+
+ surface = cairo_surface_create_similar(target,
+ cairo_surface_get_content (target),
+ 1000, 600);
+ cr = cairo_create (surface);
+ cairo_surface_destroy (surface);
+
+ cairo_set_source_rgb (cr, 0, 1, 0);
+ cairo_paint(cr);
+
+ pattern = cairo_pattern_create_for_surface (cairo_get_target (cr));
+ cairo_destroy(cr);
+
+ cairo_matrix_init_translate (&m, 0, 0.1); // y offset must be non-integer
+ cairo_pattern_set_matrix (pattern, &m);
+ return pattern;
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_pattern_t *pattern;
+
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+
+ cairo_set_source_rgb (cr, 1, 0, 0);
+ cairo_paint (cr);
+
+ cairo_new_path (cr);
+ cairo_move_to (cr, 10, 400.1);
+ cairo_line_to (cr, 990, 400.1);
+ cairo_line_to (cr, 990, 600);
+ cairo_line_to (cr, 10, 600);
+ cairo_close_path (cr);
+
+ pattern = create_pattern (cairo_get_target (cr));
+ cairo_set_source (cr, pattern);
+ cairo_pattern_destroy (pattern);
+
+ cairo_fill(cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (bug_source_cu,
+ "Exercises a bug discovered in the tracking of unbounded source extents",
+ "fill", /* keywords */
+ NULL, /* requirements */
+ 1000, 600,
+ NULL, draw)
diff --git a/test/bug-spline.c b/test/bug-spline.c
new file mode 100644
index 000000000..9a54a7c8c
--- /dev/null
+++ b/test/bug-spline.c
@@ -0,0 +1,95 @@
+/* cc `pkg-config --cflags --libs cairo` cairo-spline-image.c -o cairo-spline-image */
+
+/* Copyright © 2005 Carl Worth
+ * Copyright © 2012 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include "cairo-test.h"
+
+#define WIDE_LINE_WIDTH 160
+#define NARROW_LINE_WIDTH 2
+
+/* A spline showing bugs in the "contour-based stroking" in cairo 1.12 */
+static const struct spline {
+ struct { double x, y; } pt[5];
+ double line_width;
+ double rgba[4];
+} splines[] = {
+ {
+ {
+ { 172.25, 156.185 },
+ { 177.225, 164.06 },
+ { 176.5, 157.5 },
+ { 175.5, 159.5 },
+ },
+ WIDE_LINE_WIDTH,
+ { 1, 1, 1, 1 },
+ },
+ {
+ {
+ { 571.25, 247.185 },
+ { 78.225, 224.06 },
+ { 129.5, 312.5 },
+ { 210.5, 224.5 },
+ },
+ NARROW_LINE_WIDTH,
+ { 1, 0, 0, 1 },
+ }
+};
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ unsigned n;
+
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ cairo_paint (cr);
+
+ cairo_set_line_cap(cr, CAIRO_LINE_CAP_SQUARE);
+
+ for (n = 0; n < ARRAY_LENGTH(splines); n++) {
+ cairo_set_line_width (cr, splines[n].line_width);
+ cairo_set_source_rgba (cr,
+ splines[n].rgba[0],
+ splines[n].rgba[1],
+ splines[n].rgba[2],
+ splines[n].rgba[3]);
+
+ cairo_move_to (cr, splines[n].pt[0].x, splines[n].pt[0].y);
+ cairo_curve_to (cr,
+ splines[n].pt[1].x, splines[n].pt[1].y,
+ splines[n].pt[2].x, splines[n].pt[2].y,
+ splines[n].pt[3].x, splines[n].pt[3].y);
+
+ cairo_stroke (cr);
+ }
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (bug_spline,
+ "Exercises a bug in the stroking of splines",
+ "spline, stroke", /* keywords */
+ NULL, /* requirements */
+ 300, 300,
+ NULL, draw)
diff --git a/test/cairo-test-private.h b/test/cairo-test-private.h
new file mode 100644
index 000000000..cfd22de4e
--- /dev/null
+++ b/test/cairo-test-private.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright © 2004 Red Hat, Inc.
+ * Copyright © 2008 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ * Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#ifndef _CAIRO_TEST_PRIVATE_H_
+#define _CAIRO_TEST_PRIVATE_H_
+
+#include "cairo-test.h"
+
+/* For communication between the core components of cairo-test and not
+ * for the tests themselves.
+ */
+
+CAIRO_BEGIN_DECLS
+
+typedef enum {
+ DIRECT,
+ SIMILAR
+} cairo_test_similar_t;
+
+cairo_test_similar_t
+cairo_test_target_has_similar (const cairo_test_context_t *ctx,
+ const cairo_boilerplate_target_t *target);
+
+cairo_test_status_t
+_cairo_test_context_run_for_target (cairo_test_context_t *ctx,
+ const cairo_boilerplate_target_t *target,
+ cairo_bool_t similar,
+ int dev_offset, int dev_scale);
+
+void
+_cairo_test_context_init_for_test (cairo_test_context_t *ctx,
+ const cairo_test_context_t *parent,
+ const cairo_test_t *test);
+
+void
+cairo_test_init (cairo_test_context_t *ctx,
+ const char *test_name,
+ const char *output);
+
+void
+cairo_test_fini (cairo_test_context_t *ctx);
+
+void
+_cairo_test_runner_register_tests (void);
+
+CAIRO_END_DECLS
+
+#endif /* _CAIRO_TEST_PRIVATE_H_ */
diff --git a/test/cairo-test-runner.c b/test/cairo-test-runner.c
new file mode 100644
index 000000000..f9e7d4712
--- /dev/null
+++ b/test/cairo-test-runner.c
@@ -0,0 +1,1108 @@
+/*
+ * Copyright © 2008 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Chris Wilson not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Chris Wilson makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test-private.h"
+#include "cairo-boilerplate-getopt.h"
+
+/* get the "real" version info instead of dummy cairo-version.h */
+#undef CAIRO_VERSION_H
+#undef CAIRO_VERSION_MAJOR
+#undef CAIRO_VERSION_MINOR
+#undef CAIRO_VERSION_MICRO
+#include "../cairo-version.h"
+
+#include <pixman.h> /* for version information */
+
+#define SHOULD_FORK HAVE_FORK && HAVE_WAITPID
+#if SHOULD_FORK
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if HAVE_SIGNAL_H
+#include <signal.h>
+#endif
+#include <sys/types.h>
+#include <sys/wait.h>
+#endif
+#if HAVE_LIBGEN_H
+#include <libgen.h>
+#endif
+
+#if HAVE_VALGRIND
+#include <valgrind.h>
+#else
+#define RUNNING_ON_VALGRIND 0
+#endif
+
+#ifdef _MSC_VER
+#include <crtdbg.h>
+#endif
+
+typedef struct _cairo_test_list {
+ const cairo_test_t *test;
+ struct _cairo_test_list *next;
+} cairo_test_list_t;
+
+typedef struct _cairo_test_runner {
+ cairo_test_context_t base;
+
+ unsigned int num_device_offsets;
+ unsigned int num_device_scales;
+
+ cairo_bool_t passed;
+ int num_passed;
+ int num_skipped;
+ int num_failed;
+ int num_xfailed;
+ int num_error;
+ int num_crashed;
+
+ cairo_test_list_t *crashes_preamble;
+ cairo_test_list_t *errors_preamble;
+ cairo_test_list_t *fails_preamble;
+
+ cairo_test_list_t **crashes_per_target;
+ cairo_test_list_t **errors_per_target;
+ cairo_test_list_t **fails_per_target;
+
+ int *num_failed_per_target;
+ int *num_error_per_target;
+ int *num_crashed_per_target;
+
+ cairo_bool_t foreground;
+ cairo_bool_t exit_on_failure;
+ cairo_bool_t list_only;
+ cairo_bool_t full_test;
+ cairo_bool_t keyword_match;
+ cairo_bool_t slow;
+ cairo_bool_t force_pass;
+} cairo_test_runner_t;
+
+typedef enum {
+ GE,
+ GT
+} cairo_test_compare_op_t;
+
+static cairo_test_list_t *tests;
+
+static void CAIRO_BOILERPLATE_PRINTF_FORMAT(2,3)
+_log (cairo_test_context_t *ctx,
+ const char *fmt,
+ ...)
+{
+ va_list ap;
+
+ va_start (ap, fmt);
+ vprintf (fmt, ap);
+ va_end (ap);
+
+ va_start (ap, fmt);
+ cairo_test_logv (ctx, fmt, ap);
+ va_end (ap);
+}
+
+static cairo_test_list_t *
+_list_prepend (cairo_test_list_t *head, const cairo_test_t *test)
+{
+ cairo_test_list_t *list;
+
+ list = xmalloc (sizeof (cairo_test_list_t));
+ list->test = test;
+ list->next = head;
+ head = list;
+
+ return head;
+}
+
+static cairo_test_list_t *
+_list_reverse (cairo_test_list_t *head)
+{
+ cairo_test_list_t *list, *next;
+
+ for (list = head, head = NULL; list != NULL; list = next) {
+ next = list->next;
+ list->next = head;
+ head = list;
+ }
+
+ return head;
+}
+
+static void
+_list_free (cairo_test_list_t *list)
+{
+ while (list != NULL) {
+ cairo_test_list_t *next = list->next;
+ free (list);
+ list = next;
+ }
+}
+
+static cairo_bool_t
+is_running_under_debugger (void)
+{
+#if HAVE_UNISTD_H && HAVE_LIBGEN_H && __linux__
+ char buf[1024];
+
+ sprintf (buf, "/proc/%d/exe", getppid ());
+ if (readlink (buf, buf, sizeof (buf)) != -1 &&
+ strncmp (basename (buf), "gdb", 3) == 0)
+ {
+ return TRUE;
+ }
+#endif
+
+ if (RUNNING_ON_VALGRIND)
+ return TRUE;
+
+ return FALSE;
+}
+
+#if SHOULD_FORK
+static cairo_test_status_t
+_cairo_test_wait (pid_t pid)
+{
+ int exitcode;
+
+ if (waitpid (pid, &exitcode, 0) != pid)
+ return CAIRO_TEST_CRASHED;
+
+ if (WIFSIGNALED (exitcode)) {
+ switch (WTERMSIG (exitcode)) {
+ case SIGINT:
+#if HAVE_RAISE
+ raise (SIGINT);
+#endif
+ return CAIRO_TEST_UNTESTED;
+ default:
+ return CAIRO_TEST_CRASHED;
+ }
+ }
+
+ return WEXITSTATUS (exitcode);
+}
+#endif
+
+static cairo_test_status_t
+_cairo_test_runner_preamble (cairo_test_runner_t *runner,
+ cairo_test_context_t *ctx)
+{
+#if SHOULD_FORK
+ if (! runner->foreground) {
+ pid_t pid;
+
+ switch ((pid = fork ())) {
+ case -1: /* error */
+ return CAIRO_TEST_UNTESTED;
+
+ case 0: /* child */
+ exit (ctx->test->preamble (ctx));
+
+ default:
+ return _cairo_test_wait (pid);
+ }
+ }
+#endif
+ return ctx->test->preamble (ctx);
+}
+
+static cairo_test_status_t
+_cairo_test_runner_draw (cairo_test_runner_t *runner,
+ cairo_test_context_t *ctx,
+ const cairo_boilerplate_target_t *target,
+ cairo_bool_t similar,
+ int device_offset, int device_scale)
+{
+#if SHOULD_FORK
+ if (! runner->foreground) {
+ pid_t pid;
+
+ switch ((pid = fork ())) {
+ case -1: /* error */
+ return CAIRO_TEST_UNTESTED;
+
+ case 0: /* child */
+ exit (_cairo_test_context_run_for_target (ctx, target,
+ similar, device_offset, device_scale));
+
+ default:
+ return _cairo_test_wait (pid);
+ }
+ }
+#endif
+ return _cairo_test_context_run_for_target (ctx, target,
+ similar, device_offset, device_scale);
+}
+
+static void
+append_argv (int *argc, char ***argv, const char *str)
+{
+ int old_argc;
+ char **old_argv;
+ cairo_bool_t doit;
+ const char *s, *t;
+ int olen;
+ int len;
+ int i;
+ int args_to_add = 0;
+
+ if (str == NULL)
+ return;
+
+ old_argc = *argc;
+ old_argv = *argv;
+
+ doit = FALSE;
+ do {
+ if (doit)
+ *argv = xmalloc (olen);
+
+ olen = sizeof (char *) * (args_to_add + *argc);
+ for (i = 0; i < old_argc; i++) {
+ len = strlen (old_argv[i]) + 1;
+ if (doit) {
+ (*argv)[i] = (char *) *argv + olen;
+ memcpy ((*argv)[i], old_argv[i], len);
+ }
+ olen += len;
+ }
+
+ s = str;
+ while ((t = strpbrk (s, " \t,:;")) != NULL) {
+ if (t - s) {
+ len = t - s;
+ if (doit) {
+ (*argv)[i] = (char *) *argv + olen;
+ memcpy ((*argv)[i], s, len);
+ (*argv)[i][len] = '\0';
+ } else {
+ olen += sizeof (char *);
+ }
+ args_to_add++;
+ olen += len + 1;
+ i++;
+ }
+ s = t + 1;
+ }
+ if (*s != '\0') {
+ len = strlen (s) + 1;
+ if (doit) {
+ (*argv)[i] = (char *) *argv + olen;
+ memcpy ((*argv)[i], s, len);
+ } else {
+ olen += sizeof (char *);
+ }
+ args_to_add++;
+ olen += len;
+ i++;
+ }
+ } while (doit++ == FALSE);
+ *argc = i;
+}
+
+static void
+usage (const char *argv0)
+{
+ fprintf (stderr,
+ "Usage: %s [-afkxsl] [test-names|keywords ...]\n"
+ "\n"
+ "Run the cairo conformance test suite over the given tests (all by default)\n"
+ "The command-line arguments are interpreted as follows:\n"
+ "\n"
+ " -a all; run the full set of tests. By default the test suite\n"
+ " skips similar surface and device offset testing.\n"
+ " -f foreground; do not fork\n"
+ " -k match tests by keyword\n"
+ " -l list only; just list selected test case names without executing\n"
+ " -s include slow, long running tests\n"
+ " -x exit on first failure\n"
+ "\n"
+ "If test names are given they are used as matches either to a specific\n"
+ "test case or to a keyword, so a command such as\n"
+ "\"%s -k text\" can be used to run all text test cases, and\n"
+ "\"%s text-transform\" to run the individual case.\n",
+ argv0, argv0, argv0);
+}
+
+static void
+_parse_cmdline (cairo_test_runner_t *runner, int *argc, char **argv[])
+{
+ int c;
+
+ while (1) {
+ c = _cairo_getopt (*argc, *argv, ":afklsx");
+ if (c == -1)
+ break;
+
+ switch (c) {
+ case 'a':
+ runner->full_test = ~0;
+ break;
+ case 'f':
+ runner->foreground = TRUE;
+ break;
+ case 'k':
+ runner->keyword_match = TRUE;
+ break;
+ case 'l':
+ runner->list_only = TRUE;
+ break;
+ case 's':
+ runner->slow = TRUE;
+ break;
+ case 'x':
+ runner->exit_on_failure = TRUE;
+ break;
+ default:
+ fprintf (stderr, "Internal error: unhandled option: %c\n", c);
+ /* fall-through */
+ case '?':
+ usage ((*argv)[0]);
+ exit (1);
+ }
+ }
+
+ *argc -= optind;
+ *argv += optind;
+}
+
+static void
+_runner_init (cairo_test_runner_t *runner)
+{
+ cairo_test_init (&runner->base, "cairo-test-suite", ".");
+
+ runner->passed = TRUE;
+
+ runner->fails_preamble = NULL;
+ runner->crashes_preamble = NULL;
+ runner->errors_preamble = NULL;
+
+ runner->fails_per_target = xcalloc (sizeof (cairo_test_list_t *),
+ runner->base.num_targets);
+ runner->crashes_per_target = xcalloc (sizeof (cairo_test_list_t *),
+ runner->base.num_targets);
+ runner->errors_per_target = xcalloc (sizeof (cairo_test_list_t *),
+ runner->base.num_targets);
+ runner->num_failed_per_target = xcalloc (sizeof (int),
+ runner->base.num_targets);
+ runner->num_error_per_target = xcalloc (sizeof (int),
+ runner->base.num_targets);
+ runner->num_crashed_per_target = xcalloc (sizeof (int),
+ runner->base.num_targets);
+}
+
+static void
+_runner_print_versions (cairo_test_runner_t *runner)
+{
+ _log (&runner->base,
+ "Compiled against cairo %s, running on %s.\n",
+ CAIRO_VERSION_STRING, cairo_version_string ());
+ _log (&runner->base,
+ "Compiled against pixman %s, running on %s.\n",
+ PIXMAN_VERSION_STRING, pixman_version_string ());
+
+ fflush (runner->base.log_file);
+}
+
+static void
+_runner_print_summary (cairo_test_runner_t *runner)
+{
+ _log (&runner->base,
+ "%d Passed, %d Failed [%d crashed, %d expected], %d Skipped\n",
+ runner->num_passed,
+
+ runner->num_failed + runner->num_crashed + runner->num_xfailed,
+ runner->num_crashed,
+ runner->num_xfailed,
+
+ runner->num_skipped);
+}
+
+static void
+_runner_print_details (cairo_test_runner_t *runner)
+{
+ cairo_test_list_t *list;
+ unsigned int n;
+
+ if (runner->crashes_preamble) {
+ int count = 0;
+
+ for (list = runner->crashes_preamble; list != NULL; list = list->next)
+ count++;
+
+ _log (&runner->base, "Preamble: %d crashed! -", count);
+
+ for (list = runner->crashes_preamble; list != NULL; list = list->next) {
+ char *name = cairo_test_get_name (list->test);
+ _log (&runner->base, " %s", name);
+ free (name);
+ }
+ _log (&runner->base, "\n");
+ }
+ if (runner->errors_preamble) {
+ int count = 0;
+
+ for (list = runner->errors_preamble; list != NULL; list = list->next)
+ count++;
+
+ _log (&runner->base, "Preamble: %d error -", count);
+
+ for (list = runner->errors_preamble; list != NULL; list = list->next) {
+ char *name = cairo_test_get_name (list->test);
+ _log (&runner->base, " %s", name);
+ free (name);
+ }
+ _log (&runner->base, "\n");
+ }
+ if (runner->fails_preamble) {
+ int count = 0;
+
+ for (list = runner->fails_preamble; list != NULL; list = list->next)
+ count++;
+
+ _log (&runner->base, "Preamble: %d failed -", count);
+
+ for (list = runner->fails_preamble; list != NULL; list = list->next) {
+ char *name = cairo_test_get_name (list->test);
+ _log (&runner->base, " %s", name);
+ free (name);
+ }
+ _log (&runner->base, "\n");
+ }
+
+ for (n = 0; n < runner->base.num_targets; n++) {
+ const cairo_boilerplate_target_t *target;
+
+ target = runner->base.targets_to_test[n];
+ if (runner->num_crashed_per_target[n]) {
+ _log (&runner->base, "%s (%s): %d crashed! -",
+ target->name,
+ cairo_boilerplate_content_name (target->content),
+ runner->num_crashed_per_target[n]);
+
+ for (list = runner->crashes_per_target[n];
+ list != NULL;
+ list = list->next)
+ {
+ char *name = cairo_test_get_name (list->test);
+ _log (&runner->base, " %s", name);
+ free (name);
+ }
+ _log (&runner->base, "\n");
+ }
+ if (runner->num_error_per_target[n]) {
+ _log (&runner->base, "%s (%s): %d error -",
+ target->name,
+ cairo_boilerplate_content_name (target->content),
+ runner->num_error_per_target[n]);
+
+ for (list = runner->errors_per_target[n];
+ list != NULL;
+ list = list->next)
+ {
+ char *name = cairo_test_get_name (list->test);
+ _log (&runner->base, " %s", name);
+ free (name);
+ }
+ _log (&runner->base, "\n");
+ }
+
+ if (runner->num_failed_per_target[n]) {
+ _log (&runner->base, "%s (%s): %d failed -",
+ target->name,
+ cairo_boilerplate_content_name (target->content),
+ runner->num_failed_per_target[n]);
+
+ for (list = runner->fails_per_target[n];
+ list != NULL;
+ list = list->next)
+ {
+ char *name = cairo_test_get_name (list->test);
+ _log (&runner->base, " %s", name);
+ free (name);
+ }
+ _log (&runner->base, "\n");
+ }
+ }
+}
+
+static void
+_runner_print_results (cairo_test_runner_t *runner)
+{
+ _runner_print_summary (runner);
+ _runner_print_details (runner);
+
+ if (! runner->passed && ! runner->num_crashed) {
+ _log (&runner->base,
+"\n"
+"Note: These failures may be due to external factors.\n"
+"Please read test/README -- \"Getting the elusive zero failures\".\n");
+ }
+}
+
+static cairo_test_status_t
+_runner_fini (cairo_test_runner_t *runner)
+{
+ unsigned int n;
+
+ _list_free (runner->crashes_preamble);
+ _list_free (runner->errors_preamble);
+ _list_free (runner->fails_preamble);
+
+ for (n = 0; n < runner->base.num_targets; n++) {
+ _list_free (runner->crashes_per_target[n]);
+ _list_free (runner->errors_per_target[n]);
+ _list_free (runner->fails_per_target[n]);
+ }
+ free (runner->crashes_per_target);
+ free (runner->errors_per_target);
+ free (runner->fails_per_target);
+
+ free (runner->num_crashed_per_target);
+ free (runner->num_error_per_target);
+ free (runner->num_failed_per_target);
+
+ cairo_test_fini (&runner->base);
+
+ if (runner->force_pass)
+ return CAIRO_TEST_SUCCESS;
+
+ return runner->num_failed + runner->num_crashed ?
+ CAIRO_TEST_FAILURE :
+ runner->num_passed + runner->num_xfailed ?
+ CAIRO_TEST_SUCCESS : CAIRO_TEST_UNTESTED;
+}
+
+static cairo_bool_t
+_version_compare (int a, cairo_test_compare_op_t op, int b)
+{
+ switch (op) {
+ case GT: return a > b;
+ case GE: return a >= b;
+ default: return FALSE;
+ }
+}
+
+
+static cairo_bool_t
+_get_required_version (const char *str,
+ cairo_test_compare_op_t *op,
+ int *major,
+ int *minor,
+ int *micro)
+{
+ while (*str == ' ')
+ str++;
+
+ if (strncmp (str, ">=", 2) == 0) {
+ *op = GE;
+ str += 2;
+ } else if (strncmp (str, ">", 1) == 0) {
+ *op = GT;
+ str += 1;
+ } else
+ return FALSE;
+
+ while (*str == ' ')
+ str++;
+
+ if (sscanf (str, "%d.%d.%d", major, minor, micro) != 3) {
+ *micro = 0;
+ if (sscanf (str, "%d.%d", major, minor) != 2)
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static cairo_bool_t
+_has_required_cairo_version (const char *str)
+{
+ cairo_test_compare_op_t op;
+ int major, minor, micro;
+
+ if (! _get_required_version (str + 5 /* advance over "cairo" */,
+ &op, &major, &minor, &micro))
+ {
+ fprintf (stderr, "unrecognised cairo version requirement '%s'\n", str);
+ return FALSE;
+ }
+
+ return _version_compare (cairo_version (),
+ op,
+ CAIRO_VERSION_ENCODE (major, minor, micro));
+}
+
+static cairo_bool_t
+_has_required_ghostscript_version (const char *str)
+{
+#if ! CAIRO_CAN_TEST_PS_SURFACE
+ return TRUE;
+#endif
+
+ str += 2; /* advance over "gs" */
+
+ return TRUE;
+}
+
+static cairo_bool_t
+_has_required_poppler_version (const char *str)
+{
+#if ! CAIRO_CAN_TEST_PDF_SURFACE
+ return TRUE;
+#endif
+
+ str += 7; /* advance over "poppler" */
+
+ return TRUE;
+}
+
+static cairo_bool_t
+_has_required_rsvg_version (const char *str)
+{
+#if ! CAIRO_CAN_TEST_SVG_SURFACE
+ return TRUE;
+#endif
+
+ str += 4; /* advance over "rsvg" */
+
+ return TRUE;
+}
+
+#define TEST_SIMILAR 0x1
+#define TEST_OFFSET 0x2
+#define TEST_SCALE 0x4
+int
+main (int argc, char **argv)
+{
+ cairo_test_runner_t runner;
+ cairo_test_list_t *test_list;
+ cairo_test_status_t *target_status;
+ unsigned int n, m, k;
+ char targets[4096];
+ int len;
+ char *cairo_tests_env;
+
+#ifdef _MSC_VER
+ /* We don't want an assert dialog, we want stderr */
+ _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE);
+ _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR);
+#endif
+
+ _cairo_test_runner_register_tests ();
+ tests = _list_reverse (tests);
+
+ memset (&runner, 0, sizeof (runner));
+ runner.num_device_offsets = 1;
+ runner.num_device_scales = 1;
+
+ if (is_running_under_debugger ())
+ runner.foreground = TRUE;
+
+ if (getenv ("CAIRO_TEST_MODE")) {
+ const char *env = getenv ("CAIRO_TEST_MODE");
+
+ if (strstr (env, "full")) {
+ runner.full_test = ~0;
+ }
+ if (strstr (env, "similar")) {
+ runner.full_test |= TEST_SIMILAR;
+ }
+ if (strstr (env, "offset")) {
+ runner.full_test |= TEST_OFFSET;
+ }
+ if (strstr (env, "scale")) {
+ runner.full_test |= TEST_SCALE;
+ }
+ if (strstr (env, "foreground")) {
+ runner.foreground = TRUE;
+ }
+ if (strstr (env, "exit-on-failure")) {
+ runner.exit_on_failure = TRUE;
+ }
+ }
+
+ if (getenv ("CAIRO_TEST_FORCE_PASS")) {
+ const char *env = getenv ("CAIRO_TEST_FORCE_PASS");
+
+ runner.force_pass = atoi (env);
+ }
+
+ _parse_cmdline (&runner, &argc, &argv);
+
+ cairo_tests_env = getenv("CAIRO_TESTS");
+ append_argv (&argc, &argv, cairo_tests_env);
+
+ if (runner.full_test & TEST_OFFSET) {
+ runner.num_device_offsets = 2;
+ }
+ if (runner.full_test & TEST_SCALE) {
+ runner.num_device_scales = 2;
+ }
+
+ target_status = NULL; /* silence the compiler */
+ if (! runner.list_only) {
+ _runner_init (&runner);
+ _runner_print_versions (&runner);
+ target_status = xmalloc (sizeof (cairo_test_status_t) *
+ runner.base.num_targets);
+ }
+
+ for (test_list = tests; test_list != NULL; test_list = test_list->next) {
+ const cairo_test_t *test = test_list->test;
+ cairo_test_context_t ctx;
+ cairo_test_status_t status;
+ cairo_bool_t failed = FALSE, xfailed = FALSE, error = FALSE, crashed = FALSE, skipped = TRUE;
+ cairo_bool_t in_preamble = FALSE;
+ char *name = cairo_test_get_name (test);
+ int i;
+
+ /* check for restricted runs */
+ if (argc) {
+ cairo_bool_t found = FALSE;
+ const char *keywords = test->keywords;
+
+ for (i = 0; i < argc; i++) {
+ const char *match = argv[i];
+ cairo_bool_t invert = match[0] == '!';
+ if (invert)
+ match++;
+
+ if (runner.keyword_match) {
+ if (keywords != NULL && strstr (keywords, match) != NULL) {
+ found = ! invert;
+ break;
+ } else if (invert) {
+ found = TRUE;
+ }
+ } else {
+ /* exact match on test name */
+ if (strcmp (name, match) == 0) {
+ found = ! invert;
+ break;
+ } else if (invert) {
+ found = TRUE;
+ }
+ }
+ }
+
+ if (! found) {
+ free (name);
+ continue;
+ }
+ }
+
+ /* check to see if external requirements match */
+ if (test->requirements != NULL) {
+ const char *requirements = test->requirements;
+ const char *str;
+
+ str = strstr (requirements, "slow");
+ if (str != NULL && ! runner.slow) {
+ if (runner.list_only)
+ goto TEST_NEXT;
+ else
+ goto TEST_SKIPPED;
+ }
+
+ str = strstr (requirements, "cairo");
+ if (str != NULL && ! _has_required_cairo_version (str)) {
+ if (runner.list_only)
+ goto TEST_NEXT;
+ else
+ goto TEST_SKIPPED;
+ }
+
+ str = strstr (requirements, "gs");
+ if (str != NULL && ! _has_required_ghostscript_version (str)) {
+ if (runner.list_only)
+ goto TEST_NEXT;
+ else
+ goto TEST_SKIPPED;
+ }
+
+ str = strstr (requirements, "poppler");
+ if (str != NULL && ! _has_required_poppler_version (str)) {
+ if (runner.list_only)
+ goto TEST_NEXT;
+ else
+ goto TEST_SKIPPED;
+ }
+
+ str = strstr (requirements, "rsvg");
+ if (str != NULL && ! _has_required_rsvg_version (str)) {
+ if (runner.list_only)
+ goto TEST_NEXT;
+ else
+ goto TEST_SKIPPED;
+ }
+ }
+
+ if (runner.list_only) {
+ printf ("%s ", name);
+ goto TEST_NEXT;
+ }
+
+ _cairo_test_context_init_for_test (&ctx, &runner.base, test);
+ memset (target_status, 0,
+ sizeof (cairo_test_status_t) * ctx.num_targets);
+
+ if (ctx.test->preamble != NULL) {
+ status = _cairo_test_runner_preamble (&runner, &ctx);
+ switch (status) {
+ case CAIRO_TEST_SUCCESS:
+ in_preamble = TRUE;
+ skipped = FALSE;
+ break;
+
+ case CAIRO_TEST_XFAILURE:
+ in_preamble = TRUE;
+ xfailed = TRUE;
+ goto TEST_DONE;
+
+ case CAIRO_TEST_NEW:
+ case CAIRO_TEST_FAILURE:
+ runner.fails_preamble = _list_prepend (runner.fails_preamble,
+ test);
+ in_preamble = TRUE;
+ failed = TRUE;
+ goto TEST_DONE;
+
+ case CAIRO_TEST_ERROR:
+ runner.errors_preamble = _list_prepend (runner.errors_preamble,
+ test);
+ in_preamble = TRUE;
+ failed = TRUE;
+ goto TEST_DONE;
+
+ case CAIRO_TEST_NO_MEMORY:
+ case CAIRO_TEST_CRASHED:
+ runner.crashes_preamble = _list_prepend (runner.crashes_preamble,
+ test);
+ in_preamble = TRUE;
+ failed = TRUE;
+ goto TEST_DONE;
+
+ case CAIRO_TEST_UNTESTED:
+ goto TEST_DONE;
+ }
+ }
+
+ if (ctx.test->draw == NULL)
+ goto TEST_DONE;
+
+ for (n = 0; n < ctx.num_targets; n++) {
+ const cairo_boilerplate_target_t *target;
+ cairo_bool_t target_failed = FALSE,
+ target_xfailed = FALSE,
+ target_error = FALSE,
+ target_crashed = FALSE,
+ target_skipped = TRUE;
+ cairo_test_similar_t has_similar;
+
+ target = ctx.targets_to_test[n];
+
+ has_similar = runner.full_test & TEST_SIMILAR ?
+ cairo_test_target_has_similar (&ctx, target) :
+ DIRECT;
+ for (m = 0; m < runner.num_device_offsets; m++) {
+ for (k = 0; k < runner.num_device_scales; k++) {
+ int dev_offset = m * 25;
+ int dev_scale = k + 1;
+ cairo_test_similar_t similar;
+
+ for (similar = DIRECT; similar <= has_similar; similar++) {
+ status = _cairo_test_runner_draw (&runner, &ctx, target,
+ similar, dev_offset, dev_scale);
+ switch (status) {
+ case CAIRO_TEST_SUCCESS:
+ target_skipped = FALSE;
+ break;
+ case CAIRO_TEST_XFAILURE:
+ target_xfailed = TRUE;
+ break;
+ case CAIRO_TEST_NEW:
+ case CAIRO_TEST_FAILURE:
+ target_failed = TRUE;
+ break;
+ case CAIRO_TEST_ERROR:
+ target_error = TRUE;
+ break;
+ case CAIRO_TEST_NO_MEMORY:
+ case CAIRO_TEST_CRASHED:
+ target_crashed = TRUE;
+ break;
+ case CAIRO_TEST_UNTESTED:
+ break;
+ }
+ }
+ }
+ }
+
+ if (target_crashed) {
+ target_status[n] = CAIRO_TEST_CRASHED;
+ runner.num_crashed_per_target[n]++;
+ runner.crashes_per_target[n] = _list_prepend (runner.crashes_per_target[n],
+ test);
+ crashed = TRUE;
+ } else if (target_error) {
+ target_status[n] = CAIRO_TEST_ERROR;
+ runner.num_error_per_target[n]++;
+ runner.errors_per_target[n] = _list_prepend (runner.errors_per_target[n],
+ test);
+
+ error = TRUE;
+ } else if (target_failed) {
+ target_status[n] = CAIRO_TEST_FAILURE;
+ runner.num_failed_per_target[n]++;
+ runner.fails_per_target[n] = _list_prepend (runner.fails_per_target[n],
+ test);
+
+ failed = TRUE;
+ } else if (target_xfailed) {
+ target_status[n] = CAIRO_TEST_XFAILURE;
+ xfailed = TRUE;
+ } else if (target_skipped) {
+ target_status[n] = CAIRO_TEST_UNTESTED;
+ } else {
+ target_status[n] = CAIRO_TEST_SUCCESS;
+ skipped = FALSE;
+ }
+ }
+
+ TEST_DONE:
+ cairo_test_fini (&ctx);
+ TEST_SKIPPED:
+ targets[0] = '\0';
+ if (crashed) {
+ if (! in_preamble) {
+ len = 0;
+ for (n = 0 ; n < runner.base.num_targets; n++) {
+ if (target_status[n] == CAIRO_TEST_CRASHED) {
+ if (strstr (targets,
+ runner.base.targets_to_test[n]->name) == NULL)
+ {
+ len += snprintf (targets + len, sizeof (targets) - len,
+ "%s, ",
+ runner.base.targets_to_test[n]->name);
+ }
+ }
+ }
+ targets[len-2] = '\0';
+ _log (&runner.base, "\n%s: CRASH! (%s)\n", name, targets);
+ } else {
+ _log (&runner.base, "\n%s: CRASH!\n", name);
+ }
+ runner.num_crashed++;
+ runner.passed = FALSE;
+ } else if (error) {
+ if (! in_preamble) {
+ len = 0;
+ for (n = 0 ; n < runner.base.num_targets; n++) {
+ if (target_status[n] == CAIRO_TEST_ERROR) {
+ if (strstr (targets,
+ runner.base.targets_to_test[n]->name) == NULL)
+ {
+ len += snprintf (targets + len,
+ sizeof (targets) - len,
+ "%s, ",
+ runner.base.targets_to_test[n]->name);
+ }
+ }
+ }
+ targets[len-2] = '\0';
+ _log (&runner.base, "%s: ERROR (%s)\n", name, targets);
+ } else {
+ _log (&runner.base, "%s: ERROR\n", name);
+ }
+ runner.num_error++;
+ runner.passed = FALSE;
+ } else if (failed) {
+ if (! in_preamble) {
+ len = 0;
+ for (n = 0 ; n < runner.base.num_targets; n++) {
+ if (target_status[n] == CAIRO_TEST_FAILURE) {
+ if (strstr (targets,
+ runner.base.targets_to_test[n]->name) == NULL)
+ {
+ len += snprintf (targets + len,
+ sizeof (targets) - len,
+ "%s, ",
+ runner.base.targets_to_test[n]->name);
+ }
+ }
+ }
+ targets[len-2] = '\0';
+ _log (&runner.base, "%s: FAIL (%s)\n", name, targets);
+ } else {
+ _log (&runner.base, "%s: FAIL\n", name);
+ }
+ runner.num_failed++;
+ runner.passed = FALSE;
+ } else if (xfailed) {
+ _log (&runner.base, "%s: XFAIL\n", name);
+ runner.num_xfailed++;
+ } else if (skipped) {
+ _log (&runner.base, "%s: UNTESTED\n", name);
+ runner.num_skipped++;
+ } else {
+ _log (&runner.base, "%s: PASS\n", name);
+ runner.num_passed++;
+ }
+ fflush (runner.base.log_file);
+
+ TEST_NEXT:
+ free (name);
+ if (runner.exit_on_failure && ! runner.passed)
+ break;
+
+ }
+
+ if (cairo_tests_env)
+ free(argv);
+
+ if (runner.list_only) {
+ printf ("\n");
+ return CAIRO_TEST_SUCCESS;
+ }
+
+ for (n = 0 ; n < runner.base.num_targets; n++) {
+ runner.crashes_per_target[n] = _list_reverse (runner.crashes_per_target[n]);
+ runner.errors_per_target[n] = _list_reverse (runner.errors_per_target[n]);
+ runner.fails_per_target[n] = _list_reverse (runner.fails_per_target[n]);
+ }
+
+ _runner_print_results (&runner);
+
+ _list_free (tests);
+ free (target_status);
+ return _runner_fini (&runner);
+}
+
+void
+cairo_test_register (cairo_test_t *test)
+{
+ tests = _list_prepend (tests, test);
+}
diff --git a/test/cairo-test-trace.c b/test/cairo-test-trace.c
new file mode 100644
index 000000000..5badc4377
--- /dev/null
+++ b/test/cairo-test-trace.c
@@ -0,0 +1,1780 @@
+/*
+ * Copyright © 2009 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * the authors not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. The authors make no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+/*
+ * The basic idea is that we feed the trace to multiple backends in parallel
+ * and compare the output at the end of each context (based on the premise
+ * that contexts demarcate expose events, or their logical equivalents) with
+ * that of the image[1] backend. Each backend is executed in a separate
+ * process, for robustness and to isolate the global cairo state, with the
+ * image data residing in shared memory and synchronising over a socket.
+ *
+ * [1] Should be reference implementation, currently the image backend is
+ * considered to be the reference for all other backends.
+ */
+
+/* XXX Can't directly compare fills using spans versus trapezoidation,
+ * i.e. xlib vs image. Gah, kinda renders this whole scheme moot.
+ * How about reference platforms?
+ * E.g. accelerated xlib driver vs Xvfb?
+ *
+ * boilerplate->create_reference_surface()?
+ * boilerplate->reference->create_surface()?
+ * So for each backend spawn two processes, a reference and xlib
+ * (obviously minimising the number of reference processes when possible)
+ */
+
+/*
+ * XXX Handle show-page as well as cairo_destroy()? Though arguably that is
+ * only relevant for paginated backends which is currently outside the
+ * scope of this test.
+ */
+
+#define _GNU_SOURCE 1 /* getline() */
+
+#include "cairo-test.h"
+#include "buffer-diff.h"
+
+#include "cairo-boilerplate-getopt.h"
+#include <cairo-script-interpreter.h>
+#include "cairo-missing.h"
+
+#if CAIRO_HAS_SCRIPT_SURFACE
+#include <cairo-script.h>
+#endif
+
+/* For basename */
+#ifdef HAVE_LIBGEN_H
+#include <libgen.h>
+#endif
+#include <ctype.h> /* isspace() */
+
+#include <sys/types.h>
+#include <dirent.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <sys/wait.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <sys/mman.h>
+#include <sys/poll.h>
+#include <sys/un.h>
+#include <errno.h>
+#include <assert.h>
+#if CAIRO_HAS_REAL_PTHREAD
+#include <pthread.h>
+#endif
+
+#if HAVE_FCFINI
+#include <fontconfig/fontconfig.h>
+#endif
+
+#ifndef MAP_NORESERVE
+#define MAP_NORESERVE 0
+#endif
+
+#define DEBUG 0
+
+#define ignore_image_differences 0 /* XXX make me a cmdline option! */
+#define write_results 1
+#define write_traces 1
+
+#define DATA_SIZE (256 << 20)
+#define SHM_PATH_XXX "/.shmem-cairo-trace"
+
+typedef struct _test_trace {
+ /* Options from command-line */
+ cairo_bool_t list_only;
+ char **names;
+ unsigned int num_names;
+ char **exclude_names;
+ unsigned int num_exclude_names;
+
+ /* Stuff used internally */
+ const cairo_boilerplate_target_t **targets;
+ int num_targets;
+} test_trace_t;
+
+typedef struct _test_runner {
+ const char *name;
+ cairo_surface_t *surface;
+ void *closure;
+ uint8_t *base;
+ const char *trace;
+ pid_t pid;
+ int sk;
+ cairo_bool_t is_recording;
+
+ cairo_script_interpreter_t *csi;
+ struct context_closure {
+ struct context_closure *next;
+ unsigned long id;
+ unsigned long start_line;
+ unsigned long end_line;
+ cairo_t *context;
+ cairo_surface_t *surface;
+ } *contexts;
+
+ unsigned long context_id;
+} test_runner_t;
+
+struct slave {
+ pid_t pid;
+ int fd;
+ unsigned long image_serial;
+ unsigned long image_ready;
+ unsigned long start_line;
+ unsigned long end_line;
+ cairo_surface_t *image;
+ long width, height;
+ cairo_surface_t *difference;
+ buffer_diff_result_t result;
+ const cairo_boilerplate_target_t *target;
+ const struct slave *reference;
+ cairo_bool_t is_recording;
+};
+
+struct request_image {
+ unsigned long id;
+ unsigned long start_line;
+ unsigned long end_line;
+ cairo_format_t format;
+ long width;
+ long height;
+ long stride;
+};
+
+struct surface_tag {
+ long width, height;
+};
+static const cairo_user_data_key_t surface_tag;
+
+#define TARGET_NAME(T) ((T) ? (T)->name : "recording")
+
+#if CAIRO_HAS_REAL_PTHREAD
+#define tr_die(t) t->is_recording ? pthread_exit(NULL) : exit(1)
+#else
+#define tr_die(t) exit(1)
+#endif
+
+static cairo_bool_t
+writen (int fd, const void *ptr, int len)
+{
+#if 0
+ const uint8_t *data = ptr;
+ while (len) {
+ int ret = write (fd, data, len);
+ if (ret < 0) {
+ switch (errno) {
+ case EAGAIN:
+ case EINTR:
+ continue;
+ default:
+ return FALSE;
+ }
+ } else if (ret == 0) {
+ return FALSE;
+ } else {
+ data += ret;
+ len -= ret;
+ }
+ }
+ return TRUE;
+#else
+ int ret = send (fd, ptr, len, 0);
+ return ret == len;
+#endif
+}
+
+static cairo_bool_t
+readn (int fd, void *ptr, int len)
+{
+#if 0
+ uint8_t *data = ptr;
+ while (len) {
+ int ret = read (fd, data, len);
+ if (ret < 0) {
+ switch (errno) {
+ case EAGAIN:
+ case EINTR:
+ continue;
+ default:
+ return FALSE;
+ }
+ } else if (ret == 0) {
+ return FALSE;
+ } else {
+ data += ret;
+ len -= ret;
+ }
+ }
+ return TRUE;
+#else
+ int ret = recv (fd, ptr, len, MSG_WAITALL);
+ return ret == len;
+#endif
+}
+
+static cairo_format_t
+format_for_content (cairo_content_t content)
+{
+ switch (content) {
+ case CAIRO_CONTENT_ALPHA:
+ return CAIRO_FORMAT_A8;
+ case CAIRO_CONTENT_COLOR:
+ return CAIRO_FORMAT_RGB24;
+ default:
+ case CAIRO_CONTENT_COLOR_ALPHA:
+ return CAIRO_FORMAT_ARGB32;
+ }
+}
+
+static void
+send_recording_surface (test_runner_t *tr,
+ int width, int height,
+ struct context_closure *closure)
+{
+#if CAIRO_HAS_REAL_PTHREAD
+ const struct request_image rq = {
+ closure->id,
+ closure->start_line,
+ closure->end_line,
+ -1,
+ width, height,
+ (long) closure->surface,
+ };
+ unsigned long offset;
+ unsigned long serial;
+
+ if (DEBUG > 1) {
+ printf ("send-recording-surface: %lu [%lu, %lu]\n",
+ closure->id,
+ closure->start_line,
+ closure->end_line);
+ }
+ writen (tr->sk, &rq, sizeof (rq));
+ readn (tr->sk, &offset, sizeof (offset));
+
+ /* signal completion */
+ writen (tr->sk, &closure->id, sizeof (closure->id));
+
+ /* wait for image check */
+ serial = 0;
+ readn (tr->sk, &serial, sizeof (serial));
+ if (DEBUG > 1) {
+ printf ("send-recording-surface: serial: %lu\n", serial);
+ }
+ if (serial != closure->id)
+ pthread_exit (NULL);
+#else
+ exit (1);
+#endif
+}
+
+static void *
+request_image (test_runner_t *tr,
+ struct context_closure *closure,
+ cairo_format_t format,
+ int width, int height, int stride)
+{
+ const struct request_image rq = {
+ closure->id,
+ closure->start_line,
+ closure->end_line,
+ format, width, height, stride
+ };
+ unsigned long offset = -1;
+
+ assert (format != (cairo_format_t) -1);
+
+ writen (tr->sk, &rq, sizeof (rq));
+ readn (tr->sk, &offset, sizeof (offset));
+ if (offset == (unsigned long) -1)
+ return NULL;
+
+ return tr->base + offset;
+}
+
+static void
+send_surface (test_runner_t *tr,
+ struct context_closure *closure)
+{
+ cairo_surface_t *source = closure->surface;
+ cairo_surface_t *image;
+ cairo_format_t format = (cairo_format_t) -1;
+ cairo_t *cr;
+ int width, height, stride;
+ void *data;
+ unsigned long serial;
+
+ if (DEBUG > 1) {
+ printf ("send-surface: '%s', is-recording? %d\n",
+ tr->name, tr->is_recording);
+ }
+
+ if (cairo_surface_get_type (source) == CAIRO_SURFACE_TYPE_IMAGE) {
+ width = cairo_image_surface_get_width (source);
+ height = cairo_image_surface_get_height (source);
+ format = cairo_image_surface_get_format (source);
+ } else {
+ struct surface_tag *tag;
+
+ tag = cairo_surface_get_user_data (source, &surface_tag);
+ if (tag != NULL) {
+ width = tag->width;
+ height = tag->height;
+ } else {
+ double x0, x1, y0, y1;
+
+ /* presumably created using cairo_surface_create_similar() */
+ cr = cairo_create (source);
+ cairo_clip_extents (cr, &x0, &y0, &x1, &y1);
+ cairo_destroy (cr);
+
+ tag = xmalloc (sizeof (*tag));
+ width = tag->width = x1 - x0;
+ height = tag->height = y1 - y0;
+
+ if (cairo_surface_set_user_data (source, &surface_tag, tag, free))
+ tr_die (tr);
+ }
+ }
+
+ if (tr->is_recording) {
+ send_recording_surface (tr, width, height, closure);
+ return;
+ }
+
+ if (format == (cairo_format_t) -1)
+ format = format_for_content (cairo_surface_get_content (source));
+
+ stride = cairo_format_stride_for_width (format, width);
+
+ data = request_image (tr, closure, format, width, height, stride);
+ if (data == NULL)
+ tr_die (tr);
+
+ image = cairo_image_surface_create_for_data (data,
+ format,
+ width, height,
+ stride);
+ cr = cairo_create (image);
+ cairo_surface_destroy (image);
+
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_set_source_surface (cr, source, 0, 0);
+ cairo_paint (cr);
+ cairo_destroy (cr);
+
+ /* signal completion */
+ writen (tr->sk, &closure->id, sizeof (closure->id));
+
+ /* wait for image check */
+ serial = 0;
+ readn (tr->sk, &serial, sizeof (serial));
+ if (serial != closure->id)
+ tr_die (tr);
+}
+
+static cairo_surface_t *
+_surface_create (void *closure,
+ cairo_content_t content,
+ double width, double height,
+ long uid)
+{
+ test_runner_t *tr = closure;
+ cairo_surface_t *surface;
+
+ surface = cairo_surface_create_similar (tr->surface,
+ content, width, height);
+ if (cairo_surface_get_type (surface) != CAIRO_SURFACE_TYPE_IMAGE) {
+ struct surface_tag *tag;
+
+ tag = xmalloc (sizeof (*tag));
+ tag->width = width;
+ tag->height = height;
+ if (cairo_surface_set_user_data (surface, &surface_tag, tag, free))
+ tr_die (tr);
+ }
+
+ return surface;
+}
+
+static cairo_t *
+_context_create (void *closure, cairo_surface_t *surface)
+{
+ test_runner_t *tr = closure;
+ struct context_closure *l;
+
+ if (DEBUG) {
+ fprintf (stderr, "%s: starting context %lu on line %d\n",
+ tr->name ? tr->name : "recording" ,
+ tr->context_id + 1,
+ cairo_script_interpreter_get_line_number (tr->csi));
+ }
+
+ l = xmalloc (sizeof (*l));
+ l->next = tr->contexts;
+ l->start_line = cairo_script_interpreter_get_line_number (tr->csi);
+ l->end_line = l->start_line;
+ l->context = cairo_create (surface);
+ l->surface = cairo_surface_reference (surface);
+ l->id = ++tr->context_id;
+ if (l->id == 0)
+ l->id = ++tr->context_id;
+ tr->contexts = l;
+
+ return l->context;
+}
+
+static void
+_context_destroy (void *closure, void *ptr)
+{
+ test_runner_t *tr = closure;
+ struct context_closure *l, **prev = &tr->contexts;
+
+ while ((l = *prev) != NULL) {
+ if (l->context == ptr) {
+ if (DEBUG) {
+ fprintf (stderr, "%s: context %lu complete on line %d\n",
+ tr->name ? tr->name : "recording" ,
+ tr->context_id,
+ cairo_script_interpreter_get_line_number (tr->csi));
+ }
+ l->end_line =
+ cairo_script_interpreter_get_line_number (tr->csi);
+ if (cairo_surface_status (l->surface) == CAIRO_STATUS_SUCCESS) {
+ send_surface (tr, l);
+ } else {
+ fprintf (stderr, "%s: error during replay, line %lu: %s!\n",
+ tr->name,
+ l->end_line,
+ cairo_status_to_string (cairo_surface_status (l->surface)));
+ tr_die (tr);
+ }
+
+ cairo_surface_destroy (l->surface);
+ *prev = l->next;
+ free (l);
+ return;
+ }
+ prev = &l->next;
+ }
+}
+
+static void
+execute (test_runner_t *tr)
+{
+ const cairo_script_interpreter_hooks_t hooks = {
+ .closure = tr,
+ .surface_create = _surface_create,
+ .context_create = _context_create,
+ .context_destroy = _context_destroy,
+ };
+ pid_t ack;
+
+ tr->csi = cairo_script_interpreter_create ();
+ cairo_script_interpreter_install_hooks (tr->csi, &hooks);
+
+ ack = -1;
+ readn (tr->sk, &ack, sizeof (ack));
+ if (ack != tr->pid)
+ tr_die (tr);
+
+ cairo_script_interpreter_run (tr->csi, tr->trace);
+
+ cairo_script_interpreter_finish (tr->csi);
+ if (cairo_script_interpreter_destroy (tr->csi))
+ tr_die (tr);
+}
+
+static int
+spawn_socket (const char *socket_path, pid_t pid)
+{
+ struct sockaddr_un addr;
+ int sk;
+
+ sk = socket (PF_UNIX, SOCK_STREAM, 0);
+ if (sk == -1)
+ return -1;
+
+ memset (&addr, 0, sizeof (addr));
+ addr.sun_family = AF_UNIX;
+ strcpy (addr.sun_path, socket_path);
+
+ if (connect (sk, (struct sockaddr *) &addr, sizeof (addr)) == -1)
+ return -1;
+
+ if (! writen (sk, &pid, sizeof (pid)))
+ return -1;
+
+ return sk;
+}
+
+static void *
+spawn_shm (const char *shm_path)
+{
+ void *base;
+ int fd;
+
+ fd = shm_open (shm_path, O_RDWR, 0);
+ if (fd == -1)
+ return MAP_FAILED;
+
+ base = mmap (NULL, DATA_SIZE,
+ PROT_READ | PROT_WRITE,
+ MAP_SHARED | MAP_NORESERVE,
+ fd, 0);
+ close (fd);
+
+ return base;
+}
+
+static int
+spawn_target (const char *socket_path,
+ const char *shm_path,
+ const cairo_boilerplate_target_t *target,
+ const char *trace)
+{
+ test_runner_t tr;
+ pid_t pid;
+
+ if (DEBUG)
+ printf ("Spawning slave '%s' for %s\n", target->name, trace);
+
+ pid = fork ();
+ if (pid != 0)
+ return pid;
+
+ tr.is_recording = FALSE;
+ tr.pid = getpid ();
+
+ tr.sk = spawn_socket (socket_path, tr.pid);
+ if (tr.sk == -1) {
+ fprintf (stderr, "%s: Failed to open socket.\n",
+ target->name);
+ exit (-1);
+ }
+
+ tr.base = spawn_shm (shm_path);
+ if (tr.base == MAP_FAILED) {
+ fprintf (stderr, "%s: Failed to map shared memory segment.\n",
+ target->name);
+ exit (-1);
+ }
+
+ tr.name = target->name;
+ tr.contexts = NULL;
+ tr.context_id = 0;
+ tr.trace = trace;
+
+ tr.surface = target->create_surface (NULL,
+ target->content,
+ 1, 1,
+ 1, 1,
+ CAIRO_BOILERPLATE_MODE_TEST,
+ &tr.closure);
+ if (tr.surface == NULL) {
+ fprintf (stderr,
+ "%s: Failed to create target surface.\n",
+ target->name);
+ exit (-1);
+ }
+
+ execute (&tr);
+
+ cairo_surface_destroy (tr.surface);
+
+ if (target->cleanup)
+ target->cleanup (tr.closure);
+
+ close (tr.sk);
+ munmap (tr.base, DATA_SIZE);
+
+ exit (0);
+}
+
+#if CAIRO_HAS_REAL_PTHREAD
+static void
+cleanup_recorder (void *arg)
+{
+ test_runner_t *tr = arg;
+
+ cairo_surface_finish (tr->surface);
+ cairo_surface_destroy (tr->surface);
+
+ close (tr->sk);
+ free (tr);
+}
+
+static void *
+record (void *arg)
+{
+ test_runner_t *tr = arg;
+
+ pthread_cleanup_push (cleanup_recorder, tr);
+ execute (tr);
+ pthread_cleanup_pop (TRUE);
+
+ return NULL;
+}
+
+/* The recorder is special:
+ * 1. It doesn't generate an image, but keeps an in-memory trace to
+ * reconstruct any surface.
+ * 2. Runs in the same process, but separate thread.
+ */
+static pid_t
+spawn_recorder (const char *socket_path, const char *trace, test_runner_t **out)
+{
+ test_runner_t *tr;
+ pthread_t id;
+ pthread_attr_t attr;
+ pid_t pid = getpid ();
+
+ if (DEBUG)
+ printf ("Spawning recorder for %s\n", trace);
+
+ tr = malloc (sizeof (*tr));
+ if (tr == NULL)
+ return -1;
+
+ tr->is_recording = TRUE;
+ tr->pid = pid;
+ tr->sk = spawn_socket (socket_path, tr->pid);
+ if (tr->sk == -1) {
+ free (tr);
+ return -1;
+ }
+
+ tr->base = NULL;
+ tr->name = NULL;
+ tr->contexts = NULL;
+ tr->context_id = 0;
+ tr->trace = trace;
+
+ tr->surface = cairo_recording_surface_create (CAIRO_CONTENT_COLOR_ALPHA,
+ NULL);
+ if (tr->surface == NULL) {
+ cleanup_recorder (tr);
+ return -1;
+ }
+
+ pthread_attr_init (&attr);
+ pthread_attr_setdetachstate (&attr, TRUE);
+ if (pthread_create (&id, &attr, record, tr) < 0) {
+ pthread_attr_destroy (&attr);
+ cleanup_recorder (tr);
+ return -1;
+ }
+ pthread_attr_destroy (&attr);
+
+
+ *out = tr;
+ return pid;
+}
+#endif
+
+/* XXX imagediff - is the extra expense worth it? */
+static cairo_bool_t
+matches_reference (struct slave *slave)
+{
+ cairo_surface_t *a, *b;
+
+ a = slave->image;
+ b = slave->reference->image;
+
+ if (a == b)
+ return TRUE;
+
+ if (a == NULL || b == NULL)
+ return FALSE;
+
+ if (cairo_surface_status (a) || cairo_surface_status (b))
+ return FALSE;
+
+ if (cairo_surface_get_type (a) != cairo_surface_get_type (b))
+ return FALSE;
+
+ if (cairo_image_surface_get_format (a) != cairo_image_surface_get_format (b))
+ return FALSE;
+
+ if (cairo_image_surface_get_width (a) != cairo_image_surface_get_width (b))
+ return FALSE;
+
+ if (cairo_image_surface_get_height (a) != cairo_image_surface_get_height (b))
+ return FALSE;
+
+ if (cairo_image_surface_get_stride (a) != cairo_image_surface_get_stride (b))
+ return FALSE;
+
+ if (FALSE && cairo_surface_get_content (a) & CAIRO_CONTENT_COLOR) {
+ cairo_surface_t *diff;
+ int width, height, stride, size;
+ unsigned char *data;
+ cairo_status_t status;
+
+ width = cairo_image_surface_get_width (a);
+ height = cairo_image_surface_get_height (a);
+ stride = cairo_image_surface_get_stride (a);
+ size = height * stride * 4;
+ data = malloc (size);
+ if (data == NULL)
+ return FALSE;
+
+ diff = cairo_image_surface_create_for_data (data,
+ cairo_image_surface_get_format (a),
+ width, height, stride);
+ cairo_surface_set_user_data (diff, (cairo_user_data_key_t *) diff,
+ data, free);
+
+ status = image_diff (NULL, a, b, diff, &slave->result);
+ if (status) {
+ cairo_surface_destroy (diff);
+ return FALSE;
+ }
+
+ if (image_diff_is_failure (&slave->result, slave->target->error_tolerance)) {
+ slave->difference = diff;
+ return FALSE;
+ } else {
+ cairo_surface_destroy (diff);
+ return TRUE;
+ }
+ } else {
+ int width, height, stride;
+ const uint8_t *aa, *bb;
+ int x, y;
+
+ width = cairo_image_surface_get_width (a);
+ height = cairo_image_surface_get_height (a);
+ stride = cairo_image_surface_get_stride (a);
+
+ aa = cairo_image_surface_get_data (a);
+ bb = cairo_image_surface_get_data (b);
+ switch (cairo_image_surface_get_format (a)) {
+ case CAIRO_FORMAT_ARGB32:
+ for (y = 0; y < height; y++) {
+ const uint32_t *ua = (uint32_t *) aa;
+ const uint32_t *ub = (uint32_t *) bb;
+ for (x = 0; x < width; x++) {
+ if (ua[x] != ub[x]) {
+ int channel;
+
+ for (channel = 0; channel < 4; channel++) {
+ unsigned va, vb, diff;
+
+ va = (ua[x] >> (channel*8)) & 0xff;
+ vb = (ub[x] >> (channel*8)) & 0xff;
+ diff = abs (va - vb);
+ if (diff > slave->target->error_tolerance)
+ return FALSE;
+ }
+ }
+ }
+ aa += stride;
+ bb += stride;
+ }
+ break;
+
+ case CAIRO_FORMAT_RGB24:
+ for (y = 0; y < height; y++) {
+ const uint32_t *ua = (uint32_t *) aa;
+ const uint32_t *ub = (uint32_t *) bb;
+ for (x = 0; x < width; x++) {
+ if ((ua[x] & 0x00ffffff) != (ub[x] & 0x00ffffff)) {
+ int channel;
+
+ for (channel = 0; channel < 3; channel++) {
+ unsigned va, vb, diff;
+
+ va = (ua[x] >> (channel*8)) & 0xff;
+ vb = (ub[x] >> (channel*8)) & 0xff;
+ diff = abs (va - vb);
+ if (diff > slave->target->error_tolerance)
+ return FALSE;
+ }
+ }
+ }
+ aa += stride;
+ bb += stride;
+ }
+ break;
+
+ case CAIRO_FORMAT_A8:
+ for (y = 0; y < height; y++) {
+ for (x = 0; x < width; x++) {
+ if (aa[x] != bb[x]) {
+ unsigned diff = abs (aa[x] - bb[x]);
+ if (diff > slave->target->error_tolerance)
+ return FALSE;
+ }
+ }
+ aa += stride;
+ bb += stride;
+ }
+ break;
+
+ case CAIRO_FORMAT_A1:
+ width /= 8;
+ for (y = 0; y < height; y++) {
+ if (memcmp (aa, bb, width))
+ return FALSE;
+ aa += stride;
+ bb += stride;
+ }
+ break;
+
+ case CAIRO_FORMAT_RGB30:
+ case CAIRO_FORMAT_RGB16_565:
+ case CAIRO_FORMAT_INVALID:
+ assert (0);
+ }
+
+ return TRUE;
+ }
+}
+
+static cairo_bool_t
+check_images (struct slave *slaves, int num_slaves)
+{
+ int n;
+
+ if (ignore_image_differences)
+ return TRUE;
+
+ for (n = 0; n < num_slaves; n++) {
+ if (slaves[n].reference == NULL)
+ continue;
+
+ if (! matches_reference (&slaves[n]))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static void
+write_images (const char *trace, struct slave *slave, int num_slaves)
+{
+ while (num_slaves--) {
+ if (slave->image != NULL && ! slave->is_recording) {
+ char *filename;
+
+ xasprintf (&filename, "%s-%s-fail.png",
+ trace, slave->target->name);
+ cairo_surface_write_to_png (slave->image, filename);
+ free (filename);
+
+ if (slave->difference) {
+ xasprintf (&filename, "%s-%s-diff.png",
+ trace, slave->target->name);
+ cairo_surface_write_to_png (slave->difference, filename);
+ free (filename);
+ }
+ }
+
+ slave++;
+ }
+}
+
+static void
+write_result (const char *trace, struct slave *slave)
+{
+ static int index;
+ char *filename;
+
+ xasprintf (&filename, "%s-%s-pass-%d-%d-%d.png",
+ trace, slave->target->name, ++index,
+ slave->start_line, slave->end_line);
+ cairo_surface_write_to_png (slave->image, filename);
+ free (filename);
+}
+
+static void
+write_trace (const char *trace, const char *id, struct slave *slave)
+{
+#if CAIRO_HAS_SCRIPT_SURFACE
+ cairo_device_t *script;
+ char *filename;
+
+ assert (slave->is_recording);
+
+ xasprintf (&filename, "%s-%s.trace", trace, id);
+
+ script = cairo_script_create (filename);
+ cairo_script_from_recording_surface (script, slave->image);
+ cairo_device_destroy (script);
+
+ free (filename);
+#endif
+}
+
+static void
+dump_traces (test_runner_t *tr,
+ const char *trace,
+ const char *target,
+ const char *fail)
+{
+#if CAIRO_HAS_SCRIPT_SURFACE
+ struct context_closure *c;
+
+ for (c = tr->contexts; c; c = c->next) {
+ cairo_device_t *script;
+ char *filename;
+
+ xasprintf (&filename, "%s-%s-%s.%lu.trace",
+ trace, target, fail, c->start_line);
+
+ script = cairo_script_create (filename);
+ cairo_script_from_recording_surface (script, c->surface);
+ cairo_device_destroy (script);
+
+ free (filename);
+ }
+#endif
+}
+
+static unsigned long
+allocate_image_for_slave (uint8_t *base,
+ unsigned long offset,
+ struct slave *slave)
+{
+ struct request_image rq;
+ int size;
+ uint8_t *data;
+
+ assert (slave->image == NULL);
+
+ readn (slave->fd, &rq, sizeof (rq));
+ slave->image_serial = rq.id;
+ slave->start_line = rq.start_line;
+ slave->end_line = rq.end_line;
+
+ slave->width = rq.width;
+ slave->height = rq.height;
+
+ if (DEBUG > 1) {
+ printf ("allocate-image-for-slave: %s %lu [%lu, %lu] %ldx%ld stride=%lu => %lu, is-recording? %d\n",
+ TARGET_NAME (slave->target),
+ slave->image_serial,
+ slave->start_line,
+ slave->end_line,
+ slave->width,
+ slave->height,
+ rq.stride,
+ offset,
+ slave->is_recording);
+ }
+
+ if (slave->is_recording) {
+ /* special communication with recording-surface thread */
+ slave->image = cairo_surface_reference ((cairo_surface_t *) rq.stride);
+ } else {
+ size = rq.height * rq.stride;
+ size = (size + 4095) & -4096;
+ data = base + offset;
+ offset += size;
+ assert (offset <= DATA_SIZE);
+
+ slave->image = cairo_image_surface_create_for_data (data, rq.format,
+ rq.width, rq.height,
+ rq.stride);
+ }
+
+ return offset;
+}
+
+struct error_info {
+ unsigned long context_id;
+ unsigned long start_line;
+ unsigned long end_line;
+};
+
+static cairo_bool_t
+test_run (void *base,
+ int sk,
+ const char *trace,
+ struct slave *slaves,
+ int num_slaves,
+ struct error_info *error)
+{
+ struct pollfd *pfd;
+ int npfd, cnt, n, i;
+ int completion, err = 0;
+ cairo_bool_t ret = FALSE;
+ unsigned long image;
+
+ if (DEBUG) {
+ printf ("Running trace '%s' over %d slaves\n",
+ trace, num_slaves);
+ }
+
+ pfd = xcalloc (num_slaves+1, sizeof (*pfd));
+
+ pfd[0].fd = sk;
+ pfd[0].events = POLLIN;
+ npfd = 1;
+
+ completion = 0;
+ image = 0;
+ while ((cnt = poll (pfd, npfd, -1)) > 0) {
+ if (pfd[0].revents) {
+ int fd;
+
+ while ((fd = accept (sk, NULL, NULL)) != -1) {
+ pid_t pid;
+
+ readn (fd, &pid, sizeof (pid));
+ for (n = 0; n < num_slaves; n++) {
+ if (slaves[n].pid == pid) {
+ slaves[n].fd = fd;
+ break;
+ }
+ }
+ if (n == num_slaves) {
+ if (DEBUG)
+ printf ("unknown slave pid\n");
+ goto out;
+ }
+
+ pfd[npfd].fd = fd;
+ pfd[npfd].events = POLLIN;
+ npfd++;
+
+ if (! writen (fd, &pid, sizeof (pid)))
+ goto out;
+ }
+ cnt--;
+ }
+
+ for (n = 1; n < npfd && cnt; n++) {
+ if (! pfd[n].revents)
+ continue;
+
+ if (pfd[n].revents & POLLHUP) {
+ pfd[n].events = pfd[n].revents = 0;
+ completion++;
+ continue;
+ }
+
+ for (i = 0; i < num_slaves; i++) {
+ if (slaves[i].fd == pfd[n].fd) {
+ /* Communication with the slave is done in three phases,
+ * and we do each pass synchronously.
+ *
+ * 1. The slave requests an image buffer, which we
+ * allocate and then return to the slave the offset into
+ * the shared memory segment.
+ *
+ * 2. The slave indicates that it has finished writing
+ * into the shared image buffer. The slave now waits
+ * for the server to collate all the image data - thereby
+ * throttling the slaves.
+ *
+ * 3. After all slaves have finished writing their images,
+ * we compare them all against the reference image and,
+ * if satisfied, send an acknowledgement to all slaves.
+ */
+ if (slaves[i].image_serial == 0) {
+ unsigned long offset;
+
+ image =
+ allocate_image_for_slave (base,
+ offset = image,
+ &slaves[i]);
+ if (! writen (pfd[n].fd, &offset, sizeof (offset))) {
+ pfd[n].events = pfd[n].revents = 0;
+ err = 1;
+ completion++;
+ continue;
+ }
+ } else {
+ readn (pfd[n].fd,
+ &slaves[i].image_ready,
+ sizeof (slaves[i].image_ready));
+ if (DEBUG) {
+ printf ("slave '%s' reports completion on %lu (expecting %lu)\n",
+ TARGET_NAME (slaves[i].target),
+ slaves[i].image_ready,
+ slaves[i].image_serial);
+ }
+ if (slaves[i].image_ready != slaves[i].image_serial) {
+ pfd[n].events = pfd[n].revents = 0;
+ err = 1;
+ completion++;
+ continue;
+ }
+
+ /* Can anyone spell 'P·E·D·A·N·T'? */
+ if (! slaves[i].is_recording)
+ cairo_surface_mark_dirty (slaves[i].image);
+ completion++;
+ }
+
+ break;
+ }
+ }
+
+ cnt--;
+ }
+
+ if (completion >= num_slaves) {
+ if (err) {
+ if (DEBUG > 1)
+ printf ("error detected\n");
+ goto out;
+ }
+
+ if (DEBUG > 1) {
+ printf ("all saves report completion\n");
+ }
+ if (slaves[0].end_line >= slaves[0].start_line &&
+ ! check_images (slaves, num_slaves)) {
+ error->context_id = slaves[0].image_serial;
+ error->start_line = slaves[0].start_line;
+ error->end_line = slaves[0].end_line;
+
+ if (DEBUG) {
+ printf ("check_images failed: %lu, [%lu, %lu]\n",
+ slaves[0].image_serial,
+ slaves[0].start_line,
+ slaves[0].end_line);
+ }
+
+ write_images (trace, slaves, num_slaves);
+
+ if (slaves[0].is_recording)
+ write_trace (trace, "fail", &slaves[0]);
+
+ goto out;
+ }
+
+ if (write_results) write_result (trace, &slaves[1]);
+ if (write_traces && slaves[0].is_recording) {
+ char buf[80];
+ snprintf (buf, sizeof (buf), "%d", slaves[0].image_serial);
+ write_trace (trace, buf, &slaves[0]);
+ }
+
+ /* ack */
+ for (i = 0; i < num_slaves; i++) {
+ cairo_surface_destroy (slaves[i].image);
+ slaves[i].image = NULL;
+
+ if (DEBUG > 1) {
+ printf ("sending continuation to '%s'\n",
+ TARGET_NAME (slaves[i].target));
+ }
+ if (! writen (slaves[i].fd,
+ &slaves[i].image_serial,
+ sizeof (slaves[i].image_serial)))
+ {
+ goto out;
+ }
+
+ slaves[i].image_serial = 0;
+ slaves[i].image_ready = 0;
+ }
+
+ completion = 0;
+ image = 0;
+ }
+ }
+done:
+ ret = TRUE;
+
+out:
+ if (DEBUG) {
+ printf ("run complete: %d\n", ret);
+ }
+
+ for (n = 0; n < num_slaves; n++) {
+ if (slaves[n].fd != -1)
+ close (slaves[n].fd);
+
+ if (slaves[n].image == NULL)
+ continue;
+
+ cairo_surface_destroy (slaves[n].image);
+ slaves[n].image = NULL;
+
+ cairo_surface_destroy (slaves[n].difference);
+ slaves[n].difference = NULL;
+
+ slaves[n].image_serial = 0;
+ slaves[n].image_ready = 0;
+ }
+
+ free (pfd);
+
+ return ret;
+}
+
+static int
+server_socket (const char *socket_path)
+{
+ long flags;
+ struct sockaddr_un addr;
+ int sk;
+
+ sk = socket (PF_UNIX, SOCK_STREAM, 0);
+ if (sk == -1)
+ return -1;
+
+ memset (&addr, 0, sizeof (addr));
+ addr.sun_family = AF_UNIX;
+ strcpy (addr.sun_path, socket_path);
+ if (bind (sk, (struct sockaddr *) &addr, sizeof (addr)) == -1) {
+ close (sk);
+ return -1;
+ }
+
+ flags = fcntl (sk, F_GETFL);
+ if (flags == -1 || fcntl (sk, F_SETFL, flags | O_NONBLOCK) == -1) {
+ close (sk);
+ return -1;
+ }
+
+ if (listen (sk, 5) == -1) {
+ close (sk);
+ return -1;
+ }
+
+ return sk;
+}
+
+static int
+server_shm (const char *shm_path)
+{
+ int fd;
+
+ fd = shm_open (shm_path, O_RDWR | O_EXCL | O_CREAT, 0777);
+ if (fd == -1)
+ return -1;
+
+ if (ftruncate (fd, DATA_SIZE) == -1) {
+ close (fd);
+ return -1;
+ }
+
+ return fd;
+}
+
+static cairo_bool_t
+_test_trace (test_trace_t *test,
+ const char *trace,
+ const char *name,
+ struct error_info *error)
+{
+ const char *shm_path = SHM_PATH_XXX;
+ const cairo_boilerplate_target_t *target, *image;
+ struct slave *slaves, *s;
+ test_runner_t *recorder = NULL;
+ pid_t slave;
+ char socket_dir[] = "/tmp/cairo-test-trace.XXXXXX";
+ char *socket_path;
+ int sk, fd;
+ int i, num_slaves;
+ void *base;
+ cairo_bool_t ret = FALSE;
+
+ if (DEBUG)
+ printf ("setting up trace '%s'\n", trace);
+
+ /* create a socket to control the test runners */
+ if (mkdtemp (socket_dir) == NULL) {
+ fprintf (stderr, "Unable to create temporary name for socket\n");
+ return FALSE;
+ }
+
+ xasprintf (&socket_path, "%s/socket", socket_dir);
+ sk = server_socket (socket_path);
+ if (sk == -1) {
+ fprintf (stderr, "Unable to create socket for server\n");
+ goto cleanup_paths;
+ }
+
+ /* allocate some shared memory */
+ fd = server_shm (shm_path);
+ if (fd == -1) {
+ fprintf (stderr, "Unable to create shared memory '%s': %s\n",
+ shm_path, strerror (errno));
+ goto cleanup_sk;
+ }
+
+ image = cairo_boilerplate_get_image_target (CAIRO_CONTENT_COLOR_ALPHA);
+ assert (image != NULL);
+
+ s = slaves = xcalloc (2*test->num_targets + 1, sizeof (struct slave));
+
+#if CAIRO_HAS_REAL_PTHREAD
+ /* set-up a recording-surface to reconstruct errors */
+ slave = spawn_recorder (socket_path, trace, &recorder);
+ if (slave < 0) {
+ fprintf (stderr, "Unable to create recording surface\n");
+ goto cleanup_sk;
+ }
+
+ s->pid = slave;
+ s->is_recording = TRUE;
+ s->target = NULL;
+ s->fd = -1;
+ s->reference = NULL;
+ s++;
+#endif
+
+ /* spawn slave processes to run the trace */
+ for (i = 0; i < test->num_targets; i++) {
+ const cairo_boilerplate_target_t *reference;
+ struct slave *master;
+
+ target = test->targets[i];
+
+ if (DEBUG)
+ printf ("setting up target[%d]? '%s' (image? %d, measurable? %d)\n",
+ i, target->name, target == image, target->is_measurable);
+
+ if (target == image || ! target->is_measurable)
+ continue;
+
+ /* find a matching slave to use as a reference for this target */
+ if (target->reference_target != NULL) {
+ reference =
+ cairo_boilerplate_get_target_by_name (target->reference_target,
+ target->content);
+ assert (reference != NULL);
+ } else {
+ reference = image;
+ }
+ for (master = slaves; master < s; master++) {
+ if (master->target == reference)
+ break;
+ }
+
+ if (master == s) {
+ /* no match found, spawn a slave to render the reference image */
+ slave = spawn_target (socket_path, shm_path, reference, trace);
+ if (slave < 0)
+ continue;
+
+ s->pid = slave;
+ s->target = reference;
+ s->fd = -1;
+ s->reference = NULL;
+ s++;
+ }
+
+ slave = spawn_target (socket_path, shm_path, target, trace);
+ if (slave < 0)
+ continue;
+
+ s->pid = slave;
+ s->target = target;
+ s->fd = -1;
+ s->reference = master;
+ s++;
+ }
+ num_slaves = s - slaves;
+ if (num_slaves == 1) {
+ fprintf (stderr, "No targets to test\n");
+ goto cleanup;
+ }
+
+ base = mmap (NULL, DATA_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+ if (base == MAP_FAILED) {
+ fprintf (stderr, "Unable to mmap shared memory\n");
+ goto cleanup;
+ }
+ ret = test_run (base, sk, name, slaves, num_slaves, error);
+ munmap (base, DATA_SIZE);
+
+cleanup:
+ close (fd);
+ while (s-- > slaves) {
+ int status;
+
+ if (s->fd != -1)
+ close (s->fd);
+
+ cairo_surface_destroy (s->image);
+ cairo_surface_destroy (s->difference);
+
+ if (s->is_recording) /* in-process */
+ continue;
+
+ kill (s->pid, SIGKILL);
+ waitpid (s->pid, &status, 0);
+ if (WIFSIGNALED (status) && WTERMSIG(status) != SIGKILL) {
+ fprintf (stderr, "%s crashed\n", s->target->name);
+ if (recorder)
+ dump_traces (recorder, trace, s->target->name, "crash");
+ }
+ }
+ free (slaves);
+ shm_unlink (shm_path);
+cleanup_sk:
+ close (sk);
+
+cleanup_paths:
+ remove (socket_path);
+ remove (socket_dir);
+
+ free (socket_path);
+ return ret;
+}
+
+static void
+test_trace (test_trace_t *test, const char *trace)
+{
+ char *trace_cpy, *name, *dot;
+
+ trace_cpy = xstrdup (trace);
+ name = basename (trace_cpy);
+ dot = strchr (name, '.');
+ if (dot)
+ *dot = '\0';
+
+ if (test->list_only) {
+ printf ("%s\n", name);
+ } else {
+ struct error_info error = {0};
+ cairo_bool_t ret;
+
+ printf ("%s: ", name);
+ fflush (stdout);
+
+ ret = _test_trace (test, trace, name, &error);
+ if (ret) {
+ printf ("PASS\n");
+ } else {
+ if (error.context_id) {
+ printf ("FAIL (context %lu, lines [%lu, %lu])\n",
+ error.context_id,
+ error.start_line,
+ error.end_line);
+ } else {
+ printf ("FAIL\n");
+ }
+ }
+ }
+
+ free (trace_cpy);
+}
+
+static cairo_bool_t
+read_excludes (test_trace_t *test, const char *filename)
+{
+ FILE *file;
+ char *line = NULL;
+ size_t line_size = 0;
+ char *s, *t;
+
+ file = fopen (filename, "r");
+ if (file == NULL)
+ return FALSE;
+
+ while (getline (&line, &line_size, file) != -1) {
+ /* terminate the line at a comment marker '#' */
+ s = strchr (line, '#');
+ if (s)
+ *s = '\0';
+
+ /* whitespace delimits */
+ s = line;
+ while (*s != '\0' && isspace (*s))
+ s++;
+
+ t = s;
+ while (*t != '\0' && ! isspace (*t))
+ t++;
+
+ if (s != t) {
+ int i = test->num_exclude_names;
+ test->exclude_names = xrealloc (test->exclude_names,
+ sizeof (char *) * (i+1));
+ test->exclude_names[i] = strndup (s, t-s);
+ test->num_exclude_names++;
+ }
+ }
+ free (line);
+
+ fclose (file);
+
+ return TRUE;
+}
+
+static void
+usage (const char *argv0)
+{
+ fprintf (stderr,
+"Usage: %s [-l] [-x exclude-file] [test-names ... | traces ...]\n"
+"\n"
+"Run the cairo test suite over the given traces (all by default).\n"
+"The command-line arguments are interpreted as follows:\n"
+"\n"
+" -l list only; just list selected test case names without executing\n"
+" -x exclude; specify a file to read a list of traces to exclude\n"
+"\n"
+"If test names are given they are used as sub-string matches so a command\n"
+"such as \"%s firefox\" can be used to run all firefox traces.\n"
+"Alternatively, you can specify a list of filenames to execute.\n",
+ argv0, argv0);
+}
+
+static void
+parse_options (test_trace_t *test, int argc, char *argv[])
+{
+ int c;
+
+ test->list_only = FALSE;
+ test->names = NULL;
+ test->num_names = 0;
+ test->exclude_names = NULL;
+ test->num_exclude_names = 0;
+
+ while (1) {
+ c = _cairo_getopt (argc, argv, "lx:");
+ if (c == -1)
+ break;
+
+ switch (c) {
+ case 'l':
+ test->list_only = TRUE;
+ break;
+ case 'x':
+ if (! read_excludes (test, optarg)) {
+ fprintf (stderr, "Invalid argument for -x (not readable file): %s\n",
+ optarg);
+ exit (1);
+ }
+ break;
+ default:
+ fprintf (stderr, "Internal error: unhandled option: %c\n", c);
+ /* fall-through */
+ case '?':
+ usage (argv[0]);
+ exit (1);
+ }
+ }
+
+ if (optind < argc) {
+ test->names = &argv[optind];
+ test->num_names = argc - optind;
+ }
+}
+
+static void
+test_reset (test_trace_t *test)
+{
+ /* XXX leaking fonts again via recording-surface? */
+#if 0
+ cairo_debug_reset_static_data ();
+#if HAVE_FCFINI
+ FcFini ();
+#endif
+#endif
+}
+
+static void
+test_fini (test_trace_t *test)
+{
+ test_reset (test);
+
+ cairo_boilerplate_free_targets (test->targets);
+ free (test->exclude_names);
+}
+
+static cairo_bool_t
+test_has_filenames (test_trace_t *test)
+{
+ unsigned int i;
+
+ if (test->num_names == 0)
+ return FALSE;
+
+ for (i = 0; i < test->num_names; i++)
+ if (access (test->names[i], R_OK) == 0)
+ return TRUE;
+
+ return FALSE;
+}
+
+static cairo_bool_t
+test_can_run (test_trace_t *test, const char *name)
+{
+ unsigned int i;
+ char *copy, *dot;
+ cairo_bool_t ret;
+
+ if (test->num_names == 0 && test->num_exclude_names == 0)
+ return TRUE;
+
+ copy = xstrdup (name);
+ dot = strrchr (copy, '.');
+ if (dot != NULL)
+ *dot = '\0';
+
+ if (test->num_names) {
+ ret = TRUE;
+ for (i = 0; i < test->num_names; i++)
+ if (strstr (copy, test->names[i]))
+ goto check_exclude;
+
+ ret = FALSE;
+ goto done;
+ }
+
+check_exclude:
+ if (test->num_exclude_names) {
+ ret = FALSE;
+ for (i = 0; i < test->num_exclude_names; i++)
+ if (strstr (copy, test->exclude_names[i]))
+ goto done;
+
+ ret = TRUE;
+ goto done;
+ }
+
+done:
+ free (copy);
+
+ return ret;
+}
+
+static void
+warn_no_traces (const char *message, const char *trace_dir)
+{
+ fprintf (stderr,
+"Error: %s '%s'.\n"
+"Have you cloned the cairo-traces repository and uncompressed the traces?\n"
+" git clone git://anongit.freedesktop.org/cairo-traces\n"
+" cd cairo-traces && make\n"
+"Or set the env.var CAIRO_TRACE_DIR to point to your traces?\n",
+ message, trace_dir);
+}
+
+static void
+interrupt (int sig)
+{
+ shm_unlink (SHM_PATH_XXX);
+
+ signal (sig, SIG_DFL);
+ raise (sig);
+}
+
+int
+main (int argc, char *argv[])
+{
+ test_trace_t test;
+ const char *trace_dir = "cairo-traces";
+ unsigned int n;
+
+ signal (SIGPIPE, SIG_IGN);
+ signal (SIGINT, interrupt);
+
+ parse_options (&test, argc, argv);
+
+ shm_unlink (SHM_PATH_XXX);
+
+ if (getenv ("CAIRO_TRACE_DIR") != NULL)
+ trace_dir = getenv ("CAIRO_TRACE_DIR");
+
+ test.targets = cairo_boilerplate_get_targets (&test.num_targets, NULL);
+
+ if (test_has_filenames (&test)) {
+ for (n = 0; n < test.num_names; n++) {
+ if (access (test.names[n], R_OK) == 0) {
+ test_trace (&test, test.names[n]);
+ test_reset (&test);
+ }
+ }
+ } else {
+ DIR *dir;
+ struct dirent *de;
+ int num_traces = 0;
+
+ dir = opendir (trace_dir);
+ if (dir == NULL) {
+ warn_no_traces ("Failed to open directory", trace_dir);
+ test_fini (&test);
+ return 1;
+ }
+
+ while ((de = readdir (dir)) != NULL) {
+ char *trace;
+ const char *dot;
+
+ dot = strrchr (de->d_name, '.');
+ if (dot == NULL)
+ continue;
+ if (strcmp (dot, ".trace"))
+ continue;
+
+ num_traces++;
+ if (! test_can_run (&test, de->d_name))
+ continue;
+
+ xasprintf (&trace, "%s/%s", trace_dir, de->d_name);
+ test_trace (&test, trace);
+ test_reset (&test);
+
+ free (trace);
+
+ }
+ closedir (dir);
+
+ if (num_traces == 0) {
+ warn_no_traces ("Found no traces in", trace_dir);
+ test_fini (&test);
+ return 1;
+ }
+ }
+
+ test_fini (&test);
+
+ return 0;
+}
+
+void
+cairo_test_logv (const cairo_test_context_t *ctx,
+ const char *fmt, va_list va)
+{
+#if 0
+ vfprintf (stderr, fmt, va);
+#endif
+}
+
+void
+cairo_test_log (const cairo_test_context_t *ctx, const char *fmt, ...)
+{
+#if 0
+ va_list va;
+
+ va_start (va, fmt);
+ vfprintf (stderr, fmt, va);
+ va_end (va);
+#endif
+}
diff --git a/test/cairo-test.c b/test/cairo-test.c
new file mode 100644
index 000000000..a351b0174
--- /dev/null
+++ b/test/cairo-test.c
@@ -0,0 +1,1803 @@
+/*
+ * Copyright © 2004 Red Hat, Inc.
+ * Copyright © 2008 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ * Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#define _GNU_SOURCE 1 /* for feenableexcept() et al */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <ctype.h>
+#include <assert.h>
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <errno.h>
+#include <string.h>
+#if HAVE_FCFINI
+#include <fontconfig/fontconfig.h>
+#endif
+#if CAIRO_HAS_REAL_PTHREAD
+#include <pthread.h>
+#endif
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+
+#if HAVE_VALGRIND
+#include <valgrind.h>
+#else
+#define RUNNING_ON_VALGRIND 0
+#endif
+
+#if HAVE_MEMFAULT
+#include <memfault.h>
+#define MF(x) x
+#else
+#define MF(x)
+#endif
+
+#include "cairo-test-private.h"
+
+#include "buffer-diff.h"
+
+#ifdef _MSC_VER
+#include <crtdbg.h>
+#include <direct.h>
+#define F_OK 0
+#define HAVE_MKDIR 1
+#define mkdir _mkdir
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+#ifndef TRUE
+#define TRUE !FALSE
+#endif
+
+#if ! HAVE_ALARM || ! defined(SIGALRM)
+#define alarm(X);
+#endif
+
+static const cairo_user_data_key_t _cairo_test_context_key;
+
+static void
+_xunlink (const cairo_test_context_t *ctx, const char *pathname);
+
+static const char *fail_face = "", *xfail_face="", *normal_face = "";
+static cairo_bool_t print_fail_on_stdout;
+static int cairo_test_timeout = 60;
+
+#define NUM_DEVICE_OFFSETS 2
+#define NUM_DEVICE_SCALE 2
+
+cairo_bool_t
+cairo_test_mkdir (const char *path)
+{
+#if ! HAVE_MKDIR
+ return FALSE;
+#elif HAVE_MKDIR == 1
+ if (mkdir (path) == 0)
+ return TRUE;
+#elif HAVE_MKDIR == 2
+ if (mkdir (path, 0770) == 0)
+ return TRUE;
+#else
+#error Bad value for HAVE_MKDIR
+#endif
+
+ return errno == EEXIST;
+}
+
+static char *
+_cairo_test_fixup_name (const char *original)
+{
+ char *name, *s;
+
+ s = name = xstrdup (original);
+ while ((s = strchr (s, '_')) != NULL)
+ *s++ = '-';
+
+ return name;
+}
+
+char *
+cairo_test_get_name (const cairo_test_t *test)
+{
+ return _cairo_test_fixup_name (test->name);
+}
+
+static void
+_cairo_test_init (cairo_test_context_t *ctx,
+ const cairo_test_context_t *parent,
+ const cairo_test_t *test,
+ const char *test_name,
+ const char *output)
+{
+ char *log_name;
+
+ MF (MEMFAULT_DISABLE_FAULTS ());
+
+#if HAVE_FEENABLEEXCEPT
+ feenableexcept (FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW);
+#endif
+
+ ctx->test = test;
+ ctx->test_name = _cairo_test_fixup_name (test_name);
+ ctx->output = output;
+
+ cairo_test_mkdir (ctx->output);
+
+ ctx->malloc_failure = 0;
+#if HAVE_MEMFAULT
+ if (getenv ("CAIRO_TEST_MALLOC_FAILURE"))
+ ctx->malloc_failure = atoi (getenv ("CAIRO_TEST_MALLOC_FAILURE"));
+ if (ctx->malloc_failure && ! RUNNING_ON_MEMFAULT ())
+ ctx->malloc_failure = 0;
+#endif
+
+ ctx->timeout = cairo_test_timeout;
+ if (getenv ("CAIRO_TEST_TIMEOUT"))
+ ctx->timeout = atoi (getenv ("CAIRO_TEST_TIMEOUT"));
+
+ xasprintf (&log_name, "%s/%s%s", ctx->output, ctx->test_name, CAIRO_TEST_LOG_SUFFIX);
+ _xunlink (NULL, log_name);
+
+ ctx->log_file = fopen (log_name, "a");
+ if (ctx->log_file == NULL) {
+ fprintf (stderr, "Error opening log file: %s\n", log_name);
+ ctx->log_file = stderr;
+ }
+ free (log_name);
+
+ ctx->ref_name = NULL;
+ ctx->ref_image = NULL;
+ ctx->ref_image_flattened = NULL;
+
+ if (parent != NULL) {
+ ctx->targets_to_test = parent->targets_to_test;
+ ctx->num_targets = parent->num_targets;
+ ctx->limited_targets = parent->limited_targets;
+ ctx->own_targets = FALSE;
+
+ ctx->srcdir = parent->srcdir;
+ ctx->refdir = parent->refdir;
+ } else {
+ int tmp_num_targets;
+ cairo_bool_t tmp_limited_targets;
+
+ ctx->targets_to_test = cairo_boilerplate_get_targets (&tmp_num_targets, &tmp_limited_targets);
+ ctx->num_targets = tmp_num_targets;
+ ctx->limited_targets = tmp_limited_targets;
+ ctx->own_targets = TRUE;
+
+ ctx->srcdir = getenv ("srcdir");
+ if (ctx->srcdir == NULL)
+ ctx->srcdir = ".";
+
+ ctx->refdir = getenv ("CAIRO_REF_DIR");
+ }
+
+#ifdef HAVE_UNISTD_H
+ if (*fail_face == '\0' && isatty (2)) {
+ fail_face = "\033[41;37;1m";
+ xfail_face = "\033[43;37;1m";
+ normal_face = "\033[m";
+ if (isatty (1))
+ print_fail_on_stdout = FALSE;
+ }
+#endif
+
+ printf ("\nTESTING %s\n", ctx->test_name);
+}
+
+void
+_cairo_test_context_init_for_test (cairo_test_context_t *ctx,
+ const cairo_test_context_t *parent,
+ const cairo_test_t *test)
+{
+ _cairo_test_init (ctx, parent, test, test->name, CAIRO_TEST_OUTPUT_DIR);
+}
+
+void
+cairo_test_init (cairo_test_context_t *ctx,
+ const char *test_name,
+ const char *output)
+{
+ _cairo_test_init (ctx, NULL, NULL, test_name, output);
+}
+
+void
+cairo_test_fini (cairo_test_context_t *ctx)
+{
+ if (ctx->log_file == NULL)
+ return;
+
+ if (ctx->log_file != stderr)
+ fclose (ctx->log_file);
+ ctx->log_file = NULL;
+
+ free (ctx->ref_name);
+ cairo_surface_destroy (ctx->ref_image);
+ cairo_surface_destroy (ctx->ref_image_flattened);
+
+ if (ctx->test_name != NULL)
+ free ((char *) ctx->test_name);
+
+ if (ctx->own_targets)
+ cairo_boilerplate_free_targets (ctx->targets_to_test);
+
+ cairo_boilerplate_fini ();
+
+ cairo_debug_reset_static_data ();
+#if HAVE_FCFINI
+ FcFini ();
+#endif
+}
+
+void
+cairo_test_logv (const cairo_test_context_t *ctx,
+ const char *fmt, va_list va)
+{
+ FILE *file = ctx && ctx->log_file ? ctx->log_file : stderr;
+ vfprintf (file, fmt, va);
+}
+
+void
+cairo_test_log (const cairo_test_context_t *ctx, const char *fmt, ...)
+{
+ va_list va;
+
+ va_start (va, fmt);
+ cairo_test_logv (ctx, fmt, va);
+ va_end (va);
+}
+
+static void
+_xunlink (const cairo_test_context_t *ctx, const char *pathname)
+{
+ if (unlink (pathname) < 0 && errno != ENOENT) {
+ cairo_test_log (ctx, "Error: Cannot remove %s: %s\n",
+ pathname, strerror (errno));
+ exit (1);
+ }
+}
+
+char *
+cairo_test_reference_filename (const cairo_test_context_t *ctx,
+ const char *base_name,
+ const char *test_name,
+ const char *target_name,
+ const char *base_target_name,
+ const char *format,
+ const char *suffix,
+ const char *extension)
+{
+ char *ref_name = NULL;
+
+ /* First look for a previous build for comparison. */
+ if (ctx->refdir != NULL && strcmp(suffix, CAIRO_TEST_REF_SUFFIX) == 0) {
+ xasprintf (&ref_name, "%s/%s" CAIRO_TEST_OUT_SUFFIX "%s",
+ ctx->refdir,
+ base_name,
+ extension);
+ if (access (ref_name, F_OK) != 0)
+ free (ref_name);
+ else
+ goto done;
+ }
+
+ if (target_name != NULL) {
+ /* Next look for a target/format-specific reference image. */
+ xasprintf (&ref_name, "%s/reference/%s.%s.%s%s%s",
+ ctx->srcdir,
+ test_name,
+ target_name,
+ format,
+ suffix,
+ extension);
+ if (access (ref_name, F_OK) != 0)
+ free (ref_name);
+ else
+ goto done;
+
+ /* Next, look for target-specific reference image. */
+ xasprintf (&ref_name, "%s/reference/%s.%s%s%s",
+ ctx->srcdir,
+ test_name,
+ target_name,
+ suffix,
+ extension);
+ if (access (ref_name, F_OK) != 0)
+ free (ref_name);
+ else
+ goto done;
+ }
+
+ if (base_target_name != NULL) {
+ /* Next look for a base/format-specific reference image. */
+ xasprintf (&ref_name, "%s/reference/%s.%s.%s%s%s",
+ ctx->srcdir,
+ test_name,
+ base_target_name,
+ format,
+ suffix,
+ extension);
+ if (access (ref_name, F_OK) != 0)
+ free (ref_name);
+ else
+ goto done;
+
+ /* Next, look for base-specific reference image. */
+ xasprintf (&ref_name, "%s/reference/%s.%s%s%s",
+ ctx->srcdir,
+ test_name,
+ base_target_name,
+ suffix,
+ extension);
+ if (access (ref_name, F_OK) != 0)
+ free (ref_name);
+ else
+ goto done;
+ }
+
+ /* Next, look for format-specific reference image. */
+ xasprintf (&ref_name, "%s/reference/%s.%s%s%s",
+ ctx->srcdir,
+ test_name,
+ format,
+ suffix,
+ extension);
+ if (access (ref_name, F_OK) != 0)
+ free (ref_name);
+ else
+ goto done;
+
+ /* Finally, look for the standard reference image. */
+ xasprintf (&ref_name, "%s/reference/%s%s%s", ctx->srcdir,
+ test_name,
+ suffix,
+ extension);
+ if (access (ref_name, F_OK) != 0)
+ free (ref_name);
+ else
+ goto done;
+
+ ref_name = NULL;
+
+done:
+ return ref_name;
+}
+
+cairo_test_similar_t
+cairo_test_target_has_similar (const cairo_test_context_t *ctx,
+ const cairo_boilerplate_target_t *target)
+{
+ cairo_surface_t *surface;
+ cairo_test_similar_t has_similar;
+ cairo_t * cr;
+ cairo_surface_t *similar;
+ cairo_status_t status;
+ void *closure;
+ char *path;
+
+ /* ignore image intermediate targets */
+ if (target->expected_type == CAIRO_SURFACE_TYPE_IMAGE)
+ return DIRECT;
+
+ if (getenv ("CAIRO_TEST_IGNORE_SIMILAR"))
+ return DIRECT;
+
+ xasprintf (&path, "%s/%s",
+ cairo_test_mkdir (ctx->output) ? ctx->output : ".",
+ ctx->test_name);
+
+ has_similar = DIRECT;
+ do {
+ do {
+ surface = (target->create_surface) (path,
+ target->content,
+ ctx->test->width,
+ ctx->test->height,
+ ctx->test->width* NUM_DEVICE_SCALE + 25 * NUM_DEVICE_OFFSETS,
+ ctx->test->height* NUM_DEVICE_SCALE + 25 * NUM_DEVICE_OFFSETS,
+ CAIRO_BOILERPLATE_MODE_TEST,
+ &closure);
+ if (surface == NULL)
+ goto out;
+ } while (cairo_test_malloc_failure (ctx, cairo_surface_status (surface)));
+
+ if (cairo_surface_status (surface))
+ goto out;
+
+ cr = cairo_create (surface);
+ cairo_push_group_with_content (cr,
+ cairo_boilerplate_content (target->content));
+ similar = cairo_get_group_target (cr);
+ status = cairo_surface_status (similar);
+
+ if (cairo_surface_get_type (similar) == cairo_surface_get_type (surface))
+ has_similar = SIMILAR;
+ else
+ has_similar = DIRECT;
+
+ cairo_destroy (cr);
+ cairo_surface_destroy (surface);
+
+ if (target->cleanup)
+ target->cleanup (closure);
+ } while (! has_similar && cairo_test_malloc_failure (ctx, status));
+out:
+ free (path);
+
+ return has_similar;
+}
+
+static cairo_surface_t *
+_cairo_test_flatten_reference_image (cairo_test_context_t *ctx,
+ cairo_bool_t flatten)
+{
+ cairo_surface_t *surface;
+ cairo_t *cr;
+
+ if (! flatten)
+ return ctx->ref_image;
+
+ if (ctx->ref_image_flattened != NULL)
+ return ctx->ref_image_flattened;
+
+ surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
+ cairo_image_surface_get_width (ctx->ref_image),
+ cairo_image_surface_get_height (ctx->ref_image));
+ cr = cairo_create (surface);
+ cairo_surface_destroy (surface);
+
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+ cairo_set_source_surface (cr, ctx->ref_image, 0, 0);
+ cairo_paint (cr);
+
+ surface = cairo_surface_reference (cairo_get_target (cr));
+ cairo_destroy (cr);
+
+ if (cairo_surface_status (surface) == CAIRO_STATUS_SUCCESS)
+ ctx->ref_image_flattened = surface;
+ return surface;
+}
+
+cairo_surface_t *
+cairo_test_get_reference_image (cairo_test_context_t *ctx,
+ const char *filename,
+ cairo_bool_t flatten)
+{
+ cairo_surface_t *surface;
+
+ if (ctx->ref_name != NULL) {
+ if (strcmp (ctx->ref_name, filename) == 0)
+ return _cairo_test_flatten_reference_image (ctx, flatten);
+
+ cairo_surface_destroy (ctx->ref_image);
+ ctx->ref_image = NULL;
+
+ cairo_surface_destroy (ctx->ref_image_flattened);
+ ctx->ref_image_flattened = NULL;
+
+ free (ctx->ref_name);
+ ctx->ref_name = NULL;
+ }
+
+ surface = cairo_image_surface_create_from_png (filename);
+ if (cairo_surface_status (surface))
+ return surface;
+
+ ctx->ref_name = xstrdup (filename);
+ ctx->ref_image = surface;
+ return _cairo_test_flatten_reference_image (ctx, flatten);
+}
+
+static cairo_bool_t
+cairo_test_file_is_older (const char *filename,
+ char **ref_filenames,
+ int num_ref_filenames)
+{
+#if HAVE_SYS_STAT_H
+ struct stat st;
+
+ if (stat (filename, &st) < 0)
+ return FALSE;
+
+ while (num_ref_filenames--) {
+ struct stat ref;
+ char *ref_filename = *ref_filenames++;
+
+ if (ref_filename == NULL)
+ continue;
+
+ if (stat (ref_filename++, &ref) < 0)
+ continue;
+
+ if (st.st_mtime <= ref.st_mtime)
+ return TRUE;
+ }
+#endif
+
+ return FALSE;
+}
+
+static cairo_bool_t
+cairo_test_files_equal (const char *test_filename,
+ const char *pass_filename)
+{
+ FILE *test, *pass;
+ int t, p;
+
+ if (test_filename == NULL || pass_filename == NULL)
+ return FALSE;
+
+ test = fopen (test_filename, "rb");
+ if (test == NULL)
+ return FALSE;
+
+ pass = fopen (pass_filename, "rb");
+ if (pass == NULL) {
+ fclose (test);
+ return FALSE;
+ }
+
+ /* as simple as it gets */
+ do {
+ t = getc (test);
+ p = getc (pass);
+ if (t != p)
+ break;
+ } while (t != EOF && p != EOF);
+
+ fclose (pass);
+ fclose (test);
+
+ return t == p; /* both EOF */
+}
+
+static cairo_bool_t
+cairo_test_copy_file (const char *src_filename,
+ const char *dst_filename)
+{
+ FILE *src, *dst;
+ int c;
+
+#if HAVE_LINK
+ if (link (src_filename, dst_filename) == 0)
+ return TRUE;
+
+ unlink (dst_filename);
+#endif
+
+ src = fopen (src_filename, "rb");
+ if (src == NULL)
+ return FALSE;
+
+ dst = fopen (dst_filename, "wb");
+ if (dst == NULL) {
+ fclose (src);
+ return FALSE;
+ }
+
+ /* as simple as it gets */
+ while ((c = getc (src)) != EOF)
+ putc (c, dst);
+
+ fclose (src);
+ fclose (dst);
+
+ return TRUE;
+}
+
+static cairo_test_status_t
+cairo_test_for_target (cairo_test_context_t *ctx,
+ const cairo_boilerplate_target_t *target,
+ int dev_offset,
+ int dev_scale,
+ cairo_bool_t similar)
+{
+ cairo_test_status_t status;
+ cairo_surface_t *surface = NULL;
+ cairo_t *cr;
+ const char *empty_str = "";
+ char *offset_str;
+ char *scale_str;
+ char *base_name, *base_path;
+ char *out_png_path;
+ char *ref_path = NULL, *ref_png_path, *cmp_png_path = NULL;
+ char *new_path = NULL, *new_png_path;
+ char *xfail_path = NULL, *xfail_png_path;
+ char *base_ref_png_path;
+ char *base_new_png_path;
+ char *base_xfail_png_path;
+ char *diff_png_path;
+ char *test_filename = NULL, *pass_filename = NULL, *fail_filename = NULL;
+ cairo_test_status_t ret;
+ cairo_content_t expected_content;
+ cairo_font_options_t *font_options;
+ const char *format;
+ cairo_bool_t have_output = FALSE;
+ cairo_bool_t have_result = FALSE;
+ void *closure;
+ double width, height;
+ cairo_bool_t have_output_dir;
+#if HAVE_MEMFAULT
+ int malloc_failure_iterations = ctx->malloc_failure;
+ int last_fault_count = 0;
+#endif
+
+ /* Get the strings ready that we'll need. */
+ format = cairo_boilerplate_content_name (target->content);
+ if (dev_offset)
+ xasprintf (&offset_str, ".%d", dev_offset);
+ else
+ offset_str = (char *) empty_str;
+
+ if (dev_scale != 1)
+ xasprintf (&scale_str, ".x%d", dev_scale);
+ else
+ scale_str = (char *) empty_str;
+
+ xasprintf (&base_name, "%s.%s.%s%s%s%s",
+ ctx->test_name,
+ target->name,
+ format,
+ similar ? ".similar" : "",
+ offset_str,
+ scale_str);
+
+ if (offset_str != empty_str)
+ free (offset_str);
+ if (scale_str != empty_str)
+ free (scale_str);
+
+ ref_png_path = cairo_test_reference_filename (ctx,
+ base_name,
+ ctx->test_name,
+ target->name,
+ target->basename,
+ format,
+ CAIRO_TEST_REF_SUFFIX,
+ CAIRO_TEST_PNG_EXTENSION);
+ new_png_path = cairo_test_reference_filename (ctx,
+ base_name,
+ ctx->test_name,
+ target->name,
+ target->basename,
+ format,
+ CAIRO_TEST_NEW_SUFFIX,
+ CAIRO_TEST_PNG_EXTENSION);
+ xfail_png_path = cairo_test_reference_filename (ctx,
+ base_name,
+ ctx->test_name,
+ target->name,
+ target->basename,
+ format,
+ CAIRO_TEST_XFAIL_SUFFIX,
+ CAIRO_TEST_PNG_EXTENSION);
+
+ base_ref_png_path = cairo_test_reference_filename (ctx,
+ base_name,
+ ctx->test_name,
+ NULL, NULL,
+ format,
+ CAIRO_TEST_REF_SUFFIX,
+ CAIRO_TEST_PNG_EXTENSION);
+ base_new_png_path = cairo_test_reference_filename (ctx,
+ base_name,
+ ctx->test_name,
+ NULL, NULL,
+ format,
+ CAIRO_TEST_NEW_SUFFIX,
+ CAIRO_TEST_PNG_EXTENSION);
+ base_xfail_png_path = cairo_test_reference_filename (ctx,
+ base_name,
+ ctx->test_name,
+ NULL, NULL,
+ format,
+ CAIRO_TEST_XFAIL_SUFFIX,
+ CAIRO_TEST_PNG_EXTENSION);
+
+ if (target->file_extension != NULL) {
+ ref_path = cairo_test_reference_filename (ctx,
+ base_name,
+ ctx->test_name,
+ target->name,
+ target->basename,
+ format,
+ CAIRO_TEST_REF_SUFFIX,
+ target->file_extension);
+ new_path = cairo_test_reference_filename (ctx,
+ base_name,
+ ctx->test_name,
+ target->name,
+ target->basename,
+ format,
+ CAIRO_TEST_NEW_SUFFIX,
+ target->file_extension);
+ xfail_path = cairo_test_reference_filename (ctx,
+ base_name,
+ ctx->test_name,
+ target->name,
+ target->basename,
+ format,
+ CAIRO_TEST_XFAIL_SUFFIX,
+ target->file_extension);
+ }
+
+ have_output_dir = cairo_test_mkdir (ctx->output);
+ xasprintf (&base_path, "%s/%s",
+ have_output_dir ? ctx->output : ".",
+ base_name);
+ xasprintf (&out_png_path, "%s" CAIRO_TEST_OUT_PNG, base_path);
+ xasprintf (&diff_png_path, "%s" CAIRO_TEST_DIFF_PNG, base_path);
+
+ if (ctx->test->requirements != NULL) {
+ const char *required;
+
+ required = target->is_vector ? "target=raster" : "target=vector";
+ if (strstr (ctx->test->requirements, required) != NULL) {
+ cairo_test_log (ctx, "Error: Skipping for %s target %s\n",
+ target->is_vector ? "vector" : "raster",
+ target->name);
+ ret = CAIRO_TEST_UNTESTED;
+ goto UNWIND_STRINGS;
+ }
+
+ required = target->is_recording ? "target=!recording" : "target=recording";
+ if (strstr (ctx->test->requirements, required) != NULL) {
+ cairo_test_log (ctx, "Error: Skipping for %s target %s\n",
+ target->is_recording ? "recording" : "non-recording",
+ target->name);
+ ret = CAIRO_TEST_UNTESTED;
+ goto UNWIND_STRINGS;
+ }
+ }
+
+ width = ctx->test->width;
+ height = ctx->test->height;
+ if (width && height) {
+ width *= dev_scale;
+ height *= dev_scale;
+ width += dev_offset;
+ height += dev_offset;
+ }
+
+#if HAVE_MEMFAULT
+REPEAT:
+ MEMFAULT_CLEAR_FAULTS ();
+ MEMFAULT_RESET_LEAKS ();
+ ctx->last_fault_count = 0;
+ last_fault_count = MEMFAULT_COUNT_FAULTS ();
+
+ /* Pre-initialise fontconfig so that the configuration is loaded without
+ * malloc failures (our primary goal is to test cairo fault tolerance).
+ */
+#if HAVE_FCINIT
+ FcInit ();
+#endif
+
+ MEMFAULT_ENABLE_FAULTS ();
+#endif
+ have_output = FALSE;
+ have_result = FALSE;
+
+ /* Run the actual drawing code. */
+ ret = CAIRO_TEST_SUCCESS;
+ surface = (target->create_surface) (base_path,
+ target->content,
+ width, height,
+ ctx->test->width * NUM_DEVICE_SCALE + 25 * NUM_DEVICE_OFFSETS,
+ ctx->test->height * NUM_DEVICE_SCALE + 25 * NUM_DEVICE_OFFSETS,
+ CAIRO_BOILERPLATE_MODE_TEST,
+ &closure);
+ if (surface == NULL) {
+ cairo_test_log (ctx, "Error: Failed to set %s target\n", target->name);
+ ret = CAIRO_TEST_UNTESTED;
+ goto UNWIND_STRINGS;
+ }
+
+#if HAVE_MEMFAULT
+ if (ctx->malloc_failure &&
+ MEMFAULT_COUNT_FAULTS () - last_fault_count > 0 &&
+ cairo_surface_status (surface) == CAIRO_STATUS_NO_MEMORY)
+ {
+ goto REPEAT;
+ }
+#endif
+
+ if (cairo_surface_status (surface)) {
+ MF (MEMFAULT_PRINT_FAULTS ());
+ cairo_test_log (ctx, "Error: Created an error surface: %s\n",
+ cairo_status_to_string (cairo_surface_status (surface)));
+ ret = CAIRO_TEST_FAILURE;
+ goto UNWIND_STRINGS;
+ }
+
+ /* Check that we created a surface of the expected type. */
+ if (cairo_surface_get_type (surface) != target->expected_type) {
+ MF (MEMFAULT_PRINT_FAULTS ());
+ cairo_test_log (ctx, "Error: Created surface is of type %d (expected %d)\n",
+ cairo_surface_get_type (surface), target->expected_type);
+ ret = CAIRO_TEST_UNTESTED;
+ goto UNWIND_SURFACE;
+ }
+
+ /* Check that we created a surface of the expected content,
+ * (ignore the artificial CAIRO_TEST_CONTENT_COLOR_ALPHA_FLATTENED value).
+ */
+ expected_content = cairo_boilerplate_content (target->content);
+
+ if (cairo_surface_get_content (surface) != expected_content) {
+ MF (MEMFAULT_PRINT_FAULTS ());
+ cairo_test_log (ctx, "Error: Created surface has content %d (expected %d)\n",
+ cairo_surface_get_content (surface), expected_content);
+ ret = CAIRO_TEST_FAILURE;
+ goto UNWIND_SURFACE;
+ }
+
+ if (cairo_surface_set_user_data (surface,
+ &cairo_boilerplate_output_basename_key,
+ base_path,
+ NULL))
+ {
+#if HAVE_MEMFAULT
+ cairo_surface_destroy (surface);
+
+ if (target->cleanup)
+ target->cleanup (closure);
+
+ goto REPEAT;
+#else
+ ret = CAIRO_TEST_FAILURE;
+ goto UNWIND_SURFACE;
+#endif
+ }
+
+ cairo_surface_set_device_offset (surface, dev_offset, dev_offset);
+ cairo_surface_set_device_scale (surface, dev_scale, dev_scale);
+
+ cr = cairo_create (surface);
+ if (cairo_set_user_data (cr, &_cairo_test_context_key, (void*) ctx, NULL)) {
+#if HAVE_MEMFAULT
+ cairo_destroy (cr);
+ cairo_surface_destroy (surface);
+
+ if (target->cleanup)
+ target->cleanup (closure);
+
+ goto REPEAT;
+#else
+ ret = CAIRO_TEST_FAILURE;
+ goto UNWIND_CAIRO;
+#endif
+ }
+
+ if (similar)
+ cairo_push_group_with_content (cr, expected_content);
+
+ /* Clear to transparent (or black) depending on whether the target
+ * surface supports alpha. */
+ cairo_save (cr);
+ cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
+ cairo_paint (cr);
+ cairo_restore (cr);
+
+ /* Set all components of font_options to avoid backend differences
+ * and reduce number of needed reference images. */
+ font_options = cairo_font_options_create ();
+ cairo_font_options_set_hint_style (font_options, CAIRO_HINT_STYLE_NONE);
+ cairo_font_options_set_hint_metrics (font_options, CAIRO_HINT_METRICS_ON);
+ cairo_font_options_set_antialias (font_options, CAIRO_ANTIALIAS_GRAY);
+ cairo_set_font_options (cr, font_options);
+ cairo_font_options_destroy (font_options);
+
+ cairo_save (cr);
+ alarm (ctx->timeout);
+ status = (ctx->test->draw) (cr, ctx->test->width, ctx->test->height);
+ alarm (0);
+ cairo_restore (cr);
+
+ if (similar) {
+ cairo_pop_group_to_source (cr);
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_paint (cr);
+ }
+
+#if HAVE_MEMFAULT
+ MEMFAULT_DISABLE_FAULTS ();
+
+ /* repeat test after malloc failure injection */
+ if (ctx->malloc_failure &&
+ MEMFAULT_COUNT_FAULTS () - last_fault_count > 0 &&
+ (status == CAIRO_TEST_NO_MEMORY ||
+ cairo_status (cr) == CAIRO_STATUS_NO_MEMORY ||
+ cairo_surface_status (surface) == CAIRO_STATUS_NO_MEMORY))
+ {
+ cairo_destroy (cr);
+ cairo_surface_destroy (surface);
+ if (target->cleanup)
+ target->cleanup (closure);
+ cairo_debug_reset_static_data ();
+#if HAVE_FCFINI
+ FcFini ();
+#endif
+ if (MEMFAULT_COUNT_LEAKS () > 0) {
+ MEMFAULT_PRINT_FAULTS ();
+ MEMFAULT_PRINT_LEAKS ();
+ }
+
+ goto REPEAT;
+ }
+#endif
+
+ /* Then, check all the different ways it could fail. */
+ if (status) {
+ cairo_test_log (ctx, "Error: Function under test failed\n");
+ ret = status;
+ goto UNWIND_CAIRO;
+ }
+
+#if HAVE_MEMFAULT
+ if (MEMFAULT_COUNT_FAULTS () - last_fault_count > 0 &&
+ MEMFAULT_HAS_FAULTS ())
+ {
+ VALGRIND_PRINTF ("Unreported memfaults...");
+ MEMFAULT_PRINT_FAULTS ();
+ }
+#endif
+
+ if (target->finish_surface != NULL) {
+#if HAVE_MEMFAULT
+ /* We need to re-enable faults as most recording-surface processing
+ * is done during cairo_surface_finish().
+ */
+ MEMFAULT_CLEAR_FAULTS ();
+ last_fault_count = MEMFAULT_COUNT_FAULTS ();
+ MEMFAULT_ENABLE_FAULTS ();
+#endif
+
+ /* also check for infinite loops whilst replaying */
+ alarm (ctx->timeout);
+ status = target->finish_surface (surface);
+ alarm (0);
+
+#if HAVE_MEMFAULT
+ MEMFAULT_DISABLE_FAULTS ();
+
+ if (ctx->malloc_failure &&
+ MEMFAULT_COUNT_FAULTS () - last_fault_count > 0 &&
+ status == CAIRO_STATUS_NO_MEMORY)
+ {
+ cairo_destroy (cr);
+ cairo_surface_destroy (surface);
+ if (target->cleanup)
+ target->cleanup (closure);
+ cairo_debug_reset_static_data ();
+#if HAVE_FCFINI
+ FcFini ();
+#endif
+ if (MEMFAULT_COUNT_LEAKS () > 0) {
+ MEMFAULT_PRINT_FAULTS ();
+ MEMFAULT_PRINT_LEAKS ();
+ }
+
+ goto REPEAT;
+ }
+#endif
+ if (status) {
+ cairo_test_log (ctx, "Error: Failed to finish surface: %s\n",
+ cairo_status_to_string (status));
+ ret = CAIRO_TEST_FAILURE;
+ goto UNWIND_CAIRO;
+ }
+ }
+
+ /* Skip image check for tests with no image (width,height == 0,0) */
+ if (ctx->test->width != 0 && ctx->test->height != 0) {
+ cairo_surface_t *ref_image;
+ cairo_surface_t *test_image;
+ cairo_surface_t *diff_image;
+ buffer_diff_result_t result;
+ cairo_status_t diff_status;
+
+ if (ref_png_path == NULL) {
+ cairo_test_log (ctx, "Error: Cannot find reference image for %s\n",
+ base_name);
+
+ /* we may be running this test to generate reference images */
+ _xunlink (ctx, out_png_path);
+ /* be more generous as we may need to use external renderers */
+ alarm (4 * ctx->timeout);
+ test_image = target->get_image_surface (surface, 0,
+ ctx->test->width,
+ ctx->test->height);
+ alarm (0);
+ diff_status = cairo_surface_write_to_png (test_image, out_png_path);
+ cairo_surface_destroy (test_image);
+ if (diff_status) {
+ if (cairo_surface_status (test_image) == CAIRO_STATUS_INVALID_STATUS)
+ ret = CAIRO_TEST_CRASHED;
+ else
+ ret = CAIRO_TEST_FAILURE;
+ cairo_test_log (ctx,
+ "Error: Failed to write output image: %s\n",
+ cairo_status_to_string (diff_status));
+ }
+ have_output = TRUE;
+
+ ret = CAIRO_TEST_XFAILURE;
+ goto UNWIND_CAIRO;
+ }
+
+ if (target->file_extension != NULL) { /* compare vector surfaces */
+ char *filenames[] = {
+ ref_png_path,
+ ref_path,
+ new_png_path,
+ new_path,
+ xfail_png_path,
+ xfail_path,
+ base_ref_png_path,
+ base_new_png_path,
+ base_xfail_png_path,
+ };
+
+ xasprintf (&test_filename, "%s.out%s",
+ base_path, target->file_extension);
+ xasprintf (&pass_filename, "%s.pass%s",
+ base_path, target->file_extension);
+ xasprintf (&fail_filename, "%s.fail%s",
+ base_path, target->file_extension);
+
+ if (cairo_test_file_is_older (pass_filename,
+ filenames,
+ ARRAY_LENGTH (filenames)))
+ {
+ _xunlink (ctx, pass_filename);
+ }
+ if (cairo_test_file_is_older (fail_filename,
+ filenames,
+ ARRAY_LENGTH (filenames)))
+ {
+ _xunlink (ctx, fail_filename);
+ }
+
+ if (cairo_test_files_equal (out_png_path, ref_path)) {
+ cairo_test_log (ctx, "Vector surface matches reference.\n");
+ have_output = FALSE;
+ ret = CAIRO_TEST_SUCCESS;
+ goto UNWIND_CAIRO;
+ }
+ if (cairo_test_files_equal (out_png_path, new_path)) {
+ cairo_test_log (ctx, "Vector surface matches current failure.\n");
+ have_output = FALSE;
+ ret = CAIRO_TEST_NEW;
+ goto UNWIND_CAIRO;
+ }
+ if (cairo_test_files_equal (out_png_path, xfail_path)) {
+ cairo_test_log (ctx, "Vector surface matches known failure.\n");
+ have_output = FALSE;
+ ret = CAIRO_TEST_XFAILURE;
+ goto UNWIND_CAIRO;
+ }
+
+ if (cairo_test_files_equal (test_filename, pass_filename)) {
+ /* identical output as last known PASS */
+ cairo_test_log (ctx, "Vector surface matches last pass.\n");
+ have_output = TRUE;
+ ret = CAIRO_TEST_SUCCESS;
+ goto UNWIND_CAIRO;
+ }
+ if (cairo_test_files_equal (test_filename, fail_filename)) {
+ /* identical output as last known FAIL, fail */
+ cairo_test_log (ctx, "Vector surface matches last fail.\n");
+ have_result = TRUE; /* presume these were kept around as well */
+ have_output = TRUE;
+ ret = CAIRO_TEST_FAILURE;
+ goto UNWIND_CAIRO;
+ }
+ }
+
+ /* be more generous as we may need to use external renderers */
+ alarm (4 * ctx->timeout);
+ test_image = target->get_image_surface (surface, 0,
+ ctx->test->width,
+ ctx->test->height);
+ alarm (0);
+ if (cairo_surface_status (test_image)) {
+ cairo_test_log (ctx, "Error: Failed to extract image: %s\n",
+ cairo_status_to_string (cairo_surface_status (test_image)));
+ if (cairo_surface_status (test_image) == CAIRO_STATUS_INVALID_STATUS)
+ ret = CAIRO_TEST_CRASHED;
+ else
+ ret = CAIRO_TEST_FAILURE;
+ cairo_surface_destroy (test_image);
+ goto UNWIND_CAIRO;
+ }
+
+ _xunlink (ctx, out_png_path);
+ diff_status = cairo_surface_write_to_png (test_image, out_png_path);
+ if (diff_status) {
+ cairo_test_log (ctx, "Error: Failed to write output image: %s\n",
+ cairo_status_to_string (diff_status));
+ cairo_surface_destroy (test_image);
+ ret = CAIRO_TEST_FAILURE;
+ goto UNWIND_CAIRO;
+ }
+ have_output = TRUE;
+
+ /* binary compare png files (no decompression) */
+ if (target->file_extension == NULL) {
+ char *filenames[] = {
+ ref_png_path,
+ new_png_path,
+ xfail_png_path,
+ base_ref_png_path,
+ base_new_png_path,
+ base_xfail_png_path,
+ };
+
+ xasprintf (&test_filename, "%s", out_png_path);
+ xasprintf (&pass_filename, "%s.pass.png", base_path);
+ xasprintf (&fail_filename, "%s.fail.png", base_path);
+
+ if (cairo_test_file_is_older (pass_filename,
+ filenames,
+ ARRAY_LENGTH (filenames)))
+ {
+ _xunlink (ctx, pass_filename);
+ }
+ if (cairo_test_file_is_older (fail_filename,
+ filenames,
+ ARRAY_LENGTH (filenames)))
+ {
+ _xunlink (ctx, fail_filename);
+ }
+
+ if (cairo_test_files_equal (test_filename, pass_filename)) {
+ cairo_test_log (ctx, "PNG file exactly matches last pass.\n");
+ have_result = TRUE;
+ cairo_surface_destroy (test_image);
+ ret = CAIRO_TEST_SUCCESS;
+ goto UNWIND_CAIRO;
+ }
+ if (cairo_test_files_equal (out_png_path, ref_png_path)) {
+ cairo_test_log (ctx, "PNG file exactly matches reference image.\n");
+ have_result = TRUE;
+ cairo_surface_destroy (test_image);
+ ret = CAIRO_TEST_SUCCESS;
+ goto UNWIND_CAIRO;
+ }
+ if (cairo_test_files_equal (out_png_path, new_png_path)) {
+ cairo_test_log (ctx, "PNG file exactly matches current failure image.\n");
+ have_result = TRUE;
+ cairo_surface_destroy (test_image);
+ ret = CAIRO_TEST_NEW;
+ goto UNWIND_CAIRO;
+ }
+ if (cairo_test_files_equal (out_png_path, xfail_png_path)) {
+ cairo_test_log (ctx, "PNG file exactly matches known failure image.\n");
+ have_result = TRUE;
+ cairo_surface_destroy (test_image);
+ ret = CAIRO_TEST_XFAILURE;
+ goto UNWIND_CAIRO;
+ }
+ if (cairo_test_files_equal (test_filename, fail_filename)) {
+ cairo_test_log (ctx, "PNG file exactly matches last fail.\n");
+ have_result = TRUE; /* presume these were kept around as well */
+ cairo_surface_destroy (test_image);
+ ret = CAIRO_TEST_FAILURE;
+ goto UNWIND_CAIRO;
+ }
+ } else {
+ if (cairo_test_files_equal (out_png_path, ref_png_path)) {
+ cairo_test_log (ctx, "PNG file exactly matches reference image.\n");
+ have_result = TRUE;
+ cairo_surface_destroy (test_image);
+ ret = CAIRO_TEST_SUCCESS;
+ goto UNWIND_CAIRO;
+ }
+ if (cairo_test_files_equal (out_png_path, new_png_path)) {
+ cairo_test_log (ctx, "PNG file exactly matches current failure image.\n");
+ have_result = TRUE;
+ cairo_surface_destroy (test_image);
+ ret = CAIRO_TEST_NEW;
+ goto UNWIND_CAIRO;
+ }
+ if (cairo_test_files_equal (out_png_path, xfail_png_path)) {
+ cairo_test_log (ctx, "PNG file exactly matches known failure image.\n");
+ have_result = TRUE;
+ cairo_surface_destroy (test_image);
+ ret = CAIRO_TEST_XFAILURE;
+ goto UNWIND_CAIRO;
+ }
+ }
+
+ if (cairo_test_files_equal (out_png_path, base_ref_png_path)) {
+ cairo_test_log (ctx, "PNG file exactly reference image.\n");
+ have_result = TRUE;
+ cairo_surface_destroy (test_image);
+ ret = CAIRO_TEST_SUCCESS;
+ goto UNWIND_CAIRO;
+ }
+ if (cairo_test_files_equal (out_png_path, base_new_png_path)) {
+ cairo_test_log (ctx, "PNG file exactly current failure image.\n");
+ have_result = TRUE;
+ cairo_surface_destroy (test_image);
+ ret = CAIRO_TEST_NEW;
+ goto UNWIND_CAIRO;
+ }
+ if (cairo_test_files_equal (out_png_path, base_xfail_png_path)) {
+ cairo_test_log (ctx, "PNG file exactly known failure image.\n");
+ have_result = TRUE;
+ cairo_surface_destroy (test_image);
+ ret = CAIRO_TEST_XFAILURE;
+ goto UNWIND_CAIRO;
+ }
+
+ /* first compare against the ideal reference */
+ ref_image = cairo_test_get_reference_image (ctx, base_ref_png_path,
+ target->content == CAIRO_TEST_CONTENT_COLOR_ALPHA_FLATTENED);
+ if (cairo_surface_status (ref_image)) {
+ cairo_test_log (ctx, "Error: Cannot open reference image for %s: %s\n",
+ base_ref_png_path,
+ cairo_status_to_string (cairo_surface_status (ref_image)));
+ cairo_surface_destroy (test_image);
+ ret = CAIRO_TEST_FAILURE;
+ goto UNWIND_CAIRO;
+ }
+
+ diff_image = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
+ ctx->test->width,
+ ctx->test->height);
+
+ cmp_png_path = base_ref_png_path;
+ diff_status = image_diff (ctx,
+ test_image, ref_image, diff_image,
+ &result);
+ _xunlink (ctx, diff_png_path);
+ if (diff_status ||
+ image_diff_is_failure (&result, target->error_tolerance))
+ {
+ /* that failed, so check against the specific backend */
+ ref_image = cairo_test_get_reference_image (ctx, ref_png_path,
+ target->content == CAIRO_TEST_CONTENT_COLOR_ALPHA_FLATTENED);
+ if (cairo_surface_status (ref_image)) {
+ cairo_test_log (ctx, "Error: Cannot open reference image for %s: %s\n",
+ ref_png_path,
+ cairo_status_to_string (cairo_surface_status (ref_image)));
+ cairo_surface_destroy (test_image);
+ ret = CAIRO_TEST_FAILURE;
+ goto UNWIND_CAIRO;
+ }
+
+ cmp_png_path = ref_png_path;
+ diff_status = image_diff (ctx,
+ test_image, ref_image,
+ diff_image,
+ &result);
+ if (diff_status)
+ {
+ cairo_test_log (ctx, "Error: Failed to compare images: %s\n",
+ cairo_status_to_string (diff_status));
+ ret = CAIRO_TEST_FAILURE;
+ }
+ else if (image_diff_is_failure (&result, target->error_tolerance))
+ {
+ ret = CAIRO_TEST_FAILURE;
+
+ diff_status = cairo_surface_write_to_png (diff_image,
+ diff_png_path);
+ if (diff_status) {
+ cairo_test_log (ctx, "Error: Failed to write differences image: %s\n",
+ cairo_status_to_string (diff_status));
+ } else {
+ have_result = TRUE;
+ }
+
+ cairo_test_copy_file (test_filename, fail_filename);
+ }
+ else
+ { /* success */
+ cairo_test_copy_file (test_filename, pass_filename);
+ }
+ }
+ else
+ { /* success */
+ cairo_test_copy_file (test_filename, pass_filename);
+ }
+
+ /* If failed, compare against the current image output,
+ * and attempt to detect systematic failures.
+ */
+ if (ret == CAIRO_TEST_FAILURE) {
+ char *image_out_path;
+
+ image_out_path =
+ cairo_test_reference_filename (ctx,
+ base_name,
+ ctx->test_name,
+ "image",
+ "image",
+ format,
+ CAIRO_TEST_OUT_SUFFIX,
+ CAIRO_TEST_PNG_EXTENSION);
+ if (image_out_path != NULL) {
+ if (cairo_test_files_equal (out_png_path,
+ image_out_path))
+ {
+ ret = CAIRO_TEST_XFAILURE;
+ }
+ else
+ {
+ ref_image =
+ cairo_image_surface_create_from_png (image_out_path);
+ if (cairo_surface_status (ref_image) == CAIRO_STATUS_SUCCESS)
+ {
+ diff_status = image_diff (ctx,
+ test_image, ref_image,
+ diff_image,
+ &result);
+ if (diff_status == CAIRO_STATUS_SUCCESS &&
+ !image_diff_is_failure (&result, target->error_tolerance))
+ {
+ ret = CAIRO_TEST_XFAILURE;
+ }
+
+ cairo_surface_destroy (ref_image);
+ }
+ }
+
+ free (image_out_path);
+ }
+ }
+
+ cairo_surface_destroy (test_image);
+ cairo_surface_destroy (diff_image);
+ }
+
+ if (cairo_status (cr) != CAIRO_STATUS_SUCCESS) {
+ cairo_test_log (ctx, "Error: Function under test left cairo status in an error state: %s\n",
+ cairo_status_to_string (cairo_status (cr)));
+ ret = CAIRO_TEST_ERROR;
+ goto UNWIND_CAIRO;
+ }
+
+UNWIND_CAIRO:
+ free (test_filename);
+ free (fail_filename);
+ free (pass_filename);
+
+ test_filename = fail_filename = pass_filename = NULL;
+
+#if HAVE_MEMFAULT
+ if (ret == CAIRO_TEST_FAILURE)
+ MEMFAULT_PRINT_FAULTS ();
+#endif
+ cairo_destroy (cr);
+UNWIND_SURFACE:
+ cairo_surface_destroy (surface);
+
+ if (target->cleanup)
+ target->cleanup (closure);
+
+#if HAVE_MEMFAULT
+ cairo_debug_reset_static_data ();
+
+#if HAVE_FCFINI
+ FcFini ();
+#endif
+
+ if (MEMFAULT_COUNT_LEAKS () > 0) {
+ if (ret != CAIRO_TEST_FAILURE)
+ MEMFAULT_PRINT_FAULTS ();
+ MEMFAULT_PRINT_LEAKS ();
+ }
+
+ if (ret == CAIRO_TEST_SUCCESS && --malloc_failure_iterations > 0)
+ goto REPEAT;
+#endif
+
+ if (have_output)
+ cairo_test_log (ctx, "OUTPUT: %s\n", out_png_path);
+
+ if (have_result) {
+ if (cmp_png_path == NULL) {
+ /* XXX presume we matched the normal ref last time */
+ cmp_png_path = ref_png_path;
+ }
+ cairo_test_log (ctx,
+ "REFERENCE: %s\nDIFFERENCE: %s\n",
+ cmp_png_path, diff_png_path);
+ }
+
+UNWIND_STRINGS:
+ free (out_png_path);
+ free (ref_png_path);
+ free (base_ref_png_path);
+ free (ref_path);
+ free (new_png_path);
+ free (base_new_png_path);
+ free (new_path);
+ free (xfail_png_path);
+ free (base_xfail_png_path);
+ free (xfail_path);
+ free (diff_png_path);
+ free (base_path);
+ free (base_name);
+
+ return ret;
+}
+
+#if defined(HAVE_SIGNAL_H) && defined(HAVE_SETJMP_H)
+#include <signal.h>
+#include <setjmp.h>
+/* Used to catch crashes in a test, so that we report it as such and
+ * continue testing, although one crasher may already have corrupted memory in
+ * an nonrecoverable fashion. */
+static jmp_buf jmpbuf;
+
+static void
+segfault_handler (int signal)
+{
+ longjmp (jmpbuf, signal);
+}
+#endif
+
+cairo_test_status_t
+_cairo_test_context_run_for_target (cairo_test_context_t *ctx,
+ const cairo_boilerplate_target_t *target,
+ cairo_bool_t similar,
+ int dev_offset, int dev_scale)
+{
+ cairo_test_status_t status;
+
+ if (target->get_image_surface == NULL)
+ return CAIRO_TEST_UNTESTED;
+
+ if (similar && ! cairo_test_target_has_similar (ctx, target))
+ return CAIRO_TEST_UNTESTED;
+
+ cairo_test_log (ctx,
+ "Testing %s with %s%s target (dev offset %d scale: %d)\n",
+ ctx->test_name,
+ similar ? " (similar) " : "",
+ target->name,
+ dev_offset, dev_scale);
+
+ printf ("%s.%s.%s [%dx%d]%s:\t", ctx->test_name, target->name,
+ cairo_boilerplate_content_name (target->content),
+ dev_offset, dev_scale,
+ similar ? " (similar)": "");
+ fflush (stdout);
+
+#if defined(HAVE_SIGNAL_H) && defined(HAVE_SETJMP_H)
+ if (! RUNNING_ON_VALGRIND) {
+ void (* volatile old_segfault_handler)(int);
+ void (* volatile old_segfpe_handler)(int);
+ void (* volatile old_sigpipe_handler)(int);
+ void (* volatile old_sigabrt_handler)(int);
+ void (* volatile old_sigalrm_handler)(int);
+
+ /* Set up a checkpoint to get back to in case of segfaults. */
+#ifdef SIGSEGV
+ old_segfault_handler = signal (SIGSEGV, segfault_handler);
+#endif
+#ifdef SIGFPE
+ old_segfpe_handler = signal (SIGFPE, segfault_handler);
+#endif
+#ifdef SIGPIPE
+ old_sigpipe_handler = signal (SIGPIPE, segfault_handler);
+#endif
+#ifdef SIGABRT
+ old_sigabrt_handler = signal (SIGABRT, segfault_handler);
+#endif
+#ifdef SIGALRM
+ old_sigalrm_handler = signal (SIGALRM, segfault_handler);
+#endif
+ if (0 == setjmp (jmpbuf))
+ status = cairo_test_for_target (ctx, target, dev_offset, dev_scale, similar);
+ else
+ status = CAIRO_TEST_CRASHED;
+#ifdef SIGSEGV
+ signal (SIGSEGV, old_segfault_handler);
+#endif
+#ifdef SIGFPE
+ signal (SIGFPE, old_segfpe_handler);
+#endif
+#ifdef SIGPIPE
+ signal (SIGPIPE, old_sigpipe_handler);
+#endif
+#ifdef SIGABRT
+ signal (SIGABRT, old_sigabrt_handler);
+#endif
+#ifdef SIGALRM
+ signal (SIGALRM, old_sigalrm_handler);
+#endif
+ } else {
+ status = cairo_test_for_target (ctx, target, dev_offset, dev_scale, similar);
+ }
+#else
+ status = cairo_test_for_target (ctx, target, dev_offset, dev_scale, similar);
+#endif
+
+ cairo_test_log (ctx,
+ "TEST: %s TARGET: %s FORMAT: %s OFFSET: %d SCALE: %d SIMILAR: %d RESULT: ",
+ ctx->test_name, target->name,
+ cairo_boilerplate_content_name (target->content),
+ dev_offset, dev_scale, similar);
+ switch (status) {
+ case CAIRO_TEST_SUCCESS:
+ printf ("PASS\n");
+ cairo_test_log (ctx, "PASS\n");
+ break;
+
+ case CAIRO_TEST_UNTESTED:
+ printf ("UNTESTED\n");
+ cairo_test_log (ctx, "UNTESTED\n");
+ break;
+
+ default:
+ case CAIRO_TEST_CRASHED:
+ if (print_fail_on_stdout) {
+ printf ("!!!CRASHED!!!\n");
+ } else {
+ /* eat the test name */
+ printf ("\r");
+ fflush (stdout);
+ }
+ cairo_test_log (ctx, "CRASHED\n");
+ fprintf (stderr, "%s.%s.%s [%dx%d]%s:\t%s!!!CRASHED!!!%s\n",
+ ctx->test_name, target->name,
+ cairo_boilerplate_content_name (target->content), dev_offset, dev_scale, similar ? " (similar)" : "",
+ fail_face, normal_face);
+ break;
+
+ case CAIRO_TEST_ERROR:
+ if (print_fail_on_stdout) {
+ printf ("!!!ERROR!!!\n");
+ } else {
+ /* eat the test name */
+ printf ("\r");
+ fflush (stdout);
+ }
+ cairo_test_log (ctx, "ERROR\n");
+ fprintf (stderr, "%s.%s.%s [%dx%d]%s:\t%s!!!ERROR!!!%s\n",
+ ctx->test_name, target->name,
+ cairo_boilerplate_content_name (target->content), dev_offset, dev_scale, similar ? " (similar)" : "",
+ fail_face, normal_face);
+ break;
+
+ case CAIRO_TEST_XFAILURE:
+ if (print_fail_on_stdout) {
+ printf ("XFAIL\n");
+ } else {
+ /* eat the test name */
+ printf ("\r");
+ fflush (stdout);
+ }
+ fprintf (stderr, "%s.%s.%s [%dx%d]%s:\t%sXFAIL%s\n",
+ ctx->test_name, target->name,
+ cairo_boilerplate_content_name (target->content), dev_offset, dev_scale, similar ? " (similar)" : "",
+ xfail_face, normal_face);
+ cairo_test_log (ctx, "XFAIL\n");
+ break;
+
+ case CAIRO_TEST_NEW:
+ if (print_fail_on_stdout) {
+ printf ("NEW\n");
+ } else {
+ /* eat the test name */
+ printf ("\r");
+ fflush (stdout);
+ }
+ fprintf (stderr, "%s.%s.%s [%dx%d]%s:\t%sNEW%s\n",
+ ctx->test_name, target->name,
+ cairo_boilerplate_content_name (target->content), dev_offset, dev_scale, similar ? " (similar)" : "",
+ fail_face, normal_face);
+ cairo_test_log (ctx, "NEW\n");
+ break;
+
+ case CAIRO_TEST_NO_MEMORY:
+ case CAIRO_TEST_FAILURE:
+ if (print_fail_on_stdout) {
+ printf ("FAIL\n");
+ } else {
+ /* eat the test name */
+ printf ("\r");
+ fflush (stdout);
+ }
+ fprintf (stderr, "%s.%s.%s [%dx%d]%s:\t%sFAIL%s\n",
+ ctx->test_name, target->name,
+ cairo_boilerplate_content_name (target->content), dev_offset, dev_scale, similar ? " (similar)" : "",
+ fail_face, normal_face);
+ cairo_test_log (ctx, "FAIL\n");
+ break;
+ }
+ fflush (stdout);
+
+ return status;
+}
+
+const cairo_test_context_t *
+cairo_test_get_context (cairo_t *cr)
+{
+ return cairo_get_user_data (cr, &_cairo_test_context_key);
+}
+
+cairo_surface_t *
+cairo_test_create_surface_from_png (const cairo_test_context_t *ctx,
+ const char *filename)
+{
+ cairo_surface_t *image;
+ cairo_status_t status;
+
+ image = cairo_image_surface_create_from_png (filename);
+ status = cairo_surface_status (image);
+ if (status == CAIRO_STATUS_FILE_NOT_FOUND) {
+ /* expect not found when running with srcdir != builddir
+ * such as when 'make distcheck' is run
+ */
+ if (ctx->srcdir) {
+ char *srcdir_filename;
+ xasprintf (&srcdir_filename, "%s/%s", ctx->srcdir, filename);
+ cairo_surface_destroy (image);
+ image = cairo_image_surface_create_from_png (srcdir_filename);
+ free (srcdir_filename);
+ }
+ }
+
+ return image;
+}
+
+cairo_pattern_t *
+cairo_test_create_pattern_from_png (const cairo_test_context_t *ctx,
+ const char *filename)
+{
+ cairo_surface_t *image;
+ cairo_pattern_t *pattern;
+
+ image = cairo_test_create_surface_from_png (ctx, filename);
+
+ pattern = cairo_pattern_create_for_surface (image);
+
+ cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT);
+
+ cairo_surface_destroy (image);
+
+ return pattern;
+}
+
+static cairo_surface_t *
+_draw_check (int width, int height)
+{
+ cairo_surface_t *surface;
+ cairo_t *cr;
+
+ surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, 12, 12);
+ cr = cairo_create (surface);
+ cairo_surface_destroy (surface);
+
+ cairo_set_source_rgb (cr, 0.75, 0.75, 0.75); /* light gray */
+ cairo_paint (cr);
+
+ cairo_set_source_rgb (cr, 0.25, 0.25, 0.25); /* dark gray */
+ cairo_rectangle (cr, width / 2, 0, width / 2, height / 2);
+ cairo_rectangle (cr, 0, height / 2, width / 2, height / 2);
+ cairo_fill (cr);
+
+ surface = cairo_surface_reference (cairo_get_target (cr));
+ cairo_destroy (cr);
+
+ return surface;
+}
+
+void
+cairo_test_paint_checkered (cairo_t *cr)
+{
+ cairo_surface_t *check;
+
+ check = _draw_check (12, 12);
+
+ cairo_save (cr);
+ cairo_set_source_surface (cr, check, 0, 0);
+ cairo_surface_destroy (check);
+
+ cairo_pattern_set_filter (cairo_get_source (cr), CAIRO_FILTER_NEAREST);
+ cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_REPEAT);
+ cairo_paint (cr);
+
+ cairo_restore (cr);
+}
+
+cairo_bool_t
+cairo_test_is_target_enabled (const cairo_test_context_t *ctx,
+ const char *target)
+{
+ size_t i;
+
+ for (i = 0; i < ctx->num_targets; i++) {
+ const cairo_boilerplate_target_t *t = ctx->targets_to_test[i];
+ if (strcmp (t->name, target) == 0) {
+ /* XXX ask the target whether is it possible to run?
+ * e.g. the xlib backend could check whether it is able to connect
+ * to the Display.
+ */
+ return t->get_image_surface != NULL;
+ }
+ }
+
+ return FALSE;
+}
+
+cairo_bool_t
+cairo_test_malloc_failure (const cairo_test_context_t *ctx,
+ cairo_status_t status)
+{
+ if (! ctx->malloc_failure)
+ return FALSE;
+
+ if (status != CAIRO_STATUS_NO_MEMORY)
+ return FALSE;
+
+#if HAVE_MEMFAULT
+ {
+ int n_faults;
+
+ /* prevent infinite loops... */
+ n_faults = MEMFAULT_COUNT_FAULTS ();
+ if (n_faults == ctx->last_fault_count)
+ return FALSE;
+
+ ((cairo_test_context_t *) ctx)->last_fault_count = n_faults;
+ }
+#endif
+
+ return TRUE;
+}
+
+cairo_test_status_t
+cairo_test_status_from_status (const cairo_test_context_t *ctx,
+ cairo_status_t status)
+{
+ if (status == CAIRO_STATUS_SUCCESS)
+ return CAIRO_TEST_SUCCESS;
+
+ if (cairo_test_malloc_failure (ctx, status))
+ return CAIRO_TEST_NO_MEMORY;
+
+ return CAIRO_TEST_FAILURE;
+}
diff --git a/test/cairo-test.h b/test/cairo-test.h
new file mode 100644
index 000000000..7e9605f61
--- /dev/null
+++ b/test/cairo-test.h
@@ -0,0 +1,322 @@
+/*
+ * Copyright © 2004 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+#ifndef _CAIRO_TEST_H_
+#define _CAIRO_TEST_H_
+
+#include "cairo-boilerplate.h"
+
+#include <stdarg.h>
+
+CAIRO_BEGIN_DECLS
+
+#if HAVE_STDINT_H
+# include <stdint.h>
+#elif HAVE_INTTYPES_H
+# include <inttypes.h>
+#elif HAVE_SYS_INT_TYPES_H
+# include <sys/int_types.h>
+#elif defined(_MSC_VER)
+typedef __int8 int8_t;
+typedef unsigned __int8 uint8_t;
+typedef __int16 int16_t;
+typedef unsigned __int16 uint16_t;
+typedef __int32 int32_t;
+typedef unsigned __int32 uint32_t;
+typedef __int64 int64_t;
+typedef unsigned __int64 uint64_t;
+# ifndef HAVE_UINT64_T
+# define HAVE_UINT64_T 1
+# endif
+#else
+#error Cannot find definitions for fixed-width integral types (uint8_t, uint32_t, \etc.)
+#endif
+
+#ifdef _MSC_VER
+#define _USE_MATH_DEFINES
+
+#include <float.h>
+#define isnan(x) _isnan(x)
+
+#endif
+
+#if HAVE_FENV_H
+# include <fenv.h>
+#endif
+/* The following are optional in C99, so define them if they aren't yet */
+#ifndef FE_DIVBYZERO
+#define FE_DIVBYZERO 0
+#endif
+#ifndef FE_INEXACT
+#define FE_INEXACT 0
+#endif
+#ifndef FE_INVALID
+#define FE_INVALID 0
+#endif
+#ifndef FE_OVERFLOW
+#define FE_OVERFLOW 0
+#endif
+#ifndef FE_UNDERFLOW
+#define FE_UNDERFLOW 0
+#endif
+
+#include <math.h>
+
+static inline double
+cairo_test_NaN (void)
+{
+#ifdef _MSC_VER
+ /* MSVC strtod("NaN", NULL) returns 0.0 */
+ union {
+ uint32_t i[2];
+ double d;
+ } nan = {{0xffffffff, 0x7fffffff}};
+ return nan.d;
+#else
+ return strtod("NaN", NULL);
+#endif
+}
+
+#ifndef MIN
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
+#endif
+
+#ifndef MAX
+#define MAX(a, b) ((a) > (b) ? (a) : (b))
+#endif
+
+#define CAIRO_TEST_OUTPUT_DIR "output"
+
+#define CAIRO_TEST_LOG_SUFFIX ".log"
+
+#define CAIRO_TEST_FONT_FAMILY "DejaVu"
+
+/* What is a fail and what isn't?
+ * When running the test suite we want to detect unexpected output. This
+ * can be caused by a change we have made to cairo itself, or a change
+ * in our environment. To capture this we classify the expected output into 3
+ * classes:
+ *
+ * REF -- Perfect output.
+ * Might be different for each backend, due to slight implementation
+ * differences.
+ *
+ * NEW -- A new failure. We have uncovered a bug within cairo and have
+ * recorded the current failure (along with the expected output
+ * if possible!) so we can detect any changes in our attempt to
+ * fix the bug.
+ *
+ * XFAIL -- An external failure. We believe the cairo output is perfect,
+ * but an external renderer is causing gross failure.
+ * (We also use this to capture current WONTFIX issues within cairo,
+ * such as overflow in internal coordinates, so as not to distract
+ * us when regression testing.)
+ *
+ * If no REF is given for a test, then it is assumed to be XFAIL.
+ */
+#define CAIRO_TEST_REF_SUFFIX ".ref"
+#define CAIRO_TEST_XFAIL_SUFFIX ".xfail"
+#define CAIRO_TEST_NEW_SUFFIX ".new"
+
+#define CAIRO_TEST_OUT_SUFFIX ".out"
+#define CAIRO_TEST_DIFF_SUFFIX ".diff"
+
+#define CAIRO_TEST_PNG_EXTENSION ".png"
+#define CAIRO_TEST_OUT_PNG CAIRO_TEST_OUT_SUFFIX CAIRO_TEST_PNG_EXTENSION
+#define CAIRO_TEST_REF_PNG CAIRO_TEST_REF_SUFFIX CAIRO_TEST_PNG_EXTENSION
+#define CAIRO_TEST_DIFF_PNG CAIRO_TEST_DIFF_SUFFIX CAIRO_TEST_PNG_EXTENSION
+
+typedef enum cairo_test_status {
+ CAIRO_TEST_SUCCESS = 0,
+ CAIRO_TEST_NO_MEMORY,
+ CAIRO_TEST_FAILURE,
+ CAIRO_TEST_NEW,
+ CAIRO_TEST_XFAILURE,
+ CAIRO_TEST_ERROR,
+ CAIRO_TEST_CRASHED,
+ CAIRO_TEST_UNTESTED = 77 /* match automake's skipped exit status */
+} cairo_test_status_t;
+
+typedef struct _cairo_test_context cairo_test_context_t;
+typedef struct _cairo_test cairo_test_t;
+
+typedef cairo_test_status_t
+(cairo_test_preamble_function_t) (cairo_test_context_t *ctx);
+
+typedef cairo_test_status_t
+(cairo_test_draw_function_t) (cairo_t *cr, int width, int height);
+
+struct _cairo_test {
+ const char *name;
+ const char *description;
+ const char *keywords;
+ const char *requirements;
+ double width;
+ double height;
+ cairo_test_preamble_function_t *preamble;
+ cairo_test_draw_function_t *draw;
+};
+
+/* The standard test interface which works by examining result image.
+ *
+ * CAIRO_TEST() constructs a test which will be called once before (the
+ * preamble callback), and then once for each testable backend (the draw
+ * callback). The following checks will be performed for each backend:
+ *
+ * 1) If preamble() returns CAIRO_TEST_UNTESTED, the test is skipped.
+ *
+ * 2) If preamble() does not return CAIRO_TEST_SUCCESS, the test fails.
+ *
+ * 3) If draw() does not return CAIRO_TEST_SUCCESS then this backend
+ * fails.
+ *
+ * 4) Otherwise, if cairo_status(cr) indicates an error then this
+ * backend fails.
+ *
+ * 5) Otherwise, if the image size is 0, then this backend passes.
+ *
+ * 6) Otherwise, if every channel of every pixel exactly matches the
+ * reference image then this backend passes. If not, this backend
+ * fails.
+ *
+ * The overall test result is PASS if and only if there is at least
+ * one backend that is tested and if all tested backend pass according
+ * to the four criteria above.
+ */
+#define CAIRO_TEST(name, description, keywords, requirements, width, height, preamble, draw) \
+void _register_##name (void); \
+void _register_##name (void) { \
+ static cairo_test_t test = { \
+ #name, description, \
+ keywords, requirements, \
+ width, height, \
+ preamble, draw \
+ }; \
+ cairo_test_register (&test); \
+}
+
+void
+cairo_test_register (cairo_test_t *test);
+
+/* The full context for the test.
+ * For ordinary tests (using the CAIRO_TEST()->draw interface) the context
+ * is passed to the draw routine via user_data on the cairo_t.
+ * The reason why the context is not passed as an explicit parameter is that
+ * it is rarely required by the test itself and by removing the parameter
+ * we can keep the draw routines simple and serve as example code.
+ *
+ * In contrast, for the preamble phase the context is passed as the only
+ * parameter.
+ */
+struct _cairo_test_context {
+ const cairo_test_t *test;
+ const char *test_name;
+
+ FILE *log_file;
+ const char *output;
+ const char *srcdir; /* directory containing sources and input data */
+ const char *refdir; /* directory containing reference images */
+
+ char *ref_name; /* cache of the current reference image */
+ cairo_surface_t *ref_image;
+ cairo_surface_t *ref_image_flattened;
+
+ size_t num_targets;
+ cairo_bool_t limited_targets;
+ const cairo_boilerplate_target_t **targets_to_test;
+ cairo_bool_t own_targets;
+
+ int malloc_failure;
+ int last_fault_count;
+
+ int timeout;
+};
+
+/* Retrieve the test context from the cairo_t, used for logging, paths etc */
+const cairo_test_context_t *
+cairo_test_get_context (cairo_t *cr);
+
+
+/* Print a message to the log file, ala printf. */
+void
+cairo_test_log (const cairo_test_context_t *ctx,
+ const char *fmt, ...) CAIRO_BOILERPLATE_PRINTF_FORMAT(2, 3);
+void
+cairo_test_logv (const cairo_test_context_t *ctx,
+ const char *fmt, va_list ap) CAIRO_BOILERPLATE_PRINTF_FORMAT(2, 0);
+
+/* Helper functions that take care of finding source images even when
+ * building in a non-srcdir manner, (i.e. the tests will be run in a
+ * directory that is different from the one where the source image
+ * exists). */
+cairo_surface_t *
+cairo_test_create_surface_from_png (const cairo_test_context_t *ctx,
+ const char *filename);
+
+cairo_pattern_t *
+cairo_test_create_pattern_from_png (const cairo_test_context_t *ctx,
+ const char *filename);
+
+void
+cairo_test_paint_checkered (cairo_t *cr);
+
+#define CAIRO_TEST_DOUBLE_EQUALS(a,b) (fabs((a)-(b)) < 0.00001)
+
+cairo_bool_t
+cairo_test_is_target_enabled (const cairo_test_context_t *ctx,
+ const char *target);
+
+char *
+cairo_test_get_name (const cairo_test_t *test);
+
+cairo_bool_t
+cairo_test_malloc_failure (const cairo_test_context_t *ctx,
+ cairo_status_t status);
+
+cairo_test_status_t
+cairo_test_status_from_status (const cairo_test_context_t *ctx,
+ cairo_status_t status);
+
+char *
+cairo_test_reference_filename (const cairo_test_context_t *ctx,
+ const char *base_name,
+ const char *test_name,
+ const char *target_name,
+ const char *base_target_name,
+ const char *format,
+ const char *suffix,
+ const char *extension);
+
+cairo_surface_t *
+cairo_test_get_reference_image (cairo_test_context_t *ctx,
+ const char *filename,
+ cairo_bool_t flatten);
+
+cairo_bool_t
+cairo_test_mkdir (const char *path);
+
+CAIRO_END_DECLS
+
+#endif
diff --git a/test/caps-joins-alpha.c b/test/caps-joins-alpha.c
new file mode 100644
index 000000000..bbff44e57
--- /dev/null
+++ b/test/caps-joins-alpha.c
@@ -0,0 +1,89 @@
+/*
+ * Copyright © 2005 Red Hat, Inc.
+ * Copyright © 2006 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+#include "cairo-test.h"
+
+#define LINE_WIDTH 10.
+#define SIZE (5 * LINE_WIDTH)
+#define PAD (2 * LINE_WIDTH)
+
+static void
+make_path (cairo_t *cr)
+{
+ cairo_move_to (cr, 0., 0.);
+ cairo_rel_line_to (cr, 0., SIZE);
+ cairo_rel_line_to (cr, SIZE, 0.);
+ cairo_close_path (cr);
+
+ cairo_move_to (cr, 2 * LINE_WIDTH, 0.);
+ cairo_rel_line_to (cr, 3 * LINE_WIDTH, 0.);
+ cairo_rel_line_to (cr, 0., 3 * LINE_WIDTH);
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ /* First draw a checkered background */
+ cairo_test_paint_checkered (cr);
+
+ /* Then draw the original caps-joins test but with a bit of alphs thrown in. */
+ cairo_set_line_width (cr, LINE_WIDTH);
+
+ cairo_set_source_rgba (cr, 1.0, 0.0, 0.0, 0.5); /* 50% red */
+ cairo_translate (cr, PAD, PAD);
+
+ make_path (cr);
+ cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT);
+ cairo_set_line_join (cr, CAIRO_LINE_JOIN_BEVEL);
+ cairo_stroke (cr);
+
+ cairo_set_source_rgba (cr, 0.0, 1.0, 0.0, 0.5); /* 50% green */
+ cairo_translate (cr, SIZE + PAD, 0.);
+
+ make_path (cr);
+ cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
+ cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND);
+ cairo_stroke (cr);
+
+ cairo_set_source_rgba (cr, 0.0, 0.0, 1.0, 0.5); /* 50% blue */
+
+ cairo_translate (cr, SIZE + PAD, 0.);
+
+ make_path (cr);
+ cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE);
+ cairo_set_line_join (cr, CAIRO_LINE_JOIN_MITER);
+ cairo_stroke (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (caps_joins_alpha,
+ "Test caps and joins with some source alpha",
+ "stroke", /* keywords */
+ NULL, /* requirements */
+ 3 * (PAD + SIZE) + PAD,
+ PAD + SIZE + PAD,
+ NULL, draw)
diff --git a/test/caps-joins-curve.c b/test/caps-joins-curve.c
new file mode 100644
index 000000000..cf197547c
--- /dev/null
+++ b/test/caps-joins-curve.c
@@ -0,0 +1,111 @@
+/*
+ * Copyright © 2008 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Chris Wilson not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Chris Wilson makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+#define LINE_WIDTH 10.
+#define SIZE (5 * LINE_WIDTH)
+#define PAD (3 * LINE_WIDTH)
+
+static void
+make_path (cairo_t *cr)
+{
+ cairo_move_to (cr, 0, 0);
+ cairo_rel_curve_to (cr,
+ -SIZE/4, SIZE/3,
+ -SIZE/4, SIZE/3,
+ 0, SIZE);
+ cairo_rel_curve_to (cr,
+ SIZE/3, -SIZE/4,
+ SIZE/3, -SIZE/4,
+ SIZE, 0);
+ cairo_close_path (cr);
+
+ cairo_move_to (cr, 5 * LINE_WIDTH, 3 * LINE_WIDTH);
+ cairo_rel_curve_to (cr,
+ 0, -3 * LINE_WIDTH,
+ 0, -3 * LINE_WIDTH,
+ -3 * LINE_WIDTH, -3 * LINE_WIDTH);
+}
+
+static void
+draw_caps_joins (cairo_t *cr)
+{
+ cairo_save (cr);
+
+ cairo_translate (cr, PAD, PAD);
+
+ make_path (cr);
+ cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT);
+ cairo_set_line_join (cr, CAIRO_LINE_JOIN_BEVEL);
+ cairo_stroke (cr);
+
+ cairo_translate (cr, SIZE + PAD, 0.);
+
+ make_path (cr);
+ cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
+ cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND);
+ cairo_stroke (cr);
+
+ cairo_translate (cr, SIZE + PAD, 0.);
+
+ make_path (cr);
+ cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE);
+ cairo_set_line_join (cr, CAIRO_LINE_JOIN_MITER);
+ cairo_stroke (cr);
+
+ cairo_restore (cr);
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ /* We draw in the default black, so paint white first. */
+ cairo_save (cr);
+ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */
+ cairo_paint (cr);
+ cairo_restore (cr);
+
+ cairo_set_line_width (cr, LINE_WIDTH);
+
+ draw_caps_joins (cr);
+
+ /* and reflect to generate the opposite vertex ordering */
+ cairo_translate (cr, 0, height);
+ cairo_scale (cr, 1, -1);
+
+ draw_caps_joins (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (caps_joins_curve,
+ "Test caps and joins on curves",
+ "stroke, cap, join", /* keywords */
+ NULL, /* requirements */
+ 3 * (PAD + SIZE) + PAD,
+ 2 * (PAD + SIZE) + PAD,
+ NULL, draw)
+
diff --git a/test/caps-joins.c b/test/caps-joins.c
new file mode 100644
index 000000000..de22d0367
--- /dev/null
+++ b/test/caps-joins.c
@@ -0,0 +1,150 @@
+/*
+ * Copyright © 2005 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+#include "cairo-test.h"
+
+#define LINE_WIDTH 10.
+#define SIZE (5 * LINE_WIDTH)
+#define PAD (2 * LINE_WIDTH)
+
+static void
+make_path (cairo_t *cr)
+{
+ cairo_move_to (cr, 0., 0.);
+ cairo_rel_line_to (cr, 0., SIZE);
+ cairo_rel_line_to (cr, SIZE, 0.);
+ cairo_close_path (cr);
+
+ cairo_move_to (cr, 5 * LINE_WIDTH, 3 * LINE_WIDTH);
+ cairo_rel_line_to (cr, 0., -3 * LINE_WIDTH);
+ cairo_rel_line_to (cr, -3 * LINE_WIDTH, 0.);
+}
+
+static void
+draw_caps_joins (cairo_t *cr)
+{
+ cairo_save (cr);
+
+ cairo_translate (cr, PAD, PAD);
+
+ make_path (cr);
+ cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT);
+ cairo_set_line_join (cr, CAIRO_LINE_JOIN_BEVEL);
+ cairo_stroke (cr);
+
+ cairo_translate (cr, SIZE + PAD, 0.);
+
+ make_path (cr);
+ cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
+ cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND);
+ cairo_stroke (cr);
+
+ cairo_translate (cr, SIZE + PAD, 0.);
+
+ make_path (cr);
+ cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE);
+ cairo_set_line_join (cr, CAIRO_LINE_JOIN_MITER);
+ cairo_stroke (cr);
+
+ cairo_restore (cr);
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, float line_width)
+{
+ /* We draw in the default black, so paint white first. */
+ cairo_save (cr);
+ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */
+ cairo_paint (cr);
+ cairo_restore (cr);
+
+ cairo_set_line_width (cr, line_width);
+
+ draw_caps_joins (cr);
+
+ /* and reflect to generate the opposite vertex ordering */
+ cairo_translate (cr, 0, 2 * (PAD + SIZE) + PAD);
+ cairo_scale (cr, 1, -1);
+
+ draw_caps_joins (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+draw_10 (cairo_t *cr, int width, int height)
+{
+ return draw (cr, LINE_WIDTH);
+}
+
+static cairo_test_status_t
+draw_2 (cairo_t *cr, int width, int height)
+{
+ return draw (cr, 2.0);
+}
+
+static cairo_test_status_t
+draw_1 (cairo_t *cr, int width, int height)
+{
+ return draw (cr, 1.0);
+}
+
+static cairo_test_status_t
+draw_05 (cairo_t *cr, int width, int height)
+{
+ return draw (cr, 0.5);
+}
+
+CAIRO_TEST (caps_joins,
+ "Test caps and joins",
+ "stroke", /* keywords */
+ NULL, /* requirements */
+ 3 * (PAD + SIZE) + PAD,
+ 2 * (PAD + SIZE) + PAD,
+ NULL, draw_10)
+
+CAIRO_TEST (caps_joins_2,
+ "Test caps and joins with default line width",
+ "stroke", /* keywords */
+ NULL, /* requirements */
+ 3 * (PAD + SIZE) + PAD,
+ 2 * (PAD + SIZE) + PAD,
+ NULL, draw_2)
+
+CAIRO_TEST (caps_joins_1,
+ "Test caps and joins with hairlines",
+ "stroke", /* keywords */
+ NULL, /* requirements */
+ 3 * (PAD + SIZE) + PAD,
+ 2 * (PAD + SIZE) + PAD,
+ NULL, draw_1)
+
+CAIRO_TEST (caps_joins_05,
+ "Test caps and joins with fine lines",
+ "stroke", /* keywords */
+ NULL, /* requirements */
+ 3 * (PAD + SIZE) + PAD,
+ 2 * (PAD + SIZE) + PAD,
+ NULL, draw_05)
diff --git a/test/caps-sub-paths.c b/test/caps-sub-paths.c
new file mode 100644
index 000000000..2310eb752
--- /dev/null
+++ b/test/caps-sub-paths.c
@@ -0,0 +1,65 @@
+/*
+ * Copyright © 2005 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+#include "cairo-test.h"
+
+/* Test case for bug #4205:
+
+ https://bugs.freedesktop.org/show_bug.cgi?id=4205
+*/
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ /* We draw in the default black, so paint white first. */
+ cairo_save (cr);
+ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */
+ cairo_paint (cr);
+ cairo_restore (cr);
+
+ cairo_set_line_width (cr, 4);
+ cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
+
+ cairo_move_to (cr, 4, 4);
+ cairo_line_to (cr, 4, 16);
+
+ cairo_move_to (cr, 10, 4);
+ cairo_line_to (cr, 10, 16);
+
+ cairo_move_to (cr, 16, 4);
+ cairo_line_to (cr, 16, 16);
+
+ cairo_stroke (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (caps_sub_paths,
+ "Test that sub-paths receive caps.",
+ "stroke", /* keywords */
+ NULL, /* requirements */
+ 20, 20,
+ NULL, draw)
+
diff --git a/test/caps-tails-curve.c b/test/caps-tails-curve.c
new file mode 100644
index 000000000..fa6aded3d
--- /dev/null
+++ b/test/caps-tails-curve.c
@@ -0,0 +1,127 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+#define LINE_WIDTH 30.
+#define SIZE (2 * LINE_WIDTH)
+#define PAD (2 * LINE_WIDTH)
+
+static void
+make_path (cairo_t *cr, double theta)
+{
+ double line_width = cairo_get_line_width (cr) / 4;
+
+ cairo_move_to (cr, 0, 0);
+ cairo_rel_curve_to (cr,
+ SIZE/3, -SIZE/4,
+ SIZE/3, -SIZE/4,
+ SIZE, 0);
+
+ cairo_rel_line_to (cr,
+ cos (theta) * line_width,
+ sin (theta) * line_width);
+}
+
+static void
+draw_joins (cairo_t *cr, double theta)
+{
+ make_path (cr, theta);
+ cairo_set_line_join (cr, CAIRO_LINE_JOIN_BEVEL);
+ cairo_stroke (cr);
+
+ cairo_translate (cr, SIZE + PAD, 0.);
+
+ make_path (cr, theta);
+ cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND);
+ cairo_stroke (cr);
+
+ cairo_translate (cr, SIZE + PAD, 0.);
+
+ make_path (cr, theta);
+ cairo_set_line_join (cr, CAIRO_LINE_JOIN_MITER);
+ cairo_stroke (cr);
+
+ cairo_translate (cr, SIZE + PAD, 0.);
+}
+
+static void
+draw_caps_joins (cairo_t *cr, double theta)
+{
+ cairo_translate (cr, PAD, 0);
+ cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT);
+ draw_joins (cr, theta);
+
+ cairo_translate (cr, PAD, 0);
+ cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
+ draw_joins (cr, theta);
+
+ cairo_translate (cr, PAD, 0);
+ cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE);
+ draw_joins (cr, theta);
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ const double theta[] = {
+ -M_PI/2, -M_PI/4, 0, M_PI/8, M_PI/3, M_PI
+ };
+ unsigned int t;
+
+ /* We draw in the default black, so paint white first. */
+ cairo_save (cr);
+ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */
+ cairo_paint (cr);
+ cairo_restore (cr);
+
+ cairo_set_line_width (cr, LINE_WIDTH);
+
+ for (t = 0; t < ARRAY_LENGTH(theta); t++) {
+ cairo_save (cr);
+ cairo_translate (cr, 0, t * (SIZE + PAD) + PAD);
+ draw_caps_joins (cr, theta[t]);
+ cairo_restore (cr);
+
+ cairo_save (cr);
+ /* and reflect to generate the opposite vertex ordering */
+ cairo_translate (cr, 0, height - t * (SIZE + PAD) - PAD);
+ cairo_scale (cr, 1, -1);
+ draw_caps_joins (cr, theta[t]);
+ cairo_restore (cr);
+ }
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (caps_tails_curve,
+ "Test caps and joins on short tail segments",
+ "stroke, cap, join", /* keywords */
+ NULL, /* requirements */
+ 9 * (PAD + SIZE) + 4*PAD,
+ 12 * (PAD + SIZE) + PAD,
+ NULL, draw)
+
diff --git a/test/caps.c b/test/caps.c
new file mode 100644
index 000000000..87f008a7c
--- /dev/null
+++ b/test/caps.c
@@ -0,0 +1,138 @@
+/*
+ * Copyright © 2008 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Chris Wilson not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Chris Wilson makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+#define LINE_WIDTH 10.
+#define SIZE (5 * LINE_WIDTH)
+#define PAD (2 * LINE_WIDTH)
+
+static void
+make_path (cairo_t *cr)
+{
+ int i;
+
+ cairo_save (cr);
+ for (i = 0; i <= 3; i++) {
+ cairo_new_sub_path (cr);
+ cairo_move_to (cr, -SIZE / 2, 0.);
+ cairo_line_to (cr, SIZE / 2, 0.);
+ cairo_rotate (cr, M_PI / 4.);
+ }
+ cairo_restore (cr);
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr)
+{
+ cairo_save (cr);
+ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */
+ cairo_paint (cr);
+ cairo_restore (cr);
+
+ cairo_translate (cr, PAD + SIZE / 2., PAD + SIZE / 2.);
+
+ cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT);
+ cairo_set_line_join (cr, CAIRO_LINE_JOIN_BEVEL);
+ make_path (cr);
+ cairo_stroke (cr);
+
+ cairo_translate (cr, 0, SIZE + PAD);
+
+ cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
+ cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND);
+ make_path (cr);
+ cairo_stroke (cr);
+
+ cairo_translate (cr, 0, SIZE + PAD);
+
+ cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE);
+ cairo_set_line_join (cr, CAIRO_LINE_JOIN_MITER);
+ make_path (cr);
+ cairo_stroke (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+draw_10 (cairo_t *cr, int width, int height)
+{
+ cairo_set_line_width (cr, LINE_WIDTH);
+ return draw (cr);
+}
+
+static cairo_test_status_t
+draw_2 (cairo_t *cr, int width, int height)
+{
+ cairo_set_line_width (cr, 2);
+ return draw (cr);
+}
+
+static cairo_test_status_t
+draw_1 (cairo_t *cr, int width, int height)
+{
+ cairo_set_line_width (cr, 1);
+ return draw (cr);
+}
+
+static cairo_test_status_t
+draw_05 (cairo_t *cr, int width, int height)
+{
+ cairo_set_line_width (cr, 0.5);
+ return draw (cr);
+}
+
+CAIRO_TEST (caps,
+ "Test caps",
+ "stroke, caps", /* keywords */
+ NULL, /* requirements */
+ PAD + SIZE + PAD,
+ 3 * (PAD + SIZE) + PAD,
+ NULL, draw_10)
+
+CAIRO_TEST (caps_2,
+ "Test normal caps",
+ "stroke, caps", /* keywords */
+ NULL, /* requirements */
+ PAD + SIZE + PAD,
+ 3 * (PAD + SIZE) + PAD,
+ NULL, draw_2)
+
+CAIRO_TEST (caps_1,
+ "Test hairline caps",
+ "stroke, caps", /* keywords */
+ NULL, /* requirements */
+ PAD + SIZE + PAD,
+ 3 * (PAD + SIZE) + PAD,
+ NULL, draw_1)
+
+CAIRO_TEST (caps_05,
+ "Test fine caps",
+ "stroke, caps", /* keywords */
+ NULL, /* requirements */
+ PAD + SIZE + PAD,
+ 3 * (PAD + SIZE) + PAD,
+ NULL, draw_05)
+
diff --git a/test/check-refs.sh b/test/check-refs.sh
new file mode 100755
index 000000000..81ef81b35
--- /dev/null
+++ b/test/check-refs.sh
@@ -0,0 +1,63 @@
+#!/bin/bash
+
+cd $(dirname $0)/reference || exit
+
+pdiff=$1
+[ -n "$pdiff" ] || pdiff=../pdiff/perceptualdiff
+if [ ! -e "${pdiff}" ]; then
+ echo "Error: requires pdiff executable"
+ exit 128
+fi
+
+for file in *.ref.png; do
+ test=$(echo $file | cut -d'.' -f1)
+ target=$(echo $file | cut -d'.' -f2)
+ format=$(echo $file | cut -d'.' -f3)
+ notes=""
+ ref=""
+ result=""
+
+ if [ $target = 'base' ]; then
+ # Ignore the base images for this script's purposes
+ continue
+ elif [ $target = 'ref' ]; then
+ # This is actually the baseline reference image
+ continue
+ elif [ $format = 'ref' ]; then
+ # This is either a format-specific reference, or a target-specific/format-generic image
+ # In either case, compare it against the generic reference image
+ ref="$test.ref.png"
+ else
+ # Prefer the target-specific/format-generic reference image, if available
+ ref="$test.$target.ref.png"
+ if [ ! -e $ref ]; then
+ ref="$test.$format.ref.png"
+ fi
+ fi
+
+ # Special cases
+ if [ $test = "create-from-png" ]; then
+ # The create-from-png test utilizes multiple reference images directly
+ continue
+ elif [ $test = "fallback-resolution" ]; then
+ # The fallback-resolution test generates a set of reference images;
+ # These won't be redundant with one another, but just ignore them all.
+ continue
+ fi
+
+ if [ -e $ref ]; then
+ if cmp --silent "$ref" "$file" ; then
+ printf "redundant: %s and %s are byte-by-byte identical files\n" $file $ref
+ else
+ # Run perceptualdiff with minimum threshold
+ pdiff_output=$($pdiff $ref $file -threshold 1)
+ result=${pdiff_output%:*}
+ notes=$(echo "${pdiff_output#*: }" | tail -n 1)
+ if [ "$result" = "PASS" ] && [ "$notes" = "Images are binary identical" ]; then
+ printf "redundant: %s and %s are pixel equivalent images\n" $file $ref
+ notes=""
+ fi
+ fi
+ fi
+
+done
diff --git a/test/checkerboard.c b/test/checkerboard.c
new file mode 100644
index 000000000..aeb2efe14
--- /dev/null
+++ b/test/checkerboard.c
@@ -0,0 +1,48 @@
+/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */
+/*
+ * Copyright 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+/* Test the basic background used extensively in the test suite. */
+
+#include "cairo-test.h"
+
+#define HEIGHT 32
+#define WIDTH 32
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_test_paint_checkered (cr);
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (checkerboard,
+ "Tests the checkerboard background",
+ "paint", /* keywords */
+ NULL, /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw)
+
diff --git a/test/clear-source.c b/test/clear-source.c
new file mode 100644
index 000000000..5410932fc
--- /dev/null
+++ b/test/clear-source.c
@@ -0,0 +1,169 @@
+/*
+ * Copyright 2009 Benjamin Otte
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Benjamin Otte <otte@gnome.org>
+ */
+
+#include "cairo-test.h"
+
+typedef enum {
+ CLEAR,
+ CLEARED,
+ PAINTED
+} surface_type_t;
+
+#define SIZE 10
+#define SPACE 5
+
+static cairo_surface_t *
+create_surface (cairo_t *target, cairo_content_t content, surface_type_t type)
+{
+ cairo_surface_t *surface;
+ cairo_t *cr;
+
+ surface = cairo_surface_create_similar (cairo_get_target (target),
+ content,
+ SIZE, SIZE);
+
+ if (type == CLEAR)
+ return surface;
+
+ cr = cairo_create (surface);
+ cairo_surface_destroy (surface);
+
+ cairo_set_source_rgb (cr, 0.75, 0, 0);
+ cairo_paint (cr);
+
+ if (type == PAINTED)
+ goto DONE;
+
+ cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
+ cairo_paint (cr);
+
+DONE:
+ surface = cairo_surface_reference (cairo_get_target (cr));
+ cairo_destroy (cr);
+
+ return surface;
+}
+
+static void
+paint (cairo_t *cr, cairo_surface_t *surface)
+{
+ cairo_set_source_surface (cr, surface, 0, 0);
+ cairo_paint (cr);
+}
+
+static void
+fill (cairo_t *cr, cairo_surface_t *surface)
+{
+ cairo_set_source_surface (cr, surface, 0, 0);
+ cairo_rectangle (cr, -SPACE, -SPACE, SIZE + 2 * SPACE, SIZE + 2 * SPACE);
+ cairo_fill (cr);
+}
+
+static void
+stroke (cairo_t *cr, cairo_surface_t *surface)
+{
+ cairo_set_source_surface (cr, surface, 0, 0);
+ cairo_set_line_width (cr, 2.0);
+ cairo_rectangle (cr, 1, 1, SIZE - 2, SIZE - 2);
+ cairo_stroke (cr);
+}
+
+static void
+mask (cairo_t *cr, cairo_surface_t *surface)
+{
+ cairo_set_source_rgb (cr, 0, 0, 0.75);
+ cairo_mask_surface (cr, surface, 0, 0);
+}
+
+static void
+mask_self (cairo_t *cr, cairo_surface_t *surface)
+{
+ cairo_set_source_surface (cr, surface, 0, 0);
+ cairo_mask_surface (cr, surface, 0, 0);
+}
+
+static void
+glyphs (cairo_t *cr, cairo_surface_t *surface)
+{
+ cairo_set_source_surface (cr, surface, 0, 0);
+ cairo_select_font_face (cr,
+ "@cairo:",
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_NORMAL);
+ cairo_set_font_size (cr, 16);
+ cairo_translate (cr, 0, SIZE);
+ cairo_show_text (cr, "C");
+}
+
+typedef void (* operation_t) (cairo_t *cr, cairo_surface_t *surface);
+static operation_t operations[] = {
+ paint,
+ fill,
+ stroke,
+ mask,
+ mask_self,
+ glyphs
+};
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_content_t contents[] = { CAIRO_CONTENT_COLOR_ALPHA, CAIRO_CONTENT_COLOR, CAIRO_CONTENT_ALPHA };
+ unsigned int content, type, ops;
+
+ cairo_set_source_rgb (cr, 0.5, 0.5, 0.5);
+ cairo_paint (cr);
+ cairo_translate (cr, SPACE, SPACE);
+
+ for (type = 0; type <= PAINTED; type++) {
+ for (content = 0; content < ARRAY_LENGTH (contents); content++) {
+ cairo_surface_t *surface;
+
+ surface = create_surface (cr, contents[content], type);
+
+ cairo_save (cr);
+ for (ops = 0; ops < ARRAY_LENGTH (operations); ops++) {
+ cairo_save (cr);
+ operations[ops] (cr, surface);
+ cairo_restore (cr);
+ cairo_translate (cr, 0, SIZE + SPACE);
+ }
+ cairo_restore (cr);
+ cairo_translate (cr, SIZE + SPACE, 0);
+
+ cairo_surface_destroy (surface);
+ }
+ }
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (clear_source,
+ "Check painting with cleared surfaces works as expected",
+ NULL, /* keywords */
+ NULL, /* requirements */
+ (SIZE + SPACE) * 9 + SPACE, ARRAY_LENGTH (operations) * (SIZE + SPACE) + SPACE,
+ NULL, draw)
diff --git a/test/clear.c b/test/clear.c
new file mode 100644
index 000000000..696993d3f
--- /dev/null
+++ b/test/clear.c
@@ -0,0 +1,86 @@
+/*
+ * Copyright © 2009 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Chris Wilson not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Chris Wilson makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_text_extents_t extents;
+
+ cairo_set_source_rgb (cr, 0, 0, 1);
+ cairo_paint (cr);
+
+ cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
+
+ cairo_translate (cr, 2, 2);
+ cairo_save (cr);
+ cairo_rectangle (cr, 0, 0, 20, 20);
+ cairo_clip (cr);
+ cairo_rectangle (cr, 5, 5, 10, 10);
+ cairo_fill (cr);
+ cairo_restore (cr);
+
+ cairo_translate (cr, 20, 0);
+ cairo_save (cr);
+ cairo_rectangle (cr, 0, 0, 20, 20);
+ cairo_clip (cr);
+ cairo_arc (cr, 10, 10, 8, 0, 2*M_PI);
+ cairo_fill (cr);
+ cairo_restore (cr);
+
+ cairo_translate (cr, 0, 20);
+ cairo_save (cr);
+ cairo_rectangle (cr, 0, 0, 20, 20);
+ cairo_clip (cr);
+ cairo_text_extents (cr, "Cairo", &extents);
+ cairo_move_to (cr,
+ 10 - (extents.width/2. + extents.x_bearing),
+ 10 - (extents.height/2. + extents.y_bearing));
+ cairo_text_path (cr, "Cairo");
+ cairo_fill (cr);
+ cairo_restore (cr);
+
+ cairo_translate (cr, -20, 0);
+ cairo_save (cr);
+ cairo_rectangle (cr, 0, 0, 20, 20);
+ cairo_clip (cr);
+ cairo_move_to (cr, 10, 2);
+ cairo_line_to (cr, 18, 18);
+ cairo_line_to (cr, 2, 18);
+ cairo_close_path (cr);
+ cairo_fill (cr);
+ cairo_restore (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (clear,
+ "Test masked clears",
+ "paint, clear", /* keywords */
+ NULL, /* requirements */
+ 44, 44,
+ NULL, draw)
+
diff --git a/test/clip-all.c b/test/clip-all.c
new file mode 100644
index 000000000..dc216c9cb
--- /dev/null
+++ b/test/clip-all.c
@@ -0,0 +1,75 @@
+/*
+ * Copyright © 2005 Novell, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Novell, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Novell, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * NOVELL, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL NOVELL, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Radek Doulík <rodo@novell.com>
+ */
+
+#include "cairo-test.h"
+
+#define SIZE 10
+#define CLIP_SIZE 2
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_rectangle (cr, 0, 0, SIZE, SIZE);
+ cairo_set_source_rgb (cr, 0, 0, 1);
+ cairo_fill (cr);
+
+ cairo_reset_clip (cr);
+ cairo_rectangle (cr, CLIP_SIZE, CLIP_SIZE, CLIP_SIZE, CLIP_SIZE);
+ cairo_clip (cr);
+ cairo_rectangle (cr, 3*CLIP_SIZE, 3*CLIP_SIZE, CLIP_SIZE, CLIP_SIZE);
+ cairo_clip (cr);
+
+ cairo_translate (cr, .5, .5);
+
+ cairo_reset_clip (cr);
+ cairo_rectangle (cr, CLIP_SIZE, CLIP_SIZE, CLIP_SIZE, CLIP_SIZE);
+ cairo_clip (cr);
+ cairo_rectangle (cr, 3*CLIP_SIZE, 3*CLIP_SIZE, CLIP_SIZE, CLIP_SIZE);
+ cairo_clip (cr);
+
+ cairo_rectangle (cr, 0, 0, SIZE, SIZE);
+ cairo_set_source_rgb (cr, 1, 1, 0);
+ cairo_fill (cr);
+
+ /* https://bugs.freedesktop.org/show_bug.cgi?id=13084 */
+ cairo_select_font_face (cr,
+ CAIRO_TEST_FONT_FAMILY " Sans",
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_NORMAL);
+
+ cairo_move_to (cr, 0., SIZE);
+ cairo_show_text (cr, "cairo");
+
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (clip_all,
+ "Test clipping with everything clipped out",
+ "clip", /* keywords */
+ NULL, /* requirements */
+ SIZE, SIZE,
+ NULL, draw)
+
diff --git a/test/clip-complex-bug61592.c b/test/clip-complex-bug61592.c
new file mode 100644
index 000000000..998b7aa1e
--- /dev/null
+++ b/test/clip-complex-bug61592.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright © 2013 Uli Schlachter
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Uli Schlachter <psychon@znc.in>
+ */
+
+#include "cairo-test.h"
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ cairo_paint (cr);
+
+ cairo_set_antialias(cr, CAIRO_ANTIALIAS_NONE);
+ cairo_move_to(cr, 85, -465);
+ cairo_line_to(cr, 3, 4.1);
+ cairo_line_to(cr, -145, -25);
+ cairo_close_path(cr);
+ cairo_clip(cr);
+
+ cairo_set_antialias(cr, CAIRO_ANTIALIAS_DEFAULT);
+ cairo_move_to(cr, -139, -524);
+ cairo_line_to(cr, 78, 44);
+ cairo_line_to(cr, -229, -10);
+ cairo_close_path(cr);
+ cairo_clip(cr);
+
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (clip_complex_bug61492,
+ "Exercise a bug found in 1.12",
+ "clip", /* keywords */
+ NULL, /* requirements */
+ 8, 5,
+ NULL, draw)
diff --git a/test/clip-complex-shape.c b/test/clip-complex-shape.c
new file mode 100644
index 000000000..d7d530146
--- /dev/null
+++ b/test/clip-complex-shape.c
@@ -0,0 +1,114 @@
+/*
+ * Copyright 2011 SCore Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Taekyun Kim <podain77@gmail.com>
+ */
+
+#include "cairo-test.h"
+
+static void
+rounded_rectangle(cairo_t *cr,
+ double x, double y,
+ double width, double height,
+ double radius)
+{
+ cairo_move_to (cr, x, y + radius);
+ cairo_line_to (cr, x, y + height - radius);
+ cairo_curve_to (cr, x, y + height - radius/2.0,
+ x + radius/2.0, y + height,
+ x + radius, y + height);
+ cairo_line_to (cr, x + width - radius, y + height);
+ cairo_curve_to (cr, x + width - radius/2.0, y + height,
+ x + width, y + height - radius/2.0,
+ x + width, y + height - radius);
+ cairo_line_to (cr, x + width, y + radius);
+ cairo_curve_to (cr, x + width, y + radius/2.0,
+ x + width - radius/2.0, y,
+ x + width - radius, y);
+ cairo_line_to (cr, x + radius, y);
+ cairo_curve_to (cr, x + radius/2.0, y, x, y + radius/2.0, x, y + radius);
+ cairo_close_path(cr);
+}
+
+static void
+background (cairo_t *cr)
+{
+ cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
+ cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 1.0);
+ cairo_paint(cr);
+}
+
+static void
+foreground (cairo_t *cr)
+{
+ cairo_set_source_rgba(cr, 1.0, 0.0, 0.0, 1.0);
+ cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
+ cairo_rectangle(cr, 20, 20, 60, 60);
+ cairo_fill(cr);
+}
+
+static cairo_test_status_t
+clip_eo_mono (cairo_t *cr, int width, int height)
+{
+
+ background (cr);
+
+ cairo_set_antialias(cr, CAIRO_ANTIALIAS_NONE);
+ cairo_set_fill_rule(cr, CAIRO_FILL_RULE_EVEN_ODD);
+ rounded_rectangle(cr, 0, 0, 40, 100, 10);
+ rounded_rectangle(cr, 60, 0, 40, 100, 10);
+ cairo_clip(cr);
+
+ foreground (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+clip_eo_aa (cairo_t *cr, int width, int height)
+{
+ background (cr);
+
+ cairo_set_antialias(cr, CAIRO_ANTIALIAS_DEFAULT);
+ cairo_set_fill_rule(cr, CAIRO_FILL_RULE_EVEN_ODD);
+ rounded_rectangle(cr, 0, 0, 40, 100, 10);
+ rounded_rectangle(cr, 60, 0, 40, 100, 10);
+ cairo_clip(cr);
+
+ foreground (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (clip_complex_shape_eo_mono,
+ "Test clipping against a complex shape",
+ "clip", /* keywords */
+ NULL, /* requirements */
+ 100, 100,
+ NULL, clip_eo_mono)
+CAIRO_TEST (clip_complex_shape_eo_aa,
+ "Test clipping against a complex shape",
+ "clip", /* keywords */
+ NULL, /* requirements */
+ 100, 100,
+ NULL, clip_eo_aa)
diff --git a/test/clip-contexts.c b/test/clip-contexts.c
new file mode 100644
index 000000000..39d2004c0
--- /dev/null
+++ b/test/clip-contexts.c
@@ -0,0 +1,75 @@
+/*
+ * Copyright © 2010 Intel Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Intel Corporation not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Intel Corporation makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * INTEL CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+/*
+ * Jeff Muizelaar found a bug on Quartz with cairo-surface-clipper, which was
+ * the topmost clip path from two different contexts and finding them equally
+ * incorrectly concluding that the operation was a no-op.
+ */
+
+#define SIZE 10
+#define CLIP_SIZE 2
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_t *cr2;
+
+ /* opaque background */
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ cairo_paint (cr);
+
+ /* first create an empty, non-overlappiny clip */
+ cr2 = cairo_create (cairo_get_target (cr));
+ cairo_rectangle (cr2, 0, 0, SIZE/2-2, SIZE/2-2);
+ cairo_clip (cr2);
+
+ cairo_rectangle (cr2, SIZE/2+2, SIZE/2+2, SIZE/2-2, SIZE/2-2);
+ cairo_clip (cr2);
+
+ /* and apply the clip onto the surface, empty nothing should be painted */
+ cairo_set_source_rgba (cr2, 1, 0, 0, .5);
+ cairo_paint (cr2);
+
+ /* switch back to the original, and set only the last clip */
+ cairo_rectangle (cr, SIZE/2+2, SIZE/2+2, SIZE/2-2, SIZE/2-2);
+ cairo_clip (cr);
+
+ cairo_set_source_rgba (cr, 0, 0, 1, .5);
+ cairo_paint (cr);
+
+ cairo_destroy (cr2);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (clip_contexts,
+ "Test clipping with 2 separate contexts",
+ "clip", /* keywords */
+ NULL, /* requirements */
+ SIZE, SIZE,
+ NULL, draw)
diff --git a/test/clip-device-offset.c b/test/clip-device-offset.c
new file mode 100644
index 000000000..f725b8e93
--- /dev/null
+++ b/test/clip-device-offset.c
@@ -0,0 +1,79 @@
+/*
+ * Copyright © 2009 Benjamin Otte
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Benjamin Otte <otte@gnome.org>
+ */
+
+#include "cairo-test.h"
+
+#define WIDTH 50
+#define HEIGHT 50
+
+static cairo_pattern_t *
+create_green_source (void)
+{
+ cairo_surface_t *image;
+ cairo_pattern_t *pattern;
+ cairo_t *cr;
+
+ image = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, WIDTH, HEIGHT);
+ cr = cairo_create (image);
+ cairo_surface_destroy (image);
+
+ cairo_set_source_rgb (cr, 0, 1, 0);
+ cairo_paint (cr);
+
+ pattern = cairo_pattern_create_for_surface (cairo_get_target (cr));
+ cairo_destroy (cr);
+
+ return pattern;
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_pattern_t *source;
+ double old_x, old_y;
+
+ cairo_surface_get_device_offset (cairo_get_group_target (cr), &old_x, &old_y);
+ cairo_surface_set_device_offset (cairo_get_group_target (cr), old_x+5, old_y+5);
+
+ source = create_green_source ();
+ cairo_set_source (cr, source);
+ cairo_pattern_destroy (source);
+
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_rectangle (cr, 0, 0, WIDTH, HEIGHT);
+ cairo_clip (cr);
+ cairo_paint (cr);
+
+ cairo_surface_set_device_offset (cairo_get_group_target (cr), old_x, old_y);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (clip_device_offset,
+ "Test clipping on surfaces with device offsets",
+ "clip", /* keywords */
+ NULL, /* requirements */
+ WIDTH+10, HEIGHT+10,
+ NULL, draw)
diff --git a/test/clip-disjoint-hatching.c b/test/clip-disjoint-hatching.c
new file mode 100644
index 000000000..8626e80df
--- /dev/null
+++ b/test/clip-disjoint-hatching.c
@@ -0,0 +1,104 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+#define STEP 5
+#define WIDTH 100
+#define HEIGHT 100
+
+static void hatching (cairo_t *cr)
+{
+ int i;
+
+ cairo_rectangle (cr, 0, 0, WIDTH, HEIGHT);
+ cairo_clip (cr);
+
+ cairo_translate (cr, WIDTH/2, HEIGHT/2);
+ cairo_rotate (cr, M_PI/4);
+ cairo_translate (cr, -WIDTH/2, -HEIGHT/2);
+
+ for (i = 0; i < WIDTH; i += STEP) {
+ cairo_rectangle (cr, i, -2, 1, HEIGHT+4);
+ cairo_rectangle (cr, -2, i, WIDTH+4, 1);
+ }
+}
+
+static void background (cairo_t *cr)
+{
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_set_source_rgb (cr, 1,1,1);
+ cairo_paint (cr);
+}
+
+static void clip_to_grid (cairo_t *cr)
+{
+ int i, j;
+
+ for (j = 0; j < HEIGHT; j += 2*STEP) {
+ for (i = 0; i < WIDTH; i += 2*STEP)
+ cairo_rectangle (cr, i, j, STEP, STEP);
+
+ j += 2*STEP;
+ for (i = 0; i < WIDTH; i += 2*STEP)
+ cairo_rectangle (cr, i+STEP/2, j, STEP, STEP);
+ }
+
+ cairo_clip (cr);
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ background (cr);
+
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+
+ cairo_save (cr); {
+ clip_to_grid (cr);
+ hatching (cr);
+ cairo_set_source_rgb (cr, 1, 0, 0);
+ cairo_fill (cr);
+ } cairo_restore (cr);
+
+ cairo_translate (cr, 0.25, HEIGHT+.25);
+
+ cairo_save (cr); {
+ clip_to_grid (cr);
+ hatching (cr);
+ cairo_set_source_rgb (cr, 0, 0, 1);
+ cairo_fill (cr);
+ } cairo_restore (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (clip_disjoint_hatching,
+ "Test drawing through through an array of clips",
+ "clip", /* keywords */
+ "target=raster", /* requirements */
+ WIDTH, 2*HEIGHT,
+ NULL, draw)
diff --git a/test/clip-disjoint-quad.c b/test/clip-disjoint-quad.c
new file mode 100644
index 000000000..fe20381d7
--- /dev/null
+++ b/test/clip-disjoint-quad.c
@@ -0,0 +1,83 @@
+/*
+ * Copyright © 2012 Red Hat, Inc.
+ * Copyright © 2012 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Soren Sandmann <sandmann@redhat.com>
+ * Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+#define WIDTH 100
+#define HEIGHT 200
+
+static void
+draw_quad (cairo_t *cr,
+ double x1, double y1,
+ double x2, double y2,
+ double x3, double y3,
+ double x4, double y4)
+{
+ cairo_move_to (cr, x1, y1);
+ cairo_line_to (cr, x2, y2);
+ cairo_line_to (cr, x3, y3);
+ cairo_line_to (cr, x4, y4);
+ cairo_close_path (cr);
+
+ cairo_set_source_rgb (cr, 0, 0.6, 0);
+ cairo_fill (cr);
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ int position[5] = {0, HEIGHT/2-10, HEIGHT/2-5, HEIGHT/2, HEIGHT-10 };
+ int i;
+
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ cairo_paint (cr);
+
+ for (i = 0; i < 5; i++) {
+ cairo_reset_clip (cr);
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_rectangle (cr, 0, 0, WIDTH/2, HEIGHT/2);
+ cairo_rectangle (cr, WIDTH/2, position[i], WIDTH/2, 10);
+ cairo_fill_preserve (cr);
+ cairo_clip (cr);
+
+ cairo_set_source_rgb (cr, 1, 0, 1);
+ draw_quad (cr, 50, 50, 75, 75, 50, 150, 25, 75);
+ cairo_fill (cr);
+
+ cairo_translate(cr, WIDTH, 0);
+ }
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (clip_disjoint_quad,
+ "Tests a simple fill through two disjoint clips.",
+ "clip, fill", /* keywords */
+ NULL, /* requirements */
+ 5*WIDTH, HEIGHT,
+ NULL, draw)
diff --git a/test/clip-disjoint.c b/test/clip-disjoint.c
new file mode 100644
index 000000000..28bb963c2
--- /dev/null
+++ b/test/clip-disjoint.c
@@ -0,0 +1,90 @@
+/*
+ * Copyright © 2008 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Soren Sandmann <sandmann@redhat.com>
+ */
+
+#include "cairo-test.h"
+
+#define WIDTH 300
+#define HEIGHT 300
+
+typedef struct {
+ double x, y;
+} point_t;
+
+static void
+paint_curve (cairo_t *cr)
+{
+ const point_t points[] = {
+ { 100, 320 }, { 110, -80 },
+ { 180, 60 }, { 300, 170 },
+ { 300, -40 }
+ };
+ unsigned i;
+
+ cairo_set_line_width (cr, 2);
+ cairo_move_to (cr, points[0].x, points[0].y);
+
+ for (i = 1; i < ARRAY_LENGTH (points) - 2; i += 3) {
+ cairo_curve_to (cr,
+ points[i].x, points[i].y,
+ points[i + 1].x, points[i + 1].y,
+ points[i + 2].x, points[i + 2].y);
+ }
+ cairo_set_line_width (cr, 5);
+ cairo_stroke (cr);
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ /* Fill window with light blue */
+ cairo_set_source_rgba (cr, 0.8, 0.8, 1.9, 1.0);
+ cairo_paint (cr);
+
+ /* Paint curve in green */
+ cairo_set_source_rgba (cr, 0.6, 0.8, 0.6, 1.0);
+ paint_curve (cr);
+
+ /* Make clip region */
+ cairo_rectangle (cr, 228, 131, 50, 13);
+ cairo_rectangle (cr, 20, 99, 200, 75);
+ cairo_clip_preserve (cr);
+
+ /* Fill clip region with red */
+ cairo_set_source_rgba (cr, 1.0, 0.5, 0.5, 0.8);
+ cairo_fill (cr);
+
+ /* Paint curve again, this time in blue */
+ cairo_set_source_rgba (cr, 0, 0, 1.0, 1.0);
+ paint_curve (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (clip_disjoint,
+ "Tests stroking through two disjoint clips.",
+ "clip, stroke", /* keywords */
+ NULL, /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw)
diff --git a/test/clip-double-free.c b/test/clip-double-free.c
new file mode 100644
index 000000000..74b9a6e6d
--- /dev/null
+++ b/test/clip-double-free.c
@@ -0,0 +1,87 @@
+/*
+ * Copyright © 2011 Uli Schlachter
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Uli Schlachter <psychon@znc.in>
+ */
+
+/*
+ * This test wants to hit the following double free:
+ *
+ * ==10517== Invalid free() / delete / delete[]
+ * ==10517== at 0x4C268FE: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
+ * ==10517== by 0x87FBE80: _cairo_clip_destroy (cairo-clip.c:136)
+ * ==10517== by 0x87FE520: _cairo_clip_intersect_boxes.part.1 (cairo-clip-private.h:92)
+ * ==10517== by 0x87FE79F: _cairo_clip_intersect_rectilinear_path (cairo-clip-boxes.c:266)
+ * ==10517== by 0x87FC29B: _cairo_clip_intersect_path.part.3 (cairo-clip.c:242)
+ * ==10517== by 0x8809C3A: _cairo_gstate_clip (cairo-gstate.c:1518)
+ * ==10517== by 0x8802E40: _cairo_default_context_clip (cairo-default-context.c:1048)
+ * ==10517== by 0x87FA2C6: cairo_clip (cairo.c:2380)
+ * ==10517== Address 0x18d44cb0 is 0 bytes inside a block of size 32 free'd
+ * ==10517== at 0x4C268FE: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
+ * ==10517== by 0x87FE506: _cairo_clip_intersect_boxes.part.1 (cairo-clip-boxes.c:295)
+ * ==10517== by 0x87FE79F: _cairo_clip_intersect_rectilinear_path (cairo-clip-boxes.c:266)
+ * ==10517== by 0x87FC29B: _cairo_clip_intersect_path.part.3 (cairo-clip.c:242)
+ * ==10517== by 0x8809C3A: _cairo_gstate_clip (cairo-gstate.c:1518)
+ * ==10517== by 0x8802E40: _cairo_default_context_clip (cairo-default-context.c:1048)
+ * ==10517== by 0x87FA2C6: cairo_clip (cairo.c:2380)
+ *
+ * _cairo_clip_intersect_boxes() is called with clip->num_boxes != 0. It then
+ * calls _cairo_boxes_init_for_array (&clip_boxes, clip->boxes, clip->num_boxes)
+ * and free (clip->boxes), stealing the clip's boxes, but leaving a dangling
+ * pointer behind.
+ * Because this code already intersected the existing boxes and the new ones, we
+ * now have num_boxes == 0. This means that _cairo_clip_set_all_clipped() gets
+ * called and tries to free the clip's boxes again.
+ */
+
+#include "cairo-test.h"
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
+
+ /* To hit this bug, we first need a clip with
+ * clip->boxes != clip->embedded_boxes.
+ */
+ cairo_rectangle (cr, 0, 0, 2, 2);
+ cairo_rectangle (cr, 0, 0, 1, 1);
+ cairo_clip (cr);
+
+ /* Then we have to intersect this with a rectilinear path which results in
+ * all clipped. This path must consist of at least two boxes or we will hit
+ * a different code path.
+ */
+ cairo_rectangle (cr, 10, 10, 2, 2);
+ cairo_rectangle (cr, 10, 10, 1, 1);
+ cairo_clip (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (clip_double_free,
+ "Test a double free bug in the clipping code",
+ "clip", /* keywords */
+ NULL, /* requirements */
+ 0, 0,
+ NULL, draw)
diff --git a/test/clip-draw-unbounded.c b/test/clip-draw-unbounded.c
new file mode 100644
index 000000000..6b9263beb
--- /dev/null
+++ b/test/clip-draw-unbounded.c
@@ -0,0 +1,184 @@
+/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */
+/*
+ * Copyright 2009 Chris Wilson
+ * Copyright 2010 Andrea Canciani
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+#define WIDTH 60
+#define HEIGHT 60
+
+static void
+stroke (cairo_t *cr)
+{
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+ cairo_set_source_rgb (cr, 1, 0, 0);
+ cairo_paint (cr);
+
+ cairo_set_operator (cr, CAIRO_OPERATOR_IN);
+ cairo_set_source_rgb (cr, 0, 0.7, 0);
+ cairo_arc (cr, 10, 10, 7.5, 0, 2 * M_PI);
+ cairo_move_to (cr, 0, 20);
+ cairo_line_to (cr, 20, 0);
+ cairo_stroke (cr);
+}
+
+static void
+fill (cairo_t *cr)
+{
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+ cairo_set_source_rgb (cr, 1, 0, 0);
+ cairo_paint (cr);
+
+ cairo_set_operator (cr, CAIRO_OPERATOR_IN);
+ cairo_set_source_rgb (cr, 0, 0.7, 0);
+ cairo_new_sub_path (cr);
+ cairo_arc (cr, 10, 10, 8.5, 0, 2 * M_PI);
+ cairo_new_sub_path (cr);
+ cairo_arc_negative (cr, 10, 10, 6.5, 2 * M_PI, 0);
+
+ cairo_move_to (cr, -1, 19);
+ cairo_line_to (cr, 1, 21);
+ cairo_line_to (cr, 21, 1);
+ cairo_line_to (cr, 19, -1);
+ cairo_line_to (cr, -1, 19);
+
+ cairo_fill (cr);
+}
+
+static void
+clip_simple (cairo_t *cr)
+{
+ cairo_rectangle (cr, 0, 0, 20, 20);
+ cairo_clip (cr);
+}
+
+static void
+clip_unaligned (cairo_t *cr)
+{
+ cairo_rectangle (cr, 0.5, 0.5, 20, 20);
+ cairo_clip (cr);
+}
+
+static void
+clip_aligned (cairo_t *cr)
+{
+ cairo_fill_rule_t orig_rule;
+
+ orig_rule = cairo_get_fill_rule (cr);
+ cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
+ cairo_rectangle (cr, 0, 0, 20, 20);
+ cairo_rectangle (cr, 3, 3, 10, 10);
+ cairo_rectangle (cr, 7, 7, 10, 10);
+ cairo_clip (cr);
+ cairo_set_fill_rule (cr, orig_rule);
+}
+
+static void
+clip_mask (cairo_t *cr)
+{
+ cairo_arc (cr, 10, 10, 10, 0, 2 * M_PI);
+ cairo_new_sub_path (cr);
+ cairo_arc_negative (cr, 10, 10, 5, 2 * M_PI, 0);
+ cairo_new_sub_path (cr);
+ cairo_arc (cr, 10, 10, 2, 0, 2 * M_PI);
+ cairo_clip (cr);
+}
+
+static void (* const clip_funcs[])(cairo_t *cr) = {
+ clip_simple,
+ clip_unaligned,
+ clip_aligned,
+ clip_mask
+};
+
+static double translations[][2] = {
+ { 10, 10 },
+ { WIDTH, 0 },
+ { -WIDTH, HEIGHT },
+ { WIDTH, 0 }
+};
+
+static cairo_test_status_t
+draw (cairo_t *cr, void (*shapes)(cairo_t *))
+{
+ unsigned int i;
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+ for (i = 0; i < ARRAY_LENGTH (clip_funcs); i++) {
+ cairo_translate (cr, translations[i][0], translations[i][1]);
+
+ cairo_save (cr);
+ cairo_scale (cr, 2, 2);
+ clip_funcs[i] (cr);
+ shapes (cr);
+ cairo_restore (cr);
+ }
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+draw_stroke (cairo_t *cr, int width, int height)
+{
+ return draw (cr, stroke);
+}
+
+static cairo_test_status_t
+draw_fill_nz (cairo_t *cr, int width, int height)
+{
+ cairo_set_fill_rule (cr, CAIRO_FILL_RULE_WINDING);
+ return draw (cr, fill);
+}
+
+static cairo_test_status_t
+draw_fill_eo (cairo_t *cr, int width, int height)
+{
+ cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
+ return draw (cr, fill);
+}
+
+CAIRO_TEST (clip_stroke_unbounded,
+ "Tests unbounded stroke through complex clips.",
+ "clip, stroke, unbounded", /* keywords */
+ NULL, /* requirements */
+ 2 * WIDTH, 2 * HEIGHT,
+ NULL, draw_stroke)
+
+CAIRO_TEST (clip_fill_nz_unbounded,
+ "Tests unbounded fill through complex clips (with winding fill rule).",
+ "clip, fill, unbounded", /* keywords */
+ NULL, /* requirements */
+ 2 * WIDTH, 2 * HEIGHT,
+ NULL, draw_fill_nz)
+
+CAIRO_TEST (clip_fill_eo_unbounded,
+ "Tests unbounded fill through complex clips (with even-odd fill rule).",
+ "clip, fill, unbounded", /* keywords */
+ NULL, /* requirements */
+ 2 * WIDTH, 2 * HEIGHT,
+ NULL, draw_fill_eo)
diff --git a/test/clip-empty-group.c b/test/clip-empty-group.c
new file mode 100644
index 000000000..3829c8858
--- /dev/null
+++ b/test/clip-empty-group.c
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+/* Test the handling of cairo_push_group() with everything clipped. */
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_paint (cr); /* opaque background */
+
+ cairo_rectangle (cr, 20, 20, 0, 0);
+ cairo_clip (cr);
+
+ cairo_push_group (cr); /* => 0x0 group */
+ cairo_reset_clip (cr);
+
+ cairo_set_source_rgb (cr, 1, 0, 0);
+ cairo_paint (cr);
+
+ cairo_rectangle (cr, 0, 0, width, height);
+ cairo_set_source_rgba (cr, 0, 1, 0, .5);
+ cairo_fill (cr);
+
+ cairo_move_to (cr, 0, 20);
+ cairo_line_to (cr, width, 20);
+ cairo_set_source_rgb (cr, 0, 0, 1);
+ cairo_stroke (cr);
+
+ cairo_pop_group_to_source (cr);
+ cairo_reset_clip (cr);
+ cairo_paint (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (clip_empty_group,
+ "Test handling of groups with everything clipped",
+ "clip, group", /* keywords */
+ NULL, /* requirements */
+ 40, 40,
+ NULL, draw)
diff --git a/test/clip-empty-save.c b/test/clip-empty-save.c
new file mode 100644
index 000000000..35de3cb94
--- /dev/null
+++ b/test/clip-empty-save.c
@@ -0,0 +1,68 @@
+/*
+ * Copyright © 2007 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Chris Wilson not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Chris Wilson makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+#define SIZE 10
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_set_source_rgb (cr, 0, 0, 1);
+ cairo_paint (cr);
+
+ cairo_reset_clip (cr);
+ cairo_clip (cr);
+
+ cairo_save (cr);
+
+ cairo_translate (cr, .5, .5);
+
+ cairo_set_source_rgb (cr, 0, 1, 0);
+ cairo_rectangle (cr, 0, 0, SIZE, SIZE);
+ cairo_fill_preserve (cr);
+ cairo_set_source_rgb (cr, 1, 0, 0);
+ cairo_stroke (cr);
+
+ /* https://bugs.freedesktop.org/show_bug.cgi?id=13084 */
+ cairo_select_font_face (cr,
+ CAIRO_TEST_FONT_FAMILY " Sans",
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_NORMAL);
+
+ cairo_move_to (cr, 0., SIZE);
+ cairo_show_text (cr, "cairo");
+
+ cairo_restore (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (clip_empty_save,
+ "Test clipping with an empty clip path",
+ "clip", /* keywords */
+ NULL, /* requirements */
+ SIZE, SIZE,
+ NULL, draw)
diff --git a/test/clip-empty.c b/test/clip-empty.c
new file mode 100644
index 000000000..858b69a9e
--- /dev/null
+++ b/test/clip-empty.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright © 2007 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Chris Wilson not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Chris Wilson makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+#define SIZE 10
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_set_source_rgb (cr, 0, 0, 1);
+ cairo_paint (cr);
+
+ cairo_reset_clip (cr);
+ cairo_clip (cr);
+
+ cairo_translate (cr, .5, .5);
+
+ cairo_set_source_rgb (cr, 0, 1, 0);
+ cairo_rectangle (cr, 0, 0, SIZE, SIZE);
+ cairo_fill_preserve (cr);
+ cairo_set_source_rgb (cr, 1, 0, 0);
+ cairo_stroke (cr);
+
+ /* https://bugs.freedesktop.org/show_bug.cgi?id=13084 */
+ cairo_select_font_face (cr,
+ CAIRO_TEST_FONT_FAMILY " Sans",
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_NORMAL);
+
+ cairo_move_to (cr, 0., SIZE);
+ cairo_show_text (cr, "cairo");
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (clip_empty,
+ "Test clipping with an empty clip path",
+ "clip", /* keywords */
+ NULL, /* requirements */
+ SIZE, SIZE,
+ NULL, draw)
diff --git a/test/clip-fill-no-op.c b/test/clip-fill-no-op.c
new file mode 100644
index 000000000..b686b6e0e
--- /dev/null
+++ b/test/clip-fill-no-op.c
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2009 Benjamin Otte
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Benjamin Otte <otte@gnome.org>
+ */
+
+#include "cairo-test.h"
+
+#define WIDTH 50
+#define HEIGHT 50
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ /* Neutral gray background */
+ cairo_set_source_rgb (cr, 0.5, 0.5, 0.5);
+ cairo_paint (cr);
+
+ /* remove this clip operation and everything works */
+ cairo_rectangle (cr, 10, 10, 30, 30);
+ cairo_clip (cr);
+
+ /* remove this no-op and everything works */
+ cairo_fill (cr);
+
+ /* make the y coordinates integers and everything works */
+ cairo_move_to (cr, 20, 20.101562);
+ cairo_line_to (cr, 30, 20.101562);
+
+ /* This clip operation should fail to work. But with cairo 1.9, if all the
+ * 3 cases above happen, the clip will not work and the paint will happen.
+ */
+ cairo_save (cr); {
+ cairo_set_source_rgba (cr, 1, 0.5, 0.5, 1);
+ cairo_clip_preserve (cr);
+ cairo_paint (cr);
+ } cairo_restore (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (clip_fill_no_op,
+ "Exercises a bug found by Benjamin Otte whereby a no-op clip is nullified by a stroke",
+ "clip, fill", /* keywords */
+ NULL, /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw)
diff --git a/test/clip-fill-rule-pixel-aligned.c b/test/clip-fill-rule-pixel-aligned.c
new file mode 100644
index 000000000..210afcb83
--- /dev/null
+++ b/test/clip-fill-rule-pixel-aligned.c
@@ -0,0 +1,90 @@
+/*
+ * Copyright © 2004 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+#include "cairo-test.h"
+
+#define PAD 1
+#define SIZE 5
+
+static void
+pixel_aligned_path (cairo_t *cr)
+{
+ cairo_save (cr);
+ {
+ cairo_scale (cr, SIZE, SIZE);
+ cairo_move_to (cr, 1, 0);
+ cairo_rel_line_to (cr, 1, 0);
+ cairo_rel_line_to (cr, 0, 3);
+ cairo_rel_line_to (cr, 1, 0);
+ cairo_rel_line_to (cr, 0, -1);
+ cairo_rel_line_to (cr, -3, 0);
+ cairo_rel_line_to (cr, 0, -1);
+ cairo_rel_line_to (cr, 4, 0);
+ cairo_rel_line_to (cr, 0, 3);
+ cairo_rel_line_to (cr, -3, 0);
+ cairo_rel_line_to (cr, 0, -4);
+ cairo_close_path (cr);
+ }
+ cairo_restore (cr);
+}
+
+/* Use clipping to draw the same path twice, once with each fill rule */
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_set_source_rgb (cr, 1, 0, 0); /* red */
+
+ cairo_translate (cr, PAD, PAD);
+
+ cairo_save (cr);
+ {
+ pixel_aligned_path (cr);
+ cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
+ cairo_clip (cr);
+ cairo_paint (cr);
+ }
+ cairo_restore (cr);
+
+ cairo_translate (cr, SIZE*4 + PAD, 0);
+
+ cairo_save (cr);
+ {
+ pixel_aligned_path (cr);
+ cairo_set_fill_rule (cr, CAIRO_FILL_RULE_WINDING);
+ cairo_clip (cr);
+ cairo_paint (cr);
+ }
+ cairo_restore (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (clip_fill_rule_pixel_aligned,
+ "Tests interaction of clipping and cairo_set_fill_rule with a pixel-aligned path",
+ "clip", /* keywords */
+ NULL, /* requirements */
+ PAD + (SIZE*4) + PAD + (SIZE*4) + PAD,
+ PAD + (SIZE*4) + PAD,
+ NULL, draw)
diff --git a/test/clip-fill-rule.c b/test/clip-fill-rule.c
new file mode 100644
index 000000000..31c3ab71d
--- /dev/null
+++ b/test/clip-fill-rule.c
@@ -0,0 +1,87 @@
+/*
+ * Copyright © 2004 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+#include "cairo-test.h"
+
+#define STAR_SIZE 20
+
+static void
+star_path (cairo_t *cr)
+{
+ cairo_move_to (cr, 10, 0);
+ cairo_rel_line_to (cr, 6, 20);
+ cairo_rel_line_to (cr, -16, -12);
+ cairo_rel_line_to (cr, 20, 0);
+ cairo_rel_line_to (cr, -16, 12);
+}
+
+/* Use clipping to draw the same path twice, once with each fill rule */
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_set_source_rgb (cr, 1, 0, 0);
+
+ cairo_translate (cr, 1, 1);
+ cairo_save (cr);
+ {
+ star_path (cr);
+ cairo_set_fill_rule (cr, CAIRO_FILL_RULE_WINDING);
+ cairo_clip (cr);
+ cairo_paint (cr);
+ }
+ cairo_restore (cr);
+
+ cairo_translate (cr, STAR_SIZE + 1, 0);
+ cairo_save (cr);
+ {
+ star_path (cr);
+ cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
+ cairo_clip (cr);
+ cairo_paint (cr);
+ }
+ cairo_restore (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+a1_draw (cairo_t *cr, int width, int height)
+{
+ cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE);
+ return draw (cr, width, height);
+}
+
+CAIRO_TEST (clip_fill_rule,
+ "Tests interaction of clipping with cairo_set_fill_rule",
+ "clip", /* keywords */
+ NULL, /* requirements */
+ STAR_SIZE * 2 + 2, STAR_SIZE + 2,
+ NULL, draw)
+CAIRO_TEST (a1_clip_fill_rule,
+ "Tests interaction of clipping with cairo_set_fill_rule",
+ "clip", /* keywords */
+ "target=raster", /* requirements */
+ STAR_SIZE * 2 + 2, STAR_SIZE + 2,
+ NULL, a1_draw)
diff --git a/test/clip-fill.c b/test/clip-fill.c
new file mode 100644
index 000000000..331af7963
--- /dev/null
+++ b/test/clip-fill.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2009 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Chris Wilson not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Chris Wilson makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+#define WIDTH 20
+#define HEIGHT 20
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+ /* aligned-clip */
+ cairo_save (cr);
+ cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
+ cairo_rectangle (cr, 0, 0, 20, 20);
+ cairo_rectangle (cr, 3, 3, 10, 10);
+ cairo_rectangle (cr, 7, 7, 10, 10);
+ cairo_clip (cr);
+
+ cairo_set_source_rgb (cr, 0.7, 0, 0);
+ cairo_paint (cr);
+ cairo_set_source_rgb (cr, 0, 0.7, 0);
+ cairo_arc (cr, 10, 10, 8, 0, 2 * M_PI);
+ cairo_fill (cr);
+ cairo_restore (cr);
+
+ cairo_translate (cr, WIDTH, 0);
+
+ /* force a clip-mask */
+ cairo_save (cr);
+ cairo_arc (cr, 10, 10, 10, 0, 2 * M_PI);
+ cairo_new_sub_path (cr);
+ cairo_arc_negative (cr, 10, 10, 5, 2 * M_PI, 0);
+ cairo_new_sub_path (cr);
+ cairo_arc (cr, 10, 10, 2, 0, 2 * M_PI);
+ cairo_clip (cr);
+
+ cairo_set_source_rgb (cr, 0, 0, 0.7);
+ cairo_paint (cr);
+ cairo_set_source_rgb (cr, 0, 0.7, 0);
+ cairo_arc (cr, 10, 10, 7.5, 0, 2 * M_PI);
+ cairo_fill (cr);
+ cairo_restore (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (clip_fill,
+ "Tests filling through complex clips.",
+ "clip, fill", /* keywords */
+ NULL, /* requirements */
+ 2 * WIDTH, HEIGHT,
+ NULL, draw)
diff --git a/test/clip-group-shapes.c b/test/clip-group-shapes.c
new file mode 100644
index 000000000..88bb9b3dd
--- /dev/null
+++ b/test/clip-group-shapes.c
@@ -0,0 +1,188 @@
+/*
+ * Copyright (c) 2010 M Joonas Pihlaja
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: M Joonas Pihlaja <jpihlaja@cc.helsinki.fi>
+ */
+#include "cairo-test.h"
+
+/* Tests specific clipping fast paths and their interaction with
+ * groups: It shouldn't matter if the clip is set before or after
+ * pushing a group.
+ *
+ * There's some overlap with the following tests, but they test for
+ * different things:
+ *
+ * group-clip.c (tests preserving paths), clipped-group.c (tests
+ * clipping the same thing different ways), clip-push-group (tests
+ * for a specific bug).
+ */
+
+#define GENERATE_REF 0
+
+/* For determining whether we establish the clip path before or after
+ * pushing a group. */
+enum {
+ CLIP_OUTSIDE_GROUP,
+ CLIP_INSIDE_GROUP
+};
+
+typedef void (*clipper_t)(cairo_t *cr, int w, int h);
+
+static cairo_test_status_t
+clip_and_paint (cairo_t *cr,
+ int w, int h,
+ clipper_t do_clip,
+ int clip_where)
+{
+ cairo_save (cr); {
+ if (GENERATE_REF) {
+ do_clip (cr, w, h);
+ cairo_paint (cr);
+ } else {
+ if (clip_where == CLIP_OUTSIDE_GROUP)
+ do_clip (cr, w, h);
+ cairo_push_group (cr); {
+ if (clip_where == CLIP_INSIDE_GROUP)
+ do_clip (cr, w, h);
+ cairo_paint (cr);
+ }
+ cairo_pop_group_to_source (cr);
+ if (clip_where == CLIP_OUTSIDE_GROUP)
+ cairo_reset_clip (cr);
+ cairo_paint (cr);
+ }
+ }
+ cairo_restore (cr);
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+run_clip_test (cairo_t *cr, int w, int h, clipper_t do_clip)
+{
+ cairo_set_source_rgb (cr, 1,1,1);
+ cairo_paint (cr);
+ cairo_set_source_rgb (cr, 1,0,0);
+
+ /* Left. */
+ clip_and_paint (cr, w/2, h, do_clip, CLIP_OUTSIDE_GROUP);
+
+ /* Right */
+ cairo_translate(cr, w/2, 0);
+ clip_and_paint (cr, w/2, h, do_clip, CLIP_INSIDE_GROUP);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static void
+clip_aligned_rectangles (cairo_t *cr, int w, int h)
+{
+ int x1 = 0.2 * w;
+ int y1 = 0.2 * h;
+ int x2 = 0.8 * w;
+ int y2 = 0.8 * h;
+
+ cairo_rectangle (cr, x1, y1, w, h);
+ cairo_clip (cr);
+
+ cairo_rectangle (cr, x2, y2, -w, -h);
+ cairo_clip (cr);
+}
+
+static void
+clip_unaligned_rectangles (cairo_t *cr, int w, int h)
+{
+ /* This clip stresses the antialiased edges produced by an
+ * unaligned rectangular clip. The edges should be produced by
+ * compositing red on white with alpha = 0.5 on the sides, and with
+ * alpha = 0.25 in the corners. */
+ int x1 = 0.2 * w;
+ int y1 = 0.2 * h;
+ int x2 = 0.8 * w;
+ int y2 = 0.8 * h;
+
+ cairo_rectangle (cr, x1+0.5, y1+0.5, w, h);
+ cairo_clip (cr);
+
+ cairo_rectangle (cr, x2+0.5, y2+0.5, -w, -h);
+ w = x2 - x1;
+ h = y2 - y1;
+ cairo_rectangle (cr, x2, y1+1, -w+1, h-1);
+ cairo_clip (cr);
+}
+
+static void
+clip_circles (cairo_t *cr, int w, int h)
+{
+ int x1 = 0.5 * w;
+ int y1 = 0.5 * h;
+ int x2 = 0.75 * w;
+ int y2 = 0.75 * h;
+ int r = 0.4*MIN(w,h);
+
+ cairo_arc (cr, x1, y1, r, 0, 6.28);
+ cairo_close_path (cr);
+ cairo_clip (cr);
+
+ cairo_arc (cr, x2, y2, r, 0, 6.28);
+ cairo_close_path (cr);
+ cairo_clip (cr);
+}
+
+static cairo_test_status_t
+draw_aligned_rectangles (cairo_t *cr, int width, int height)
+{
+ return run_clip_test (cr, width, height, clip_aligned_rectangles);
+}
+
+static cairo_test_status_t
+draw_unaligned_rectangles (cairo_t *cr, int width, int height)
+{
+ return run_clip_test (cr, width, height, clip_unaligned_rectangles);
+}
+
+static cairo_test_status_t
+draw_circles (cairo_t *cr, int width, int height)
+{
+ return run_clip_test (cr, width, height, clip_circles);
+}
+
+CAIRO_TEST (clip_group_shapes_aligned_rectangles,
+ "Test clip and group interaction with aligned rectangle clips",
+ "clip", /* keywords */
+ NULL, /* requirements */
+ 200, 100,
+ NULL, draw_aligned_rectangles)
+
+CAIRO_TEST (clip_group_shapes_unaligned_rectangles,
+ "Test clip and group interaction with unaligned rectangle clips",
+ "clip", /* keywords */
+ "target=raster", /* requirements */
+ 200, 100,
+ NULL, draw_unaligned_rectangles)
+
+CAIRO_TEST (clip_group_shapes_circles,
+ "Test clip and group interaction with circular clips",
+ "clip", /* keywords */
+ NULL, /* requirements */
+ 200, 100,
+ NULL, draw_circles)
diff --git a/test/clip-image.c b/test/clip-image.c
new file mode 100644
index 000000000..68ed142d6
--- /dev/null
+++ b/test/clip-image.c
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2009 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Chris Wilson not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Chris Wilson makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+#define WIDTH 20
+#define HEIGHT 20
+
+static const char *png_filename = "romedalen.png";
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ const cairo_test_context_t *ctx = cairo_test_get_context (cr);
+ cairo_surface_t *image;
+
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+ image = cairo_test_create_surface_from_png (ctx, png_filename);
+ cairo_set_source_surface (cr, image, 0, 0);
+ cairo_surface_destroy (image);
+
+ /* simple clip */
+ cairo_save (cr);
+ cairo_rectangle (cr, 2, 2, 16, 16);
+ cairo_clip (cr);
+ cairo_paint (cr);
+ cairo_restore (cr);
+
+ cairo_translate (cr, WIDTH, 0);
+
+ /* unaligned clip */
+ cairo_save (cr);
+ cairo_rectangle (cr, 2.5, 2.5, 15, 15);
+ cairo_clip (cr);
+ cairo_paint (cr);
+ cairo_restore (cr);
+
+ cairo_translate (cr, -WIDTH, HEIGHT);
+
+ /* aligned-clip */
+ cairo_save (cr);
+ cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
+ cairo_rectangle (cr, 0, 0, 20, 20);
+ cairo_rectangle (cr, 3, 3, 10, 10);
+ cairo_rectangle (cr, 7, 7, 10, 10);
+ cairo_clip (cr);
+ cairo_paint (cr);
+ cairo_restore (cr);
+
+ cairo_translate (cr, WIDTH, 0);
+
+ /* force a clip-mask */
+ cairo_save (cr);
+ cairo_arc (cr, 10, 10, 10, 0, 2 * M_PI);
+ cairo_new_sub_path (cr);
+ cairo_arc_negative (cr, 10, 10, 5, 2 * M_PI, 0);
+ cairo_new_sub_path (cr);
+ cairo_arc (cr, 10, 10, 2, 0, 2 * M_PI);
+ cairo_clip (cr);
+ cairo_paint (cr);
+ cairo_restore (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (clip_image,
+ "Tests painting an image through complex clips.",
+ "clip, paint", /* keywords */
+ NULL, /* requirements */
+ 2 * WIDTH, 2 * HEIGHT,
+ NULL, draw)
diff --git a/test/clip-intersect.c b/test/clip-intersect.c
new file mode 100644
index 000000000..295fbc93c
--- /dev/null
+++ b/test/clip-intersect.c
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2009 Chris Wilson
+ * Copyright 2011 Intel Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Chris Wilson not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Chris Wilson makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+#define WIDTH 20
+#define HEIGHT 20
+
+static void clip_mask (cairo_t *cr)
+{
+ cairo_move_to (cr, 10, 0);
+ cairo_line_to (cr, 0, 10);
+ cairo_line_to (cr, 10, 20);
+ cairo_line_to (cr, 20, 10);
+ cairo_clip (cr);
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+ clip_mask (cr);
+ cairo_set_source_rgb (cr, 0, 1, 0);
+ cairo_paint (cr);
+ cairo_reset_clip (cr);
+
+ cairo_set_source_rgb (cr, 1, 0, 0);
+
+ cairo_rectangle (cr, 0, 0, 4, 4);
+ cairo_clip (cr);
+ clip_mask (cr);
+ cairo_paint (cr);
+ cairo_reset_clip (cr);
+
+ cairo_rectangle (cr, 20, 0, -4, 4);
+ cairo_clip (cr);
+ clip_mask (cr);
+ cairo_paint (cr);
+ cairo_reset_clip (cr);
+
+ cairo_rectangle (cr, 20, 20, -4, -4);
+ cairo_clip (cr);
+ clip_mask (cr);
+ cairo_paint (cr);
+ cairo_reset_clip (cr);
+
+ cairo_rectangle (cr, 0, 20, 4, -4);
+ cairo_clip (cr);
+ clip_mask (cr);
+ cairo_paint (cr);
+ cairo_reset_clip (cr);
+
+ cairo_set_source_rgb (cr, 0, 0, 1);
+
+ cairo_rectangle (cr, 8, 8, 4, 4);
+ cairo_clip (cr);
+ clip_mask (cr);
+ cairo_paint (cr);
+ cairo_reset_clip (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (clip_intersect,
+ "Tests intersection of a simple clip with a clip-mask",
+ "clip, paint", /* keywords */
+ NULL, /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw)
diff --git a/test/clip-mixed-antialias.c b/test/clip-mixed-antialias.c
new file mode 100644
index 000000000..23a55ff63
--- /dev/null
+++ b/test/clip-mixed-antialias.c
@@ -0,0 +1,128 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+#define WIDTH 200
+#define HEIGHT 200
+
+/* This is an example from the wild, as silly as it is
+n 52 0 429 709 rectangle
+clip+
+//ANTIALIAS_NONE set-antialias
+n 8 0 m 952 0 l 956.417969 0 960 3.582031 960 8 c 960 1807 l 960 1811.417969 956.417969 1815 952 1815 c 8 1815 l 3.582031 1815 0 1811.417969 0 1807 c 0 8 l 0 3.582031 3.582031 0 8 0 c h
+clip+
+//EVEN_ODD set-fill-rule
+n 0 0 m 480 0 l 480 708 l 0 708 l h 8 1 m 952 1 l 955.867188 1 959 4.132812 959 8 c 959 1807 l 959 1810.867188 955.867188 1814 952 1814 c 8 1814 l 4.132812 1814 1 1810.867188 1 1807 c 1 8 l 1 4.132812 4.132812 1 8 1 c h
+clip+
+//WINDING set-fill-rule
+//ANTIALIAS_DEFAULT set-antialias
+n 960 0 m 52.5 907.5 l 52.5 1815 l 960 1815 l h
+clip+
+//ANTIALIAS_NONE set-antialias
+n 960 0 m 52.5 0 l 52.5 907.5 l 960 1815 l h
+clip+
+*/
+
+static void background (cairo_t *cr)
+{
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_set_source_rgb (cr, 1,1,1);
+ cairo_paint (cr);
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+}
+
+static void clip_0 (cairo_t *cr)
+{
+ cairo_rectangle (cr, 5, 5, 190, 190);
+ cairo_clip (cr);
+}
+
+static void clip_1 (cairo_t *cr)
+{
+ cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE);
+
+ cairo_arc (cr, 100, 100, 125, 0, 2*M_PI);
+ cairo_clip (cr);
+
+ cairo_set_antialias (cr, CAIRO_ANTIALIAS_DEFAULT);
+}
+
+static void
+rounded_rectangle (cairo_t *cr, int x, int y, int w, int h, int r)
+{
+ cairo_new_sub_path (cr);
+ cairo_arc (cr, x + r, y + r, r, M_PI, 3 * M_PI / 2);
+ cairo_arc (cr, x + w - r, y + r, r, 3 *M_PI / 2, 2 * M_PI);
+ cairo_arc (cr, x + w - r, y + h - r, r, 0, M_PI / 2);
+ cairo_arc (cr, x + r, y + h - r, r, M_PI / 2, M_PI);
+ cairo_close_path (cr);
+}
+
+static void clip_2 (cairo_t *cr)
+{
+ cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
+
+ rounded_rectangle (cr, 50, 50, 100, 100, 15);
+ rounded_rectangle (cr, 60, 60, 80, 80, 5);
+ cairo_clip (cr);
+
+ cairo_set_fill_rule (cr, CAIRO_FILL_RULE_WINDING);
+}
+
+static void clip_3 (cairo_t *cr)
+{
+ cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE);
+
+ cairo_rectangle (cr, 40.25, 60.25, 120, 80);
+ cairo_rectangle (cr, 60.25, 40.25, 80, 120);
+ cairo_clip (cr);
+
+ cairo_set_antialias (cr, CAIRO_ANTIALIAS_DEFAULT);
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ background (cr);
+
+ clip_0 (cr);
+ clip_1 (cr);
+ clip_2 (cr);
+ clip_3 (cr);
+
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ cairo_paint (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (clip_mixed_antialias,
+ "Test drawing through through an mixture of clips",
+ "clip", /* keywords */
+ "target=raster", /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw)
diff --git a/test/clip-nesting.c b/test/clip-nesting.c
new file mode 100644
index 000000000..a9227ec77
--- /dev/null
+++ b/test/clip-nesting.c
@@ -0,0 +1,109 @@
+/*
+ * Copyright © 2005 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Owen Taylor <otaylor@redhat.com>
+ */
+
+#include "cairo-test.h"
+#include <math.h>
+#include <stdio.h>
+
+#define SIZE 100
+#define BORDER 10
+#define LINE_WIDTH 20
+
+static void
+_propagate_status (cairo_t *dst, cairo_t *src)
+{
+ cairo_path_t path;
+
+ path.status = cairo_status (src);
+ if (path.status) {
+ path.num_data = 0;
+ path.data = NULL;
+ cairo_append_path (dst, &path);
+ }
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_surface_t *target_surface;
+ cairo_t *cr2, *cr3;
+
+ target_surface = cairo_get_group_target (cr);
+
+ cr2 = cairo_create (target_surface);
+
+ /* Draw a diagonal line and clip to it */
+
+ cairo_move_to (cr2, BORDER, BORDER);
+ cairo_line_to (cr2, BORDER + LINE_WIDTH, BORDER);
+ cairo_line_to (cr2, SIZE - BORDER, SIZE - BORDER);
+ cairo_line_to (cr2, SIZE - BORDER - LINE_WIDTH, SIZE - BORDER);
+
+ cairo_clip (cr2);
+ cairo_set_source_rgb (cr2, 0, 0, 1); /* Blue */
+ cairo_paint (cr2);
+
+ /* Clipping affects this cairo_t */
+
+ cairo_set_source_rgb (cr2, 1, 1, 1); /* White */
+ cairo_rectangle (cr2,
+ SIZE / 2 - LINE_WIDTH / 2, BORDER,
+ LINE_WIDTH, SIZE - 2 * BORDER);
+ cairo_fill (cr2);
+
+ /* But doesn't affect another cairo_t that we create temporarily for
+ * the same surface
+ */
+ cr3 = cairo_create (target_surface);
+ cairo_set_source_rgb (cr3, 1, 1, 1); /* White */
+ cairo_rectangle (cr3,
+ SIZE - BORDER - LINE_WIDTH, BORDER,
+ LINE_WIDTH, SIZE - 2 * BORDER);
+ cairo_fill (cr3);
+
+ _propagate_status (cr, cr3);
+ cairo_destroy (cr3);
+
+ _propagate_status (cr, cr2);
+ cairo_destroy (cr2);
+
+ /* And doesn't affect anything after this cairo_t is destroyed */
+
+ cairo_set_source_rgb (cr, 1, 1, 1); /* White */
+ cairo_rectangle (cr,
+ BORDER, BORDER,
+ LINE_WIDTH, SIZE - 2 * BORDER);
+ cairo_fill (cr);
+
+ return CAIRO_TEST_SUCCESS;
+
+}
+
+CAIRO_TEST (clip_nesting,
+ "Test clipping with multiple contexts for the same surface",
+ "clip", /* keywords */
+ NULL, /* requirements */
+ SIZE, SIZE,
+ NULL, draw)
diff --git a/test/clip-operator.c b/test/clip-operator.c
new file mode 100644
index 000000000..ac0a5e966
--- /dev/null
+++ b/test/clip-operator.c
@@ -0,0 +1,188 @@
+/*
+ * Copyright © 2005 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Kristian Høgsberg <krh@redhat.com>
+ */
+
+#include "cairo-test.h"
+#include <math.h>
+#include <stdio.h>
+
+#define WIDTH 16
+#define HEIGHT 16
+#define PAD 2
+
+static void
+draw_mask (cairo_t *cr, int x, int y)
+{
+ cairo_surface_t *mask_surface;
+ cairo_t *cr2;
+
+ double width = (int)(0.9 * WIDTH);
+ double height = (int)(0.9 * HEIGHT);
+ x += 0.05 * WIDTH;
+ y += 0.05 * HEIGHT;
+
+ mask_surface = cairo_surface_create_similar (cairo_get_group_target (cr),
+ CAIRO_CONTENT_ALPHA,
+ width, height);
+ cr2 = cairo_create (mask_surface);
+ cairo_surface_destroy (mask_surface);
+
+ cairo_save (cr2);
+ cairo_set_source_rgba (cr2, 0, 0, 0, 0); /* transparent */
+ cairo_set_operator (cr2, CAIRO_OPERATOR_SOURCE);
+ cairo_paint (cr2);
+ cairo_restore (cr2);
+
+ cairo_set_source_rgb (cr2, 1, 1, 1); /* white */
+
+ cairo_arc (cr2, 0.5 * width, 0.5 * height, 0.45 * height, 0, 2 * M_PI);
+ cairo_fill (cr2);
+
+ cairo_mask_surface (cr, cairo_get_target (cr2), x, y);
+ cairo_destroy (cr2);
+}
+
+static void
+draw_glyphs (cairo_t *cr, int x, int y)
+{
+ cairo_text_extents_t extents;
+
+ cairo_set_font_size (cr, 0.8 * HEIGHT);
+
+ cairo_text_extents (cr, "FG", &extents);
+ cairo_move_to (cr,
+ x + floor ((WIDTH - extents.width) / 2 + 0.5) - extents.x_bearing,
+ y + floor ((HEIGHT - extents.height) / 2 + 0.5) - extents.y_bearing);
+ cairo_show_text (cr, "FG");
+}
+
+static void
+draw_polygon (cairo_t *cr, int x, int y)
+{
+ double width = (int)(0.9 * WIDTH);
+ double height = (int)(0.9 * HEIGHT);
+ x += 0.05 * WIDTH;
+ y += 0.05 * HEIGHT;
+
+ cairo_new_path (cr);
+ cairo_move_to (cr, x, y);
+ cairo_line_to (cr, x, y + height);
+ cairo_line_to (cr, x + width / 2, y + 3 * height / 4);
+ cairo_line_to (cr, x + width, y + height);
+ cairo_line_to (cr, x + width, y);
+ cairo_line_to (cr, x + width / 2, y + height / 4);
+ cairo_close_path (cr);
+ cairo_fill (cr);
+}
+
+static void
+draw_rects (cairo_t *cr, int x, int y)
+{
+ double block_width = (int)(0.33 * WIDTH + 0.5);
+ double block_height = (int)(0.33 * HEIGHT + 0.5);
+ int i, j;
+
+ for (i = 0; i < 3; i++)
+ for (j = 0; j < 3; j++)
+ if ((i + j) % 2 == 0)
+ cairo_rectangle (cr,
+ x + block_width * i, y + block_height * j,
+ block_width, block_height);
+
+ cairo_fill (cr);
+}
+
+static void (* const draw_funcs[])(cairo_t *cr, int x, int y) = {
+ draw_mask,
+ draw_glyphs,
+ draw_polygon,
+ draw_rects
+};
+
+#define N_OPERATORS (1 + CAIRO_OPERATOR_SATURATE - CAIRO_OPERATOR_CLEAR)
+
+#define IMAGE_WIDTH (N_OPERATORS * (WIDTH + PAD) + PAD)
+#define IMAGE_HEIGHT (ARRAY_LENGTH (draw_funcs) * (HEIGHT + PAD) + PAD)
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ const cairo_test_context_t *ctx = cairo_test_get_context (cr);
+ size_t j, x, y;
+ cairo_operator_t op;
+ cairo_pattern_t *pattern;
+
+ cairo_select_font_face (cr, CAIRO_TEST_FONT_FAMILY " Sans",
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_NORMAL);
+ cairo_set_font_size (cr, 0.9 * HEIGHT);
+
+ for (j = 0; j < ARRAY_LENGTH (draw_funcs); j++) {
+ for (op = CAIRO_OPERATOR_CLEAR; op < N_OPERATORS; op++) {
+ x = op * (WIDTH + PAD) + PAD;
+ y = j * (HEIGHT + PAD) + PAD;
+
+ cairo_save (cr);
+
+ pattern = cairo_pattern_create_linear (x + WIDTH, y,
+ x, y + HEIGHT);
+ cairo_pattern_add_color_stop_rgba (pattern, 0.2,
+ 0.0, 0.0, 1.0, 1.0); /* Solid blue */
+ cairo_pattern_add_color_stop_rgba (pattern, 0.8,
+ 0.0, 0.0, 1.0, 0.0); /* Transparent blue */
+ cairo_set_source (cr, pattern);
+ cairo_pattern_destroy (pattern);
+
+ cairo_rectangle (cr, x, y, WIDTH, HEIGHT);
+ cairo_fill (cr);
+
+ cairo_set_operator (cr, op);
+ cairo_set_source_rgb (cr, 1.0, 0.0, 0.0);
+
+ cairo_move_to (cr, x, y);
+ cairo_line_to (cr, x + WIDTH, y);
+ cairo_line_to (cr, x, y + HEIGHT);
+ cairo_clip (cr);
+
+ draw_funcs[j] (cr, x, y);
+ if (cairo_status (cr))
+ cairo_test_log (ctx, "%d %d HERE!\n", op, (int)j);
+
+ cairo_restore (cr);
+ }
+ }
+
+ if (cairo_status (cr) != CAIRO_STATUS_SUCCESS)
+ cairo_test_log (ctx, "%d %d .HERE!\n", op, (int)j);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (clip_operator,
+ "Surface clipping with different operators",
+ "clip", /* keywords */
+ NULL, /* requirements */
+ IMAGE_WIDTH, IMAGE_HEIGHT,
+ NULL, draw)
+
diff --git a/test/clip-polygons.c b/test/clip-polygons.c
new file mode 100644
index 000000000..83eb4df3a
--- /dev/null
+++ b/test/clip-polygons.c
@@ -0,0 +1,112 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+#define STEP 5
+#define WIDTH 100
+#define HEIGHT 100
+
+static void diamond (cairo_t *cr)
+{
+ cairo_move_to (cr, WIDTH/2, 0);
+ cairo_line_to (cr, WIDTH, HEIGHT/2);
+ cairo_line_to (cr, WIDTH/2, HEIGHT);
+ cairo_line_to (cr, 0, HEIGHT/2);
+ cairo_close_path (cr);
+}
+
+static void background (cairo_t *cr)
+{
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_set_source_rgb (cr, 1,1,1);
+ cairo_paint (cr);
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+ cairo_set_source_rgb (cr, 0,0,0);
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ background (cr);
+
+ /* completely overlapping diamonds */
+ cairo_save (cr);
+ diamond (cr);
+ cairo_clip (cr);
+ diamond (cr);
+ cairo_clip (cr);
+ cairo_paint (cr);
+ cairo_restore (cr);
+
+ cairo_translate (cr, WIDTH, 0);
+
+ /* partial overlap */
+ cairo_save (cr);
+ cairo_translate (cr, -WIDTH/4, 0);
+ diamond (cr);
+ cairo_clip (cr);
+ cairo_translate (cr, WIDTH/2, 0);
+ diamond (cr);
+ cairo_clip (cr);
+ cairo_paint (cr);
+ cairo_restore (cr);
+
+ cairo_translate (cr, WIDTH, 0);
+
+ /* no overlap, but the bounding boxes must */
+ cairo_save (cr);
+ cairo_translate (cr, -WIDTH/2 + 2, -2);
+ diamond (cr);
+ cairo_clip (cr);
+ cairo_translate (cr, WIDTH - 4, 4);
+ diamond (cr);
+ cairo_clip (cr);
+ cairo_paint (cr);
+ cairo_restore (cr);
+
+ cairo_translate (cr, WIDTH, 0);
+
+ /* completely disjoint */
+ cairo_save (cr);
+ cairo_translate (cr, -WIDTH/2 - 1, 0);
+ diamond (cr);
+ cairo_clip (cr);
+ cairo_translate (cr, WIDTH + 2, 0);
+ diamond (cr);
+ cairo_clip (cr);
+ cairo_paint (cr);
+ cairo_restore (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (clip_polygons,
+ "Test drawing through through an intersection of polygons",
+ "clip", /* keywords */
+ "target=raster", /* requirements */
+ 4*WIDTH, HEIGHT,
+ NULL, draw)
diff --git a/test/clip-push-group.c b/test/clip-push-group.c
new file mode 100644
index 000000000..4effb0aba
--- /dev/null
+++ b/test/clip-push-group.c
@@ -0,0 +1,67 @@
+/*
+ * Copyright © 2006 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+/* A test for the crash described here:
+ *
+ * http://lists.freedesktop.org/archives/cairo/2006-August/007698.html
+ *
+ * The triggering condition for this bug should be setting a
+ * surface-based clip and then calling cairo_push_group.
+ */
+
+#include "cairo-test.h"
+
+#define SIZE 10
+#define PAD 2
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ /* An overly complex way of drawing a blue circle onto a red
+ * background, to trigger the bug. */
+ cairo_set_source_rgb (cr, 1, 0, 0); /* red */
+ cairo_paint (cr);
+
+ cairo_arc (cr,
+ SIZE / 2, SIZE / 2,
+ SIZE / 2 - PAD,
+ 0, 2 * M_PI);
+ cairo_clip (cr);
+
+ cairo_push_group (cr);
+ cairo_set_source_rgb (cr, 0, 0, 1); /* blue */
+ cairo_paint (cr);
+ cairo_pop_group_to_source (cr);
+ cairo_paint (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (clip_push_group,
+ "Test that push_group doesn't crash after setting a surface-based clip",
+ "clip", /* keywords */
+ NULL, /* requirements */
+ SIZE, SIZE,
+ NULL, draw)
diff --git a/test/clip-rectilinear.c b/test/clip-rectilinear.c
new file mode 100644
index 000000000..98db4a2c7
--- /dev/null
+++ b/test/clip-rectilinear.c
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+#define SIZE 120
+
+static void L(cairo_t *cr, int w, int h)
+{
+ cairo_move_to (cr, 0, 0);
+ cairo_line_to (cr, 0, h);
+ cairo_line_to (cr, w, h);
+ cairo_line_to (cr, w, h/2);
+ cairo_line_to (cr, w/2, h/2);
+ cairo_line_to (cr, w/2, 0);
+ cairo_close_path (cr);
+}
+
+static void LL(cairo_t *cr, int w, int h)
+{
+ cairo_save (cr);
+
+ /* aligned */
+ cairo_rectangle (cr, 0, 0, w, h);
+ cairo_clip (cr);
+ L (cr, w, h);
+ cairo_clip (cr);
+ cairo_paint (cr);
+ cairo_reset_clip (cr);
+
+ /* unaligned */
+ cairo_translate (cr, w+.25, .25);
+ cairo_rectangle (cr, 0, 0, w, h);
+ cairo_clip (cr);
+ L (cr, w, h);
+ cairo_clip (cr);
+ cairo_paint (cr);
+ cairo_reset_clip (cr);
+
+ cairo_restore (cr);
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ int w = SIZE/2, h = SIZE/2;
+
+ cairo_paint (cr); /* opaque background */
+
+ cairo_set_source_rgb (cr, 1, 0, 0);
+ LL (cr, w, h);
+
+ cairo_translate (cr, 0, h);
+ cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE);
+
+ cairo_set_source_rgb (cr, 0, 0, 1);
+ LL (cr, w, h);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (clip_rectilinear,
+ "Test handling of rectilinear clipping",
+ "clip", /* keywords */
+ NULL, /* requirements */
+ SIZE, SIZE,
+ NULL, draw)
diff --git a/test/clip-shape.c b/test/clip-shape.c
new file mode 100644
index 000000000..6a74a6ed5
--- /dev/null
+++ b/test/clip-shape.c
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+/* Adapted from a bug report by <cairouser@yahoo.com> */
+
+#include "cairo-test.h"
+
+static const struct xy {
+ double x;
+ double y;
+} gp[] = {
+ { 100, 250 },
+ { 100, 100 },
+ { 150, 230 },
+ { 239, 100 },
+ { 239, 250 },
+};
+
+static const double vp[3] = { 100, 144, 238.5 };
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ int i;
+
+ cairo_paint (cr); /* opaque background */
+
+ for (i = 0; i < 5; ++i)
+ cairo_line_to (cr, gp[i].x, gp[i].y);
+ cairo_close_path (cr);
+
+ cairo_set_source_rgb (cr, 1, 0, 0);
+ cairo_set_line_width (cr, 1.5);
+ cairo_stroke_preserve (cr);
+ cairo_clip (cr);
+
+ for (i = 1; i < 3; ++i) {
+ double x1 = vp[i - 1];
+ double x2 = vp[i];
+
+ cairo_move_to (cr, x1, 0);
+ cairo_line_to (cr, x1, height);
+ cairo_line_to (cr, x2, height);
+ cairo_line_to (cr, x2, 0);
+ cairo_close_path (cr);
+
+ if (i & 1)
+ cairo_set_source_rgb (cr, 0, 1, 0);
+ else
+ cairo_set_source_rgb (cr, 1, 1, 0);
+
+ cairo_fill (cr);
+ }
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (clip_shape,
+ "Test handling of clipping with a non-aligned shape",
+ "clip", /* keywords */
+ NULL, /* requirements */
+ 400, 300,
+ NULL, draw)
diff --git a/test/clip-stroke-no-op.c b/test/clip-stroke-no-op.c
new file mode 100644
index 000000000..8eb91719b
--- /dev/null
+++ b/test/clip-stroke-no-op.c
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2009 Benjamin Otte
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Benjamin Otte <otte@gnome.org>
+ */
+
+#include "cairo-test.h"
+
+#define WIDTH 50
+#define HEIGHT 50
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ /* Neutral gray background */
+ cairo_set_source_rgb (cr, 0.5, 0.5, 0.5);
+ cairo_paint (cr);
+
+ /* remove this clip operation and everything works */
+ cairo_rectangle (cr, 10, 10, 30, 30);
+ cairo_clip (cr);
+
+ /* remove this no-op and everything works */
+ cairo_stroke (cr);
+
+ /* make the y coordinates integers and everything works */
+ cairo_move_to (cr, 20, 20.101562);
+ cairo_line_to (cr, 30, 20.101562);
+
+ /* This clip operation should fail to work. But with cairo 1.9, if all the
+ * 3 cases above happen, the clip will not work and the paint will happen.
+ */
+ cairo_save (cr); {
+ cairo_set_source_rgba (cr, 1, 0.5, 0.5, 1);
+ cairo_clip_preserve (cr);
+ cairo_paint (cr);
+ } cairo_restore (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (clip_stroke_no_op,
+ "Exercises a bug found by Benjamin Otte whereby a no-op clip is nullified by a stroke",
+ "clip, stroke", /* keywords */
+ NULL, /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw)
diff --git a/test/clip-stroke.c b/test/clip-stroke.c
new file mode 100644
index 000000000..9714dd067
--- /dev/null
+++ b/test/clip-stroke.c
@@ -0,0 +1,121 @@
+/*
+ * Copyright 2009 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Chris Wilson not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Chris Wilson makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+#define WIDTH 40
+#define HEIGHT 40
+
+static void
+shapes (cairo_t *cr)
+{
+ cairo_set_source_rgb (cr, 1, 0, 0);
+ cairo_paint (cr);
+
+ cairo_set_source_rgb (cr, 0, 0.7, 0);
+ cairo_arc (cr, 10, 10, 7.5, 0, 2 * M_PI);
+ cairo_stroke (cr);
+
+ cairo_set_source_rgb (cr, 0, 0.7, 0.7);
+ cairo_arc (cr, 10, 10, 25, 0, 2 * M_PI);
+ cairo_stroke (cr);
+ cairo_rectangle (cr, -5, -5, 30, 30);
+ cairo_stroke (cr);
+
+ cairo_set_source_rgb (cr, 0.7, 0.7, 0);
+ cairo_save (cr);
+ cairo_translate (cr, 10, 10);
+ cairo_rotate (cr, M_PI/4);
+ cairo_translate (cr, -10, -10);
+ cairo_rectangle (cr, -5, -5, 30, 30);
+ cairo_stroke (cr);
+ cairo_restore (cr);
+
+ cairo_set_source_rgb (cr, 0.7, 0.0, 0.7);
+ cairo_move_to (cr, 15, -10);
+ cairo_line_to (cr, 30, 10);
+ cairo_line_to (cr, 15, 30);
+ cairo_stroke (cr);
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+ cairo_translate (cr, 10, 10);
+
+ /* simple clip */
+ cairo_save (cr);
+ cairo_rectangle (cr, 0, 0, 20, 20);
+ cairo_clip (cr);
+ shapes (cr);
+ cairo_restore (cr);
+
+ cairo_translate (cr, WIDTH, 0);
+
+ /* unaligned clip */
+ cairo_save (cr);
+ cairo_rectangle (cr, 0.5, 0.5, 20, 20);
+ cairo_clip (cr);
+ shapes (cr);
+ cairo_restore (cr);
+
+ cairo_translate (cr, -WIDTH, HEIGHT);
+
+ /* aligned-clip */
+ cairo_save (cr);
+ cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
+ cairo_rectangle (cr, 0, 0, 20, 20);
+ cairo_rectangle (cr, 3, 3, 10, 10);
+ cairo_rectangle (cr, 7, 7, 10, 10);
+ cairo_clip (cr);
+ shapes (cr);
+ cairo_restore (cr);
+
+ cairo_translate (cr, WIDTH, 0);
+
+ /* force a clip-mask */
+ cairo_save (cr);
+ cairo_arc (cr, 10, 10, 10, 0, 2 * M_PI);
+ cairo_new_sub_path (cr);
+ cairo_arc_negative (cr, 10, 10, 5, 2 * M_PI, 0);
+ cairo_new_sub_path (cr);
+ cairo_arc (cr, 10, 10, 2, 0, 2 * M_PI);
+ cairo_clip (cr);
+ shapes (cr);
+ cairo_restore (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (clip_stroke,
+ "Tests stroke through complex clips.",
+ "clip, stroke", /* keywords */
+ NULL, /* requirements */
+ 2 * WIDTH, 2* HEIGHT,
+ NULL, draw)
+
diff --git a/test/clip-text.c b/test/clip-text.c
new file mode 100644
index 000000000..ed8e10796
--- /dev/null
+++ b/test/clip-text.c
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2009 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Chris Wilson not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Chris Wilson makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+#define WIDTH 20
+#define HEIGHT 20
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ const char *cairo = "Cairo";
+ cairo_text_extents_t extents;
+ double x0, y0;
+
+ cairo_text_extents (cr, cairo, &extents);
+ x0 = WIDTH/2. - (extents.width/2. + extents.x_bearing);
+ y0 = HEIGHT/2. - (extents.height/2. + extents.y_bearing);
+
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+ /* aligned-clip */
+ cairo_save (cr);
+ cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
+ cairo_rectangle (cr, 0, 0, 20, 20);
+ cairo_rectangle (cr, 3, 3, 10, 10);
+ cairo_rectangle (cr, 7, 7, 10, 10);
+ cairo_clip (cr);
+
+ cairo_set_source_rgb (cr, 0.7, 0, 0);
+ cairo_paint (cr);
+ cairo_set_source_rgb (cr, 0, 0, 0);
+
+ cairo_move_to (cr, x0, y0);
+ cairo_show_text (cr, cairo);
+ cairo_restore (cr);
+
+ cairo_translate (cr, WIDTH, 0);
+
+ /* force a clip-mask */
+ cairo_save (cr);
+ cairo_arc (cr, 10, 10, 10, 0, 2 * M_PI);
+ cairo_new_sub_path (cr);
+ cairo_arc_negative (cr, 10, 10, 5, 2 * M_PI, 0);
+ cairo_new_sub_path (cr);
+ cairo_arc (cr, 10, 10, 2, 0, 2 * M_PI);
+ cairo_clip (cr);
+
+ cairo_set_source_rgb (cr, 0, 0, 0.7);
+ cairo_paint (cr);
+ cairo_set_source_rgb (cr, 0, 0, 0);
+
+ cairo_move_to (cr, x0, y0);
+ cairo_show_text (cr, cairo);
+ cairo_restore (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (clip_text,
+ "Tests drawing text through complex clips.",
+ "clip, text", /* keywords */
+ NULL, /* requirements */
+ 2 * WIDTH, HEIGHT,
+ NULL, draw)
diff --git a/test/clip-twice-rectangle.c b/test/clip-twice-rectangle.c
new file mode 100644
index 000000000..28f16ec84
--- /dev/null
+++ b/test/clip-twice-rectangle.c
@@ -0,0 +1,70 @@
+/*
+ * Copyright © 2010 Mozilla Corporation
+ * Copyright © 2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_surface_t *mask;
+ cairo_t *cr2;
+
+ cairo_set_source_rgb (cr, 0, 1, 0);
+ cairo_paint (cr);
+
+ /* clip twice, note that the intersection is smaller then the extents */
+ cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
+ cairo_rectangle (cr, 10, 10, 80, 80);
+ cairo_rectangle (cr, 20, 20, 60, 60);
+ cairo_clip (cr);
+
+ cairo_rectangle (cr, 0, 40, 40, 30);
+ cairo_clip (cr);
+
+ /* and exercise the bug found by Jeff Muizelaar */
+ mask = cairo_surface_create_similar (cairo_get_target (cr),
+ CAIRO_CONTENT_ALPHA,
+ width-20, height-20);
+ cr2 = cairo_create (mask);
+ cairo_surface_destroy (mask);
+
+ cairo_set_source_rgba (cr2, 1, 1, 1, 1);
+ cairo_paint (cr2);
+
+ cairo_set_source_rgb (cr, 1, 0, 0);
+ cairo_mask_surface (cr, cairo_get_target (cr2), 0, 0);
+ cairo_destroy (cr2);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (clip_twice_rectangle,
+ "Tests clipping twice using rectangles",
+ "clip", /* keywords */
+ NULL, /* requirements */
+ 100, 100,
+ NULL, draw)
diff --git a/test/clip-twice.c b/test/clip-twice.c
new file mode 100644
index 000000000..641b55144
--- /dev/null
+++ b/test/clip-twice.c
@@ -0,0 +1,74 @@
+/*
+ * Copyright © 2005 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Kristian Høgsberg <krh@redhat.com>
+ */
+
+#include "cairo-test.h"
+
+#define WIDTH 64
+#define HEIGHT 64
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_new_path (cr);
+ cairo_arc (cr, WIDTH / 2, HEIGHT / 2, WIDTH / 3, 0, 2 * M_PI);
+ cairo_clip (cr);
+
+ cairo_new_path (cr);
+ cairo_move_to (cr, 0, 0);
+ cairo_line_to (cr, WIDTH / 4, HEIGHT / 2);
+ cairo_line_to (cr, 0, HEIGHT);
+ cairo_line_to (cr, WIDTH, HEIGHT);
+ cairo_line_to (cr, 3 * WIDTH / 4, HEIGHT / 2);
+ cairo_line_to (cr, WIDTH, 0);
+ cairo_close_path (cr);
+ cairo_clip (cr);
+
+ cairo_set_source_rgb (cr, 0, 0, 0.6);
+
+ cairo_new_path (cr);
+ cairo_move_to (cr, 0, 0);
+ cairo_line_to (cr, 0, HEIGHT);
+ cairo_line_to (cr, WIDTH / 2, 3 * HEIGHT / 4);
+ cairo_line_to (cr, WIDTH, HEIGHT);
+ cairo_line_to (cr, WIDTH, 0);
+ cairo_line_to (cr, WIDTH / 2, HEIGHT / 4);
+ cairo_close_path (cr);
+ cairo_fill (cr);
+
+ cairo_new_path (cr);
+ cairo_arc (cr, WIDTH / 2, HEIGHT / 2, WIDTH / 5, 0, 2 * M_PI);
+ cairo_clip (cr);
+ cairo_set_source_rgb (cr, 1, 1, 0);
+ cairo_paint (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (clip_twice,
+ "Verifies that the clip mask is updated correctly when it constructed by setting the clip path twice.",
+ "clip", /* keywords */
+ NULL, /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw)
diff --git a/test/clip-unbounded.c b/test/clip-unbounded.c
new file mode 100644
index 000000000..cd1c60223
--- /dev/null
+++ b/test/clip-unbounded.c
@@ -0,0 +1,80 @@
+/*
+ * Copyright © 2009 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Chris Wilson not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Chris Wilson makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+#define SIZE 10
+
+static cairo_surface_t *
+create_source (cairo_surface_t *target)
+{
+ cairo_surface_t *similar;
+ cairo_t *cr;
+
+ similar = cairo_surface_create_similar (target,
+ CAIRO_CONTENT_COLOR, SIZE/2, SIZE);
+ cr = cairo_create (similar);
+ cairo_surface_destroy (similar);
+
+ cairo_set_source_rgb (cr, 1, 0, 0);
+ cairo_paint (cr);
+
+ similar = cairo_surface_reference (cairo_get_target (cr));
+ cairo_destroy (cr);
+
+ return similar;
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_surface_t *source;
+
+ cairo_set_source_rgb (cr, 0, 0, 1);
+ cairo_paint (cr);
+
+ cairo_rectangle (cr, 0, 0, SIZE/2, SIZE);
+ cairo_clip (cr);
+
+ /* Draw a source rectangle outside the image, the effect should be to
+ * clear only within the clip region.
+ */
+ source = create_source (cairo_get_target (cr));
+ cairo_set_source_surface (cr, source, SIZE/2, 0);
+ cairo_surface_destroy (source);
+
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_paint (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (clip_unbounded,
+ "Test handling of an unbounded fill outside the clip region",
+ "clip", /* keywords */
+ NULL, /* requirements */
+ SIZE, SIZE,
+ NULL, draw)
+
diff --git a/test/clip-zero.c b/test/clip-zero.c
new file mode 100644
index 000000000..5afd1b561
--- /dev/null
+++ b/test/clip-zero.c
@@ -0,0 +1,72 @@
+/*
+ * Copyright © 2007 Mozilla Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Vladimir Vukicevic <vladimir@pobox.com>
+ */
+
+#include "cairo-test.h"
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_pattern_t *pat;
+ cairo_surface_t *surf;
+
+ cairo_new_path (cr);
+ cairo_rectangle (cr, 0, 0, 0, 0);
+ cairo_clip (cr);
+
+ cairo_push_group (cr);
+
+ cairo_set_source_rgb (cr, 1, 0, 0);
+
+ cairo_new_path (cr);
+ cairo_rectangle (cr, -10, 10, 20, 20);
+ cairo_fill_preserve (cr);
+ cairo_stroke_preserve (cr);
+ cairo_paint (cr);
+
+ cairo_select_font_face (cr, "sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
+ cairo_show_text (cr, "ABC");
+
+ cairo_mask (cr, cairo_get_source (cr));
+
+ surf = cairo_surface_create_similar (cairo_get_group_target (cr), CAIRO_CONTENT_COLOR_ALPHA, 0, 0);
+ pat = cairo_pattern_create_for_surface (surf);
+ cairo_surface_destroy (surf);
+
+ cairo_mask (cr, pat);
+ cairo_pattern_destroy (pat);
+
+ cairo_pop_group_to_source (cr);
+ cairo_paint (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (clip_zero,
+ "Verifies that 0x0 surfaces or clips don't cause problems.",
+ "clip", /* keywords */
+ NULL, /* requirements */
+ 0, 0,
+ NULL, draw)
diff --git a/test/clipped-group.c b/test/clipped-group.c
new file mode 100644
index 000000000..a66f357f8
--- /dev/null
+++ b/test/clipped-group.c
@@ -0,0 +1,88 @@
+/*
+ * Copyright © 2008 Mozilla Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Mozilla Corporation not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Mozilla Corporation makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * MOZILLA CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL MOZILLA CORPORATION BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Jeff Muizelaar
+ */
+
+#include "cairo-test.h"
+
+#define WIDTH 60
+#define HEIGHT 70
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ /* fill with black so we don't need an rgb test case */
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ cairo_paint (cr);
+
+ /* setting a scale will ensure that the device offset is transformed */
+ cairo_scale (cr, 2.1, 2.8);
+ cairo_set_source_rgb (cr, 1, .5,.4);
+
+ /* all rectangles should look the same */
+
+ /* plain rectangle */
+ cairo_rectangle (cr, 4, 4, 8, 8);
+ cairo_fill (cr);
+
+ cairo_translate (cr, 10, 0);
+
+ /* clipped rectangle */
+ cairo_save (cr);
+ cairo_rectangle (cr, 3, 3, 9, 9);
+ cairo_clip (cr);
+ cairo_rectangle (cr, 4, 4, 8, 8);
+ cairo_fill (cr);
+ cairo_restore (cr);
+
+ cairo_translate (cr, 0, 10);
+
+ /* clipped and grouped rectangle */
+ cairo_save (cr);
+ cairo_rectangle (cr, 3, 3, 9, 9);
+ cairo_clip (cr);
+ cairo_push_group (cr);
+ cairo_rectangle (cr, 4, 4, 8, 8);
+ cairo_fill (cr);
+ cairo_pop_group_to_source (cr);
+ cairo_paint (cr);
+ cairo_restore (cr);
+
+ cairo_translate (cr, -10, 0);
+
+ /* grouped rectangle */
+ cairo_push_group (cr);
+ cairo_rectangle (cr, 4, 4, 8, 8);
+ cairo_fill (cr);
+ cairo_pop_group_to_source (cr);
+ cairo_paint (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (clipped_group,
+ "Test that a clipped group ends up in the right place",
+ "clip", /* keywords */
+ NULL, /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw)
diff --git a/test/clipped-surface.c b/test/clipped-surface.c
new file mode 100644
index 000000000..a10652dc8
--- /dev/null
+++ b/test/clipped-surface.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2008 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Chris Wilson not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Chris Wilson makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+/*
+ * Michael Natterer (mitch) reported a bad regression with post-1.8 trunk
+ * with artifacts drawn whilst repainting exposed areas.
+ */
+
+#include "cairo-test.h"
+
+static const char png_filename[] = "romedalen.png";
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ const cairo_test_context_t *ctx = cairo_test_get_context (cr);
+ cairo_surface_t *image;
+
+ image = cairo_test_create_surface_from_png (ctx, png_filename);
+
+ cairo_set_source_rgb (cr, 1, 0, 0);
+ cairo_paint (cr);
+
+ cairo_rectangle (cr, 20, 20, 10, 10);
+ cairo_clip (cr);
+
+ cairo_set_source_surface (cr, image, 10, 10);
+ cairo_surface_destroy (image);
+
+ cairo_rectangle (cr, 10, 10, 20, 20);
+ cairo_fill (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (clipped_surface,
+ "Tests application of a clip to a source surface",
+ "clip", /* keywords */
+ NULL, /* requirements */
+ 40, 40,
+ NULL, draw)
diff --git a/test/clipped-trapezoids-ref.png b/test/clipped-trapezoids-ref.png
new file mode 100644
index 000000000..3fd300c04
--- /dev/null
+++ b/test/clipped-trapezoids-ref.png
Binary files differ
diff --git a/test/clipped-trapezoids.c b/test/clipped-trapezoids.c
new file mode 100644
index 000000000..1f96daa8c
--- /dev/null
+++ b/test/clipped-trapezoids.c
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2008 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Chris Wilson not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Chris Wilson makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ double dash[2] = { 8, 4 };
+ double radius;
+
+ radius = width;
+ if (height > radius)
+ radius = height;
+
+ /* fill the background using a big circle */
+ cairo_arc (cr, 0, 0, 4 * radius, 0, 2 * M_PI);
+ cairo_fill (cr);
+
+ /* a rotated square - overlapping the corners */
+ cairo_save (cr);
+ cairo_save (cr);
+ cairo_translate (cr, width/2, height/2);
+ cairo_rotate (cr, M_PI/4);
+ cairo_scale (cr, M_SQRT2, M_SQRT2);
+ cairo_rectangle (cr, -width/2, -height/2, width, height);
+ cairo_restore (cr);
+ cairo_set_source_rgba (cr, 0, 1, 0, .5);
+ cairo_set_line_width (cr, radius/2);
+ cairo_stroke (cr);
+ cairo_restore (cr);
+
+ /* and put some circles in the corners */
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_new_sub_path (cr);
+ cairo_arc (cr, 0, 0, radius/4, 0, 2 * M_PI);
+ cairo_new_sub_path (cr);
+ cairo_arc (cr, width, 0, radius/4, 0, 2 * M_PI);
+ cairo_new_sub_path (cr);
+ cairo_arc (cr, width, height, radius/4, 0, 2 * M_PI);
+ cairo_new_sub_path (cr);
+ cairo_arc (cr, 0, height, radius/4, 0, 2 * M_PI);
+ cairo_fill (cr);
+
+ /* a couple of pixel-aligned lines */
+ cairo_set_source_rgb (cr, 0, 0, 1);
+ cairo_move_to (cr, width/2, -height);
+ cairo_rel_line_to (cr, 0, 3*height);
+ cairo_move_to (cr, -width, height/2);
+ cairo_rel_line_to (cr, 3*width, 0);
+ cairo_stroke (cr);
+
+ /* a couple of dashed diagonals */
+ cairo_save (cr);
+ cairo_set_source_rgb (cr, 1, 0, 0);
+ cairo_set_dash (cr, dash, 2, 0);
+ cairo_set_line_width (cr, 4.);
+ cairo_move_to (cr, -width, -height);
+ cairo_line_to (cr, width+width, height+height);
+ cairo_move_to (cr, width+width, -height);
+ cairo_line_to (cr, -width, height+height);
+ cairo_stroke (cr);
+ cairo_restore (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (clipped_trapezoids,
+ "Tests clipping of trapezoids larger than the surface",
+ "clip", /* keywords */
+ NULL, /* requirements */
+ 40, 40,
+ NULL, draw)
diff --git a/test/close-path-current-point.c b/test/close-path-current-point.c
new file mode 100644
index 000000000..35f8d423b
--- /dev/null
+++ b/test/close-path-current-point.c
@@ -0,0 +1,95 @@
+/*
+ * Copyright © 2009 Nis Martensen
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of the copyright holder
+ * not be used in advertising or publicity pertaining to distribution of
+ * the software without specific, written prior permission. The
+ * copyright holder makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without
+ * express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+ * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Nis Martensen <nis.martensen@web.de>
+ */
+
+#include "cairo-test.h"
+
+#define SIZE 20
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ /* We draw in the default black, so paint white first. */
+ cairo_save (cr);
+ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */
+ cairo_paint (cr);
+ cairo_restore (cr);
+
+ /* subpath starts with cairo_move_to */
+ cairo_new_sub_path (cr);
+ cairo_move_to (cr, SIZE, SIZE);
+ cairo_rel_line_to (cr, SIZE, 0);
+ cairo_rel_line_to (cr, 0, SIZE);
+ cairo_close_path (cr);
+ cairo_rel_line_to (cr, 0.5 * SIZE, SIZE);
+
+ /* subpath starts with cairo_line_to */
+ cairo_new_sub_path (cr);
+ cairo_line_to (cr, SIZE, 3 * SIZE);
+ cairo_rel_line_to (cr, SIZE, 0);
+ cairo_rel_line_to (cr, 0, SIZE);
+ cairo_close_path (cr);
+ cairo_rel_line_to (cr, 0, SIZE);
+
+ /* subpath starts with cairo_curve_to */
+ cairo_new_sub_path (cr);
+ cairo_curve_to (cr,
+ SIZE, 5 * SIZE,
+ 1.5 * SIZE, 6 * SIZE,
+ 2 * SIZE, 5 * SIZE);
+ cairo_rel_line_to (cr, 0, SIZE);
+ cairo_close_path (cr);
+ cairo_rel_line_to (cr, -0.5 * SIZE, SIZE);
+
+ /* subpath starts with cairo_arc */
+ cairo_new_sub_path (cr);
+ cairo_arc (cr,
+ 1.5 * SIZE, 7 * SIZE,
+ 0.5 * SIZE,
+ M_PI, 2 * M_PI);
+ cairo_rel_line_to (cr, 0, SIZE);
+ cairo_close_path (cr);
+ cairo_rel_line_to (cr, -0.7 * SIZE, 0.7 * SIZE);
+
+ /* subpath starts with cairo_arc_negative */
+ cairo_new_sub_path (cr);
+ cairo_arc_negative (cr,
+ 1.5 * SIZE, 9 * SIZE,
+ 0.5 * SIZE,
+ M_PI, 2 * M_PI);
+ cairo_rel_line_to (cr, 0, SIZE);
+ cairo_close_path (cr);
+ cairo_rel_line_to (cr, -0.8 * SIZE, 0.3 * SIZE);
+
+ cairo_stroke (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (close_path_current_point,
+ "Test some corner cases related to cairo path operations and the current point",
+ "path", /* keywords */
+ NULL, /* requirements */
+ 3 * SIZE, 11 * SIZE,
+ NULL, draw)
diff --git a/test/close-path.c b/test/close-path.c
new file mode 100644
index 000000000..f1f1230fa
--- /dev/null
+++ b/test/close-path.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright © 2006 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+#include "cairo-test.h"
+#include <stdlib.h>
+
+static cairo_test_draw_function_t draw;
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_path_t *path;
+
+ /* We draw in the default black, so paint white first. */
+ cairo_save (cr);
+ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */
+ cairo_paint (cr);
+ cairo_restore (cr);
+
+ /* This curious approach for drawing a circle (starting with a
+ * closed arc) exercises a bug in which the "last move point" was
+ * not being set so the close_path closes to (0,0). */
+ cairo_arc (cr, 8, 8, 4, 0, M_PI);
+ cairo_close_path (cr);
+ cairo_arc (cr, 8, 8, 4, M_PI, 2 * M_PI);
+
+ cairo_fill (cr);
+
+ cairo_translate (cr, 16, 0);
+
+ /* Here a curve immediately after a close_to will begin from (0,0)
+ * when the path is obtained with cairo_copy_path_flat. */
+ cairo_move_to (cr, 8, 4);
+ cairo_arc_negative (cr, 8, 8, 4, 3 * M_PI / 2.0, M_PI / 2.0);
+ cairo_close_path (cr);
+ cairo_curve_to (cr,
+ 12, 4,
+ 12, 12,
+ 8, 12);
+
+ path = cairo_copy_path_flat (cr);
+ cairo_new_path (cr);
+ cairo_append_path (cr, path);
+ cairo_path_destroy (path);
+
+ cairo_fill (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (close_path,
+ "Test some corner cases related to cairo_close_path",
+ "path", /* keywords */
+ NULL, /* requirements */
+ 32, 16,
+ NULL, draw)
diff --git a/test/composite-integer-translate-over-repeat.c b/test/composite-integer-translate-over-repeat.c
new file mode 100644
index 000000000..d9e00057b
--- /dev/null
+++ b/test/composite-integer-translate-over-repeat.c
@@ -0,0 +1,84 @@
+/*
+ * Copyright © 2007 Mozilla Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Vladimir Vukicevic <vladimir@pobox.com>
+ */
+
+#include "cairo-test.h"
+#include <math.h>
+#include <stdio.h>
+
+#define SIZE 100
+#define SIZE2 20
+#define OFFSET 10
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_surface_t *image;
+ cairo_pattern_t *pat;
+ cairo_t *cr2;
+
+ image = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, SIZE2, SIZE2);
+ cr2 = cairo_create (image);
+ cairo_surface_destroy (image);
+
+ cairo_set_source_rgba (cr2, 1, 0, 0, 1);
+ cairo_rectangle (cr2, 0, 0, SIZE2/2, SIZE2/2);
+ cairo_fill (cr2);
+ cairo_set_source_rgba (cr2, 0, 1, 0, 1);
+ cairo_rectangle (cr2, SIZE2/2, 0, SIZE2/2, SIZE2/2);
+ cairo_fill (cr2);
+ cairo_set_source_rgba (cr2, 0, 0, 1, 1);
+ cairo_rectangle (cr2, 0, SIZE2/2, SIZE2/2, SIZE2/2);
+ cairo_fill (cr2);
+ cairo_set_source_rgba (cr2, 1, 1, 0, 1);
+ cairo_rectangle (cr2, SIZE2/2, SIZE2/2, SIZE2/2, SIZE2/2);
+ cairo_fill (cr2);
+
+ pat = cairo_pattern_create_for_surface (cairo_get_target (cr2));
+ cairo_destroy (cr2);
+
+ cairo_pattern_set_extend (pat, CAIRO_EXTEND_REPEAT);
+
+ cairo_set_source_rgba (cr, 0, 0, 0, 1);
+ cairo_rectangle (cr, 0, 0, SIZE, SIZE);
+ cairo_fill (cr);
+
+ cairo_translate (cr, OFFSET, OFFSET);
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+ cairo_set_source (cr, pat);
+ cairo_rectangle (cr, 0, 0, SIZE - OFFSET, SIZE - OFFSET);
+ cairo_fill (cr);
+
+ cairo_pattern_destroy (pat);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (composite_integer_translate_over_repeat,
+ "Test simple compositing: integer-translation 32->32 OVER, with repeat",
+ "composite", /* keywords */
+ NULL, /* requirements */
+ SIZE, SIZE,
+ NULL, draw)
diff --git a/test/composite-integer-translate-over.c b/test/composite-integer-translate-over.c
new file mode 100644
index 000000000..1b82a3379
--- /dev/null
+++ b/test/composite-integer-translate-over.c
@@ -0,0 +1,61 @@
+/*
+ * Copyright © 2006 Mozilla Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Mozilla Corporation not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Mozilla Corporation makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * MOZILLA CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL MOZILLA CORPORATION BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Vladimir Vukicevic <vladimir@pobox.com>
+ */
+#include "cairo-test.h"
+#include <math.h>
+#include <stdio.h>
+
+#define SIZE 100
+#define OFFSET 10
+static const char *png_filename = "romedalen.png";
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ const cairo_test_context_t *ctx = cairo_test_get_context (cr);
+ cairo_surface_t *image;
+
+ image = cairo_test_create_surface_from_png (ctx, png_filename);
+
+ cairo_set_source_rgba (cr, 0, 0, 0, 1);
+ cairo_rectangle (cr, 0, 0, SIZE, SIZE);
+ cairo_fill (cr);
+
+ cairo_translate (cr, OFFSET, OFFSET);
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+ cairo_set_source_surface (cr, image, 0, 0);
+ cairo_rectangle (cr, 0, 0, (SIZE-OFFSET), (SIZE-OFFSET));
+ cairo_fill (cr);
+
+ cairo_surface_destroy (image);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (composite_integer_translate_over,
+ "Test simple compositing: integer-translation 32->32 OVER",
+ "composite", /* keywords */
+ NULL, /* requirements */
+ SIZE, SIZE,
+ NULL, draw)
diff --git a/test/composite-integer-translate-source.c b/test/composite-integer-translate-source.c
new file mode 100644
index 000000000..e6fd93366
--- /dev/null
+++ b/test/composite-integer-translate-source.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright © 2007 Mozilla Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Vladimir Vukicevic <vladimir@pobox.com>
+ */
+
+#include "cairo-test.h"
+#include <math.h>
+#include <stdio.h>
+
+#define SIZE 100
+#define OFFSET 10
+
+static const char *png_filename = "romedalen.png";
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ const cairo_test_context_t *ctx = cairo_test_get_context (cr);
+ cairo_surface_t *image;
+
+ image = cairo_test_create_surface_from_png (ctx, png_filename);
+
+ cairo_set_source_rgba (cr, 0, 0, 0, 1);
+ cairo_rectangle (cr, 0, 0, SIZE, SIZE);
+ cairo_fill (cr);
+
+ cairo_translate (cr, OFFSET, OFFSET);
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_set_source_surface (cr, image, 0, 0);
+ cairo_rectangle (cr, 0, 0, SIZE - OFFSET, SIZE - OFFSET);
+ cairo_fill (cr);
+
+ cairo_surface_destroy (image);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (composite_integer_translate_source,
+ "Test simple compositing: integer-translation 32->32 SOURCE",
+ "composite", /* keywords */
+ NULL, /* requirements */
+ SIZE, SIZE,
+ NULL, draw)
diff --git a/test/copy-disjoint.c b/test/copy-disjoint.c
new file mode 100644
index 000000000..1ddfd5a91
--- /dev/null
+++ b/test/copy-disjoint.c
@@ -0,0 +1,87 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+/* The goal is exercise a bug that existed in the xlib backend, where
+ * it assumed the rectangles generated by rectangular tessallator had
+ * any sorting guarantees.
+ */
+
+#define WIDTH 300
+#define HEIGHT 300
+
+static cairo_surface_t *
+create_source (cairo_surface_t *target)
+{
+ cairo_surface_t *surface;
+ cairo_t *cr;
+
+ surface = cairo_surface_create_similar (target,
+ CAIRO_CONTENT_COLOR,
+ WIDTH, HEIGHT);
+ cr = cairo_create (surface);
+ cairo_surface_destroy (surface);
+
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+ surface = cairo_surface_reference (cairo_get_target (cr));
+ cairo_destroy (cr);
+
+ return surface;
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_surface_t *white;
+ int x;
+
+ /* black background */
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ cairo_paint (cr);
+
+ /* white rectangles */
+ white = create_source (cairo_get_target (cr));
+ cairo_set_source_surface (cr, white, 0, 0);
+ cairo_surface_destroy (white);
+
+ /* blit a set of rectangles that the rectangular tessellator
+ * will not emit sorted. */
+ for (x = 0; x < WIDTH - 10; x += 15)
+ cairo_rectangle (cr, x, x, 10, HEIGHT - 2*x);
+ cairo_fill (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (copy_disjoint,
+ "Tests copying unsorted rectangles.",
+ "fill", /* keywords */
+ NULL, /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw)
diff --git a/test/copy-path.c b/test/copy-path.c
new file mode 100644
index 000000000..25823b6b1
--- /dev/null
+++ b/test/copy-path.c
@@ -0,0 +1,314 @@
+/*
+ * Copyright © 2005 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+#include "cairo-test.h"
+#include <stdlib.h>
+
+static void
+scale_by_two (double *x, double *y)
+{
+ *x = *x * 2.0;
+ *y = *y * 2.0;
+}
+
+typedef void (*munge_func_t) (double *x, double *y);
+
+static void
+munge_and_set_path (cairo_t *cr,
+ cairo_path_t *path,
+ munge_func_t munge)
+{
+ int i;
+ cairo_path_data_t *p;
+ double x1, y1, x2, y2, x3, y3;
+
+ if (path->status) {
+ cairo_append_path (cr, path);
+ return;
+ }
+
+ for (i=0; i < path->num_data; i += path->data[i].header.length) {
+ p = &path->data[i];
+ switch (p->header.type) {
+ case CAIRO_PATH_MOVE_TO:
+ x1 = p[1].point.x; y1 = p[1].point.y;
+ (munge) (&x1, &y1);
+ cairo_move_to (cr, x1, y1);
+ break;
+ case CAIRO_PATH_LINE_TO:
+ x1 = p[1].point.x; y1 = p[1].point.y;
+ (munge) (&x1, &y1);
+ cairo_line_to (cr, x1, y1);
+ break;
+ case CAIRO_PATH_CURVE_TO:
+ x1 = p[1].point.x; y1 = p[1].point.y;
+ x2 = p[2].point.x; y2 = p[2].point.y;
+ x3 = p[3].point.x; y3 = p[3].point.y;
+ (munge) (&x1, &y1);
+ (munge) (&x2, &y2);
+ (munge) (&x3, &y3);
+ cairo_curve_to (cr,
+ x1, y1,
+ x2, y2,
+ x3, y3);
+ break;
+ case CAIRO_PATH_CLOSE_PATH:
+ cairo_close_path (cr);
+ break;
+ }
+ }
+}
+
+static void
+make_path (cairo_t *cr)
+{
+ cairo_rectangle (cr, 0, 0, 5, 5);
+ cairo_move_to (cr, 15, 2.5);
+ cairo_arc (cr, 12.5, 2.5, 2.5, 0, 2 * M_PI);
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ const cairo_test_context_t *ctx = cairo_test_get_context (cr);
+ cairo_path_t *path;
+ cairo_t *cr_error;
+
+ /* Ensure that calling cairo_copy_path on an in-error cairo_t will
+ * propagate the error. */
+ cr_error = cairo_create (NULL);
+ path = cairo_copy_path (cr_error);
+ if (path->status != CAIRO_STATUS_NULL_POINTER) {
+ cairo_test_log (ctx,
+ "Error: cairo_copy_path returned status of %s rather than propagating %s\n",
+ cairo_status_to_string (path->status),
+ cairo_status_to_string (CAIRO_STATUS_NULL_POINTER));
+ cairo_path_destroy (path);
+ cairo_destroy (cr_error);
+ return CAIRO_TEST_FAILURE;
+ }
+ cairo_path_destroy (path);
+
+ path = cairo_copy_path_flat (cr_error);
+ if (path->status != CAIRO_STATUS_NULL_POINTER) {
+ cairo_test_log (ctx,
+ "Error: cairo_copy_path_flat returned status of %s rather than propagating %s\n",
+ cairo_status_to_string (path->status),
+ cairo_status_to_string (CAIRO_STATUS_NULL_POINTER));
+ cairo_path_destroy (path);
+ cairo_destroy (cr_error);
+ return CAIRO_TEST_FAILURE;
+ }
+ cairo_path_destroy (path);
+
+ cairo_destroy (cr_error);
+
+ /* first check that we can copy an empty path */
+ cairo_new_path (cr);
+ path = cairo_copy_path (cr);
+ if (path->status != CAIRO_STATUS_SUCCESS) {
+ cairo_status_t status = path->status;
+ cairo_test_log (ctx,
+ "Error: cairo_copy_path returned status of %s\n",
+ cairo_status_to_string (status));
+ cairo_path_destroy (path);
+ return cairo_test_status_from_status (ctx, status);
+ }
+ if (path->num_data != 0) {
+ cairo_test_log (ctx,
+ "Error: cairo_copy_path did not copy an empty path, returned path contains %d elements\n",
+ path->num_data);
+ cairo_path_destroy (path);
+ return CAIRO_TEST_FAILURE;
+ }
+ cairo_append_path (cr, path);
+ cairo_path_destroy (path);
+ if (cairo_status (cr) != CAIRO_STATUS_SUCCESS) {
+ cairo_test_log (ctx,
+ "Error: cairo_append_path failed with a copy of an empty path, returned status of %s\n",
+ cairo_status_to_string (cairo_status (cr)));
+ return cairo_test_status_from_status (ctx, cairo_status (cr));
+ }
+
+ /* We draw in the default black, so paint white first. */
+ cairo_save (cr);
+ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */
+ cairo_paint (cr);
+ cairo_restore (cr);
+
+ /* copy path, munge, and fill */
+ cairo_translate (cr, 5, 5);
+ make_path (cr);
+ path = cairo_copy_path (cr);
+
+ cairo_new_path (cr);
+ munge_and_set_path (cr, path, scale_by_two);
+ cairo_path_destroy (path);
+ cairo_fill (cr);
+
+ /* copy flattened path, munge, and fill */
+ cairo_translate (cr, 0, 15);
+ make_path (cr);
+ path = cairo_copy_path_flat (cr);
+
+ cairo_new_path (cr);
+ munge_and_set_path (cr, path, scale_by_two);
+ cairo_path_destroy (path);
+ cairo_fill (cr);
+
+ /* append two copies of path, and fill */
+ cairo_translate (cr, 0, 15);
+ cairo_scale (cr, 2.0, 2.0);
+ make_path (cr);
+ path = cairo_copy_path (cr);
+
+ cairo_new_path (cr);
+ cairo_append_path (cr, path);
+ cairo_translate (cr, 2.5, 2.5);
+ cairo_append_path (cr, path);
+
+ cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
+ cairo_fill (cr);
+
+ cairo_path_destroy (path);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+preamble (cairo_test_context_t *ctx)
+{
+ cairo_t *cr;
+ cairo_path_data_t data;
+ cairo_path_t path;
+ cairo_surface_t *surface;
+ cairo_status_t status;
+
+ surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 1, 1);
+ status = cairo_surface_status (surface);
+ if (status) {
+ cairo_surface_destroy (surface);
+ return cairo_test_status_from_status (ctx, status);
+ }
+
+ /* Test a few error cases for cairo_append_path_data */
+#define CAIRO_CREATE() do {\
+ cr = cairo_create (surface); \
+ status = cairo_status (cr); \
+ if (status) { \
+ cairo_destroy (cr); \
+ cairo_surface_destroy (surface); \
+ return cairo_test_status_from_status (ctx, status); \
+ } \
+} while (0)
+ CAIRO_CREATE ();
+ cairo_append_path (cr, NULL);
+ status = cairo_status (cr);
+ cairo_destroy (cr);
+ if (status != CAIRO_STATUS_NULL_POINTER) {
+ cairo_surface_destroy (surface);
+ return cairo_test_status_from_status (ctx, status);
+ }
+
+ CAIRO_CREATE ();
+ path.status = -1;
+ cairo_append_path (cr, &path);
+ status = cairo_status (cr);
+ cairo_destroy (cr);
+ if (status != CAIRO_STATUS_INVALID_STATUS) {
+ cairo_surface_destroy (surface);
+ return cairo_test_status_from_status (ctx, status);
+ }
+
+ CAIRO_CREATE ();
+ path.status = CAIRO_STATUS_NO_MEMORY;
+ cairo_append_path (cr, &path);
+ status = cairo_status (cr);
+ cairo_destroy (cr);
+ if (status != CAIRO_STATUS_NO_MEMORY) {
+ cairo_surface_destroy (surface);
+ return cairo_test_status_from_status (ctx, status);
+ }
+
+ CAIRO_CREATE ();
+ path.data = NULL;
+ path.num_data = 0;
+ path.status = CAIRO_STATUS_SUCCESS;
+ cairo_append_path (cr, &path);
+ status = cairo_status (cr);
+ cairo_destroy (cr);
+ if (status != CAIRO_STATUS_SUCCESS) {
+ cairo_surface_destroy (surface);
+ return cairo_test_status_from_status (ctx, status);
+ }
+
+ CAIRO_CREATE ();
+ path.data = NULL;
+ path.num_data = 1;
+ path.status = CAIRO_STATUS_SUCCESS;
+ cairo_append_path (cr, &path);
+ status = cairo_status (cr);
+ cairo_destroy (cr);
+ if (status != CAIRO_STATUS_NULL_POINTER) {
+ cairo_surface_destroy (surface);
+ return cairo_test_status_from_status (ctx, status);
+ }
+
+ CAIRO_CREATE ();
+ /* Intentionally insert bogus header.length value (otherwise would be 2) */
+ data.header.type = CAIRO_PATH_MOVE_TO;
+ data.header.length = 1;
+ path.data = &data;
+ path.num_data = 1;
+ cairo_append_path (cr, &path);
+ status = cairo_status (cr);
+ cairo_destroy (cr);
+ if (status != CAIRO_STATUS_INVALID_PATH_DATA) {
+ cairo_surface_destroy (surface);
+ return cairo_test_status_from_status (ctx, status);
+ }
+
+ /* And test the degnerate case */
+ CAIRO_CREATE ();
+ path.num_data = 0;
+ cairo_append_path (cr, &path);
+ status = cairo_status (cr);
+ cairo_destroy (cr);
+ if (status != CAIRO_STATUS_SUCCESS) {
+ cairo_surface_destroy (surface);
+ return cairo_test_status_from_status (ctx, status);
+ }
+
+ cairo_surface_destroy (surface);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (copy_path,
+ "Tests calls to path_data functions: cairo_copy_path, cairo_copy_path_flat, and cairo_append_path",
+ "path", /* keywords */
+ NULL, /* requirements */
+ 45, 53,
+ preamble, draw)
diff --git a/test/coverage.c b/test/coverage.c
new file mode 100644
index 000000000..12225c325
--- /dev/null
+++ b/test/coverage.c
@@ -0,0 +1,506 @@
+/*
+ * Copyright 2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+/* Test the fidelity of the rasterisation, because Cairo is my favourite
+ * driver test suite.
+ */
+
+#define GENERATE_REFERENCE 0
+
+#define WIDTH 256
+#define HEIGHT 40
+
+#include "../src/cairo-fixed-type-private.h"
+#define PRECISION (1 << CAIRO_FIXED_FRAC_BITS)
+
+/* XXX beware multithreading! */
+static uint32_t state;
+
+static uint32_t
+hars_petruska_f54_1_random (void)
+{
+#define rol(x,k) ((x << k) | (x >> (32-k)))
+ return state = (state ^ rol (state, 5) ^ rol (state, 24)) + 0x37798849;
+#undef rol
+}
+
+static double
+random_offset (int range, int precise)
+{
+ double x = hars_petruska_f54_1_random() / (double) UINT32_MAX * range / WIDTH;
+ if (precise)
+ x = floor (x * PRECISION) / PRECISION;
+ return x;
+}
+
+static cairo_test_status_t
+rectangles (cairo_t *cr, int width, int height)
+{
+ int x, y, channel;
+
+ state = 0x12345678;
+
+ cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
+ cairo_paint (cr);
+
+#if GENERATE_REFERENCE
+ for (x = 0; x < WIDTH; x++) {
+ cairo_set_source_rgba (cr, 1, 1, 1, x * x * 1.0 / (WIDTH * WIDTH));
+ cairo_rectangle (cr, x, 0, 1, HEIGHT);
+ cairo_fill (cr);
+ }
+#else
+ cairo_set_operator (cr, CAIRO_OPERATOR_ADD);
+ for (channel = 0; channel < 3; channel++) {
+ switch (channel) {
+ default:
+ case 0: cairo_set_source_rgb (cr, 1.0, 0.0, 0.0); break;
+ case 1: cairo_set_source_rgb (cr, 0.0, 1.0, 0.0); break;
+ case 2: cairo_set_source_rgb (cr, 0.0, 0.0, 1.0); break;
+ }
+
+ for (x = 0; x < WIDTH; x++) {
+ for (y = 0; y < HEIGHT; y++) {
+ double dx = random_offset (WIDTH - x, TRUE);
+ double dy = random_offset (WIDTH - x, TRUE);
+ cairo_rectangle (cr, x + dx, y + dy, x / (double) WIDTH, x / (double) WIDTH);
+ }
+ }
+ cairo_fill (cr);
+ }
+#endif
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+rhombus (cairo_t *cr, int width, int height)
+{
+ int x, y;
+
+ cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
+ cairo_paint (cr);
+
+#if GENERATE_REFERENCE
+ for (y = 0; y < WIDTH; y++) {
+ for (x = 0; x < WIDTH; x++) {
+ cairo_set_source_rgba (cr, 1, 1, 1,
+ x * y / (2. * WIDTH * WIDTH));
+ cairo_rectangle (cr, 2*x, 2*y, 2, 2);
+ cairo_fill (cr);
+ }
+ }
+#else
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+ cairo_set_source_rgb (cr, 1, 1, 1);
+
+ for (y = 0; y < WIDTH; y++) {
+ double yf = y / (double) WIDTH;
+ for (x = 0; x < WIDTH; x++) {
+ double xf = x / (double) WIDTH;
+
+ cairo_move_to (cr,
+ 2*x + 1 - xf,
+ 2*y + 1);
+ cairo_line_to (cr,
+ 2*x + 1,
+ 2*y + 1 - yf);
+ cairo_line_to (cr,
+ 2*x + 1 + xf,
+ 2*y + 1);
+ cairo_line_to (cr,
+ 2*x + 1,
+ 2*y + 1 + yf);
+ cairo_close_path (cr);
+ }
+ }
+
+ cairo_fill (cr);
+#endif
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+intersecting_quads (cairo_t *cr, int width, int height)
+{
+ int x, y, channel;
+
+ state = 0x12345678;
+
+ cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
+ cairo_paint (cr);
+
+#if GENERATE_REFERENCE
+ for (x = 0; x < WIDTH; x++) {
+ cairo_set_source_rgba (cr, 1, 1, 1, x * x * 0.5 / (WIDTH * WIDTH));
+ cairo_rectangle (cr, x, 0, 1, HEIGHT);
+ cairo_fill (cr);
+ }
+#else
+ cairo_set_operator (cr, CAIRO_OPERATOR_ADD);
+ for (channel = 0; channel < 3; channel++) {
+ switch (channel) {
+ default:
+ case 0: cairo_set_source_rgb (cr, 1.0, 0.0, 0.0); break;
+ case 1: cairo_set_source_rgb (cr, 0.0, 1.0, 0.0); break;
+ case 2: cairo_set_source_rgb (cr, 0.0, 0.0, 1.0); break;
+ }
+
+ for (x = 0; x < WIDTH; x++) {
+ double step = x / (double) WIDTH;
+ for (y = 0; y < HEIGHT; y++) {
+ double dx = random_offset (WIDTH - x, TRUE);
+ double dy = random_offset (WIDTH - x, TRUE);
+ cairo_move_to (cr, x + dx, y + dy);
+ cairo_rel_line_to (cr, step, step);
+ cairo_rel_line_to (cr, 0, -step);
+ cairo_rel_line_to (cr, -step, step);
+ cairo_close_path (cr);
+ }
+ }
+ cairo_fill (cr);
+ }
+#endif
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+intersecting_triangles (cairo_t *cr, int width, int height)
+{
+ int x, y, channel;
+
+ state = 0x12345678;
+
+ cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
+ cairo_paint (cr);
+
+#if GENERATE_REFERENCE
+ for (x = 0; x < WIDTH; x++) {
+ cairo_set_source_rgba (cr, 1, 1, 1, x * 0.75 / WIDTH);
+ cairo_rectangle (cr, x, 0, 1, HEIGHT);
+ cairo_fill (cr);
+ }
+#else
+ cairo_set_operator (cr, CAIRO_OPERATOR_ADD);
+ for (channel = 0; channel < 3; channel++) {
+ switch (channel) {
+ default:
+ case 0: cairo_set_source_rgb (cr, 1.0, 0.0, 0.0); break;
+ case 1: cairo_set_source_rgb (cr, 0.0, 1.0, 0.0); break;
+ case 2: cairo_set_source_rgb (cr, 0.0, 0.0, 1.0); break;
+ }
+
+ for (x = 0; x < WIDTH; x++) {
+ double step = x / (double) WIDTH;
+ for (y = 0; y < HEIGHT; y++) {
+ double dx = random_offset (WIDTH - x, TRUE);
+ double dy = random_offset (WIDTH - x, TRUE);
+
+ /* left */
+ cairo_move_to (cr, x + dx, y + dy);
+ cairo_rel_line_to (cr, 0, step);
+ cairo_rel_line_to (cr, step, 0);
+ cairo_close_path (cr);
+
+ /* right, mirrored */
+ cairo_move_to (cr, x + dx + step, y + dy + step);
+ cairo_rel_line_to (cr, 0, -step);
+ cairo_rel_line_to (cr, -step, step);
+ cairo_close_path (cr);
+ }
+ }
+ cairo_fill (cr);
+ }
+#endif
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+triangles (cairo_t *cr, int width, int height)
+{
+ int x, y, channel;
+
+ state = 0x12345678;
+
+ cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
+ cairo_paint (cr);
+
+#if GENERATE_REFERENCE
+ for (x = 0; x < WIDTH; x++) {
+ cairo_set_source_rgba (cr, 1, 1, 1, x * x * 0.5 / (WIDTH * WIDTH));
+ cairo_rectangle (cr, x, 0, 1, HEIGHT);
+ cairo_fill (cr);
+ }
+#else
+ cairo_set_operator (cr, CAIRO_OPERATOR_ADD);
+ for (channel = 0; channel < 3; channel++) {
+ switch (channel) {
+ default:
+ case 0: cairo_set_source_rgb (cr, 1.0, 0.0, 0.0); break;
+ case 1: cairo_set_source_rgb (cr, 0.0, 1.0, 0.0); break;
+ case 2: cairo_set_source_rgb (cr, 0.0, 0.0, 1.0); break;
+ }
+
+ for (x = 0; x < WIDTH; x++) {
+ for (y = 0; y < HEIGHT; y++) {
+ double dx = random_offset (WIDTH - x, TRUE);
+ double dy = random_offset (WIDTH - x, TRUE);
+ cairo_move_to (cr, x + dx, y + dy);
+ cairo_rel_line_to (cr, x / (double) WIDTH, 0);
+ cairo_rel_line_to (cr, 0, x / (double) WIDTH);
+ cairo_close_path (cr);
+ }
+ }
+ cairo_fill (cr);
+ }
+#endif
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+abutting (cairo_t *cr, int width, int height)
+{
+ int x, y;
+
+ cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
+ cairo_paint (cr);
+
+ cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.75);
+
+#if GENERATE_REFERENCE
+ cairo_paint (cr);
+#else
+ cairo_set_operator (cr, CAIRO_OPERATOR_ADD);
+
+ for (y = 0; y < 16; y++) {
+ for (x = 0; x < 16; x++) {
+ double theta = (y * 16 + x) * M_PI / 512;
+ double cx = 16 * cos (theta) + x * 16;
+ double cy = 16 * sin (theta) + y * 16;
+
+ cairo_move_to (cr, x * 16, y * 16);
+ cairo_line_to (cr, cx, cy);
+ cairo_line_to (cr, (x + 1) * 16, y * 16);
+ cairo_fill (cr);
+
+ cairo_move_to (cr, (x + 1) * 16, y * 16);
+ cairo_line_to (cr, cx, cy);
+ cairo_line_to (cr, (x + 1) * 16, (y + 1) * 16);
+ cairo_fill (cr);
+
+ cairo_move_to (cr, (x + 1) * 16, (y + 1) * 16);
+ cairo_line_to (cr, cx, cy);
+ cairo_line_to (cr, x * 16, (y + 1) * 16);
+ cairo_fill (cr);
+
+ cairo_move_to (cr, x * 16, (y + 1) * 16);
+ cairo_line_to (cr, cx, cy);
+ cairo_line_to (cr, x * 16, y * 16);
+ cairo_fill (cr);
+ }
+ }
+#endif
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+column_triangles (cairo_t *cr, int width, int height)
+{
+ int x, y, i, channel;
+
+ state = 0x12345678;
+
+ cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
+ cairo_paint (cr);
+
+#if GENERATE_REFERENCE
+ for (x = 0; x < WIDTH; x++) {
+ cairo_set_source_rgba (cr, 1, 1, 1, x * 0.5 / WIDTH);
+ cairo_rectangle (cr, x, 0, 1, HEIGHT);
+ cairo_fill (cr);
+ }
+#else
+ cairo_set_operator (cr, CAIRO_OPERATOR_ADD);
+ for (channel = 0; channel < 3; channel++) {
+ switch (channel) {
+ default:
+ case 0: cairo_set_source_rgb (cr, 1.0, 0.0, 0.0); break;
+ case 1: cairo_set_source_rgb (cr, 0.0, 1.0, 0.0); break;
+ case 2: cairo_set_source_rgb (cr, 0.0, 0.0, 1.0); break;
+ }
+
+ for (x = 0; x < WIDTH; x++) {
+ double step = x / (double) (2 * WIDTH);
+ for (y = 0; y < HEIGHT; y++) {
+ for (i = 0; i < PRECISION; i++) {
+ double dy = random_offset (WIDTH - x, FALSE);
+
+ /*
+ * We want to test some sharing of edges to further
+ * stress the rasterisers, so instead of using one
+ * tall triangle, it is split into two, with vertical
+ * edges on either side that may co-align with their
+ * neighbours:
+ *
+ * s --- . ---
+ * t | |\ |
+ * e | | \ |
+ * p --- .... | 2 * step = x / WIDTH
+ * \ | |
+ * \| |
+ * . ---
+ * |---|
+ * 1 / PRECISION
+ *
+ * Each column contains two triangles of width one quantum and
+ * total height of (x / WIDTH), thus the total area covered by all
+ * columns in each pixel is .5 * (x / WIDTH).
+ */
+
+ cairo_move_to (cr, x + i / (double) PRECISION, y + dy);
+ cairo_rel_line_to (cr, 0, step);
+ cairo_rel_line_to (cr, 1 / (double) PRECISION, step);
+ cairo_rel_line_to (cr, 0, -step);
+ cairo_close_path (cr);
+ }
+ cairo_fill (cr); /* do these per-pixel due to the extra volume of edges */
+ }
+ }
+ }
+#endif
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+row_triangles (cairo_t *cr, int width, int height)
+{
+ int x, y, i, channel;
+
+ state = 0x12345678;
+
+ cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
+ cairo_paint (cr);
+
+#if GENERATE_REFERENCE
+ for (x = 0; x < WIDTH; x++) {
+ cairo_set_source_rgba (cr, 1, 1, 1, x * 0.5 / WIDTH);
+ cairo_rectangle (cr, x, 0, 1, HEIGHT);
+ cairo_fill (cr);
+ }
+#else
+ cairo_set_operator (cr, CAIRO_OPERATOR_ADD);
+ for (channel = 0; channel < 3; channel++) {
+ switch (channel) {
+ default:
+ case 0: cairo_set_source_rgb (cr, 1.0, 0.0, 0.0); break;
+ case 1: cairo_set_source_rgb (cr, 0.0, 1.0, 0.0); break;
+ case 2: cairo_set_source_rgb (cr, 0.0, 0.0, 1.0); break;
+ }
+
+ for (x = 0; x < WIDTH; x++) {
+ double step = x / (double) (2 * WIDTH);
+ for (y = 0; y < HEIGHT; y++) {
+ for (i = 0; i < PRECISION; i++) {
+ double dx = random_offset (WIDTH - x, FALSE);
+
+ /* See column_triangles() for a transposed description
+ * of this geometry.
+ */
+
+ cairo_move_to (cr, x + dx, y + i / (double) PRECISION);
+ cairo_rel_line_to (cr, step, 0);
+ cairo_rel_line_to (cr, step, 1 / (double) PRECISION);
+ cairo_rel_line_to (cr, -step, 0);
+ cairo_close_path (cr);
+ }
+ cairo_fill (cr); /* do these per-pixel due to the extra volume of edges */
+ }
+ }
+ }
+#endif
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (coverage_rectangles,
+ "Check the fidelity of the rasterisation.",
+ NULL, /* keywords */
+ "target=raster", /* requirements */
+ WIDTH, HEIGHT,
+ NULL, rectangles)
+
+CAIRO_TEST (coverage_rhombus,
+ "Check the fidelity of the rasterisation.",
+ NULL, /* keywords */
+ "target=raster", /* requirements */
+ 2*WIDTH, 2*WIDTH,
+ NULL, rhombus)
+
+CAIRO_TEST (coverage_intersecting_quads,
+ "Check the fidelity of the rasterisation.",
+ NULL, /* keywords */
+ "target=raster", /* requirements */
+ WIDTH, HEIGHT,
+ NULL, intersecting_quads)
+
+CAIRO_TEST (coverage_intersecting_triangles,
+ "Check the fidelity of the rasterisation.",
+ NULL, /* keywords */
+ "target=raster", /* requirements */
+ WIDTH, HEIGHT,
+ NULL, intersecting_triangles)
+CAIRO_TEST (coverage_row_triangles,
+ "Check the fidelity of the rasterisation.",
+ NULL, /* keywords */
+ "target=raster", /* requirements */
+ WIDTH, HEIGHT,
+ NULL, row_triangles)
+CAIRO_TEST (coverage_column_triangles,
+ "Check the fidelity of the rasterisation.",
+ NULL, /* keywords */
+ "target=raster", /* requirements */
+ WIDTH, HEIGHT,
+ NULL, column_triangles)
+CAIRO_TEST (coverage_triangles,
+ "Check the fidelity of the rasterisation.",
+ NULL, /* keywords */
+ "target=raster", /* requirements */
+ WIDTH, HEIGHT,
+ NULL, triangles)
+CAIRO_TEST (coverage_abutting,
+ "Check the fidelity of the rasterisation.",
+ NULL, /* keywords */
+ "target=raster", /* requirements */
+ 16*16, 16*16,
+ NULL, abutting)
diff --git a/test/create-for-stream.c b/test/create-for-stream.c
new file mode 100644
index 000000000..af1632f14
--- /dev/null
+++ b/test/create-for-stream.c
@@ -0,0 +1,311 @@
+/*
+ * Copyright © 2006 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Kristian Høgsberg <krh@redhat.com>
+ */
+
+#include "cairo-test.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#if CAIRO_HAS_PS_SURFACE
+#include <cairo-ps.h>
+#endif
+
+#if CAIRO_HAS_PDF_SURFACE
+#include <cairo-pdf.h>
+#endif
+
+#if CAIRO_HAS_SVG_SURFACE
+#include <cairo-svg.h>
+#endif
+
+#include "cairo-test.h"
+
+/* The main test suite doesn't test the *_create_for_stream
+ * constructors for the PDF, PS and SVG surface, so we do that here.
+ * We draw to an in-memory buffer using the stream constructor and
+ * compare the output to the contents of a file written using the
+ * file constructor.
+ */
+
+#define MAX_OUTPUT_SIZE 4096
+
+#define WIDTH_IN_INCHES 3
+#define HEIGHT_IN_INCHES 3
+#define WIDTH_IN_POINTS (WIDTH_IN_INCHES * 72.0)
+#define HEIGHT_IN_POINTS (HEIGHT_IN_INCHES * 72.0)
+
+#define BASENAME "create-for-stream.out"
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ /* Just draw a rectangle. */
+
+ cairo_rectangle (cr, width / 10., height /10.,
+ width - 2 * width / 10.,
+ height - 2 * height /10.);
+ cairo_fill (cr);
+
+ cairo_show_page (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static void
+draw_to (cairo_surface_t *surface)
+{
+ cairo_t *cr;
+
+ cr = cairo_create (surface);
+
+ draw (cr, WIDTH_IN_POINTS, HEIGHT_IN_POINTS);
+
+ cairo_destroy (cr);
+}
+
+typedef struct _write_closure {
+ const cairo_test_context_t *ctx;
+ char buffer[MAX_OUTPUT_SIZE];
+ size_t index;
+ cairo_test_status_t status;
+} write_closure_t;
+
+static cairo_status_t
+bad_write (void *closure,
+ const unsigned char *data,
+ unsigned int length)
+{
+ return CAIRO_STATUS_WRITE_ERROR;
+}
+
+static cairo_status_t
+test_write (void *closure,
+ const unsigned char *data,
+ unsigned int length)
+{
+ write_closure_t *wc = closure;
+
+ if (wc->index + length >= sizeof wc->buffer) {
+ cairo_test_log (wc->ctx, "Error: out of bounds in write callback\n");
+ wc->status = CAIRO_TEST_FAILURE;
+ return CAIRO_STATUS_SUCCESS;
+ }
+
+ memcpy (&wc->buffer[wc->index], data, length);
+ wc->index += length;
+
+ return CAIRO_STATUS_SUCCESS;
+}
+
+
+typedef cairo_surface_t *
+(*file_constructor_t) (const char *filename,
+ double width_in_points,
+ double height_in_points);
+
+typedef cairo_surface_t *
+(*stream_constructor_t) (cairo_write_func_t write_func,
+ void *closure,
+ double width_in_points,
+ double height_in_points);
+
+static cairo_test_status_t
+test_surface (const cairo_test_context_t *ctx,
+ const char *backend,
+ const char *filename,
+ file_constructor_t file_constructor,
+ stream_constructor_t stream_constructor)
+{
+ cairo_surface_t *surface;
+ write_closure_t wc;
+ char file_contents[MAX_OUTPUT_SIZE];
+ cairo_status_t status;
+ FILE *fp;
+
+ /* test propagation of user errors */
+ surface = stream_constructor (bad_write, &wc,
+ WIDTH_IN_POINTS, HEIGHT_IN_POINTS);
+
+ status = cairo_surface_status (surface);
+ if (status) {
+ cairo_test_log (ctx,
+ "%s: Failed to create surface for stream.\n",
+ backend);
+ return CAIRO_TEST_FAILURE;
+ }
+
+ draw_to (surface);
+
+ cairo_surface_finish (surface);
+ status = cairo_surface_status (surface);
+ cairo_surface_destroy (surface);
+
+ if (status != CAIRO_STATUS_WRITE_ERROR) {
+ cairo_test_log (ctx,
+ "%s: Error: expected \"write error\", but received \"%s\".\n",
+ backend, cairo_status_to_string (status));
+ return CAIRO_TEST_FAILURE;
+ }
+
+ /* construct the real surface */
+ wc.ctx = ctx;
+ wc.status = CAIRO_TEST_SUCCESS;
+ wc.index = 0;
+
+ surface = stream_constructor (test_write, &wc,
+ WIDTH_IN_POINTS, HEIGHT_IN_POINTS);
+
+ status = cairo_surface_status (surface);
+ if (status) {
+ cairo_test_log (ctx,
+ "%s: Failed to create surface for stream.\n", backend);
+ return CAIRO_TEST_FAILURE;
+ }
+
+ draw_to (surface);
+
+ cairo_surface_destroy (surface);
+
+ if (wc.status != CAIRO_TEST_SUCCESS) {
+ /* Error already reported. */
+ return wc.status;
+ }
+
+ surface = file_constructor (filename,
+ WIDTH_IN_POINTS, HEIGHT_IN_POINTS);
+
+ status = cairo_surface_status (surface);
+ if (status) {
+ cairo_test_log (ctx, "%s: Failed to create surface for file %s: %s.\n",
+ backend, filename, cairo_status_to_string (status));
+ return CAIRO_TEST_FAILURE;
+ }
+
+ draw_to (surface);
+
+ cairo_surface_destroy (surface);
+
+ fp = fopen (filename, "r");
+ if (fp == NULL) {
+ cairo_test_log (ctx, "%s: Failed to open %s for reading: %s.\n",
+ backend, filename, strerror (errno));
+ return CAIRO_TEST_FAILURE;
+ }
+
+ if (fread (file_contents, 1, wc.index, fp) != wc.index) {
+ cairo_test_log (ctx, "%s: Failed to read %s: %s.\n",
+ backend, filename, strerror (errno));
+ fclose (fp);
+ return CAIRO_TEST_FAILURE;
+ }
+
+ if (memcmp (file_contents, wc.buffer, wc.index) != 0) {
+ cairo_test_log (ctx, "%s: Stream based output differ from file output for %s.\n",
+ backend, filename);
+ fclose (fp);
+ return CAIRO_TEST_FAILURE;
+ }
+
+ fclose (fp);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+preamble (cairo_test_context_t *ctx)
+{
+ cairo_test_status_t status = CAIRO_TEST_UNTESTED;
+ cairo_test_status_t test_status;
+ char *filename;
+ const char *path = cairo_test_mkdir (CAIRO_TEST_OUTPUT_DIR) ? CAIRO_TEST_OUTPUT_DIR : ".";
+
+#if CAIRO_HAS_PS_SURFACE
+ if (cairo_test_is_target_enabled (ctx, "ps2") ||
+ cairo_test_is_target_enabled (ctx, "ps3"))
+ {
+ if (status == CAIRO_TEST_UNTESTED)
+ status = CAIRO_TEST_SUCCESS;
+
+ xasprintf (&filename, "%s/%s", path, BASENAME ".ps");
+ test_status = test_surface (ctx, "ps", filename,
+ cairo_ps_surface_create,
+ cairo_ps_surface_create_for_stream);
+ cairo_test_log (ctx, "TEST: %s TARGET: %s RESULT: %s\n",
+ ctx->test->name, "ps",
+ test_status ? "FAIL" : "PASS");
+ if (status == CAIRO_TEST_SUCCESS)
+ status = test_status;
+ free (filename);
+ }
+#endif
+
+#if CAIRO_HAS_PDF_SURFACE
+ if (cairo_test_is_target_enabled (ctx, "pdf")) {
+ if (status == CAIRO_TEST_UNTESTED)
+ status = CAIRO_TEST_SUCCESS;
+
+ xasprintf (&filename, "%s/%s", path, BASENAME ".pdf");
+ test_status = test_surface (ctx, "pdf", filename,
+ cairo_pdf_surface_create,
+ cairo_pdf_surface_create_for_stream);
+ cairo_test_log (ctx, "TEST: %s TARGET: %s RESULT: %s\n",
+ ctx->test->name, "pdf",
+ test_status ? "FAIL" : "PASS");
+ if (status == CAIRO_TEST_SUCCESS)
+ status = test_status;
+ free (filename);
+ }
+#endif
+
+#if CAIRO_HAS_SVG_SURFACE
+ if (cairo_test_is_target_enabled (ctx, "svg11") ||
+ cairo_test_is_target_enabled (ctx, "svg12"))
+ {
+ if (status == CAIRO_TEST_UNTESTED)
+ status = CAIRO_TEST_SUCCESS;
+
+ xasprintf (&filename, "%s/%s", path, BASENAME ".svg");
+ test_status = test_surface (ctx, "svg", filename,
+ cairo_svg_surface_create,
+ cairo_svg_surface_create_for_stream);
+ cairo_test_log (ctx, "TEST: %s TARGET: %s RESULT: %s\n",
+ ctx->test->name, "svg",
+ test_status ? "FAIL" : "PASS");
+ if (status == CAIRO_TEST_SUCCESS)
+ status = test_status;
+ free (filename);
+ }
+#endif
+
+ return status;
+}
+
+CAIRO_TEST (create_for_stream,
+ "Checks creating vector surfaces with user defined I/O\n",
+ "stream", /* keywords */
+ "target=vector", /* requirements */
+ 0, 0,
+ preamble, NULL)
diff --git a/test/create-from-png-stream.c b/test/create-from-png-stream.c
new file mode 100644
index 000000000..2e9eeeeac
--- /dev/null
+++ b/test/create-from-png-stream.c
@@ -0,0 +1,119 @@
+/*
+ * Copyright © 2005 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl Worth <cworth@cworth.org>
+ */
+
+#include "cairo-test.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+
+#define WIDTH 2
+#define HEIGHT 2
+
+static cairo_status_t
+read_png_from_file (void *closure, unsigned char *data, unsigned int length)
+{
+ FILE *file = closure;
+ size_t bytes_read;
+
+ bytes_read = fread (data, 1, length, file);
+ if (bytes_read != length)
+ return CAIRO_STATUS_READ_ERROR;
+
+ return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ const cairo_test_context_t *ctx = cairo_test_get_context (cr);
+ char *filename;
+ FILE *file;
+ cairo_surface_t *surface;
+ cairo_status_t status;
+
+ xasprintf (&filename, "%s/reference/%s", ctx->srcdir,
+ "create-from-png-stream.ref.png");
+
+ file = fopen (filename, "rb");
+ if (file == NULL) {
+ cairo_test_status_t ret;
+
+ ret = CAIRO_TEST_FAILURE;
+ if (errno == ENOMEM)
+ ret = cairo_test_status_from_status (ctx, CAIRO_STATUS_NO_MEMORY);
+
+ if (ret != CAIRO_TEST_NO_MEMORY)
+ cairo_test_log (ctx, "Error: failed to open file: %s\n", filename);
+
+ free (filename);
+ return ret;
+ }
+
+ surface = cairo_image_surface_create_from_png_stream (read_png_from_file,
+ file);
+
+ fclose (file);
+
+ status = cairo_surface_status (surface);
+ if (status) {
+ cairo_test_status_t ret;
+
+ cairo_surface_destroy (surface);
+
+ ret = cairo_test_status_from_status (ctx, status);
+ if (ret != CAIRO_TEST_NO_MEMORY) {
+ cairo_test_log (ctx,
+ "Error: failed to create surface from PNG: %s - %s\n",
+ filename,
+ cairo_status_to_string (status));
+ }
+
+ free (filename);
+
+ return ret;
+ }
+
+ free (filename);
+
+ /* Pretend we modify the surface data (which detaches the PNG mime data) */
+ cairo_surface_flush (surface);
+ cairo_surface_mark_dirty (surface);
+
+ cairo_set_source_surface (cr, surface, 0, 0);
+ cairo_pattern_set_filter (cairo_get_source (cr), CAIRO_FILTER_NEAREST);
+ cairo_paint (cr);
+
+ cairo_surface_destroy (surface);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (create_from_png_stream,
+ "Tests the creation of an image surface from a PNG using a FILE *",
+ "png", /* keywords */
+ NULL, /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw)
diff --git a/test/create-from-png.c b/test/create-from-png.c
new file mode 100644
index 000000000..2ca1fa2c0
--- /dev/null
+++ b/test/create-from-png.c
@@ -0,0 +1,320 @@
+/*
+ * Copyright © 2005 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl Worth <cworth@cworth.org>
+ */
+
+#include "cairo-test.h"
+
+#include <stdlib.h>
+
+#define WIDTH 2
+#define HEIGHT 2
+
+static cairo_status_t
+no_memory_error (void *closure, unsigned char *data, unsigned int size)
+{
+ return CAIRO_STATUS_NO_MEMORY;
+}
+
+static cairo_status_t
+read_error (void *closure, unsigned char *data, unsigned int size)
+{
+ return CAIRO_STATUS_READ_ERROR;
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ const cairo_test_context_t *ctx = cairo_test_get_context (cr);
+ char *filename;
+ cairo_surface_t *surface;
+
+ xasprintf (&filename, "%s/reference/%s",
+ ctx->srcdir, "create-from-png.ref.png");
+
+ surface = cairo_image_surface_create_from_png (filename);
+ if (cairo_surface_status (surface)) {
+ cairo_test_status_t result;
+
+ result = cairo_test_status_from_status (ctx,
+ cairo_surface_status (surface));
+ if (result == CAIRO_TEST_FAILURE) {
+ cairo_test_log (ctx, "Error reading PNG image %s: %s\n",
+ filename,
+ cairo_status_to_string (cairo_surface_status (surface)));
+ }
+
+ free (filename);
+ return result;
+ }
+
+ /* Pretend we modify the surface data (which detaches the PNG mime data) */
+ cairo_surface_flush (surface);
+ cairo_surface_mark_dirty (surface);
+
+ cairo_set_source_surface (cr, surface, 0, 0);
+ cairo_pattern_set_filter (cairo_get_source (cr), CAIRO_FILTER_NEAREST);
+ cairo_paint (cr);
+
+ cairo_surface_destroy (surface);
+
+ free (filename);
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+preamble (cairo_test_context_t *ctx)
+{
+ char *filename;
+ char *path;
+ cairo_surface_t *surface;
+ cairo_status_t status;
+ cairo_test_status_t result = CAIRO_TEST_SUCCESS;
+
+ surface = cairo_image_surface_create_from_png ("___THIS_FILE_DOES_NOT_EXIST___");
+ if (cairo_surface_status (surface) != CAIRO_STATUS_FILE_NOT_FOUND) {
+ result = cairo_test_status_from_status (ctx,
+ cairo_surface_status (surface));
+ if (result == CAIRO_TEST_FAILURE) {
+ cairo_test_log (ctx, "Error: expected \"file not found\", but got: %s\n",
+ cairo_status_to_string (cairo_surface_status (surface)));
+ }
+ }
+ cairo_surface_destroy (surface);
+ if (result != CAIRO_TEST_SUCCESS)
+ return result;
+
+ surface = cairo_image_surface_create_from_png_stream (no_memory_error, NULL);
+ if (cairo_surface_status (surface) != CAIRO_STATUS_NO_MEMORY) {
+ result = cairo_test_status_from_status (ctx,
+ cairo_surface_status (surface));
+ if (result == CAIRO_TEST_FAILURE) {
+ cairo_test_log (ctx, "Error: expected \"out of memory\", but got: %s\n",
+ cairo_status_to_string (cairo_surface_status (surface)));
+ }
+ }
+ cairo_surface_destroy (surface);
+ if (result != CAIRO_TEST_SUCCESS)
+ return result;
+
+ surface = cairo_image_surface_create_from_png_stream (read_error, NULL);
+ if (cairo_surface_status (surface) != CAIRO_STATUS_READ_ERROR) {
+ result = cairo_test_status_from_status (ctx,
+ cairo_surface_status (surface));
+ if (result == CAIRO_TEST_FAILURE) {
+ cairo_test_log (ctx, "Error: expected \"read error\", but got: %s\n",
+ cairo_status_to_string (cairo_surface_status (surface)));
+ }
+ }
+ cairo_surface_destroy (surface);
+ if (result != CAIRO_TEST_SUCCESS)
+ return result;
+
+ /* cheekily test error propagation from the user write funcs as well ... */
+ xasprintf (&path, "%s/reference", ctx->srcdir);
+ xasprintf (&filename, "%s/%s", path, "create-from-png.ref.png");
+
+ surface = cairo_image_surface_create_from_png (filename);
+ if (cairo_surface_status (surface)) {
+ result = cairo_test_status_from_status (ctx,
+ cairo_surface_status (surface));
+ if (result == CAIRO_TEST_FAILURE) {
+ cairo_test_log (ctx, "Error reading PNG image %s: %s\n",
+ filename,
+ cairo_status_to_string (cairo_surface_status (surface)));
+ }
+ } else {
+ status = cairo_surface_write_to_png_stream (surface,
+ (cairo_write_func_t) no_memory_error,
+ NULL);
+ if (status != CAIRO_STATUS_NO_MEMORY) {
+ result = cairo_test_status_from_status (ctx, status);
+ if (result == CAIRO_TEST_FAILURE) {
+ cairo_test_log (ctx, "Error: expected \"out of memory\", but got: %s\n",
+ cairo_status_to_string (status));
+ }
+ }
+
+ status = cairo_surface_write_to_png_stream (surface,
+ (cairo_write_func_t) read_error,
+ NULL);
+ if (status != CAIRO_STATUS_READ_ERROR) {
+ result = cairo_test_status_from_status (ctx, status);
+ if (result == CAIRO_TEST_FAILURE) {
+ cairo_test_log (ctx, "Error: expected \"read error\", but got: %s\n",
+ cairo_status_to_string (status));
+ }
+ }
+
+ /* and check that error has not propagated to the surface */
+ if (cairo_surface_status (surface)) {
+ result = cairo_test_status_from_status (ctx,
+ cairo_surface_status (surface));
+ if (result == CAIRO_TEST_FAILURE) {
+ cairo_test_log (ctx, "Error: user write error propagated to surface: %s",
+ cairo_status_to_string (cairo_surface_status (surface)));
+ }
+ }
+ }
+ cairo_surface_destroy (surface);
+ free (filename);
+ if (result != CAIRO_TEST_SUCCESS)
+ return result;
+
+ /* check that loading alpha/opaque PNGs generate the correct surfaces */
+ /* TODO: Avoid using target-specific references as sample images */
+ xasprintf (&filename, "%s/%s", path, "create-from-png.alpha.ref.png");
+ surface = cairo_image_surface_create_from_png (filename);
+ if (cairo_surface_status (surface)) {
+ result = cairo_test_status_from_status (ctx,
+ cairo_surface_status (surface));
+ if (result == CAIRO_TEST_FAILURE) {
+ cairo_test_log (ctx, "Error reading PNG image %s: %s\n",
+ filename,
+ cairo_status_to_string (cairo_surface_status (surface)));
+ }
+ } else if (cairo_image_surface_get_format (surface) != CAIRO_FORMAT_ARGB32) {
+ cairo_test_log (ctx, "Error reading PNG image %s: did not create an ARGB32 image\n",
+ filename);
+ result = CAIRO_TEST_FAILURE;
+ }
+ free (filename);
+ cairo_surface_destroy (surface);
+ if (result != CAIRO_TEST_SUCCESS)
+ return result;
+
+ xasprintf (&filename, "%s/%s", path, "create-from-png.ref.png");
+ surface = cairo_image_surface_create_from_png (filename);
+ if (cairo_surface_status (surface)) {
+ result = cairo_test_status_from_status (ctx,
+ cairo_surface_status (surface));
+ if (result == CAIRO_TEST_FAILURE) {
+ cairo_test_log (ctx, "Error reading PNG image %s: %s\n",
+ filename,
+ cairo_status_to_string (cairo_surface_status (surface)));
+ }
+ } else if (cairo_image_surface_get_format (surface) != CAIRO_FORMAT_RGB24) {
+ cairo_test_log (ctx, "Error reading PNG image %s: did not create an RGB24 image\n",
+ filename);
+ result = CAIRO_TEST_FAILURE;
+ }
+ free (filename);
+ cairo_surface_destroy (surface);
+ if (result != CAIRO_TEST_SUCCESS)
+ return result;
+
+ /* check paletted PNGs */
+ /* TODO: Avoid using target-specific references as sample images */
+ xasprintf (&filename, "%s/%s", path, "create-from-png.indexed-alpha.ref.png");
+ surface = cairo_image_surface_create_from_png (filename);
+ if (cairo_surface_status (surface)) {
+ result = cairo_test_status_from_status (ctx,
+ cairo_surface_status (surface));
+ if (result == CAIRO_TEST_FAILURE) {
+ cairo_test_log (ctx, "Error reading PNG image %s: %s\n",
+ filename,
+ cairo_status_to_string (cairo_surface_status (surface)));
+ }
+ } else if (cairo_image_surface_get_format (surface) != CAIRO_FORMAT_ARGB32) {
+ cairo_test_log (ctx, "Error reading PNG image %s: did not create an ARGB32 image\n",
+ filename);
+ result = CAIRO_TEST_FAILURE;
+ }
+ free (filename);
+ cairo_surface_destroy (surface);
+ if (result != CAIRO_TEST_SUCCESS)
+ return result;
+
+ /* TODO: Avoid using target-specific references as sample images */
+ xasprintf (&filename, "%s/%s", path, "create-from-png.indexed.ref.png");
+ surface = cairo_image_surface_create_from_png (filename);
+ if (cairo_surface_status (surface)) {
+ result = cairo_test_status_from_status (ctx,
+ cairo_surface_status (surface));
+ if (result == CAIRO_TEST_FAILURE) {
+ cairo_test_log (ctx, "Error reading PNG image %s: %s\n",
+ filename,
+ cairo_status_to_string (cairo_surface_status (surface)));
+ }
+ } else if (cairo_image_surface_get_format (surface) != CAIRO_FORMAT_RGB24) {
+ cairo_test_log (ctx, "Error reading PNG image %s: did not create an RGB24 image\n",
+ filename);
+ result = CAIRO_TEST_FAILURE;
+ }
+ free (filename);
+ cairo_surface_destroy (surface);
+ if (result != CAIRO_TEST_SUCCESS)
+ return result;
+
+ /* check grayscale PNGs */
+ /* TODO: Avoid using target-specific references as sample images */
+ xasprintf (&filename, "%s/%s", path, "create-from-png.gray-alpha.ref.png");
+ surface = cairo_image_surface_create_from_png (filename);
+ if (cairo_surface_status (surface)) {
+ result = cairo_test_status_from_status (ctx,
+ cairo_surface_status (surface));
+ if (result == CAIRO_TEST_FAILURE) {
+ cairo_test_log (ctx, "Error reading PNG image %s: %s\n",
+ filename,
+ cairo_status_to_string (cairo_surface_status (surface)));
+ }
+ } else if (cairo_image_surface_get_format (surface) != CAIRO_FORMAT_ARGB32) {
+ cairo_test_log (ctx, "Error reading PNG image %s: did not create an ARGB32 image\n",
+ filename);
+ result = CAIRO_TEST_FAILURE;
+ }
+ free (filename);
+ cairo_surface_destroy (surface);
+ if (result != CAIRO_TEST_SUCCESS)
+ return result;
+
+ /* TODO: Avoid using target-specific references as sample images */
+ xasprintf (&filename, "%s/%s", path, "create-from-png.gray.ref.png");
+ surface = cairo_image_surface_create_from_png (filename);
+ if (cairo_surface_status (surface)) {
+ result = cairo_test_status_from_status (ctx,
+ cairo_surface_status (surface));
+ if (result == CAIRO_TEST_FAILURE) {
+ cairo_test_log (ctx, "Error reading PNG image %s: %s\n",
+ filename,
+ cairo_status_to_string (cairo_surface_status (surface)));
+ }
+ } else if (cairo_image_surface_get_format (surface) != CAIRO_FORMAT_RGB24) {
+ cairo_test_log (ctx, "Error reading PNG image %s: did not create an RGB24 image\n",
+ filename);
+ result = CAIRO_TEST_FAILURE;
+ }
+ free (filename);
+ cairo_surface_destroy (surface);
+
+ free (path);
+
+ return result;
+}
+
+CAIRO_TEST (create_from_png,
+ "Tests the creation of an image surface from a PNG file",
+ "png", /* keywords */
+ NULL, /* requirements */
+ WIDTH, HEIGHT,
+ preamble, draw)
diff --git a/test/culled-glyphs.c b/test/culled-glyphs.c
new file mode 100644
index 000000000..28bee7e8c
--- /dev/null
+++ b/test/culled-glyphs.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2008 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Chris Wilson not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Chris Wilson makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ const char *text =
+"This needs to be a very long string, wider than the surface, and yet wider."
+"Ideally it should overflow the stack buffers, but do you really want to read "
+"a message that long. No. So we compromise with around 300 glyphs that is "
+"long enough to trigger the conditions as stated in "
+"http://lists.cairographics.org/archives/cairo/2008-December/015976.html. "
+"Happy now?";
+ cairo_text_extents_t extents;
+
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+ cairo_set_source_rgb (cr, 0, 0, 0);
+
+ cairo_set_font_size (cr, 16);
+ cairo_text_extents (cr, text, &extents);
+ cairo_move_to (cr, -extents.width/2, 18);
+ cairo_show_text (cr, text);
+
+ /* XXX we should exercise cairo_show_text_glyphs() as well,
+ * and CAIRO_TEXT_CLUSTER_BACKWARDS
+ */
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (culled_glyphs,
+ "Tests culling of glyphs and text clusters",
+ "glyphs", /* keywords */
+ NULL, /* requirements */
+ 20, 20,
+ NULL, draw)
+
diff --git a/test/curve-to-as-line-to.c b/test/curve-to-as-line-to.c
new file mode 100644
index 000000000..07eb005f5
--- /dev/null
+++ b/test/curve-to-as-line-to.c
@@ -0,0 +1,95 @@
+/*
+ * Copyright © 2005 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+#include "cairo-test.h"
+
+#define SIZE 30
+
+/* At one point, an optimization was proposed for cairo in which a
+ * curve_to would be optimized as a line_to. The initial (buggy)
+ * implementation verified that the slopes of several segments of the
+ * spline's control polygon were identical, but left open the
+ * possibility of an anti-parallel slope for one segment.
+ *
+ * For example, given a spline with collinear control points (A,B,C,D)
+ * positioned as follows:
+ *
+ * C--A--B--D
+ *
+ * The code verified identical slopes for AB, CD, and AD. The missing
+ * check for the BC segment allowed it to be anti-parallel to the
+ * others as above, and hence invalid to replace this spline with the
+ * AD line segment.
+ */
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */
+ cairo_paint (cr);
+
+ cairo_set_line_width (cr, 1.0);
+ cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT);
+ cairo_set_line_join (cr, CAIRO_LINE_JOIN_BEVEL);
+ cairo_set_source_rgb (cr, 0.0, 0.0, 0.0); /* black */
+
+ cairo_translate (cr, 0, 1.0);
+
+ /* The CABD spline as described above. We ensure that the spline
+ * folds over on itself outside the bounds of the image to avoid
+ * the reference image having the curved portion of that fold,
+ * (which would just be harder to match in all the backends than
+ * we really want). */
+ cairo_move_to (cr,
+ 10.5, 0.5);
+ cairo_curve_to (cr,
+ 11.5, 0.5,
+ -25.0, 0.5,
+ 31.0, 0.5);
+
+ cairo_stroke (cr);
+
+ cairo_translate (cr, 0, 2.0);
+
+ /* A reflected version: DBAC */
+ cairo_move_to (cr,
+ 19.5, 0.5);
+
+ cairo_curve_to (cr,
+ 18.5, 0.5,
+ 55.0, 0.5,
+ -1.0, 0.5);
+
+ cairo_stroke (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (curve_to_as_line_to,
+ "Test optimization treating curve_to as line_to",
+ "path", /* keywords */
+ NULL, /* requirements */
+ 30,
+ 5,
+ NULL, draw)
diff --git a/test/dash-caps-joins.c b/test/dash-caps-joins.c
new file mode 100644
index 000000000..ace27e9b9
--- /dev/null
+++ b/test/dash-caps-joins.c
@@ -0,0 +1,104 @@
+/*
+ * Copyright © 2005 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+/* Test case for bug #4409:
+ *
+ * Dashes are missing initial caps
+ * https://bugs.freedesktop.org/show_bug.cgi?id=4409
+ */
+
+#include "cairo-test.h"
+
+#define LINE_WIDTH 10.
+#define SIZE (5 * LINE_WIDTH)
+#define PAD (2 * LINE_WIDTH)
+
+static void
+make_path (cairo_t *cr)
+{
+ cairo_move_to (cr, 0., 0.);
+ cairo_rel_line_to (cr, 0., SIZE);
+ cairo_rel_line_to (cr, SIZE, 0.);
+ cairo_close_path (cr);
+
+ cairo_move_to (cr, 2 * LINE_WIDTH, 0.);
+ cairo_rel_line_to (cr, 3 * LINE_WIDTH, 0.);
+ cairo_rel_line_to (cr, 0., 3 * LINE_WIDTH);
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ double dash[] = {LINE_WIDTH, 1.5 * LINE_WIDTH};
+ double dash_offset = -2 * LINE_WIDTH;
+ int i;
+
+ /* We draw in the default black, so paint white first. */
+ cairo_save (cr);
+ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */
+ cairo_paint (cr);
+ cairo_restore (cr);
+
+ for (i=0; i<2; i++) {
+ cairo_save (cr);
+ cairo_set_line_width (cr, LINE_WIDTH);
+ cairo_set_dash (cr, dash, ARRAY_LENGTH (dash), dash_offset);
+
+ cairo_translate (cr, PAD, PAD);
+
+ make_path (cr);
+ cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT);
+ cairo_set_line_join (cr, CAIRO_LINE_JOIN_BEVEL);
+ cairo_stroke (cr);
+
+ cairo_translate (cr, SIZE + PAD, 0.);
+
+ make_path (cr);
+ cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
+ cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND);
+ cairo_stroke (cr);
+
+ cairo_translate (cr, SIZE + PAD, 0.);
+
+ make_path (cr);
+ cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE);
+ cairo_set_line_join (cr, CAIRO_LINE_JOIN_MITER);
+ cairo_stroke (cr);
+
+ cairo_restore (cr);
+ cairo_translate (cr, 0., SIZE + PAD);
+ dash_offset = 0;
+ }
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (dash_caps_joins,
+ "Test caps and joins when dashing",
+ "dash, stroke", /* keywords */
+ NULL, /* requirements */
+ 3 * (PAD + SIZE) + PAD,
+ PAD + SIZE + PAD + SIZE + PAD,
+ NULL, draw)
diff --git a/test/dash-curve.c b/test/dash-curve.c
new file mode 100644
index 000000000..c31998012
--- /dev/null
+++ b/test/dash-curve.c
@@ -0,0 +1,66 @@
+/*
+ * Copyright © 2007 Jeff Smith
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Jeff Smith not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Jeff Smith makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * JEFF SMITH DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL JEFF SMITH BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Jeff Smith <whydoubt@yahoo.com>
+ */
+
+#include "cairo-test.h"
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ double dashes[2] = {20, 20};
+ int a=0, b=0, c=0;
+
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ cairo_paint (cr);
+
+ for (a=0; a<4; a++)
+ for (b=0; b<5; b++)
+ for (c=0; c<5; c++) {
+ cairo_move_to (cr, ((b*5)+c)*60+10, a*60+10);
+ cairo_rel_curve_to (cr,
+ 0, b*10,
+ 0, b*10,
+ c*10, b*10);
+
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_set_line_width (cr, 8);
+ cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
+ cairo_set_dash (cr, dashes, 2, a*10);
+ cairo_stroke_preserve (cr);
+
+ cairo_set_source_rgb (cr, 0, 0.5, 1);
+ cairo_set_line_width (cr, 2);
+ cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT);
+ cairo_set_dash (cr, 0, 0, 0);
+ cairo_stroke (cr);
+ }
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (dash_curve,
+ "Tries to explore the state space of the dashing code along curves",
+ "dash, stroke", /* keywords */
+ NULL, /* requirements */
+ 25*60, 4*60,
+ NULL, draw)
diff --git a/test/dash-infinite-loop.c b/test/dash-infinite-loop.c
new file mode 100644
index 000000000..a3d75442c
--- /dev/null
+++ b/test/dash-infinite-loop.c
@@ -0,0 +1,83 @@
+/*
+ * Copyright © 2009 M Joonas Pihlaja
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: M Joonas Pihlaja <jpihlaja@cc.helsinki.fi>
+ */
+
+#include "cairo-test.h"
+
+/* When faced with very small dash lengths the stroker is liable to
+ * get stuck in an infinite loop when advancing the dash offset. This
+ * test attempts to hit each of the locations in the stroker code
+ * where the dash offset is advanced in a loop.
+ *
+ * Reported to the cairo mailing list by Hans Breuer.
+ * http://lists.cairographics.org/archives/cairo/2009-June/017506.html
+ */
+
+#define EPS 1e-30
+/* This should be comfortably smaller than the unit epsilon of the
+ * floating point type used to advance the dashing, yet not small
+ * enough that it underflows to zero. 1e-30 works to foil up to 80
+ * bit extended precision arithmetic. We want to avoid zero dash
+ * lengths because those trigger special processing in the stroker. */
+
+static void
+do_dash (cairo_t *cr, double dx, double dy, double offset)
+{
+ /* Set the dash pattern to be predominantly ON so that we can
+ * create a reference image by just ignoring the dashing. */
+ static double dash[] = { EPS, EPS/512 };
+ cairo_set_dash (cr, dash, 2, offset);
+ cairo_move_to (cr, 10, 10);
+ cairo_rel_line_to (cr, dx, dy);
+ cairo_stroke (cr);
+ cairo_translate (cr, dx, dy);
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ (void)width; (void)height;
+
+ cairo_set_source_rgb (cr, 1,1,1);
+ cairo_paint (cr);
+ cairo_set_source_rgb (cr, 0,0,0);
+
+ cairo_set_line_width (cr, 10);
+
+ /* The following calls will wedge in various places that try
+ * to advance the dashing in a loop inside the stroker. */
+ do_dash (cr, 30, 30, 0); /* _cairo_stroker_line_to_dashed */
+ do_dash (cr, 30, 0, 0); /* _cairo_rectilinear_stroker_line_to_dashed */
+ do_dash (cr, 30, 30, 1); /* _cairo_stroker_dash_start */
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (dash_infinite_loop,
+ "Test dashing with extremely small dash lengths.",
+ "dash",
+ NULL,
+ 100, 100,
+ NULL, draw);
diff --git a/test/dash-no-dash.c b/test/dash-no-dash.c
new file mode 100644
index 000000000..e03094ad4
--- /dev/null
+++ b/test/dash-no-dash.c
@@ -0,0 +1,87 @@
+/*
+ * Copyright © 2006 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+#include "cairo-test.h"
+#include <stdlib.h>
+
+#define PAD 1
+#define LINE_WIDTH 2
+#define HEIGHT (PAD + 4 * (LINE_WIDTH + PAD))
+#define WIDTH 16
+
+static void
+line (cairo_t *cr)
+{
+ cairo_move_to (cr, PAD, 0.0);
+ cairo_line_to (cr, WIDTH - PAD, 0.0);
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ double dash = 2.0;
+
+ /* We draw in black, so paint white first. */
+ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */
+ cairo_paint (cr);
+
+ cairo_set_source_rgb (cr, 0, 0, 0); /* black */
+
+ cairo_translate (cr, 0.0, PAD + LINE_WIDTH / 2);
+
+ /* First draw a solid line... */
+ line (cr);
+ cairo_stroke (cr);
+
+ cairo_translate (cr, 0.0, LINE_WIDTH + PAD);
+
+ /* then a dashed line... */
+ cairo_set_dash (cr, &dash, 1, 0.0);
+ line (cr);
+ cairo_stroke (cr);
+
+ cairo_translate (cr, 0.0, LINE_WIDTH + PAD);
+
+ /* back to solid... */
+ cairo_set_dash (cr, NULL, 0, 0.0);
+ line (cr);
+ cairo_stroke (cr);
+
+ cairo_translate (cr, 0.0, LINE_WIDTH + PAD);
+
+ /* and finally, back to dashed. */
+ cairo_set_dash (cr, &dash, 1, 0.0);
+ line (cr);
+ cairo_stroke (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (dash_no_dash,
+ "Tests that we can actually turn dashing on and off again",
+ "dash, stroke", /* keywords */
+ NULL, /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw)
diff --git a/test/dash-offset-negative.c b/test/dash-offset-negative.c
new file mode 100644
index 000000000..8766cc576
--- /dev/null
+++ b/test/dash-offset-negative.c
@@ -0,0 +1,100 @@
+/*
+ * Copyright © 2005 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Owen Taylor <otaylor@redhat.com>
+ */
+
+#include "cairo-test.h"
+
+#define IMAGE_WIDTH 19
+#define IMAGE_HEIGHT 19
+
+/* Basic test of dashed strokes, including a test for the negative
+ * dash offset bug:
+ *
+ * https://bugs.freedesktop.org/show_bug.cgi?id=2729
+ */
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ double dashes[] = { 1 };
+
+ /* We draw in the default black, so paint white first. */
+ cairo_save (cr);
+ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */
+ cairo_paint (cr);
+ cairo_restore (cr);
+
+ cairo_set_line_width (cr, 2);
+
+ /* Basic 1-1 dash pattern */
+ cairo_set_dash (cr, dashes, 1, 0.);
+
+ cairo_move_to (cr, 1, 2);
+ cairo_line_to (cr, 18, 2);
+ cairo_stroke (cr);
+
+ /* Adjust path by 0.5. Ideally this would give a constant 50%
+ * gray, (but does not due to the location of the regular sample
+ * grid points. */
+ cairo_move_to (cr, 1.5, 5);
+ cairo_line_to (cr, 18., 5);
+ cairo_stroke (cr);
+
+ /* Offset dash by 0.5, rather than the path */
+ cairo_set_dash (cr, dashes, 1, 0.5);
+
+ cairo_move_to (cr, 1, 8);
+ cairo_line_to (cr, 18, 8);
+ cairo_stroke (cr);
+
+ /* Now, similar tests with negative dash offsets. */
+
+ /* Basic 1-1 dash pattern dashing */
+ cairo_set_dash (cr, dashes, 1, -4);
+
+ cairo_move_to (cr, 1, 11);
+ cairo_line_to (cr, 18, 11);
+ cairo_stroke (cr);
+
+ /* Adjust path by 0.5 */
+ cairo_move_to (cr, 1.5, 14);
+ cairo_line_to (cr, 18., 14);
+ cairo_stroke (cr);
+
+ /* Offset dash by 0.5 */
+ cairo_set_dash (cr, dashes, 1, -3.5);
+
+ cairo_move_to (cr, 1, 17);
+ cairo_line_to (cr, 18, 17);
+ cairo_stroke (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (dash_offset_negative,
+ "Tests cairo_set_dash with a negative offset",
+ "dash, stroke", /* keywords */
+ NULL, /* requirements */
+ IMAGE_WIDTH, IMAGE_HEIGHT,
+ NULL, draw)
diff --git a/test/dash-offset.c b/test/dash-offset.c
new file mode 100644
index 000000000..f4269ee13
--- /dev/null
+++ b/test/dash-offset.c
@@ -0,0 +1,83 @@
+/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */
+/*
+ * Copyright 2009 Andrea Canciani
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Andrea Canciani <ranma42@gmail.com>
+ */
+
+#include "cairo-test.h"
+
+/* Lengths of the dashes of the dash patterns */
+static const double dashes[] = { 2, 2, 4, 4 };
+/* Dash offset in userspace units
+ * They always grow by 2, so the dash pattern is
+ * should be shifted by the same amount each time */
+static const double frac_offset[] = { 0, 2, 4, 6 };
+/* Dash offset relative to the whole dash pattern
+ * This corresponds to the non-inverted part only if
+ * the dash pattern has odd length, so the expected result
+ * is the same for every int_offset if the pattern has
+ * even length, and inverted each time (or shifted by half
+ * period, which is the same) if the pattern has odd length. */
+static const double int_offset[] = { -2, -1, 0, 1, 2 };
+
+#define PAD 6
+#define STROKE_LENGTH 32
+#define IMAGE_WIDTH (PAD + (STROKE_LENGTH + PAD) * ARRAY_LENGTH (dashes))
+#define IMAGE_HEIGHT (PAD + PAD * ARRAY_LENGTH (int_offset) + PAD * ARRAY_LENGTH (frac_offset) * ARRAY_LENGTH (int_offset))
+
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ double total;
+ size_t i, j, k;
+
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ cairo_set_line_width (cr, 2);
+
+ total = 0.0;
+ for (k = 0; k < ARRAY_LENGTH (dashes); ++k) {
+ total += dashes[k];
+ for (i = 0; i < ARRAY_LENGTH (frac_offset); ++i) {
+ for (j = 0; j < ARRAY_LENGTH (int_offset); ++j) {
+ cairo_set_dash (cr, dashes, k + 1, frac_offset[i] + total * int_offset[j]);
+ cairo_move_to (cr, (STROKE_LENGTH + PAD) * k + PAD, PAD * (i + j + ARRAY_LENGTH (frac_offset) * j + 1));
+ cairo_line_to (cr, (STROKE_LENGTH + PAD) * (k + 1), PAD * (i + j + ARRAY_LENGTH (frac_offset) * j + 1));
+ cairo_stroke (cr);
+ }
+ }
+ }
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (dash_offset,
+ "Tests dashes of different length with various offsets",
+ "stroke, dash", /* keywords */
+ NULL, /* requirements */
+ IMAGE_WIDTH, IMAGE_HEIGHT,
+ NULL, draw)
diff --git a/test/dash-scale.c b/test/dash-scale.c
new file mode 100644
index 000000000..fd5170255
--- /dev/null
+++ b/test/dash-scale.c
@@ -0,0 +1,120 @@
+/*
+ * Copyright © 2005 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+#include "cairo-test.h"
+
+#define LINE_WIDTH 8.
+#define SIZE (5 * LINE_WIDTH)
+#define PAD (2 * LINE_WIDTH)
+
+static void
+make_path (cairo_t *cr)
+{
+ cairo_move_to (cr, 0., 0.);
+ cairo_rel_line_to (cr, 0., SIZE);
+ cairo_rel_line_to (cr, SIZE, 0.);
+ cairo_close_path (cr);
+
+ cairo_move_to (cr, 2 * LINE_WIDTH, 0.);
+ cairo_rel_line_to (cr, 3 * LINE_WIDTH, 0.);
+ cairo_rel_line_to (cr, 0., 3 * LINE_WIDTH);
+}
+
+static void
+draw_three_shapes (cairo_t *cr)
+{
+ cairo_save (cr);
+
+ make_path (cr);
+ cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT);
+ cairo_set_line_join (cr, CAIRO_LINE_JOIN_BEVEL);
+ cairo_stroke (cr);
+
+ cairo_translate (cr, SIZE + PAD, 0.);
+
+ make_path (cr);
+ cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
+ cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND);
+ cairo_stroke (cr);
+
+ cairo_translate (cr, SIZE + PAD, 0.);
+
+ make_path (cr);
+ cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE);
+ cairo_set_line_join (cr, CAIRO_LINE_JOIN_MITER);
+ cairo_stroke (cr);
+
+ cairo_restore (cr);
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ double dash[] = {1.5 * LINE_WIDTH};
+
+ /* We draw in the default black, so paint white first. */
+ cairo_save (cr);
+ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */
+ cairo_paint (cr);
+ cairo_restore (cr);
+
+ cairo_translate (cr, PAD, PAD);
+
+ cairo_set_dash (cr, dash, ARRAY_LENGTH (dash), - 2 * LINE_WIDTH);
+ cairo_set_line_width (cr, LINE_WIDTH);
+ draw_three_shapes (cr);
+
+ cairo_translate (cr, 0, SIZE + 2 * PAD);
+
+ cairo_save (cr);
+ {
+ cairo_set_dash (cr, dash, ARRAY_LENGTH (dash), - 2 * LINE_WIDTH);
+ cairo_set_line_width (cr, LINE_WIDTH);
+ cairo_scale (cr, 1, 2);
+ draw_three_shapes (cr);
+ }
+ cairo_restore (cr);
+
+ cairo_translate (cr, 0, 2 * (SIZE + PAD));
+
+ cairo_save (cr);
+ {
+ cairo_scale (cr, 1, 2);
+ cairo_set_dash (cr, dash, ARRAY_LENGTH (dash), - 2 * LINE_WIDTH);
+ cairo_set_line_width (cr, LINE_WIDTH);
+ draw_three_shapes (cr);
+ }
+ cairo_restore (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (dash_scale,
+ "Test interactions of cairo_set_dash and cairo_scale, (in particular with a non-uniformly scaled pen)",
+ "dash, stroke, transform", /* keywords */
+ NULL, /* requirements */
+ 3 * (PAD + SIZE) + PAD,
+ PAD + 5 * SIZE + 2 * (2 * PAD) + PAD,
+ NULL, draw)
diff --git a/test/dash-state.c b/test/dash-state.c
new file mode 100644
index 000000000..5276aeaa6
--- /dev/null
+++ b/test/dash-state.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright © 2007 Jeff Smith
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Jeff Smith not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Jeff Smith makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * JEFF SMITH DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL JEFF SMITH BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Jeff Smith <whydoubt@yahoo.com>
+ */
+
+#include "cairo-test.h"
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ double dashes[2] = {20, 20};
+ int a=0, b=0, c=0;
+
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ cairo_paint (cr);
+
+ for (a=0; a<4; a++)
+ for (b=0; b<5; b++)
+ for (c=0; c<5; c++) {
+ cairo_move_to (cr, ((b*5)+c)*60+10, a*60+10);
+ cairo_rel_line_to (cr, 0, b*10);
+ cairo_rel_line_to (cr, c*10, 0);
+
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_set_line_width (cr, 8);
+ cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
+ cairo_set_dash (cr, dashes, 2, a*10);
+ cairo_stroke_preserve (cr);
+
+ cairo_set_source_rgb (cr, 0, 0.5, 1);
+ cairo_set_line_width (cr, 2);
+ cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT);
+ cairo_set_dash (cr, 0, 0, 0);
+ cairo_stroke (cr);
+ }
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (dash_state,
+ "Tries to explore the state space of the dashing code",
+ "dash, stroke", /* keywords */
+ NULL, /* requirements */
+ 25*60, 4*60,
+ NULL, draw)
diff --git a/test/dash-zero-length.c b/test/dash-zero-length.c
new file mode 100644
index 000000000..5ab944bb7
--- /dev/null
+++ b/test/dash-zero-length.c
@@ -0,0 +1,110 @@
+/*
+ * Copyright © 2006 Jeff Muizelaar
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Jeff Muizelaar. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Jeff Muizelaar. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * JEFF MUIZELAAR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL JEFF MUIZELAAR BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Jeff Muizelaar <jeff@infidigm.net>
+ */
+
+#include "cairo-test.h"
+
+#define IMAGE_WIDTH 19
+#define IMAGE_HEIGHT 61
+
+/* A test of the two extremes of dashing: a solid line
+ * and an invisible one. Also test that capping works
+ * on invisible lines.
+ */
+
+static void
+draw_dash (cairo_t *cr, double *dash, int num_dashes)
+{
+ cairo_set_dash (cr, dash, num_dashes, 0.0);
+ cairo_move_to (cr, 1, 2);
+ cairo_line_to (cr, 18, 2);
+ cairo_stroke (cr);
+ cairo_translate (cr, 0, 3);
+}
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ static double solid_line[] = { 4, 0 };
+ static double invisible_line[] = { 0, 4 };
+ static double dotted_line[] = { 0, 6 };
+ static double zero_1_of_3[] = { 0, 2, 3 };
+ static double zero_2_of_3[] = { 1, 0, 3 };
+ static double zero_3_of_3[] = { 1, 2, 0 };
+ static double zero_1_of_4[] = { 0, 2, 3, 4 };
+ static double zero_2_of_4[] = { 1, 0, 3, 4 };
+ static double zero_3_of_4[] = { 1, 2, 0, 4 };
+ static double zero_4_of_4[] = { 1, 2, 3, 0 };
+ static double zero_1_2_of_4[] = { 0, 0, 3, 4 };
+ static double zero_1_3_of_4[] = { 0, 2, 0, 4 };
+/* Clearly it would be nice to draw this one as well, but it seems to trigger a bug in ghostscript. */
+#if BUG_FIXED_IN_GHOSTSCRIPT
+ static double zero_1_4_of_4[] = { 0, 2, 3, 0 };
+#endif
+ static double zero_2_3_of_4[] = { 1, 0, 0, 4 };
+ static double zero_2_4_of_4[] = { 1, 0, 3, 0 };
+ static double zero_3_4_of_4[] = { 1, 2, 0, 0 };
+ static double zero_1_2_3_of_4[] = { 0, 0, 0, 4 };
+ static double zero_1_2_4_of_4[] = { 0, 0, 3, 0 };
+ static double zero_1_3_4_of_4[] = { 0, 2, 0, 0 };
+ static double zero_2_3_4_of_4[] = { 1, 0, 0, 0 };
+
+ cairo_set_source_rgb (cr, 1, 0, 0);
+ cairo_set_line_width (cr, 2);
+
+ draw_dash (cr, solid_line, 2);
+ draw_dash (cr, invisible_line, 2);
+
+ cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
+ draw_dash (cr, dotted_line, 2);
+ cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT);
+
+ draw_dash (cr, zero_1_of_3, 3);
+ draw_dash (cr, zero_2_of_3, 3);
+ draw_dash (cr, zero_3_of_3, 3);
+ draw_dash (cr, zero_1_of_4, 4);
+ draw_dash (cr, zero_2_of_4, 4);
+ draw_dash (cr, zero_3_of_4, 4);
+ draw_dash (cr, zero_4_of_4, 4);
+ draw_dash (cr, zero_1_2_of_4, 4);
+ draw_dash (cr, zero_1_3_of_4, 4);
+#if BUG_FIXED_IN_GHOSTSCRIPT
+ draw_dash (cr, zero_1_4_of_4, 4);
+#endif
+ draw_dash (cr, zero_2_3_of_4, 4);
+ draw_dash (cr, zero_2_4_of_4, 4);
+ draw_dash (cr, zero_3_4_of_4, 4);
+ draw_dash (cr, zero_1_2_3_of_4, 4);
+ draw_dash (cr, zero_1_2_4_of_4, 4);
+ draw_dash (cr, zero_1_3_4_of_4, 4);
+ draw_dash (cr, zero_2_3_4_of_4, 4);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (dash_zero_length,
+ "Tests cairo_set_dash with zero length",
+ "dash, stroke", /* keywords */
+ NULL, /* requirements */
+ IMAGE_WIDTH, IMAGE_HEIGHT,
+ NULL, draw)
diff --git a/test/degenerate-arc.c b/test/degenerate-arc.c
new file mode 100644
index 000000000..ab6577421
--- /dev/null
+++ b/test/degenerate-arc.c
@@ -0,0 +1,74 @@
+/*
+ * Copyright © 2008 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Chris Wilson not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Chris Wilson makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+/* This test case exercises a "Potential division by zero in cairo_arc"
+ * reported by Luiz Americo Pereira Camara <luizmed@oi.com.br>,
+ * http://lists.cairographics.org/archives/cairo/2008-May/014054.html.
+ */
+
+#include "cairo-test.h"
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ int n;
+
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+ cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
+
+ cairo_set_line_width (cr, 5);
+ cairo_set_source_rgb (cr, 0, 1, 0);
+ for (n = 0; n < 8; n++) {
+ double theta = n * 2 * M_PI / 8;
+ cairo_new_sub_path (cr);
+ cairo_arc (cr, 20, 20, 15, theta, theta);
+ cairo_close_path (cr);
+ }
+ cairo_stroke (cr);
+
+ cairo_set_line_width (cr, 2);
+ cairo_set_source_rgb (cr, 0, 0, 1);
+ for (n = 0; n < 8; n++) {
+ double theta = n * 2 * M_PI / 8;
+ cairo_move_to (cr, 20, 20);
+ cairo_arc (cr, 20, 20, 15, theta, theta);
+ }
+ cairo_stroke (cr);
+
+ cairo_set_source_rgb (cr, 1, 0, 0);
+ cairo_arc (cr, 20, 20, 2, 0, 2*M_PI);
+ cairo_fill (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (degenerate_arc,
+ "Tests the behaviour of degenerate arcs",
+ "degenerate", /* keywords */
+ NULL, /* requirements */
+ 40, 40,
+ NULL, draw)
diff --git a/test/degenerate-arcs.c b/test/degenerate-arcs.c
new file mode 100644
index 000000000..2470828bb
--- /dev/null
+++ b/test/degenerate-arcs.c
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2010 Intel Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Chris Wilson not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Chris Wilson makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+#define WIDTH 20
+#define HEIGHT 20
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+ cairo_set_source_rgb (cr, 0.3, 0.4, 0.5);
+
+ /* This should be equivalent to a simple rectangle, such as may be
+ * constructed for a rounded-rectangle with corner radii of 0...
+ */
+ cairo_arc (cr, 5, 5, 0, M_PI, 3*M_PI/2);
+ cairo_arc (cr, 15, 5, 0, 3*M_PI/2, 2*M_PI);
+ cairo_arc (cr, 15, 15, 0, 0, M_PI/2);
+ cairo_arc (cr, 5, 15, 0, M_PI/2, M_PI);
+
+ cairo_fill (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (degenerate_arcs,
+ "Tests path construction using a series of degenerate (radius=0) arcs",
+ "arc, fill", /* keywords */
+ NULL, /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw)
diff --git a/test/degenerate-curve-to.c b/test/degenerate-curve-to.c
new file mode 100644
index 000000000..a081a3bb0
--- /dev/null
+++ b/test/degenerate-curve-to.c
@@ -0,0 +1,103 @@
+/*
+ * Copyright © 2005 Red Hat, Inc.
+ * Copyright © 2009 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ * Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+#define SIZE 30
+
+/* Another attempt at avoiding unnecessary splines was made, where
+ * a curve-to that ended on the same point as it began were discarded.
+ */
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */
+ cairo_paint (cr);
+
+ cairo_set_line_width (cr, 1.0);
+ cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT);
+ cairo_set_line_join (cr, CAIRO_LINE_JOIN_BEVEL);
+ cairo_set_source_rgb (cr, 0.0, 0.0, 0.0); /* black */
+
+ /* entirely degenerate */
+ cairo_move_to (cr,
+ 2.5, 2.5);
+ cairo_curve_to (cr,
+ 2.5, 2.5,
+ 2.5, 2.5,
+ 2.5, 2.5);
+ cairo_stroke (cr);
+
+ /* horizontal */
+ cairo_move_to (cr,
+ 5.5, 2.5);
+ cairo_curve_to (cr,
+ 22.0, 2.5,
+ -0.5, 2.5,
+ 5.5, 2.5);
+ cairo_stroke (cr);
+
+ /* vertical */
+ cairo_move_to (cr,
+ 7.5, 0.0);
+ cairo_curve_to (cr,
+ 7.5, 11.0,
+ 7.5, 0.0,
+ 7.5, 0.0);
+ cairo_stroke (cr);
+
+ cairo_translate (cr, 15, 0);
+
+ /* horizontal/vertical */
+ cairo_move_to (cr,
+ 5.5, 0.5);
+ cairo_curve_to (cr,
+ -0.5, 0.5,
+ 5.5, 10.5,
+ 5.5, 0.5);
+
+ cairo_translate (cr, 10, 0);
+
+ /* vertical/horizontal */
+ cairo_move_to (cr,
+ 5.5, 0.0);
+ cairo_curve_to (cr,
+ 5.5, 11.0,
+ 10.5, 0.0,
+ 5.5, 0.0);
+ cairo_stroke (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (degenerate_curve_to,
+ "Test optimization treating degenerate curve_to as line_to",
+ "path", /* keywords */
+ NULL, /* requirements */
+ 40,
+ 5,
+ NULL, draw)
diff --git a/test/degenerate-dash.c b/test/degenerate-dash.c
new file mode 100644
index 000000000..6e7bf6b37
--- /dev/null
+++ b/test/degenerate-dash.c
@@ -0,0 +1,90 @@
+/*
+ * Copyright © 2008 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Chris Wilson not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Chris Wilson makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ *
+ * Based on an original test case by M Joonas Pihlaja.
+ */
+
+#include "cairo-test.h"
+
+#define PAD 5
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ const double dashes[] = { 25, 25 };
+ cairo_line_join_t joins[] = {
+ CAIRO_LINE_JOIN_ROUND,
+ CAIRO_LINE_JOIN_MITER,
+ CAIRO_LINE_JOIN_BEVEL
+ };
+ cairo_line_cap_t caps[] = {
+ CAIRO_LINE_CAP_ROUND,
+ CAIRO_LINE_CAP_SQUARE,
+ CAIRO_LINE_CAP_BUTT,
+ };
+ int i, j;
+
+ cairo_set_source_rgb (cr, 1,1,1);
+ cairo_paint (cr);
+
+ cairo_set_source_rgb (cr, 1, 0, 0);
+
+ cairo_set_dash (cr, dashes, 2, 0.);
+ cairo_set_line_width (cr, 10);
+
+ cairo_translate (cr, 5 + PAD, 5 + PAD);
+
+ for (i = 0; i < ARRAY_LENGTH (joins); i++) {
+ cairo_set_line_join (cr, joins[i]);
+ cairo_save (cr);
+
+ for (j = 0; j < ARRAY_LENGTH (caps); j++) {
+ cairo_set_line_cap (cr, caps[j]);
+
+ cairo_move_to (cr, 0, 0);
+ cairo_line_to (cr, 50, 0);
+ cairo_line_to (cr, 50,50);
+ cairo_stroke (cr);
+
+ cairo_translate (cr, 75, 0);
+ }
+ cairo_restore (cr);
+
+ cairo_translate (cr, 0, 75);
+ }
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+/*
+ * XFAIL: needs path editing in PS to convert degenerate
+ * end-caps into the shapes as expected by cairo (Or maybe PS is the correct
+ * behaviour?)
+ */
+CAIRO_TEST (degenerate_dash,
+ "Tests the behaviour of dashed segments that end on a off-on transition",
+ "dash, degenerate", /* keywords */
+ NULL, /* requirementts */
+ 210 + 2*PAD, 210 + 2*PAD,
+ NULL, draw)
diff --git a/test/degenerate-linear-gradient.c b/test/degenerate-linear-gradient.c
new file mode 100644
index 000000000..0d174fc89
--- /dev/null
+++ b/test/degenerate-linear-gradient.c
@@ -0,0 +1,81 @@
+/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */
+/*
+ * Copyright 2010 Andrea Canciani
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Andrea Canciani <ranma42@gmail.com>
+ */
+
+#include "cairo-test.h"
+
+#define NUM_EXTEND 4
+#define HEIGHT 16
+#define WIDTH 16
+#define PAD 3
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_pattern_t *pattern;
+ unsigned int j;
+
+ cairo_extend_t extend[NUM_EXTEND] = {
+ CAIRO_EXTEND_NONE,
+ CAIRO_EXTEND_REPEAT,
+ CAIRO_EXTEND_REFLECT,
+ CAIRO_EXTEND_PAD
+ };
+
+ cairo_test_paint_checkered (cr);
+
+ pattern = cairo_pattern_create_linear (WIDTH/2, HEIGHT/2, WIDTH/2, HEIGHT/2);
+
+ cairo_pattern_add_color_stop_rgba (pattern, 0, 1, 0, 0, 1);
+ cairo_pattern_add_color_stop_rgba (pattern, sqrt (1.0 / 2.0), 0, 1, 0, 0);
+ cairo_pattern_add_color_stop_rgba (pattern, 1, 0, 0, 1, 0.5);
+
+ cairo_translate (cr, PAD, PAD);
+
+ for (j = 0; j < NUM_EXTEND; j++) {
+ cairo_reset_clip (cr);
+ cairo_rectangle (cr, 0, 0, WIDTH, HEIGHT);
+ cairo_clip (cr);
+
+ cairo_pattern_set_extend (pattern, extend[j]);
+
+ cairo_set_source (cr, pattern);
+ cairo_paint (cr);
+
+ cairo_translate (cr, WIDTH+PAD, 0);
+ }
+
+ cairo_pattern_destroy (pattern);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (degenerate_linear_gradient,
+ "Tests degenerate linear gradients",
+ "linear, pattern, extend", /* keywords */
+ NULL, /* requirements */
+ (WIDTH+PAD) * NUM_EXTEND + PAD, 1*(HEIGHT + PAD) + PAD,
+ NULL, draw)
diff --git a/test/degenerate-path.c b/test/degenerate-path.c
new file mode 100644
index 000000000..aa5f8225b
--- /dev/null
+++ b/test/degenerate-path.c
@@ -0,0 +1,120 @@
+/*
+ * Copyright © 2006 Jeff Muizelaar
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Jeff Muizelaar not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Jeff Muizelaar makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * JEFF MUIZELAAR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL JEFF MUIZELAAR BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Jeff Muizelaar <jeff@infidigm.net>
+ */
+
+#include "cairo-test.h"
+
+#define PAD 3.0
+#define LINE_WIDTH 6.0
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ const cairo_line_cap_t cap[] = { CAIRO_LINE_CAP_ROUND, CAIRO_LINE_CAP_SQUARE, CAIRO_LINE_CAP_BUTT };
+ size_t i;
+ double dash[] = {2, 2};
+ double dash_long[] = {6, 6};
+
+ cairo_set_source_rgb (cr, 1, 0, 0);
+
+ for (i = 0; i < ARRAY_LENGTH (cap); i++) {
+ cairo_save (cr);
+
+ cairo_set_line_cap (cr, cap[i]);
+
+ /* simple degenerate paths */
+ cairo_set_line_width (cr, LINE_WIDTH);
+ cairo_move_to (cr, LINE_WIDTH, LINE_WIDTH);
+ cairo_line_to (cr, LINE_WIDTH, LINE_WIDTH);
+ cairo_stroke (cr);
+
+ cairo_translate (cr, 0, 3*PAD);
+ cairo_move_to (cr, LINE_WIDTH, LINE_WIDTH);
+ cairo_close_path (cr);
+ cairo_stroke (cr);
+
+ /* degenerate paths starting with dash on */
+ cairo_set_dash (cr, dash, 2, 0.);
+
+ cairo_translate (cr, 0, 3*PAD);
+ cairo_move_to (cr, LINE_WIDTH, LINE_WIDTH);
+ cairo_line_to (cr, LINE_WIDTH, LINE_WIDTH);
+ cairo_stroke (cr);
+
+ cairo_translate (cr, 0, 3*PAD);
+ cairo_move_to (cr, LINE_WIDTH, LINE_WIDTH);
+ cairo_close_path (cr);
+ cairo_stroke (cr);
+
+ /* degenerate paths starting with dash off */
+ /* these should not draw anything */
+ cairo_set_dash (cr, dash, 2, 2.);
+
+ cairo_translate (cr, 0, 3*PAD);
+ cairo_move_to (cr, LINE_WIDTH, LINE_WIDTH);
+ cairo_line_to (cr, LINE_WIDTH, LINE_WIDTH);
+ cairo_stroke (cr);
+
+ cairo_translate (cr, 0, 3*PAD);
+ cairo_move_to (cr, LINE_WIDTH, LINE_WIDTH);
+ cairo_close_path (cr);
+ cairo_stroke (cr);
+
+ /* this should draw a single degenerate sub-path
+ * at the end of the path */
+ cairo_set_dash (cr, dash_long, 2, 6.);
+
+ cairo_translate (cr, 0, 3*PAD);
+ cairo_move_to (cr, LINE_WIDTH + 6.0, LINE_WIDTH);
+ cairo_line_to (cr, LINE_WIDTH, LINE_WIDTH);
+ cairo_stroke (cr);
+
+ /* this should draw a single degenerate sub-path
+ * at the end of the path. The difference between this
+ * and the above is that this ends with a degenerate sub-path*/
+ cairo_set_dash (cr, dash_long, 2, 6.);
+
+ cairo_translate (cr, 0, 3*PAD);
+ cairo_move_to (cr, LINE_WIDTH + 6.0, LINE_WIDTH);
+ cairo_line_to (cr, LINE_WIDTH, LINE_WIDTH);
+ cairo_line_to (cr, LINE_WIDTH, LINE_WIDTH);
+ cairo_stroke (cr);
+
+ cairo_restore (cr);
+
+ cairo_translate (cr, PAD+LINE_WIDTH+PAD, 0);
+ }
+ return CAIRO_TEST_SUCCESS;
+}
+
+/*
+ * XFAIL: undefined behaviour in PS, needs path editing to convert degenerate
+ * segments into circles/rectangles as expected by cairo
+ */
+CAIRO_TEST (degenerate_path,
+ "Tests the behaviour of degenerate paths with different cap types",
+ "degenerate", /* keywords */
+ NULL, /* requirements */
+ 3*(PAD+LINE_WIDTH+PAD), 8*(LINE_WIDTH+PAD) + PAD,
+ NULL, draw)
diff --git a/test/degenerate-pen.c b/test/degenerate-pen.c
new file mode 100644
index 000000000..ec8bd198a
--- /dev/null
+++ b/test/degenerate-pen.c
@@ -0,0 +1,105 @@
+/*
+ * Copyright © 2007 Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+#include "cairo-test.h"
+
+#define SIZE 20
+#define PAD 5
+#define WIDTH (PAD + 3 * (PAD + SIZE) + PAD)
+#define HEIGHT (PAD + SIZE + PAD)
+
+/* We're demonstrating here a bug originally reported by Benjamin Otte
+ * on the cairo mailing list here, (after he ran into this problem
+ * with various flash animations):
+ *
+ * [cairo] Assertion `i < pen->num_vertices' failed in 1.4.10
+ * http://lists.cairographics.org/archives/cairo/2007-August/011282.html
+ *
+ * The problem shows up with an extreme transformation matrix that
+ * collapses the pen to a single line, (which means that
+ * _cairo_slope_compare cannot handle adjacent vertices in the pen
+ * since they have parallel slope).
+ *
+ * This test case tests degenerate pens in several directions and uses
+ * round caps to force the stroking code to attempt to walk around the
+ * pen doing slope comparisons.
+ */
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND);
+
+ cairo_translate (cr, PAD, PAD);
+
+ /* First compress the pen to a vertical line. */
+ cairo_rectangle (cr, 0, 0, SIZE, SIZE);
+ cairo_curve_to (cr, SIZE / 2, 0, SIZE, SIZE / 2, SIZE, SIZE);
+ cairo_save (cr);
+ {
+ cairo_scale (cr, 0.000001, 1.0);
+ cairo_stroke (cr);
+ }
+ cairo_restore (cr);
+
+ cairo_translate (cr, PAD + SIZE, 0);
+
+ /* Then compress the pen to a horizontal line. */
+ cairo_rectangle (cr, 0, 0, SIZE, SIZE);
+ cairo_curve_to (cr, SIZE / 2, 0, SIZE, SIZE / 2, SIZE, SIZE);
+ cairo_save (cr);
+ {
+ cairo_scale (cr, 1.0, 0.000001);
+ cairo_stroke (cr);
+ }
+ cairo_restore (cr);
+
+ cairo_translate (cr, PAD + SIZE, 0);
+
+ /* Finally a line at an angle. */
+ cairo_rectangle (cr, 0, 0, SIZE, SIZE);
+ cairo_curve_to (cr, SIZE / 2, 0, SIZE, SIZE / 2, SIZE, SIZE);
+ cairo_save (cr);
+ {
+ cairo_rotate (cr, M_PI / 4.0);
+ cairo_scale (cr, 0.000001, 1.0);
+ cairo_stroke (cr);
+ }
+ cairo_restore (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (degenerate_pen,
+ "Test round joins with a pen that's transformed to a line",
+ "degenerate", /* keywords */
+ NULL, /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw)
diff --git a/test/degenerate-radial-gradient.c b/test/degenerate-radial-gradient.c
new file mode 100644
index 000000000..14666450e
--- /dev/null
+++ b/test/degenerate-radial-gradient.c
@@ -0,0 +1,93 @@
+/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */
+/*
+ * Copyright 2010 Andrea Canciani
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Andrea Canciani <ranma42@gmail.com>
+ */
+
+#include "cairo-test.h"
+
+#define NUM_EXTEND 4
+#define HEIGHT 32
+#define WIDTH 32
+#define PAD 6
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_pattern_t *pattern;
+ unsigned int i, j;
+
+ cairo_extend_t extend[NUM_EXTEND] = {
+ CAIRO_EXTEND_NONE,
+ CAIRO_EXTEND_REPEAT,
+ CAIRO_EXTEND_REFLECT,
+ CAIRO_EXTEND_PAD
+ };
+
+ cairo_test_paint_checkered (cr);
+
+ cairo_translate (cr, PAD, PAD);
+
+ for (i = 0; i < 3; i++) {
+ cairo_save (cr);
+
+ for (j = 0; j < NUM_EXTEND; j++) {
+ cairo_reset_clip (cr);
+ cairo_rectangle (cr, 0, 0, WIDTH, HEIGHT);
+ cairo_clip (cr);
+
+ if (i == 0)
+ pattern = cairo_pattern_create_radial (WIDTH/2, HEIGHT/2, 0, WIDTH/2, HEIGHT/2, 0);
+ else if (i == 1)
+ pattern = cairo_pattern_create_radial (WIDTH/2, HEIGHT/2, 2*PAD, WIDTH/2, HEIGHT/2, 2*PAD);
+ else if (i == 2)
+ pattern = cairo_pattern_create_radial (PAD, PAD, 0, WIDTH-PAD, HEIGHT-PAD, 0);
+
+ cairo_pattern_add_color_stop_rgba (pattern, 0, 1, 0, 0, 1);
+ cairo_pattern_add_color_stop_rgba (pattern, sqrt (1.0 / 2.0), 0, 1, 0, 0);
+ cairo_pattern_add_color_stop_rgba (pattern, 1, 0, 0, 1, 0.5);
+
+ cairo_pattern_set_extend (pattern, extend[j]);
+
+ cairo_set_source (cr, pattern);
+ cairo_paint (cr);
+
+ cairo_pattern_destroy (pattern);
+
+ cairo_translate (cr, WIDTH+PAD, 0);
+ }
+
+ cairo_restore (cr);
+ cairo_translate (cr, 0, HEIGHT+PAD);
+ }
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (degenerate_radial_gradient,
+ "Tests degenerate radial gradients",
+ "radial, pattern, extend", /* keywords */
+ NULL, /* requirements */
+ (WIDTH+PAD) * NUM_EXTEND + PAD, 3*(HEIGHT + PAD) + PAD,
+ NULL, draw)
diff --git a/test/degenerate-rel-curve-to.c b/test/degenerate-rel-curve-to.c
new file mode 100644
index 000000000..d7c0523c6
--- /dev/null
+++ b/test/degenerate-rel-curve-to.c
@@ -0,0 +1,99 @@
+/*
+ * Copyright © 2005 Red Hat, Inc.
+ * Copyright © 2009 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ * Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+#define SIZE 30
+
+/* Another attempt at avoiding unnecessary splines was made, where
+ * a curve-to that ended on the same point as it began were discarded.
+ * The same bug was made to rel-curve-to as well, hence this test.
+ */
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */
+ cairo_paint (cr);
+
+ cairo_set_line_width (cr, 1.0);
+ cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT);
+ cairo_set_line_join (cr, CAIRO_LINE_JOIN_BEVEL);
+ cairo_set_source_rgb (cr, 0.0, 0.0, 0.0); /* black */
+
+ /* entirely degenerate */
+ cairo_move_to (cr, 2.5, 2.5);
+ cairo_rel_curve_to (cr,
+ 0., 0.,
+ 0., 0.,
+ 0., 0.);
+ cairo_stroke (cr);
+
+ /* horizontal */
+ cairo_move_to (cr, 5.5, 2.5);
+ cairo_rel_curve_to (cr,
+ 10., 0.,
+ -10., 0.,
+ 0., 0.);
+ cairo_stroke (cr);
+
+ /* vertical */
+ cairo_move_to (cr, 5.5, 2.5);
+ cairo_rel_curve_to (cr,
+ 0., 10.,
+ 0., -10.,
+ 0., 0.);
+ cairo_stroke (cr);
+
+ cairo_translate (cr, 15, 0);
+
+ /* horizontal/vertical */
+ cairo_move_to (cr, 5.5, 0.5);
+ cairo_rel_curve_to (cr,
+ -6., 0.,
+ 0., 10.,
+ 0., 0.);
+
+ cairo_translate (cr, 10, 0);
+
+ /* vertical/horizontal */
+ cairo_move_to (cr, 5.5, 0.0);
+ cairo_rel_curve_to (cr,
+ 0., 11.,
+ 5., 0.,
+ 0., 0.);
+ cairo_stroke (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (degenerate_rel_curve_to,
+ "Test optimization treating degenerate rel-curve-to as line-to",
+ "path", /* keywords */
+ NULL, /* requirements */
+ 40,
+ 5,
+ NULL, draw)
diff --git a/test/degenerate-solid-dash.c b/test/degenerate-solid-dash.c
new file mode 100644
index 000000000..293a80899
--- /dev/null
+++ b/test/degenerate-solid-dash.c
@@ -0,0 +1,69 @@
+/*
+ * Copyright © 2012 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ const double dashes_1[] = { 10, 0 };
+ const double dashes_2[] = { 10, 0, 10, 10};
+ const double dashes_3[] = { 10, 0, 10, 0};
+
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+ cairo_set_source_rgb (cr, 0, 0, 0);
+
+ cairo_set_line_width (cr, 6);
+
+ cairo_set_dash (cr, NULL, 0, 0);
+ cairo_rectangle (cr, 10, 10, 30, 30);
+ cairo_stroke (cr);
+
+ cairo_translate (cr, 50, 0);
+ cairo_set_dash (cr, dashes_1, 2, 0);
+ cairo_rectangle (cr, 10, 10, 30, 30);
+ cairo_stroke (cr);
+
+ cairo_translate (cr, 0, 50);
+ cairo_set_dash (cr, dashes_2, 4, 0);
+ cairo_rectangle (cr, 10, 10, 30, 30);
+ cairo_stroke (cr);
+
+ cairo_translate (cr, -50, 0);
+ cairo_set_dash (cr, dashes_3, 4, 0);
+ cairo_rectangle (cr, 10, 10, 30, 30);
+ cairo_stroke (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (degenerate_solid_dash,
+ "Exercises degenerate dash ellison",
+ "stroke, dash", /* keywords */
+ NULL, /* requirements */
+ 100, 100,
+ NULL, draw)
diff --git a/test/device-offset-fractional.c b/test/device-offset-fractional.c
new file mode 100644
index 000000000..adc21161f
--- /dev/null
+++ b/test/device-offset-fractional.c
@@ -0,0 +1,72 @@
+/*
+ * Copyright © 2006 Red Hat, Inc.
+ * Copyright © 2008 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ * Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+#define SIZE 10
+#define PAD 4
+#define COUNT 4
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_surface_t *surface;
+ cairo_t *cr2;
+ int i,j;
+
+ /* Fill the background */
+ cairo_set_source_rgb (cr, 1, 1, 1); /* white */
+ cairo_paint (cr);
+
+ surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, SIZE, SIZE);
+ cr2 = cairo_create (surface);
+ cairo_surface_destroy (surface);
+
+ cairo_set_source_rgb (cr2, 0, 0, 1); /* blue */
+ cairo_paint (cr2);
+
+ cairo_set_source_surface (cr, cairo_get_target (cr2), 0, 0);
+ cairo_destroy (cr2);
+
+ for (i = 0; i < COUNT; i++) {
+ for (j = 0; j < COUNT; j++) {
+ cairo_surface_set_device_offset (surface,
+ -i*(SIZE+PAD+.5)-PAD,
+ -j*(SIZE+PAD+.5)-PAD);
+ cairo_paint (cr);
+ }
+ }
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (device_offset_fractional,
+ "Test using image surfaces with fractional device-offsets as sources.",
+ "device-offset", /* keywords */
+ NULL, /* requirements */
+ COUNT*(SIZE+PAD+.5)+PAD, COUNT*(SIZE+PAD+.5)+PAD,
+ NULL, draw)
diff --git a/test/device-offset-positive.c b/test/device-offset-positive.c
new file mode 100644
index 000000000..5afe9730d
--- /dev/null
+++ b/test/device-offset-positive.c
@@ -0,0 +1,82 @@
+/*
+ * Copyright © 2006 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+#include "cairo-test.h"
+#include <stddef.h>
+
+#define SIZE 10
+#define PAD 2
+
+static void
+draw_square (cairo_t *cr)
+{
+ cairo_rectangle (cr,
+ PAD, PAD,
+ SIZE - 2 * PAD,
+ SIZE - 2 * PAD);
+ cairo_fill (cr);
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_surface_t *surface, *target;
+ cairo_t *cr2;
+
+ /* First draw a shape in blue on the original destination. */
+ cairo_set_source_rgb (cr, 0, 0, 1); /* blue */
+ draw_square (cr);
+
+ /* Then, create an offset surface and repeat the drawing in red. */
+ target = cairo_get_group_target (cr);
+ surface = cairo_surface_create_similar (target,
+ cairo_surface_get_content (target),
+ SIZE / 2, SIZE / 2);
+ cr2 = cairo_create (surface);
+ cairo_surface_destroy (surface);
+
+ cairo_set_source_rgb (cr2, 1, 0, 0); /* red */
+ draw_square (cr2);
+
+ /* Finally, copy the offset surface to the original destination.
+ * The final result should be a blue square with the upper-left
+ * quarter red. */
+ surface = cairo_surface_reference (cairo_get_target (cr2));
+ cairo_destroy (cr2);
+ cairo_surface_set_device_offset (surface, + SIZE / 2, + SIZE / 2);
+ cairo_set_source_surface (cr, surface, SIZE / 2, SIZE / 2);
+ cairo_surface_destroy (surface);
+
+ cairo_paint (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (device_offset_positive,
+ "Simple test using a surface with a positive device-offset as a source.",
+ "device-offset", /* keywords */
+ NULL, /* requirements */
+ SIZE, SIZE,
+ NULL, draw)
diff --git a/test/device-offset-scale.c b/test/device-offset-scale.c
new file mode 100644
index 000000000..33784fa8b
--- /dev/null
+++ b/test/device-offset-scale.c
@@ -0,0 +1,77 @@
+/*
+ * Copyright © 2008 Mozilla Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Mozilla Corporation not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Mozilla Corporation makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * MOZILLA CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL MOZILLA CORPORATION BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Michael Ventnor, Jeff Muizelaar
+ */
+
+#include "cairo-test.h"
+
+#define WIDTH 20
+#define HEIGHT 20
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_surface_t *second;
+ cairo_t *second_cr;
+
+ /* fill with black so we don't need an rgb test case */
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ cairo_paint (cr);
+
+ cairo_scale (cr, 0.5, 0.5);
+
+ /* draw the first rectangle */
+ cairo_set_source_rgb (cr, 0, 0, 0.4);
+ cairo_rectangle (cr, 6, 6, 10, 10);
+ cairo_fill (cr);
+
+ /* adjust the offset so that the second rectangle will fit on the surface */
+ second = cairo_image_surface_create (CAIRO_FORMAT_A8, 10, 10);
+ cairo_surface_set_device_offset (second, -6, -6);
+
+ /* draw the second rectangle:
+ * this rectangle should end up in the same place as the rectangle above
+ * independent of the device offset of the surface it is painted on*/
+ second_cr = cairo_create (second);
+ cairo_surface_destroy (second);
+ cairo_rectangle (second_cr, 6, 6, 10, 10);
+ cairo_fill (second_cr);
+
+ /* paint the second rectangle on top of the first rectangle */
+ cairo_set_source_rgb (cr, 0.5, 0.5, 0);
+ cairo_mask_surface (cr, cairo_get_target (second_cr), 0, 0);
+ cairo_destroy (second_cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+/*
+ * XFAIL: complication of pre-multiplying device_offset into the pattern_matrix
+ * and then requiring further manipulation for SVG
+ */
+CAIRO_TEST (device_offset_scale,
+ "Test that the device-offset transform is transformed by the ctm.",
+ "device-offset", /* keywords */
+ NULL, /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw)
diff --git a/test/device-offset.c b/test/device-offset.c
new file mode 100644
index 000000000..1bf5283bd
--- /dev/null
+++ b/test/device-offset.c
@@ -0,0 +1,82 @@
+/*
+ * Copyright © 2006 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+#include "cairo-test.h"
+#include <stddef.h>
+
+#define SIZE 10
+#define PAD 2
+
+static void
+draw_square (cairo_t *cr)
+{
+ cairo_rectangle (cr,
+ PAD, PAD,
+ SIZE - 2 * PAD,
+ SIZE - 2 * PAD);
+ cairo_fill (cr);
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_surface_t *surface, *target;
+ cairo_t *cr2;
+
+ /* First draw a shape in blue on the original destination. */
+ cairo_set_source_rgb (cr, 0, 0, 1); /* blue */
+ draw_square (cr);
+
+ /* Then, create an offset surface and repeat the drawing in red. */
+ target = cairo_get_group_target (cr);
+ surface = cairo_surface_create_similar (target,
+ cairo_surface_get_content (target),
+ SIZE / 2, SIZE / 2);
+ cairo_surface_set_device_offset (surface, - SIZE / 2, - SIZE / 2);
+ cr2 = cairo_create (surface);
+ cairo_surface_destroy (surface);
+
+ cairo_set_source_rgb (cr2, 1, 0, 0); /* red */
+ draw_square (cr2);
+
+
+ /* Finally, copy the offset surface to the original destination.
+ * The final result should be a blue square with the lower-right
+ * quarter red. */
+ cairo_set_source_surface (cr, cairo_get_target (cr2), 0, 0);
+ cairo_destroy (cr2);
+
+ cairo_paint (cr);
+
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (device_offset,
+ "Simple test using a surface with a negative device-offset as a source.",
+ "device-offset", /* keywords */
+ NULL, /* requirements */
+ SIZE, SIZE,
+ NULL, draw)
diff --git a/test/drunkard-tails.c b/test/drunkard-tails.c
new file mode 100644
index 000000000..f55c7becf
--- /dev/null
+++ b/test/drunkard-tails.c
@@ -0,0 +1,135 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+#define LINE_WIDTH 10.
+#define SIZE (5 * LINE_WIDTH)
+#define PAD (3 * LINE_WIDTH)
+
+static uint32_t state;
+
+static double
+uniform_random (double minval, double maxval)
+{
+ static uint32_t const poly = 0x9a795537U;
+ uint32_t n = 32;
+ while (n-->0)
+ state = 2*state < state ? (2*state ^ poly) : 2*state;
+ return minval + state * (maxval - minval) / 4294967296.0;
+}
+
+static void
+make_path (cairo_t *cr)
+{
+ int i;
+
+ state = 0xdeadbeef;
+
+ cairo_move_to (cr, SIZE/2, SIZE/2);
+ for (i = 0; i < 200; i++) {
+ double theta = uniform_random (-M_PI, M_PI);
+ cairo_rel_line_to (cr,
+ cos (theta) * LINE_WIDTH / 4,
+ sin (theta) * LINE_WIDTH / 4);
+ }
+}
+
+static void
+draw_caps_joins (cairo_t *cr)
+{
+ cairo_save (cr);
+
+ cairo_translate (cr, PAD, PAD);
+
+ cairo_reset_clip (cr);
+ cairo_rectangle (cr, 0, 0, SIZE, SIZE);
+ cairo_clip (cr);
+
+ make_path (cr);
+ cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT);
+ cairo_set_line_join (cr, CAIRO_LINE_JOIN_BEVEL);
+ cairo_stroke (cr);
+
+ cairo_translate (cr, SIZE + PAD, 0.);
+
+ cairo_reset_clip (cr);
+ cairo_rectangle (cr, 0, 0, SIZE, SIZE);
+ cairo_clip (cr);
+
+ make_path (cr);
+ cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
+ cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND);
+ cairo_stroke (cr);
+
+ cairo_translate (cr, SIZE + PAD, 0.);
+
+ cairo_reset_clip (cr);
+ cairo_rectangle (cr, 0, 0, SIZE, SIZE);
+ cairo_clip (cr);
+
+ make_path (cr);
+ cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE);
+ cairo_set_line_join (cr, CAIRO_LINE_JOIN_MITER);
+ cairo_stroke (cr);
+
+ cairo_restore (cr);
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ /* We draw in the default black, so paint white first. */
+ cairo_save (cr);
+ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */
+ cairo_paint (cr);
+ cairo_restore (cr);
+
+ cairo_set_line_width (cr, LINE_WIDTH);
+
+ draw_caps_joins (cr);
+
+ cairo_save (cr);
+ /* and reflect to generate the opposite vertex ordering */
+ cairo_translate (cr, 0, height);
+ cairo_scale (cr, 1, -1);
+
+ draw_caps_joins (cr);
+ cairo_restore (cr);
+
+ cairo_translate (cr, 0, SIZE + PAD);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (drunkard_tails,
+ "Test caps and joins on short tail segments",
+ "stroke, cap, join", /* keywords */
+ NULL, /* requirements */
+ 3 * (PAD + SIZE) + PAD,
+ 2 * (PAD + SIZE) + PAD,
+ NULL, draw)
+
diff --git a/test/egl-oversized-surface.c b/test/egl-oversized-surface.c
new file mode 100644
index 000000000..cb85a628d
--- /dev/null
+++ b/test/egl-oversized-surface.c
@@ -0,0 +1,117 @@
+/*
+ * Copyright © 2014 Samsung Electronics
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Ravi Nanjundappa <nravi.n@samsung.com>
+ */
+
+/*
+ * This test exercises error scenario for over sized egl surface
+ *
+ */
+
+#include "cairo-test.h"
+#include <cairo-gl.h>
+#include <assert.h>
+#include <limits.h>
+
+static cairo_test_status_t
+preamble (cairo_test_context_t *test_ctx)
+{
+ EGLint rgba_attribs[] = {
+ EGL_RED_SIZE, 8,
+ EGL_GREEN_SIZE, 8,
+ EGL_BLUE_SIZE, 8,
+ EGL_ALPHA_SIZE, 8,
+ EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
+#if CAIRO_HAS_GL_SURFACE
+ EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
+#elif CAIRO_HAS_GLESV2_SURFACE
+ EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+#endif
+ EGL_NONE
+ };
+ const EGLint ctx_attribs[] = {
+#if CAIRO_HAS_GLESV2_SURFACE
+ EGL_CONTEXT_CLIENT_VERSION, 2,
+#endif
+ EGL_NONE
+ };
+
+ EGLDisplay dpy;
+ EGLContext ctx;
+ EGLConfig config;
+ EGLint numConfigs;
+ int major, minor;
+ cairo_device_t *device;
+ cairo_surface_t *oversized_surface;
+ cairo_test_status_t test_status = CAIRO_TEST_SUCCESS;
+
+ dpy = eglGetDisplay (EGL_DEFAULT_DISPLAY);
+ if (! eglInitialize (dpy, &major, &minor)) {
+ test_status = CAIRO_TEST_UNTESTED;
+ goto CLEANUP_1;
+ }
+
+ eglChooseConfig (dpy, rgba_attribs, &config, 1, &numConfigs);
+ if (numConfigs == 0) {
+ test_status = CAIRO_TEST_UNTESTED;
+ goto CLEANUP_1;
+ }
+
+#if CAIRO_HAS_GL_SURFACE
+ eglBindAPI (EGL_OPENGL_API);
+#elif CAIRO_HAS_GLESV2_SURFACE
+ eglBindAPI (EGL_OPENGL_ES_API);
+#endif
+
+ ctx = eglCreateContext (dpy, config, EGL_NO_CONTEXT,
+ ctx_attribs);
+ if (ctx == EGL_NO_CONTEXT) {
+ test_status = CAIRO_TEST_UNTESTED;
+ goto CLEANUP_2;
+ }
+
+ device = cairo_egl_device_create (dpy, ctx);
+
+ oversized_surface = cairo_gl_surface_create (device, CAIRO_CONTENT_COLOR_ALPHA, INT_MAX, INT_MAX);
+ if (cairo_surface_status (oversized_surface) != CAIRO_STATUS_INVALID_SIZE)
+ test_status = CAIRO_TEST_FAILURE;
+
+ cairo_device_destroy (device);
+ eglDestroyContext (dpy, ctx);
+ eglMakeCurrent (dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+ ctx = EGL_NO_CONTEXT;
+
+CLEANUP_2:
+ eglTerminate (dpy);
+
+CLEANUP_1:
+ return test_status;
+}
+
+CAIRO_TEST (egl_oversized_surface,
+ "Test that creating a surface beyond texture limits results in an error surface",
+ "egl", /* keywords */
+ NULL, /* requirements */
+ 0, 0,
+ preamble, NULL)
diff --git a/test/egl-surface-source.c b/test/egl-surface-source.c
new file mode 100644
index 000000000..4a84d7042
--- /dev/null
+++ b/test/egl-surface-source.c
@@ -0,0 +1,135 @@
+/*
+ * Copyright © 2014 Samsung Electronics
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Ravi Nanjundappa <nravi.n@samsung.com>
+ */
+
+/*
+ * This case tests using a EGL surface as the source
+ *
+ */
+
+#include "cairo-test.h"
+#include <cairo-gl.h>
+
+#include "surface-source.c"
+
+struct closure {
+ EGLDisplay dpy;
+ EGLContext ctx;
+};
+
+static void
+cleanup (void *data)
+{
+ struct closure *arg = data;
+
+ eglDestroyContext (arg->dpy, arg->ctx);
+ eglMakeCurrent (arg->dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+ eglTerminate (arg->dpy);
+
+ free (arg);
+}
+
+static cairo_surface_t *
+create_source_surface (int size)
+{
+ EGLint config_attribs[] = {
+ EGL_RED_SIZE, 8,
+ EGL_GREEN_SIZE, 8,
+ EGL_BLUE_SIZE, 8,
+ EGL_ALPHA_SIZE, 8,
+ EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
+#if CAIRO_HAS_GL_SURFACE
+ EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
+#elif CAIRO_HAS_GLESV2_SURFACE
+ EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+#endif
+ EGL_NONE
+ };
+ const EGLint ctx_attribs[] = {
+#if CAIRO_HAS_GLESV2_SURFACE
+ EGL_CONTEXT_CLIENT_VERSION, 2,
+#endif
+ EGL_NONE
+ };
+
+ struct closure *arg;
+ cairo_device_t *device;
+ cairo_surface_t *surface;
+ EGLConfig config;
+ EGLint numConfigs;
+ EGLDisplay dpy;
+ EGLContext ctx;
+ int major, minor;
+
+ dpy = eglGetDisplay (EGL_DEFAULT_DISPLAY);
+ if (! eglInitialize (dpy, &major, &minor)) {
+ return NULL;
+ }
+
+ eglChooseConfig (dpy, config_attribs, &config, 1, &numConfigs);
+ if (numConfigs == 0) {
+ return NULL;
+ }
+
+#if CAIRO_HAS_GL_SURFACE
+ eglBindAPI (EGL_OPENGL_API);
+#elif CAIRO_HAS_GLESV2_SURFACE
+ eglBindAPI (EGL_OPENGL_ES_API);
+#endif
+
+ ctx = eglCreateContext (dpy, config, EGL_NO_CONTEXT,
+ ctx_attribs);
+ if (ctx == EGL_NO_CONTEXT) {
+ eglTerminate (dpy);
+ return NULL;
+ }
+
+ arg = xmalloc (sizeof (struct closure));
+ arg->dpy = dpy;
+ arg->ctx = ctx;
+ device = cairo_egl_device_create (dpy, ctx);
+ if (cairo_device_set_user_data (device,
+ (cairo_user_data_key_t *) cleanup,
+ arg,
+ cleanup))
+ {
+ cleanup (arg);
+ return NULL;
+ }
+
+ surface = cairo_gl_surface_create (device,
+ CAIRO_CONTENT_COLOR_ALPHA,
+ size, size);
+ cairo_device_destroy (device);
+
+ return surface;
+}
+
+CAIRO_TEST (egl_surface_source,
+ "Test using a EGL surface as the source",
+ "source", /* keywords */
+ NULL, /* requirements */
+ SIZE, SIZE,
+ preamble, draw)
diff --git a/test/error-setters.c b/test/error-setters.c
new file mode 100644
index 000000000..ff65ad4f2
--- /dev/null
+++ b/test/error-setters.c
@@ -0,0 +1,109 @@
+/*
+ * Copyright © 2010 Red Hat Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Benjamin Otte <otte@redhat.com>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <limits.h>
+
+#include "cairo-test.h"
+
+#if CAIRO_HAS_GL_SURFACE
+#include <cairo-gl.h>
+#endif
+#if CAIRO_HAS_OS2_SURFACE
+#include <cairo-os2.h>
+#endif
+#if CAIRO_HAS_PDF_SURFACE
+#include <cairo-pdf.h>
+#endif
+#if CAIRO_HAS_PS_SURFACE
+#include <cairo-ps.h>
+#endif
+#if CAIRO_HAS_XCB_SURFACE
+#include <cairo-xcb.h>
+#endif
+#if CAIRO_HAS_XLIB_SURFACE
+#include <cairo-xlib.h>
+#endif
+
+static cairo_test_status_t
+preamble (cairo_test_context_t *ctx)
+{
+ cairo_surface_t *surface;
+
+ /* get the error surface */
+ surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, INT_MAX, INT_MAX);
+
+#if CAIRO_HAS_GL_SURFACE
+ cairo_gl_surface_set_size (surface, 0, 0);
+ cairo_gl_surface_swapbuffers (surface);
+#endif
+
+#if CAIRO_HAS_OS2_SURFACE
+ cairo_os2_surface_set_hwnd (surface, 0);
+ cairo_os2_surface_set_size (surface, 0, 0, 0);
+ cairo_os2_surface_set_manual_window_refresh (surface, FALSE);
+#endif
+
+#if CAIRO_HAS_PDF_SURFACE
+ cairo_pdf_surface_restrict_to_version (surface, CAIRO_PDF_VERSION_1_4);
+ cairo_pdf_surface_set_size (surface, 0, 0);
+#endif
+
+#if CAIRO_HAS_PS_SURFACE
+ cairo_ps_surface_set_eps (surface, FALSE);
+ cairo_ps_surface_set_size (surface, 0, 0);
+ cairo_ps_surface_restrict_to_level (surface, CAIRO_PS_LEVEL_2);
+ cairo_ps_surface_dsc_comment (surface, NULL);
+ cairo_ps_surface_dsc_begin_setup (surface);
+ cairo_ps_surface_dsc_begin_page_setup (surface);
+#endif
+
+#if CAIRO_HAS_XCB_SURFACE
+ cairo_xcb_surface_set_size (surface, 0, 0);
+#endif
+
+#if CAIRO_HAS_XLIB_SURFACE
+ cairo_xlib_surface_set_size (surface, 0, 0);
+ cairo_xlib_surface_set_drawable (surface, 0, 0, 0);
+#endif
+
+ cairo_surface_set_mime_data (surface, NULL, NULL, 0, NULL, 0);
+ cairo_surface_set_device_offset (surface, 0, 0);
+ cairo_surface_set_fallback_resolution (surface, 0, 0);
+
+ cairo_surface_destroy (surface);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (error_setters,
+ "Check setters properly error out on read-only error surfaces",
+ NULL, /* keywords */
+ NULL, /* requirements */
+ 0, 0,
+ preamble, NULL)
diff --git a/test/extend-pad-border.c b/test/extend-pad-border.c
new file mode 100644
index 000000000..c02ec4f00
--- /dev/null
+++ b/test/extend-pad-border.c
@@ -0,0 +1,95 @@
+/*
+ * Copyright © 2007 Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Behdad Esfahbod <behdad@behdad.org>
+ */
+
+#include "cairo-test.h"
+#include <math.h>
+#include <stdio.h>
+
+#define SIZE 90
+
+/* Check the border-pixels of an EXTEND_PAD image pattern */
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_surface_t *surface;
+ cairo_t * cr_surface;
+ int surface_size = (SIZE - 30) / 10;
+
+ cairo_set_source_rgba (cr, 0, 0, 0, 1);
+ cairo_rectangle (cr, 0, 0, SIZE, SIZE);
+ cairo_fill (cr);
+
+ /* Create an image surface with my favorite four colors in each
+ * quadrant. */
+ surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24,
+ surface_size, surface_size);
+ cr_surface = cairo_create (surface);
+ cairo_surface_destroy (surface);
+
+ cairo_set_source_rgb (cr_surface, 1, 1, 1);
+ cairo_rectangle (cr_surface,
+ 0, 0,
+ surface_size / 2, surface_size / 2);
+ cairo_fill (cr_surface);
+ cairo_set_source_rgb (cr_surface, 1, 0, 0);
+ cairo_rectangle (cr_surface,
+ surface_size / 2, 0,
+ surface_size / 2, surface_size / 2);
+ cairo_fill (cr_surface);
+ cairo_set_source_rgb (cr_surface, 0, 1, 0);
+ cairo_rectangle (cr_surface,
+ 0, surface_size / 2,
+ surface_size / 2, surface_size / 2);
+ cairo_fill (cr_surface);
+ cairo_set_source_rgb (cr_surface, 0, 0, 1);
+ cairo_rectangle (cr_surface,
+ surface_size / 2, surface_size / 2,
+ surface_size / 2, surface_size / 2);
+ cairo_fill (cr_surface);
+
+ cairo_scale (cr, 10, 10);
+ cairo_set_source_surface (cr, cairo_get_target (cr_surface), 1.5, 1.5);
+ cairo_destroy (cr_surface);
+
+ /* Using EXTEND_REFLECT makes this test pass for image and xlib backends */
+ /*cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_REFLECT);*/
+
+ cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_PAD);
+ cairo_rectangle (cr, 1.5, 1.5, 6, 6);
+ cairo_clip (cr);
+
+ cairo_paint (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (extend_pad_border,
+ "Test CAIRO_EXTEND_PAD for surface patterns",
+ "extend", /* keywords */
+ NULL, /* requirements */
+ SIZE, SIZE,
+ NULL, draw)
diff --git a/test/extend-pad-similar.c b/test/extend-pad-similar.c
new file mode 100644
index 000000000..09a90f46d
--- /dev/null
+++ b/test/extend-pad-similar.c
@@ -0,0 +1,82 @@
+/*
+ * Copyright © 2007 Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Behdad Esfahbod <behdad@behdad.org>
+ */
+
+#include "cairo-test.h"
+#include <math.h>
+#include <stdio.h>
+
+#define SIZE 90
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_surface_t *surface;
+ cairo_t *cr_surface;
+
+ /* Create a 4-pixel similar surface with my favorite four colors in each
+ * quadrant. */
+ surface = cairo_surface_create_similar (cairo_get_group_target (cr),
+ CAIRO_CONTENT_COLOR, 2, 2);
+ cr_surface = cairo_create (surface);
+ cairo_surface_destroy (surface);
+
+ /* upper-left = white */
+ cairo_set_source_rgb (cr_surface, 1, 1, 1);
+ cairo_rectangle (cr_surface, 0, 0, 1, 1);
+ cairo_fill (cr_surface);
+
+ /* upper-right = red */
+ cairo_set_source_rgb (cr_surface, 1, 0, 0);
+ cairo_rectangle (cr_surface, 1, 0, 1, 1);
+ cairo_fill (cr_surface);
+
+ /* lower-left = green */
+ cairo_set_source_rgb (cr_surface, 0, 1, 0);
+ cairo_rectangle (cr_surface, 0, 1, 1, 1);
+ cairo_fill (cr_surface);
+
+ /* lower-right = blue */
+ cairo_set_source_rgb (cr_surface, 0, 0, 1);
+ cairo_rectangle (cr_surface, 1, 1, 1, 1);
+ cairo_fill (cr_surface);
+
+ /* Now use extend pad to cover the entire surface with those 4 colors */
+ cairo_set_source_surface (cr, cairo_get_target (cr_surface),
+ width/2 - 1,
+ height/2 - 1);
+ cairo_destroy (cr_surface);
+ cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_PAD);
+ cairo_paint (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (extend_pad_similar,
+ "Test CAIRO_EXTEND_PAD for similar surface patterns",
+ "extend", /* keywords */
+ NULL, /* requirements */
+ SIZE, SIZE,
+ NULL, draw)
diff --git a/test/extend-pad.c b/test/extend-pad.c
new file mode 100644
index 000000000..f851d44a4
--- /dev/null
+++ b/test/extend-pad.c
@@ -0,0 +1,81 @@
+/*
+ * Copyright © 2007 Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Behdad Esfahbod <behdad@behdad.org>
+ */
+
+#include "cairo-test.h"
+#include <math.h>
+#include <stdio.h>
+
+#define SIZE 90
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_surface_t *surface;
+ cairo_t *cr_surface;
+
+ /* Create a 4-pixel image surface with my favorite four colors in each
+ * quadrant. */
+ surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, 2, 2);
+ cr_surface = cairo_create (surface);
+ cairo_surface_destroy (surface);
+
+ /* upper-left = white */
+ cairo_set_source_rgb (cr_surface, 1, 1, 1);
+ cairo_rectangle (cr_surface, 0, 0, 1, 1);
+ cairo_fill (cr_surface);
+
+ /* upper-right = red */
+ cairo_set_source_rgb (cr_surface, 1, 0, 0);
+ cairo_rectangle (cr_surface, 1, 0, 1, 1);
+ cairo_fill (cr_surface);
+
+ /* lower-left = green */
+ cairo_set_source_rgb (cr_surface, 0, 1, 0);
+ cairo_rectangle (cr_surface, 0, 1, 1, 1);
+ cairo_fill (cr_surface);
+
+ /* lower-right = blue */
+ cairo_set_source_rgb (cr_surface, 0, 0, 1);
+ cairo_rectangle (cr_surface, 1, 1, 1, 1);
+ cairo_fill (cr_surface);
+
+ /* Now use extend pad to cover the entire surface with those 4 colors */
+ cairo_set_source_surface (cr, cairo_get_target (cr_surface),
+ width/2 - 1,
+ height/2 - 1);
+ cairo_destroy (cr_surface);
+ cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_PAD);
+ cairo_paint (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (extend_pad,
+ "Test CAIRO_EXTEND_PAD for surface patterns",
+ "extend", /* keywords */
+ NULL, /* requirements */
+ SIZE, SIZE,
+ NULL, draw)
diff --git a/test/extend-reflect-similar.c b/test/extend-reflect-similar.c
new file mode 100644
index 000000000..fa376a7bf
--- /dev/null
+++ b/test/extend-reflect-similar.c
@@ -0,0 +1,51 @@
+#include "cairo-test.h"
+
+static const char *png_filename = "romedalen.png";
+
+static cairo_surface_t *
+clone_similar_surface (cairo_surface_t * target, cairo_surface_t *surface)
+{
+ cairo_t *cr;
+ cairo_surface_t *similar;
+
+ similar = cairo_surface_create_similar (target,
+ cairo_surface_get_content (surface),
+ cairo_image_surface_get_width (surface),
+ cairo_image_surface_get_height (surface));
+ cr = cairo_create (similar);
+ cairo_surface_destroy (similar);
+ cairo_set_source_surface (cr, surface, 0, 0);
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_paint (cr);
+ similar = cairo_surface_reference (cairo_get_target (cr));
+ cairo_destroy (cr);
+
+ return similar;
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ const cairo_test_context_t *ctx = cairo_test_get_context (cr);
+ cairo_surface_t *surface;
+ cairo_surface_t *similar;
+
+ surface = cairo_test_create_surface_from_png (ctx, png_filename);
+ similar = clone_similar_surface (cairo_get_group_target (cr), surface);
+ cairo_set_source_surface (cr, similar, 32, 32);
+ cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_REFLECT);
+
+ cairo_paint (cr);
+
+ cairo_surface_destroy (similar);
+ cairo_surface_destroy (surface);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (extend_reflect_similar,
+ "Test CAIRO_EXTEND_REFLECT for surface patterns",
+ "extend", /* keywords */
+ NULL, /* requirements */
+ 256 + 32*2, 192 + 32*2,
+ NULL, draw)
diff --git a/test/extend-reflect.c b/test/extend-reflect.c
new file mode 100644
index 000000000..173befc26
--- /dev/null
+++ b/test/extend-reflect.c
@@ -0,0 +1,29 @@
+#include "cairo-test.h"
+#include <math.h>
+#include <stdio.h>
+
+static const char *png_filename = "romedalen.png";
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ const cairo_test_context_t *ctx = cairo_test_get_context (cr);
+ cairo_surface_t *surface;
+
+ surface = cairo_test_create_surface_from_png (ctx, png_filename);
+ cairo_set_source_surface (cr, surface, 32, 32);
+ cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_REFLECT);
+
+ cairo_paint (cr);
+
+ cairo_surface_destroy (surface);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (extend_reflect,
+ "Test CAIRO_EXTEND_REFLECT for surface patterns",
+ "extend", /* keywords */
+ NULL, /* requirements */
+ 256 + 32*2, 192 + 32*2,
+ NULL, draw)
diff --git a/test/extend-repeat-similar.c b/test/extend-repeat-similar.c
new file mode 100644
index 000000000..08cfd29ab
--- /dev/null
+++ b/test/extend-repeat-similar.c
@@ -0,0 +1,51 @@
+#include "cairo-test.h"
+
+static const char *png_filename = "romedalen.png";
+
+static cairo_surface_t *
+clone_similar_surface (cairo_surface_t * target, cairo_surface_t *surface)
+{
+ cairo_t *cr;
+ cairo_surface_t *similar;
+
+ similar = cairo_surface_create_similar (target,
+ cairo_surface_get_content (surface),
+ cairo_image_surface_get_width (surface),
+ cairo_image_surface_get_height (surface));
+ cr = cairo_create (similar);
+ cairo_surface_destroy (similar);
+ cairo_set_source_surface (cr, surface, 0, 0);
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_paint (cr);
+ similar = cairo_surface_reference (cairo_get_target (cr));
+ cairo_destroy (cr);
+
+ return similar;
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ const cairo_test_context_t *ctx = cairo_test_get_context (cr);
+ cairo_surface_t *surface;
+ cairo_surface_t *similar;
+
+ surface = cairo_test_create_surface_from_png (ctx, png_filename);
+ similar = clone_similar_surface (cairo_get_group_target (cr), surface);
+ cairo_set_source_surface (cr, similar, 32, 32);
+ cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_REPEAT);
+
+ cairo_paint (cr);
+
+ cairo_surface_destroy (similar);
+ cairo_surface_destroy (surface);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (extend_repeat_similar,
+ "Test CAIRO_EXTEND_REPEAT for surface patterns",
+ "extend", /* keywords */
+ NULL, /* requirements */
+ 256 + 32*2, 192 + 32*2,
+ NULL, draw)
diff --git a/test/extend-repeat.c b/test/extend-repeat.c
new file mode 100644
index 000000000..e6c0bccb6
--- /dev/null
+++ b/test/extend-repeat.c
@@ -0,0 +1,27 @@
+#include "cairo-test.h"
+
+static const char *png_filename = "romedalen.png";
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ const cairo_test_context_t *ctx = cairo_test_get_context (cr);
+ cairo_surface_t *surface;
+
+ surface = cairo_test_create_surface_from_png (ctx, png_filename);
+ cairo_set_source_surface (cr, surface, 32, 32);
+ cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_REPEAT);
+
+ cairo_paint (cr);
+
+ cairo_surface_destroy (surface);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (extend_repeat,
+ "Test CAIRO_EXTEND_REPEAT for surface patterns",
+ "extend", /* keywords */
+ NULL, /* requirements */
+ 256 + 32*2, 192 + 32*2,
+ NULL, draw)
diff --git a/test/extended-blend.c b/test/extended-blend.c
new file mode 100644
index 000000000..8edd182d6
--- /dev/null
+++ b/test/extended-blend.c
@@ -0,0 +1,256 @@
+/*
+ * Copyright © 2005 Red Hat, Inc.
+ * Copyright © 2007 Emmanuel Pacaud
+ * Copyright © 2008 Benjamin Otte
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Owen Taylor <otaylor@redhat.com>
+ * Kristian Høgsberg <krh@redhat.com>
+ * Emmanuel Pacaud <emmanuel.pacaud@lapp.in2p3.fr>
+ */
+
+#include "cairo-test.h"
+#include <math.h>
+#include <stdio.h>
+
+#define STEPS 16
+#define START_OPERATOR CAIRO_OPERATOR_MULTIPLY
+#define STOP_OPERATOR CAIRO_OPERATOR_HSL_LUMINOSITY
+
+#define SIZE 5
+#define COUNT 4
+#define FULL_WIDTH ((STEPS + 1) * COUNT - 1)
+#define FULL_HEIGHT ((COUNT + STOP_OPERATOR - START_OPERATOR) / COUNT) * (STEPS + 1)
+
+static void
+set_solid_pattern (cairo_t *cr,
+ int step,
+ cairo_bool_t bg,
+ cairo_bool_t alpha)
+{
+ double c, a;
+
+ a = ((double) step) / (STEPS - 1);
+ if (alpha) {
+ c = 1;
+ } else {
+ c = a;
+ a = 1;
+ }
+
+ if (bg) /* draw a yellow background fading in using discrete steps */
+ cairo_set_source_rgba (cr, c, c, 0, a);
+ else /* draw a teal foreground pattern fading in using discrete steps */
+ cairo_set_source_rgba (cr, 0, c, c, a);
+}
+
+/* expects a STEP*STEP pixel rectangle */
+static void
+do_blend_solid (cairo_t *cr, cairo_operator_t op, cairo_bool_t alpha)
+{
+ int x;
+
+ cairo_save (cr);
+ cairo_scale (cr, SIZE, SIZE);
+
+ /* not using CAIRO_OPERATOR_SOURCE here, it triggers a librsvg bug */
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+ for (x = 0; x < STEPS; x++) {
+ /* draw the background using discrete steps */
+ set_solid_pattern (cr, x, TRUE, alpha);
+ cairo_rectangle (cr, x, 0, 1, STEPS);
+ cairo_fill (cr);
+ }
+
+ cairo_set_operator (cr, op);
+ for (x = 0; x < STEPS; x++) {
+ /* draw an orthogonal foreground pattern using discrete steps */
+ set_solid_pattern (cr, x, FALSE, alpha);
+ cairo_rectangle (cr, 0, x, STEPS, 1);
+ cairo_fill (cr);
+ }
+
+ cairo_restore (cr);
+}
+
+static void
+create_patterns (cairo_t *cr,
+ cairo_surface_t **bg,
+ cairo_surface_t **fg,
+ cairo_bool_t alpha)
+{
+ cairo_t *bgcr, *fgcr;
+
+ *bg = cairo_surface_create_similar (cairo_get_target (cr),
+ CAIRO_CONTENT_COLOR_ALPHA,
+ SIZE * STEPS,
+ SIZE * STEPS);
+ *fg = cairo_surface_create_similar (cairo_get_target (cr),
+ CAIRO_CONTENT_COLOR_ALPHA,
+ SIZE * STEPS,
+ SIZE * STEPS);
+
+ bgcr = cairo_create (*bg);
+ fgcr = cairo_create (*fg);
+
+ do_blend_solid (bgcr, CAIRO_OPERATOR_DEST, alpha);
+ do_blend_solid (fgcr, CAIRO_OPERATOR_SOURCE, alpha);
+
+ cairo_destroy (bgcr);
+ cairo_destroy (fgcr);
+}
+
+/* expects a STEP*STEP pixel rectangle */
+static void
+do_blend (cairo_t *cr, cairo_operator_t op, cairo_bool_t alpha)
+{
+ cairo_surface_t *bg, *fg;
+
+ create_patterns (cr, &bg, &fg, alpha);
+
+ /* not using CAIRO_OPERATOR_SOURCE here, it triggers a librsvg bug */
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+ cairo_set_source_surface (cr, bg, 0, 0);
+ cairo_paint (cr);
+
+ cairo_set_operator (cr, op);
+ cairo_set_source_surface (cr, fg, 0, 0);
+ cairo_paint (cr);
+
+ cairo_surface_destroy (fg);
+ cairo_surface_destroy (bg);
+}
+
+static void
+do_blend_mask (cairo_t *cr, cairo_operator_t op, cairo_bool_t alpha)
+{
+ cairo_surface_t *bg, *fg;
+
+ create_patterns (cr, &bg, &fg, alpha);
+
+ /* not using CAIRO_OPERATOR_SOURCE here, it triggers a librsvg bug */
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+ cairo_set_source_surface (cr, bg, 0, 0);
+ cairo_paint (cr);
+
+ cairo_set_operator (cr, op);
+ cairo_set_source_surface (cr, fg, 0, 0);
+ cairo_paint_with_alpha (cr, .5);
+
+ cairo_surface_destroy (fg);
+ cairo_surface_destroy (bg);
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, cairo_bool_t alpha,
+ void (*blend)(cairo_t *, cairo_operator_t, cairo_bool_t))
+{
+ size_t i = 0;
+ cairo_operator_t op;
+
+ for (op = START_OPERATOR; op <= STOP_OPERATOR; op++, i++) {
+ cairo_save (cr);
+ cairo_translate (cr,
+ SIZE * (STEPS + 1) * (i % COUNT),
+ SIZE * (STEPS + 1) * (i / COUNT));
+ blend (cr, op, alpha);
+ cairo_restore (cr);
+ }
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+draw_extended_blend (cairo_t *cr, int width, int height)
+{
+ return draw (cr, FALSE, do_blend);
+}
+
+static cairo_test_status_t
+draw_extended_blend_alpha (cairo_t *cr, int width, int height)
+{
+ return draw (cr, TRUE, do_blend);
+}
+
+static cairo_test_status_t
+draw_extended_blend_solid (cairo_t *cr, int width, int height)
+{
+ return draw (cr, FALSE, do_blend_solid);
+}
+
+static cairo_test_status_t
+draw_extended_blend_solid_alpha (cairo_t *cr, int width, int height)
+{
+ return draw (cr, TRUE, do_blend_solid);
+}
+
+static cairo_test_status_t
+draw_extended_blend_mask (cairo_t *cr, int width, int height)
+{
+ return draw (cr, FALSE, do_blend_mask);
+}
+static cairo_test_status_t
+draw_extended_blend_alpha_mask (cairo_t *cr, int width, int height)
+{
+ return draw (cr, TRUE, do_blend_mask);
+}
+
+CAIRO_TEST (extended_blend,
+ "Tests extended blend modes without alpha",
+ "operator", /* keywords */
+ NULL, /* requirements */
+ FULL_WIDTH * SIZE, FULL_HEIGHT * SIZE,
+ NULL, draw_extended_blend)
+
+CAIRO_TEST (extended_blend_alpha,
+ "Tests extended blend modes with alpha",
+ "operator", /* keywords */
+ NULL, /* requirements */
+ FULL_WIDTH * SIZE, FULL_HEIGHT * SIZE,
+ NULL, draw_extended_blend_alpha)
+
+CAIRO_TEST (extended_blend_mask,
+ "Tests extended blend modes with an alpha mask",
+ "operator,mask", /* keywords */
+ NULL, /* requirements */
+ FULL_WIDTH * SIZE, FULL_HEIGHT * SIZE,
+ NULL, draw_extended_blend_mask)
+CAIRO_TEST (extended_blend_alpha_mask,
+ "Tests extended blend modes with an alpha mask",
+ "operator,mask", /* keywords */
+ NULL, /* requirements */
+ FULL_WIDTH * SIZE, FULL_HEIGHT * SIZE,
+ NULL, draw_extended_blend_alpha_mask)
+
+
+CAIRO_TEST (extended_blend_solid,
+ "Tests extended blend modes on solid patterns without alpha",
+ "operator", /* keywords */
+ NULL, /* requirements */
+ FULL_WIDTH * SIZE, FULL_HEIGHT * SIZE,
+ NULL, draw_extended_blend_solid)
+
+CAIRO_TEST (extended_blend_solid_alpha,
+ "Tests extended blend modes on solid patterns with alpha",
+ "operator", /* keywords */
+ NULL, /* requirements */
+ FULL_WIDTH * SIZE, FULL_HEIGHT * SIZE,
+ NULL, draw_extended_blend_solid_alpha)
diff --git a/test/fallback-resolution.c b/test/fallback-resolution.c
new file mode 100644
index 000000000..306a57013
--- /dev/null
+++ b/test/fallback-resolution.c
@@ -0,0 +1,517 @@
+/*
+ * Copyright © 2006 Red Hat, Inc.
+ * Copyright © 2008 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ * Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <cairo.h>
+
+#if CAIRO_HAS_PDF_SURFACE
+#include <cairo-pdf.h>
+#endif
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#include <errno.h>
+#endif
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+
+#include "cairo-test.h"
+#include "buffer-diff.h"
+
+/* This test exists to test cairo_surface_set_fallback_resolution
+ *
+ * <behdad> one more thing.
+ * if you can somehow incorporate cairo_show_page stuff in the
+ * test suite. such that fallback-resolution can actually be
+ * automated..
+ * if we could get a callback on surface when that function is
+ * called, we could do cool stuff like making other backends
+ * draw a long strip of images, one for each page...
+ */
+
+#define INCHES_TO_POINTS(in) ((in) * 72.0)
+#define SIZE INCHES_TO_POINTS(2)
+
+/* cairo_set_tolerance() is not respected by the PS/PDF backends currently */
+#define SET_TOLERANCE 0
+
+#define GENERATE_REFERENCE 0
+
+static void
+draw (cairo_t *cr, double width, double height)
+{
+ const char *text = "cairo";
+ cairo_text_extents_t extents;
+ const double dash[2] = { 8, 16 };
+ cairo_pattern_t *pattern;
+
+ cairo_save (cr);
+
+ cairo_new_path (cr);
+
+ cairo_set_line_width (cr, .05 * SIZE / 2.0);
+
+ cairo_arc (cr, SIZE / 2.0, SIZE / 2.0,
+ 0.875 * SIZE / 2.0,
+ 0, 2.0 * M_PI);
+ cairo_stroke (cr);
+
+ /* use dashes to demonstrate bugs:
+ * https://bugs.freedesktop.org/show_bug.cgi?id=9189
+ * https://bugs.freedesktop.org/show_bug.cgi?id=17223
+ */
+ cairo_save (cr);
+ cairo_set_dash (cr, dash, 2, 0);
+ cairo_arc (cr, SIZE / 2.0, SIZE / 2.0,
+ 0.75 * SIZE / 2.0,
+ 0, 2.0 * M_PI);
+ cairo_stroke (cr);
+ cairo_restore (cr);
+
+ cairo_save (cr);
+ cairo_rectangle (cr, 0, 0, SIZE/2, SIZE);
+ cairo_clip (cr);
+ cairo_arc (cr, SIZE / 2.0, SIZE / 2.0,
+ 0.6 * SIZE / 2.0,
+ 0, 2.0 * M_PI);
+ cairo_fill (cr);
+ cairo_restore (cr);
+
+ /* use a pattern to exercise bug:
+ * https://bugs.launchpad.net/inkscape/+bug/234546
+ */
+ cairo_save (cr);
+ cairo_rectangle (cr, SIZE/2, 0, SIZE/2, SIZE);
+ cairo_clip (cr);
+ pattern = cairo_pattern_create_linear (SIZE/2, 0, SIZE, 0);
+ cairo_pattern_add_color_stop_rgba (pattern, 0, 0, 0, 0, 1.);
+ cairo_pattern_add_color_stop_rgba (pattern, 1, 0, 0, 0, 0.);
+ cairo_set_source (cr, pattern);
+ cairo_pattern_destroy (pattern);
+ cairo_arc (cr, SIZE / 2.0, SIZE / 2.0,
+ 0.6 * SIZE / 2.0,
+ 0, 2.0 * M_PI);
+ cairo_fill (cr);
+ cairo_restore (cr);
+
+ cairo_set_source_rgb (cr, 1, 1, 1); /* white */
+ cairo_set_font_size (cr, .25 * SIZE / 2.0);
+ cairo_text_extents (cr, text, &extents);
+ cairo_move_to (cr, (SIZE-extents.width)/2.0-extents.x_bearing,
+ (SIZE-extents.height)/2.0-extents.y_bearing);
+ cairo_show_text (cr, text);
+
+ cairo_restore (cr);
+}
+
+static void
+_xunlink (const cairo_test_context_t *ctx, const char *pathname)
+{
+ if (unlink (pathname) < 0 && errno != ENOENT) {
+ cairo_test_log (ctx, "Error: Cannot remove %s: %s\n",
+ pathname, strerror (errno));
+ exit (1);
+ }
+}
+
+static cairo_bool_t
+check_result (cairo_test_context_t *ctx,
+ const cairo_boilerplate_target_t *target,
+ const char *test_name,
+ const char *base_name,
+ cairo_surface_t *surface)
+{
+ const char *format;
+ char *ref_name;
+ char *png_name;
+ char *diff_name;
+ cairo_surface_t *test_image, *ref_image, *diff_image;
+ buffer_diff_result_t result;
+ cairo_status_t status;
+ cairo_bool_t ret;
+
+ /* XXX log target, OUTPUT, REFERENCE, DIFFERENCE for index.html */
+
+ if (target->finish_surface != NULL) {
+ status = target->finish_surface (surface);
+ if (status) {
+ cairo_test_log (ctx, "Error: Failed to finish surface: %s\n",
+ cairo_status_to_string (status));
+ cairo_surface_destroy (surface);
+ return FALSE;
+ }
+ }
+
+ xasprintf (&png_name, "%s.out.png", base_name);
+ xasprintf (&diff_name, "%s.diff.png", base_name);
+
+ test_image = target->get_image_surface (surface, 0, SIZE, SIZE);
+ if (cairo_surface_status (test_image)) {
+ cairo_test_log (ctx, "Error: Failed to extract page: %s\n",
+ cairo_status_to_string (cairo_surface_status (test_image)));
+ cairo_surface_destroy (test_image);
+ free (png_name);
+ free (diff_name);
+ return FALSE;
+ }
+
+ _xunlink (ctx, png_name);
+ status = cairo_surface_write_to_png (test_image, png_name);
+ if (status) {
+ cairo_test_log (ctx, "Error: Failed to write output image: %s\n",
+ cairo_status_to_string (status));
+ cairo_surface_destroy (test_image);
+ free (png_name);
+ free (diff_name);
+ return FALSE;
+ }
+
+ format = cairo_boilerplate_content_name (target->content);
+ ref_name = cairo_test_reference_filename (ctx,
+ base_name,
+ test_name,
+ target->name,
+ target->basename,
+ format,
+ CAIRO_TEST_REF_SUFFIX,
+ CAIRO_TEST_PNG_EXTENSION);
+ if (ref_name == NULL) {
+ cairo_test_log (ctx, "Error: Cannot find reference image for %s\n",
+ base_name);
+ cairo_surface_destroy (test_image);
+ free (png_name);
+ free (diff_name);
+ return FALSE;
+ }
+
+
+ ref_image = cairo_test_get_reference_image (ctx, ref_name,
+ target->content == CAIRO_TEST_CONTENT_COLOR_ALPHA_FLATTENED);
+ if (cairo_surface_status (ref_image)) {
+ cairo_test_log (ctx, "Error: Cannot open reference image for %s: %s\n",
+ ref_name,
+ cairo_status_to_string (cairo_surface_status (ref_image)));
+ cairo_surface_destroy (ref_image);
+ cairo_surface_destroy (test_image);
+ free (png_name);
+ free (diff_name);
+ free (ref_name);
+ return FALSE;
+ }
+
+ diff_image = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
+ SIZE, SIZE);
+
+ ret = TRUE;
+ status = image_diff (ctx,
+ test_image, ref_image, diff_image,
+ &result);
+ _xunlink (ctx, diff_name);
+ if (status) {
+ cairo_test_log (ctx, "Error: Failed to compare images: %s\n",
+ cairo_status_to_string (status));
+ ret = FALSE;
+ } else if (image_diff_is_failure (&result, target->error_tolerance))
+ {
+ ret = FALSE;
+
+ status = cairo_surface_write_to_png (diff_image, diff_name);
+ if (status) {
+ cairo_test_log (ctx, "Error: Failed to write differences image: %s\n",
+ cairo_status_to_string (status));
+ }
+ }
+
+ cairo_surface_destroy (test_image);
+ cairo_surface_destroy (diff_image);
+ free (png_name);
+ free (diff_name);
+ free (ref_name);
+
+ return ret;
+}
+
+#if GENERATE_REFERENCE
+static void
+generate_reference (double ppi_x, double ppi_y, const char *filename)
+{
+ cairo_surface_t *surface, *target;
+ cairo_t *cr;
+ cairo_status_t status;
+
+ surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24,
+ SIZE*ppi_x/72, SIZE*ppi_y/72);
+ cr = cairo_create (surface);
+ cairo_surface_destroy (surface);
+
+ /* As we wish to mimic a PDF surface, copy across the default font options
+ * from the PDF backend.
+ */
+ {
+ cairo_surface_t *pdf;
+ cairo_font_options_t *options;
+
+ options = cairo_font_options_create ();
+
+#if CAIRO_HAS_PDF_SURFACE
+ pdf = cairo_pdf_surface_create ("tmp.pdf", 1, 1);
+ cairo_surface_get_font_options (pdf, options);
+ cairo_surface_destroy (pdf);
+#endif
+
+ cairo_set_font_options (cr, options);
+ cairo_font_options_destroy (options);
+ }
+
+#if SET_TOLERANCE
+ cairo_set_tolerance (cr, 3.0);
+#endif
+
+ cairo_save (cr); {
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+ } cairo_restore (cr);
+
+ cairo_scale (cr, ppi_x/72., ppi_y/72.);
+ draw (cr, SIZE, SIZE);
+
+ surface = cairo_surface_reference (cairo_get_target (cr));
+ cairo_destroy (cr);
+
+ target = cairo_image_surface_create (CAIRO_FORMAT_RGB24, SIZE, SIZE);
+ cr = cairo_create (target);
+ cairo_scale (cr, 72./ppi_x, 72./ppi_y);
+ cairo_set_source_surface (cr, surface, 0, 0);
+ cairo_paint (cr);
+
+ status = cairo_surface_write_to_png (cairo_get_target (cr), filename);
+ cairo_destroy (cr);
+
+ if (status) {
+ fprintf (stderr, "Failed to generate reference image '%s': %s\n",
+ filename, cairo_status_to_string (status));
+ exit (1);
+ }
+}
+#endif
+
+/* TODO: Split each ppi case out to its own CAIRO_TEST() test case */
+static cairo_test_status_t
+preamble (cairo_test_context_t *ctx)
+{
+ cairo_t *cr;
+ cairo_test_status_t ret = CAIRO_TEST_UNTESTED;
+ struct {
+ double x, y;
+ } ppi[] = {
+ { 576, 576 },
+ { 576, 72 },
+
+ { 288, 288 },
+ { 288, 72 },
+
+ { 144, 144 },
+ { 144, 72 },
+
+ { 72, 576 },
+ { 72, 288 },
+ { 72, 144 },
+ { 72, 72 },
+ };
+ unsigned int i;
+ int n, num_ppi;
+ const char *path = cairo_test_mkdir (CAIRO_TEST_OUTPUT_DIR) ? CAIRO_TEST_OUTPUT_DIR : ".";
+
+ num_ppi = ARRAY_LENGTH (ppi);
+
+#if GENERATE_REFERENCE
+ for (n = 0; n < num_ppi; n++) {
+ char *ref_name;
+ xasprintf (&ref_name, "reference/fallback-resolution.ppi%gx%g.ref.png",
+ ppi[n].x, ppi[n].y);
+ generate_reference (ppi[n].x, ppi[n].y, ref_name);
+ free (ref_name);
+ }
+#endif
+
+ for (i = 0; i < ctx->num_targets; i++) {
+ const cairo_boilerplate_target_t *target = ctx->targets_to_test[i];
+ cairo_surface_t *surface = NULL;
+ char *base_name;
+ void *closure;
+ const char *format;
+ cairo_status_t status;
+
+ if (! target->is_vector)
+ continue;
+
+ if (! cairo_test_is_target_enabled (ctx, target->name))
+ continue;
+
+ format = cairo_boilerplate_content_name (target->content);
+ xasprintf (&base_name, "%s/fallback-resolution.%s.%s",
+ path, target->name,
+ format);
+
+ surface = (target->create_surface) (base_name,
+ target->content,
+ SIZE, SIZE,
+ SIZE, SIZE,
+ CAIRO_BOILERPLATE_MODE_TEST,
+ &closure);
+
+ if (surface == NULL) {
+ free (base_name);
+ continue;
+ }
+
+ if (ret == CAIRO_TEST_UNTESTED)
+ ret = CAIRO_TEST_SUCCESS;
+
+ cairo_surface_destroy (surface);
+ if (target->cleanup)
+ target->cleanup (closure);
+ free (base_name);
+
+ /* we need to recreate the surface for each resolution as we include
+ * SVG in testing which does not support the paginated interface.
+ */
+ for (n = 0; n < num_ppi; n++) {
+ char *test_name;
+ cairo_bool_t pass;
+
+ xasprintf (&test_name, "fallback-resolution.ppi%gx%g",
+ ppi[n].x, ppi[n].y);
+ xasprintf (&base_name, "%s/%s.%s.%s",
+ path, test_name,
+ target->name,
+ format);
+
+ surface = (target->create_surface) (base_name,
+ target->content,
+ SIZE + 25, SIZE + 25,
+ SIZE + 25, SIZE + 25,
+ CAIRO_BOILERPLATE_MODE_TEST,
+ &closure);
+ if (surface == NULL || cairo_surface_status (surface)) {
+ cairo_test_log (ctx, "Failed to generate surface: %s.%s\n",
+ target->name,
+ format);
+ free (base_name);
+ free (test_name);
+ ret = CAIRO_TEST_FAILURE;
+ continue;
+ }
+
+ cairo_test_log (ctx,
+ "Testing fallback-resolution %gx%g with %s target\n",
+ ppi[n].x, ppi[n].y, target->name);
+ printf ("%s:\t", base_name);
+ fflush (stdout);
+
+ if (target->force_fallbacks != NULL)
+ target->force_fallbacks (surface, ppi[n].x, ppi[n].y);
+ cr = cairo_create (surface);
+#if SET_TOLERANCE
+ cairo_set_tolerance (cr, 3.0);
+#endif
+
+ cairo_surface_set_device_offset (surface, 25, 25);
+
+ cairo_save (cr); {
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+ } cairo_restore (cr);
+
+ /* First draw the top half in a conventional way. */
+ cairo_save (cr); {
+ cairo_rectangle (cr, 0, 0, SIZE, SIZE / 2.0);
+ cairo_clip (cr);
+
+ draw (cr, SIZE, SIZE);
+ } cairo_restore (cr);
+
+ /* Then draw the bottom half in a separate group,
+ * (exposing a bug in 1.6.4 with the group not being
+ * rendered with the correct fallback resolution). */
+ cairo_save (cr); {
+ cairo_rectangle (cr, 0, SIZE / 2.0, SIZE, SIZE / 2.0);
+ cairo_clip (cr);
+
+ cairo_push_group (cr); {
+ draw (cr, SIZE, SIZE);
+ } cairo_pop_group_to_source (cr);
+
+ cairo_paint (cr);
+ } cairo_restore (cr);
+
+ status = cairo_status (cr);
+ cairo_destroy (cr);
+
+ pass = FALSE;
+ if (status) {
+ cairo_test_log (ctx, "Error: Failed to create target surface: %s\n",
+ cairo_status_to_string (status));
+ ret = CAIRO_TEST_FAILURE;
+ } else {
+ /* extract the image and compare it to our reference */
+ if (! check_result (ctx, target, test_name, base_name, surface))
+ ret = CAIRO_TEST_FAILURE;
+ else
+ pass = TRUE;
+ }
+ cairo_surface_destroy (surface);
+ if (target->cleanup)
+ target->cleanup (closure);
+
+ free (base_name);
+ free (test_name);
+
+ if (pass) {
+ printf ("PASS\n");
+ } else {
+ printf ("FAIL\n");
+ }
+ fflush (stdout);
+ }
+ }
+
+ return ret;
+}
+
+CAIRO_TEST (fallback_resolution,
+ "Check handling of fallback resolutions",
+ "fallback", /* keywords */
+ NULL, /* requirements */
+ 0, 0,
+ preamble, NULL)
diff --git a/test/fallback.c b/test/fallback.c
new file mode 100644
index 000000000..a3cfc401c
--- /dev/null
+++ b/test/fallback.c
@@ -0,0 +1,79 @@
+/*
+ * Copyright © 2012 Adrian Johnson
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Adrian Johnson <ajohnson@redneon.com>
+ */
+
+#include "cairo-test.h"
+
+#define SIZE 40
+#define WIDTH (7*SIZE)
+#define HEIGHT (5*SIZE)
+
+#define FALLBACK_RES_X 300
+#define FALLBACK_RES_Y 150
+
+static void
+rectangles (cairo_t *cr)
+{
+ cairo_save (cr);
+
+ cairo_rotate (cr, M_PI/8);
+ cairo_translate (cr, 2*SIZE, SIZE/16);
+ cairo_scale (cr, 1.5, 1.5);
+
+ cairo_rectangle (cr, 0, 0, SIZE, SIZE);
+ cairo_set_source_rgba (cr, 1, 0, 0, 0.5);
+ cairo_fill (cr);
+
+ /* Select an operator not supported by PDF/PS/SVG to trigger fallback */
+ cairo_set_operator (cr, CAIRO_OPERATOR_SATURATE);
+
+ cairo_rectangle (cr, SIZE/2, SIZE/2, SIZE, SIZE);
+ cairo_set_source_rgba (cr, 0, 1, 0, 0.5);
+ cairo_fill (cr);
+
+ cairo_restore (cr);
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_surface_set_fallback_resolution (cairo_get_target (cr), FALLBACK_RES_X, FALLBACK_RES_Y);
+
+ rectangles (cr);
+ cairo_translate (cr, 3*SIZE, 0);
+ cairo_push_group (cr);
+ rectangles (cr);
+ cairo_pop_group_to_source (cr);
+ cairo_paint (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (fallback,
+ "Check that fallback images are correct when fallback resolution is not 72ppi",
+ "fallback", /* keywords */
+ NULL, /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw)
diff --git a/test/fill-alpha-pattern.c b/test/fill-alpha-pattern.c
new file mode 100644
index 000000000..3698779c1
--- /dev/null
+++ b/test/fill-alpha-pattern.c
@@ -0,0 +1,87 @@
+/*
+ * Copyright © 2008 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Chris Wilson not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Chris Wilson makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+#define SIZE 60 /* needs to be big to check large area effects (dithering) */
+#define PAD 2
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ const double alpha = 1./3;
+ cairo_pattern_t *pattern;
+ int n;
+
+ /* draw a simple pattern behind */
+ pattern = cairo_pattern_create_linear (0, 0, width, height);
+ cairo_pattern_add_color_stop_rgb (pattern, 0, 1, 1, 0);
+ cairo_pattern_add_color_stop_rgb (pattern, 1, 1, 1, 1);
+ cairo_set_source (cr, pattern);
+ cairo_pattern_destroy (pattern);
+ cairo_paint (cr);
+
+ /* square */
+ cairo_rectangle (cr, PAD, PAD, SIZE, SIZE);
+ cairo_set_source_rgba (cr, 1, 0, 0, alpha);
+ cairo_fill (cr);
+
+ /* circle */
+ cairo_translate (cr, SIZE + 2 * PAD, 0);
+ cairo_arc (cr, PAD + SIZE / 2., PAD + SIZE / 2., SIZE / 2., 0, 2 * M_PI);
+ cairo_set_source_rgba (cr, 0, 1, 0, alpha);
+ cairo_fill (cr);
+
+ /* triangle */
+ cairo_translate (cr, 0, SIZE + 2 * PAD);
+ cairo_move_to (cr, PAD + SIZE / 2, PAD);
+ cairo_line_to (cr, PAD + SIZE, PAD + SIZE);
+ cairo_line_to (cr, PAD, PAD + SIZE);
+ cairo_set_source_rgba (cr, 0, 0, 1, alpha);
+ cairo_fill (cr);
+
+ /* star */
+ cairo_translate (cr, -(SIZE + 2 * PAD) + SIZE/2., SIZE/2.);
+ for (n = 0; n < 5; n++) {
+ cairo_line_to (cr,
+ SIZE/2 * cos (2*n * 2*M_PI / 10),
+ SIZE/2 * sin (2*n * 2*M_PI / 10));
+
+ cairo_line_to (cr,
+ SIZE/4 * cos ((2*n+1)*2*M_PI / 10),
+ SIZE/4 * sin ((2*n+1)*2*M_PI / 10));
+ }
+ cairo_set_source_rgba (cr, 0, 0, 0, alpha);
+ cairo_fill (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (fill_alpha_pattern,
+ "Tests using set_rgba();fill() over a linear gradient",
+ "fill, alpha", /* keywords */
+ NULL, /* requirements */
+ 2*SIZE + 4*PAD, 2*SIZE + 4*PAD,
+ NULL, draw)
diff --git a/test/fill-alpha.c b/test/fill-alpha.c
new file mode 100644
index 000000000..6c2948dfa
--- /dev/null
+++ b/test/fill-alpha.c
@@ -0,0 +1,82 @@
+/*
+ * Copyright © 2008 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Chris Wilson not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Chris Wilson makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+#define SIZE 60 /* needs to be big to check large area effects (dithering) */
+#define PAD 2
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ const double alpha = 1./3;
+ int n;
+
+ /* flatten to white */
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+ /* square */
+ cairo_rectangle (cr, PAD, PAD, SIZE, SIZE);
+ cairo_set_source_rgba (cr, 1, 0, 0, alpha);
+ cairo_fill (cr);
+
+ /* circle */
+ cairo_translate (cr, SIZE + 2 * PAD, 0);
+ cairo_arc (cr, PAD + SIZE / 2., PAD + SIZE / 2., SIZE / 2., 0, 2 * M_PI);
+ cairo_set_source_rgba (cr, 0, 1, 0, alpha);
+ cairo_fill (cr);
+
+ /* triangle */
+ cairo_translate (cr, 0, SIZE + 2 * PAD);
+ cairo_move_to (cr, PAD + SIZE / 2, PAD);
+ cairo_line_to (cr, PAD + SIZE, PAD + SIZE);
+ cairo_line_to (cr, PAD, PAD + SIZE);
+ cairo_set_source_rgba (cr, 0, 0, 1, alpha);
+ cairo_fill (cr);
+
+ /* star */
+ cairo_translate (cr, -(SIZE + 2 * PAD) + SIZE/2., SIZE/2.);
+ for (n = 0; n < 5; n++) {
+ cairo_line_to (cr,
+ SIZE/2 * cos (2*n * 2*M_PI / 10),
+ SIZE/2 * sin (2*n * 2*M_PI / 10));
+
+ cairo_line_to (cr,
+ SIZE/4 * cos ((2*n+1)*2*M_PI / 10),
+ SIZE/4 * sin ((2*n+1)*2*M_PI / 10));
+ }
+ cairo_set_source_rgba (cr, 0, 0, 0, alpha);
+ cairo_fill (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (fill_alpha,
+ "Tests using set_rgba();fill()",
+ "fill, alpha", /* keywords */
+ NULL, /* requirements */
+ 2*SIZE + 4*PAD, 2*SIZE + 4*PAD,
+ NULL, draw)
diff --git a/test/fill-and-stroke-alpha-add.c b/test/fill-and-stroke-alpha-add.c
new file mode 100644
index 000000000..55cd4c6a2
--- /dev/null
+++ b/test/fill-and-stroke-alpha-add.c
@@ -0,0 +1,107 @@
+/*
+ * Copyright © 2005 Red Hat, Inc.
+ * Copyright © 2006 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+#include "cairo-test.h"
+
+#define PAD 2
+#define SIZE 10
+
+typedef void (*path_func_t) (cairo_t *cr);
+
+static void
+rectangle (cairo_t *cr)
+{
+ cairo_rectangle (cr, PAD, PAD, SIZE, SIZE);
+}
+
+static void
+circle (cairo_t *cr)
+{
+ cairo_arc (cr,
+ PAD + SIZE / 2, PAD + SIZE / 2,
+ SIZE / 2,
+ 0, 2 * M_PI);
+}
+
+/* Given a path-generating function and two possibly translucent
+ * patterns, fill and stroke the path with the patterns (to an
+ * offscreen group), then blend the result into the destination.
+ */
+static void
+fill_and_stroke (cairo_t *cr,
+ path_func_t path_func,
+ cairo_pattern_t *fill_pattern,
+ cairo_pattern_t *stroke_pattern)
+{
+ cairo_push_group (cr);
+ {
+ (path_func) (cr);
+ cairo_set_source (cr, fill_pattern);
+ cairo_fill_preserve (cr);
+
+ /* Use DEST_OUT to subtract stroke from fill. */
+ cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
+ cairo_set_operator (cr, CAIRO_OPERATOR_DEST_OUT);
+ cairo_stroke_preserve (cr);
+
+ /* Then use ADD to draw the stroke without a seam. */
+ cairo_set_source (cr, stroke_pattern);
+ cairo_set_operator (cr, CAIRO_OPERATOR_ADD);
+ cairo_stroke (cr);
+ }
+ cairo_pop_group_to_source (cr);
+ cairo_paint (cr);
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_pattern_t *blue;
+ cairo_pattern_t *red;
+
+ blue = cairo_pattern_create_rgba (0.0, 0.0, 1.0, 0.8);
+ red = cairo_pattern_create_rgba (1.0, 0.0, 0.0, 0.2);
+
+ cairo_test_paint_checkered (cr);
+
+ fill_and_stroke (cr, rectangle, blue, red);
+
+ cairo_translate (cr, SIZE + 2 * PAD, 0);
+
+ fill_and_stroke (cr, circle, red, blue);
+
+ cairo_pattern_destroy (blue);
+ cairo_pattern_destroy (red);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (fill_and_stroke_alpha_add,
+ "Use a group to fill/stroke a path (each with different alpha) using DEST_OUT and ADD to combine",
+ "fill-and-stroke, fill, stroke", /* keywords */
+ NULL, /* requirements */
+ 2 * SIZE + 4 * PAD, SIZE + 2 * PAD,
+ NULL, draw)
diff --git a/test/fill-and-stroke-alpha.c b/test/fill-and-stroke-alpha.c
new file mode 100644
index 000000000..c6d7c0062
--- /dev/null
+++ b/test/fill-and-stroke-alpha.c
@@ -0,0 +1,101 @@
+/*
+ * Copyright © 2005 Red Hat, Inc.
+ * Copyright © 2006 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+#include "cairo-test.h"
+
+#define PAD 2
+#define SIZE 10
+
+typedef void (*path_func_t) (cairo_t *cr);
+
+static void
+rectangle (cairo_t *cr)
+{
+ cairo_rectangle (cr, PAD, PAD, SIZE, SIZE);
+}
+
+static void
+circle (cairo_t *cr)
+{
+ cairo_arc (cr,
+ PAD + SIZE / 2, PAD + SIZE / 2,
+ SIZE / 2,
+ 0, 2 * M_PI);
+}
+
+/* Given a path-generating function and two opaque patterns, fill and
+ * stroke the path with the patterns (to an offscreen group), then
+ * blend the result into the destination with the given alpha
+ * value.
+ */
+static void
+fill_and_stroke_alpha (cairo_t *cr,
+ path_func_t path_func,
+ cairo_pattern_t *fill_pattern,
+ cairo_pattern_t *stroke_pattern,
+ double alpha)
+{
+ cairo_push_group (cr);
+ {
+ (path_func) (cr);
+ cairo_set_source (cr, fill_pattern);
+ cairo_fill_preserve (cr);
+ cairo_set_source (cr, stroke_pattern);
+ cairo_stroke (cr);
+ }
+ cairo_pop_group_to_source (cr);
+ cairo_paint_with_alpha (cr, alpha);
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_pattern_t *blue;
+ cairo_pattern_t *red;
+
+ blue = cairo_pattern_create_rgb (0.0, 0.0, 1.0);
+ red = cairo_pattern_create_rgb (1.0, 0.0, 0.0);
+
+ cairo_test_paint_checkered (cr);
+
+ fill_and_stroke_alpha (cr, rectangle, blue, red, 0.5);
+
+ cairo_translate (cr, SIZE + 2 * PAD, 0);
+
+ fill_and_stroke_alpha (cr, circle, red, blue, 0.5);
+
+ cairo_pattern_destroy (blue);
+ cairo_pattern_destroy (red);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (fill_and_stroke_alpha,
+ "Use a group to fill/stroke a path then blend the result with alpha onto the destination",
+ "fill-and-stroke, fill, stroke", /* keywords */
+ NULL, /* requirements */
+ 2 * SIZE + 4 * PAD, SIZE + 2 * PAD,
+ NULL, draw)
diff --git a/test/fill-and-stroke.c b/test/fill-and-stroke.c
new file mode 100644
index 000000000..c983c3299
--- /dev/null
+++ b/test/fill-and-stroke.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright © 2005 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+#include "cairo-test.h"
+
+#define PAD 2
+#define SIZE 10
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_rectangle (cr, PAD, PAD, SIZE, SIZE);
+ cairo_set_source_rgb (cr, 0, 0, 1);
+ cairo_fill_preserve (cr);
+ cairo_set_source_rgb (cr, 1, 0, 0);
+ cairo_stroke (cr);
+
+ cairo_translate (cr, SIZE + 2 * PAD, 0);
+
+ cairo_arc (cr,
+ PAD + SIZE / 2, PAD + SIZE / 2,
+ SIZE / 2,
+ 0, 2 * M_PI);
+ cairo_fill_preserve (cr);
+ cairo_set_source_rgb (cr, 0, 0, 1);
+ cairo_stroke (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (fill_and_stroke,
+ "Tests using cairo_fill_preserve/cairo_stroke to fill/stroke the same path",
+ "fill-and-stroke, fill, stroke", /* keywords */
+ NULL, /* requirements */
+ 2 * SIZE + 4 * PAD, SIZE + 2 * PAD,
+ NULL, draw)
diff --git a/test/fill-degenerate-sort-order.c b/test/fill-degenerate-sort-order.c
new file mode 100644
index 000000000..d93481048
--- /dev/null
+++ b/test/fill-degenerate-sort-order.c
@@ -0,0 +1,77 @@
+/*
+ * Copyright © 2006 M Joonas Pihlaja
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: M Joonas Pihlaja <jpihlaja@cc.helsinki.fi>
+ */
+
+/* Bug history
+ *
+ * 2006-12-05 M Joonas Pihlaja <jpihlaja@cc.helsinki.fi>
+ *
+ * There's currently a regression bug in the tessellation code from
+ * switching to the "new tessellator". The bug is caused by
+ * confusion in the comparator used to order events when there are
+ * degenerate edges.
+ */
+
+#include "cairo-test.h"
+
+/* Derived from zrusin's "another" polygon in the performance suite. */
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_set_source_rgb (cr, 1, 0, 0);
+
+ /* The polygon uses (43,103) as its "base point". Closed
+ * subpaths are simulated by going from the base point to the
+ * subpath's first point, doing the subpath, and returning to the
+ * base point. The moving to and from the base point causes
+ * degenerate edges which shouldn't result in anything visible. */
+ cairo_move_to (cr, 43, 103);
+
+ /* First subpath. */
+ cairo_line_to (cr, 91, 101);
+ cairo_line_to (cr, 0, 112);
+ cairo_line_to (cr, 60, 0);
+ cairo_line_to (cr, 91, 101);
+
+ cairo_line_to (cr, 43, 103);
+
+ /* Second subpath. */
+ cairo_line_to (cr, 176, 110);
+ cairo_line_to (cr, 116, 100);
+ cairo_line_to (cr, 176, 0);
+ cairo_line_to (cr, 176, 110);
+
+ cairo_close_path (cr);
+ cairo_fill (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (fill_degenerate_sort_order,
+ "Tests the tessellator's event comparator with degenerate input",
+ "degenerate, fill", /* keywords */
+ NULL, /* requirements */
+ 190, 120,
+ NULL, draw)
diff --git a/test/fill-disjoint.c b/test/fill-disjoint.c
new file mode 100644
index 000000000..ea2c14fff
--- /dev/null
+++ b/test/fill-disjoint.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+/* The goal is exercise a bug that existed in the xlib backend, where
+ * it assumed the rectangles generated by rectangular tessallator had
+ * any sorting guarantees.
+ */
+
+#define WIDTH 300
+#define HEIGHT 300
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ int x;
+
+ /* black background */
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ cairo_paint (cr);
+
+ /* white rectangles */
+ cairo_set_source_rgb (cr, 1, 1, 1);
+
+ /* fill with a set of rectangles that the rectangular tessellator
+ * will not emit sorted. */
+ for (x = 0; x < WIDTH - 10; x += 15)
+ cairo_rectangle (cr, x, x, 10, HEIGHT - 2*x);
+ cairo_fill (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (fill_disjoint,
+ "Tests filling unsorted rectangles.",
+ "fill", /* keywords */
+ NULL, /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw)
diff --git a/test/fill-empty.c b/test/fill-empty.c
new file mode 100644
index 000000000..0594e57ad
--- /dev/null
+++ b/test/fill-empty.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright © 2009 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Chris Wilson not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Chris Wilson makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+#define SIZE 10
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_set_source_rgb (cr, 0, 0, 1);
+ cairo_paint (cr);
+
+ cairo_set_source_rgb (cr, 1, 0, 0);
+
+ /* first drawn an ordinary empty path */
+ cairo_save (cr);
+ cairo_rectangle (cr, 0, 0, SIZE, SIZE/2);
+ cairo_clip (cr);
+ cairo_fill (cr);
+ cairo_restore (cr);
+
+ /* and then an unbounded empty path */
+ cairo_save (cr);
+ cairo_rectangle (cr, 0, SIZE/2, SIZE, SIZE/2);
+ cairo_clip (cr);
+ cairo_set_operator (cr, CAIRO_OPERATOR_DEST_IN);
+ cairo_fill (cr);
+ cairo_restore (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (fill_empty,
+ "Test filling with an empty path",
+ "fill", /* keywords */
+ NULL, /* requirements */
+ SIZE, SIZE,
+ NULL, draw)
+
diff --git a/test/fill-image.c b/test/fill-image.c
new file mode 100644
index 000000000..24ee03142
--- /dev/null
+++ b/test/fill-image.c
@@ -0,0 +1,83 @@
+/*
+ * Copyright © 2006 Mozilla Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Mozilla Corporation not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Mozilla Corporation makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * MOZILLA CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL MOZILLA CORPORATION BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Vladimir Vukicevic <vladimir@pobox.com>
+ */
+
+#include "cairo-test.h"
+
+#define PAD 10
+#define SIZE 100
+#define IMAGE_SIZE (SIZE-PAD*2)
+#define LINE_WIDTH 10
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_surface_t *image;
+ cairo_t *cr_image;
+
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ cairo_paint (cr);
+
+ image = cairo_image_surface_create (CAIRO_FORMAT_RGB24,
+ IMAGE_SIZE, IMAGE_SIZE);
+ cr_image = cairo_create (image);
+ cairo_surface_destroy (image);
+
+ /* Create the image */
+ cairo_set_source_rgb (cr_image, 0, 0, 0);
+ cairo_paint (cr_image);
+
+ cairo_set_source_rgb (cr_image, 0, 1, 0);
+ cairo_new_sub_path (cr_image);
+ cairo_arc (cr_image, IMAGE_SIZE/2, IMAGE_SIZE/2, IMAGE_SIZE/2 - LINE_WIDTH, 0, M_PI * 2.0);
+ cairo_close_path (cr_image);
+ cairo_new_sub_path (cr_image);
+ cairo_arc_negative (cr_image, IMAGE_SIZE/2, IMAGE_SIZE/2, IMAGE_SIZE/2, 0, -M_PI * 2.0);
+ cairo_close_path (cr_image);
+ cairo_fill (cr_image);
+
+ /* Now stroke^Wfill with it */
+ cairo_translate (cr, PAD, PAD);
+
+ cairo_set_source_surface (cr, cairo_get_target (cr_image), 0, 0);
+ cairo_destroy (cr_image);
+
+ cairo_new_sub_path (cr);
+ cairo_arc (cr, IMAGE_SIZE/2, IMAGE_SIZE/2, IMAGE_SIZE/2 - LINE_WIDTH, 0, M_PI * 2.0);
+ cairo_close_path (cr);
+ cairo_new_sub_path (cr);
+ cairo_arc_negative (cr, IMAGE_SIZE/2, IMAGE_SIZE/2, IMAGE_SIZE/2, 0, -M_PI * 2.0);
+ cairo_close_path (cr);
+
+ cairo_fill (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (fill_image,
+ "Test filling with an image source, with a non-identity CTM",
+ "fill, image, transform", /* keywords */
+ NULL, /* requirements */
+ SIZE, SIZE,
+ NULL, draw)
diff --git a/test/fill-missed-stop.c b/test/fill-missed-stop.c
new file mode 100644
index 000000000..558933778
--- /dev/null
+++ b/test/fill-missed-stop.c
@@ -0,0 +1,83 @@
+/*
+ * Copyright © 2006 M Joonas Pihlaja
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: M Joonas Pihlaja <jpihlaja@cc.helsinki.fi>
+ */
+
+/* Bug history
+ *
+ * 2006-12-05 M Joonas Pihlaja <jpihlaja@cc.helsinki.fi>
+ *
+ * The tessellator has a regression where a trapezoid may continue
+ * below the end of a polygon edge (i.e. the bottom of the trapezoid
+ * is miscomputed.) This can only happen if the right edge of a
+ * trapezoid stops earlier than the left edge and there is no start
+ * event at the end point of the right edge.
+ */
+
+#include "cairo-test.h"
+
+#define SIZE 50
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_set_source_rgb (cr, 1, 0, 0);
+
+ cairo_translate (cr, 1, 1);
+
+ /* What it should look like, with # marking the filled areas:
+ *
+ * |\ |\
+ * |#\ |#\
+ * |##\__|##\
+ * \#|
+ * \|
+ *
+ * What it looke like with the bug, when the rightmost edge's end
+ * is missed:
+ *
+ * |\ |\
+ * |#\ |#\
+ * |##\__|##\
+ * \#####|
+ * \####|
+ */
+
+ cairo_move_to (cr, 0, 0);
+ cairo_line_to (cr, SIZE/2, SIZE);
+ cairo_line_to (cr, SIZE/2, 0);
+ cairo_line_to (cr, SIZE, SIZE/2);
+ cairo_line_to (cr, 0, SIZE/2);
+ cairo_close_path (cr);
+ cairo_fill (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (fill_missed_stop,
+ "Tests that the tessellator doesn't miss stop events when generating trapezoids",
+ "fill", /* keywords */
+ NULL, /* requirements */
+ SIZE+3, SIZE+3,
+ NULL, draw)
diff --git a/test/fill-rule.c b/test/fill-rule.c
new file mode 100644
index 000000000..66f19b7cc
--- /dev/null
+++ b/test/fill-rule.c
@@ -0,0 +1,127 @@
+/*
+ * Copyright © 2004 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+/* Bug history
+ *
+ * 2004-10-27 Carl Worth <cworth@cworth.org>
+ *
+ * There's currently a regression bug in the tessellation code. This
+ * causes each of these simple star shapes to be filled incorrectly.
+ *
+ * It looks like right now we can get this test to pass by doing:
+ *
+ * cvs update -r 1.16 src/cairo_traps.c
+ *
+ * But we don't want to revert that change permanently since it
+ * really does correct some bugs. It must be that the old version of
+ * the code is masking some other bugs in the tessellation code. My
+ * current plan is to back this revision up for the next snapshot,
+ * but not to list the test as an expected failure since I'm
+ * planning on doing the new tessellator which should fix this
+ * problem.
+ *
+ * 2005-01-11 Carl Worth <cworth@cworth.org>
+ *
+ * Keith committed some fixes that fix the original size-20
+ * star_path:
+ *
+ * * src/cairo_wideint.c: (_cairo_int32x32_64_mul),
+ * (_cairo_int64x64_128_mul):
+ * * src/cairo_wideint.h:
+ * int32x32_64_mul and int64x64_128_mul are different from their
+ * unsigned compatriots
+ *
+ * 2005-01-12 Carl Worth <cworth@cworth.org>
+ *
+ * Going back to the SVG test suite, however, the original star
+ * shape is still broken. Adding both shapes now as little_star_path
+ * and big_star_path.
+ *
+ */
+
+#include "cairo-test.h"
+
+#define LITTLE_STAR_SIZE 20
+#define BIG_STAR_SIZE 80
+
+/* The SVG start trimmed down, but still showing the bug (originally) */
+static void
+little_star_path (cairo_t *cr)
+{
+ cairo_move_to (cr, 10, 0);
+ cairo_rel_line_to (cr, 6, 20);
+ cairo_rel_line_to (cr, -16, -12);
+ cairo_rel_line_to (cr, 20, 0);
+ cairo_rel_line_to (cr, -16, 12);
+}
+
+/* The star shape from the SVG test suite. This was is still buggy even after
+ we got little_star_path working. */
+static void
+big_star_path (cairo_t *cr)
+{
+ cairo_move_to (cr, 40, 0);
+ cairo_rel_line_to (cr, 25, 80);
+ cairo_rel_line_to (cr, -65, -50);
+ cairo_rel_line_to (cr, 80, 0);
+ cairo_rel_line_to (cr, -65, 50);
+ cairo_close_path (cr);
+}
+
+/* Fill the same path twice, once with each fill rule */
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_set_source_rgb (cr, 1, 0, 0);
+
+ cairo_translate (cr, 1, 1);
+ little_star_path (cr);
+ cairo_set_fill_rule (cr, CAIRO_FILL_RULE_WINDING);
+ cairo_fill (cr);
+
+ cairo_translate (cr, LITTLE_STAR_SIZE + 1, 0);
+ little_star_path (cr);
+ cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
+ cairo_fill (cr);
+
+ cairo_translate (cr, -(LITTLE_STAR_SIZE + 1), LITTLE_STAR_SIZE + 1);
+ big_star_path (cr);
+ cairo_set_fill_rule (cr, CAIRO_FILL_RULE_WINDING);
+ cairo_fill (cr);
+
+ cairo_translate (cr, BIG_STAR_SIZE + 1, 0);
+ big_star_path (cr);
+ cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
+ cairo_fill (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (fill_rule,
+ "Tests cairo_set_fill_rule with some star shapes",
+ "fill, path", /* keywords */
+ NULL, /* requirements */
+ BIG_STAR_SIZE * 2 + 3, BIG_STAR_SIZE + LITTLE_STAR_SIZE + 3,
+ NULL, draw)
diff --git a/test/filter-bilinear-extents.c b/test/filter-bilinear-extents.c
new file mode 100644
index 000000000..79d36f6e6
--- /dev/null
+++ b/test/filter-bilinear-extents.c
@@ -0,0 +1,102 @@
+/*
+ * Copyright © 2008 Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors: Carl D. Worth <cworth@cworth.org>
+ * Owen Taylor <otaylor@redhat.com>
+ */
+
+#include "cairo-test.h"
+
+/* This test exercises code that computes the extents of a surface
+ * pattern with CAIRO_FILTER_BILINEAR, (where the filtering
+ * effectively increases the extents of the pattern).
+ *
+ * The original bug was reported by Owen Taylor here:
+ *
+ * bad clipping with EXTEND_NONE
+ * http://bugs.freedesktop.org/show_bug.cgi?id=15349
+ */
+
+#define SCALE 10
+#define PAD 3
+#define WIDTH (PAD + 3 * SCALE + PAD)
+#define HEIGHT WIDTH
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_surface_t *image;
+ cairo_t *cr2;
+
+ image = cairo_image_surface_create (CAIRO_FORMAT_RGB24, 2, 2);
+
+ /* Fill with an opaque background to avoid a separate rgb24 ref image */
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ cairo_paint (cr);
+
+ /* First check handling of pattern extents > surface extents */
+ cairo_save (cr);
+ cairo_scale (cr, width/2., height/2.);
+
+ /* Create a solid black source to merge with the background */
+ cr2 = cairo_create (image);
+ cairo_set_source_rgb (cr2, 0, 0 ,0);
+ cairo_paint (cr2);
+ cairo_set_source_surface (cr, cairo_get_target (cr2), 0, 0);
+ cairo_destroy (cr2);
+ cairo_pattern_set_filter (cairo_get_source (cr), CAIRO_FILTER_BILINEAR);
+ cairo_paint (cr);
+ cairo_restore (cr);
+
+ /* Then scale to smaller so we can see the full bilinear extents */
+ cairo_save (cr);
+ cairo_translate (cr, PAD, PAD);
+ cairo_scale (cr, SCALE, SCALE);
+ cairo_translate (cr, 0.5, 0.5);
+
+ /* Create a 2x2 blue+red checkerboard source */
+ cr2 = cairo_create (image);
+ cairo_set_source_rgb (cr2, 1, 0 ,0); /* red */
+ cairo_paint (cr2);
+ cairo_set_source_rgb (cr2, 0, 0, 1); /* blue */
+ cairo_rectangle (cr2, 0, 1, 1, 1);
+ cairo_rectangle (cr2, 1, 0, 1, 1);
+ cairo_fill (cr2);
+ cairo_set_source_surface (cr, cairo_get_target (cr2), 0, 0);
+ cairo_destroy (cr2);
+
+ cairo_pattern_set_filter (cairo_get_source (cr), CAIRO_FILTER_BILINEAR);
+ cairo_paint (cr);
+ cairo_restore (cr);
+
+ cairo_surface_destroy (image);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (filter_bilinear_extents,
+ "Test that pattern extents are properly computed for CAIRO_FILTER_BILINEAR",
+ "extents", /* keywords */
+ NULL, /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw)
diff --git a/test/filter-nearest-offset.c b/test/filter-nearest-offset.c
new file mode 100644
index 000000000..4df609702
--- /dev/null
+++ b/test/filter-nearest-offset.c
@@ -0,0 +1,109 @@
+/*
+ * Copyright © 2005 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+#include "cairo-test.h"
+
+#define STAMP_WIDTH 4
+#define STAMP_HEIGHT 4
+#define PAD 1
+
+#define STEPS 10
+
+#define IMAGE_WIDTH (PAD + STEPS * (STAMP_WIDTH + PAD) + PAD)
+#define IMAGE_HEIGHT (PAD + STEPS * (STAMP_HEIGHT + PAD) + PAD)
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_surface_t *surface;
+ uint32_t data[STAMP_WIDTH * STAMP_HEIGHT] = {
+ 0xffffffff, 0xffffffff, 0xffff0000, 0xffff0000,
+ 0xffffffff, 0xffffffff, 0xffff0000, 0xffff0000,
+
+ 0xff00ff00, 0xff00ff00, 0xff0000ff, 0xff0000ff,
+ 0xff00ff00, 0xff00ff00, 0xff0000ff, 0xff0000ff
+ };
+ int i, j;
+
+ /* fill with off-white to avoid a separate rgb24 ref image */
+ cairo_save (cr);
+ cairo_set_source_rgb (cr, .7, .7, .7);
+ cairo_paint (cr);
+ cairo_restore (cr);
+
+ /* Draw reference lines where the jump should be. */
+ cairo_move_to (cr, PAD + STEPS / 2 * (STAMP_WIDTH + PAD), 0);
+ cairo_rel_line_to (cr, 0, IMAGE_HEIGHT);
+ cairo_move_to (cr, 0, PAD + STEPS / 2 * (STAMP_HEIGHT + PAD));
+ cairo_rel_line_to (cr, IMAGE_WIDTH, 0);
+ cairo_set_line_width (cr, 2.0);
+ cairo_stroke (cr);
+
+ surface = cairo_image_surface_create_for_data ((unsigned char *) data,
+ CAIRO_FORMAT_RGB24,
+ STAMP_WIDTH,
+ STAMP_HEIGHT,
+ STAMP_WIDTH * 4);
+
+ for (j=0; j < STEPS; j++) {
+ double j_step;
+
+ for (i=0; i < STEPS; i++) {
+ double i_step;
+
+#define GENERATE_REFERENCE_IMAGE 0
+#if GENERATE_REFERENCE_IMAGE
+ i_step = i >= STEPS / 2 ? 1 : 0;
+ j_step = j >= STEPS / 2 ? 1 : 0;
+#else
+ i_step = i * 1.0 / STEPS;
+ j_step = j * 1.0 / STEPS;
+#endif
+
+ cairo_save (cr);
+
+ cairo_set_source_surface (cr, surface,
+ PAD + i * (STAMP_WIDTH + PAD) + i_step,
+ PAD + j * (STAMP_HEIGHT + PAD) + j_step);
+ cairo_pattern_set_filter (cairo_get_source (cr), CAIRO_FILTER_NEAREST);
+ cairo_paint (cr);
+
+ cairo_restore (cr);
+ }
+ }
+
+ cairo_surface_finish (surface); /* data goes out of scope */
+ cairo_surface_destroy (surface);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (filter_nearest_offset,
+ "Test sampling offset of CAIRO_FILTER_NEAREST"
+ "\nwrong sampling location for nearest-neighbor filter in libpixman and Render",
+ "filter", /* keywords */
+ NULL, /* requirements */
+ IMAGE_WIDTH, IMAGE_HEIGHT,
+ NULL, draw)
diff --git a/test/filter-nearest-transformed.c b/test/filter-nearest-transformed.c
new file mode 100644
index 000000000..ba56f7c5a
--- /dev/null
+++ b/test/filter-nearest-transformed.c
@@ -0,0 +1,120 @@
+/*
+ * Copyright © 2008 Chris Wilson
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+/*
+ * We wish to check the optimization away of non-fractional translations
+ * for NEAREST surface patterns under a few transformations.
+ */
+
+static const char png_filename[] = "romedalen.png";
+
+/* A single, black pixel */
+static const uint32_t black_pixel = 0xff000000;
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ const cairo_test_context_t *ctx = cairo_test_get_context (cr);
+ unsigned int i, j, k;
+ cairo_surface_t *surface;
+ cairo_pattern_t *pattern;
+ const cairo_matrix_t transform[] = {
+ { 1, 0, 0, 1, 0, 0 },
+ { -1, 0, 0, 1, 8, 0 },
+ { 1, 0, 0, -1, 0, 8 },
+ { -1, 0, 0, -1, 8, 8 },
+ };
+ const cairo_matrix_t ctx_transform[] = {
+ { 1, 0, 0, 1, 0, 0 },
+ { -1, 0, 0, 1, 14, 0 },
+ { 1, 0, 0, -1, 0, 14 },
+ { -1, 0, 0, -1, 14, 14 },
+ };
+ const double colour[][3] = {
+ {0, 0, 0},
+ {1, 0, 0},
+ {0, 1, 0},
+ {0, 0, 1},
+ };
+ cairo_matrix_t m;
+
+ surface = cairo_image_surface_create_for_data ((uint8_t *) &black_pixel,
+ CAIRO_FORMAT_ARGB32,
+ 1, 1, 4);
+ pattern = cairo_pattern_create_for_surface (surface);
+ cairo_surface_destroy (surface);
+
+ cairo_pattern_set_filter (pattern, CAIRO_FILTER_NEAREST);
+
+ surface = cairo_test_create_surface_from_png (ctx, png_filename);
+
+ /* Fill background white */
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+ cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE);
+
+ for (k = 0; k < ARRAY_LENGTH (transform); k++) {
+ /* draw a "large" section from an image */
+ cairo_save (cr); {
+ cairo_set_matrix(cr, &ctx_transform[k]);
+ cairo_rectangle (cr, 0, 0, 7, 7);
+ cairo_clip (cr);
+
+ cairo_set_source_surface (cr, surface,
+ -cairo_image_surface_get_width (surface)/2.,
+ -cairo_image_surface_get_height (surface)/2.);
+ cairo_pattern_set_filter (cairo_get_source (cr), CAIRO_FILTER_NEAREST);
+ cairo_paint (cr);
+ } cairo_restore (cr);
+
+ cairo_set_source_rgb (cr, colour[k][0], colour[k][1], colour[k][2]);
+ for (j = 4; j <= 6; j++) {
+ for (i = 4; i <= 6; i++) {
+ cairo_matrix_init_translate (&m,
+ -(2*(i-4) + .1*i),
+ -(2*(j-4) + .1*j));
+ cairo_matrix_multiply (&m, &m, &transform[k]);
+ cairo_pattern_set_matrix (pattern, &m);
+ cairo_mask (cr, pattern);
+ }
+ }
+ }
+
+ cairo_pattern_destroy (pattern);
+ cairo_surface_destroy (surface);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (filter_nearest_transformed,
+ "Test sample position when drawing transformed images with FILTER_NEAREST",
+ "filter, nearest", /* keywords */
+ NULL,
+ 14, 14,
+ NULL, draw)
diff --git a/test/finer-grained-fallbacks.c b/test/finer-grained-fallbacks.c
new file mode 100644
index 000000000..fa16f72f0
--- /dev/null
+++ b/test/finer-grained-fallbacks.c
@@ -0,0 +1,180 @@
+/*
+ * Copyright © 2008 Adrian Johnson
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Adrian Johnson <ajohnson@redneon.com>
+ */
+
+#include "cairo-test.h"
+
+#define CIRCLE_SIZE 10
+#define PAD 2
+#define WIDTH (CIRCLE_SIZE*6.5 + PAD)
+#define HEIGHT (CIRCLE_SIZE*7.0 + PAD)
+
+static void
+draw_circle (cairo_t *cr, double x, double y)
+{
+ cairo_save (cr);
+ cairo_translate (cr, x, y);
+ cairo_arc (cr, 0, 0, CIRCLE_SIZE / 2, 0., 2. * M_PI);
+ cairo_fill (cr);
+ cairo_restore (cr);
+}
+
+static void
+draw_image_circle (cairo_t *cr, cairo_surface_t *source, double x, double y)
+{
+ cairo_save (cr);
+
+ cairo_set_source_surface (cr, source, x, y);
+ cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_REFLECT);
+ cairo_rectangle (cr, x, y, CIRCLE_SIZE, CIRCLE_SIZE);
+ cairo_fill (cr);
+
+ cairo_restore (cr);
+}
+
+static void
+draw_circles (cairo_t *cr)
+{
+ draw_circle (cr, 0, -CIRCLE_SIZE*0.1);
+ draw_circle (cr, CIRCLE_SIZE*0.4, CIRCLE_SIZE*0.25);
+
+ draw_circle (cr, CIRCLE_SIZE*2, 0);
+ draw_circle (cr, CIRCLE_SIZE*4, 0);
+ draw_circle (cr, CIRCLE_SIZE*6, 0);
+}
+
+static void
+draw_image_circles (cairo_t *cr, cairo_surface_t *source)
+{
+ draw_image_circle (cr, source, 0, -CIRCLE_SIZE*0.1);
+ draw_image_circle (cr, source, CIRCLE_SIZE*0.4, CIRCLE_SIZE*0.25);
+
+ draw_image_circle (cr, source, CIRCLE_SIZE*2, 0);
+ draw_image_circle (cr, source, CIRCLE_SIZE*4, 0);
+ draw_image_circle (cr, source, CIRCLE_SIZE*6, 0);
+}
+
+/* For each of circle and fallback_circle we draw:
+ * - two overlapping
+ * - one isolated
+ * - one off the page
+ * - one overlapping the edge of the page.
+ *
+ * We also draw a circle and fallback_circle overlapping each other.
+ *
+ * Circles are drawn in green. An opaque color and CAIRO_OPERATOR_OVER
+ * is used to ensure they will be emitted as a vectors in PS/PDF.
+ *
+ * Fallback circles are drawn in red. CAIRO_OPERATOR_ADD is used to
+ * ensure they will be emitted as a fallback image in PS/PDF.
+ *
+ * In order to trigger a fallback for SVG, we need to use a surface with
+ * REFLECT.
+ */
+static cairo_surface_t *
+surface_create (cairo_t *target)
+{
+ cairo_surface_t *surface;
+ cairo_t *cr;
+
+ surface = cairo_surface_create_similar (cairo_get_target (target),
+ CAIRO_CONTENT_COLOR_ALPHA,
+ CIRCLE_SIZE, CIRCLE_SIZE);
+ cr = cairo_create (surface);
+ cairo_surface_destroy (surface);
+
+ cairo_set_source_rgb (cr, 1.0, 0.0, 0.0);
+ draw_circle (cr, CIRCLE_SIZE/2, CIRCLE_SIZE/2);
+
+ surface = cairo_surface_reference (cairo_get_target (cr));
+ cairo_destroy (cr);
+
+ return surface;
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_surface_t *surface;
+
+ cairo_translate (cr, PAD, PAD);
+
+ cairo_save (cr);
+
+ /* Draw overlapping circle and fallback circle */
+ cairo_set_source_rgb (cr, 0.0, 1.0, 0.0);
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+ draw_circle (cr, CIRCLE_SIZE*0.5, CIRCLE_SIZE*1.5);
+
+ cairo_set_source_rgb (cr, 1.0, 0.0, 0.0);
+ cairo_set_operator (cr, CAIRO_OPERATOR_ADD);
+ draw_circle (cr, CIRCLE_SIZE*0.75, CIRCLE_SIZE*1.75);
+
+ /* Draw circles */
+ cairo_set_source_rgb (cr, 0.0, 1.0, 0.0);
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+ cairo_translate (cr, CIRCLE_SIZE*2.5, CIRCLE_SIZE*0.6);
+ draw_circles (cr);
+
+ /* Draw fallback circles */
+ cairo_set_source_rgb (cr, 1.0, 0.0, 0.0);
+ cairo_set_operator (cr, CAIRO_OPERATOR_ADD);
+ cairo_translate (cr, 0, CIRCLE_SIZE*2);
+ draw_circles (cr);
+
+ cairo_restore (cr);
+ cairo_translate (cr, 0, CIRCLE_SIZE * 3.5);
+
+ /* Draw using fallback surface */
+ surface = surface_create (cr);
+
+ cairo_set_source_rgb (cr, 0.0, 1.0, 0.0);
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+ draw_circle (cr, CIRCLE_SIZE*0.5, CIRCLE_SIZE*1.5);
+
+ cairo_set_operator (cr, CAIRO_OPERATOR_ADD);
+ draw_image_circle (cr, surface, CIRCLE_SIZE/4, CIRCLE_SIZE + CIRCLE_SIZE/4);
+
+ /* Draw circles */
+ cairo_set_source_rgb (cr, 0.0, 1.0, 0.0);
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+ cairo_translate (cr, CIRCLE_SIZE*2.5, CIRCLE_SIZE*0.6);
+ draw_circles (cr);
+
+ cairo_set_operator (cr, CAIRO_OPERATOR_ADD);
+ cairo_translate (cr, -CIRCLE_SIZE/2, CIRCLE_SIZE*1.5);
+ draw_image_circles (cr, surface);
+
+ cairo_surface_destroy (surface);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (finer_grained_fallbacks,
+ "Test that multiple PS/PDF fallback images in various locations are correct",
+ "fallbacks", /* keywords */
+ NULL, /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw)
diff --git a/test/font-face-get-type.c b/test/font-face-get-type.c
new file mode 100644
index 000000000..afbb73944
--- /dev/null
+++ b/test/font-face-get-type.c
@@ -0,0 +1,79 @@
+/*
+ * Copyright © 2006 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+#include "cairo-test.h"
+
+static cairo_test_status_t
+preamble (cairo_test_context_t *ctx)
+{
+ cairo_test_status_t status = CAIRO_TEST_SUCCESS;
+ cairo_surface_t *surface;
+ cairo_t *cr;
+ cairo_font_face_t *font_face;
+ cairo_scaled_font_t *scaled_font;
+
+ cairo_test_log (ctx, "Creating cairo context and obtaining a font face\n");
+
+ surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 1, 1);
+ cr = cairo_create (surface);
+
+ cairo_select_font_face (cr, CAIRO_TEST_FONT_FAMILY " Sans",
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_NORMAL);
+
+ cairo_test_log (ctx, "Testing return value of cairo_font_face_get_type\n");
+
+ font_face = cairo_get_font_face (cr);
+
+ if (cairo_font_face_get_type (font_face) != CAIRO_FONT_TYPE_TOY) {
+ cairo_test_log (ctx, "Unexpected value %d from cairo_font_face_get_type (expected %d)\n",
+ cairo_font_face_get_type (font_face), CAIRO_FONT_TYPE_TOY);
+ status = CAIRO_TEST_FAILURE;
+ goto done;
+ }
+
+ cairo_test_log (ctx, "Testing return value of cairo_get_scaled_font\n");
+
+ scaled_font = cairo_get_scaled_font (cr);
+
+ if (cairo_scaled_font_get_font_face (scaled_font) != font_face) {
+ cairo_test_log (ctx, "Font face returned from the scaled font is different from that returned by the context\n");
+ status = CAIRO_TEST_FAILURE;
+ goto done;
+ }
+
+done:
+ cairo_destroy (cr);
+ cairo_surface_destroy (surface);
+
+ return status;
+}
+
+CAIRO_TEST (font_face_get_type,
+ "Check the returned type from cairo_select_font_face.",
+ "font", /* keywords */
+ NULL, /* requirements */
+ 0, 0,
+ preamble, NULL)
diff --git a/test/font-matrix-translation.c b/test/font-matrix-translation.c
new file mode 100644
index 000000000..465ac7cf4
--- /dev/null
+++ b/test/font-matrix-translation.c
@@ -0,0 +1,141 @@
+/*
+ * Copyright © 2006 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+#include "cairo-test.h"
+
+#define TEXT_SIZE 12
+#define PAD 4
+#define TEXT "text"
+
+static cairo_bool_t
+text_extents_equal (const cairo_text_extents_t *A,
+ const cairo_text_extents_t *B)
+{
+ return A->x_bearing == B->x_bearing &&
+ A->y_bearing == B->y_bearing &&
+ A->width == B->width &&
+ A->height == B->height &&
+ A->x_advance == B->x_advance &&
+ A->y_advance == B->y_advance;
+}
+
+static cairo_test_status_t
+box_text (const cairo_test_context_t *ctx, cairo_t *cr,
+ const char *utf8,
+ double x, double y)
+{
+ double line_width;
+ cairo_text_extents_t extents = {0}, scaled_extents = {0};
+ cairo_scaled_font_t *scaled_font;
+ cairo_status_t status;
+
+ cairo_save (cr);
+
+ cairo_text_extents (cr, utf8, &extents);
+
+ scaled_font = cairo_get_scaled_font (cr);
+ cairo_scaled_font_text_extents (scaled_font, TEXT, &scaled_extents);
+ status = cairo_scaled_font_status (scaled_font);
+ if (status)
+ return cairo_test_status_from_status (ctx, status);
+
+ if (! text_extents_equal (&extents, &scaled_extents)) {
+ cairo_test_log (ctx,
+ "Error: extents differ when they shouldn't:\n"
+ "cairo_text_extents(); extents (%g, %g, %g, %g, %g, %g)\n"
+ "cairo_scaled_font_text_extents(); extents (%g, %g, %g, %g, %g, %g)\n",
+ extents.x_bearing, extents.y_bearing,
+ extents.width, extents.height,
+ extents.x_advance, extents.y_advance,
+ scaled_extents.x_bearing, scaled_extents.y_bearing,
+ scaled_extents.width, scaled_extents.height,
+ scaled_extents.x_advance, scaled_extents.y_advance);
+ return CAIRO_TEST_FAILURE;
+ }
+
+ line_width = cairo_get_line_width (cr);
+ cairo_rectangle (cr,
+ x + extents.x_bearing - line_width / 2,
+ y + extents.y_bearing - line_width / 2,
+ extents.width + line_width,
+ extents.height + line_width);
+ cairo_stroke (cr);
+
+ cairo_move_to (cr, x, y);
+ cairo_show_text (cr, utf8);
+
+ cairo_restore (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ const cairo_test_context_t *ctx = cairo_test_get_context (cr);
+ cairo_test_status_t status;
+ cairo_text_extents_t extents;
+ cairo_matrix_t matrix;
+
+ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */
+ cairo_paint (cr);
+
+ cairo_select_font_face (cr, CAIRO_TEST_FONT_FAMILY " Sans",
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_NORMAL);
+ cairo_set_font_size (cr, TEXT_SIZE);
+
+ cairo_translate (cr, PAD, PAD);
+ cairo_set_line_width (cr, 1.0);
+
+ cairo_text_extents (cr, TEXT, &extents);
+
+ /* Draw text and bounding box */
+ cairo_set_source_rgb (cr, 0, 0, 0); /* black */
+ status = box_text (ctx, cr, TEXT, 0, - extents.y_bearing);
+ if (status)
+ return status;
+
+ /* Then draw again with the same coordinates, but with a font
+ * matrix to position the text below and shifted a bit to the
+ * right. */
+ cairo_matrix_init_translate (&matrix, TEXT_SIZE / 2, TEXT_SIZE + PAD);
+ cairo_matrix_scale (&matrix, TEXT_SIZE, TEXT_SIZE);
+ cairo_set_font_matrix (cr, &matrix);
+
+ cairo_set_source_rgb (cr, 0, 0, 1); /* blue */
+ status = box_text (ctx, cr, TEXT, 0, - extents.y_bearing);
+ if (status)
+ return status;
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (font_matrix_translation,
+ "Test that translation in a font matrix can be used to offset a string",
+ "font", /* keywords */
+ NULL, /* requirements */
+ 38, 34,
+ NULL, draw)
diff --git a/test/font-options.c b/test/font-options.c
new file mode 100644
index 000000000..873a5c398
--- /dev/null
+++ b/test/font-options.c
@@ -0,0 +1,110 @@
+/*
+ * Copyright © 2008 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Chris Wilson not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Chris Wilson makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+#include <assert.h>
+
+static cairo_test_status_t
+preamble (cairo_test_context_t *ctx)
+{
+ cairo_font_options_t *default_options;
+ cairo_font_options_t *nil_options;
+ cairo_surface_t *surface;
+ cairo_matrix_t identity;
+ cairo_t *cr;
+ cairo_scaled_font_t *scaled_font;
+
+ /* first check NULL handling of cairo_font_options_t */
+ default_options = cairo_font_options_create ();
+ assert (cairo_font_options_status (default_options) == CAIRO_STATUS_SUCCESS);
+ nil_options = cairo_font_options_copy (NULL);
+ assert (cairo_font_options_status (nil_options) == CAIRO_STATUS_NO_MEMORY);
+
+ assert (cairo_font_options_equal (default_options, default_options));
+ assert (! cairo_font_options_equal (default_options, nil_options));
+ assert (! cairo_font_options_equal (NULL, nil_options));
+ assert (! cairo_font_options_equal (nil_options, nil_options));
+ assert (! cairo_font_options_equal (default_options, NULL));
+ assert (! cairo_font_options_equal (NULL, default_options));
+
+ assert (cairo_font_options_hash (default_options) == cairo_font_options_hash (nil_options));
+ assert (cairo_font_options_hash (NULL) == cairo_font_options_hash (nil_options));
+ assert (cairo_font_options_hash (default_options) == cairo_font_options_hash (NULL));
+
+ cairo_font_options_merge (NULL, NULL);
+ cairo_font_options_merge (default_options, NULL);
+ cairo_font_options_merge (default_options, nil_options);
+
+ cairo_font_options_set_antialias (NULL, CAIRO_ANTIALIAS_DEFAULT);
+ cairo_font_options_get_antialias (NULL);
+ assert (cairo_font_options_get_antialias (default_options) == CAIRO_ANTIALIAS_DEFAULT);
+
+ cairo_font_options_set_subpixel_order (NULL, CAIRO_SUBPIXEL_ORDER_DEFAULT);
+ cairo_font_options_get_subpixel_order (NULL);
+ assert (cairo_font_options_get_subpixel_order (default_options) == CAIRO_SUBPIXEL_ORDER_DEFAULT);
+
+ cairo_font_options_set_hint_style (NULL, CAIRO_HINT_STYLE_DEFAULT);
+ cairo_font_options_get_hint_style (NULL);
+ assert (cairo_font_options_get_hint_style (default_options) == CAIRO_HINT_STYLE_DEFAULT);
+
+ cairo_font_options_set_hint_metrics (NULL, CAIRO_HINT_METRICS_DEFAULT);
+ cairo_font_options_get_hint_metrics (NULL);
+ assert (cairo_font_options_get_hint_metrics (default_options) == CAIRO_HINT_METRICS_DEFAULT);
+
+ cairo_font_options_destroy (NULL);
+ cairo_font_options_destroy (default_options);
+ cairo_font_options_destroy (nil_options);
+
+
+ /* Now try creating fonts with NULLs */
+ surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, 0, 0);
+ cr = cairo_create (surface);
+ cairo_surface_destroy (surface);
+
+ cairo_matrix_init_identity (&identity);
+ scaled_font = cairo_scaled_font_create (cairo_get_font_face (cr),
+ &identity, &identity,
+ NULL);
+ assert (cairo_scaled_font_status (scaled_font) == CAIRO_STATUS_NULL_POINTER);
+ cairo_scaled_font_get_font_options (scaled_font, NULL);
+ cairo_scaled_font_destroy (scaled_font);
+
+ assert (cairo_status (cr) == CAIRO_STATUS_SUCCESS);
+ cairo_get_font_options (cr, NULL);
+ cairo_set_font_options (cr, NULL);
+ assert (cairo_status (cr) == CAIRO_STATUS_NULL_POINTER);
+
+ cairo_destroy (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (font_options,
+ "Check setters and getters on cairo_font_options_t.",
+ "font, api", /* keywords */
+ NULL, /* requirements */
+ 0, 0,
+ preamble, NULL)
diff --git a/test/ft-font-create-for-ft-face.c b/test/ft-font-create-for-ft-face.c
new file mode 100644
index 000000000..52c838dd4
--- /dev/null
+++ b/test/ft-font-create-for-ft-face.c
@@ -0,0 +1,228 @@
+/*
+ * Copyright © 2005 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+#include "cairo-test.h"
+#include <cairo-ft.h>
+
+static void
+_stress_font_cache (FT_Face ft_face, cairo_t *cr, int lvl);
+
+static cairo_font_face_t *
+_load_font (FT_Face ft_face, int flags, cairo_t *cr, int lvl)
+{
+ cairo_font_face_t *font_face;
+ cairo_font_extents_t font_extents;
+
+ _stress_font_cache (ft_face, cr, lvl+1);
+
+ font_face = cairo_ft_font_face_create_for_ft_face (ft_face, flags);
+
+ cairo_set_font_face (cr, font_face);
+ cairo_font_extents (cr, &font_extents);
+
+ _stress_font_cache (ft_face, cr, lvl+1);
+
+ return font_face;
+}
+
+static void
+_stress_font_cache (FT_Face ft_face, cairo_t *cr, int lvl)
+{
+#define A _load_font (ft_face, 0, cr, lvl)
+#define B _load_font (ft_face, FT_LOAD_NO_BITMAP, cr, lvl)
+#define C _load_font (ft_face, FT_LOAD_NO_RECURSE, cr, lvl)
+#define D _load_font (ft_face, FT_LOAD_FORCE_AUTOHINT, cr, lvl)
+
+ cairo_font_face_t *font_face[4];
+
+ while (lvl++ < 5) {
+ font_face[0] = A; font_face[1] = A;
+ font_face[2] = A; font_face[3] = A;
+ cairo_font_face_destroy (font_face[0]);
+ cairo_font_face_destroy (font_face[1]);
+ cairo_font_face_destroy (font_face[2]);
+ cairo_font_face_destroy (font_face[3]);
+
+ font_face[0] = A; font_face[1] = B;
+ font_face[2] = C; font_face[3] = D;
+ cairo_font_face_destroy (font_face[0]);
+ cairo_font_face_destroy (font_face[1]);
+ cairo_font_face_destroy (font_face[2]);
+ cairo_font_face_destroy (font_face[3]);
+
+ font_face[0] = A; font_face[1] = B;
+ font_face[2] = C; font_face[3] = D;
+ cairo_font_face_destroy (font_face[3]);
+ cairo_font_face_destroy (font_face[2]);
+ cairo_font_face_destroy (font_face[1]);
+ cairo_font_face_destroy (font_face[0]);
+
+ font_face[0] = A;
+ font_face[1] = A;
+ cairo_font_face_destroy (font_face[0]);
+ font_face[2] = A;
+ cairo_font_face_destroy (font_face[1]);
+ font_face[3] = A;
+ cairo_font_face_destroy (font_face[2]);
+ cairo_font_face_destroy (font_face[3]);
+
+ font_face[0] = A;
+ font_face[1] = B;
+ cairo_font_face_destroy (font_face[0]);
+ font_face[2] = C;
+ cairo_font_face_destroy (font_face[1]);
+ font_face[3] = D;
+ cairo_font_face_destroy (font_face[2]);
+ cairo_font_face_destroy (font_face[3]);
+ }
+
+#undef A
+#undef B
+#undef C
+#undef D
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ const cairo_test_context_t *ctx = cairo_test_get_context (cr);
+ FcPattern *pattern, *resolved;
+ FcResult result;
+ cairo_font_face_t *font_face;
+ cairo_scaled_font_t *scaled_font;
+ cairo_font_options_t *font_options;
+ cairo_font_extents_t font_extents;
+ cairo_matrix_t font_matrix, ctm;
+ FT_Face ft_face;
+
+ /* We're trying here to get our hands on _some_ FT_Face but we do
+ * not at all care which one. So we start with an empty pattern
+ * and do the minimal substitution on it in order to get a valid
+ * pattern.
+ *
+ * Do not use this in production code! */
+ pattern = FcPatternCreate ();
+ if (! pattern) {
+ cairo_test_log (ctx, "FcPatternCreate failed.\n");
+ return cairo_test_status_from_status (ctx, CAIRO_STATUS_NO_MEMORY);
+ }
+
+ FcConfigSubstitute (NULL, pattern, FcMatchPattern);
+ FcDefaultSubstitute (pattern);
+ resolved = FcFontMatch (NULL, pattern, &result);
+ if (! resolved) {
+ FcPatternDestroy (pattern);
+ cairo_test_log (ctx, "FcFontMatch failed.\n");
+ return cairo_test_status_from_status (ctx, CAIRO_STATUS_NO_MEMORY);
+ }
+
+ font_face = cairo_ft_font_face_create_for_pattern (resolved);
+ if (cairo_font_face_status (font_face)) {
+ FcPatternDestroy (resolved);
+ FcPatternDestroy (pattern);
+ return cairo_test_status_from_status (ctx, cairo_font_face_status (font_face));
+ }
+
+ if (cairo_font_face_get_type (font_face) != CAIRO_FONT_TYPE_FT) {
+ cairo_test_log (ctx, "Unexpected value from cairo_font_face_get_type: %d (expected %d)\n",
+ cairo_font_face_get_type (font_face), CAIRO_FONT_TYPE_FT);
+ cairo_font_face_destroy (font_face);
+ FcPatternDestroy (resolved);
+ FcPatternDestroy (pattern);
+ return CAIRO_TEST_FAILURE;
+ }
+
+ cairo_matrix_init_identity (&font_matrix);
+
+ cairo_get_matrix (cr, &ctm);
+
+ font_options = cairo_font_options_create ();
+
+ cairo_get_font_options (cr, font_options);
+
+ scaled_font = cairo_scaled_font_create (font_face,
+ &font_matrix,
+ &ctm,
+ font_options);
+
+ cairo_font_options_destroy (font_options);
+ cairo_font_face_destroy (font_face);
+ FcPatternDestroy (pattern);
+ FcPatternDestroy (resolved);
+
+ if (cairo_scaled_font_status (scaled_font)) {
+ return cairo_test_status_from_status (ctx,
+ cairo_scaled_font_status (scaled_font));
+ }
+
+ if (cairo_scaled_font_get_type (scaled_font) != CAIRO_FONT_TYPE_FT) {
+ cairo_test_log (ctx, "Unexpected value from cairo_scaled_font_get_type: %d (expected %d)\n",
+ cairo_scaled_font_get_type (scaled_font), CAIRO_FONT_TYPE_FT);
+ cairo_scaled_font_destroy (scaled_font);
+ return CAIRO_TEST_FAILURE;
+ }
+
+ ft_face = cairo_ft_scaled_font_lock_face (scaled_font);
+ if (ft_face == NULL) {
+ cairo_test_log (ctx, "Failed to get an ft_face with cairo_ft_scaled_font_lock_face\n");
+ cairo_scaled_font_destroy (scaled_font);
+ return CAIRO_TEST_FAILURE;
+ }
+
+ /* phew, that was a lot of work. But at least we didn't ever have
+ * to call freetype directly, nor did we have to make many (any?)
+ * assumptions about the current system.
+ *
+ * Now, on to the simple thing we actually want to test.
+ */
+
+ cairo_save (cr);
+
+ /* First we want to test caching behaviour */
+ _stress_font_cache (ft_face, cr, 0);
+
+ /* Set the font_face and force cairo to actually use it for
+ * something. */
+ font_face = cairo_ft_font_face_create_for_ft_face (ft_face, 0);
+ cairo_set_font_face (cr, font_face);
+ cairo_font_extents (cr, &font_extents);
+
+ cairo_restore (cr);
+
+ /* Finally, even more cleanup */
+ cairo_font_face_destroy (font_face);
+ cairo_ft_scaled_font_unlock_face (scaled_font);
+ cairo_scaled_font_destroy (scaled_font);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (ft_font_create_for_ft_face,
+ "Simple test to verify that cairo_ft_font_create_for_ft_face doesn't crash.",
+ "ft, font", /* keywords */
+ NULL, /* requirements */
+ 0, 0,
+ NULL, draw)
+
diff --git a/test/ft-show-glyphs-positioning.c b/test/ft-show-glyphs-positioning.c
new file mode 100644
index 000000000..449f8eb1f
--- /dev/null
+++ b/test/ft-show-glyphs-positioning.c
@@ -0,0 +1,191 @@
+/*
+ * Copyright © 2008 Adrian Johnson
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Adrian Johnson <ajohnson@redneon.com>
+ */
+
+#include "cairo-test.h"
+#include <cairo-ft.h>
+
+#define TEXT_SIZE 12
+
+typedef struct {
+ cairo_glyph_t glyph_list[100];
+ int num_glyphs;
+ double x;
+ double y;
+} glyph_array_t;
+
+static void
+glyph_array_init (glyph_array_t *glyphs, double x, double y)
+{
+ glyphs->num_glyphs = 0;
+ glyphs->x = x;
+ glyphs->y = y;
+}
+
+static void
+glyph_array_rel_move_to (glyph_array_t *glyphs, double x, double y)
+{
+ glyphs->x += x;
+ glyphs->y += y;
+}
+
+static void
+glyph_array_show (glyph_array_t *glyphs, cairo_t *cr)
+{
+ cairo_show_glyphs (cr, glyphs->glyph_list, glyphs->num_glyphs);
+}
+
+#define DOUBLE_FROM_26_6(t) ((double)(t) / 64.0)
+
+static cairo_status_t
+glyph_array_add_text(glyph_array_t *glyphs, cairo_t *cr, const char *s, double spacing)
+{
+ cairo_scaled_font_t *scaled_font;
+ cairo_status_t status;
+ FT_Face face;
+ unsigned long charcode;
+ unsigned int index;
+ cairo_text_extents_t extents;
+ const char *p;
+ FT_Vector kerning;
+ double kern_x;
+ int first = TRUE;
+
+ scaled_font = cairo_get_scaled_font (cr);
+ status = cairo_scaled_font_status (scaled_font);
+ if (status)
+ return status;
+
+ face = cairo_ft_scaled_font_lock_face (scaled_font);
+ if (face == NULL)
+ return CAIRO_STATUS_FONT_TYPE_MISMATCH;
+
+ p = s;
+ while (*p)
+ {
+ charcode = *p;
+ index = FT_Get_Char_Index (face, charcode);
+ glyphs->glyph_list[glyphs->num_glyphs].index = index;
+ if (first) {
+ first = FALSE;
+ glyphs->glyph_list[glyphs->num_glyphs].x = glyphs->x;
+ glyphs->glyph_list[glyphs->num_glyphs].y = glyphs->y;
+ } else {
+ cairo_glyph_extents (cr, &glyphs->glyph_list[glyphs->num_glyphs - 1], 1, &extents);
+ FT_Get_Kerning (face,
+ glyphs->glyph_list[glyphs->num_glyphs - 1].index,
+ glyphs->glyph_list[glyphs->num_glyphs].index,
+ FT_KERNING_UNSCALED,
+ &kerning);
+ kern_x = DOUBLE_FROM_26_6(kerning.x);
+ glyphs->glyph_list[glyphs->num_glyphs].x =
+ glyphs->glyph_list[glyphs->num_glyphs - 1].x + extents.x_advance + kern_x + spacing;
+ glyphs->glyph_list[glyphs->num_glyphs].y =
+ glyphs->glyph_list[glyphs->num_glyphs - 1].y + extents.y_advance;
+ }
+
+ cairo_glyph_extents (cr, &glyphs->glyph_list[glyphs->num_glyphs], 1, &extents);
+ glyphs->x = glyphs->glyph_list[glyphs->num_glyphs].x + extents.x_advance + spacing;
+ glyphs->y = glyphs->glyph_list[glyphs->num_glyphs].y + extents.y_advance;
+ p++;
+ glyphs->num_glyphs++;
+ }
+
+ cairo_ft_scaled_font_unlock_face (scaled_font);
+ return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ const cairo_test_context_t *ctx = cairo_test_get_context (cr);
+ glyph_array_t glyphs;
+ cairo_font_options_t *font_options;
+ cairo_status_t status;
+
+ /* paint white so we don't need separate ref images for
+ * RGB24 and ARGB32 */
+ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
+ cairo_paint (cr);
+
+ cairo_select_font_face (cr, CAIRO_TEST_FONT_FAMILY " Sans",
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_NORMAL);
+ cairo_set_font_size (cr, TEXT_SIZE);
+
+ font_options = cairo_font_options_create ();
+ cairo_get_font_options (cr, font_options);
+ cairo_font_options_set_hint_metrics (font_options, CAIRO_HINT_METRICS_OFF);
+ cairo_set_font_options (cr, font_options);
+ cairo_font_options_destroy (font_options);
+
+ cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
+
+ glyph_array_init (&glyphs, 1, TEXT_SIZE);
+
+ status = glyph_array_add_text(&glyphs, cr, "AWAY again", 0.0);
+ if (status)
+ return cairo_test_status_from_status (ctx, status);
+
+ glyph_array_rel_move_to (&glyphs, TEXT_SIZE*1, 0.0);
+ status = glyph_array_add_text(&glyphs, cr, "character space", TEXT_SIZE*0.3);
+ if (status)
+ return cairo_test_status_from_status (ctx, status);
+
+ glyph_array_show (&glyphs, cr);
+
+
+ glyph_array_init (&glyphs, 1, TEXT_SIZE*2 + 4);
+
+ status = glyph_array_add_text(&glyphs, cr, "Increasing", 0.0);
+ if (status)
+ return cairo_test_status_from_status (ctx, status);
+
+ glyph_array_rel_move_to (&glyphs, TEXT_SIZE*0.5, 0.0);
+ status = glyph_array_add_text(&glyphs, cr, "space", 0.0);
+ if (status)
+ return cairo_test_status_from_status (ctx, status);
+
+ glyph_array_rel_move_to (&glyphs, TEXT_SIZE*1.0, 0.0);
+ status = glyph_array_add_text(&glyphs, cr, "between", 0.0);
+ if (status)
+ return cairo_test_status_from_status (ctx, status);
+
+ glyph_array_rel_move_to (&glyphs, TEXT_SIZE*1.5, 0.0);
+ status = glyph_array_add_text(&glyphs, cr, "words", 0.0);
+ if (status)
+ return cairo_test_status_from_status (ctx, status);
+
+ glyph_array_show (&glyphs, cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (ft_show_glyphs_positioning,
+ "Test that the PS/PDF glyph positioning optimizations are correct",
+ "ft, text", /* keywords */
+ NULL, /* requirements */
+ 235, (TEXT_SIZE + 4)*2,
+ NULL, draw)
diff --git a/test/ft-show-glyphs-table.c b/test/ft-show-glyphs-table.c
new file mode 100644
index 000000000..344392f40
--- /dev/null
+++ b/test/ft-show-glyphs-table.c
@@ -0,0 +1,109 @@
+/*
+ * Copyright © 2008 Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors: Eugeniy Meshcheryakov <eugen@debian.org>
+ * Adrian Johnson <ajohnson@redneon.com>
+ * Carl Worth <cworth@cworth.org>
+ */
+
+#include "cairo-test.h"
+#include <cairo-ft.h>
+
+#define TEXT_SIZE 20
+#define PAD 10
+#define GRID_SIZE 30
+#define GRID_ROWS 10
+#define GRID_COLS 4
+#define NUM_GLYPHS (GRID_ROWS * GRID_COLS)
+#define WIDTH (PAD + GRID_COLS * GRID_SIZE + PAD)
+#define HEIGHT (PAD + GRID_ROWS * GRID_SIZE + PAD)
+
+/* This test was originally inspired by this bug report:
+ *
+ * Error when creating pdf charts for new FreeSerifItalic.ttf
+ * http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=%23474136
+ *
+ * The original assertion failure was fairly boring, but the later
+ * glyph mispositiing was quite interesting. And it turns out that the
+ * _cairo_pdf_operators_show_glyphs code is fairly convoluted with a
+ * code path that wasn't being exercised at all by the test suite.
+ *
+ * So this is an attempt to exercise that code path. Apparently laying
+ * glyphs out vertically in a table like this, (so that there's a
+ * large change in Y position from one glyph to the next), exercises
+ * the code well.
+ */
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_font_options_t *font_options;
+ cairo_scaled_font_t *scaled_font;
+ FT_Face face;
+ FT_ULong charcode;
+ FT_UInt idx;
+ int i = 0;
+ cairo_glyph_t glyphs[NUM_GLYPHS];
+
+ /* paint white so we don't need separate ref images for
+ * RGB24 and ARGB32 */
+ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
+ cairo_paint (cr);
+
+ cairo_select_font_face (cr, CAIRO_TEST_FONT_FAMILY " Sans",
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_NORMAL);
+ cairo_set_font_size (cr, TEXT_SIZE);
+
+ font_options = cairo_font_options_create ();
+ cairo_get_font_options (cr, font_options);
+ cairo_font_options_set_hint_metrics (font_options, CAIRO_HINT_METRICS_OFF);
+ cairo_set_font_options (cr, font_options);
+ cairo_font_options_destroy (font_options);
+
+ cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
+
+ scaled_font = cairo_get_scaled_font (cr);
+ face = cairo_ft_scaled_font_lock_face (scaled_font);
+ {
+ charcode = FT_Get_First_Char(face, &idx);
+ while (idx && (i < NUM_GLYPHS)) {
+ glyphs[i] = (cairo_glyph_t) {idx, PAD + GRID_SIZE * (i/GRID_ROWS), PAD + TEXT_SIZE + GRID_SIZE * (i%GRID_ROWS)};
+ i++;
+ charcode = FT_Get_Next_Char(face, charcode, &idx);
+ }
+ }
+ cairo_ft_scaled_font_unlock_face (scaled_font);
+
+ cairo_show_glyphs(cr, glyphs, i);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (ft_show_glyphs_table,
+ "Test cairo_show_glyphs with cairo-ft backend and glyphs laid out in a table",
+ "ft, text", /* keywords */
+ NULL, /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw)
+
diff --git a/test/ft-text-antialias-none.c b/test/ft-text-antialias-none.c
new file mode 100644
index 000000000..64eea64f9
--- /dev/null
+++ b/test/ft-text-antialias-none.c
@@ -0,0 +1,146 @@
+/*
+ * Copyright © 2006 Jinghua Luo
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * JINGHUA LUO DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Jinghua Luo <sunmoon1997@gmail.com>
+ * Derived from:
+ * text-antialias-none.c,
+ * ft-font-create-for-ft-face.c.
+ * Original Author: Carl D. Worth <cworth@cworth.org>
+ */
+#include "cairo-test.h"
+#include <cairo-ft.h>
+
+#define WIDTH 40
+#define HEIGHT 30
+#define TEXT_SIZE 12
+
+static cairo_status_t
+create_scaled_font (cairo_t * cr,
+ cairo_scaled_font_t **out)
+{
+ FcPattern *pattern, *resolved;
+ FcResult result;
+ cairo_font_face_t *font_face;
+ cairo_scaled_font_t *scaled_font;
+ cairo_font_options_t *font_options;
+ cairo_matrix_t font_matrix, ctm;
+ cairo_status_t status;
+ double pixel_size;
+
+ font_options = cairo_font_options_create ();
+
+ cairo_get_font_options (cr, font_options);
+
+ pattern = FcPatternCreate ();
+ if (pattern == NULL)
+ return CAIRO_STATUS_NO_MEMORY;
+
+ FcPatternAddString (pattern, FC_FAMILY, (FcChar8 *) CAIRO_TEST_FONT_FAMILY " Sans");
+ FcPatternAddDouble (pattern, FC_SIZE, TEXT_SIZE);
+ FcConfigSubstitute (NULL, pattern, FcMatchPattern);
+
+ cairo_ft_font_options_substitute (font_options, pattern);
+
+ FcDefaultSubstitute (pattern);
+ resolved = FcFontMatch (NULL, pattern, &result);
+ if (resolved == NULL) {
+ FcPatternDestroy (pattern);
+ return CAIRO_STATUS_NO_MEMORY;
+ }
+
+ /* turn antialiasing off */
+ FcPatternDel (resolved, FC_ANTIALIAS);
+ FcPatternAddBool (resolved, FC_ANTIALIAS, FcFalse);
+
+ FcPatternGetDouble (resolved, FC_PIXEL_SIZE, 0, &pixel_size);
+
+ font_face = cairo_ft_font_face_create_for_pattern (resolved);
+
+ cairo_matrix_init_identity (&font_matrix);
+ cairo_matrix_scale (&font_matrix, pixel_size, pixel_size);
+
+ cairo_get_matrix (cr, &ctm);
+
+ scaled_font = cairo_scaled_font_create (font_face,
+ &font_matrix,
+ &ctm,
+ font_options);
+
+ cairo_font_options_destroy (font_options);
+ cairo_font_face_destroy (font_face);
+ FcPatternDestroy (pattern);
+ FcPatternDestroy (resolved);
+
+ status = cairo_scaled_font_status (scaled_font);
+ if (status) {
+ cairo_scaled_font_destroy (scaled_font);
+ return status;
+ }
+
+ *out = scaled_font;
+ return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_text_extents_t extents;
+ cairo_scaled_font_t *scaled_font;
+ cairo_status_t status;
+ const char black[] = "black", blue[] = "blue";
+
+ /* We draw in the default black, so paint white first. */
+ cairo_save (cr);
+ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */
+ cairo_paint (cr);
+ cairo_restore (cr);
+
+ status = create_scaled_font (cr, &scaled_font);
+ if (status) {
+ return cairo_test_status_from_status (cairo_test_get_context (cr),
+ status);
+ }
+
+ cairo_set_scaled_font (cr, scaled_font);
+
+ cairo_set_source_rgb (cr, 0, 0, 0); /* black */
+ cairo_text_extents (cr, black, &extents);
+ cairo_move_to (cr, -extents.x_bearing, -extents.y_bearing);
+ cairo_show_text (cr, black);
+ cairo_translate (cr, 0, -extents.y_bearing + 1);
+
+ cairo_set_source_rgb (cr, 0, 0, 1); /* blue */
+ cairo_text_extents (cr, blue, &extents);
+ cairo_move_to (cr, -extents.x_bearing, -extents.y_bearing);
+ cairo_show_text (cr, blue);
+
+ cairo_scaled_font_destroy (scaled_font);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (ft_text_antialias_none,
+ "Tests text rendering with no antialiasing",
+ "ft, text", /* keywords */
+ "target=raster", /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw)
diff --git a/test/ft-text-vertical-layout-type1.c b/test/ft-text-vertical-layout-type1.c
new file mode 100644
index 000000000..c6f26a66a
--- /dev/null
+++ b/test/ft-text-vertical-layout-type1.c
@@ -0,0 +1,167 @@
+/*
+ * Copyright © 2006 Jinghua Luo
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * JINGHUA LUO DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Jinghua Luo <sunmoon1997@gmail.com>
+ * Derived from:
+ * text-antialias-none.c,
+ * ft-font-create-for-ft-face.c.
+ * Original Author: Carl D. Worth <cworth@cworth.org>
+ */
+#include "cairo-test.h"
+#include <cairo-ft.h>
+
+#define WIDTH 80
+#define HEIGHT 240
+#define TEXT_SIZE 30
+
+static cairo_status_t
+create_scaled_font (cairo_t * cr,
+ cairo_scaled_font_t **out)
+{
+ FcPattern *pattern, *resolved;
+ FcResult result;
+ cairo_font_face_t *font_face;
+ cairo_scaled_font_t *scaled_font;
+ cairo_font_options_t *font_options;
+ cairo_matrix_t font_matrix, ctm;
+ cairo_status_t status;
+ double pixel_size;
+
+ font_options = cairo_font_options_create ();
+
+ cairo_get_font_options (cr, font_options);
+
+ pattern = FcPatternCreate ();
+ if (pattern == NULL)
+ return CAIRO_STATUS_NO_MEMORY;
+
+ FcPatternAddString (pattern, FC_FAMILY, (FcChar8 *)"Nimbus Sans L");
+ FcPatternAddDouble (pattern, FC_PIXEL_SIZE, TEXT_SIZE);
+ FcConfigSubstitute (NULL, pattern, FcMatchPattern);
+
+ cairo_ft_font_options_substitute (font_options, pattern);
+
+ FcDefaultSubstitute (pattern);
+ resolved = FcFontMatch (NULL, pattern, &result);
+ if (resolved == NULL) {
+ FcPatternDestroy (pattern);
+ return CAIRO_STATUS_NO_MEMORY;
+ }
+
+ /* set layout to vertical */
+ FcPatternDel (resolved, FC_VERTICAL_LAYOUT);
+ FcPatternAddBool (resolved, FC_VERTICAL_LAYOUT, FcTrue);
+
+ FcPatternGetDouble (resolved, FC_PIXEL_SIZE, 0, &pixel_size);
+
+ font_face = cairo_ft_font_face_create_for_pattern (resolved);
+
+ cairo_matrix_init_translate (&font_matrix, 10, 30);
+ cairo_matrix_rotate (&font_matrix, M_PI_2/3);
+ cairo_matrix_scale (&font_matrix, pixel_size, pixel_size);
+
+ cairo_get_matrix (cr, &ctm);
+
+ scaled_font = cairo_scaled_font_create (font_face,
+ &font_matrix,
+ &ctm,
+ font_options);
+
+ cairo_font_options_destroy (font_options);
+ cairo_font_face_destroy (font_face);
+ FcPatternDestroy (pattern);
+ FcPatternDestroy (resolved);
+
+ status = cairo_scaled_font_status (scaled_font);
+ if (status) {
+ cairo_scaled_font_destroy (scaled_font);
+ return status;
+ }
+
+ *out = scaled_font;
+ return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_text_extents_t extents;
+ cairo_scaled_font_t *scaled_font;
+ cairo_status_t status;
+ const char text[] = "i-W";
+ double line_width, x, y;
+
+ line_width = cairo_get_line_width (cr);
+
+ /* We draw in the default black, so paint white first. */
+ cairo_save (cr);
+ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */
+ cairo_paint (cr);
+ cairo_restore (cr);
+
+ status = create_scaled_font (cr, &scaled_font);
+ if (status) {
+ return cairo_test_status_from_status (cairo_test_get_context (cr),
+ status);
+ }
+
+ cairo_set_scaled_font (cr, scaled_font);
+ cairo_scaled_font_destroy (scaled_font);
+
+ cairo_set_line_width (cr, 1.0);
+ cairo_set_source_rgb (cr, 0, 0, 0); /* black */
+ cairo_text_extents (cr, text, &extents);
+ x = width - (extents.width + extents.x_bearing) - 5;
+ y = height - (extents.height + extents.y_bearing) - 5;
+ cairo_move_to (cr, x, y);
+ cairo_show_text (cr, text);
+ cairo_rectangle (cr,
+ x + extents.x_bearing - line_width / 2,
+ y + extents.y_bearing - line_width / 2,
+ extents.width + line_width,
+ extents.height + line_width);
+ cairo_stroke (cr);
+
+ cairo_set_source_rgb (cr, 0, 0, 1); /* blue */
+ cairo_text_extents (cr, text, &extents);
+ x = -extents.x_bearing + 5;
+ y = -extents.y_bearing + 5;
+ cairo_move_to (cr, x, y);
+ cairo_text_path (cr, text);
+ cairo_fill (cr);
+ cairo_rectangle (cr,
+ x + extents.x_bearing - line_width / 2,
+ y + extents.y_bearing - line_width / 2,
+ extents.width + line_width,
+ extents.height + line_width);
+ cairo_stroke (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (ft_text_vertical_layout_type1,
+ "Tests text rendering for vertical layout with Type1 fonts"
+ "\nCan fail if an incorrect font is loaded---need to bundle the desired font",
+ "ft, fc, text", /* keywords */
+ NULL, /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw)
diff --git a/test/ft-text-vertical-layout-type3.c b/test/ft-text-vertical-layout-type3.c
new file mode 100644
index 000000000..0cea9dd80
--- /dev/null
+++ b/test/ft-text-vertical-layout-type3.c
@@ -0,0 +1,166 @@
+/*
+ * Copyright © 2006 Jinghua Luo
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * JINGHUA LUO DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Jinghua Luo <sunmoon1997@gmail.com>
+ * Derived from:
+ * text-antialias-none.c,
+ * ft-font-create-for-ft-face.c.
+ * Original Author: Carl D. Worth <cworth@cworth.org>
+ */
+#include "cairo-test.h"
+#include <cairo-ft.h>
+
+#define WIDTH 80
+#define HEIGHT 200
+#define TEXT_SIZE 30
+
+static cairo_status_t
+create_scaled_font (cairo_t * cr,
+ cairo_scaled_font_t **out)
+{
+ FcPattern *pattern, *resolved;
+ FcResult result;
+ cairo_font_face_t *font_face;
+ cairo_scaled_font_t *scaled_font;
+ cairo_font_options_t *font_options;
+ cairo_matrix_t font_matrix, ctm;
+ cairo_status_t status;
+ double pixel_size;
+
+ font_options = cairo_font_options_create ();
+
+ cairo_get_font_options (cr, font_options);
+
+ pattern = FcPatternCreate ();
+ if (pattern == NULL)
+ return CAIRO_STATUS_NO_MEMORY;
+
+ FcPatternAddString (pattern, FC_FAMILY, (FcChar8 *)CAIRO_TEST_FONT_FAMILY " Sans");
+ FcPatternAddDouble (pattern, FC_PIXEL_SIZE, TEXT_SIZE);
+ FcConfigSubstitute (NULL, pattern, FcMatchPattern);
+
+ cairo_ft_font_options_substitute (font_options, pattern);
+
+ FcDefaultSubstitute (pattern);
+ resolved = FcFontMatch (NULL, pattern, &result);
+ if (resolved == NULL) {
+ FcPatternDestroy (pattern);
+ return CAIRO_STATUS_NO_MEMORY;
+ }
+
+ /* set layout to vertical */
+ FcPatternDel (resolved, FC_VERTICAL_LAYOUT);
+ FcPatternAddBool (resolved, FC_VERTICAL_LAYOUT, FcTrue);
+
+ FcPatternGetDouble (resolved, FC_PIXEL_SIZE, 0, &pixel_size);
+
+ font_face = cairo_ft_font_face_create_for_pattern (resolved);
+
+ cairo_matrix_init_translate (&font_matrix, 10, 30);
+ cairo_matrix_rotate (&font_matrix, M_PI_2/3);
+ cairo_matrix_scale (&font_matrix, pixel_size, pixel_size);
+
+ cairo_get_matrix (cr, &ctm);
+
+ scaled_font = cairo_scaled_font_create (font_face,
+ &font_matrix,
+ &ctm,
+ font_options);
+
+ cairo_font_options_destroy (font_options);
+ cairo_font_face_destroy (font_face);
+ FcPatternDestroy (pattern);
+ FcPatternDestroy (resolved);
+
+ status = cairo_scaled_font_status (scaled_font);
+ if (status) {
+ cairo_scaled_font_destroy (scaled_font);
+ return status;
+ }
+
+ *out = scaled_font;
+ return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_text_extents_t extents;
+ cairo_scaled_font_t *scaled_font;
+ cairo_status_t status;
+ const char text[] = "i-W";
+ double line_width, x, y;
+
+ line_width = cairo_get_line_width (cr);
+
+ /* We draw in the default black, so paint white first. */
+ cairo_save (cr);
+ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */
+ cairo_paint (cr);
+ cairo_restore (cr);
+
+ status = create_scaled_font (cr, &scaled_font);
+ if (status) {
+ return cairo_test_status_from_status (cairo_test_get_context (cr),
+ status);
+ }
+
+ cairo_set_scaled_font (cr, scaled_font);
+ cairo_scaled_font_destroy (scaled_font);
+
+ cairo_set_line_width (cr, 1.0);
+ cairo_set_source_rgb (cr, 0, 0, 0); /* black */
+ cairo_text_extents (cr, text, &extents);
+ x = width - (extents.width + extents.x_bearing) - 5;
+ y = height - (extents.height + extents.y_bearing) - 5;
+ cairo_move_to (cr, x, y);
+ cairo_show_text (cr, text);
+ cairo_rectangle (cr,
+ x + extents.x_bearing - line_width / 2,
+ y + extents.y_bearing - line_width / 2,
+ extents.width + line_width,
+ extents.height + line_width);
+ cairo_stroke (cr);
+
+ cairo_set_source_rgb (cr, 0, 0, 1); /* blue */
+ cairo_text_extents (cr, text, &extents);
+ x = -extents.x_bearing + 5;
+ y = -extents.y_bearing + 5;
+ cairo_move_to (cr, x, y);
+ cairo_text_path (cr, text);
+ cairo_fill (cr);
+ cairo_rectangle (cr,
+ x + extents.x_bearing - line_width / 2,
+ y + extents.y_bearing - line_width / 2,
+ extents.width + line_width,
+ extents.height + line_width);
+ cairo_stroke (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (ft_text_vertical_layout_type3,
+ "Tests text rendering for vertical layout with TrueType fonts",
+ "ft, fc, text", /* keywords */
+ NULL, /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw)
diff --git a/test/generate_refs.sh b/test/generate_refs.sh
new file mode 100755
index 000000000..e22aa2548
--- /dev/null
+++ b/test/generate_refs.sh
@@ -0,0 +1,12 @@
+#!/bin/bash
+
+# A very simple script. But sufficient, hopefully, for our current purposes.
+
+cat <<EOF
+# Note REFERENCE_IMAGES must be in lexicographical order.
+# Use generate_refs.sh on a git checkout with updated images.
+REFERENCE_IMAGES = \\
+EOF
+
+git ls-files 'reference/*.ref.png' '*.xfail.png' | sed 's/\(.*\)/ \1 \\/'
+echo ' $(NULL)'
diff --git a/test/get-and-set.c b/test/get-and-set.c
new file mode 100644
index 000000000..6a395d6c7
--- /dev/null
+++ b/test/get-and-set.c
@@ -0,0 +1,159 @@
+/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */
+/*
+ * Copyright © 2005 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+#include "cairo-test.h"
+
+typedef struct {
+ cairo_operator_t op;
+ double tolerance;
+ cairo_fill_rule_t fill_rule;
+ double line_width;
+ cairo_line_cap_t line_cap;
+ cairo_line_join_t line_join;
+ double miter_limit;
+ cairo_matrix_t matrix;
+ double dash[5];
+ double dash_offset;
+} settings_t;
+
+/* Two sets of settings, no defaults */
+static const settings_t settings[] = {
+ {
+ CAIRO_OPERATOR_IN,
+ 2.0,
+ CAIRO_FILL_RULE_EVEN_ODD,
+ 7.7,
+ CAIRO_LINE_CAP_SQUARE,
+ CAIRO_LINE_JOIN_ROUND,
+ 3.14,
+ {2.0, 0.0, 0.0, 2.0, 5.0, 5.0},
+ {0.1, 0.2, 0.3, 0.4, 0.5},
+ 2.0
+ },
+ {
+ CAIRO_OPERATOR_ATOP,
+ 5.25,
+ CAIRO_FILL_RULE_WINDING,
+ 2.17,
+ CAIRO_LINE_CAP_ROUND,
+ CAIRO_LINE_JOIN_BEVEL,
+ 1000.0,
+ {-3.0, 1.0, 1.0, -3.0, -4, -4},
+ {1.0, 2.0, 3.0, 4.0, 5.0},
+ 3.0
+ }
+};
+
+static void
+settings_set (cairo_t *cr, const settings_t *settings)
+{
+ cairo_set_operator (cr, settings->op);
+ cairo_set_tolerance (cr, settings->tolerance);
+ cairo_set_fill_rule (cr, settings->fill_rule);
+ cairo_set_line_width (cr, settings->line_width);
+ cairo_set_line_cap (cr, settings->line_cap);
+ cairo_set_line_join (cr, settings->line_join);
+ cairo_set_miter_limit (cr, settings->miter_limit);
+ cairo_set_matrix (cr, &settings->matrix);
+ cairo_set_dash (cr, settings->dash, 5, settings->dash_offset);
+}
+
+static int
+settings_get (cairo_t *cr, settings_t *settings)
+{
+ int count;
+
+ settings->op = cairo_get_operator (cr);
+ settings->tolerance = cairo_get_tolerance (cr);
+ settings->fill_rule = cairo_get_fill_rule (cr);
+ settings->line_width = cairo_get_line_width (cr);
+ settings->line_cap = cairo_get_line_cap (cr);
+ settings->line_join = cairo_get_line_join (cr);
+ settings->miter_limit = cairo_get_miter_limit (cr);
+ cairo_get_matrix (cr, &settings->matrix);
+
+ count = cairo_get_dash_count (cr);
+ if (count != 5)
+ return -1;
+
+ cairo_get_dash (cr, settings->dash, &settings->dash_offset);
+
+ return 0;
+}
+
+static int
+settings_equal (const settings_t *a, const settings_t *b)
+{
+ return (a->op == b->op &&
+ a->tolerance == b->tolerance &&
+ a->fill_rule == b->fill_rule &&
+ a->line_width == b->line_width &&
+ a->line_cap == b->line_cap &&
+ a->line_join == b->line_join &&
+ a->miter_limit == b->miter_limit &&
+ a->matrix.xx == b->matrix.xx &&
+ a->matrix.xy == b->matrix.xy &&
+ a->matrix.x0 == b->matrix.x0 &&
+ a->matrix.yx == b->matrix.yx &&
+ a->matrix.yy == b->matrix.yy &&
+ a->matrix.y0 == b->matrix.y0 &&
+ memcmp(a->dash, b->dash, sizeof(a->dash)) == 0 &&
+ a->dash_offset == b->dash_offset);
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ settings_t check;
+
+ settings_set (cr, &settings[0]);
+
+ cairo_save (cr);
+ {
+ settings_set (cr, &settings[1]);
+ if (settings_get (cr, &check))
+ return CAIRO_TEST_FAILURE;
+
+ if (!settings_equal (&settings[1], &check))
+ return CAIRO_TEST_FAILURE;
+ }
+ cairo_restore (cr);
+
+ if (settings_get (cr, &check))
+ return CAIRO_TEST_FAILURE;
+
+ if (!settings_equal (&settings[0], &check))
+ return CAIRO_TEST_FAILURE;
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (get_and_set,
+ "Tests calls to the most trivial cairo_get and cairo_set functions",
+ "api", /* keywords */
+ NULL, /* requirements */
+ 0, 0,
+ NULL, draw)
diff --git a/test/get-clip.c b/test/get-clip.c
new file mode 100644
index 000000000..f97db3f62
--- /dev/null
+++ b/test/get-clip.c
@@ -0,0 +1,264 @@
+/*
+ * Copyright © 2006 Novell, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Novell, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Novell, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * NOVELL, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Robert O'Callahan <rocallahan@novell.com>
+ */
+
+#include "cairo-test.h"
+#include <stddef.h>
+
+static cairo_bool_t
+check_count (const cairo_test_context_t *ctx,
+ const char *message,
+ cairo_rectangle_list_t *list, int expected)
+{
+ if (list->status != CAIRO_STATUS_SUCCESS) {
+ cairo_test_log (ctx, "Error: %s; cairo_copy_clip_rectangle_list failed with \"%s\"\n",
+ message, cairo_status_to_string(list->status));
+ return 0;
+ }
+
+ if (list->num_rectangles == expected)
+ return 1;
+ cairo_test_log (ctx, "Error: %s; expected %d rectangles, got %d\n", message,
+ expected, list->num_rectangles);
+ return 0;
+}
+
+static cairo_bool_t
+check_unrepresentable (const cairo_test_context_t *ctx, const char *message, cairo_rectangle_list_t *list)
+{
+ if (list->status != CAIRO_STATUS_CLIP_NOT_REPRESENTABLE) {
+ cairo_test_log (ctx, "Error: %s; cairo_copy_clip_rectangle_list got unexpected result \"%s\"\n"
+ " (we expected CAIRO_STATUS_CLIP_NOT_REPRESENTABLE)",
+ message, cairo_status_to_string(list->status));
+ return 0;
+ }
+ return 1;
+}
+
+static cairo_bool_t
+check_rectangles_contain (const cairo_test_context_t *ctx,
+ const char *message,
+ cairo_rectangle_list_t *list,
+ double x, double y, double width, double height)
+{
+ int i;
+
+ for (i = 0; i < list->num_rectangles; ++i) {
+ if (list->rectangles[i].x == x && list->rectangles[i].y == y &&
+ list->rectangles[i].width == width && list->rectangles[i].height == height)
+ return 1;
+ }
+ cairo_test_log (ctx, "Error: %s; rectangle list does not contain rectangle %f,%f,%f,%f\n",
+ message, x, y, width, height);
+ return 0;
+}
+
+static cairo_bool_t
+check_clip_extents (const cairo_test_context_t *ctx,
+ const char *message, cairo_t *cr,
+ double x, double y, double width, double height)
+{
+ double ext_x1, ext_y1, ext_x2, ext_y2;
+ cairo_clip_extents (cr, &ext_x1, &ext_y1, &ext_x2, &ext_y2);
+ if (ext_x1 == x && ext_y1 == y && ext_x2 == x + width && ext_y2 == y + height)
+ return 1;
+ if (width == 0.0 && height == 0.0 && ext_x1 == ext_x2 && ext_y1 == ext_y2)
+ return 1;
+ cairo_test_log (ctx, "Error: %s; clip extents %f,%f,%f,%f should be %f,%f,%f,%f\n",
+ message, ext_x1, ext_y1, ext_x2 - ext_x1, ext_y2 - ext_y1,
+ x, y, width, height);
+ return 0;
+}
+
+#define SIZE 100
+
+static cairo_test_status_t
+preamble (cairo_test_context_t *ctx)
+{
+ cairo_surface_t *surface;
+ cairo_t *cr;
+ cairo_rectangle_list_t *rectangle_list;
+ const char *phase;
+ cairo_bool_t completed = 0;
+ cairo_status_t status;
+
+ surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, SIZE, SIZE);
+ cr = cairo_create (surface);
+ cairo_surface_destroy (surface);
+
+
+ /* first, test basic stuff. This should not be clipped, it should
+ return the surface rectangle. */
+ phase = "No clip set";
+ rectangle_list = cairo_copy_clip_rectangle_list (cr);
+ if (! check_count (ctx, phase, rectangle_list, 1) ||
+ ! check_clip_extents (ctx, phase, cr, 0, 0, SIZE, SIZE) ||
+ ! check_rectangles_contain (ctx, phase, rectangle_list, 0, 0, SIZE, SIZE))
+ {
+ goto FAIL;
+ }
+ cairo_rectangle_list_destroy (rectangle_list);
+
+ /* We should get the same results after applying a clip that contains the
+ existing clip. */
+ phase = "Clip beyond surface extents";
+ cairo_save (cr);
+ cairo_rectangle (cr, -10, -10, SIZE + 20 , SIZE + 20);
+ cairo_clip (cr);
+ rectangle_list = cairo_copy_clip_rectangle_list (cr);
+ if (! check_count (ctx, phase, rectangle_list, 1) ||
+ ! check_clip_extents (ctx, phase, cr, 0, 0, SIZE, SIZE) ||
+ ! check_rectangles_contain (ctx, phase, rectangle_list, 0, 0, SIZE, SIZE))
+ {
+ goto FAIL;
+ }
+ cairo_rectangle_list_destroy (rectangle_list);
+ cairo_restore (cr);
+
+ /* Test simple clip rect. */
+ phase = "Simple clip rect";
+ cairo_save (cr);
+ cairo_rectangle (cr, 10, 10, 80, 80);
+ cairo_clip (cr);
+ rectangle_list = cairo_copy_clip_rectangle_list (cr);
+ if (! check_count (ctx, phase, rectangle_list, 1) ||
+ ! check_clip_extents (ctx, phase, cr, 10, 10, 80, 80) ||
+ ! check_rectangles_contain (ctx, phase, rectangle_list, 10, 10, 80, 80))
+ {
+ goto FAIL;
+ }
+ cairo_rectangle_list_destroy (rectangle_list);
+ cairo_restore (cr);
+
+ /* Test everything clipped out. */
+ phase = "All clipped out";
+ cairo_save (cr);
+ cairo_clip (cr);
+ rectangle_list = cairo_copy_clip_rectangle_list (cr);
+ if (! check_count (ctx, phase, rectangle_list, 0) ||
+ ! check_clip_extents (ctx, phase, cr, 0, 0, 0, 0))
+ {
+ goto FAIL;
+ }
+ cairo_rectangle_list_destroy (rectangle_list);
+ cairo_restore (cr);
+
+ /* test two clip rects */
+ phase = "Two clip rects";
+ cairo_save (cr);
+ cairo_rectangle (cr, 10, 10, 10, 10);
+ cairo_rectangle (cr, 20, 20, 10, 10);
+ cairo_clip (cr);
+ cairo_rectangle (cr, 15, 15, 10, 10);
+ cairo_clip (cr);
+ rectangle_list = cairo_copy_clip_rectangle_list (cr);
+ if (! check_count (ctx, phase, rectangle_list, 2) ||
+ ! check_clip_extents (ctx, phase, cr, 15, 15, 10, 10) ||
+ ! check_rectangles_contain (ctx, phase, rectangle_list, 15, 15, 5, 5) ||
+ ! check_rectangles_contain (ctx, phase, rectangle_list, 20, 20, 5, 5))
+ {
+ goto FAIL;
+ }
+ cairo_rectangle_list_destroy (rectangle_list);
+ cairo_restore (cr);
+
+ /* test non-rectangular clip */
+ phase = "Nonrectangular clip";
+ cairo_save (cr);
+ cairo_move_to (cr, 0, 0);
+ cairo_line_to (cr, 100, 100);
+ cairo_line_to (cr, 100, 0);
+ cairo_close_path (cr);
+ cairo_clip (cr);
+ rectangle_list = cairo_copy_clip_rectangle_list (cr);
+ /* can't get this in one tight user-space rectangle */
+ if (! check_unrepresentable (ctx, phase, rectangle_list) ||
+ ! check_clip_extents (ctx, phase, cr, 0, 0, 100, 100))
+ {
+ goto FAIL;
+ }
+ cairo_rectangle_list_destroy (rectangle_list);
+ cairo_restore (cr);
+
+ phase = "User space, simple scale, getting clip with same transform";
+ cairo_save (cr);
+ cairo_scale (cr, 2, 2);
+ cairo_rectangle (cr, 5, 5, 40, 40);
+ cairo_clip (cr);
+ rectangle_list = cairo_copy_clip_rectangle_list (cr);
+ if (! check_count (ctx, phase, rectangle_list, 1) ||
+ ! check_clip_extents (ctx, phase, cr, 5, 5, 40, 40) ||
+ ! check_rectangles_contain (ctx, phase, rectangle_list, 5, 5, 40, 40))
+ {
+ goto FAIL;
+ }
+ cairo_rectangle_list_destroy (rectangle_list);
+ cairo_restore (cr);
+
+ phase = "User space, simple scale, getting clip with no transform";
+ cairo_save (cr);
+ cairo_save (cr);
+ cairo_scale (cr, 2, 2);
+ cairo_rectangle (cr, 5, 5, 40, 40);
+ cairo_restore (cr);
+ cairo_clip (cr);
+ rectangle_list = cairo_copy_clip_rectangle_list (cr);
+ if (! check_count (ctx, phase, rectangle_list, 1) ||
+ ! check_clip_extents (ctx, phase, cr, 10, 10, 80, 80) ||
+ ! check_rectangles_contain (ctx, phase, rectangle_list, 10, 10, 80, 80))
+ {
+ goto FAIL;
+ }
+ cairo_rectangle_list_destroy (rectangle_list);
+ cairo_restore (cr);
+
+ phase = "User space, rotation, getting clip with no transform";
+ cairo_save (cr);
+ cairo_save (cr);
+ cairo_rotate (cr, 12);
+ cairo_rectangle (cr, 5, 5, 40, 40);
+ cairo_restore (cr);
+ cairo_clip (cr);
+ rectangle_list = cairo_copy_clip_rectangle_list (cr);
+ if (! check_unrepresentable (ctx, phase, rectangle_list))
+ goto FAIL;
+
+ completed = 1;
+FAIL:
+ cairo_rectangle_list_destroy (rectangle_list);
+ status = cairo_status (cr);
+ cairo_destroy (cr);
+
+ if (!completed)
+ return CAIRO_TEST_FAILURE;
+
+ return cairo_test_status_from_status (ctx, status);
+}
+
+CAIRO_TEST (get_clip,
+ "Test cairo_copy_clip_rectangle_list and cairo_clip_extents",
+ "clip, extents", /* keywords */
+ NULL, /* requirements */
+ 0, 0,
+ preamble, NULL)
diff --git a/test/get-group-target.c b/test/get-group-target.c
new file mode 100644
index 000000000..5aff19b29
--- /dev/null
+++ b/test/get-group-target.c
@@ -0,0 +1,85 @@
+/*
+ * Copyright © 2006 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+#include "cairo-test.h"
+
+#define SIZE 8
+#define PAD 2
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_surface_t *group;
+ double x, y;
+
+ /* First paint background in blue. */
+ cairo_set_source_rgb (cr, 0.0, 0.0, 1.0);
+ cairo_paint (cr);
+
+ /* Then clip so that the group surface ends up smaller than the
+ * original surface. */
+ cairo_rectangle (cr, PAD, PAD, width - 2 * PAD, height - 2 * PAD);
+ cairo_clip (cr);
+
+ /* Paint the clipped region in red (which should all be overwritten later). */
+ cairo_set_source_rgb (cr, 1.0, 0.0, 0.0);
+ cairo_paint (cr);
+
+ /* Redirect to a new group and get that surface. */
+ cairo_push_group (cr);
+ group = cairo_get_group_target (cr);
+
+ /* Then paint in green what we query the group surface size to be. */
+ cairo_set_source_rgb (cr, 0.0, 1.0, 0.0);
+ cairo_surface_get_device_offset (group, &x, &y);
+ /* Or rather, we calculate the group surface size based on the
+ * only thing we can query which is the device offset. Ideally,
+ * the size would always be the minimal (width - 2 * PAD, height -
+ * 2 * PAD) based on the clip. But currently, group targets are
+ * created oversized for paginated surfaces, so we only subtract
+ * anything from the size if there is a non-zero device offfset.
+ *
+ * The calculation below might also be less confusing if the sign
+ * convention on the device offset were reversed, but it is what
+ * it is. Oh well. */
+ cairo_rectangle (cr,
+ -x, -y,
+ width + 2 * x,
+ height + 2 * y);
+ cairo_fill (cr);
+
+ /* Finish up the group painting. */
+ cairo_pop_group_to_source (cr);
+ cairo_paint (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (get_group_target,
+ "Test of both cairo_get_group_target and cairo_surface_get_device_offset",
+ "api", /* keywords */
+ NULL, /* requirements */
+ SIZE, SIZE,
+ NULL, draw)
diff --git a/test/get-path-extents.c b/test/get-path-extents.c
new file mode 100644
index 000000000..075fd6fd6
--- /dev/null
+++ b/test/get-path-extents.c
@@ -0,0 +1,443 @@
+/*
+ * Copyright © 2006 Novell, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Novell, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Novell, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * NOVELL, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Robert O'Callahan <rocallahan@novell.com>
+ */
+
+#include "cairo-test.h"
+#include <stddef.h>
+#include <math.h>
+
+enum ExtentsType { FILL, STROKE, PATH };
+
+enum Relation { EQUALS, APPROX_EQUALS, CONTAINS };
+
+
+static cairo_bool_t within_tolerance(double x1, double y1,
+ double x2, double y2,
+ double expected_x1, double expected_y1,
+ double expected_x2, double expected_y2,
+ double tolerance)
+{
+ return (fabs (expected_x1 - x1) < tolerance &&
+ fabs (expected_y1 - y1) < tolerance &&
+ fabs (expected_x2 - x2) < tolerance &&
+ fabs (expected_y2 - y2) < tolerance);
+}
+
+static cairo_bool_t
+check_extents (const cairo_test_context_t *ctx,
+ const char *message, cairo_t *cr, enum ExtentsType type,
+ enum Relation relation,
+ double x, double y, double width, double height)
+{
+ double ext_x1, ext_y1, ext_x2, ext_y2;
+ const char *type_string;
+ const char *relation_string;
+
+ switch (type) {
+ default:
+ case FILL:
+ type_string = "fill";
+ cairo_fill_extents (cr, &ext_x1, &ext_y1, &ext_x2, &ext_y2);
+ break;
+ case STROKE:
+ type_string = "stroke";
+ cairo_stroke_extents (cr, &ext_x1, &ext_y1, &ext_x2, &ext_y2);
+ break;
+ case PATH:
+ type_string = "path";
+ cairo_path_extents (cr, &ext_x1, &ext_y1, &ext_x2, &ext_y2);
+ break;
+ }
+
+ /* ignore results after an error occurs */
+ if (cairo_status (cr))
+ return 1;
+
+ switch (relation) {
+ default:
+ case EQUALS:
+ relation_string = "equal";
+ if (within_tolerance(x, y, x + width, y + height,
+ ext_x1, ext_y1, ext_x2, ext_y2,
+ cairo_get_tolerance(cr)))
+ return 1;
+ break;
+ case APPROX_EQUALS:
+ relation_string = "approx. equal";
+ if (within_tolerance(x, y, x + width, y + height,
+ ext_x1, ext_y1, ext_x2, ext_y2,
+ 1.))
+ return 1;
+ break;
+ case CONTAINS:
+ relation_string = "contain";
+ if (width == 0 || height == 0) {
+ /* odd test that doesn't really test anything... */
+ return 1;
+ }
+ if (ext_x1 <= x && ext_y1 <= y && ext_x2 >= x + width && ext_y2 >= y + height)
+ return 1;
+ break;
+ }
+
+ cairo_test_log (ctx, "Error: %s; %s extents (%g, %g) x (%g, %g) should %s (%g, %g) x (%g, %g)\n",
+ message, type_string,
+ ext_x1, ext_y1, ext_x2 - ext_x1, ext_y2 - ext_y1,
+ relation_string,
+ x, y, width, height);
+ return 0;
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ const cairo_test_context_t *ctx = cairo_test_get_context (cr);
+ cairo_surface_t *surface;
+ cairo_t *cr2;
+ const char *phase;
+ const char string[] = "The quick brown fox jumps over the lazy dog.";
+ cairo_text_extents_t extents, scaled_font_extents;
+ cairo_status_t status;
+ int errors = 0;
+
+ surface = cairo_surface_create_similar (cairo_get_group_target (cr),
+ CAIRO_CONTENT_COLOR, 1000, 1000);
+ /* don't use cr accidentally */
+ cr = NULL;
+ cr2 = cairo_create (surface);
+ cairo_surface_destroy (surface);
+
+ cairo_set_line_width (cr2, 10);
+ cairo_set_line_join (cr2, CAIRO_LINE_JOIN_MITER);
+ cairo_set_miter_limit (cr2, 100);
+
+ phase = "No path";
+ errors += !check_extents (ctx, phase, cr2, FILL, EQUALS, 0, 0, 0, 0);
+ errors += !check_extents (ctx, phase, cr2, STROKE, EQUALS, 0, 0, 0, 0);
+ errors += !check_extents (ctx, phase, cr2, PATH, EQUALS, 0, 0, 0, 0);
+
+ cairo_save (cr2);
+
+ cairo_new_path (cr2);
+ cairo_move_to (cr2, 200, 400);
+ cairo_close_path (cr2);
+ phase = "Degenerate closed path";
+ errors += !check_extents (ctx, phase, cr2, FILL, EQUALS, 0, 0, 0, 0);
+ errors += !check_extents (ctx, phase, cr2, STROKE, EQUALS, 0, 0, 0, 0);
+ errors += !check_extents (ctx, phase, cr2, PATH, EQUALS, 200, 400, 0, 0);
+
+ cairo_new_path (cr2);
+ cairo_move_to (cr2, 200, 400);
+ cairo_rel_line_to (cr2, 0., 0.);
+ phase = "Degenerate line";
+ errors += !check_extents (ctx, phase, cr2, FILL, EQUALS, 0, 0, 0, 0);
+ errors += !check_extents (ctx, phase, cr2, STROKE, EQUALS, 0, 0, 0, 0);
+ errors += !check_extents (ctx, phase, cr2, PATH, EQUALS, 200, 400, 0, 0);
+
+ cairo_new_path (cr2);
+ cairo_move_to (cr2, 200, 400);
+ cairo_rel_curve_to (cr2, 0., 0., 0., 0., 0., 0.);
+ phase = "Degenerate curve";
+ errors += !check_extents (ctx, phase, cr2, FILL, EQUALS, 0, 0, 0, 0);
+ errors += !check_extents (ctx, phase, cr2, STROKE, EQUALS, 0, 0, 0, 0);
+ errors += !check_extents (ctx, phase, cr2, PATH, EQUALS, 200, 400, 0, 0);
+
+ cairo_new_path (cr2);
+ cairo_arc (cr2, 200, 400, 0., 0, 2 * M_PI);
+ phase = "Degenerate arc (R=0)";
+ errors += !check_extents (ctx, phase, cr2, FILL, EQUALS, 0, 0, 0, 0);
+ errors += !check_extents (ctx, phase, cr2, STROKE, EQUALS, 0, 0, 0, 0);
+ errors += !check_extents (ctx, phase, cr2, PATH, EQUALS, 200, 400, 0, 0);
+
+ cairo_new_path (cr2);
+ cairo_arc_negative (cr2, 200, 400, 0., 0, 2 * M_PI);
+ phase = "Degenerate negative arc (R=0)";
+ errors += !check_extents (ctx, phase, cr2, FILL, EQUALS, 0, 0, 0, 0);
+ errors += !check_extents (ctx, phase, cr2, STROKE, EQUALS, 0, 0, 0, 0);
+ errors += !check_extents (ctx, phase, cr2, PATH, EQUALS, 200, 400, 0, 0);
+
+ cairo_new_path (cr2);
+ cairo_arc (cr2, 200, 400, 10., 0, 0);
+ phase = "Degenerate arc (Θ=0)";
+ errors += !check_extents (ctx, phase, cr2, FILL, EQUALS, 0, 0, 0, 0);
+ errors += !check_extents (ctx, phase, cr2, STROKE, EQUALS, 0, 0, 0, 0);
+ errors += !check_extents (ctx, phase, cr2, PATH, EQUALS, 210, 400, 0, 0);
+
+ cairo_new_path (cr2);
+ cairo_arc_negative (cr2, 200, 400, 10., 0, 0);
+ phase = "Degenerate negative arc (Θ=0)";
+ errors += !check_extents (ctx, phase, cr2, FILL, EQUALS, 0, 0, 0, 0);
+ errors += !check_extents (ctx, phase, cr2, STROKE, EQUALS, 0, 0, 0, 0);
+ errors += !check_extents (ctx, phase, cr2, PATH, EQUALS, 210, 400, 0, 0);
+
+ cairo_new_path (cr2);
+ cairo_restore (cr2);
+
+ /* Test that with CAIRO_LINE_CAP_ROUND, we get "dots" from
+ * cairo_move_to; cairo_rel_line_to(0,0) */
+ cairo_save (cr2);
+
+ cairo_set_line_cap (cr2, CAIRO_LINE_CAP_ROUND);
+ cairo_set_line_width (cr2, 20);
+
+ cairo_move_to (cr2, 200, 400);
+ cairo_rel_line_to (cr2, 0, 0);
+ phase = "Single 'dot'";
+ errors += !check_extents (ctx, phase, cr2, FILL, EQUALS, 0, 0, 0, 0);
+ errors += !check_extents (ctx, phase, cr2, STROKE, APPROX_EQUALS, 190, 390, 20, 20);
+ errors += !check_extents (ctx, phase, cr2, PATH, EQUALS, 200, 400, 0, 0);
+
+ /* Add another dot without starting a new path */
+ cairo_move_to (cr2, 100, 500);
+ cairo_rel_line_to (cr2, 0, 0);
+ phase = "Multiple 'dots'";
+ errors += !check_extents (ctx, phase, cr2, FILL, EQUALS, 0, 0, 0, 0);
+ errors += !check_extents (ctx, phase, cr2, STROKE, APPROX_EQUALS, 90, 390, 120, 120);
+ errors += !check_extents (ctx, phase, cr2, PATH, EQUALS, 100, 400, 100, 100);
+
+ cairo_new_path (cr2);
+
+ cairo_restore (cr2);
+
+ /* http://bugs.freedesktop.org/show_bug.cgi?id=7965 */
+ phase = "A horizontal, open path";
+ cairo_save (cr2);
+ cairo_set_line_cap (cr2, CAIRO_LINE_CAP_ROUND);
+ cairo_set_line_join (cr2, CAIRO_LINE_JOIN_ROUND);
+ cairo_move_to (cr2, 0, 180);
+ cairo_line_to (cr2, 750, 180);
+ errors += !check_extents (ctx, phase, cr2, FILL, EQUALS, 0, 0, 0, 0);
+ errors += !check_extents (ctx, phase, cr2, STROKE, EQUALS, -5, 175, 760, 10);
+ errors += !check_extents (ctx, phase, cr2, PATH, EQUALS, 0, 180, 750, 0);
+ cairo_new_path (cr2);
+ cairo_restore (cr2);
+
+ phase = "A vertical, open path";
+ cairo_save (cr2);
+ cairo_set_line_cap (cr2, CAIRO_LINE_CAP_ROUND);
+ cairo_set_line_join (cr2, CAIRO_LINE_JOIN_ROUND);
+ cairo_new_path (cr2);
+ cairo_move_to (cr2, 180, 0);
+ cairo_line_to (cr2, 180, 750);
+ errors += !check_extents (ctx, phase, cr2, FILL, EQUALS, 0, 0, 0, 0);
+ errors += !check_extents (ctx, phase, cr2, STROKE, EQUALS, 175, -5, 10, 760);
+ errors += !check_extents (ctx, phase, cr2, PATH, EQUALS, 180, 0, 0, 750);
+ cairo_new_path (cr2);
+ cairo_restore (cr2);
+
+ phase = "A degenerate open path";
+ cairo_save (cr2);
+ cairo_set_line_cap (cr2, CAIRO_LINE_CAP_ROUND);
+ cairo_set_line_join (cr2, CAIRO_LINE_JOIN_ROUND);
+ cairo_new_path (cr2);
+ cairo_move_to (cr2, 180, 0);
+ cairo_line_to (cr2, 180, 0);
+ errors += !check_extents (ctx, phase, cr2, FILL, EQUALS, 0, 0, 0, 0);
+ errors += !check_extents (ctx, phase, cr2, STROKE, EQUALS, 175, -5, 10, 10);
+ errors += !check_extents (ctx, phase, cr2, PATH, EQUALS, 180, 0, 0, 0);
+ cairo_new_path (cr2);
+ cairo_restore (cr2);
+
+ phase = "Simple rect";
+ cairo_save (cr2);
+ cairo_rectangle (cr2, 10, 10, 80, 80);
+ errors += !check_extents (ctx, phase, cr2, FILL, EQUALS, 10, 10, 80, 80);
+ errors += !check_extents (ctx, phase, cr2, STROKE, EQUALS, 5, 5, 90, 90);
+ errors += !check_extents (ctx, phase, cr2, PATH, EQUALS, 10, 10, 80, 80);
+ cairo_new_path (cr2);
+ cairo_restore (cr2);
+
+ phase = "Two rects";
+ cairo_save (cr2);
+ cairo_rectangle (cr2, 10, 10, 10, 10);
+ cairo_rectangle (cr2, 20, 20, 10, 10);
+ errors += !check_extents (ctx, phase, cr2, FILL, EQUALS, 10, 10, 20, 20);
+ errors += !check_extents (ctx, phase, cr2, STROKE, EQUALS, 5, 5, 30, 30);
+ errors += !check_extents (ctx, phase, cr2, PATH, EQUALS, 10, 10, 20, 20);
+ cairo_new_path (cr2);
+ cairo_restore (cr2);
+
+ phase = "Triangle";
+ cairo_save (cr2);
+ cairo_move_to (cr2, 10, 10);
+ cairo_line_to (cr2, 90, 90);
+ cairo_line_to (cr2, 90, 10);
+ cairo_close_path (cr2);
+ /* miter joins protrude 5*(1+sqrt(2)) above the top-left corner and to
+ the right of the bottom-right corner */
+ errors += !check_extents (ctx, phase, cr2, FILL, EQUALS, 10, 10, 80, 80);
+ errors += !check_extents (ctx, phase, cr2, STROKE, CONTAINS, 0, 5, 95, 95);
+ errors += !check_extents (ctx, phase, cr2, PATH, CONTAINS, 10, 10, 80, 80);
+ cairo_new_path (cr2);
+ cairo_restore (cr2);
+
+ cairo_save (cr2);
+
+ cairo_set_line_width (cr2, 4);
+
+ cairo_rectangle (cr2, 10, 10, 30, 30);
+ cairo_rectangle (cr2, 25, 10, 15, 30);
+
+ cairo_set_fill_rule (cr2, CAIRO_FILL_RULE_EVEN_ODD);
+ phase = "EVEN_ODD overlapping rectangles";
+ errors += !check_extents (ctx, phase, cr2, FILL, EQUALS, 10, 10, 15, 30);
+ errors += !check_extents (ctx, phase, cr2, STROKE, EQUALS, 8, 8, 34, 34);
+ errors += !check_extents (ctx, phase, cr2, PATH, EQUALS, 10, 10, 30, 30);
+
+ /* Test other fill rule with the same path. */
+
+ cairo_set_fill_rule (cr2, CAIRO_FILL_RULE_WINDING);
+ phase = "WINDING overlapping rectangles";
+ errors += !check_extents (ctx, phase, cr2, FILL, EQUALS, 10, 10, 30, 30);
+ errors += !check_extents (ctx, phase, cr2, STROKE, EQUALS, 8, 8, 34, 34);
+ errors += !check_extents (ctx, phase, cr2, PATH, EQUALS, 10, 10, 30, 30);
+
+ /* Now, change the direction of the second rectangle and test both
+ * fill rules again. */
+ cairo_new_path (cr2);
+ cairo_rectangle (cr2, 10, 10, 30, 30);
+ cairo_rectangle (cr2, 25, 40, 15, -30);
+
+ cairo_set_fill_rule (cr2, CAIRO_FILL_RULE_EVEN_ODD);
+ phase = "EVEN_ODD overlapping rectangles";
+ errors += !check_extents (ctx, phase, cr2, FILL, EQUALS, 10, 10, 15, 30);
+ errors += !check_extents (ctx, phase, cr2, STROKE, EQUALS, 8, 8, 34, 34);
+ errors += !check_extents (ctx, phase, cr2, PATH, EQUALS, 10, 10, 30, 30);
+
+ /* Test other fill rule with the same path. */
+
+ cairo_set_fill_rule (cr2, CAIRO_FILL_RULE_WINDING);
+ phase = "WINDING overlapping rectangles";
+ errors += !check_extents (ctx, phase, cr2, FILL, EQUALS, 10, 10, 15, 30);
+ errors += !check_extents (ctx, phase, cr2, STROKE, EQUALS, 8, 8, 34, 34);
+ errors += !check_extents (ctx, phase, cr2, PATH, EQUALS, 10, 10, 30, 30);
+
+ cairo_new_path (cr2);
+
+ cairo_restore (cr2);
+
+ /* http://bugs.freedesktop.org/show_bug.cgi?id=7245 */
+ phase = "Arc";
+ cairo_save (cr2);
+ cairo_arc (cr2, 250.0, 250.0, 157.0, 5.147, 3.432);
+ cairo_set_line_width (cr2, 154.0);
+ errors += !check_extents (ctx, phase, cr2, STROKE, APPROX_EQUALS, 16, 38, 468, 446);
+ cairo_new_path (cr2);
+ cairo_restore (cr2);
+
+ phase = "Text";
+ cairo_save (cr2);
+ cairo_select_font_face (cr2, CAIRO_TEST_FONT_FAMILY " Sans",
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_NORMAL);
+ cairo_set_font_size (cr2, 12);
+ cairo_text_extents (cr2, string, &extents);
+ /* double check that the two methods of measuring the text agree... */
+ cairo_scaled_font_text_extents (cairo_get_scaled_font (cr2),
+ string,
+ &scaled_font_extents);
+ if (memcmp (&extents, &scaled_font_extents, sizeof (extents))) {
+ cairo_test_log (ctx, "Error: cairo_text_extents() does not match cairo_scaled_font_text_extents() - font extents (%f, %f) x (%f, %f) should be (%f, %f) x (%f, %f)\n",
+ scaled_font_extents.x_bearing,
+ scaled_font_extents.y_bearing,
+ scaled_font_extents.width,
+ scaled_font_extents.height,
+ extents.x_bearing,
+ extents.y_bearing,
+ extents.width,
+ extents.height);
+ errors++;
+ }
+
+ cairo_move_to (cr2, -extents.x_bearing, -extents.y_bearing);
+ cairo_text_path (cr2, string);
+ cairo_set_line_width (cr2, 2.0);
+ /* XXX: We'd like to be able to use EQUALS here, but currently
+ * when hinting is enabled freetype returns integer extents. See
+ * http://cairographics.org/todo */
+ errors += !check_extents (ctx, phase, cr2, FILL, APPROX_EQUALS,
+ 0, 0, extents.width, extents.height);
+ errors += !check_extents (ctx, phase, cr2, STROKE, APPROX_EQUALS,
+ -1, -1, extents.width+2, extents.height+2);
+ errors += !check_extents (ctx, phase, cr2, PATH, APPROX_EQUALS,
+ 0, 0, extents.width, extents.height);
+ cairo_new_path (cr2);
+ cairo_restore (cr2);
+
+ phase = "User space, simple scale, getting extents with same transform";
+ cairo_save (cr2);
+ cairo_scale (cr2, 2, 2);
+ cairo_rectangle (cr2, 5, 5, 40, 40);
+ errors += !check_extents (ctx, phase, cr2, FILL, EQUALS, 5, 5, 40, 40);
+ errors += !check_extents (ctx, phase, cr2, STROKE, EQUALS, 0, 0, 50, 50);
+ errors += !check_extents (ctx, phase, cr2, PATH, EQUALS, 5, 5, 40, 40);
+ cairo_new_path (cr2);
+ cairo_restore (cr2);
+
+ phase = "User space, simple scale, getting extents with no transform";
+ cairo_save (cr2);
+ cairo_save (cr2);
+ cairo_scale (cr2, 2, 2);
+ cairo_rectangle (cr2, 5, 5, 40, 40);
+ cairo_restore (cr2);
+ errors += !check_extents (ctx, phase, cr2, FILL, EQUALS, 10, 10, 80, 80);
+ errors += !check_extents (ctx, phase, cr2, STROKE, EQUALS, 5, 5, 90, 90);
+ errors += !check_extents (ctx, phase, cr2, PATH, EQUALS, 10, 10, 80, 80);
+ cairo_new_path (cr2);
+ cairo_restore (cr2);
+
+ phase = "User space, rotation, getting extents with transform";
+ cairo_save (cr2);
+ cairo_rectangle (cr2, -50, -50, 50, 50);
+ cairo_rotate (cr2, -M_PI/4);
+ /* the path in user space is now (nearly) the square rotated by
+ 45 degrees about the origin. Thus its x1 and x2 are both nearly 0.
+ This should show any bugs where we just transform device-space
+ x1,y1 and x2,y2 to get the extents. */
+ /* The largest axis-aligned square inside the rotated path has
+ side lengths 50*sqrt(2), so a bit over 35 on either side of
+ the axes. With the stroke width added to the rotated path,
+ the largest axis-aligned square is a bit over 38 on either side of
+ the axes. */
+ errors += !check_extents (ctx, phase, cr2, FILL, CONTAINS, -35, -35, 35, 35);
+ errors += !check_extents (ctx, phase, cr2, STROKE, CONTAINS, -38, -38, 38, 38);
+ errors += !check_extents (ctx, phase, cr2, PATH, CONTAINS, -35, -35, 35, 35);
+ cairo_new_path (cr2);
+ cairo_restore (cr2);
+
+ status = cairo_status (cr2);
+ cairo_destroy (cr2);
+
+ if (status)
+ return cairo_test_status_from_status (ctx, status);
+
+ return errors == 0 ? CAIRO_TEST_SUCCESS : CAIRO_TEST_FAILURE;
+}
+
+CAIRO_TEST (get_path_extents,
+ "Test cairo_fill_extents and cairo_stroke_extents",
+ "extents, path", /* keywords */
+ NULL, /* requirements */
+ 0, 0,
+ NULL, draw)
diff --git a/test/get-xrender-format.c b/test/get-xrender-format.c
new file mode 100644
index 000000000..3228d57c6
--- /dev/null
+++ b/test/get-xrender-format.c
@@ -0,0 +1,122 @@
+/*
+ * Copyright © 2008 Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+#include "cairo-test.h"
+
+#include "cairo-xlib.h"
+#include "cairo-xlib-xrender.h"
+
+#include "cairo-boilerplate-xlib.h"
+
+static cairo_test_status_t
+preamble (cairo_test_context_t *ctx)
+{
+ Display *dpy;
+ XRenderPictFormat *orig_format, *format;
+ cairo_surface_t *surface;
+ Pixmap pixmap;
+ int screen;
+ cairo_test_status_t result;
+
+ result = CAIRO_TEST_UNTESTED;
+
+ if (! cairo_test_is_target_enabled (ctx, "xlib"))
+ goto CLEANUP_TEST;
+
+ dpy = XOpenDisplay (NULL);
+ if (! dpy) {
+ cairo_test_log (ctx, "Error: Cannot open display: %s, skipping.\n",
+ XDisplayName (NULL));
+ goto CLEANUP_TEST;
+ }
+
+ result = CAIRO_TEST_FAILURE;
+
+ screen = DefaultScreen (dpy);
+
+ cairo_test_log (ctx, "Testing with image surface.\n");
+
+ surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 1, 1);
+
+ format = cairo_xlib_surface_get_xrender_format (surface);
+ if (format != NULL) {
+ cairo_test_log (ctx, "Error: expected NULL for image surface\n");
+ goto CLEANUP_SURFACE;
+ }
+
+ cairo_surface_destroy (surface);
+
+ cairo_test_log (ctx, "Testing with non-xrender xlib surface.\n");
+
+ pixmap = XCreatePixmap (dpy, DefaultRootWindow (dpy),
+ 1, 1, DefaultDepth (dpy, screen));
+ surface = cairo_xlib_surface_create (dpy, pixmap,
+ DefaultVisual (dpy, screen),
+ 1, 1);
+ orig_format = XRenderFindVisualFormat (dpy, DefaultVisual (dpy, screen));
+ format = cairo_xlib_surface_get_xrender_format (surface);
+ if (format != orig_format) {
+ cairo_test_log (ctx, "Error: did not receive the same format as XRenderFindVisualFormat\n");
+ goto CLEANUP_PIXMAP;
+ }
+ cairo_surface_destroy (surface);
+ XFreePixmap (dpy, pixmap);
+
+ cairo_test_log (ctx, "Testing with xlib xrender surface.\n");
+
+ orig_format = XRenderFindStandardFormat (dpy, PictStandardARGB32);
+ pixmap = XCreatePixmap (dpy, DefaultRootWindow (dpy),
+ 1, 1, 32);
+ surface = cairo_xlib_surface_create_with_xrender_format (dpy,
+ pixmap,
+ DefaultScreenOfDisplay (dpy),
+ orig_format,
+ 1, 1);
+ format = cairo_xlib_surface_get_xrender_format (surface);
+ if (format != orig_format) {
+ cairo_test_log (ctx, "Error: did not receive the same format originally set\n");
+ goto CLEANUP_PIXMAP;
+ }
+
+ result = CAIRO_TEST_SUCCESS;
+
+ CLEANUP_PIXMAP:
+ XFreePixmap (dpy, pixmap);
+ CLEANUP_SURFACE:
+ cairo_surface_destroy (surface);
+
+ XCloseDisplay (dpy);
+
+ CLEANUP_TEST:
+ return result;
+}
+
+CAIRO_TEST (get_xrender_format,
+ "Check XRender specific API",
+ "xrender, api", /* keywords */
+ NULL, /* requirements */
+ 0, 0,
+ preamble, NULL)
diff --git a/test/gl-device-release.c b/test/gl-device-release.c
new file mode 100644
index 000000000..7f554be30
--- /dev/null
+++ b/test/gl-device-release.c
@@ -0,0 +1,182 @@
+/*
+ * Copyright © 2012 Igalia S.L.
+ * Copyright © 2009 Eric Anholt
+ * Copyright © 2009 Chris Wilson
+ * Copyright © 2005 Red Hat, Inc
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Chris Wilson not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Chris Wilson makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * IGALIA S.L. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Martin Robinson <mrobinson@igalia.com>
+ */
+
+#include "cairo-test.h"
+#include <cairo-gl.h>
+#include <assert.h>
+
+static Window
+create_test_window (Display *display,
+ GLXContext glx_context,
+ XVisualInfo *visual_info)
+{
+ Colormap colormap;
+ XSetWindowAttributes window_attributes;
+ Window window = None;
+
+ colormap = XCreateColormap (display,
+ RootWindow (display, visual_info->screen),
+ visual_info->visual,
+ AllocNone);
+ window_attributes.colormap = colormap;
+ window_attributes.border_pixel = 0;
+ window = XCreateWindow (display, RootWindow (display, visual_info->screen),
+ -1, -1, 1, 1, 0,
+ visual_info->depth,
+ InputOutput,
+ visual_info->visual,
+ CWBorderPixel | CWColormap, &window_attributes);
+ XFreeColormap (display, colormap);
+
+ XFlush (display);
+ return window;
+}
+
+static cairo_bool_t
+multithread_makecurrent_available (Display *display)
+{
+ const char *extensions = glXQueryExtensionsString (display,
+ DefaultScreen (display));
+ return !! strstr(extensions, "GLX_MESA_multithread_makecurrent");
+}
+
+static void
+draw_to_surface (cairo_surface_t *surface)
+{
+ cairo_t *cr = cairo_create (surface);
+ cairo_paint (cr);
+ cairo_destroy (cr);
+}
+
+static cairo_test_status_t
+preamble (cairo_test_context_t *test_ctx)
+{
+ int rgba_attribs[] = {
+ GLX_RGBA,
+ GLX_RED_SIZE, 1,
+ GLX_GREEN_SIZE, 1,
+ GLX_BLUE_SIZE, 1,
+ GLX_ALPHA_SIZE, 1,
+ GLX_DOUBLEBUFFER,
+ None
+ };
+
+ XVisualInfo *visual_info;
+ GLXContext glx_context;
+ cairo_device_t *device;
+ Display *display;
+ Window test_window;
+ cairo_surface_t *window_surface;
+ cairo_bool_t has_multithread_makecurrent;
+
+ display = XOpenDisplay (NULL);
+ if (display == NULL)
+ return CAIRO_TEST_UNTESTED;
+
+ visual_info = glXChooseVisual (display, DefaultScreen (display), rgba_attribs);
+ if (visual_info == NULL) {
+ XCloseDisplay (display);
+ return CAIRO_TEST_UNTESTED;
+ }
+
+ glx_context = glXCreateContext (display, visual_info, NULL, True);
+ if (glx_context == NULL) {
+ XCloseDisplay (display);
+ return CAIRO_TEST_UNTESTED;
+ }
+
+ test_window = create_test_window (display, glx_context, visual_info);
+ XFree (visual_info);
+ if (test_window == None) {
+ XCloseDisplay (display);
+ return CAIRO_TEST_UNTESTED;
+ }
+
+ has_multithread_makecurrent = multithread_makecurrent_available (display);
+
+ glXMakeCurrent (display, None, None);
+
+ /* Creating the device should actually change the GL context, because of
+ * the creation/activation of a dummy window used for texture surfaces. */
+ device = cairo_glx_device_create (display, glx_context);
+
+ /* It's important that when multithread_makecurrent isn't available the
+ * Cairo backend clears the current context, so that the dummy texture
+ * window is not active while the device is unlocked. */
+ if (has_multithread_makecurrent) {
+ assert (None != glXGetCurrentDrawable ());
+ assert (display == glXGetCurrentDisplay ());
+ assert (glx_context == glXGetCurrentContext ());
+ } else {
+ assert (None == glXGetCurrentDrawable ());
+ assert (None == glXGetCurrentDisplay ());
+ assert (None == glXGetCurrentContext ());
+ }
+
+ window_surface = cairo_gl_surface_create_for_window (device, test_window,
+ 1, 1);
+ assert (cairo_surface_status (window_surface) == CAIRO_STATUS_SUCCESS);
+
+ draw_to_surface (window_surface);
+ if (has_multithread_makecurrent) {
+ assert (test_window == glXGetCurrentDrawable ());
+ assert (display == glXGetCurrentDisplay ());
+ assert (glx_context == glXGetCurrentContext ());
+ } else {
+ assert (None == glXGetCurrentDrawable ());
+ assert (None == glXGetCurrentDisplay ());
+ assert (None == glXGetCurrentContext ());
+ }
+
+ /* In this case, drawing to the window surface will not change the current
+ * GL context, so Cairo setting the current surface and context to none. */
+ glXMakeCurrent (display, test_window, glx_context);
+ draw_to_surface (window_surface);
+ assert (test_window == glXGetCurrentDrawable ());
+ assert (display == glXGetCurrentDisplay ());
+ assert (glx_context == glXGetCurrentContext ());
+
+ /* There should be no context change when destroying the device. */
+ cairo_device_destroy (device);
+ assert (test_window == glXGetCurrentDrawable ());
+ assert (display == glXGetCurrentDisplay ());
+ assert (glx_context == glXGetCurrentContext ());
+
+ glXDestroyContext(display, glx_context);
+ XDestroyWindow (display, test_window);
+ XCloseDisplay (display);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (gl_device_creation_changes_context,
+ "Test that using the Cairo GL backend leaves the current GL context in the appropriate state",
+ "gl", /* keywords */
+ NULL, /* requirements */
+ 0, 0,
+ preamble, NULL)
diff --git a/test/gl-oversized-surface.c b/test/gl-oversized-surface.c
new file mode 100644
index 000000000..4c46efd80
--- /dev/null
+++ b/test/gl-oversized-surface.c
@@ -0,0 +1,88 @@
+/*
+ * Copyright © 2012 Igalia S.L.
+ * Copyright © 2009 Eric Anholt
+ * Copyright © 2009 Chris Wilson
+ * Copyright © 2005 Red Hat, Inc
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Chris Wilson not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Chris Wilson makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * IGALIA S.L. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Martin Robinson <mrobinson@igalia.com>
+ */
+
+#include "cairo-test.h"
+#include <cairo-gl.h>
+#include <assert.h>
+#include <limits.h>
+
+static cairo_test_status_t
+preamble (cairo_test_context_t *test_ctx)
+{
+ int rgba_attribs[] = {
+ GLX_RGBA,
+ GLX_RED_SIZE, 1,
+ GLX_GREEN_SIZE, 1,
+ GLX_BLUE_SIZE, 1,
+ GLX_ALPHA_SIZE, 1,
+ GLX_DOUBLEBUFFER,
+ None
+ };
+
+ Display *display;
+ XVisualInfo *visual_info;
+ GLXContext glx_context;
+ cairo_device_t *device;
+ cairo_surface_t *oversized_surface;
+ cairo_test_status_t test_status = CAIRO_TEST_SUCCESS;
+
+ display = XOpenDisplay (NULL);
+ if (display == NULL)
+ return CAIRO_TEST_UNTESTED;
+
+ visual_info = glXChooseVisual (display, DefaultScreen (display), rgba_attribs);
+ if (visual_info == NULL) {
+ XCloseDisplay (display);
+ return CAIRO_TEST_UNTESTED;
+ }
+
+ glx_context = glXCreateContext (display, visual_info, NULL, True);
+ if (glx_context == NULL) {
+ XCloseDisplay (display);
+ return CAIRO_TEST_UNTESTED;
+ }
+
+ device = cairo_glx_device_create (display, glx_context);
+
+ oversized_surface = cairo_gl_surface_create (device, CAIRO_CONTENT_COLOR_ALPHA, INT_MAX, INT_MAX);
+ if (cairo_surface_status (oversized_surface) != CAIRO_STATUS_INVALID_SIZE)
+ test_status = CAIRO_TEST_FAILURE;
+
+ cairo_device_destroy (device);
+ glXDestroyContext(display, glx_context);
+ XCloseDisplay (display);
+
+ return test_status;
+}
+
+CAIRO_TEST (gl_oversized_surface,
+ "Test that creating a surface beyond texture limits results in an error surface",
+ "gl", /* keywords */
+ NULL, /* requirements */
+ 0, 0,
+ preamble, NULL)
diff --git a/test/gl-surface-source.c b/test/gl-surface-source.c
new file mode 100644
index 000000000..09d4d9c47
--- /dev/null
+++ b/test/gl-surface-source.c
@@ -0,0 +1,111 @@
+/*
+ * Copyright © 2008 Chris Wilson
+ * Copyright © 2010 Intel Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Chris Wilson not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Chris Wilson makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+#include <cairo-gl.h>
+
+#include "surface-source.c"
+
+struct closure {
+ Display *dpy;
+ GLXContext ctx;
+};
+
+static void
+cleanup (void *data)
+{
+ struct closure *arg = data;
+
+ glXDestroyContext (arg->dpy, arg->ctx);
+ XCloseDisplay (arg->dpy);
+
+ free (arg);
+}
+
+static cairo_surface_t *
+create_source_surface (int size)
+{
+ int rgba_attribs[] = {
+ GLX_RGBA,
+ GLX_RED_SIZE, 1,
+ GLX_GREEN_SIZE, 1,
+ GLX_BLUE_SIZE, 1,
+ GLX_ALPHA_SIZE, 1,
+ GLX_DOUBLEBUFFER,
+ None
+ };
+ XVisualInfo *visinfo;
+ GLXContext ctx;
+ struct closure *arg;
+ cairo_device_t *device;
+ cairo_surface_t *surface;
+ Display *dpy;
+
+ dpy = XOpenDisplay (NULL);
+ if (dpy == NULL)
+ return NULL;
+
+ visinfo = glXChooseVisual (dpy, DefaultScreen (dpy), rgba_attribs);
+ if (visinfo == NULL) {
+ XCloseDisplay (dpy);
+ return NULL;
+ }
+
+ ctx = glXCreateContext (dpy, visinfo, NULL, True);
+ XFree (visinfo);
+
+ if (ctx == NULL) {
+ XCloseDisplay (dpy);
+ return NULL;
+ }
+
+ arg = xmalloc (sizeof (struct closure));
+ arg->dpy = dpy;
+ arg->ctx = ctx;
+ device = cairo_glx_device_create (dpy, ctx);
+ if (cairo_device_set_user_data (device,
+ (cairo_user_data_key_t *) cleanup,
+ arg,
+ cleanup))
+ {
+ cleanup (arg);
+ return NULL;
+ }
+
+ surface = cairo_gl_surface_create (device,
+ CAIRO_CONTENT_COLOR_ALPHA,
+ size, size);
+ cairo_device_destroy (device);
+
+ return surface;
+}
+
+CAIRO_TEST (gl_surface_source,
+ "Test using a GL surface as the source",
+ "source", /* keywords */
+ NULL, /* requirements */
+ SIZE, SIZE,
+ preamble, draw)
diff --git a/test/global.jb2 b/test/global.jb2
new file mode 100644
index 000000000..5a1549853
--- /dev/null
+++ b/test/global.jb2
Binary files differ
diff --git a/test/glyph-cache-pressure.c b/test/glyph-cache-pressure.c
new file mode 100644
index 000000000..eb4f7c5c2
--- /dev/null
+++ b/test/glyph-cache-pressure.c
@@ -0,0 +1,81 @@
+/*
+ * Copyright © 2005 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+#include "cairo-test.h"
+#include "cairo-boilerplate-scaled-font.h"
+
+#define TEXT_SIZE 12
+
+/* Bug history
+ *
+ * 2006-06-22 Carl Worth <cworth@cworth.org>
+ *
+ * This is a test case to demonstrate the following bug in the xlib backend:
+ *
+ * Some characters aren't displayed when using xlib (cache usage missing freeze/thaw)
+ * https://bugs.freedesktop.org/show_bug.cgi?id=6955
+ *
+ * We replicate this bug by using the cairo_scaled_font_set_max_glyphs_per_font
+ * function to artificially induce cache pressure. (This function was added
+ * for this very purpose.)
+ *
+ * 2006-06-22 Carl Worth <cworth@cworth.org>
+ *
+ * Bug was simple enough to solve by just adding a freeze/thaw pair
+ * around the scaled_font's glyph cache in
+ * _cairo_xlib_surface_show_glyphs, (I went ahead and added
+ * _cairo_sacled_font_freeze/thaw_cache functions for this).
+ */
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ /* We draw in the default black, so paint white first. */
+ cairo_save (cr);
+ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */
+ cairo_paint (cr);
+ cairo_restore (cr);
+
+ cairo_select_font_face (cr, CAIRO_TEST_FONT_FAMILY " Sans",
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_NORMAL);
+ cairo_set_font_size (cr, TEXT_SIZE);
+
+ cairo_set_source_rgb (cr, 0, 0, 0); /* black */
+
+ cairo_boilerplate_scaled_font_set_max_glyphs_cached (cairo_get_scaled_font (cr), 1);
+
+ cairo_move_to (cr, 1, TEXT_SIZE);
+ cairo_show_text (cr, "the five boxing wizards jump quickly");
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (glyph_cache_pressure,
+ "Ensure that all backends behave well under artificial glyph cache pressure",
+ "stress", /* keywords */
+ NULL, /* requirements */
+ 223, TEXT_SIZE + 4,
+ NULL, draw)
diff --git a/test/gradient-alpha.c b/test/gradient-alpha.c
new file mode 100644
index 000000000..24cd3245f
--- /dev/null
+++ b/test/gradient-alpha.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright © 2005 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+#include "cairo-test.h"
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_pattern_t *gradient;
+
+ gradient = cairo_pattern_create_linear (0, -height,
+ 0, height);
+ cairo_pattern_add_color_stop_rgba (gradient, 0.0,
+ 1.0, 0.0, 0.0,
+ 1.0);
+ cairo_pattern_add_color_stop_rgba (gradient, 1.0,
+ 0.0, 0.0, 1.0,
+ 0.5);
+
+ cairo_set_source (cr, gradient);
+
+ cairo_paint (cr);
+
+ cairo_pattern_destroy (gradient);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (gradient_alpha,
+ "Tests drawing of a gradient with various alpha values in the color stops",
+ "gradient, alpha", /* keywords */
+ NULL, /* requirements */
+ 10, 10,
+ NULL, draw)
diff --git a/test/gradient-constant-alpha.c b/test/gradient-constant-alpha.c
new file mode 100644
index 000000000..7640b6eb5
--- /dev/null
+++ b/test/gradient-constant-alpha.c
@@ -0,0 +1,61 @@
+/*
+ * Copyright © 2005 Red Hat, Inc.
+ * Copyright © 2008 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ * Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_pattern_t *gradient;
+
+ gradient = cairo_pattern_create_linear (0, 0,
+ 0, height);
+ cairo_pattern_add_color_stop_rgba (gradient, 0.0,
+ 1.0, 0.0, 0.0,
+ 0.5);
+ cairo_pattern_add_color_stop_rgba (gradient, 0.0,
+ 0.0, 1.0, 0.0,
+ 0.5);
+ cairo_pattern_add_color_stop_rgba (gradient, 1.0,
+ 0.0, 0.0, 1.0,
+ 0.5);
+
+ cairo_set_source (cr, gradient);
+
+ cairo_paint (cr);
+
+ cairo_pattern_destroy (gradient);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (gradient_constant_alpha,
+ "Tests drawing of a gradient with constant alpha values in the color stops",
+ "gradient, alpha", /* keywords */
+ NULL,
+ 10, 10,
+ NULL, draw)
diff --git a/test/gradient-zero-stops-mask.c b/test/gradient-zero-stops-mask.c
new file mode 100644
index 000000000..b2a10ec34
--- /dev/null
+++ b/test/gradient-zero-stops-mask.c
@@ -0,0 +1,59 @@
+/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */
+/*
+ * Copyright © 2007 Brian Ewins
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Brian Ewins <Brian.Ewins@gmail.com>
+ * Contributor(s):
+ * Andrea Canciani <ranma42@gmail.com>
+ */
+
+#include "cairo-test.h"
+
+/* This test case is designed to exercise the opaque test for
+ * gradients with no stop.
+ */
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_pattern_t *pat;
+
+ cairo_set_source_rgb (cr, 1., 0., 0.);
+
+ pat = cairo_pattern_create_linear (0., 0., 1., 1.);
+ cairo_mask (cr, pat);
+ cairo_pattern_destroy (pat);
+
+ pat = cairo_pattern_create_radial (0., 0., 0., 1., 1., 1.);
+ cairo_mask (cr, pat);
+ cairo_pattern_destroy (pat);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (gradient_zero_stops_mask,
+ "Verifies that gradients with no stops are considered clear.",
+ "gradient", /* keywords */
+ NULL, /* requirements */
+ 2, 2,
+ NULL, draw)
diff --git a/test/gradient-zero-stops.c b/test/gradient-zero-stops.c
new file mode 100644
index 000000000..57a91c536
--- /dev/null
+++ b/test/gradient-zero-stops.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright © 2007 Brian Ewins
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Brian Ewins <Brian.Ewins@gmail.com>
+ */
+
+#include "cairo-test.h"
+
+/* This test case is designed to exercise the following bug:
+ *
+ * Crash when trying to paint gradient with no stops
+ * https://bugzilla.mozilla.org/show_bug.cgi?id=407104
+ */
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_pattern_t *pat;
+
+ pat = cairo_pattern_create_linear (0., 0., 1., 1.);
+ cairo_set_source (cr, pat);
+ cairo_paint (cr);
+ cairo_pattern_destroy (pat);
+
+ pat = cairo_pattern_create_radial (0., 0., 0., 1., 1., 1.);
+ cairo_set_source (cr, pat);
+ cairo_paint (cr);
+ cairo_pattern_destroy (pat);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (gradient_zero_stops,
+ "Verifies that gradients with no stops don't cause problems.",
+ "gradient", /* keywords */
+ NULL, /* requirements */
+ 2, 2,
+ NULL, draw)
diff --git a/test/group-clip.c b/test/group-clip.c
new file mode 100644
index 000000000..b99d8617e
--- /dev/null
+++ b/test/group-clip.c
@@ -0,0 +1,57 @@
+/*
+ * Copyright © Chris Wilson, 2008
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Chris Wilson not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Chris Wilson <chris@chris-wilson.co.uk>
+ * Larry Ewing <lewing@novell.com>
+ */
+
+#include "cairo-test.h"
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+ cairo_rectangle (cr, 25, 25, width, height);
+ cairo_clip_preserve (cr);
+ cairo_push_group (cr);
+ cairo_set_source_rgb (cr, 0, 0, 1);
+ cairo_fill (cr);
+ cairo_rectangle (cr, 0, 0, width, height);
+ cairo_pop_group_to_source (cr);
+ cairo_paint (cr);
+
+ cairo_reset_clip (cr);
+ cairo_clip_preserve (cr);
+ cairo_set_source_rgba (cr, 1, 0, 0, .5);
+ cairo_paint (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (group_clip,
+ "test preserving paths across groups",
+ "group", /* keywords */
+ NULL, /* requirements */
+ 40 + 25, 40 + 25,
+ NULL, draw)
diff --git a/test/group-paint.c b/test/group-paint.c
new file mode 100644
index 000000000..38544856f
--- /dev/null
+++ b/test/group-paint.c
@@ -0,0 +1,48 @@
+/*
+ * Copyright © Chris Wilson, 2008
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Chris Wilson not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_push_group (cr);
+
+ cairo_set_source_rgb (cr, 0, 0, 1);
+ cairo_paint (cr);
+
+ cairo_pop_group_to_source (cr);
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_paint (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (group_paint,
+ "test push_group(); pop_group_to_source(); set_operator(SOURCE); paint();",
+ "group", /* keywords */
+ NULL, /* requirements */
+ 10, 10,
+ NULL, draw)
diff --git a/test/group-state.c b/test/group-state.c
new file mode 100644
index 000000000..a96b2e3d0
--- /dev/null
+++ b/test/group-state.c
@@ -0,0 +1,96 @@
+/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */
+/*
+ * Copyright 2011 Andrea Canciani
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Andrea Canciani <ranma42@gmail.com>
+ */
+
+#include "cairo-test.h"
+
+#define CHECK_STATUS(status) \
+ do { \
+ if (cairo_status (cr) != (status)) { \
+ cairo_test_log (ctx, "Expected status: %s\n", \
+ cairo_status_to_string (status)); \
+ cairo_test_log (ctx, "Actual status: %s\n", \
+ cairo_status_to_string (cairo_status (cr))); \
+ result = CAIRO_TEST_FAILURE; \
+ } \
+ } while (0)
+
+static void
+reinit_cairo (cairo_t **cr)
+{
+ if (*cr)
+ cairo_destroy (*cr);
+
+ *cr = cairo_create (cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 1, 1));
+ cairo_surface_destroy (cairo_get_target (*cr));
+}
+
+static cairo_test_status_t
+preamble (cairo_test_context_t *ctx)
+{
+ cairo_t *cr;
+ cairo_test_status_t result = CAIRO_TEST_SUCCESS;
+
+ cr = NULL;
+
+ reinit_cairo (&cr);
+
+ /* cairo_restore() must fail with CAIRO_STATUS_INVALID_RESTORE if
+ * no matching cairo_save() call has been performed. */
+ cairo_test_log (ctx, "Checking save(); push(); restore();\n");
+ cairo_save (cr);
+ CHECK_STATUS (CAIRO_STATUS_SUCCESS);
+ cairo_push_group (cr);
+ CHECK_STATUS (CAIRO_STATUS_SUCCESS);
+ cairo_restore (cr);
+ CHECK_STATUS (CAIRO_STATUS_INVALID_RESTORE);
+
+
+ reinit_cairo (&cr);
+
+ /* cairo_restore() must fail with CAIRO_STATUS_INVALID_RESTORE if
+ * no matching cairo_save() call has been performed. */
+ cairo_test_log (ctx, "Checking push(); save(); pop();\n");
+ cairo_push_group (cr);
+ CHECK_STATUS (CAIRO_STATUS_SUCCESS);
+ cairo_save (cr);
+ CHECK_STATUS (CAIRO_STATUS_SUCCESS);
+ cairo_pop_group_to_source (cr);
+ CHECK_STATUS (CAIRO_STATUS_INVALID_POP_GROUP);
+
+
+ cairo_destroy (cr);
+
+ return result;
+}
+
+CAIRO_TEST (group_state,
+ "Tests the interaction between state (cairo_save, cairo_restore) "
+ "and group (cairo_push_group/cairo_pop_group) API",
+ "api", /* keywords */
+ NULL, /* requirements */
+ 0, 0,
+ preamble, NULL)
diff --git a/test/group-unaligned.c b/test/group-unaligned.c
new file mode 100644
index 000000000..9124a032c
--- /dev/null
+++ b/test/group-unaligned.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright © Chris Wilson, 2008
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Chris Wilson not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Chris Wilson <chris@chris-wilson.co.uk>
+ * Stefan Röllin <stefan.roellin@gmx.ch>
+ */
+
+#include "cairo-test.h"
+
+static void
+circle (cairo_t* cr, double xc, double yc, double radius)
+{
+ cairo_arc (cr, xc, yc, radius, 0.0, 2*M_PI);
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+ cairo_set_source_rgb (cr, 1, 0, 0);
+ circle (cr, 12.5, 12.5, 10.);
+ cairo_fill (cr);
+
+ cairo_push_group (cr);
+ cairo_set_source_rgb (cr, 0, 0, 1);
+ circle (cr, 12.5, 12.5, 10.);
+ cairo_fill (cr);
+ cairo_pop_group_to_source (cr);
+ cairo_paint (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (group_unaligned,
+ "test non-integer sized sub-surface",
+ "group", /* keywords */
+ NULL, /* requirements */
+ 35.5, 35.5,
+ NULL, draw)
diff --git a/test/half-coverage.c b/test/half-coverage.c
new file mode 100644
index 000000000..38cafda75
--- /dev/null
+++ b/test/half-coverage.c
@@ -0,0 +1,155 @@
+/*
+ * Copyright 2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+/* Test the fidelity of the rasterisation, because Cairo is my favourite
+ * driver test suite.
+ */
+
+#define SIZE 256
+#define WIDTH 2
+#define HEIGHT 10
+
+static cairo_test_status_t
+rectangles (cairo_t *cr, int width, int height)
+{
+ int i;
+
+ cairo_set_source_rgb (cr, 1.0, 0.0, 0.0);
+ cairo_paint (cr);
+ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
+
+ for (i = 1; i <= SIZE; i++) {
+ int x, y;
+
+ cairo_save (cr);
+ cairo_rectangle (cr, 0, 0, WIDTH, HEIGHT);
+ cairo_clip (cr);
+
+ cairo_scale (cr, 1./SIZE, 1./SIZE);
+ for (x = -i; x < SIZE*WIDTH; x += 2*i) {
+ for (y = -i; y < SIZE*HEIGHT; y += 2*i) {
+ /* Add a little tile composed of two non-overlapping squares
+ * +--+
+ * | |
+ * |__|__
+ * | |
+ * | |
+ * +--+
+ */
+ cairo_rectangle (cr, x, y, i, i);
+ cairo_rectangle (cr, x+i, y+i, i, i);
+ }
+ }
+ cairo_fill (cr);
+ cairo_restore (cr);
+
+ cairo_translate (cr, WIDTH, 0);
+ }
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+triangles (cairo_t *cr, int width, int height)
+{
+ int i;
+
+ cairo_set_source_rgb (cr, 1.0, 0.0, 0.0);
+ cairo_paint (cr);
+ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
+
+ for (i = 1; i <= SIZE; i++) {
+ int x, y;
+
+ cairo_save (cr);
+ cairo_rectangle (cr, 0, 0, WIDTH, HEIGHT);
+ cairo_clip (cr);
+
+ cairo_scale (cr, 1./SIZE, 1./SIZE);
+ for (x = -i; x < SIZE*WIDTH; x += 2*i) {
+ for (y = -i; y < SIZE*HEIGHT; y += 2*i) {
+ /* Add a tile composed of four non-overlapping
+ * triangles. The plus and minus signs inside the
+ * triangles denote the orientation of the triangle's
+ * edges: + for clockwise and - for anticlockwise.
+ *
+ * +-----+
+ * \-|+/
+ * \|/
+ * /|\
+ * /-|-\
+ * +-----+
+ */
+
+ /* top left triangle */
+ cairo_move_to (cr, x, y);
+ cairo_line_to (cr, x+i, y+i);
+ cairo_line_to (cr, x+i, y);
+ cairo_close_path (cr);
+
+ /* top right triangle */
+ cairo_move_to (cr, x+i, y);
+ cairo_line_to (cr, x+2*i, y);
+ cairo_line_to (cr, x+i, y+i);
+ cairo_close_path (cr);
+
+ /* bottom left triangle */
+ cairo_move_to (cr, x+i, y+i);
+ cairo_line_to (cr, x, y+2*i);
+ cairo_line_to (cr, x+i, y+2*i);
+ cairo_close_path (cr);
+
+ /* bottom right triangle */
+ cairo_move_to (cr, x+i, y+i);
+ cairo_line_to (cr, x+i, y+2*i);
+ cairo_line_to (cr, x+2*i, y+2*i);
+ cairo_close_path (cr);
+ }
+ }
+ cairo_fill (cr);
+ cairo_restore (cr);
+
+ cairo_translate (cr, WIDTH, 0);
+ }
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (half_coverage_rectangles,
+ "Check the fidelity of the rasterisation.",
+ NULL, /* keywords */
+ "target=raster slow", /* requirements */
+ WIDTH * SIZE, HEIGHT,
+ NULL, rectangles)
+
+CAIRO_TEST (half_coverage_triangles,
+ "Check the fidelity of the rasterisation.",
+ NULL, /* keywords */
+ "target=raster slow", /* requirements */
+ WIDTH * SIZE, HEIGHT,
+ NULL, triangles)
diff --git a/test/halo.c b/test/halo.c
new file mode 100644
index 000000000..30064e51a
--- /dev/null
+++ b/test/halo.c
@@ -0,0 +1,158 @@
+/*
+ * Copyright 2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+/* Try to replicate the misbehaviour of show_glyphs() versus glyph_path()
+ * in the PDF backend reported by Ian Britten.
+ */
+
+static void
+halo_around_path (cairo_t *cr, const char *str)
+{
+ cairo_text_path (cr, str);
+
+ cairo_set_source_rgb (cr, 0, .5, 1);
+ cairo_stroke_preserve (cr);
+ cairo_set_source_rgb (cr, 1, .5, 0);
+ cairo_fill (cr);
+}
+
+static void
+halo_around_text (cairo_t *cr, const char *str)
+{
+ double x, y;
+
+ cairo_get_current_point (cr, &x, &y);
+ cairo_text_path (cr, str);
+
+ cairo_set_source_rgb (cr, 0, .5, 1);
+ cairo_stroke(cr);
+
+ cairo_set_source_rgb (cr, 1, .5, 0);
+ cairo_move_to (cr, x, y);
+ cairo_show_text (cr, str);
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ const char *string = "0123456789";
+ cairo_text_extents_t extents;
+
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+ cairo_text_extents (cr, string, &extents);
+
+ cairo_set_font_size (cr, 12);
+ cairo_set_line_width (cr, 3);
+ cairo_move_to (cr, 9, 4 + extents.height);
+ halo_around_path (cr, string);
+
+ cairo_move_to (cr, 109, 4 + extents.height);
+ halo_around_text (cr, string);
+
+ cairo_set_font_size (cr, 6);
+ cairo_set_line_width (cr, 3);
+ cairo_move_to (cr, 19 + extents.width, 20 + extents.height);
+ halo_around_path (cr, "0");
+
+ cairo_move_to (cr, 119 + extents.width, 20 + extents.height);
+ halo_around_text (cr, "0");
+
+ cairo_set_font_size (cr, 64);
+ cairo_set_line_width (cr, 10);
+ cairo_move_to (cr, 8, 70);
+ halo_around_path (cr, "6");
+ cairo_move_to (cr, 32, 90);
+ halo_around_path (cr, "7");
+
+ cairo_move_to (cr, 108, 70);
+ halo_around_text (cr, "6");
+ cairo_move_to (cr, 132, 90);
+ halo_around_text (cr, "7");
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+draw_transform (cairo_t *cr, int width, int height)
+{
+ const char *string = "0123456789";
+ cairo_text_extents_t extents;
+
+ cairo_translate (cr, 50, 50);
+ cairo_scale (cr, M_SQRT2, M_SQRT2);
+
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+ cairo_text_extents (cr, string, &extents);
+
+ cairo_set_line_width (cr, 3);
+ cairo_move_to (cr, 9, 4 + extents.height);
+ halo_around_path (cr, string);
+
+ cairo_move_to (cr, 109, 4 + extents.height);
+ halo_around_text (cr, string);
+
+ cairo_set_font_size (cr, 6);
+ cairo_set_line_width (cr, 3);
+ cairo_move_to (cr, 19 + extents.width, 20 + extents.height);
+ halo_around_path (cr, "0");
+
+ cairo_move_to (cr, 119 + extents.width, 20 + extents.height);
+ halo_around_text (cr, "0");
+
+ cairo_set_font_size (cr, 64);
+ cairo_set_line_width (cr, 10);
+ cairo_move_to (cr, 8, 70);
+ halo_around_path (cr, "6");
+ cairo_move_to (cr, 32, 90);
+ halo_around_path (cr, "7");
+
+ cairo_move_to (cr, 108, 70);
+ halo_around_text (cr, "6");
+ cairo_move_to (cr, 132, 90);
+ halo_around_text (cr, "7");
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (halo,
+ "Check the show_glyphs() vs glyph_path()",
+ "text", /* keywords */
+ NULL, /* requirements */
+ 200, 100,
+ NULL, draw)
+
+CAIRO_TEST (halo_transform,
+ "Check the show_glyphs() vs glyph_path()",
+ "text", /* keywords */
+ NULL, /* requirements */
+ 400, 200,
+ NULL, draw_transform)
diff --git a/test/hatchings.c b/test/hatchings.c
new file mode 100644
index 000000000..ca3f2c6af
--- /dev/null
+++ b/test/hatchings.c
@@ -0,0 +1,153 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+#define STEP 5
+#define WIDTH 100
+#define HEIGHT 100
+
+static void hatching (cairo_t *cr)
+{
+ int i;
+
+ cairo_rectangle (cr, 0, 0, WIDTH, HEIGHT);
+ cairo_clip (cr);
+
+ for (i = 0; i < WIDTH; i += STEP) {
+ cairo_rectangle (cr, i-1, -2, 2, HEIGHT+4);
+ cairo_rectangle (cr, -2, i-1, WIDTH+4, 2);
+ }
+}
+
+static void background (cairo_t *cr)
+{
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_set_source_rgb (cr, 1,1,1);
+ cairo_paint (cr);
+}
+
+static void clip_to_quadrant (cairo_t *cr)
+{
+ cairo_rectangle (cr, 0, 0, WIDTH, HEIGHT);
+ cairo_clip (cr);
+}
+
+static void draw_hatching (cairo_t *cr, void (*func) (cairo_t *))
+{
+ cairo_save (cr); {
+ clip_to_quadrant (cr);
+ hatching (cr);
+ func (cr);
+ } cairo_restore (cr);
+
+ cairo_translate (cr, WIDTH, 0);
+
+ cairo_save (cr); {
+ clip_to_quadrant (cr);
+ cairo_translate (cr, 0.25, 0.25);
+ hatching (cr);
+ func (cr);
+ } cairo_restore (cr);
+
+ cairo_translate (cr, WIDTH, 0);
+
+ cairo_save (cr); {
+ clip_to_quadrant (cr);
+ cairo_translate (cr, WIDTH/2, HEIGHT/2);
+ cairo_rotate (cr, M_PI/4);
+ cairo_translate (cr, -WIDTH/2, -HEIGHT/2);
+ hatching (cr);
+ func (cr);
+ } cairo_restore (cr);
+
+ cairo_translate (cr, WIDTH, 0);
+}
+
+static void do_clip (cairo_t *cr)
+{
+ cairo_clip (cr);
+ cairo_paint (cr);
+}
+
+static void do_clip_alpha (cairo_t *cr)
+{
+ cairo_clip (cr);
+ cairo_paint_with_alpha (cr, .5);
+}
+
+static void hatchings (cairo_t *cr, void (*func) (cairo_t *))
+{
+ cairo_save (cr); {
+ cairo_set_source_rgb(cr, 1, 0, 0);
+ cairo_set_antialias (cr, CAIRO_ANTIALIAS_DEFAULT);
+ draw_hatching (cr, func);
+ cairo_set_source_rgb(cr, 0, 0, 1);
+ cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE);
+ draw_hatching (cr, func);
+ } cairo_restore (cr);
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ background (cr);
+
+
+ /* aligned, misaligned, diagonal; mono repeat
+ * x fill
+ * x clip; paint
+ * x clip; paint-alpha
+ * repeated, for over/source
+ */
+
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+
+ hatchings (cr, cairo_fill);
+ cairo_translate (cr, 0, HEIGHT);
+ hatchings (cr, do_clip);
+ cairo_translate (cr, 0, HEIGHT);
+ hatchings (cr, do_clip_alpha);
+ cairo_translate (cr, 0, HEIGHT);
+
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+
+ hatchings (cr, cairo_fill);
+ cairo_translate (cr, 0, HEIGHT);
+ hatchings (cr, do_clip);
+ cairo_translate (cr, 0, HEIGHT);
+ hatchings (cr, do_clip_alpha);
+ cairo_translate (cr, 0, HEIGHT);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (hatchings,
+ "Test drawing through various aligned/unaliged clips",
+ "clip, alpha", /* keywords */
+ "target=raster", /* requirements */
+ 6*WIDTH, 6*HEIGHT,
+ NULL, draw)
diff --git a/test/horizontal-clip.c b/test/horizontal-clip.c
new file mode 100644
index 000000000..93127a722
--- /dev/null
+++ b/test/horizontal-clip.c
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2011 Intel Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Chris Wilson not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Chris Wilson makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+/* Exercises a bug spotted by Andrea Canciani where the polygon clipping
+ * code was hopeless broken with horizontal edges.
+ */
+
+#include "cairo-test.h"
+
+#define WIDTH 16
+#define HEIGHT 26
+
+#define BUGY 1
+#define BUGX (4 * BUGY * WIDTH * 256)
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+ cairo_set_source_rgb (cr, 0, 0, 0);
+
+ cairo_move_to (cr, - BUGX, 6 - BUGY);
+ cairo_line_to (cr, + BUGX, 6 + BUGY);
+ cairo_line_to (cr, WIDTH + BUGX, 2 - BUGY);
+ cairo_line_to (cr, WIDTH - BUGX, 2 + BUGY);
+ cairo_fill (cr);
+
+ cairo_move_to (cr, WIDTH + BUGX, 8 - BUGY);
+ cairo_line_to (cr, WIDTH - BUGX, 8 + BUGY);
+ cairo_line_to (cr, - BUGX, 12 - BUGY);
+ cairo_line_to (cr, + BUGX, 12 + BUGY);
+ cairo_fill (cr);
+
+ cairo_move_to (cr, - BUGX, 14 - BUGY);
+ cairo_line_to (cr, + BUGX, 14 + BUGY);
+ cairo_line_to (cr, WIDTH + BUGX, 18 - BUGY);
+ cairo_line_to (cr, WIDTH - BUGX, 18 + BUGY);
+ cairo_fill (cr);
+
+ cairo_move_to (cr, WIDTH + BUGX, 24 - BUGY);
+ cairo_line_to (cr, WIDTH - BUGX, 24 + BUGY);
+ cairo_line_to (cr, - BUGX, 20 - BUGY);
+ cairo_line_to (cr, + BUGX, 20 + BUGY);
+ cairo_fill (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (horizontal_clip,
+ "Tests intersection of a nearly horizontal lines with a clipped polygon",
+ "clip, fill", /* keywords */
+ NULL, /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw)
diff --git a/test/huge-linear.c b/test/huge-linear.c
new file mode 100644
index 000000000..f84b4ea0c
--- /dev/null
+++ b/test/huge-linear.c
@@ -0,0 +1,67 @@
+/*
+ * Copyright © 2006 Benjamin Otte
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Benjamin Otte <otte@gnome.org>
+ */
+
+#include "cairo-test.h"
+
+/* set this to 0.1 to make this test work */
+#define FACTOR 1.e6
+
+/* XXX poppler-cairo doesn't handle gradients very well... */
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_pattern_t *pattern;
+ cairo_matrix_t mat = {
+ 0, -4.5254285714285709 * FACTOR,
+ -2.6398333333333333 * FACTOR, 0,
+ 0, 0
+ };
+
+ pattern = cairo_pattern_create_linear (-16384 * FACTOR, 0,
+ 16384 * FACTOR, 0);
+ cairo_pattern_add_color_stop_rgba (pattern,
+ 0, 0.376471, 0.533333, 0.27451, 1);
+ cairo_pattern_add_color_stop_rgba (pattern, 1, 1, 1, 1, 1);
+ cairo_pattern_set_matrix (pattern, &mat);
+
+ cairo_scale (cr, 0.05, 0.05);
+ cairo_translate (cr, 6000, 3500);
+
+ cairo_set_source (cr, pattern);
+ cairo_rectangle (cr, -6000, -3500, 12000, 7000);
+ cairo_pattern_destroy (pattern);
+ cairo_fill (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (huge_linear,
+ "Test huge linear patterns",
+ "gradient, linear", /* keywords */
+ NULL, /* requirements */
+ 600, 350,
+ NULL, draw)
diff --git a/test/huge-radial.c b/test/huge-radial.c
new file mode 100644
index 000000000..21524b7a4
--- /dev/null
+++ b/test/huge-radial.c
@@ -0,0 +1,69 @@
+/*
+ * Copyright © 2006 Benjamin Otte
+ * Copyright © 2009 Chris Wilson
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Benjamin Otte <otte@gnome.org>
+ * Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+/* set this to 0.1 to make this test work */
+#define FACTOR 1.e6
+
+/* XXX poppler-cairo doesn't handle gradients very well... */
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_pattern_t *pattern;
+ cairo_matrix_t mat = {
+ 0, -4.5254285714285709 * FACTOR,
+ -2.6398333333333333 * FACTOR, 0,
+ 0, 0
+ };
+
+ pattern = cairo_pattern_create_radial (0, 0, 0,
+ 0, 0, 16384 * FACTOR);
+ cairo_pattern_add_color_stop_rgba (pattern,
+ 0, 0.376471, 0.533333, 0.27451, 1);
+ cairo_pattern_add_color_stop_rgba (pattern, 1, 1, 1, 1, 1);
+ cairo_pattern_set_matrix (pattern, &mat);
+
+ cairo_scale (cr, 0.05, 0.05);
+ cairo_translate (cr, 6000, 3500);
+
+ cairo_set_source (cr, pattern);
+ cairo_rectangle (cr, -6000, -3500, 12000, 7000);
+ cairo_pattern_destroy (pattern);
+ cairo_fill (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (huge_radial,
+ "Test huge radial patterns",
+ "gradient, radial", /* keywords */
+ NULL, /* requirements */
+ 600, 350,
+ NULL, draw)
diff --git a/test/image-bug-710072.c b/test/image-bug-710072.c
new file mode 100644
index 000000000..9cf0da799
--- /dev/null
+++ b/test/image-bug-710072.c
@@ -0,0 +1,80 @@
+/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */
+/*
+ * Copyright 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+/*
+ * This test case aims to reproduce the misbehaviour exhibited in
+ * https://bugs.launchpad.net/ubuntu/+source/cairo/+bug/710072
+ * i.e. out of bounds rendering with the rectangular span compositor.
+ */
+
+#include "cairo-test.h"
+
+static cairo_test_status_t
+draw_aligned (cairo_t *cr, int width, int height)
+{
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+ cairo_rectangle (cr, -10, -10, 20, 20);
+ cairo_rectangle (cr, 5, 5, 20, 20);
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ cairo_fill_preserve (cr);
+ cairo_set_source_rgba (cr, 1, 0, 0, .5);
+ cairo_stroke (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+draw_unaligned (cairo_t *cr, int width, int height)
+{
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+ cairo_rectangle (cr, -10.5, -10.5, 20, 20);
+ cairo_rectangle (cr, 5.5, 5.5, 20, 20);
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ cairo_fill_preserve (cr);
+ cairo_set_source_rgba (cr, 1, 0, 0, .5);
+ cairo_stroke (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (image_bug_710072_aligned,
+ "Tests a bug where we may compute spans greater than bounded extents",
+ "extents, fill, stroke", /* keywords */
+ NULL, /* requirements */
+ 15, 15,
+ NULL, draw_aligned)
+
+CAIRO_TEST (image_bug_710072_unaligned,
+ "Tests a bug where we may compute spans greater than bounded extents",
+ "extents, fill, stroke", /* keywords */
+ NULL, /* requirements */
+ 15, 15,
+ NULL, draw_unaligned)
diff --git a/test/image-surface-source.c b/test/image-surface-source.c
new file mode 100644
index 000000000..c7c1fdc33
--- /dev/null
+++ b/test/image-surface-source.c
@@ -0,0 +1,41 @@
+/*
+ * Copyright © 2008 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Chris Wilson not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Chris Wilson makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+#include "surface-source.c"
+
+static cairo_surface_t *
+create_source_surface (int size)
+{
+ return cairo_image_surface_create (CAIRO_FORMAT_ARGB32, size, size);
+}
+
+CAIRO_TEST (image_surface_source,
+ "Test using a image surface as the source",
+ "source", /* keywords */
+ NULL, /* requirements */
+ SIZE, SIZE,
+ preamble, draw)
diff --git a/test/image1.jb2 b/test/image1.jb2
new file mode 100644
index 000000000..882ca95eb
--- /dev/null
+++ b/test/image1.jb2
Binary files differ
diff --git a/test/image2.jb2 b/test/image2.jb2
new file mode 100644
index 000000000..48e41463f
--- /dev/null
+++ b/test/image2.jb2
Binary files differ
diff --git a/test/imagediff.c b/test/imagediff.c
new file mode 100644
index 000000000..6ebbcfca7
--- /dev/null
+++ b/test/imagediff.c
@@ -0,0 +1,303 @@
+/* imagediff - Compare two images
+ *
+ * Copyright © 2004 Richard D. Worth
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of Richard Worth
+ * not be used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * Richard Worth makes no representations about the suitability of this
+ * software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ *
+ * RICHARD WORTH DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
+ * NO EVENT SHALL RICHARD WORTH BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+ * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Richard D. Worth <richard@theworths.org> */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <errno.h>
+
+#include "buffer-diff.h"
+
+static void
+_xunlink (const char *pathname)
+{
+ if (unlink (pathname) < 0 && errno != ENOENT) {
+ fprintf (stderr, " Error: Cannot remove %s: %s\n",
+ pathname, strerror (errno));
+ exit (1);
+ }
+}
+
+void
+cairo_test_logv (const cairo_test_context_t *ctx,
+ const char *fmt, va_list va)
+{
+ vfprintf (stderr, fmt, va);
+}
+
+void
+cairo_test_log (const cairo_test_context_t *ctx, const char *fmt, ...)
+{
+ va_list va;
+
+ va_start (va, fmt);
+ vfprintf (stderr, fmt, va);
+ va_end (va);
+}
+
+/* Flatten an ARGB surface by blending it over white. The resulting
+ * surface, (still in ARGB32 format, but with only alpha==1.0
+ * everywhere) is returned in the same surface pointer.
+ *
+ * The original surface will be destroyed.
+ *
+ * The (x,y) value specify an origin of interest for the original
+ * image. The flattened image will be generated only from the box
+ * extending from (x,y) to (width,height).
+ */
+static void
+flatten_surface (cairo_surface_t **surface, int x, int y)
+{
+ cairo_surface_t *flat;
+ cairo_t *cr;
+
+ flat = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
+ cairo_image_surface_get_width (*surface) - x,
+ cairo_image_surface_get_height (*surface) - y);
+ cairo_surface_set_device_offset (flat, -x, -y);
+
+ cr = cairo_create (flat);
+ cairo_surface_destroy (flat);
+
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+ cairo_set_source_surface (cr, *surface, 0, 0);
+ cairo_surface_destroy (*surface);
+ cairo_paint (cr);
+
+ *surface = cairo_surface_reference (cairo_get_target (cr));
+ cairo_destroy (cr);
+}
+
+/* Given an image surface, create a new surface that has the same
+ * contents as the sub-surface with its origin at x,y.
+ *
+ * The original surface will be destroyed.
+ */
+static void
+extract_sub_surface (cairo_surface_t **surface, int x, int y)
+{
+ cairo_surface_t *sub;
+ cairo_t *cr;
+
+ sub = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
+ cairo_image_surface_get_width (*surface) - x,
+ cairo_image_surface_get_height (*surface) - y);
+
+ /* We don't use a device offset like flatten_surface. That's not
+ * for any important reason, (the results should be
+ * identical). This style just seemed more natural to me this
+ * time, so I'm leaving both here so I can look at both to see
+ * which I like better. */
+ cr = cairo_create (sub);
+ cairo_surface_destroy (sub);
+
+ cairo_set_source_surface (cr, *surface, -x, -y);
+ cairo_surface_destroy (*surface);
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_paint (cr);
+
+ *surface = cairo_surface_reference (cairo_get_target (cr));
+ cairo_destroy (cr);
+}
+
+static cairo_status_t
+stdio_write_func (void *closure, const unsigned char *data, unsigned int length)
+{
+ FILE *file = closure;
+
+ if (fwrite (data, 1, length, file) != length)
+ return CAIRO_STATUS_WRITE_ERROR;
+
+ return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_status_t
+write_png (cairo_surface_t *surface, const char *filename)
+{
+ cairo_status_t status;
+ FILE *png_file;
+
+ if (filename != NULL) {
+ png_file = fopen (filename, "wb");
+ if (png_file == NULL) {
+ switch (errno) {
+ case ENOMEM:
+ return CAIRO_STATUS_NO_MEMORY;
+ default:
+ return CAIRO_STATUS_WRITE_ERROR;
+ }
+ }
+ } else
+ png_file = stdout;
+
+ status = cairo_surface_write_to_png_stream (surface,
+ stdio_write_func,
+ png_file);
+
+ if (png_file != stdout)
+ fclose (png_file);
+
+ return status;
+}
+
+static cairo_status_t
+png_diff (const char *filename_a,
+ const char *filename_b,
+ const char *filename_diff,
+ int ax,
+ int ay,
+ int bx,
+ int by,
+ buffer_diff_result_t *result)
+{
+ cairo_surface_t *surface_a;
+ cairo_surface_t *surface_b;
+ cairo_surface_t *surface_diff;
+ cairo_status_t status;
+
+ surface_a = cairo_image_surface_create_from_png (filename_a);
+ status = cairo_surface_status (surface_a);
+ if (status) {
+ fprintf (stderr, "Error: Failed to create surface from %s: %s\n",
+ filename_a, cairo_status_to_string (status));
+ return status;
+ }
+
+ surface_b = cairo_image_surface_create_from_png (filename_b);
+ status = cairo_surface_status (surface_b);
+ if (status) {
+ fprintf (stderr, "Error: Failed to create surface from %s: %s\n",
+ filename_b, cairo_status_to_string (status));
+ cairo_surface_destroy (surface_a);
+ return status;
+ }
+
+ if (ax || ay) {
+ extract_sub_surface (&surface_a, ax, ay);
+ ax = ay = 0;
+ }
+
+ if (bx || by) {
+ extract_sub_surface (&surface_b, bx, by);
+ bx = by = 0;
+ }
+
+ status = cairo_surface_status (surface_a);
+ if (status) {
+ fprintf (stderr, "Error: Failed to extract surface from %s: %s\n",
+ filename_a, cairo_status_to_string (status));
+ cairo_surface_destroy (surface_a);
+ cairo_surface_destroy (surface_b);
+ return status;
+ }
+ status = cairo_surface_status (surface_b);
+ if (status) {
+ fprintf (stderr, "Error: Failed to extract surface from %s: %s\n",
+ filename_b, cairo_status_to_string (status));
+ cairo_surface_destroy (surface_a);
+ cairo_surface_destroy (surface_b);
+ return status;
+ }
+
+ surface_diff = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
+ cairo_image_surface_get_width (surface_a),
+ cairo_image_surface_get_height (surface_a));
+ status = cairo_surface_status (surface_diff);
+ if (status) {
+ fprintf (stderr,
+ "Error: Failed to allocate surface to hold differences\n");
+ cairo_surface_destroy (surface_a);
+ cairo_surface_destroy (surface_b);
+ return CAIRO_STATUS_NO_MEMORY;
+ }
+
+ status = image_diff (NULL,
+ surface_a, surface_b, surface_diff,
+ result);
+
+ if (filename_diff)
+ _xunlink (filename_diff);
+
+ if (status == CAIRO_STATUS_SUCCESS &&
+ result->pixels_changed)
+ {
+ status = write_png (surface_diff, filename_diff);
+ }
+
+ cairo_surface_destroy (surface_a);
+ cairo_surface_destroy (surface_b);
+ cairo_surface_destroy (surface_diff);
+
+ return status;
+}
+
+int
+main (int argc, char *argv[])
+{
+ buffer_diff_result_t result;
+ cairo_status_t status;
+
+ unsigned int ax, ay, bx, by;
+
+ if (argc != 3 && argc != 7) {
+ fprintf (stderr, "Usage: %s image1.png image2.png [ax ay bx by]\n", argv[0]);
+ fprintf (stderr, "Computes an output image designed to present a \"visual diff\" such that even\n");
+ fprintf (stderr, "small errors in single pixels are readily apparent in the output.\n");
+ fprintf (stderr, "The output image is written on stdout.\n");
+ exit (1);
+ }
+
+ if (argc == 7) {
+ ax = strtoul (argv[3], NULL, 0);
+ ay = strtoul (argv[4], NULL, 0);
+ bx = strtoul (argv[5], NULL, 0);
+ by = strtoul (argv[6], NULL, 0);
+ } else {
+ ax = ay = bx = by = 0;
+ }
+
+ status = png_diff (argv[1], argv[2], NULL, ax, ay, bx, by, &result);
+
+ if (status) {
+ fprintf (stderr, "Error comparing images: %s\n",
+ cairo_status_to_string (status));
+ return 1;
+ }
+
+ if (result.pixels_changed)
+ fprintf (stderr, "Total pixels changed: %d with a maximum channel difference of %d.\n",
+ result.pixels_changed,
+ result.max_diff);
+
+ return (result.pixels_changed != 0);
+}
diff --git a/test/implicit-close.c b/test/implicit-close.c
new file mode 100644
index 000000000..2529bb00f
--- /dev/null
+++ b/test/implicit-close.c
@@ -0,0 +1,54 @@
+/*
+ * Copyright © 2009 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Chris Wilson not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Chris Wilson makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+#define SIZE 40
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+ cairo_move_to (cr, SIZE, 0);
+ cairo_rel_line_to (cr, 0, SIZE);
+ cairo_rel_line_to (cr, -SIZE, 0);
+
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ cairo_fill_preserve (cr);
+
+ cairo_set_source_rgb (cr, 1, 0, 0);
+ cairo_stroke (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (implicit_close,
+ "Test implicitly closing paths",
+ "fill", /* keywords */
+ NULL, /* requirements */
+ SIZE, SIZE,
+ NULL, draw)
diff --git a/test/in-fill-empty-trapezoid.c b/test/in-fill-empty-trapezoid.c
new file mode 100644
index 000000000..0797399c5
--- /dev/null
+++ b/test/in-fill-empty-trapezoid.c
@@ -0,0 +1,109 @@
+/*
+ * Copyright © 2006 M Joonas Pihlaja
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: M Joonas Pihlaja <jpihlaja@cc.helsinki.fi>
+ */
+
+/* Bug history
+ *
+ * 2006-12-05 M Joonas Pihlaja <jpihlaja@cc.helsinki.fi>
+ *
+ * The cairo_in_fill () function can sometimes produce false
+ * positives when the tessellator produces empty trapezoids
+ * and the query point lands exactly on a trapezoid edge.
+ */
+
+#include "cairo-test.h"
+
+static cairo_test_status_t
+preamble (cairo_test_context_t *ctx)
+{
+ int x,y;
+ int width = 10;
+ int height = 10;
+ cairo_surface_t *surf;
+ cairo_t *cr;
+ int false_positive_count = 0;
+ cairo_status_t status;
+ cairo_test_status_t ret;
+
+ surf = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
+ cr = cairo_create (surf);
+ cairo_surface_destroy (surf);
+
+ /* Empty horizontal trapezoid. */
+ cairo_move_to (cr, 0, height/3);
+ cairo_line_to (cr, width, height/3);
+ cairo_close_path (cr);
+
+ /* Empty non-horizontal trapezoid #1. */
+ cairo_move_to (cr, 0, 0);
+ cairo_line_to (cr, width, height/2);
+ cairo_close_path (cr);
+
+ /* Empty non-horizontal trapezoid #2 intersecting #1. */
+ cairo_move_to (cr, 0, height/2);
+ cairo_line_to (cr, width, 0);
+ cairo_close_path (cr);
+
+ status = cairo_status (cr);
+
+ /* Point sample the tessellated path. */
+ for (y = 0; y < height; y++) {
+ for (x = 0; x < width; x++) {
+ if (cairo_in_fill (cr, x, y)) {
+ false_positive_count++;
+ }
+ }
+ }
+ cairo_destroy (cr);
+
+ /* Check that everything went well. */
+ ret = CAIRO_TEST_SUCCESS;
+ if (CAIRO_STATUS_SUCCESS != status) {
+ cairo_test_log (ctx, "Failed to create a test surface and path: %s\n",
+ cairo_status_to_string (status));
+ ret = CAIRO_TEST_XFAILURE;
+ }
+
+ if (0 != false_positive_count) {
+ cairo_test_log (ctx, "Point sampling found %d false positives "
+ "from cairo_in_fill()\n",
+ false_positive_count);
+ ret = CAIRO_TEST_XFAILURE;
+ }
+
+ return ret;
+}
+
+/*
+ * XFAIL: The cairo_in_fill () function can sometimes produce false positives
+ * when the tessellator produces empty trapezoids and the query point lands
+ * exactly on a trapezoid edge.
+ */
+CAIRO_TEST (in_fill_empty_trapezoid,
+ "Test that the tessellator isn't producing obviously empty trapezoids",
+ "in, trap", /* keywords */
+ NULL, /* requirements */
+ 0, 0,
+ preamble, NULL)
diff --git a/test/in-fill-trapezoid.c b/test/in-fill-trapezoid.c
new file mode 100644
index 000000000..84b323a05
--- /dev/null
+++ b/test/in-fill-trapezoid.c
@@ -0,0 +1,279 @@
+/*
+ * Copyright © 2008 Chris Wilson
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+static cairo_test_status_t
+preamble (cairo_test_context_t *ctx)
+{
+ cairo_test_status_t ret = CAIRO_TEST_SUCCESS;
+ cairo_surface_t *surface;
+ cairo_t *cr;
+
+ surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 0, 0);
+ cr = cairo_create (surface);
+ cairo_surface_destroy (surface);
+
+ cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
+
+ /* simple rectangle */
+ cairo_new_path (cr);
+ cairo_rectangle (cr, -10, -10, 20, 20);
+ if (! cairo_in_fill (cr, 0, 0)) {
+ cairo_test_log (ctx, "Error: Failed to find point inside rectangle\n");
+ ret = CAIRO_TEST_FAILURE;
+ }
+
+ /* rectangular boundary tests */
+ if (! cairo_in_fill (cr, -10, -10)) {
+ cairo_test_log (ctx, "Error: Failed to find top-left vertex inside rectangle\n");
+ ret = CAIRO_TEST_FAILURE;
+ }
+ if (! cairo_in_fill (cr, -10, 10)) {
+ cairo_test_log (ctx, "Error: Failed to find bottom-left vertex inside rectangle\n");
+ ret = CAIRO_TEST_FAILURE;
+ }
+ if (! cairo_in_fill (cr, 10, -10)) {
+ cairo_test_log (ctx, "Error: Failed to find top-right vertex inside rectangle\n");
+ ret = CAIRO_TEST_FAILURE;
+ }
+ if (! cairo_in_fill (cr, 10, 10)) {
+ cairo_test_log (ctx, "Error: Failed to find bottom-right vertex inside rectangle\n");
+ ret = CAIRO_TEST_FAILURE;
+ }
+ if (! cairo_in_fill (cr, -10, 0)) {
+ cairo_test_log (ctx, "Error: Failed to find left edge inside rectangle\n");
+ ret = CAIRO_TEST_FAILURE;
+ }
+ if (! cairo_in_fill (cr, 0, -10)) {
+ cairo_test_log (ctx, "Error: Failed to find top edge inside rectangle\n");
+ ret = CAIRO_TEST_FAILURE;
+ }
+ if (! cairo_in_fill (cr, 10, 0)) {
+ cairo_test_log (ctx, "Error: Failed to find right edge inside rectangle\n");
+ ret = CAIRO_TEST_FAILURE;
+ }
+ if (! cairo_in_fill (cr, 0, 10)) {
+ cairo_test_log (ctx, "Error: Failed to find bottom edge inside rectangle\n");
+ ret = CAIRO_TEST_FAILURE;
+ }
+
+ /* simple circle */
+ cairo_new_path (cr);
+ cairo_arc (cr, 0, 0, 10, 0, 2 * M_PI);
+ if (! cairo_in_fill (cr, 0, 0)) {
+ cairo_test_log (ctx, "Error: Failed to find point inside circle [even-odd]\n");
+ ret = CAIRO_TEST_FAILURE;
+ }
+
+ /* holey rectangle */
+ cairo_new_path (cr);
+ cairo_rectangle (cr, -10, -10, 20, 20);
+ cairo_rectangle (cr, -5, -5, 10, 10);
+ if (cairo_in_fill (cr, 0, 0)) {
+ cairo_test_log (ctx, "Error: Found an unexpected point inside rectangular eo-hole\n");
+ ret = CAIRO_TEST_FAILURE;
+ }
+
+ /* holey circle */
+ cairo_new_path (cr);
+ cairo_arc (cr, 0, 0, 10, 0, 2 * M_PI);
+ cairo_arc (cr, 0, 0, 5, 0, 2 * M_PI);
+ if (cairo_in_fill (cr, 0, 0)) {
+ cairo_test_log (ctx, "Error: Found an unexpected point inside circular eo-hole\n");
+ ret = CAIRO_TEST_FAILURE;
+ }
+
+
+ cairo_set_fill_rule (cr, CAIRO_FILL_RULE_WINDING);
+
+ /* simple rectangle */
+ cairo_new_path (cr);
+ cairo_rectangle (cr, -10, -10, 20, 20);
+ if (! cairo_in_fill (cr, 0, 0)) {
+ cairo_test_log (ctx, "Error: Failed to find point inside rectangle\n");
+ ret = CAIRO_TEST_FAILURE;
+ }
+
+ /* simple circle */
+ cairo_new_path (cr);
+ cairo_arc (cr, 0, 0, 10, 0, 2 * M_PI);
+ if (! cairo_in_fill (cr, 0, 0)) {
+ cairo_test_log (ctx, "Error: Failed to find point inside circle [nonzero]\n");
+ ret = CAIRO_TEST_FAILURE;
+ }
+
+ /* overlapping circle/rectangle */
+ cairo_new_path (cr);
+ cairo_rectangle (cr, -10, -10, 20, 20);
+ cairo_new_sub_path (cr);
+ cairo_arc (cr, 0, 0, 10, 0, 2 * M_PI);
+ if (! cairo_in_fill (cr, 0, 0)) {
+ cairo_test_log (ctx, "Error: Failed to find point inside circle+rectangle\n");
+ ret = CAIRO_TEST_FAILURE;
+ }
+
+ /* holey rectangle */
+ cairo_new_path (cr);
+ cairo_rectangle (cr, -10, -10, 20, 20);
+ cairo_rectangle (cr, 5, -5, -10, 10);
+ if (cairo_in_fill (cr, 0, 0)) {
+ cairo_test_log (ctx, "Error: Found an unexpected point inside rectangular non-zero-hole\n");
+ ret = CAIRO_TEST_FAILURE;
+ }
+
+ /* holey circle */
+ cairo_new_path (cr);
+ cairo_arc (cr, 0, 0, 10, 0, 2 * M_PI);
+ cairo_arc_negative (cr, 0, 0, 5, 0, -2 * M_PI);
+ if (cairo_in_fill (cr, 0, 0)) {
+ cairo_test_log (ctx, "Error: Found an unexpected point inside circular non-zero-hole\n");
+ ret = CAIRO_TEST_FAILURE;
+ }
+
+ /* not a holey circle */
+ cairo_new_path (cr);
+ cairo_arc (cr, 0, 0, 10, 0, 2 * M_PI);
+ cairo_arc (cr, 0, 0, 5, 0, 2 * M_PI);
+ if (! cairo_in_fill (cr, 0, 0)) {
+ cairo_test_log (ctx, "Error: Failed to find point inside two circles\n");
+ ret = CAIRO_TEST_FAILURE;
+ }
+
+ /* check off-centre */
+ cairo_new_path (cr);
+ cairo_arc (cr, 7.5, 0, 10, 0, 2 * M_PI);
+ cairo_arc_negative (cr, 7.5, 0, 5, 0, -2 * M_PI);
+ if (cairo_in_fill (cr, 7.5, 0)) {
+ cairo_test_log (ctx, "Error: Found an unexpected point inside off-centre-x circular non-zero-hole\n");
+ ret = CAIRO_TEST_FAILURE;
+ }
+ cairo_new_path (cr);
+ cairo_arc (cr, 0, 7.5, 10, 0, 2 * M_PI);
+ cairo_arc_negative (cr, 0, 7.5, 5, 0, -2 * M_PI);
+ if (cairo_in_fill (cr, 0, 7.5)) {
+ cairo_test_log (ctx, "Error: Found an unexpected point inside off-centre-y circular non-zero-hole\n");
+ ret = CAIRO_TEST_FAILURE;
+ }
+ cairo_new_path (cr);
+ cairo_arc (cr, 15, 0, 10, 0, 2 * M_PI);
+ if (! cairo_in_fill (cr, 15, 0)) {
+ cairo_test_log (ctx, "Error: Failed to find point inside off-centre-x circle\n");
+ ret = CAIRO_TEST_FAILURE;
+ }
+ cairo_new_path (cr);
+ cairo_arc (cr, 0, 15, 10, 0, 2 * M_PI);
+ if (! cairo_in_fill (cr, 0, 15)) {
+ cairo_test_log (ctx, "Error: Failed to find point inside off-centre-y circle\n");
+ ret = CAIRO_TEST_FAILURE;
+ }
+
+ /* simple rectangle */
+ cairo_new_path (cr);
+ cairo_rectangle (cr, 10, 0, 5, 5);
+ if (cairo_in_fill (cr, 0, 0)) {
+ cairo_test_log (ctx, "Error: Found an unexpected point outside rectangle\n");
+ ret = CAIRO_TEST_FAILURE;
+ }
+ if (cairo_in_fill (cr, 20, 20)) {
+ cairo_test_log (ctx, "Error: Found an unexpected point outside rectangle\n");
+ ret = CAIRO_TEST_FAILURE;
+ }
+ if (! cairo_in_fill (cr, 12.5, 2.5)) {
+ cairo_test_log (ctx, "Error: Failed to find point inside rectangle\n");
+ ret = CAIRO_TEST_FAILURE;
+ }
+
+ /* off-centre triangle */
+ cairo_new_path (cr);
+ cairo_move_to (cr, 10, 0);
+ cairo_line_to (cr, 15, 5);
+ cairo_line_to (cr, 5, 5);
+ cairo_close_path (cr);
+ if (cairo_in_fill (cr, 0, 0) ||
+ cairo_in_fill (cr, 5, 0) ||
+ cairo_in_fill (cr, 15, 0) ||
+ cairo_in_fill (cr, 20, 0) ||
+ cairo_in_fill (cr, 0, 10) ||
+ cairo_in_fill (cr, 10, 10) ||
+ cairo_in_fill (cr, 20, 10) ||
+ cairo_in_fill (cr, 7, 2.5) ||
+ cairo_in_fill (cr, 13, 2.5))
+ {
+ cairo_test_log (ctx,
+ "Error: Found an unexpected point outside triangle\n"
+ "\t(0, 0) -> %s\n"
+ "\t(5, 0) -> %s\n"
+ "\t(15, 0) -> %s\n"
+ "\t(20, 0) -> %s\n"
+ "\t(0, 10) -> %s\n"
+ "\t(10, 10) -> %s\n"
+ "\t(20, 10) -> %s\n"
+ "\t(7, 2.5) -> %s\n"
+ "\t(13, 2.5) -> %s\n",
+ cairo_in_fill (cr, 0, 0) ? "inside" : "outside",
+ cairo_in_fill (cr, 5, 0) ? "inside" : "outside",
+ cairo_in_fill (cr, 15, 0) ? "inside" : "outside",
+ cairo_in_fill (cr, 20, 0) ? "inside" : "outside",
+ cairo_in_fill (cr, 0, 10) ? "inside" : "outside",
+ cairo_in_fill (cr, 10, 10) ? "inside" : "outside",
+ cairo_in_fill (cr, 20, 10) ? "inside" : "outside",
+ cairo_in_fill (cr, 7, 2.5) ? "inside" : "outside",
+ cairo_in_fill (cr, 13, 2.5) ? "inside" : "outside");
+ ret = CAIRO_TEST_FAILURE;
+ }
+ if (! cairo_in_fill (cr, 7.5, 2.5) ||
+ ! cairo_in_fill (cr, 12.5, 2.5) ||
+ ! cairo_in_fill (cr, 10, 5))
+ {
+ cairo_test_log (ctx,
+ "Error: Failed to find point on triangle edge\n"
+ "\t(7.5, 2.5) -> %s\n"
+ "\t(12.5, 2.5) -> %s\n"
+ "\t(10, 5) -> %s\n",
+ cairo_in_fill (cr, 7.5, 2.5) ? "inside" : "outside",
+ cairo_in_fill (cr, 12.5, 2.5) ? "inside" : "outside",
+ cairo_in_fill (cr, 10, 5) ? "inside" : "outside");
+ ret = CAIRO_TEST_FAILURE;
+ }
+ if (! cairo_in_fill (cr, 8, 2.5) ||
+ ! cairo_in_fill (cr, 12, 2.5))
+ {
+ cairo_test_log (ctx, "Error: Failed to find point inside triangle\n");
+ ret = CAIRO_TEST_FAILURE;
+ }
+
+ cairo_destroy (cr);
+
+ return ret;
+}
+
+CAIRO_TEST (in_fill_trapezoid,
+ "Test cairo_in_fill",
+ "in, trap", /* keywords */
+ NULL, /* requirements */
+ 0, 0,
+ preamble, NULL)
diff --git a/test/index.html b/test/index.html
new file mode 100644
index 000000000..54c65cdc1
--- /dev/null
+++ b/test/index.html
@@ -0,0 +1,42 @@
+<html><head>
+<title>Cairo Test Results</title>
+<style type="text/css">
+#HcolHeader { text-align: center; }
+
+img { max-width: 15em; min-width: 3em; min-height: 3em; margin: 3px; }
+a img { border: solid 1px #FFF; }
+
+td { vertical-align: top; }
+span { cursor: pointer; }
+
+td.PASS { background-color: #0B0; min-width: 1em; }
+span.PASS { color: #0B0; }
+
+td.NEW { background-color: #B70; }
+span.NEW { color: #B70; }
+
+td.FAIL { background-color: #B00; }
+span.FAIL { color: #D00; }
+
+td.XFAIL { background-color: #BB0; }
+span.XFAIL { color: #BB0; }
+
+td.UNTESTED { background-color: #555; }
+span.UNTESTED { color: #555; }
+
+td.CRASHED { background-color: #F00; color: #FF0; }
+span.CRASHED { color: #F00; }
+
+.test { }
+.target { }
+.format { }
+.offset { }
+.similar { }
+
+</style>
+<script language="JavaScript" src="testtable.js"></script>
+</head>
+<body oncontextmenu='ignoreEvent (event)' onmouseup='noDrag (event)'>
+<table id="testTable" border="1"></table>
+</body>
+</html>
diff --git a/test/infinite-join.c b/test/infinite-join.c
new file mode 100644
index 000000000..a573f56a5
--- /dev/null
+++ b/test/infinite-join.c
@@ -0,0 +1,72 @@
+/*
+ * Copyright © 2006 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of the
+ * copyright holders not be used in advertising or publicity
+ * pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied
+ * warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+/* Test case for bug #8379:
+ *
+ * infinite loop when stroking
+ * https://bugs.freedesktop.org/show_bug.cgi?id=8379
+ */
+
+#include "cairo-test.h"
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ /* Paint white, then draw in black. */
+ cairo_set_source_rgb (cr, 1, 1, 1); /* white */
+ cairo_paint (cr);
+ cairo_set_source_rgb (cr, 0, 0, 0); /* black */
+
+ cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND);
+
+ /* scaling 2 times causes a slight rounding error in the ctm.
+ * Without that, the bug doesn't happen. */
+ cairo_scale (cr, 20 / 100., 20 / 100.);
+ cairo_scale (cr, 1. / 20, 1. / 20);
+
+ cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND);
+ cairo_set_line_width (cr, 20);
+
+ cairo_translate (cr, -18300, -13200);
+
+ cairo_new_path (cr);
+ cairo_move_to (cr, 18928, 13843);
+ cairo_line_to (cr, 18500, 13843);
+ cairo_line_to (cr, 18500, 13400);
+ cairo_line_to (cr, 18928, 13400);
+ cairo_line_to (cr, 18928, 13843);
+ cairo_stroke (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (infinite_join,
+ "Test case for infinite loop when stroking with round joins",
+ "stroke", /* keywords */
+ NULL,
+ 8, 8,
+ NULL, draw)
diff --git a/test/invalid-matrix.c b/test/invalid-matrix.c
new file mode 100644
index 000000000..9bb26be0b
--- /dev/null
+++ b/test/invalid-matrix.c
@@ -0,0 +1,374 @@
+/*
+ * Copyright © 2007 Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Carl Worth <cworth@cworth.org>
+ */
+
+#define _ISOC99_SOURCE /* for INFINITY */
+#define _GNU_SOURCE 1 /* for fedisableeexcept() et al */
+
+#include "cairo-test.h"
+
+#if !defined(INFINITY)
+#define INFINITY HUGE_VAL
+#endif
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ const cairo_test_context_t *ctx = cairo_test_get_context (cr);
+ cairo_status_t status;
+ cairo_surface_t *target;
+ cairo_font_face_t *font_face;
+ cairo_font_options_t *font_options;
+ cairo_scaled_font_t *scaled_font;
+ cairo_pattern_t *pattern;
+ cairo_t *cr2;
+ cairo_matrix_t identity, bogus, inf, invalid = {
+ 4.0, 4.0,
+ 4.0, 4.0,
+ 4.0, 4.0
+ };
+
+#define CHECK_STATUS(status, function_name) \
+if ((status) == CAIRO_STATUS_SUCCESS) { \
+ cairo_test_log (ctx, "Error: %s with invalid matrix passed\n", \
+ (function_name)); \
+ return CAIRO_TEST_FAILURE; \
+} else if ((status) != CAIRO_STATUS_INVALID_MATRIX) { \
+ cairo_test_log (ctx, "Error: %s with invalid matrix returned unexpected status " \
+ "(%d): %s\n", \
+ (function_name), \
+ status, \
+ cairo_status_to_string (status)); \
+ return CAIRO_TEST_FAILURE; \
+}
+
+ /* clear floating point exceptions (added by cairo_test_init()) */
+#if HAVE_FEDISABLEEXCEPT
+ fedisableexcept (FE_INVALID);
+#endif
+
+ /* create a bogus matrix and check results of attempted inversion */
+ bogus.x0 = bogus.xy = bogus.xx = cairo_test_NaN ();
+ bogus.y0 = bogus.yx = bogus.yy = bogus.xx;
+ status = cairo_matrix_invert (&bogus);
+ CHECK_STATUS (status, "cairo_matrix_invert(NaN)");
+
+ inf.x0 = inf.xy = inf.xx = INFINITY;
+ inf.y0 = inf.yx = inf.yy = inf.xx;
+ status = cairo_matrix_invert (&inf);
+ CHECK_STATUS (status, "cairo_matrix_invert(infinity)");
+
+ /* test cairo_matrix_invert with invalid matrix */
+ status = cairo_matrix_invert (&invalid);
+ CHECK_STATUS (status, "cairo_matrix_invert(invalid)");
+
+
+ cairo_matrix_init_identity (&identity);
+
+ target = cairo_get_group_target (cr);
+
+ /* test cairo_transform with invalid matrix */
+ cr2 = cairo_create (target);
+ cairo_transform (cr2, &invalid);
+
+ status = cairo_status (cr2);
+ cairo_destroy (cr2);
+ CHECK_STATUS (status, "cairo_transform(invalid)");
+
+ /* test cairo_transform with bogus matrix */
+ cr2 = cairo_create (target);
+ cairo_transform (cr2, &bogus);
+
+ status = cairo_status (cr2);
+ cairo_destroy (cr2);
+ CHECK_STATUS (status, "cairo_transform(NaN)");
+
+ /* test cairo_transform with ∞ matrix */
+ cr2 = cairo_create (target);
+ cairo_transform (cr2, &inf);
+
+ status = cairo_status (cr2);
+ cairo_destroy (cr2);
+ CHECK_STATUS (status, "cairo_transform(infinity)");
+
+
+ /* test cairo_set_matrix with invalid matrix */
+ cr2 = cairo_create (target);
+ cairo_set_matrix (cr2, &invalid);
+
+ status = cairo_status (cr2);
+ cairo_destroy (cr2);
+ CHECK_STATUS (status, "cairo_set_matrix(invalid)");
+
+ /* test cairo_set_matrix with bogus matrix */
+ cr2 = cairo_create (target);
+ cairo_set_matrix (cr2, &bogus);
+
+ status = cairo_status (cr2);
+ cairo_destroy (cr2);
+ CHECK_STATUS (status, "cairo_set_matrix(NaN)");
+
+ /* test cairo_set_matrix with ∞ matrix */
+ cr2 = cairo_create (target);
+ cairo_set_matrix (cr2, &inf);
+
+ status = cairo_status (cr2);
+ cairo_destroy (cr2);
+ CHECK_STATUS (status, "cairo_set_matrix(infinity)");
+
+
+ /* test cairo_set_font_matrix with invalid matrix */
+ cr2 = cairo_create (target);
+ cairo_set_font_matrix (cr2, &invalid);
+
+ /* draw some text to force the font to be resolved */
+ cairo_show_text (cr2, "hello");
+
+ status = cairo_status (cr2);
+ cairo_destroy (cr2);
+ CHECK_STATUS (status, "cairo_set_font_matrix(invalid)");
+
+ /* test cairo_set_font_matrix with bogus matrix */
+ cr2 = cairo_create (target);
+ cairo_set_font_matrix (cr2, &bogus);
+
+ /* draw some text to force the font to be resolved */
+ cairo_show_text (cr2, "hello");
+
+ status = cairo_status (cr2);
+ cairo_destroy (cr2);
+ CHECK_STATUS (status, "cairo_set_font_matrix(NaN)");
+
+ /* test cairo_set_font_matrix with ∞ matrix */
+ cr2 = cairo_create (target);
+ cairo_set_font_matrix (cr2, &inf);
+
+ /* draw some text to force the font to be resolved */
+ cairo_show_text (cr2, "hello");
+
+ status = cairo_status (cr2);
+ cairo_destroy (cr2);
+ CHECK_STATUS (status, "cairo_set_font_matrix(infinity)");
+
+
+ /* test cairo_scaled_font_create with invalid matrix */
+ cr2 = cairo_create (target);
+ font_face = cairo_get_font_face (cr2);
+ font_options = cairo_font_options_create ();
+ cairo_get_font_options (cr, font_options);
+ scaled_font = cairo_scaled_font_create (font_face,
+ &invalid,
+ &identity,
+ font_options);
+ status = cairo_scaled_font_status (scaled_font);
+ CHECK_STATUS (status, "cairo_scaled_font_create(invalid)");
+
+ cairo_scaled_font_destroy (scaled_font);
+
+ scaled_font = cairo_scaled_font_create (font_face,
+ &identity,
+ &invalid,
+ font_options);
+ status = cairo_scaled_font_status (scaled_font);
+ CHECK_STATUS (status, "cairo_scaled_font_create(invalid)");
+
+ cairo_scaled_font_destroy (scaled_font);
+ cairo_font_options_destroy (font_options);
+ cairo_destroy (cr2);
+
+ /* test cairo_scaled_font_create with bogus matrix */
+ cr2 = cairo_create (target);
+ font_face = cairo_get_font_face (cr2);
+ font_options = cairo_font_options_create ();
+ cairo_get_font_options (cr, font_options);
+ scaled_font = cairo_scaled_font_create (font_face,
+ &bogus,
+ &identity,
+ font_options);
+ status = cairo_scaled_font_status (scaled_font);
+ CHECK_STATUS (status, "cairo_scaled_font_create(NaN)");
+
+ cairo_scaled_font_destroy (scaled_font);
+
+ scaled_font = cairo_scaled_font_create (font_face,
+ &identity,
+ &bogus,
+ font_options);
+ status = cairo_scaled_font_status (scaled_font);
+ CHECK_STATUS (status, "cairo_scaled_font_create(NaN)");
+
+ cairo_scaled_font_destroy (scaled_font);
+ cairo_font_options_destroy (font_options);
+ cairo_destroy (cr2);
+
+ /* test cairo_scaled_font_create with ∞ matrix */
+ cr2 = cairo_create (target);
+ font_face = cairo_get_font_face (cr2);
+ font_options = cairo_font_options_create ();
+ cairo_get_font_options (cr, font_options);
+ scaled_font = cairo_scaled_font_create (font_face,
+ &inf,
+ &identity,
+ font_options);
+ status = cairo_scaled_font_status (scaled_font);
+ CHECK_STATUS (status, "cairo_scaled_font_create(infinity)");
+
+ cairo_scaled_font_destroy (scaled_font);
+
+ scaled_font = cairo_scaled_font_create (font_face,
+ &identity,
+ &inf,
+ font_options);
+ status = cairo_scaled_font_status (scaled_font);
+ CHECK_STATUS (status, "cairo_scaled_font_create(infinity)");
+
+ cairo_scaled_font_destroy (scaled_font);
+ cairo_font_options_destroy (font_options);
+ cairo_destroy (cr2);
+
+
+ /* test cairo_pattern_set_matrix with invalid matrix */
+ pattern = cairo_pattern_create_rgb (1.0, 1.0, 1.0);
+ cairo_pattern_set_matrix (pattern, &invalid);
+ status = cairo_pattern_status (pattern);
+ CHECK_STATUS (status, "cairo_pattern_set_matrix(invalid)");
+ cairo_pattern_destroy (pattern);
+
+ /* test cairo_pattern_set_matrix with bogus matrix */
+ pattern = cairo_pattern_create_rgb (1.0, 1.0, 1.0);
+ cairo_pattern_set_matrix (pattern, &bogus);
+ status = cairo_pattern_status (pattern);
+ CHECK_STATUS (status, "cairo_pattern_set_matrix(NaN)");
+ cairo_pattern_destroy (pattern);
+
+ /* test cairo_pattern_set_matrix with ∞ matrix */
+ pattern = cairo_pattern_create_rgb (1.0, 1.0, 1.0);
+ cairo_pattern_set_matrix (pattern, &inf);
+ status = cairo_pattern_status (pattern);
+ CHECK_STATUS (status, "cairo_pattern_set_matrix(infinity)");
+ cairo_pattern_destroy (pattern);
+
+
+ /* test invalid transformations */
+ cr2 = cairo_create (target);
+ cairo_translate (cr2, bogus.xx, bogus.yy);
+ CHECK_STATUS (status, "cairo_translate(NaN, NaN)");
+ cairo_destroy (cr2);
+
+ cr2 = cairo_create (target);
+ cairo_translate (cr2, 0, bogus.yy);
+ CHECK_STATUS (status, "cairo_translate(0, NaN)");
+ cairo_destroy (cr2);
+
+ cr2 = cairo_create (target);
+ cairo_translate (cr2, bogus.xx, 0);
+ CHECK_STATUS (status, "cairo_translate(NaN, 0)");
+ cairo_destroy (cr2);
+
+ cr2 = cairo_create (target);
+ cairo_translate (cr2, inf.xx, inf.yy);
+ CHECK_STATUS (status, "cairo_translate(∞, ∞)");
+ cairo_destroy (cr2);
+
+ cr2 = cairo_create (target);
+ cairo_translate (cr2, 0, inf.yy);
+ CHECK_STATUS (status, "cairo_translate(0, ∞)");
+ cairo_destroy (cr2);
+
+ cr2 = cairo_create (target);
+ cairo_translate (cr2, inf.xx, 0);
+ CHECK_STATUS (status, "cairo_translate(∞, 0)");
+ cairo_destroy (cr2);
+
+
+ cr2 = cairo_create (target);
+ cairo_scale (cr2, bogus.xx, bogus.yy);
+ CHECK_STATUS (status, "cairo_scale(NaN, NaN)");
+ cairo_destroy (cr2);
+
+ cr2 = cairo_create (target);
+ cairo_scale (cr2, 1, bogus.yy);
+ CHECK_STATUS (status, "cairo_scale(1, NaN)");
+ cairo_destroy (cr2);
+
+ cr2 = cairo_create (target);
+ cairo_scale (cr2, bogus.xx, 1);
+ CHECK_STATUS (status, "cairo_scale(NaN, 1)");
+ cairo_destroy (cr2);
+
+ cr2 = cairo_create (target);
+ cairo_scale (cr2, inf.xx, inf.yy);
+ CHECK_STATUS (status, "cairo_scale(∞, ∞)");
+ cairo_destroy (cr2);
+
+ cr2 = cairo_create (target);
+ cairo_scale (cr2, 1, inf.yy);
+ CHECK_STATUS (status, "cairo_scale(1, ∞)");
+ cairo_destroy (cr2);
+
+ cr2 = cairo_create (target);
+ cairo_scale (cr2, inf.xx, 1);
+ CHECK_STATUS (status, "cairo_scale(∞, 1)");
+ cairo_destroy (cr2);
+
+ cr2 = cairo_create (target);
+ cairo_scale (cr2, bogus.xx, bogus.yy);
+ CHECK_STATUS (status, "cairo_scale(0, 0)");
+ cairo_destroy (cr2);
+
+ cr2 = cairo_create (target);
+ cairo_scale (cr2, 1, bogus.yy);
+ CHECK_STATUS (status, "cairo_scale(1, 0)");
+ cairo_destroy (cr2);
+
+ cr2 = cairo_create (target);
+ cairo_scale (cr2, bogus.xx, 1);
+ CHECK_STATUS (status, "cairo_scale(0, 1)");
+ cairo_destroy (cr2);
+
+
+ cr2 = cairo_create (target);
+ cairo_rotate (cr2, bogus.xx);
+ CHECK_STATUS (status, "cairo_rotate(NaN)");
+ cairo_destroy (cr2);
+
+ cr2 = cairo_create (target);
+ cairo_rotate (cr2, inf.xx);
+ CHECK_STATUS (status, "cairo_rotate(∞)");
+ cairo_destroy (cr2);
+
+#if HAVE_FECLEAREXCEPT
+ feclearexcept (FE_INVALID);
+#endif
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (invalid_matrix,
+ "Test that all relevant public functions return CAIRO_STATUS_INVALID_MATRIX as appropriate",
+ "api, matrix", /* keywords */
+ NULL, /* requirements */
+ 0, 0,
+ NULL, draw)
diff --git a/test/inverse-text.c b/test/inverse-text.c
new file mode 100644
index 000000000..c8d7aea62
--- /dev/null
+++ b/test/inverse-text.c
@@ -0,0 +1,67 @@
+/*
+ * Copyright © 2006 Red Hat, Inc.
+ * Copyright © 2010 Intel Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ * Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+#define TEXT_SIZE 12
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ /* This is just the inverse of select-font-face.c */
+ cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
+ cairo_paint (cr);
+
+ cairo_set_source_rgb (cr, 1, 1, 1);
+
+ cairo_set_font_size (cr, TEXT_SIZE);
+ cairo_move_to (cr, 0, TEXT_SIZE);
+
+ cairo_select_font_face (cr, CAIRO_TEST_FONT_FAMILY " Serif",
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_NORMAL);
+ cairo_show_text (cr, "i-am-serif");
+
+ cairo_select_font_face (cr, CAIRO_TEST_FONT_FAMILY " Sans",
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_NORMAL);
+ cairo_show_text (cr, " i-am-sans");
+
+ cairo_select_font_face (cr, CAIRO_TEST_FONT_FAMILY " Sans Mono",
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_NORMAL);
+ cairo_show_text (cr, " i-am-mono");
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (inverse_text,
+ "Tests rendering of inverse text (white-on-black)",
+ "font, text", /* keywords */
+ NULL, /* requirements */
+ 192, TEXT_SIZE + 4,
+ NULL, draw)
diff --git a/test/inverted-clip.c b/test/inverted-clip.c
new file mode 100644
index 000000000..b05dd6b6b
--- /dev/null
+++ b/test/inverted-clip.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+/* An assertion failure found by Rico Tzschichholz */
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
+ cairo_set_source_rgb (cr, 0, 1, 0);
+
+ cairo_arc (cr, 50, 50, 40, 0, 2 * M_PI);
+ cairo_clip_preserve (cr);
+
+ cairo_paint (cr);
+
+ cairo_rectangle (cr, 0, 0, 100, 100);
+ cairo_reset_clip (cr);
+ cairo_clip (cr);
+
+ cairo_paint (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (inverted_clip,
+ "Clip + InvertedClip should be opaque",
+ "clip, paint", /* keywords */
+ "target=raster", /* requirements */
+ 100, 100,
+ NULL, draw)
diff --git a/test/joins-loop.c b/test/joins-loop.c
new file mode 100644
index 000000000..f0b7bc11d
--- /dev/null
+++ b/test/joins-loop.c
@@ -0,0 +1,100 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+#define LINE_WIDTH 10.
+#define SIZE (8 * LINE_WIDTH)
+#define PAD (1 * LINE_WIDTH)
+
+
+static void
+make_path (cairo_t *cr)
+{
+ cairo_move_to (cr, 0, 0);
+ cairo_rel_curve_to (cr,
+ SIZE, 0,
+ 0, SIZE,
+ SIZE, SIZE);
+ cairo_rel_line_to (cr, -SIZE, 0);
+ cairo_rel_curve_to (cr,
+ SIZE, 0,
+ 0, -SIZE,
+ SIZE, -SIZE);
+ cairo_close_path (cr);
+}
+
+static void
+draw_joins (cairo_t *cr)
+{
+ cairo_save (cr);
+ cairo_translate (cr, PAD, PAD);
+
+ make_path (cr);
+ cairo_set_line_join (cr, CAIRO_LINE_JOIN_BEVEL);
+ cairo_stroke (cr);
+ cairo_translate (cr, SIZE + PAD, 0.);
+
+ make_path (cr);
+ cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND);
+ cairo_stroke (cr);
+ cairo_translate (cr, SIZE + PAD, 0.);
+
+ make_path (cr);
+ cairo_set_line_join (cr, CAIRO_LINE_JOIN_MITER);
+ cairo_stroke (cr);
+ cairo_translate (cr, SIZE + PAD, 0.);
+
+ cairo_restore (cr);
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
+ cairo_paint (cr);
+
+ cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
+ cairo_set_line_width (cr, LINE_WIDTH);
+
+ draw_joins (cr);
+
+ /* and reflect to generate the opposite vertex ordering */
+ cairo_translate (cr, 0, height);
+ cairo_scale (cr, 1, -1);
+
+ draw_joins (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (joins_loop,
+ "A loopy concave shape",
+ "stroke", /* keywords */
+ NULL, /* requirements */
+ 3*(SIZE+PAD)+PAD, 2*(SIZE+PAD)+2*PAD,
+ NULL, draw)
+
diff --git a/test/joins-retrace.c b/test/joins-retrace.c
new file mode 100644
index 000000000..9a2cf708b
--- /dev/null
+++ b/test/joins-retrace.c
@@ -0,0 +1,109 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+#define LINE_WIDTH 10.
+#define SIZE (8 * LINE_WIDTH)
+#define PAD (1 * LINE_WIDTH)
+
+
+static void
+make_path (cairo_t *cr)
+{
+ cairo_move_to (cr, 0, SIZE/2 + LINE_WIDTH);
+ cairo_rel_line_to (cr, SIZE, 0);
+ cairo_rel_line_to (cr, -SIZE, 0);
+ cairo_close_path (cr);
+
+ cairo_move_to (cr, 3*SIZE/4, 0);
+ cairo_rel_line_to (cr, -SIZE/2, SIZE);
+ cairo_rel_line_to (cr, SIZE/2, -SIZE);
+ cairo_close_path (cr);
+
+ cairo_move_to (cr, 0, SIZE/2-LINE_WIDTH);
+ cairo_rel_curve_to (cr,
+ SIZE/2, -2*LINE_WIDTH,
+ SIZE/2, 2*LINE_WIDTH,
+ SIZE, 0);
+ cairo_rel_curve_to (cr,
+ -SIZE/2, 2*LINE_WIDTH,
+ -SIZE/2, -2*LINE_WIDTH,
+ -SIZE, 0);
+ cairo_close_path (cr);
+}
+
+static void
+draw_joins (cairo_t *cr)
+{
+ cairo_save (cr);
+ cairo_translate (cr, PAD, PAD);
+
+ make_path (cr);
+ cairo_set_line_join (cr, CAIRO_LINE_JOIN_BEVEL);
+ cairo_stroke (cr);
+ cairo_translate (cr, SIZE + PAD, 0.);
+
+ make_path (cr);
+ cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND);
+ cairo_stroke (cr);
+ cairo_translate (cr, SIZE + PAD, 0.);
+
+ make_path (cr);
+ cairo_set_line_join (cr, CAIRO_LINE_JOIN_MITER);
+ cairo_stroke (cr);
+ cairo_translate (cr, SIZE + PAD, 0.);
+
+ cairo_restore (cr);
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
+ cairo_paint (cr);
+
+ cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
+ cairo_set_line_width (cr, LINE_WIDTH);
+
+ draw_joins (cr);
+
+ /* and reflect to generate the opposite vertex ordering */
+ cairo_translate (cr, 0, height);
+ cairo_scale (cr, 1, -1);
+
+ draw_joins (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (joins_retrace,
+ "A shape that repeats upon itself",
+ "stroke", /* keywords */
+ NULL, /* requirements */
+ 3*(SIZE+PAD)+PAD, 2*(SIZE+PAD)+2*PAD,
+ NULL, draw)
+
diff --git a/test/joins-star.c b/test/joins-star.c
new file mode 100644
index 000000000..17c1b4e66
--- /dev/null
+++ b/test/joins-star.c
@@ -0,0 +1,99 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+#define LINE_WIDTH 10.
+#define SIZE (8 * LINE_WIDTH)
+#define PAD (1 * LINE_WIDTH)
+
+
+static void
+make_path (cairo_t *cr)
+{
+#define PROTRUSION 20
+ cairo_move_to (cr, SIZE/2-PROTRUSION, LINE_WIDTH);
+ cairo_line_to (cr, SIZE-LINE_WIDTH, SIZE/2+PROTRUSION);
+ cairo_line_to (cr, SIZE-LINE_WIDTH, SIZE/2-PROTRUSION);
+ cairo_line_to (cr, SIZE/2-PROTRUSION, SIZE-LINE_WIDTH);
+ cairo_line_to (cr, SIZE/2+PROTRUSION, SIZE-LINE_WIDTH);
+ cairo_line_to (cr, LINE_WIDTH, SIZE/2-PROTRUSION);
+ cairo_line_to (cr, LINE_WIDTH, SIZE/2+PROTRUSION);
+ cairo_line_to (cr, SIZE/2+PROTRUSION, LINE_WIDTH);
+ cairo_close_path (cr);
+}
+
+static void
+draw_joins (cairo_t *cr)
+{
+ cairo_save (cr);
+ cairo_translate (cr, PAD, PAD);
+
+ make_path (cr);
+ cairo_set_line_join (cr, CAIRO_LINE_JOIN_BEVEL);
+ cairo_stroke (cr);
+ cairo_translate (cr, SIZE + PAD, 0.);
+
+ make_path (cr);
+ cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND);
+ cairo_stroke (cr);
+ cairo_translate (cr, SIZE + PAD, 0.);
+
+ make_path (cr);
+ cairo_set_line_join (cr, CAIRO_LINE_JOIN_MITER);
+ cairo_stroke (cr);
+ cairo_translate (cr, SIZE + PAD, 0.);
+
+ cairo_restore (cr);
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
+ cairo_paint (cr);
+
+ cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
+ cairo_set_line_width (cr, LINE_WIDTH);
+
+ draw_joins (cr);
+
+ /* and reflect to generate the opposite vertex ordering */
+ cairo_translate (cr, 0, height);
+ cairo_scale (cr, 1, -1);
+
+ draw_joins (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (joins_star,
+ "A nice and simple concave shape",
+ "stroke", /* keywords */
+ NULL, /* requirements */
+ 3*(SIZE+PAD)+PAD, 2*(SIZE+PAD)+PAD,
+ NULL, draw)
+
diff --git a/test/joins.c b/test/joins.c
new file mode 100644
index 000000000..40ef72e21
--- /dev/null
+++ b/test/joins.c
@@ -0,0 +1,109 @@
+/*
+ * Copyright © 2008 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Chris Wilson not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Chris Wilson makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+#define LINE_WIDTH 12.
+#define SIZE (5 * LINE_WIDTH)
+#define PAD (2 * LINE_WIDTH)
+
+static void
+make_path (cairo_t *cr)
+{
+ const struct {
+ double x, y;
+ } scales[] = {
+ { 1, 1 },
+ { -1, 1 },
+ { 1, -1 },
+ { -1, -1 },
+ };
+ unsigned int i, j;
+
+ for (j = 0; j < ARRAY_LENGTH (scales); j++) {
+ cairo_save (cr);
+ /* include reflections to flip the orientation of the join */
+ cairo_scale (cr, scales[j].x, scales[j].y);
+ for (i = 0; i < 3; i++) {
+ cairo_new_sub_path (cr);
+ cairo_move_to (cr, 0, -9*LINE_WIDTH/4 - 2);
+ cairo_line_to (cr, 0, -2*LINE_WIDTH - 2);
+ cairo_line_to (cr, LINE_WIDTH/4, -2*LINE_WIDTH - 2);
+ cairo_rotate (cr, M_PI / 4.);
+ }
+ cairo_restore (cr);
+ }
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_line_join_t join;
+
+ cairo_save (cr);
+ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */
+ cairo_paint (cr);
+ cairo_restore (cr);
+
+ cairo_set_line_width (cr, LINE_WIDTH);
+ cairo_translate (cr, PAD + SIZE / 2., PAD + SIZE / 2.);
+
+ for (join = CAIRO_LINE_JOIN_MITER; join <= CAIRO_LINE_JOIN_BEVEL; join++) {
+ cairo_save (cr);
+
+ cairo_set_line_join (cr, join);
+
+ cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT);
+ make_path (cr);
+ cairo_stroke (cr);
+
+ cairo_translate (cr, 0, SIZE + PAD);
+
+ cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
+ make_path (cr);
+ cairo_stroke (cr);
+
+ cairo_translate (cr, 0, SIZE + PAD);
+
+ cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE);
+ make_path (cr);
+ cairo_stroke (cr);
+
+ cairo_restore (cr);
+
+ cairo_translate (cr, SIZE + PAD, 0);
+ }
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (joins,
+ "Test joins",
+ "stroke, joins", /* keywords */
+ NULL, /* requirements */
+ 3 * (PAD + SIZE) + PAD,
+ 3 * (PAD + SIZE) + PAD,
+ NULL, draw)
+
diff --git a/test/jp2.jp2 b/test/jp2.jp2
new file mode 100644
index 000000000..fe8dd6e54
--- /dev/null
+++ b/test/jp2.jp2
Binary files differ
diff --git a/test/jpeg.jpg b/test/jpeg.jpg
new file mode 100644
index 000000000..a1bac1c81
--- /dev/null
+++ b/test/jpeg.jpg
Binary files differ
diff --git a/test/large-clip.c b/test/large-clip.c
new file mode 100644
index 000000000..d2380def5
--- /dev/null
+++ b/test/large-clip.c
@@ -0,0 +1,50 @@
+/*
+ * Copyright © 2008 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Soren Sandmann <sandmann@redhat.com>
+ */
+
+#include "cairo-test.h"
+
+#define SIZE 100
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_set_source_rgb (cr, 0, 0, 1);
+ cairo_paint (cr);
+
+ cairo_rectangle (cr, 0, 0, 65536 + 25, 65536 + 25);
+ cairo_clip (cr);
+
+ cairo_set_source_rgb (cr, 1, 0, 0);
+ cairo_paint (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (large_clip,
+ "Incorrect clipping when the clip rectangle doesn't fit in 16 bits signed",
+ "clip, stress", /* keywords */
+ NULL, /* requirements */
+ SIZE, SIZE,
+ NULL, draw)
diff --git a/test/large-font.c b/test/large-font.c
new file mode 100644
index 000000000..0a139441c
--- /dev/null
+++ b/test/large-font.c
@@ -0,0 +1,73 @@
+/*
+ * Copyright © 2008 Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+/* Bug history:
+ *
+ * 2008-05-23: Caolan McNamara noticed a bug in OpenOffice.org where,
+ * when using a very large font, space would be left for a
+ * glyph but it would actually be rendered in the wrong
+ * place. He wrote a minimal test case and posted the bug
+ * here:
+ *
+ * corrupt glyph positions with large font
+ * https://bugzilla.redhat.com/show_bug.cgi?id=448104
+ *
+ * 2008-05-23: Carl Worth wrote this test for the cairo test suite to
+ * exercise the bug.
+ */
+
+#include "cairo-test.h"
+
+#define WIDTH 800
+#define HEIGHT 800
+#define TEXT_SIZE 10000
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ /* paint white so we don't need separate ref images for
+ * RGB24 and ARGB32 */
+ cairo_set_source_rgb (cr, 1., 1., 1.);
+ cairo_paint (cr);
+
+ cairo_select_font_face (cr, CAIRO_TEST_FONT_FAMILY " Sans",
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_NORMAL);
+ cairo_set_font_size (cr, TEXT_SIZE);
+
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ cairo_move_to (cr, -TEXT_SIZE / 2, TEXT_SIZE / 2);
+ cairo_show_text (cr, "xW");
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (large_font,
+ "Draws a very large font to exercise a glyph-positioning bug",
+ "stress, font", /* keywords */
+ NULL, /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw)
diff --git a/test/large-source-roi.c b/test/large-source-roi.c
new file mode 100644
index 000000000..dfd3554d7
--- /dev/null
+++ b/test/large-source-roi.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright © 2009 Joonas Pihlaja
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#include "cairo-test.h"
+
+/* This test attempts to trigger failures in those clone_similar
+ * backend methods that have size restrictions. */
+
+static cairo_surface_t *
+create_large_source (int width, int height)
+{
+ cairo_surface_t *surface;
+ cairo_t *cr;
+
+ surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, width, height);
+ cr = cairo_create (surface);
+ cairo_surface_destroy (surface);
+
+ cairo_set_source_rgb (cr, 1,0,0); /* red */
+ cairo_paint (cr);
+ surface = cairo_surface_reference (cairo_get_target (cr));
+ cairo_destroy (cr);
+
+ return surface;
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_surface_t *source;
+ /* Since 1cc750ed92a936d84b47cac696aaffd226e1c02e pixman will not
+ * paint on the source surface if source_width > 30582. */
+ double source_width = 30000.0;
+
+ cairo_set_source_rgb (cr, 1,1,1);
+ cairo_paint (cr);
+
+ /* Create an excessively wide source image, all red. */
+ source = create_large_source (source_width, height);
+
+ /* Set a transform so that the source is scaled down to fit in the
+ * destination horizontally and then paint the entire source to
+ * the context. */
+ cairo_scale (cr, width/source_width, 1.0);
+ cairo_set_source_surface (cr, source, 0, 0);
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_paint (cr);
+
+ cairo_surface_destroy (source);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (large_source_roi,
+ "Uses a all of a large source image.",
+ "stress, source", /* keywords */
+ NULL, /* requirements */
+ 7, 7,
+ NULL, draw)
diff --git a/test/large-source.c b/test/large-source.c
new file mode 100644
index 000000000..2b6b84fb4
--- /dev/null
+++ b/test/large-source.c
@@ -0,0 +1,100 @@
+/*
+ * Copyright © Chris Wilson, 2008
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Chris Wilson not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Chris Wilson makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+/* This is a test case for the following bug:
+ *
+ * crafted gif file will crash firefox
+ * [XError: 'BadAlloc (insufficient resources for operation)']
+ * https://bugzilla.mozilla.org/show_bug.cgi?id=424333
+ */
+
+#ifdef WORDS_BIGENDIAN
+#define RED_MASK 0xA0
+#define GREEN_MASK 0xA
+#else
+#define RED_MASK 0x5
+#define GREEN_MASK 0x50
+#endif
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_surface_t *surface;
+ unsigned char *data;
+
+ cairo_set_source_rgb (cr, 0, 0, 1); /* blue */
+ cairo_paint (cr);
+
+ surface = cairo_image_surface_create (CAIRO_FORMAT_A1, 32000, 20);
+ data = cairo_image_surface_get_data (surface);
+ if (data != NULL) {
+ int stride = cairo_image_surface_get_stride (surface);
+ int width = cairo_image_surface_get_width (surface);
+ int height = cairo_image_surface_get_height (surface);
+ int x, y;
+
+ for (y = 0; y < height; y++) {
+ for (x = 0; x < (width + 7) / 8; x++)
+ data[x] = RED_MASK;
+ data += stride;
+ }
+ cairo_surface_mark_dirty (surface);
+ }
+
+ cairo_set_source_rgb (cr, 1, 0, 0); /* red */
+ cairo_mask_surface (cr, surface, 0, 0);
+ cairo_surface_destroy (surface);
+
+ surface = cairo_image_surface_create (CAIRO_FORMAT_A1, 20, 32000);
+ data = cairo_image_surface_get_data (surface);
+ if (data != NULL) {
+ int stride = cairo_image_surface_get_stride (surface);
+ int width = cairo_image_surface_get_width (surface);
+ int height = cairo_image_surface_get_height (surface);
+ int x, y;
+
+ for (y = 0; y < height; y++) {
+ for (x = 0; x < (width + 7) / 8; x++)
+ data[x] = GREEN_MASK;
+ data += stride;
+ }
+ cairo_surface_mark_dirty (surface);
+ }
+
+ cairo_set_source_rgb (cr, 0, 1, 0); /* green */
+ cairo_mask_surface (cr, surface, 0, 0);
+ cairo_surface_destroy (surface);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (large_source,
+ "Exercises mozilla bug 424333 - handling of massive images",
+ "stress, source", /* keywords */
+ NULL, /* requirements */
+ 20, 20,
+ NULL, draw)
diff --git a/test/large-twin-antialias-mixed.c b/test/large-twin-antialias-mixed.c
new file mode 100644
index 000000000..9626a9dd2
--- /dev/null
+++ b/test/large-twin-antialias-mixed.c
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2009 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Chris Wilson not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Chris Wilson makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+static cairo_scaled_font_t *
+create_twin (cairo_t *cr, cairo_antialias_t antialias)
+{
+ cairo_font_options_t *options;
+
+ cairo_select_font_face (cr,
+ "@cairo:",
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_NORMAL);
+
+ options = cairo_font_options_create ();
+ cairo_font_options_set_antialias (options, antialias);
+ cairo_set_font_options (cr, options);
+ cairo_font_options_destroy (options);
+
+ return cairo_scaled_font_reference (cairo_get_scaled_font (cr));
+}
+
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_scaled_font_t *subpixel, *gray, *none;
+
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+ cairo_set_source_rgb (cr, 0, 0, 0);
+
+ cairo_set_font_size (cr, 64);
+ subpixel = create_twin (cr, CAIRO_ANTIALIAS_SUBPIXEL);
+ gray = create_twin (cr, CAIRO_ANTIALIAS_GRAY);
+ none = create_twin (cr, CAIRO_ANTIALIAS_NONE);
+
+ cairo_move_to (cr, 4, 64);
+ cairo_set_scaled_font (cr, subpixel);
+ cairo_show_text (cr, "Is cairo's");
+ cairo_set_scaled_font (cr, gray);
+ cairo_show_text (cr, " twin");
+ cairo_set_scaled_font (cr, none);
+ cairo_show_text (cr, " giza?");
+
+ cairo_move_to (cr, 4, 128+16);
+ cairo_set_scaled_font (cr, gray);
+ cairo_show_text (cr, "Is cairo's");
+ cairo_set_scaled_font (cr, none);
+ cairo_show_text (cr, " twin");
+ cairo_set_scaled_font (cr, subpixel);
+ cairo_show_text (cr, " giza?");
+
+ cairo_move_to (cr, 4, 192+32);
+ cairo_set_scaled_font (cr, none);
+ cairo_show_text (cr, "Is cairo's");
+ cairo_set_scaled_font (cr, gray);
+ cairo_show_text (cr, " twin");
+ cairo_set_scaled_font (cr, subpixel);
+ cairo_show_text (cr, " giza?");
+
+ cairo_scaled_font_destroy (none);
+ cairo_scaled_font_destroy (gray);
+ cairo_scaled_font_destroy (subpixel);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (large_twin_antialias_mixed,
+ "Tests the internal font (with intermixed antialiasing)",
+ "twin, font", /* keywords */
+ "target=raster", /* requirements */
+ 524, 240,
+ NULL, draw)
diff --git a/test/leaky-dash.c b/test/leaky-dash.c
new file mode 100644
index 000000000..12e91ac1d
--- /dev/null
+++ b/test/leaky-dash.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright © 2005 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+/* Test case for bug #4863:
+ *
+ * stroking problems with wide dashed lines
+ * https://bugs.freedesktop.org/show_bug.cgi?id=4863
+ */
+
+#include "cairo-test.h"
+
+#define WIDTH 71
+#define HEIGHT 28
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ double dash[2];
+
+ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */
+ cairo_paint (cr);
+ cairo_set_source_rgb (cr, 0.0, 0.0, 0.0); /* black */
+
+ cairo_set_line_width (cr, 2);
+ dash[0] = 8.0;
+ dash[1] = 2.0;
+
+ cairo_rectangle (cr, 2.0, 2.0, 67.0, 24.0);
+
+ cairo_set_dash (cr, dash, 2, 9.0);
+ cairo_stroke (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (leaky_dash,
+ "Exercises bug #4863 in which a dashed stroke leaks into half the rectangle being filled"
+ "\nknown bug (#4863) which has existed since the 1.0 release",
+ "dash, stroke", /* keywords */
+ NULL, /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw)
diff --git a/test/leaky-dashed-rectangle.c b/test/leaky-dashed-rectangle.c
new file mode 100644
index 000000000..25f5674e9
--- /dev/null
+++ b/test/leaky-dashed-rectangle.c
@@ -0,0 +1,86 @@
+/*
+ * Copyright © 2008 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Chris Wilson not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Chris Wilson makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ * Franz Schmid <Franz.Schmid@altmuehlnet.de>
+ */
+
+/* Test case for bug reported by Franz Schmid <Franz.Schmid@altmuehlnet.de>
+ * http://lists.cairographics.org/archives/cairo/2008-April/013912.html
+ *
+ * See also: http://bugs.freedesktop.org/show_bug.cgi?id=17177
+ */
+
+#include "cairo-test.h"
+
+#define WIDTH 60
+#define HEIGHT 60
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ const double dash[2] = {4, 2};
+
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+ cairo_set_source_rgb (cr, 0., 0., 0);
+
+ cairo_translate (cr, 0.5, .5);
+ cairo_set_line_width (cr, 1); /* This is vital to reproduce the bug. */
+
+ /* First check simple rectangles */
+ cairo_set_source_rgb (cr, 0., 0., 0);
+ cairo_rectangle (cr, -WIDTH/4, -HEIGHT/4, WIDTH, HEIGHT);
+ cairo_stroke (cr);
+ cairo_rectangle (cr, WIDTH+WIDTH/4, -HEIGHT/4, -WIDTH, HEIGHT);
+ cairo_stroke (cr);
+ cairo_rectangle (cr, -WIDTH/4, HEIGHT+HEIGHT/4, WIDTH, -HEIGHT);
+ cairo_stroke (cr);
+ cairo_rectangle (cr, WIDTH+WIDTH/4, HEIGHT+HEIGHT/4, -WIDTH, -HEIGHT);
+ cairo_stroke (cr);
+
+ cairo_set_dash (cr, dash, 2, 0);
+
+ /* And now dashed. */
+ cairo_set_source_rgb (cr, 1., 0., 0);
+ cairo_rectangle (cr, -WIDTH/4, -HEIGHT/4, WIDTH, HEIGHT);
+ cairo_stroke (cr);
+ cairo_set_source_rgb (cr, 0., 1., 0);
+ cairo_rectangle (cr, WIDTH+WIDTH/4, -HEIGHT/4, -WIDTH, HEIGHT);
+ cairo_stroke (cr);
+ cairo_set_source_rgb (cr, 0., 0., 1);
+ cairo_rectangle (cr, -WIDTH/4, HEIGHT+HEIGHT/4, WIDTH, -HEIGHT);
+ cairo_stroke (cr);
+ cairo_set_source_rgb (cr, 1., 1., 0);
+ cairo_rectangle (cr, WIDTH+WIDTH/4, HEIGHT+HEIGHT/4, -WIDTH, -HEIGHT);
+ cairo_stroke (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (leaky_dashed_rectangle,
+ "Exercises bug in which a dashed stroke leaks in from outside the surface",
+ "dash, stroke", /* keywords */
+ NULL, /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw)
diff --git a/test/leaky-dashed-stroke.c b/test/leaky-dashed-stroke.c
new file mode 100644
index 000000000..457d7ce70
--- /dev/null
+++ b/test/leaky-dashed-stroke.c
@@ -0,0 +1,166 @@
+/*
+ * Copyright © 2008 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Chris Wilson not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Chris Wilson makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+/* Extracted from a test case reported by Jeff Muizelaar found whilst running
+ * firefox http://people.mozilla.com/~jmuizelaar/BerlinDistricts-check.svg
+ */
+
+#include "cairo-test.h"
+
+#define WIDTH 205
+#define HEIGHT 260
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ const double dash[2] = {.5, .5};
+
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+ cairo_set_source_rgb (cr, 1., 0., 0);
+
+ /* By adjusting the miter limit, we can see variations on the artifact.
+ * cairo_set_miter_limit (cr, 4.);
+ */
+
+ cairo_translate (cr, -720, -484);
+ cairo_scale (cr, 2.5, 2.5);
+
+ cairo_set_dash (cr, dash, 2, 0);
+
+ cairo_move_to (cr, 293.622, 330);
+ cairo_line_to (cr, 293.703, 337.028);
+ cairo_line_to (cr, 297.45, 336.851);
+ cairo_line_to (cr, 308.88, 342.609);
+ cairo_line_to (cr, 309.736, 346.107);
+ cairo_line_to (cr, 312.972, 348.128);
+ cairo_line_to (cr, 312.977, 353.478);
+ cairo_line_to (cr, 322.486, 359.355);
+ cairo_line_to (cr, 320.831, 363.642);
+ cairo_line_to (cr, 315.175, 367.171);
+ cairo_line_to (cr, 308.987, 365.715);
+ cairo_line_to (cr, 301.3, 365.964);
+ cairo_line_to (cr, 304.712, 368.852);
+ cairo_line_to (cr, 305.349, 373.022);
+ cairo_line_to (cr, 303.211, 376.551);
+ cairo_line_to (cr, 304.915, 382.855);
+ cairo_line_to (cr, 323.715, 400.475);
+ cairo_line_to (cr, 355.323, 424.072);
+ cairo_line_to (cr, 443.078, 426.534);
+ cairo_line_to (cr, 455.26, 400.603);
+ cairo_line_to (cr, 471.924, 392.604);
+ cairo_line_to (cr, 478.556, 390.797);
+ cairo_line_to (cr, 477.715, 386);
+ cairo_line_to (cr, 456.807, 376.507);
+ cairo_line_to (cr, 449.134, 368.722);
+ cairo_line_to (cr, 449.147, 365.847);
+ cairo_line_to (cr, 439.981, 361.692);
+ cairo_line_to (cr, 439.994, 358.603);
+ cairo_line_to (cr, 454.645, 336.128);
+ cairo_line_to (cr, 434.995, 324.005);
+ cairo_line_to (cr, 423.884, 319.354);
+ cairo_line_to (cr, 421.098, 312.569);
+ cairo_line_to (cr, 424.291, 305.997);
+ cairo_line_to (cr, 431.308, 305.069);
+ cairo_line_to (cr, 437.257, 296.882);
+ cairo_line_to (cr, 448.544, 296.808);
+ cairo_line_to (cr, 452.113, 290.651);
+ cairo_line_to (cr, 448.469, 285.483);
+ cairo_line_to (cr, 442.903, 282.877);
+ cairo_line_to (cr, 447.798, 281.124);
+ cairo_line_to (cr, 454.622, 274.911);
+ cairo_line_to (cr, 449.491, 269.978);
+ cairo_line_to (cr, 443.666, 253.148);
+ cairo_line_to (cr, 445.741, 250.834);
+ cairo_line_to (cr, 441.87, 247.131);
+ cairo_line_to (cr, 436.932, 246.203);
+ cairo_line_to (cr, 430.5, 251.252);
+ cairo_line_to (cr, 427.483, 250.751);
+ cairo_line_to (cr, 427.26, 253.572);
+ cairo_line_to (cr, 423.621, 255.539);
+ cairo_line_to (cr, 423.824, 257.933);
+ cairo_line_to (cr, 425.239, 259.582);
+ cairo_line_to (cr, 422.385, 261.443);
+ cairo_line_to (cr, 421.665, 260.53);
+ cairo_line_to (cr, 419.238, 262.819);
+ cairo_line_to (cr, 418.731, 257.849);
+ cairo_line_to (cr, 419.72, 255.227);
+ cairo_line_to (cr, 418.786, 250.258);
+ cairo_line_to (cr, 405.685, 235.254);
+ cairo_line_to (cr, 427.167, 215.127);
+ cairo_line_to (cr, 413.852, 196.281);
+ cairo_line_to (cr, 420.177, 192.379);
+ cairo_line_to (cr, 419.885, 185.701);
+ cairo_line_to (cr, 413.401, 185.428);
+ cairo_line_to (cr, 407.985, 186.863);
+ cairo_line_to (cr, 397.11, 189.112);
+ cairo_line_to (cr, 390.505, 186.664);
+ cairo_line_to (cr, 388.527, 183.694);
+ cairo_line_to (cr, 336.503, 221.048);
+ cairo_line_to (cr, 367.028, 241.656);
+ cairo_line_to (cr, 365.103, 244.117);
+ cairo_line_to (cr, 364.886, 246.792);
+ cairo_line_to (cr, 361.467, 247.119);
+ cairo_line_to (cr, 360.396, 245.525);
+ cairo_line_to (cr, 356.336, 245.638);
+ cairo_line_to (cr, 353.344, 242.122);
+ cairo_line_to (cr, 347.149, 242.876);
+ cairo_line_to (cr, 341.809, 256.652);
+ cairo_line_to (cr, 342.232, 268.72);
+ cairo_line_to (cr, 329.579, 269.095);
+ cairo_line_to (cr, 327.001, 271.009);
+ cairo_line_to (cr, 325.579, 275.598);
+ cairo_line_to (cr, 318.941, 277.313);
+ cairo_line_to (cr, 306.048, 277.231);
+ cairo_line_to (cr, 304.071, 276.27);
+ cairo_line_to (cr, 301.153, 277.175);
+ cairo_line_to (cr, 293.52, 277.529);
+ cairo_line_to (cr, 290.682, 281.947);
+ cairo_line_to (cr, 293.911, 286.63);
+ cairo_line_to (cr, 302.417, 290.547);
+ cairo_line_to (cr, 303.521, 294.73);
+ cairo_line_to (cr, 307.787, 298.088);
+ cairo_line_to (cr, 311.718, 299.126);
+ cairo_line_to (cr, 313.255, 302.146);
+ cairo_line_to (cr, 314.6, 306.206);
+ cairo_line_to (cr, 322.603, 308.96);
+ cairo_line_to (cr, 321.718, 314.477);
+ cairo_line_to (cr, 319.596, 320.341);
+ cairo_line_to (cr, 300.689, 323.69);
+ cairo_line_to (cr, 301.232, 326.789);
+ cairo_line_to (cr, 293.622, 330);
+ cairo_close_path (cr);
+
+ cairo_stroke (cr);
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (leaky_dashed_stroke,
+ "Exercises bug in which a dashed stroke leaks in from outside the surface",
+ "dash, stroke", /* keywords */
+ NULL, /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw)
diff --git a/test/leaky-polygon.c b/test/leaky-polygon.c
new file mode 100644
index 000000000..0ea7094c9
--- /dev/null
+++ b/test/leaky-polygon.c
@@ -0,0 +1,85 @@
+/*
+ * Copyright © 2005 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+/* Bug history
+ *
+ * 2005-01-07 Carl Worth <cworth@cworth.org>
+ *
+ * Bug reported:
+ *
+ * From: Chris <fltk@functionalfuture.com>
+ * Subject: [cairo] Render to image buffer artifacts
+ * To: cairo@cairographics.org
+ * Date: Fri, 07 Jan 2005 02:22:28 -0500
+ *
+ * I've attached the code and image that shows this off. Scaling at
+ * different levels seems to change the corruption.
+ *
+ * For some reason there are artifacts in the alpha channel. I don't know
+ * if that's the only place, but the alpha channel looks bad.
+ *
+ * If you run the code and parse the attached image, directing stdout to a
+ * file, you can see in the lower left corner there are alpha values where
+ * it should be transparent.
+ * [...]
+ *
+ * 2005-01-11 Carl Worth <cworth@cworth.org>
+ *
+ * I trimmed the original test case down to the code that appears here.
+ *
+ */
+
+#include "cairo-test.h"
+
+#define WIDTH 21
+#define HEIGHT 21
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ /* We draw in the default black, so paint white first. */
+ cairo_save (cr);
+ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */
+ cairo_paint (cr);
+ cairo_restore (cr);
+
+ cairo_scale (cr, 1.0/(1<<16), 1.0/(1<<16));
+
+ cairo_move_to (cr, 131072,39321);
+ cairo_line_to (cr, 1103072,1288088);
+ cairo_line_to (cr, 1179648,1294990);
+ cairo_close_path (cr);
+
+ cairo_fill (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (leaky_polygon,
+ "Exercises a corner case in the trapezoid rasterization in which pixels outside the trapezoids received a non-zero alpha",
+ "fill, trap", /* keywords */
+ NULL, /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw)
diff --git a/test/line-width-large-overlap.c b/test/line-width-large-overlap.c
new file mode 100644
index 000000000..767734f6b
--- /dev/null
+++ b/test/line-width-large-overlap.c
@@ -0,0 +1,149 @@
+/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */
+/*
+ * Copyright 2011 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Benjamin Otte <otte@redhat.com>
+ */
+
+/*
+ * Test case taken from the WebKit test suite, failure originally reported
+ * by Zan Dobersek <zandobersek@gmail.com>. WebKit test is
+ * LayoutTests/canvas/philip/tests/2d.path.rect.selfintersect.html
+ */
+
+#include "cairo-test.h"
+
+#include <math.h>
+
+#define LINE_WIDTH 120
+#define SIZE 100
+#define RECT_SIZE 10
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ /* fill with green so RGB and RGBA tests can share the ref image */
+ cairo_set_source_rgb (cr, 0, 1, 0);
+ cairo_paint (cr);
+
+ /* red to see eventual bugs immediately */
+ cairo_set_source_rgb (cr, 1, 0, 0);
+
+ /* big line width */
+ cairo_set_line_width (cr, LINE_WIDTH);
+
+ /* rectangle that is smaller than the line width in center of image */
+ cairo_rectangle (cr,
+ (SIZE - RECT_SIZE) / 2,
+ (SIZE - RECT_SIZE) / 2,
+ RECT_SIZE,
+ RECT_SIZE);
+
+ cairo_stroke (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+/* and again slightly offset to trigger another path */
+static cairo_test_status_t
+draw_offset (cairo_t *cr, int width, int height)
+{
+ cairo_translate (cr, .5, .5);
+ return draw (cr, width, height);
+}
+
+static cairo_test_status_t
+draw_rotated (cairo_t *cr, int width, int height)
+{
+ cairo_translate (cr, SIZE/2, SIZE/2);
+ cairo_rotate (cr, M_PI/4);
+ cairo_translate (cr, -SIZE/2, -SIZE/2);
+
+ return draw (cr, width, height);
+}
+
+static cairo_test_status_t
+draw_flipped (cairo_t *cr, int width, int height)
+{
+ cairo_translate (cr, SIZE/2, SIZE/2);
+ cairo_scale (cr, -1, 1);
+ cairo_translate (cr, -SIZE/2, -SIZE/2);
+
+ return draw (cr, width, height);
+}
+
+static cairo_test_status_t
+draw_flopped (cairo_t *cr, int width, int height)
+{
+ cairo_translate (cr, SIZE/2, SIZE/2);
+ cairo_scale (cr, 1, -1);
+ cairo_translate (cr, -SIZE/2, -SIZE/2);
+
+ return draw (cr, width, height);
+}
+
+static cairo_test_status_t
+draw_dashed (cairo_t *cr, int width, int height)
+{
+ const double dashes[] = { 4 };
+ cairo_set_dash (cr, dashes, 1, 0);
+ cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT);
+ return draw (cr, width, height);
+}
+
+CAIRO_TEST (line_width_large_overlap,
+ "Test overlapping lines due to large line width",
+ "stroke", /* keywords */
+ NULL, /* requirements */
+ SIZE, SIZE,
+ NULL, draw)
+CAIRO_TEST (line_width_large_overlap_offset,
+ "Test overlapping lines due to large line width",
+ "stroke", /* keywords */
+ NULL, /* requirements */
+ SIZE, SIZE,
+ NULL, draw_offset)
+CAIRO_TEST (line_width_large_overlap_rotated,
+ "Test overlapping lines due to large line width",
+ "stroke", /* keywords */
+ NULL, /* requirements */
+ SIZE, SIZE,
+ NULL, draw_rotated)
+CAIRO_TEST (line_width_large_overlap_flipped,
+ "Test overlapping lines due to large line width",
+ "stroke", /* keywords */
+ NULL, /* requirements */
+ SIZE, SIZE,
+ NULL, draw_flipped)
+CAIRO_TEST (line_width_large_overlap_flopped,
+ "Test overlapping lines due to large line width",
+ "stroke", /* keywords */
+ NULL, /* requirements */
+ SIZE, SIZE,
+ NULL, draw_flopped)
+CAIRO_TEST (line_width_large_overlap_dashed,
+ "Test overlapping lines due to large line width",
+ "stroke", /* keywords */
+ NULL, /* requirements */
+ SIZE, SIZE,
+ NULL, draw_dashed)
diff --git a/test/line-width-overlap.c b/test/line-width-overlap.c
new file mode 100644
index 000000000..ac8c23479
--- /dev/null
+++ b/test/line-width-overlap.c
@@ -0,0 +1,149 @@
+/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */
+/*
+ * Copyright 2011 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Benjamin Otte <otte@redhat.com>
+ */
+
+/*
+ * Test case taken from the WebKit test suite, failure originally reported
+ * by Zan Dobersek <zandobersek@gmail.com>. WebKit test is
+ * LayoutTests/canvas/philip/tests/2d.path.rect.selfintersect.html
+ */
+
+#include "cairo-test.h"
+
+#include <math.h>
+
+#define LINE_WIDTH 60
+#define SIZE 100
+#define RECT_SIZE 10
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ /* fill with green so RGB and RGBA tests can share the ref image */
+ cairo_set_source_rgb (cr, 0, 1, 0);
+ cairo_paint (cr);
+
+ /* red to see eventual bugs immediately */
+ cairo_set_source_rgb (cr, 1, 0, 0);
+
+ /* big line width */
+ cairo_set_line_width (cr, LINE_WIDTH);
+
+ /* rectangle that is smaller than the line width in center of image */
+ cairo_rectangle (cr,
+ (SIZE - RECT_SIZE) / 2,
+ (SIZE - RECT_SIZE) / 2,
+ RECT_SIZE,
+ RECT_SIZE);
+
+ cairo_stroke (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+/* and again slightly offset to trigger another path */
+static cairo_test_status_t
+draw_offset (cairo_t *cr, int width, int height)
+{
+ cairo_translate (cr, .5, .5);
+ return draw (cr, width, height);
+}
+
+static cairo_test_status_t
+draw_rotated (cairo_t *cr, int width, int height)
+{
+ cairo_translate (cr, SIZE/2, SIZE/2);
+ cairo_rotate (cr, M_PI/4);
+ cairo_translate (cr, -SIZE/2, -SIZE/2);
+
+ return draw (cr, width, height);
+}
+
+static cairo_test_status_t
+draw_flipped (cairo_t *cr, int width, int height)
+{
+ cairo_translate (cr, SIZE/2, SIZE/2);
+ cairo_scale (cr, -1, 1);
+ cairo_translate (cr, -SIZE/2, -SIZE/2);
+
+ return draw (cr, width, height);
+}
+
+static cairo_test_status_t
+draw_flopped (cairo_t *cr, int width, int height)
+{
+ cairo_translate (cr, SIZE/2, SIZE/2);
+ cairo_scale (cr, 1, -1);
+ cairo_translate (cr, -SIZE/2, -SIZE/2);
+
+ return draw (cr, width, height);
+}
+
+static cairo_test_status_t
+draw_dashed (cairo_t *cr, int width, int height)
+{
+ const double dashes[] = { 4 };
+ cairo_set_dash (cr, dashes, 1, 0);
+ cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT);
+ return draw (cr, width, height);
+}
+
+CAIRO_TEST (line_width_overlap,
+ "Test overlapping lines due to large line width",
+ "stroke", /* keywords */
+ NULL, /* requirements */
+ SIZE, SIZE,
+ NULL, draw)
+CAIRO_TEST (line_width_overlap_offset,
+ "Test overlapping lines due to large line width",
+ "stroke", /* keywords */
+ NULL, /* requirements */
+ SIZE, SIZE,
+ NULL, draw_offset)
+CAIRO_TEST (line_width_overlap_rotated,
+ "Test overlapping lines due to large line width",
+ "stroke", /* keywords */
+ NULL, /* requirements */
+ SIZE, SIZE,
+ NULL, draw_rotated)
+CAIRO_TEST (line_width_overlap_flipped,
+ "Test overlapping lines due to large line width",
+ "stroke", /* keywords */
+ NULL, /* requirements */
+ SIZE, SIZE,
+ NULL, draw_flipped)
+CAIRO_TEST (line_width_overlap_flopped,
+ "Test overlapping lines due to large line width",
+ "stroke", /* keywords */
+ NULL, /* requirements */
+ SIZE, SIZE,
+ NULL, draw_flopped)
+CAIRO_TEST (line_width_overlap_dashed,
+ "Test overlapping lines due to large line width",
+ "stroke", /* keywords */
+ NULL, /* requirements */
+ SIZE, SIZE,
+ NULL, draw_dashed)
diff --git a/test/line-width-scale.c b/test/line-width-scale.c
new file mode 100644
index 000000000..037b887fd
--- /dev/null
+++ b/test/line-width-scale.c
@@ -0,0 +1,178 @@
+/*
+ * Copyright © 2006 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+#include "cairo-test.h"
+
+/* This test exercises the various interactions between
+ * cairo_set_line_width and cairo_scale. Specifically it shows how
+ * separate transformations can affect the pen for stroking compared
+ * to the path itself.
+ *
+ * This was inspired by an image by Maxim Shemanarev demonstrating the
+ * flexible-pipeline nature of his Antigrain Geometry project:
+ *
+ * http://antigrain.com/tips/line_alignment/conv_order.gif
+ *
+ * It also uncovered some behavior in cairo that I found surprising.
+ * Namely, cairo_set_line_width was not transforming the width
+ * according the the current CTM, but instead delaying that
+ * transformation until the time of cairo_stroke.
+ *
+ * This delayed behavior was released in cairo 1.0 so we're going to
+ * document this as the way cairo_set_line_width works rather than
+ * considering this a bug.
+ */
+
+#define LINE_WIDTH 13
+#define SPLINE 50.0
+#define XSCALE 0.5
+#define YSCALE 2.0
+#define WIDTH (XSCALE * SPLINE * 6.0)
+#define HEIGHT (YSCALE * SPLINE * 2.0)
+
+static void
+spline_path (cairo_t *cr)
+{
+ cairo_save (cr);
+ {
+ cairo_move_to (cr,
+ - SPLINE, 0);
+ cairo_curve_to (cr,
+ - SPLINE / 4, - SPLINE,
+ SPLINE / 4, SPLINE,
+ SPLINE, 0);
+ }
+ cairo_restore (cr);
+}
+
+/* If we scale before setting the line width or creating the path,
+ * then obviously both will be scaled. */
+static void
+scale_then_set_line_width_and_stroke (cairo_t *cr)
+{
+ cairo_scale (cr, XSCALE, YSCALE);
+ cairo_set_line_width (cr, LINE_WIDTH);
+ spline_path (cr);
+ cairo_stroke (cr);
+}
+
+/* This is used to verify the results of
+ * scale_then_set_line_width_and_stroke.
+ *
+ * It uses save/restore pairs to isolate the scaling of the path and
+ * line_width and ensures that both are scaled.
+ */
+static void
+scale_path_and_line_width (cairo_t *cr)
+{
+ cairo_save (cr);
+ {
+ cairo_scale (cr, XSCALE, YSCALE);
+ spline_path (cr);
+ }
+ cairo_restore (cr);
+
+ cairo_save (cr);
+ {
+ cairo_scale (cr, XSCALE, YSCALE);
+ cairo_set_line_width (cr, LINE_WIDTH);
+ cairo_stroke (cr);
+ }
+ cairo_restore (cr);
+}
+
+/* This is the case that was surprising.
+ *
+ * Setting the line width before scaling doesn't change anything. The
+ * line width will be interpreted under the CTM in effect at the time
+ * of cairo_stroke, so the line width will be scaled as well as the
+ * path here.
+ */
+static void
+set_line_width_then_scale_and_stroke (cairo_t *cr)
+{
+ cairo_set_line_width (cr, LINE_WIDTH);
+ cairo_scale (cr, XSCALE, YSCALE);
+ spline_path (cr);
+ cairo_stroke (cr);
+}
+
+/* Here then is the way to achieve the alternate result.
+ *
+ * This uses save/restore pairs to isolate the scaling of the path and
+ * line_width and ensures that the path is scaled while the line width
+ * is not.
+ */
+static void
+scale_path_not_line_width (cairo_t *cr)
+{
+ cairo_save (cr);
+ {
+ cairo_scale (cr, XSCALE, YSCALE);
+ spline_path (cr);
+ }
+ cairo_restore (cr);
+
+ cairo_save (cr);
+ {
+ cairo_set_line_width (cr, LINE_WIDTH);
+ cairo_stroke (cr);
+ }
+ cairo_restore (cr);
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ int i;
+ void (* const figures[4]) (cairo_t *cr) = {
+ scale_then_set_line_width_and_stroke,
+ scale_path_and_line_width,
+ set_line_width_then_scale_and_stroke,
+ scale_path_not_line_width
+ };
+
+ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */
+ cairo_paint (cr);
+ cairo_set_source_rgb (cr, 0.0, 0.0, 0.0); /* black */
+
+ for (i = 0; i < 4; i++) {
+ cairo_save (cr);
+ cairo_translate (cr,
+ WIDTH/4 + (i % 2) * WIDTH/2,
+ HEIGHT/4 + (i / 2) * HEIGHT/2);
+ (figures[i]) (cr);
+ cairo_restore (cr);
+ }
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (line_width_scale,
+ "Tests interaction of cairo_set_line_width with cairo_scale",
+ "stroke", /* keywords */
+ NULL, /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw)
diff --git a/test/line-width-tolerance.c b/test/line-width-tolerance.c
new file mode 100644
index 000000000..5a581ca11
--- /dev/null
+++ b/test/line-width-tolerance.c
@@ -0,0 +1,66 @@
+/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */
+/*
+ * Copyright 2011 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Benjamin Otte <otte@redhat.com>
+ */
+
+/*
+ * Test case taken from the WebKit test suite, failure originally reported
+ * by Zan Dobersek <zandobersek@gmail.com> at
+ * https://bugs.webkit.org/show_bug.cgi?id=54471
+ */
+
+#include "cairo-test.h"
+
+#include <math.h>
+
+#define RADIUS 50
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ /* fill with green so RGB and RGBA tests can share the ref image */
+ cairo_set_source_rgb (cr, 0, 1, 0);
+ cairo_paint (cr);
+
+ /* red to see eventual bugs immediately */
+ cairo_set_source_rgb (cr, 1, 0, 0);
+
+ /* stroke 3/4 of a circle where the last quarter would be this
+ * reference image. Keep just a 1 pixel border. Use a huge line
+ * width (twice the circle's radius to get it filled completely).
+ */
+ cairo_set_line_width (cr, 2 * RADIUS);
+ cairo_arc (cr, 1, RADIUS - 1, RADIUS, 0, - M_PI / 2.0);
+ cairo_stroke (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (line_width_tolerance,
+ "Test interaction of line width and tolerance when stroking arcs",
+ "stroke", /* keywords */
+ NULL, /* requirements */
+ RADIUS, RADIUS,
+ NULL, draw)
diff --git a/test/line-width-zero.c b/test/line-width-zero.c
new file mode 100644
index 000000000..c7ac8a0fd
--- /dev/null
+++ b/test/line-width-zero.c
@@ -0,0 +1,71 @@
+/*
+ * Copyright © 2007 Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Carl Worth <cworth@cworth.org>
+ */
+
+#include "cairo-test.h"
+
+/* This is a test case for the following bug:
+ *
+ * Crash in cairo_stroke_extents whe line width is 0 and line cap is ROUND
+ * (_cairo_pen_find_active_cw_vertex_index)
+ * https://bugs.freedesktop.org/show_bug.cgi?id=10231
+ */
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ double x1, y1, x2, y2;
+
+ cairo_move_to (cr, 0.0, 0.0);
+ cairo_line_to (cr, 100.0, 100.0);
+ cairo_set_line_width (cr, 0.0);
+
+ cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT);
+ cairo_set_line_join (cr, CAIRO_LINE_JOIN_MITER);
+ cairo_stroke_extents (cr, &x1, &y1, &x2, &y2);
+ cairo_in_stroke (cr, 50, 50);
+ cairo_stroke_preserve (cr);
+
+ cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
+ cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND);
+ cairo_stroke_extents (cr, &x1, &y1, &x2, &y2);
+ cairo_in_stroke (cr, 50, 50);
+ cairo_stroke_preserve (cr);
+
+ cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE);
+ cairo_set_line_join (cr, CAIRO_LINE_JOIN_BEVEL);
+ cairo_stroke_extents (cr, &x1, &y1, &x2, &y2);
+ cairo_in_stroke (cr, 50, 50);
+ cairo_stroke (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (line_width_zero,
+ "Test all stroke operations and all cap,join styles with line width of zero",
+ "stroke", /* keywords */
+ NULL, /* requirements */
+ 0, 0,
+ NULL, draw)
diff --git a/test/line-width.c b/test/line-width.c
new file mode 100644
index 000000000..315ebc393
--- /dev/null
+++ b/test/line-width.c
@@ -0,0 +1,77 @@
+/*
+ * Copyright © 2004 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+#include "cairo-test.h"
+
+#define LINES 5
+#define LINE_LENGTH 10
+#define IMAGE_WIDTH 2 * LINE_LENGTH + 6
+#define IMAGE_HEIGHT ((LINES+4)*LINES)/2 + 2
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ int i;
+
+ /* We draw in black, so paint white first. */
+ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */
+ cairo_paint (cr);
+
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ cairo_translate (cr, 2, 2);
+
+ for (i=0; i < LINES; i++) {
+ cairo_set_line_width (cr, i+1);
+ cairo_move_to (cr, 0, 0);
+ cairo_rel_line_to (cr, LINE_LENGTH, 0);
+ cairo_stroke (cr);
+ cairo_move_to (cr, LINE_LENGTH + 2, 0.5);
+ cairo_rel_line_to (cr, LINE_LENGTH, 0);
+ cairo_stroke (cr);
+ cairo_translate (cr, 0, i+3);
+ }
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+draw_a1 (cairo_t *cr, int width, int height)
+{
+ cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE);
+ return draw (cr, width, height);
+}
+
+CAIRO_TEST (line_width,
+ "Tests cairo_set_line_width",
+ "stroke", /* keywords */
+ NULL, /* requirements */
+ IMAGE_WIDTH, IMAGE_HEIGHT,
+ NULL, draw)
+CAIRO_TEST (a1_line_width,
+ "Tests cairo_set_line_width",
+ "stroke", /* keywords */
+ "target=raster", /* requirements */
+ IMAGE_WIDTH, IMAGE_HEIGHT,
+ NULL, draw_a1)
diff --git a/test/linear-gradient-extend.c b/test/linear-gradient-extend.c
new file mode 100644
index 000000000..b1328b425
--- /dev/null
+++ b/test/linear-gradient-extend.c
@@ -0,0 +1,92 @@
+/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */
+/*
+ * Copyright 2010 Andrea Canciani
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Andrea Canciani <ranma42@gmail.com>
+ */
+
+#include "cairo-test.h"
+
+#define NUM_EXTEND 4
+#define HEIGHT 16
+#define WIDTH 16
+#define PAD 3
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_pattern_t *pattern;
+ unsigned int i, j;
+
+ cairo_extend_t extend[NUM_EXTEND] = {
+ CAIRO_EXTEND_NONE,
+ CAIRO_EXTEND_REPEAT,
+ CAIRO_EXTEND_REFLECT,
+ CAIRO_EXTEND_PAD
+ };
+
+ cairo_test_paint_checkered (cr);
+
+ pattern = cairo_pattern_create_linear (0, 2*PAD, 0, HEIGHT - 2*PAD);
+
+ cairo_pattern_add_color_stop_rgb (pattern, 0, 0, 0, 1);
+ cairo_pattern_add_color_stop_rgb (pattern, 1, 0, 0, 1);
+
+ cairo_translate (cr, PAD, PAD);
+
+ for (i = 0; i < 2; i++) {
+ cairo_save (cr);
+
+ for (j = 0; j < NUM_EXTEND; j++) {
+ cairo_pattern_set_extend (pattern, extend[j]);
+
+ cairo_reset_clip (cr);
+ cairo_rectangle (cr, 0, 0, WIDTH, HEIGHT);
+ cairo_clip (cr);
+
+ if (i & 1) {
+ cairo_set_source_rgb (cr, 0, 1, 0);
+ cairo_mask (cr, pattern);
+ } else {
+ cairo_set_source (cr, pattern);
+ cairo_paint (cr);
+ }
+
+ cairo_translate (cr, WIDTH+PAD, 0);
+ }
+
+ cairo_restore (cr);
+ cairo_translate (cr, 0, HEIGHT+PAD);
+ }
+
+ cairo_pattern_destroy (pattern);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (linear_gradient_extend,
+ "Tests gradient to solid reduction of linear gradients",
+ "linear, pattern, extend", /* keywords */
+ NULL, /* requirements */
+ (WIDTH+PAD) * NUM_EXTEND + PAD, 2*(HEIGHT + PAD) + PAD,
+ NULL, draw)
diff --git a/test/linear-gradient-large.c b/test/linear-gradient-large.c
new file mode 100644
index 000000000..5646aa485
--- /dev/null
+++ b/test/linear-gradient-large.c
@@ -0,0 +1,68 @@
+/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */
+/*
+ * Copyright 2010 Krzysztof Kosiński
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Krzysztof Kosiński <tweenk.pl@gmail.com>
+ */
+
+#include "cairo-test.h"
+
+/* originally reported in https://bugs.freedesktop.org/show_bug.cgi?id=29470 */
+
+#define OFFSET 50
+#define SIZE 1000
+
+static void mark_point(cairo_t *ct, double x, double y)
+{
+ cairo_rectangle(ct, x-2, y-2, 4, 4);
+ cairo_set_source_rgb(ct, 1,0,0);
+ cairo_fill(ct);
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_pattern_t *gr = cairo_pattern_create_linear (SIZE - OFFSET, OFFSET,
+ OFFSET, SIZE - OFFSET);
+
+ cairo_pattern_add_color_stop_rgb (gr, 0.0, 1, 1, 1);
+ cairo_pattern_add_color_stop_rgb (gr, 0.0, 0, 0, 0);
+ cairo_pattern_add_color_stop_rgb (gr, 1.0, 0, 0, 0);
+ cairo_pattern_add_color_stop_rgb (gr, 1.0, 1, 1, 1);
+
+ cairo_set_source (cr, gr);
+ cairo_pattern_destroy (gr);
+ cairo_paint (cr);
+
+ mark_point(cr, SIZE - OFFSET, OFFSET);
+ mark_point(cr, OFFSET, SIZE - OFFSET);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (linear_gradient_large,
+ "Tests that large linear gradients get rendered at the correct place",
+ "linear, pattern", /* keywords */
+ NULL, /* requirements */
+ SIZE, SIZE,
+ NULL, draw)
diff --git a/test/linear-gradient-one-stop.c b/test/linear-gradient-one-stop.c
new file mode 100644
index 000000000..09c4b9d23
--- /dev/null
+++ b/test/linear-gradient-one-stop.c
@@ -0,0 +1,90 @@
+/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */
+/*
+ * Copyright 2010 Andrea Canciani
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Andrea Canciani <ranma42@gmail.com>
+ */
+
+#include "cairo-test.h"
+
+#define NUM_EXTEND 4
+#define HEIGHT 16
+#define WIDTH 16
+#define PAD 3
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_pattern_t *pattern;
+ unsigned int i, j;
+
+ cairo_extend_t extend[NUM_EXTEND] = {
+ CAIRO_EXTEND_NONE,
+ CAIRO_EXTEND_REPEAT,
+ CAIRO_EXTEND_REFLECT,
+ CAIRO_EXTEND_PAD
+ };
+
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+
+ cairo_translate (cr, PAD, PAD);
+
+ for (i = 0; i < 3; i++) {
+ cairo_save (cr);
+
+ for (j = 0; j < NUM_EXTEND; j++) {
+ cairo_reset_clip (cr);
+ cairo_rectangle (cr, 0, 0, WIDTH, HEIGHT);
+ cairo_clip (cr);
+
+ if (i == 0)
+ pattern = cairo_pattern_create_linear (0, 2*PAD, 0, HEIGHT - 2*PAD);
+ else if (i == 1)
+ pattern = cairo_pattern_create_linear (2*PAD, 2*PAD, HEIGHT - 2*PAD, HEIGHT - 2*PAD);
+ else if (i == 2)
+ pattern = cairo_pattern_create_linear (2*PAD, 0, HEIGHT - 2*PAD, 0);
+
+ cairo_pattern_add_color_stop_rgb (pattern, 0.25, 0, 0, 1);
+ cairo_pattern_set_extend (pattern, extend[j]);
+
+ cairo_set_source (cr, pattern);
+ cairo_paint (cr);
+
+ cairo_pattern_destroy (pattern);
+
+ cairo_translate (cr, WIDTH+PAD, 0);
+ }
+
+ cairo_restore (cr);
+ cairo_translate (cr, 0, HEIGHT+PAD);
+ }
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (linear_gradient_one_stop,
+ "Tests linear gradients with a single stop",
+ "gradient,linear,", /* keywords */
+ NULL, /* requirements */
+ (WIDTH+PAD) * NUM_EXTEND + PAD, 3*(HEIGHT + PAD) + PAD,
+ NULL, draw)
diff --git a/test/linear-gradient-reflect.c b/test/linear-gradient-reflect.c
new file mode 100644
index 000000000..8adb58784
--- /dev/null
+++ b/test/linear-gradient-reflect.c
@@ -0,0 +1,67 @@
+/*
+ * Copyright © 2007 Tim Rowley
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Tim Rowley
+ */
+
+#include "cairo-test.h"
+#include "stdio.h"
+
+#define WIDTH 50
+#define HEIGHT 50
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_pattern_t *pattern;
+
+ cairo_set_source_rgb (cr, 0.5, 0.5, 0.5);
+ cairo_paint (cr);
+
+ cairo_save (cr);
+
+ pattern = cairo_pattern_create_linear (0, 0, 10.0, 0);
+
+ cairo_pattern_add_color_stop_rgb (pattern, 0.0,
+ 0.0, 0.0, 1.0);
+ cairo_pattern_add_color_stop_rgb (pattern, 1.0,
+ 1.0, 0.0, 0.0);
+ cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REFLECT);
+
+ cairo_set_source (cr, pattern);
+ cairo_pattern_destroy (pattern);
+ cairo_rectangle (cr, 0.0, 0.0, WIDTH, HEIGHT);
+ cairo_fill (cr);
+
+ cairo_restore (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (linear_gradient_reflect,
+ "Tests the drawing of linear gradient with reflect",
+ "gradient", /* keywords */
+ NULL, /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw)
+
diff --git a/test/linear-gradient-subset.c b/test/linear-gradient-subset.c
new file mode 100644
index 000000000..ce05e6ec1
--- /dev/null
+++ b/test/linear-gradient-subset.c
@@ -0,0 +1,127 @@
+/*
+ * Copyright © 2005 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Owen Taylor <otaylor@redhat.com>
+ */
+
+#include "cairo-test.h"
+#include "stdio.h"
+
+/* The test matrix is
+ *
+ * A) Horizontal B) 5° C) 45° D) Vertical
+ * 1) Rotated 0° 2) Rotated 45° C) Rotated 90°
+ * a) 2 stop b) 3 stop
+ *
+ * A1a B1a C1a D1a
+ * A2a B2a C2a D2a
+ * A3a B3a C3a D3a
+ * A1b B1b C1b D1b
+ * A2b B2b C2b D2b
+ * A3b B3b C3b D3b
+ */
+
+static const double gradient_angles[] = { 0, 45, 90 };
+#define N_GRADIENT_ANGLES 3
+static const double rotate_angles[] = { 0, 45, 90 };
+#define N_ROTATE_ANGLES 3
+static const int n_stops[] = { 2, 3 };
+#define N_N_STOPS 2
+
+#define UNIT_SIZE 6
+#define UNIT_SIZE 6
+#define PAD 1
+
+#define WIDTH N_GRADIENT_ANGLES * UNIT_SIZE + (N_GRADIENT_ANGLES + 1) * PAD
+#define HEIGHT N_N_STOPS * N_ROTATE_ANGLES * UNIT_SIZE + (N_N_STOPS * N_ROTATE_ANGLES + 1) * PAD
+
+static void
+draw_unit (cairo_t *cr,
+ double gradient_angle,
+ double rotate_angle,
+ int n_stops)
+{
+ cairo_pattern_t *pattern;
+
+ cairo_rectangle (cr, 0, 0, 1, 1);
+ cairo_clip (cr);
+ cairo_new_path(cr);
+
+ cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
+ cairo_rectangle (cr, 0, 0, 1, 1);
+ cairo_fill (cr);
+
+ cairo_translate (cr, 0.5, 0.5);
+ cairo_scale (cr, 1 / 1.5, 1 / 1.5);
+ cairo_rotate (cr, rotate_angle);
+
+ pattern = cairo_pattern_create_linear (-0.5 * cos (gradient_angle), -0.5 * sin (gradient_angle),
+ 0.5 * cos (gradient_angle), 0.5 * sin (gradient_angle));
+
+ if (n_stops == 2) {
+ cairo_pattern_add_color_stop_rgb (pattern, 0.2, 0.3, 0.3, 0.3);
+ cairo_pattern_add_color_stop_rgb (pattern, 0.8, 1.0, 1.0, 1.0);
+ } else {
+ cairo_pattern_add_color_stop_rgb (pattern, 0.2, 1.0, 0.0, 0.0);
+ cairo_pattern_add_color_stop_rgb (pattern, 0.5, 1.0, 1.0, 1.0);
+ cairo_pattern_add_color_stop_rgb (pattern, 0.8, 0.0, 0.0, 1.0);
+ }
+
+ cairo_set_source (cr, pattern);
+ cairo_pattern_destroy (pattern);
+ cairo_rectangle (cr, -0.5, -0.5, 1, 1);
+ cairo_fill (cr);
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ int i, j, k;
+
+ cairo_set_source_rgb (cr, 0.5, 0.5, 0.5);
+ cairo_paint (cr);
+
+ for (i = 0; i < N_GRADIENT_ANGLES; i++)
+ for (j = 0; j < N_ROTATE_ANGLES; j++)
+ for (k = 0; k < N_N_STOPS; k++) {
+ cairo_save (cr);
+ cairo_translate (cr,
+ PAD + (PAD + UNIT_SIZE) * i,
+ PAD + (PAD + UNIT_SIZE) * (N_ROTATE_ANGLES * k + j));
+ cairo_scale (cr, UNIT_SIZE, UNIT_SIZE);
+
+ draw_unit (cr,
+ gradient_angles[i] * M_PI / 180.,
+ rotate_angles[j] * M_PI / 180.,
+ n_stops[k]);
+ cairo_restore (cr);
+ }
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (linear_gradient_subset,
+ "Tests the drawing of linear gradients",
+ "gradient", /* keywords */
+ NULL, /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw)
diff --git a/test/linear-gradient.c b/test/linear-gradient.c
new file mode 100644
index 000000000..054d6abbc
--- /dev/null
+++ b/test/linear-gradient.c
@@ -0,0 +1,132 @@
+/*
+ * Copyright © 2005 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Owen Taylor <otaylor@redhat.com>
+ */
+
+#include "cairo-test.h"
+#include "stdio.h"
+
+/* The test matrix is
+ *
+ * A) Horizontal B) 5° C) 45° D) Vertical
+ * 1) Rotated 0° 2) Rotated 45° C) Rotated 90°
+ * a) 2 stop b) 3 stop
+ *
+ * A1a B1a C1a D1a
+ * A2a B2a C2a D2a
+ * A3a B3a C3a D3a
+ * A1b B1b C1b D1b
+ * A2b B2b C2b D2b
+ * A3b B3b C3b D3b
+ */
+
+static const double gradient_angles[] = { 0, 45, 90 };
+#define N_GRADIENT_ANGLES 3
+static const double rotate_angles[] = { 0, 45, 90 };
+#define N_ROTATE_ANGLES 3
+static const int n_stops[] = { 2, 3 };
+#define N_N_STOPS 2
+
+#define UNIT_SIZE 6
+#define UNIT_SIZE 6
+#define PAD 1
+
+#define WIDTH N_GRADIENT_ANGLES * UNIT_SIZE + (N_GRADIENT_ANGLES + 1) * PAD
+#define HEIGHT N_N_STOPS * N_ROTATE_ANGLES * UNIT_SIZE + (N_N_STOPS * N_ROTATE_ANGLES + 1) * PAD
+
+static void
+draw_unit (cairo_t *cr,
+ double gradient_angle,
+ double rotate_angle,
+ int n_stops)
+{
+ cairo_pattern_t *pattern;
+
+ cairo_rectangle (cr, 0, 0, 1, 1);
+ cairo_clip (cr);
+ cairo_new_path(cr);
+
+ cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
+ cairo_rectangle (cr, 0, 0, 1, 1);
+ cairo_fill (cr);
+
+ cairo_translate (cr, 0.5, 0.5);
+ cairo_scale (cr, 1 / 1.5, 1 / 1.5);
+ cairo_rotate (cr, rotate_angle);
+
+ pattern = cairo_pattern_create_linear (-0.5 * cos (gradient_angle), -0.5 * sin (gradient_angle),
+ 0.5 * cos (gradient_angle), 0.5 * sin (gradient_angle));
+
+ if (n_stops == 2) {
+ cairo_pattern_add_color_stop_rgb (pattern, 0.,
+ 0.3, 0.3, 0.3);
+ cairo_pattern_add_color_stop_rgb (pattern, 1.,
+ 1.0, 1.0, 1.0);
+ } else {
+ cairo_pattern_add_color_stop_rgb (pattern, 0.,
+ 1.0, 0.0, 0.0);
+ cairo_pattern_add_color_stop_rgb (pattern, 0.5,
+ 1.0, 1.0, 1.0);
+ cairo_pattern_add_color_stop_rgb (pattern, 1.,
+ 0.0, 0.0, 1.0);
+ }
+
+ cairo_set_source (cr, pattern);
+ cairo_pattern_destroy (pattern);
+ cairo_rectangle (cr, -0.5, -0.5, 1, 1);
+ cairo_fill (cr);
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ int i, j, k;
+
+ cairo_set_source_rgb (cr, 0.5, 0.5, 0.5);
+ cairo_paint (cr);
+
+ for (i = 0; i < N_GRADIENT_ANGLES; i++)
+ for (j = 0; j < N_ROTATE_ANGLES; j++)
+ for (k = 0; k < N_N_STOPS; k++) {
+ cairo_save (cr);
+ cairo_translate (cr,
+ PAD + (PAD + UNIT_SIZE) * i,
+ PAD + (PAD + UNIT_SIZE) * (N_ROTATE_ANGLES * k + j));
+ cairo_scale (cr, UNIT_SIZE, UNIT_SIZE);
+
+ draw_unit (cr,
+ gradient_angles[i] * M_PI / 180.,
+ rotate_angles[j] * M_PI / 180.,
+ n_stops[k]);
+ cairo_restore (cr);
+ }
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (linear_gradient,
+ "Tests the drawing of linear gradients",
+ "gradient", /* keywords */
+ NULL, /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw)
diff --git a/test/linear-step-function.c b/test/linear-step-function.c
new file mode 100644
index 000000000..da7e8ca19
--- /dev/null
+++ b/test/linear-step-function.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright © 2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_pattern_t *pattern;
+
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ cairo_paint (cr);
+
+ pattern = cairo_pattern_create_linear (width/2, 0, width/2, 0);
+ cairo_pattern_add_color_stop_rgb (pattern, 0, 1, 0, 0);
+ cairo_pattern_add_color_stop_rgb (pattern, 1, 0, 0, 1);
+ cairo_set_source (cr, pattern);
+
+ cairo_pattern_set_extend (pattern, CAIRO_EXTEND_NONE); /* nothing */
+ cairo_rectangle (cr, 0, 0, width, height/2);
+ cairo_fill (cr);
+
+ cairo_pattern_set_extend (pattern, CAIRO_EXTEND_PAD); /* step */
+ cairo_rectangle (cr, 0, height/2, width, height/2);
+ cairo_fill (cr);
+
+ cairo_pattern_destroy (pattern);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (linear_step_function,
+ "Tests creating a step function using a linear gradient",
+ "gradient, linear", /* keywords */
+ NULL, /* requirements */
+ 40, 40,
+ NULL, draw)
diff --git a/test/linear-uniform.c b/test/linear-uniform.c
new file mode 100644
index 000000000..2f6553502
--- /dev/null
+++ b/test/linear-uniform.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright © 2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_pattern_t *pattern;
+
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ cairo_paint (cr);
+
+ /* with alpha */
+ pattern = cairo_pattern_create_linear (0, 0, 0, height);
+ cairo_pattern_add_color_stop_rgba (pattern, 0, 1, 1, 1, .5);
+ cairo_pattern_add_color_stop_rgba (pattern, 1, 1, 1, 1, .5);
+ cairo_set_source (cr, pattern);
+ cairo_pattern_destroy (pattern);
+ cairo_rectangle (cr, 0, 0, width/2, height);
+ cairo_fill (cr);
+
+ /* without alpha */
+ pattern = cairo_pattern_create_linear (0, 0, 0, height);
+ cairo_pattern_add_color_stop_rgb (pattern, 0, 1, 1, 1);
+ cairo_pattern_add_color_stop_rgb (pattern, 1, 1, 1, 1);
+ cairo_set_source (cr, pattern);
+ cairo_pattern_destroy (pattern);
+ cairo_rectangle (cr, width/2, 0, width/2, height);
+ cairo_fill (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (linear_uniform,
+ "Tests handling of \"solid\" linear gradients",
+ "gradient, linear", /* keywords */
+ NULL, /* requirements */
+ 40, 40,
+ NULL, draw)
diff --git a/test/long-dashed-lines.c b/test/long-dashed-lines.c
new file mode 100644
index 000000000..4d6ded9a5
--- /dev/null
+++ b/test/long-dashed-lines.c
@@ -0,0 +1,66 @@
+/*
+ * Copyright © 2008 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * the author not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. The author makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THE AUTHOR. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ int i;
+ double dashes[] = {6, 3};
+
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+ /* partially visible rectangle... */
+ cairo_rectangle (cr, -0.5, -0.5, 61, 61);
+
+ /* rectangles with intersecting segments... */
+ cairo_save (cr);
+ cairo_translate (cr, 30, 30);
+ for (i = 0; i < 4; i++) {
+ cairo_rotate (cr, M_PI / 4);
+ cairo_rectangle (cr, -37, -15, 74, 30);
+ }
+ cairo_restore (cr);
+
+ /* completely invisible rectangle */
+ cairo_rectangle (cr, -5, -5, 70, 70);
+
+ cairo_set_dash (cr, dashes, ARRAY_LENGTH (dashes), 0.);
+ cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
+ cairo_set_line_join (cr, CAIRO_LINE_JOIN_BEVEL);
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ cairo_stroke (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (long_dashed_lines,
+ "Exercises _cairo_box_intersects_line_segment()",
+ "dash, stroke, stress", /* keywords */
+ NULL, /* requirements */
+ 60, 60,
+ NULL, draw)
diff --git a/test/long-lines.c b/test/long-lines.c
new file mode 100644
index 000000000..69b64e9c4
--- /dev/null
+++ b/test/long-lines.c
@@ -0,0 +1,85 @@
+/*
+ * Copyright © 2005 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Carl D. Worth <cworth@cworth.org>
+ * Emmanuel Pacaud <emmanuel.pacaud@lapp.in2p3.fr>
+ */
+
+#include "cairo-test.h"
+
+#define LINE_WIDTH 1.
+#define SIZE 10
+#define LINE_NBR 6
+
+struct {
+ double length;
+ double red, green, blue;
+} lines[LINE_NBR] = {
+ { 100.0, 1.0, 0.0, 0.0 },
+ { 10000.0, 0.0, 1.0, 0.0 },
+ { 100000.0, 0.0, 0.0, 1.0 },
+ { 1000000.0, 1.0, 1.0, 0.0 },
+ { 10000000.0, 0.0, 1.0, 1.0 },
+ { 100000000.0, 1.0, 0.0, 1.0 }
+};
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ double pos;
+ int i;
+
+ /* We draw in the default black, so paint white first. */
+ cairo_save (cr);
+ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */
+ cairo_paint (cr);
+ cairo_restore (cr);
+
+ cairo_set_line_width (cr, LINE_WIDTH);
+
+ pos = SIZE + .5;
+ for (i = 0; i < LINE_NBR; i++) {
+ cairo_move_to (cr, pos, -lines[i].length);
+ cairo_line_to (cr, pos, +lines[i].length);
+ cairo_set_source_rgb (cr, lines[i].red, lines[i].green, lines[i].blue);
+ cairo_stroke (cr);
+ pos += SIZE;
+ }
+
+ /* This should display a perfect vertically centered black line */
+ cairo_move_to (cr, 0.5, -1e100);
+ cairo_line_to (cr, pos, 1e100);
+ cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
+ cairo_stroke (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+/* XFAIL: range overflow of fixed-point */
+CAIRO_TEST (long_lines,
+ "Test long lines"
+ "\nLong lines are not drawn due to the limitations of the internal 16.16 fixed-point coordinates",
+ "stroke, stress", /* keywords */
+ NULL, /* requirements */
+ SIZE * (LINE_NBR + 1), SIZE * (LINE_NBR + 1),
+ NULL, draw)
+
diff --git a/test/make-cairo-test-constructors.sh b/test/make-cairo-test-constructors.sh
new file mode 100644
index 000000000..cb1391e73
--- /dev/null
+++ b/test/make-cairo-test-constructors.sh
@@ -0,0 +1,29 @@
+#! /bin/sh
+
+if test $# -eq 0; then
+ echo "$0: no input files." >&2
+ exit 0
+fi
+
+cat <<HERE
+/* WARNING: Autogenerated file - see $0! */
+
+#include "cairo-test-private.h"
+
+void _cairo_test_runner_register_tests (void);
+
+HERE
+
+cat "$@" | sed '/^CAIRO_TEST/!d; s/CAIRO_TEST.*(\(.*\),.*/extern void _register_\1 (void);/'
+cat <<HERE
+
+void
+_cairo_test_runner_register_tests (void)
+{
+HERE
+
+cat "$@" | sed '/^CAIRO_TEST/!d; s/CAIRO_TEST.*(\(.*\),.*/ _register_\1 ();/'
+
+echo "}"
+
+
diff --git a/test/map-to-image.c b/test/map-to-image.c
new file mode 100644
index 000000000..0262245a8
--- /dev/null
+++ b/test/map-to-image.c
@@ -0,0 +1,156 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+#define WIDTH 3
+#define HEIGHT 3
+
+/* A single, black pixel */
+static const uint32_t black_pixel_argb = 0xff000000;
+static const uint32_t black_pixel = 0x00000000;
+
+static cairo_bool_t
+set_pixel_black(uint8_t *data, int stride,
+ cairo_format_t format, int x, int y)
+{
+ switch (format) {
+ case CAIRO_FORMAT_ARGB32:
+ case CAIRO_FORMAT_RGB24:
+ *(uint32_t *)(data + y * stride + 4*x) = black_pixel_argb;
+ break;
+ case CAIRO_FORMAT_RGB16_565:
+ *(uint16_t *)(data + y * stride + 2*x) = black_pixel;
+ break;
+ case CAIRO_FORMAT_RGB30:
+ case CAIRO_FORMAT_A8:
+ case CAIRO_FORMAT_A1:
+ case CAIRO_FORMAT_INVALID:
+ default:
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static cairo_test_status_t
+all (cairo_t *cr, int width, int height)
+{
+ cairo_surface_t *surface;
+ uint8_t *data;
+ int stride;
+ cairo_format_t format;
+ int i, j;
+
+ /* Fill background white */
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+ surface = cairo_surface_map_to_image (cairo_get_target (cr), NULL);
+ cairo_surface_flush (surface);
+ format = cairo_image_surface_get_format (surface);
+ stride = cairo_image_surface_get_stride (surface);
+ data = cairo_image_surface_get_data (surface);
+ if (data) {
+ for (j = 0; j < HEIGHT; j++)
+ for (i = 0; i < WIDTH; i++)
+ if (! set_pixel_black (data, stride, format, i, j))
+ return CAIRO_TEST_FAILURE;
+ }
+ cairo_surface_mark_dirty (surface);
+ cairo_surface_unmap_image (cairo_get_target (cr), surface);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+bit (cairo_t *cr, int width, int height)
+{
+ cairo_surface_t *surface;
+ cairo_rectangle_int_t extents;
+ cairo_format_t format;
+ uint8_t *data;
+
+ extents.x = extents.y = extents.width = extents.height = 1;
+
+ /* Fill background white */
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+ surface = cairo_surface_map_to_image (cairo_get_target (cr), &extents);
+ cairo_surface_flush (surface);
+ data = cairo_image_surface_get_data (surface);
+ format = cairo_image_surface_get_format (surface);
+ if (data) {
+ if (! set_pixel_black (data, 0, format, 0, 0))
+ return CAIRO_TEST_FAILURE;
+ }
+ cairo_surface_mark_dirty (surface);
+ cairo_surface_unmap_image (cairo_get_target (cr), surface);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+fill (cairo_t *cr, int width, int height)
+{
+ cairo_surface_t *surface;
+ cairo_rectangle_int_t extents;
+ cairo_t *cr2;
+
+ extents.x = extents.y = extents.width = extents.height = 1;
+
+ /* Fill background white */
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+ surface = cairo_surface_map_to_image (cairo_get_target (cr), &extents);
+ cr2 = cairo_create (surface);
+ cairo_set_source_rgb (cr2, 1, 0, 0);
+ cairo_paint (cr2);
+ cairo_destroy (cr2);
+ cairo_surface_unmap_image (cairo_get_target (cr), surface);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (map_all_to_image,
+ "Test maping a surface to an image and modifying it externally",
+ "image", /* keywords */
+ "target=raster", /* requirements */
+ WIDTH, HEIGHT,
+ NULL, all)
+CAIRO_TEST (map_bit_to_image,
+ "Test maping a surface to an image and modifying it externally",
+ "image", /* keywords */
+ "target=raster", /* requirements */
+ WIDTH, HEIGHT,
+ NULL, bit)
+CAIRO_TEST (map_to_image_fill,
+ "Test maping a surface to an image and modifying it externally",
+ "image", /* keywords */
+ "target=raster", /* requirements */
+ WIDTH, HEIGHT,
+ NULL, fill)
diff --git a/test/mask-alpha.c b/test/mask-alpha.c
new file mode 100644
index 000000000..d66e0ac13
--- /dev/null
+++ b/test/mask-alpha.c
@@ -0,0 +1,82 @@
+/*
+ * Copyright © 2007 Adrian Johnson
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Adrian Johnson <ajohnson@redneon.com>
+ */
+
+#include "cairo-test.h"
+
+#define SIZE 40
+#define PAD 2
+#define WIDTH (PAD + SIZE + PAD)
+#define HEIGHT WIDTH
+
+/* This test is designed to test that PDF viewers use the correct
+ * alpha values in an Alpha SMasks. Some viewers use the color values
+ * instead of the alpha. The test draws a triangle and rectangle in a
+ * group then draws the group using cairo_mask(). The mask consists of
+ * a circle with the rgba (0.4, 0.4, 0.4, 0.8) and the background rgba
+ * (0.8, 0.8, 0.8, 0.4).
+ */
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_pattern_t *pattern;
+
+ cairo_translate (cr, PAD, PAD);
+
+ /* mask */
+ cairo_push_group (cr);
+ cairo_set_source_rgba (cr, 0.8, 0.8, 0.8, 0.4);
+ cairo_paint (cr);
+ cairo_arc (cr, SIZE / 2, SIZE / 2, SIZE / 6, 0., 2. * M_PI);
+ cairo_set_source_rgba (cr, 0.4, 0.4, 0.4, 0.8);
+ cairo_fill (cr);
+ pattern = cairo_pop_group (cr);
+
+ /* source */
+ cairo_push_group (cr);
+ cairo_rectangle (cr, 0.3 * SIZE, 0.2 * SIZE, 0.5 * SIZE, 0.5 * SIZE);
+ cairo_set_source_rgb (cr, 0, 0, 1);
+ cairo_fill (cr);
+ cairo_move_to (cr, 0.0, 0.8 * SIZE);
+ cairo_rel_line_to (cr, 0.7 * SIZE, 0.0);
+ cairo_rel_line_to (cr, -0.375 * SIZE, -0.6 * SIZE);
+ cairo_close_path (cr);
+ cairo_set_source_rgb (cr, 0, 1, 0);
+ cairo_fill (cr);
+ cairo_pop_group_to_source (cr);
+
+ cairo_mask (cr, pattern);
+ cairo_pattern_destroy (pattern);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (mask_alpha,
+ "A simple test painting a group through a circle mask",
+ "mask, alpha", /* keywords */
+ NULL, /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw)
diff --git a/test/mask-ctm.c b/test/mask-ctm.c
new file mode 100644
index 000000000..205ab0691
--- /dev/null
+++ b/test/mask-ctm.c
@@ -0,0 +1,80 @@
+/*
+ * Copyright © 2005 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+#include "cairo-test.h"
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_surface_t *mask_surface;
+ cairo_pattern_t *mask;
+ uint32_t data[] = {
+ 0x80000000, 0x80000000,
+ 0x80000000, 0x80000000,
+ };
+ cairo_matrix_t matrix;
+
+ mask_surface = cairo_image_surface_create_for_data ((unsigned char *) data,
+ CAIRO_FORMAT_ARGB32, 2, 2, 8);
+ mask = cairo_pattern_create_for_surface (mask_surface);
+
+ cairo_set_source_rgb (cr, 1.0, 0, 0);
+
+ /* We can translate with the CTM, with the pattern matrix, or with
+ * both. */
+
+ /* 1. CTM alone. */
+ cairo_save (cr);
+ {
+ cairo_translate (cr, 2, 2);
+ cairo_mask (cr, mask);
+ }
+ cairo_restore (cr);
+
+ /* 2. Pattern matrix alone. */
+ cairo_matrix_init_translate (&matrix, -4, -4);
+ cairo_pattern_set_matrix (mask, &matrix);
+
+ cairo_mask (cr, mask);
+
+ /* 3. CTM + pattern matrix */
+ cairo_translate (cr, 2, 2);
+ cairo_mask (cr, mask);
+
+ cairo_pattern_destroy (mask);
+
+ cairo_surface_finish (mask_surface); /* data goes out of scope */
+ cairo_surface_destroy (mask_surface);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (mask_ctm,
+ "Test that cairo_mask is affected properly by the CTM",
+ "mask", /* keywords */
+ NULL, /* requirements */
+ 10, 10,
+ NULL, draw)
+
diff --git a/test/mask-glyphs.c b/test/mask-glyphs.c
new file mode 100644
index 000000000..2e7b70301
--- /dev/null
+++ b/test/mask-glyphs.c
@@ -0,0 +1,187 @@
+/*
+ * Copyright 2009 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Chris Wilson not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Chris Wilson makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+#include <assert.h>
+
+static const char *png_filename = "romedalen.png";
+
+#define WIDTH 800
+#define HEIGHT 600
+
+static cairo_status_t
+_image_to_glyphs (cairo_surface_t *image,
+ int channel,
+ int level,
+ cairo_scaled_font_t *scaled_font,
+ double tx, double ty,
+ cairo_glyph_t *glyphs,
+ int *num_glyphs)
+{
+ int width, height, stride;
+ const unsigned char *data;
+ int x, y, z, n;
+
+ width = cairo_image_surface_get_width (image);
+ height = cairo_image_surface_get_height (image);
+ stride = cairo_image_surface_get_stride (image);
+ data = cairo_image_surface_get_data (image);
+
+ n = 0;
+ for (y = 0; y < height; y++) {
+ const uint32_t *row = (uint32_t *) (data + y * stride);
+
+ for (x = 0; x < width; x++) {
+ z = (row[x] >> channel) & 0xff;
+ if (z == level) {
+ double xx, yy, zz;
+ char c = n % 26 + 'a';
+ int count = 1;
+ cairo_glyph_t *glyphs_p = &glyphs[n];
+ cairo_status_t status;
+
+ xx = 4 * (x - width/2.) + width/2.;
+ yy = 4 * (y - height/2.) + height/2.;
+
+ zz = z / 1000.;
+ xx = xx + zz*(width/2. - xx);
+ yy = yy + zz*(height/2. - yy);
+
+ cairo_scaled_font_text_to_glyphs (scaled_font,
+ tx + xx, ty + yy,
+ &c, 1,
+ &glyphs_p, &count,
+ NULL, NULL,
+ NULL);
+ status = cairo_scaled_font_status (scaled_font);
+ if (status)
+ return status;
+
+ assert (glyphs_p == &glyphs[n]);
+ assert (count == 1);
+ n++;
+ }
+ }
+ }
+
+ *num_glyphs = n;
+ return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_status_t
+_render_image (cairo_t *cr,
+ int width, int height,
+ cairo_surface_t *image)
+{
+ int ww, hh;
+ cairo_glyph_t *glyphs;
+ cairo_pattern_t *mask;
+ cairo_scaled_font_t *scaled_font;
+ double tx, ty;
+ const struct {
+ int shift;
+ double red;
+ double green;
+ double blue;
+ } channel[3] = {
+ { 0, 0.9, 0.3, 0.4 },
+ { 8, 0.4, 0.9, 0.3 },
+ { 16, 0.3, 0.4, 0.9 },
+ };
+ unsigned int n, i;
+
+ ww = cairo_image_surface_get_width (image);
+ hh = cairo_image_surface_get_height (image);
+
+ glyphs = cairo_glyph_allocate (ww * hh);
+ if (glyphs == NULL)
+ return CAIRO_STATUS_NO_MEMORY;
+
+ tx = (width - ww) / 2.;
+ ty = (height - hh) / 2.;
+
+ cairo_set_font_size (cr, 5);
+ scaled_font = cairo_get_scaled_font (cr);
+
+ for (i = 0; i < ARRAY_LENGTH (channel); i++) {
+ cairo_push_group_with_content (cr, CAIRO_CONTENT_ALPHA);
+ for (n = 0; n < 256; n++) {
+ cairo_status_t status;
+ int num_glyphs;
+
+ status = _image_to_glyphs (image, channel[i].shift, n,
+ scaled_font,
+ tx, ty, glyphs, &num_glyphs);
+ if (status) {
+ cairo_glyph_free (glyphs);
+ return status;
+ }
+
+ cairo_set_source_rgba (cr,
+ 0, 0, 0,
+ .15 + .85 * n / 255.);
+ cairo_show_glyphs (cr, glyphs, num_glyphs);
+ }
+ mask = cairo_pop_group (cr);
+ cairo_set_source_rgb (cr,
+ channel[i].red,
+ channel[i].green,
+ channel[i].blue);
+ cairo_mask (cr, mask);
+ cairo_pattern_destroy (mask);
+ }
+
+ cairo_glyph_free (glyphs);
+ return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ const cairo_test_context_t *ctx = cairo_test_get_context (cr);
+ cairo_surface_t *image;
+ cairo_status_t status;
+
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ cairo_paint (cr);
+
+ image = cairo_test_create_surface_from_png (ctx, png_filename);
+ status = cairo_surface_status (image);
+ if (status)
+ return cairo_test_status_from_status (ctx, status);
+
+ status = _render_image (cr, width, height, image);
+ cairo_surface_destroy (image);
+
+ return cairo_test_status_from_status (ctx, status);
+}
+
+CAIRO_TEST (mask_glyphs,
+ "Creates a mask using a distorted array of overlapping glyphs",
+ "mask, glyphs", /* keywords */
+ "slow", /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw)
diff --git a/test/mask-surface-ctm.c b/test/mask-surface-ctm.c
new file mode 100644
index 000000000..064de3c54
--- /dev/null
+++ b/test/mask-surface-ctm.c
@@ -0,0 +1,71 @@
+/*
+ * Copyright © 2005 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+#include "cairo-test.h"
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_surface_t *mask;
+ uint32_t data[] = {
+ 0x80000000, 0x80000000,
+ 0x80000000, 0x80000000,
+ };
+
+ mask = cairo_image_surface_create_for_data ((unsigned char *) data,
+ CAIRO_FORMAT_ARGB32, 2, 2, 8);
+
+ cairo_set_source_rgb (cr, 1.0, 0, 0);
+
+ /* We can translate with the CTM, with the mask_surface offset, or
+ * with both. */
+
+ /* 1. CTM alone. */
+ cairo_save (cr);
+ {
+ cairo_translate (cr, 2, 2);
+ cairo_mask_surface (cr, mask, 0, 0);
+ }
+ cairo_restore (cr);
+
+ /* 2. Offset alone. */
+ cairo_mask_surface (cr, mask, 4, 4);
+
+ /* 3. CTM + offset */
+ cairo_translate (cr, 2, 2);
+ cairo_mask_surface (cr, mask, 4, 4);
+
+ cairo_surface_finish (mask); /* data goes out of scope */
+ cairo_surface_destroy (mask);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (mask_surface_ctm,
+ "Test that cairo_mask_surface is affected properly by the CTM",
+ "mask", /* keywords */
+ NULL, /* requirements */
+ 10, 10,
+ NULL, draw)
diff --git a/test/mask-transformed-image.c b/test/mask-transformed-image.c
new file mode 100644
index 000000000..13c8fe7fc
--- /dev/null
+++ b/test/mask-transformed-image.c
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2008 Kai-Uwe Behrmann
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Kai-Uwe Behrmann not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Kai-Uwe Behrmann makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * KAI_UWE BEHRMANN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL KAI_UWE BEHRMANN BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Kai-Uwe Behrmann <ku.b@gmx.de>
+ * Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+static const char png_filename[] = "romedalen.png";
+
+static cairo_surface_t *
+create_mask (cairo_t *dst, int width, int height)
+{
+ cairo_surface_t *mask;
+ cairo_t *cr;
+
+ mask = cairo_image_surface_create (CAIRO_FORMAT_A8, width, height);
+ cr = cairo_create (mask);
+ cairo_surface_destroy (mask);
+
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+ cairo_rectangle (cr, width/4, height/4, width/2, height/2);
+ cairo_fill (cr);
+
+ mask = cairo_surface_reference (cairo_get_target (cr));
+ cairo_destroy (cr);
+
+ return mask;
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ const cairo_test_context_t *ctx = cairo_test_get_context (cr);
+ cairo_surface_t *image, *mask;
+
+ image = cairo_test_create_surface_from_png (ctx, png_filename);
+ mask = create_mask (cr, 40, 40);
+
+ /* opaque background */
+ cairo_paint (cr);
+
+ /* center */
+ cairo_translate (cr,
+ (width - cairo_image_surface_get_width (image)) / 2.,
+ (height - cairo_image_surface_get_height (image)) / 2.);
+
+ /* rotate 30 degree around the center */
+ cairo_translate (cr, width/2., height/2.);
+ cairo_rotate (cr, -30 * 2 * M_PI / 360);
+ cairo_translate (cr, -width/2., -height/2.);
+
+ /* place the image on our surface */
+ cairo_set_source_surface (cr, image, 0, 0);
+
+ /* reset the drawing matrix */
+ cairo_identity_matrix (cr);
+
+ /* fill nicely */
+ cairo_scale (cr, width / 40., height / 40.);
+
+ /* apply the mask */
+ cairo_mask_surface (cr, mask, 0, 0);
+
+ cairo_surface_destroy (mask);
+ cairo_surface_destroy (image);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (mask_transformed_image,
+ "Test that cairo_mask() is affected properly by the CTM and not the image",
+ "mask", /* keywords */
+ NULL, /* requirements */
+ 80, 80,
+ NULL, draw)
diff --git a/test/mask-transformed-similar.c b/test/mask-transformed-similar.c
new file mode 100644
index 000000000..c37deb2c0
--- /dev/null
+++ b/test/mask-transformed-similar.c
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2008 Kai-Uwe Behrmann
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Kai-Uwe Behrmann not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Kai-Uwe Behrmann makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * KAI_UWE BEHRMANN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL KAI_UWE BEHRMANN BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Kai-Uwe Behrmann <ku.b@gmx.de>
+ * Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+static const char png_filename[] = "romedalen.png";
+
+static cairo_surface_t *
+create_mask (cairo_t *dst, int width, int height)
+{
+ cairo_surface_t *mask;
+ cairo_t *cr;
+
+ mask = cairo_surface_create_similar (cairo_get_target (dst),
+ CAIRO_CONTENT_ALPHA,
+ width, height);
+ cr = cairo_create (mask);
+ cairo_surface_destroy (mask);
+
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+ cairo_rectangle (cr, width/4, height/4, width/2, height/2);
+ cairo_fill (cr);
+
+ mask = cairo_surface_reference (cairo_get_target (cr));
+ cairo_destroy (cr);
+
+ return mask;
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ const cairo_test_context_t *ctx = cairo_test_get_context (cr);
+ cairo_surface_t *image, *mask;
+
+ image = cairo_test_create_surface_from_png (ctx, png_filename);
+ mask = create_mask (cr, 40, 40);
+
+ /* opaque background */
+ cairo_paint (cr);
+
+ /* center */
+ cairo_translate (cr,
+ (width - cairo_image_surface_get_width (image)) / 2.,
+ (height - cairo_image_surface_get_height (image)) / 2.);
+
+ /* rotate 30 degree around the center */
+ cairo_translate (cr, width/2., height/2.);
+ cairo_rotate (cr, -30 * 2 * M_PI / 360);
+ cairo_translate (cr, -width/2., -height/2.);
+
+ /* place the image on our surface */
+ cairo_set_source_surface (cr, image, 0, 0);
+
+ /* reset the drawing matrix */
+ cairo_identity_matrix (cr);
+
+ /* fill nicely */
+ cairo_scale (cr, width / 40., height / 40.);
+
+ /* apply the mask */
+ cairo_mask_surface (cr, mask, 0, 0);
+
+ cairo_surface_destroy (mask);
+ cairo_surface_destroy (image);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (mask_transformed_similar,
+ "Test that cairo_mask() is affected properly by the CTM and not the image",
+ "mask", /* keywords */
+ NULL, /* requirements */
+ 80, 80,
+ NULL, draw)
diff --git a/test/mask.c b/test/mask.c
new file mode 100644
index 000000000..89f4c3cc2
--- /dev/null
+++ b/test/mask.c
@@ -0,0 +1,246 @@
+/*
+ * Copyright © 2005 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Owen Taylor <otaylor@redhat.com>
+ * Kristian Høgsberg <krh@redhat.com>
+ */
+
+#include "cairo-test.h"
+#include <math.h>
+#include <stdio.h>
+
+#define WIDTH 16
+#define HEIGHT 16
+#define PAD 2
+
+static const char *png_filename = "romedalen.png";
+static cairo_surface_t *image;
+
+static void
+set_solid_pattern (const cairo_test_context_t *ctx, cairo_t *cr, int x, int y)
+{
+ cairo_set_source_rgb (cr, 0, 0, 0.6);
+}
+
+static void
+set_translucent_pattern (const cairo_test_context_t *ctx, cairo_t *cr, int x, int y)
+{
+ cairo_set_source_rgba (cr, 0, 0, 0.6, 0.5);
+}
+
+static void
+set_gradient_pattern (const cairo_test_context_t *ctx, cairo_t *cr, int x, int y)
+{
+ cairo_pattern_t *pattern;
+
+ pattern =
+ cairo_pattern_create_linear (x, y, x + WIDTH, y + HEIGHT);
+ cairo_pattern_add_color_stop_rgba (pattern, 0, 1, 1, 1, 1);
+ cairo_pattern_add_color_stop_rgba (pattern, 1, 0, 0, 0.4, 1);
+ cairo_set_source (cr, pattern);
+ cairo_pattern_destroy (pattern);
+}
+
+static void
+set_image_pattern (const cairo_test_context_t *ctx, cairo_t *cr, int x, int y)
+{
+ cairo_pattern_t *pattern;
+
+ if (image == NULL || cairo_surface_status (image)) {
+ cairo_surface_destroy (image);
+ image = cairo_test_create_surface_from_png (ctx, png_filename);
+ }
+
+ pattern = cairo_pattern_create_for_surface (image);
+ cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT);
+ cairo_set_source (cr, pattern);
+ cairo_pattern_destroy (pattern);
+}
+
+static void
+mask_polygon (cairo_t *cr, int x, int y)
+{
+ cairo_surface_t *mask_surface;
+ cairo_t *cr2;
+
+ mask_surface = cairo_surface_create_similar (cairo_get_group_target (cr),
+ CAIRO_CONTENT_ALPHA,
+ WIDTH, HEIGHT);
+ cr2 = cairo_create (mask_surface);
+ cairo_surface_destroy (mask_surface);
+
+ cairo_save (cr2);
+ cairo_set_operator (cr2, CAIRO_OPERATOR_CLEAR);
+ cairo_paint (cr2);
+ cairo_restore (cr2);
+
+ cairo_set_source_rgb (cr2, 1, 1, 1); /* white */
+
+ cairo_new_path (cr2);
+ cairo_move_to (cr2, 0, 0);
+ cairo_line_to (cr2, 0, HEIGHT);
+ cairo_line_to (cr2, WIDTH / 2, 3 * HEIGHT / 4);
+ cairo_line_to (cr2, WIDTH, HEIGHT);
+ cairo_line_to (cr2, WIDTH, 0);
+ cairo_line_to (cr2, WIDTH / 2, HEIGHT / 4);
+ cairo_close_path (cr2);
+ cairo_fill (cr2);
+
+ cairo_mask_surface (cr, cairo_get_target (cr2), x, y);
+ cairo_destroy (cr2);
+}
+
+static void
+mask_alpha (cairo_t *cr, int x, int y)
+{
+ cairo_paint_with_alpha (cr, 0.75);
+}
+
+static void
+mask_gradient (cairo_t *cr, int x, int y)
+{
+ cairo_pattern_t *pattern;
+
+ pattern = cairo_pattern_create_linear (x, y,
+ x + WIDTH, y + HEIGHT);
+
+ cairo_pattern_add_color_stop_rgba (pattern,
+ 0,
+ 1, 1, 1, 1);
+ cairo_pattern_add_color_stop_rgba (pattern,
+ 1,
+ 1, 1, 1, 0);
+
+ cairo_mask (cr, pattern);
+
+ cairo_pattern_destroy (pattern);
+}
+
+static void
+clip_none (cairo_t *cr, int x, int y)
+{
+}
+
+static void
+clip_rects (cairo_t *cr, int x, int y)
+{
+ int height = HEIGHT / 3;
+
+ cairo_new_path (cr);
+ cairo_rectangle (cr, x, y, WIDTH, height);
+ cairo_rectangle (cr, x, y + 2 * height, WIDTH, height);
+ cairo_clip (cr);
+}
+
+static void
+clip_circle (cairo_t *cr, int x, int y)
+{
+ cairo_new_path (cr);
+ cairo_arc (cr, x + WIDTH / 2, y + HEIGHT / 2,
+ WIDTH / 2, 0, 2 * M_PI);
+ cairo_clip (cr);
+ cairo_new_path (cr);
+}
+
+static void (* const pattern_funcs[])(const cairo_test_context_t *ctx, cairo_t *cr, int x, int y) = {
+ set_solid_pattern,
+ set_translucent_pattern,
+ set_gradient_pattern,
+ set_image_pattern,
+};
+
+static void (* const mask_funcs[])(cairo_t *cr, int x, int y) = {
+ mask_alpha,
+ mask_gradient,
+ mask_polygon,
+};
+
+static void (* const clip_funcs[])(cairo_t *cr, int x, int y) = {
+ clip_none,
+ clip_rects,
+ clip_circle,
+};
+
+#define IMAGE_WIDTH (ARRAY_LENGTH (pattern_funcs) * (WIDTH + PAD) + PAD)
+#define IMAGE_HEIGHT (ARRAY_LENGTH (mask_funcs) * ARRAY_LENGTH (clip_funcs) * (HEIGHT + PAD) + PAD)
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ const cairo_test_context_t *ctx = cairo_test_get_context (cr);
+ cairo_surface_t *tmp_surface;
+ size_t i, j, k;
+ cairo_t *cr2;
+
+ /* Some of our drawing is unbounded, so we draw each test to
+ * a temporary surface and copy over.
+ */
+ tmp_surface = cairo_surface_create_similar (cairo_get_group_target (cr),
+ CAIRO_CONTENT_COLOR_ALPHA,
+ IMAGE_WIDTH, IMAGE_HEIGHT);
+ cr2 = cairo_create (tmp_surface);
+ cairo_surface_destroy (tmp_surface);
+
+ for (k = 0; k < ARRAY_LENGTH (clip_funcs); k++) {
+ for (j = 0; j < ARRAY_LENGTH (mask_funcs); j++) {
+ for (i = 0; i < ARRAY_LENGTH (pattern_funcs); i++) {
+ int x = i * (WIDTH + PAD) + PAD;
+ int y = (ARRAY_LENGTH (mask_funcs) * k + j) * (HEIGHT + PAD) + PAD;
+
+ /* Clear intermediate surface we are going to be drawing onto */
+ cairo_save (cr2);
+ cairo_set_operator (cr2, CAIRO_OPERATOR_CLEAR);
+ cairo_paint (cr2);
+ cairo_restore (cr2);
+
+ /* draw */
+ cairo_save (cr2);
+
+ clip_funcs[k] (cr2, x, y);
+ pattern_funcs[i] (ctx, cr2, x, y);
+ mask_funcs[j] (cr2, x, y);
+
+ cairo_restore (cr2);
+
+ /* Copy back to the main pixmap */
+ cairo_set_source_surface (cr, cairo_get_target (cr2), 0, 0);
+ cairo_rectangle (cr, x, y, WIDTH, HEIGHT);
+ cairo_fill (cr);
+ }
+ }
+ }
+
+ cairo_destroy (cr2);
+
+ cairo_surface_destroy (image);
+ image = NULL;
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (mask,
+ "Tests of cairo_mask",
+ "mask", /* keywords */
+ NULL, /* requirements */
+ IMAGE_WIDTH, IMAGE_HEIGHT,
+ NULL, draw)
+
diff --git a/test/mesh-pattern-accuracy.c b/test/mesh-pattern-accuracy.c
new file mode 100644
index 000000000..d1f60b2fa
--- /dev/null
+++ b/test/mesh-pattern-accuracy.c
@@ -0,0 +1,99 @@
+/*
+ * Copyright © 2009 Adrian Johnson
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Adrian Johnson <ajohnson@redneon.com>
+ */
+
+#include "cairo-test.h"
+#include <float.h>
+
+#define SIZE 256
+
+/* This test is designed to test the accuracy of the rendering of mesh
+ * patterns.
+ *
+ * Color accuracy is tested by a square patch covering the whole
+ * surface with black and white corners.
+ *
+ * Extents accuracy is checked by a small red square patch at the
+ * center of the surface which should measure 2x2 pixels.
+ */
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_pattern_t *pattern;
+ double offset;
+
+ cairo_test_paint_checkered (cr);
+
+ pattern = cairo_pattern_create_mesh ();
+
+ cairo_mesh_pattern_begin_patch (pattern);
+
+ cairo_mesh_pattern_move_to (pattern, 0, 0);
+ cairo_mesh_pattern_line_to (pattern, 1, 0);
+ cairo_mesh_pattern_line_to (pattern, 1, 1);
+ cairo_mesh_pattern_line_to (pattern, 0, 1);
+
+ cairo_mesh_pattern_set_corner_color_rgb (pattern, 0, 0, 0, 0);
+ cairo_mesh_pattern_set_corner_color_rgb (pattern, 1, 1, 1, 1);
+ cairo_mesh_pattern_set_corner_color_rgb (pattern, 2, 0, 0, 0);
+ cairo_mesh_pattern_set_corner_color_rgb (pattern, 3, 1, 1, 1);
+
+ cairo_mesh_pattern_end_patch (pattern);
+
+ cairo_mesh_pattern_begin_patch (pattern);
+
+ /* A small 1x1 red patch, that should be rendered as a 2x2 red
+ * square in the center of the image */
+
+ offset = 0.5 / SIZE;
+
+ cairo_mesh_pattern_move_to (pattern, 0.5 + offset, 0.5 + offset);
+ cairo_mesh_pattern_line_to (pattern, 0.5 + offset, 0.5 - offset);
+ cairo_mesh_pattern_line_to (pattern, 0.5 - offset, 0.5 - offset);
+ cairo_mesh_pattern_line_to (pattern, 0.5 - offset, 0.5 + offset);
+
+ cairo_mesh_pattern_set_corner_color_rgb (pattern, 0, 1, 0, 0);
+ cairo_mesh_pattern_set_corner_color_rgb (pattern, 1, 1, 0, 0);
+ cairo_mesh_pattern_set_corner_color_rgb (pattern, 2, 1, 0, 0);
+ cairo_mesh_pattern_set_corner_color_rgb (pattern, 3, 1, 0, 0);
+
+ cairo_mesh_pattern_end_patch (pattern);
+
+ cairo_scale (cr, SIZE, SIZE);
+
+ cairo_set_source (cr, pattern);
+ cairo_paint (cr);
+ cairo_pattern_destroy (pattern);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (mesh_pattern_accuracy,
+ "Paint mesh pattern",
+ "mesh, pattern", /* keywords */
+ NULL, /* requirements */
+ SIZE, SIZE,
+ NULL, draw)
diff --git a/test/mesh-pattern-conical.c b/test/mesh-pattern-conical.c
new file mode 100644
index 000000000..4e87eec66
--- /dev/null
+++ b/test/mesh-pattern-conical.c
@@ -0,0 +1,135 @@
+/*
+ * Copyright © 2009 Adrian Johnson
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Adrian Johnson <ajohnson@redneon.com>
+ */
+
+#include "cairo-test.h"
+#include <math.h>
+
+#define PAT_WIDTH 100
+#define PAT_HEIGHT 100
+#define SIZE PAT_WIDTH
+#define PAD 2
+#define WIDTH (PAD + SIZE + PAD)
+#define HEIGHT WIDTH
+
+
+/*
+ * This test is designed to paint a mesh pattern which contains 8
+ * circular sectors approximating a conical gradient.
+ */
+
+#define CENTER_X 50
+#define CENTER_Y 50
+#define RADIUS 50
+
+static void
+sector_patch (cairo_pattern_t *pattern,
+ double angle_A,
+ double A_r, double A_g, double A_b,
+ double angle_B,
+ double B_r, double B_g, double B_b)
+{
+ double r_sin_A, r_cos_A;
+ double r_sin_B, r_cos_B;
+ double h;
+
+ r_sin_A = RADIUS * sin (angle_A);
+ r_cos_A = RADIUS * cos (angle_A);
+ r_sin_B = RADIUS * sin (angle_B);
+ r_cos_B = RADIUS * cos (angle_B);
+
+ h = 4.0/3.0 * tan ((angle_B - angle_A) / 4.0);
+
+ cairo_mesh_pattern_begin_patch (pattern);
+
+ cairo_mesh_pattern_move_to (pattern, CENTER_X, CENTER_Y);
+ cairo_mesh_pattern_line_to (pattern,
+ CENTER_X + r_cos_A,
+ CENTER_Y + r_sin_A);
+
+ cairo_mesh_pattern_curve_to (pattern,
+ CENTER_X + r_cos_A - h * r_sin_A,
+ CENTER_Y + r_sin_A + h * r_cos_A,
+ CENTER_X + r_cos_B + h * r_sin_B,
+ CENTER_Y + r_sin_B - h * r_cos_B,
+ CENTER_X + r_cos_B,
+ CENTER_Y + r_sin_B);
+
+ cairo_mesh_pattern_set_corner_color_rgb (pattern, 0, 1, 1, 1);
+ cairo_mesh_pattern_set_corner_color_rgb (pattern, 1, A_r, A_g, A_b);
+ cairo_mesh_pattern_set_corner_color_rgb (pattern, 2, B_r, B_g, B_b);
+
+ cairo_mesh_pattern_end_patch (pattern);
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_pattern_t *pattern;
+
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+ cairo_translate (cr, PAD, PAD);
+
+ pattern = cairo_pattern_create_mesh ();
+ sector_patch (pattern,
+ 0, 1, 0, 0,
+ M_PI/4, 1, 1, 0);
+ sector_patch (pattern,
+ M_PI/4, 0, 1, 0,
+ M_PI/2, 0, 1, 1);
+ sector_patch (pattern,
+ M_PI/2, 0, 0, 1,
+ 3*M_PI/4, 1, 0, 1);
+ sector_patch (pattern,
+ 3*M_PI/4, 1, 0, 0,
+ M_PI, 1, 1, 0);
+ sector_patch (pattern,
+ -M_PI, 1, 1, 0,
+ -3*M_PI/4, 0, 1, 0);
+ sector_patch (pattern,
+ -3*M_PI/4, 0, 1, 0,
+ -M_PI/2, 0, 1, 1);
+ sector_patch (pattern,
+ -M_PI/2, 0, 1, 1,
+ -M_PI/4, 0, 0, 1);
+ sector_patch (pattern,
+ -M_PI/4, 0, 0, 1,
+ 0, 1, 0, 0);
+
+ cairo_set_source (cr, pattern);
+ cairo_paint (cr);
+ cairo_pattern_destroy (pattern);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (mesh_pattern_conical,
+ "Paint a conical pattern using a mesh pattern",
+ "conical, mesh, pattern", /* keywords */
+ NULL, /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw)
diff --git a/test/mesh-pattern-control-points.c b/test/mesh-pattern-control-points.c
new file mode 100644
index 000000000..057e7a1f6
--- /dev/null
+++ b/test/mesh-pattern-control-points.c
@@ -0,0 +1,114 @@
+/*
+ * Copyright © 2009 Adrian Johnson
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Adrian Johnson <ajohnson@redneon.com>
+ */
+
+#include "cairo-test.h"
+
+#define SIZE 90
+#define PAD 10
+#define WIDTH (PAD + 2 * (SIZE + PAD))
+#define HEIGHT (PAD + SIZE + PAD)
+
+
+/*
+ * This test is designed to paint a two mesh patches. One with default
+ * control points and one with a control point at a no default
+ * location. The control points of both of them are drawn as squares
+ * to make them visible.
+ */
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_pattern_t *pattern;
+ unsigned int i, j;
+ unsigned int num_patches;
+ double x, y;
+
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+ cairo_translate (cr, PAD, PAD);
+
+ pattern = cairo_pattern_create_mesh ();
+ cairo_mesh_pattern_begin_patch (pattern);
+
+ cairo_mesh_pattern_move_to (pattern, 0, 0);
+ cairo_mesh_pattern_line_to (pattern, SIZE, 0);
+ cairo_mesh_pattern_line_to (pattern, SIZE, SIZE);
+ cairo_mesh_pattern_line_to (pattern, 0, SIZE);
+
+ cairo_mesh_pattern_set_corner_color_rgb (pattern, 0, 1, 0, 0);
+ cairo_mesh_pattern_set_corner_color_rgb (pattern, 1, 0, 1, 0);
+ cairo_mesh_pattern_set_corner_color_rgb (pattern, 2, 0, 0, 1);
+ cairo_mesh_pattern_set_corner_color_rgb (pattern, 3, 1, 1, 0);
+
+ cairo_mesh_pattern_set_control_point (pattern, 0, SIZE * .7, SIZE * .7);
+ cairo_mesh_pattern_set_control_point (pattern, 1, SIZE * .9, SIZE * .7);
+ cairo_mesh_pattern_set_control_point (pattern, 2, SIZE * .9, SIZE * .9);
+ cairo_mesh_pattern_set_control_point (pattern, 3, SIZE * .7, SIZE * .9);
+
+ cairo_mesh_pattern_end_patch (pattern);
+
+ cairo_mesh_pattern_begin_patch (pattern);
+
+ cairo_mesh_pattern_move_to (pattern, SIZE + PAD, 0);
+ cairo_mesh_pattern_line_to (pattern, 2*SIZE + PAD, 0);
+ cairo_mesh_pattern_line_to (pattern, 2*SIZE + PAD, SIZE);
+ cairo_mesh_pattern_line_to (pattern, SIZE + PAD, SIZE);
+
+ cairo_mesh_pattern_set_corner_color_rgb (pattern, 0, 1, 0, 0);
+ cairo_mesh_pattern_set_corner_color_rgb (pattern, 1, 0, 1, 0);
+ cairo_mesh_pattern_set_corner_color_rgb (pattern, 2, 0, 0, 1);
+ cairo_mesh_pattern_set_corner_color_rgb (pattern, 3, 1, 1, 0);
+
+ cairo_mesh_pattern_end_patch (pattern);
+
+ cairo_set_source (cr, pattern);
+ cairo_paint (cr);
+
+ /* mark the location of the control points */
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ cairo_mesh_pattern_get_patch_count (pattern, &num_patches);
+ for (i = 0; i < num_patches; i++) {
+ for (j = 0; j < 4; j++) {
+ cairo_mesh_pattern_get_control_point (pattern, i, j, &x, &y);
+ cairo_rectangle (cr, x - 5, y - 5, 10, 10);
+ cairo_fill (cr);
+ }
+ }
+
+ cairo_pattern_destroy (pattern);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+
+CAIRO_TEST (mesh_pattern_control_points,
+ "Paint mesh pattern with non default control points",
+ "mesh, pattern", /* keywords */
+ NULL, /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw)
diff --git a/test/mesh-pattern-fold.c b/test/mesh-pattern-fold.c
new file mode 100644
index 000000000..cacd712e7
--- /dev/null
+++ b/test/mesh-pattern-fold.c
@@ -0,0 +1,82 @@
+/*
+ * Copyright © 2009 Adrian Johnson
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Adrian Johnson <ajohnson@redneon.com>
+ */
+
+#include "cairo-test.h"
+
+#define SIZE 100
+#define PAD 15
+#define WIDTH (5*SIZE)
+#define HEIGHT (5*SIZE)
+
+
+/* This test is designed to paint a mesh pattern which folds along
+ * both parameters. */
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_pattern_t *pattern;
+
+ cairo_test_paint_checkered (cr);
+
+ pattern = cairo_pattern_create_mesh ();
+
+ cairo_mesh_pattern_begin_patch (pattern);
+
+ cairo_mesh_pattern_move_to (pattern, 1, 1);
+
+ cairo_mesh_pattern_curve_to (pattern, 6, 0, -1, 0, 4, 1);
+ cairo_mesh_pattern_curve_to (pattern, 5, 6, 5, -1, 4, 4);
+ cairo_mesh_pattern_curve_to (pattern, -1, 3, 6, 3, 1, 4);
+ cairo_mesh_pattern_curve_to (pattern, 2, -1, 2, 6, 1, 1);
+
+ cairo_mesh_pattern_set_control_point (pattern, 0, 2, 3);
+ cairo_mesh_pattern_set_control_point (pattern, 1, 3, 3);
+ cairo_mesh_pattern_set_control_point (pattern, 2, 3, 2);
+ cairo_mesh_pattern_set_control_point (pattern, 3, 2, 2);
+
+ cairo_mesh_pattern_set_corner_color_rgb (pattern, 0, 1, 0, 0);
+ cairo_mesh_pattern_set_corner_color_rgb (pattern, 1, 0, 0, 1);
+ cairo_mesh_pattern_set_corner_color_rgb (pattern, 2, 0, 0, 0);
+ cairo_mesh_pattern_set_corner_color_rgb (pattern, 3, 0, 1, 0);
+
+ cairo_mesh_pattern_end_patch (pattern);
+
+ cairo_scale (cr, SIZE, SIZE);
+
+ cairo_set_source (cr, pattern);
+ cairo_paint (cr);
+ cairo_pattern_destroy (pattern);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (mesh_pattern_fold,
+ "Paint a mesh pattern with complex folds",
+ "mesh, pattern", /* keywords */
+ NULL, /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw)
diff --git a/test/mesh-pattern-overlap.c b/test/mesh-pattern-overlap.c
new file mode 100644
index 000000000..969bc73a3
--- /dev/null
+++ b/test/mesh-pattern-overlap.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright © 2009 Adrian Johnson
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Adrian Johnson <ajohnson@redneon.com>
+ */
+
+#include "cairo-test.h"
+
+#define SIZE 100
+#define PAD 15
+#define WIDTH (PAD + SIZE + PAD)
+#define HEIGHT WIDTH
+
+
+/* This test is designed to paint a mesh pattern with a simple
+ * fold. */
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_pattern_t *pattern;
+
+ cairo_test_paint_checkered (cr);
+
+ cairo_translate (cr, PAD, PAD);
+
+ pattern = cairo_pattern_create_mesh ();
+
+ cairo_mesh_pattern_begin_patch (pattern);
+
+ cairo_mesh_pattern_move_to (pattern, 0, 0);
+ cairo_mesh_pattern_curve_to (pattern, 30, -30, 60, 30, 100, 0);
+ cairo_mesh_pattern_curve_to (pattern, 130, 140, 60, -40, 100, 100);
+ cairo_mesh_pattern_curve_to (pattern, 60, 70, 30, 130, 0, 100);
+ cairo_mesh_pattern_curve_to (pattern, -30, -40, 30, 140, 0, 0);
+
+ cairo_mesh_pattern_set_corner_color_rgb (pattern, 0, 1, 0, 0);
+ cairo_mesh_pattern_set_corner_color_rgb (pattern, 1, 0, 1, 0);
+ cairo_mesh_pattern_set_corner_color_rgb (pattern, 2, 0, 0, 1);
+ cairo_mesh_pattern_set_corner_color_rgb (pattern, 3, 1, 1, 0);
+
+ cairo_mesh_pattern_end_patch (pattern);
+
+ cairo_set_source (cr, pattern);
+ cairo_paint (cr);
+ cairo_pattern_destroy (pattern);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (mesh_pattern_overlap,
+ "Paint a mesh pattern with a simple fold",
+ "mesh, pattern", /* keywords */
+ NULL, /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw)
diff --git a/test/mesh-pattern-transformed.c b/test/mesh-pattern-transformed.c
new file mode 100644
index 000000000..5fe0dc048
--- /dev/null
+++ b/test/mesh-pattern-transformed.c
@@ -0,0 +1,107 @@
+/*
+ * Copyright © 2009 Adrian Johnson
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Adrian Johnson <ajohnson@redneon.com>
+ */
+
+#include "cairo-test.h"
+
+#define PAT_WIDTH 170
+#define PAT_HEIGHT 170
+#define SIZE PAT_WIDTH
+#define PAD 10
+#define WIDTH 190
+#define HEIGHT 140
+
+
+/* This test is designed to paint a mesh pattern containing two
+ * overlapping patches transformed in different ways. */
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_pattern_t *pattern;
+
+ cairo_test_paint_checkered (cr);
+
+ cairo_translate (cr, PAD, PAD);
+
+ pattern = cairo_pattern_create_mesh ();
+
+ cairo_mesh_pattern_begin_patch (pattern);
+
+ cairo_mesh_pattern_move_to (pattern, 0, 0);
+ cairo_mesh_pattern_curve_to (pattern, 30, -30, 60, 30, 100, 0);
+ cairo_mesh_pattern_curve_to (pattern, 60, 30, 130, 60, 100, 100);
+ cairo_mesh_pattern_curve_to (pattern, 60, 70, 30, 130, 0, 100);
+ cairo_mesh_pattern_curve_to (pattern, 30, 70, -30, 30, 0, 0);
+
+ cairo_mesh_pattern_set_corner_color_rgb (pattern, 0, 1, 0, 0);
+ cairo_mesh_pattern_set_corner_color_rgb (pattern, 1, 0, 1, 0);
+ cairo_mesh_pattern_set_corner_color_rgb (pattern, 2, 0, 0, 1);
+ cairo_mesh_pattern_set_corner_color_rgb (pattern, 3, 1, 1, 0);
+
+ cairo_mesh_pattern_end_patch (pattern);
+
+ cairo_mesh_pattern_begin_patch (pattern);
+
+ cairo_mesh_pattern_move_to (pattern, 50, 50);
+ cairo_mesh_pattern_curve_to (pattern, 80, 20, 110, 80, 150, 50);
+
+ cairo_mesh_pattern_curve_to (pattern, 110, 80, 180, 110, 150, 150);
+
+ cairo_mesh_pattern_curve_to (pattern, 110, 120, 80, 180, 50, 150);
+
+ cairo_mesh_pattern_curve_to (pattern, 80, 120, 20, 80, 50, 50);
+
+ cairo_mesh_pattern_set_corner_color_rgba (pattern, 0, 1, 0, 0, 0.3);
+ cairo_mesh_pattern_set_corner_color_rgb (pattern, 1, 0, 1, 0);
+ cairo_mesh_pattern_set_corner_color_rgba (pattern, 2, 0, 0, 1, 0.3);
+ cairo_mesh_pattern_set_corner_color_rgb (pattern, 3, 1, 1, 0);
+
+ cairo_mesh_pattern_end_patch (pattern);
+
+ cairo_scale (cr, .5, .5);
+
+ cairo_set_source (cr, pattern);
+ cairo_paint (cr);
+
+ cairo_translate (cr, PAT_WIDTH, PAT_HEIGHT);
+ cairo_translate (cr, PAT_WIDTH/2, PAT_HEIGHT/2);
+ cairo_rotate (cr, M_PI/4);
+ cairo_translate (cr, -PAT_WIDTH, -PAT_HEIGHT);
+ cairo_set_source (cr, pattern);
+ cairo_paint (cr);
+
+ cairo_pattern_destroy (pattern);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (mesh_pattern_transformed,
+ "Paint mesh pattern with a transformation",
+ "mesh, pattern", /* keywords */
+ NULL, /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw)
+
diff --git a/test/mesh-pattern.c b/test/mesh-pattern.c
new file mode 100644
index 000000000..eccbd389a
--- /dev/null
+++ b/test/mesh-pattern.c
@@ -0,0 +1,94 @@
+/*
+ * Copyright © 2009 Adrian Johnson
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Adrian Johnson <ajohnson@redneon.com>
+ */
+
+#include "cairo-test.h"
+
+#define PAT_WIDTH 170
+#define PAT_HEIGHT 170
+#define SIZE PAT_WIDTH
+#define PAD 2
+#define WIDTH (PAD + SIZE + PAD)
+#define HEIGHT WIDTH
+
+
+/* This test is designed to paint a mesh pattern. The mesh contains
+ * two overlapping patches */
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_pattern_t *pattern;
+
+ cairo_test_paint_checkered (cr);
+
+ cairo_translate (cr, PAD, PAD);
+ cairo_translate (cr, 10, 10);
+
+ pattern = cairo_pattern_create_mesh ();
+
+ cairo_mesh_pattern_begin_patch (pattern);
+
+ cairo_mesh_pattern_move_to (pattern, 0, 0);
+ cairo_mesh_pattern_curve_to (pattern, 30, -30, 60, 30, 100, 0);
+ cairo_mesh_pattern_curve_to (pattern, 60, 30, 130, 60, 100, 100);
+ cairo_mesh_pattern_curve_to (pattern, 60, 70, 30, 130, 0, 100);
+ cairo_mesh_pattern_curve_to (pattern, 30, 70, -30, 30, 0, 0);
+
+ cairo_mesh_pattern_set_corner_color_rgb (pattern, 0, 1, 0, 0);
+ cairo_mesh_pattern_set_corner_color_rgb (pattern, 1, 0, 1, 0);
+ cairo_mesh_pattern_set_corner_color_rgb (pattern, 2, 0, 0, 1);
+ cairo_mesh_pattern_set_corner_color_rgb (pattern, 3, 1, 1, 0);
+
+ cairo_mesh_pattern_end_patch (pattern);
+
+ cairo_mesh_pattern_begin_patch (pattern);
+
+ cairo_mesh_pattern_move_to (pattern, 50, 50);
+ cairo_mesh_pattern_curve_to (pattern, 80, 20, 110, 80, 150, 50);
+ cairo_mesh_pattern_curve_to (pattern, 110, 80, 180, 110, 150, 150);
+ cairo_mesh_pattern_curve_to (pattern, 110, 120, 80, 180, 50, 150);
+ cairo_mesh_pattern_curve_to (pattern, 80, 120, 20, 80, 50, 50);
+
+ cairo_mesh_pattern_set_corner_color_rgba (pattern, 0, 1, 0, 0, 0.3);
+ cairo_mesh_pattern_set_corner_color_rgb (pattern, 1, 0, 1, 0);
+ cairo_mesh_pattern_set_corner_color_rgba (pattern, 2, 0, 0, 1, 0.3);
+ cairo_mesh_pattern_set_corner_color_rgb (pattern, 3, 1, 1, 0);
+
+ cairo_mesh_pattern_end_patch (pattern);
+
+ cairo_set_source (cr, pattern);
+ cairo_paint (cr);
+ cairo_pattern_destroy (pattern);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (mesh_pattern,
+ "Paint mesh pattern",
+ "mesh, pattern", /* keywords */
+ NULL, /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw)
diff --git a/test/mime-data.c b/test/mime-data.c
new file mode 100644
index 000000000..c744f5c9b
--- /dev/null
+++ b/test/mime-data.c
@@ -0,0 +1,241 @@
+/*
+ * Copyright © 2008 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Chris Wilson not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Chris Wilson makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+#include <stdio.h>
+#include <errno.h>
+
+/* Basic test to exercise the new mime-data embedding. */
+
+static cairo_status_t
+read_file (const cairo_test_context_t *ctx,
+ const char *filename,
+ unsigned char **data_out,
+ unsigned int *length_out)
+{
+ FILE *file;
+ unsigned char *buf;
+ unsigned int len;
+
+ file = fopen (filename, "rb");
+ if (file == NULL) {
+ char path[4096];
+
+ if (errno == ENOMEM)
+ return CAIRO_STATUS_NO_MEMORY;
+
+ /* try again with srcdir */
+ snprintf (path, sizeof (path),
+ "%s/%s", ctx->srcdir, filename);
+ file = fopen (path, "rb");
+ }
+ if (file == NULL) {
+ switch (errno) {
+ case ENOMEM:
+ return CAIRO_STATUS_NO_MEMORY;
+ default:
+ return CAIRO_STATUS_FILE_NOT_FOUND;
+ }
+ }
+
+ fseek (file, 0, SEEK_END);
+ len = ftell (file);
+ fseek (file, 0, SEEK_SET);
+
+ buf = xmalloc (len);
+ *length_out = fread (buf, 1, len, file);
+ fclose (file);
+ if (*length_out != len) {
+ free (buf);
+ return CAIRO_STATUS_READ_ERROR;
+ }
+
+ *data_out = buf;
+ return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_test_status_t
+paint_file (cairo_t *cr,
+ const char *filename, const char *mime_type,
+ int x, int y)
+{
+ const cairo_test_context_t *ctx = cairo_test_get_context (cr);
+ cairo_surface_t *image;
+ unsigned char *mime_data;
+ unsigned int mime_length;
+ cairo_status_t status;
+
+ /* Deliberately use a non-matching MIME images, so that we can identify
+ * when the MIME representation is used in preference to the plain image
+ * surface.
+ */
+ status = read_file (ctx, filename, &mime_data, &mime_length);
+ if (status)
+ return cairo_test_status_from_status (ctx, status);
+
+ image = cairo_image_surface_create (CAIRO_FORMAT_RGB24, 200, 50);
+
+ status = cairo_surface_set_mime_data (image, mime_type,
+ mime_data, mime_length,
+ free, mime_data);
+ if (status) {
+ cairo_surface_destroy (image);
+ free (mime_data);
+ return cairo_test_status_from_status (ctx, status);
+ }
+
+ cairo_set_source_surface (cr, image, x, y);
+ cairo_surface_destroy (image);
+
+ cairo_paint (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+paint_jbig2_file (cairo_t *cr, int x, int y)
+{
+ const cairo_test_context_t *ctx = cairo_test_get_context (cr);
+ cairo_surface_t *image;
+ unsigned char *mime_data;
+ unsigned int mime_length;
+ cairo_status_t status;
+ const char jbig2_image1_filename[] = "image1.jb2";
+ const char jbig2_image2_filename[] = "image2.jb2";
+ const char jbig2_global_filename[] = "global.jb2";
+
+ /* Deliberately use a non-matching MIME images, so that we can identify
+ * when the MIME representation is used in preference to the plain image
+ * surface.
+ */
+
+ /* Image 1 */
+
+ status = read_file (ctx, jbig2_image1_filename, &mime_data, &mime_length);
+ if (status)
+ return cairo_test_status_from_status (ctx, status);
+
+ image = cairo_image_surface_create (CAIRO_FORMAT_RGB24, 200, 50);
+
+ status = cairo_surface_set_mime_data (image, CAIRO_MIME_TYPE_JBIG2_GLOBAL_ID,
+ (unsigned char *)"global", 6, NULL, NULL);
+ if (status) {
+ cairo_surface_destroy (image);
+ return cairo_test_status_from_status (ctx, status);
+ }
+
+ status = cairo_surface_set_mime_data (image, CAIRO_MIME_TYPE_JBIG2,
+ mime_data, mime_length,
+ free, mime_data);
+ if (status) {
+ cairo_surface_destroy (image);
+ free (mime_data);
+ return cairo_test_status_from_status (ctx, status);
+ }
+
+ cairo_set_source_surface (cr, image, x, y);
+ cairo_surface_destroy (image);
+
+ cairo_paint (cr);
+
+ /* Image 2 */
+
+ status = read_file (ctx, jbig2_image2_filename, &mime_data, &mime_length);
+ if (status)
+ return cairo_test_status_from_status (ctx, status);
+
+ image = cairo_image_surface_create (CAIRO_FORMAT_RGB24, 200, 50);
+
+ status = cairo_surface_set_mime_data (image, CAIRO_MIME_TYPE_JBIG2_GLOBAL_ID,
+ (unsigned char *)"global", 6, NULL, NULL);
+ if (status) {
+ cairo_surface_destroy (image);
+ return cairo_test_status_from_status (ctx, status);
+ }
+
+ status = cairo_surface_set_mime_data (image, CAIRO_MIME_TYPE_JBIG2,
+ mime_data, mime_length,
+ free, mime_data);
+ if (status) {
+ cairo_surface_destroy (image);
+ free (mime_data);
+ return cairo_test_status_from_status (ctx, status);
+ }
+
+ /* Set the global data */
+ status = read_file (ctx, jbig2_global_filename, &mime_data, &mime_length);
+ if (status)
+ return cairo_test_status_from_status (ctx, status);
+
+ status = cairo_surface_set_mime_data (image, CAIRO_MIME_TYPE_JBIG2_GLOBAL,
+ mime_data, mime_length,
+ free, mime_data);
+ if (status) {
+ cairo_surface_destroy (image);
+ free (mime_data);
+ return cairo_test_status_from_status (ctx, status);
+ }
+
+ cairo_set_source_surface (cr, image, x, y + 50);
+ cairo_surface_destroy (image);
+
+ cairo_paint (cr);
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ const char jpg_filename[] = "jpeg.jpg";
+ const char png_filename[] = "png.png";
+ const char jp2_filename[] = "jp2.jp2";
+ cairo_test_status_t status;
+
+ status = paint_file (cr, jpg_filename, CAIRO_MIME_TYPE_JPEG, 0, 0);
+ if (status)
+ return status;
+
+ status = paint_file (cr, png_filename, CAIRO_MIME_TYPE_PNG, 0, 50);
+ if (status)
+ return status;
+
+ status = paint_file (cr, jp2_filename, CAIRO_MIME_TYPE_JP2, 0, 100);
+ if (status)
+ return status;
+
+ status = paint_jbig2_file (cr, 0, 150);
+ if (status)
+ return status;
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (mime_data,
+ "Check that the mime-data embedding works",
+ "jpeg, api", /* keywords */
+ NULL, /* requirements */
+ 200, 250,
+ NULL, draw)
diff --git a/test/mime-surface-api.c b/test/mime-surface-api.c
new file mode 100644
index 000000000..ce12653e1
--- /dev/null
+++ b/test/mime-surface-api.c
@@ -0,0 +1,151 @@
+/*
+ * Copyright © 2011 Uli Schlachter
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Uli Schlachter <psychon@znc.in>
+ */
+
+#include "cairo-test.h"
+
+static void
+mime_data_destroy_func (void *data)
+{
+ cairo_bool_t *called = data;
+ *called = TRUE;
+}
+
+static cairo_test_status_t
+check_mime_data (cairo_test_context_t *ctx, cairo_surface_t *surface,
+ const char *mimetype, const unsigned char *data,
+ unsigned long length)
+{
+ const unsigned char *data_ret;
+ unsigned long length_ret;
+
+ cairo_surface_get_mime_data (surface, mimetype, &data_ret, &length_ret);
+ if (data_ret != data || length_ret != length) {
+ cairo_test_log (ctx,
+ "Surface has mime data %p with length %lu, "
+ "but expected %p with length %lu\n",
+ data_ret, length_ret, data, length);
+ return CAIRO_TEST_ERROR;
+ }
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+set_and_check_mime_data (cairo_test_context_t *ctx, cairo_surface_t *surface,
+ const char *mimetype, const unsigned char *data,
+ unsigned long length, cairo_bool_t *destroy_called)
+{
+ cairo_status_t status;
+
+ status = cairo_surface_set_mime_data (surface, mimetype,
+ data, length,
+ mime_data_destroy_func,
+ destroy_called);
+ if (status) {
+ cairo_test_log (ctx, "Could not set mime data to %s: %s\n",
+ data, cairo_status_to_string(status));
+ return CAIRO_TEST_ERROR;
+ }
+
+ return check_mime_data (ctx, surface, mimetype, data, length);
+}
+
+static cairo_test_status_t
+preamble (cairo_test_context_t *ctx)
+{
+ const char *mimetype = "text/x-uri";
+ const char *data1 = "http://www.cairographics.org";
+ const char *data2 = "http://cairographics.org/examples/";
+ cairo_bool_t destroy1_called = FALSE;
+ cairo_bool_t destroy2_called = FALSE;
+ cairo_surface_t *surface;
+ cairo_test_status_t test_status = CAIRO_TEST_SUCCESS;
+
+ surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 0, 0);
+ if (cairo_surface_status (surface)) {
+ cairo_test_log (ctx, "Could not create image surface\n");
+ test_status = CAIRO_TEST_ERROR;
+ goto out;
+ }
+
+ test_status = check_mime_data (ctx, surface, mimetype, NULL, 0);
+ if (test_status)
+ goto out;
+
+ test_status = set_and_check_mime_data (ctx, surface, mimetype,
+ (const unsigned char *) data1,
+ strlen (data1),
+ &destroy1_called);
+ if (test_status)
+ goto out;
+
+ if (destroy1_called) {
+ cairo_test_log (ctx, "MIME data 1 destroyed too early\n");
+ test_status = CAIRO_TEST_ERROR;
+ goto out;
+ }
+
+ test_status = set_and_check_mime_data (ctx, surface, mimetype,
+ (const unsigned char *) data2,
+ strlen (data2),
+ &destroy2_called);
+ if (test_status)
+ goto out;
+
+ if (!destroy1_called) {
+ cairo_test_log (ctx, "MIME data 1 destroy callback not called\n");
+ test_status = CAIRO_TEST_ERROR;
+ goto out;
+ }
+ if (destroy2_called) {
+ cairo_test_log (ctx, "MIME data 2 destroyed too early\n");
+ test_status = CAIRO_TEST_ERROR;
+ goto out;
+ }
+
+ test_status = set_and_check_mime_data (ctx, surface, mimetype,
+ NULL, 0, NULL);
+ if (test_status)
+ goto out;
+
+ if (!destroy2_called) {
+ cairo_test_log (ctx, "MIME data destroy callback not called\n");
+ test_status = CAIRO_TEST_ERROR;
+ goto out;
+ }
+
+out:
+ cairo_surface_destroy (surface);
+
+ return test_status;
+}
+
+CAIRO_TEST (mime_surface_api,
+ "Check the mime data API",
+ "api", /* keywords */
+ NULL, /* requirements */
+ 0, 0,
+ preamble, NULL)
diff --git a/test/miter-precision.c b/test/miter-precision.c
new file mode 100644
index 000000000..3bcdde00d
--- /dev/null
+++ b/test/miter-precision.c
@@ -0,0 +1,72 @@
+/*
+ * Copyright © 2007 Keith Packard
+ *
+ * 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 Keith Packard
+ *
+ * Contributor(s):
+ * Keith Packard <keithp@keithp.com>
+ */
+#include "cairo-test.h"
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ double xscale, yscale;
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ cairo_set_miter_limit (cr, 100000);
+ for (xscale = 1; xscale <= 1000; xscale += 999)
+ for (yscale = 1; yscale <= 1000; yscale += 999)
+ {
+ double max_scale = xscale > yscale ? xscale : yscale;
+ cairo_save (cr);
+ if (xscale > 1)
+ cairo_translate (cr, 50, 0);
+ if (yscale > 1)
+ cairo_translate (cr, 0, 50);
+ cairo_scale (cr, xscale, yscale);
+ cairo_set_line_width (cr, 10.0 / max_scale);
+ cairo_move_to (cr, 10.0 / xscale, 10.0 / yscale);
+ cairo_line_to (cr, 40.0 / xscale, 10.0 / yscale);
+ cairo_line_to (cr, 10.0 / xscale, 30.0 / yscale);
+ cairo_stroke (cr);
+ cairo_restore (cr);
+ }
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (miter_precision,
+ "test how cairo deals with small miters"
+ "\ncurrent code draws inappropriate bevels at times",
+ "stoke, stress", /* keywords */
+ NULL, /* requirements */
+ 120, 100,
+ NULL, draw)
diff --git a/test/move-to-show-surface.c b/test/move-to-show-surface.c
new file mode 100644
index 000000000..a52b46827
--- /dev/null
+++ b/test/move-to-show-surface.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright © 2004 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+/* Bug history
+ *
+ * 2004-10-25 Carl Worth <cworth@cworth.org>
+ *
+ * It looks like cairo_show_surface has no effect if it follows a
+ * call to cairo_move_to to any coordinate other than 0,0. A little
+ * bit of poking around suggests this isn't a regression, (at least
+ * not since the last pixman snapshot).
+ *
+ * 2005-04-02 Carl Worth <cworth@cworth.org>
+ *
+ * Status: RESOLVED
+ *
+ * Inside cairo_show_surface the current point was being used as
+ * both source and destination offsets. After fixing that to use 0,0
+ * as the source offset and the current point as the destination
+ * offset, the bug seems to be gone.
+ *
+ */
+
+#include "cairo-test.h"
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_surface_t *surface;
+ uint32_t colors[4] = {
+ 0xffffffff, 0xffff0000,
+ 0xff00ff00, 0xff0000ff
+ };
+ int i;
+
+ for (i=0; i < 4; i++) {
+ surface = cairo_image_surface_create_for_data ((unsigned char *) &colors[i],
+ CAIRO_FORMAT_RGB24,
+ 1, 1, 4);
+ cairo_set_source_surface (cr, surface,
+ i % 2, i / 2);
+ cairo_paint (cr);
+
+ cairo_surface_finish (surface); /* colors will go out of scope */
+ cairo_surface_destroy (surface);
+ }
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (move_to_show_surface,
+ "Tests calls to cairo_show_surface after cairo_move_to",
+ "transform", /* keywords */
+ NULL, /* requirements */
+ 2, 2,
+ NULL, draw)
diff --git a/test/multi-page.c b/test/multi-page.c
new file mode 100644
index 000000000..a3102dba3
--- /dev/null
+++ b/test/multi-page.c
@@ -0,0 +1,198 @@
+/*
+ * Copyright © 2005 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+#include "cairo-test.h"
+
+#include <stdio.h>
+
+#include <cairo.h>
+
+#if CAIRO_HAS_PS_SURFACE
+#include <cairo-ps.h>
+#endif
+
+#if CAIRO_HAS_PDF_SURFACE
+#include <cairo-pdf.h>
+#endif
+
+/* The PostScript and PDF backends are now integrated into the main
+ * test suite, so we are getting good verification of most things
+ * there.
+ *
+ * One thing that isn't supported there yet is multi-page output. So,
+ * for now we have this one-off test. There's no automatic
+ * verififcation here yet, but you can manually view the output to
+ * make sure it looks happy.
+ */
+
+#define WIDTH_IN_INCHES 3
+#define HEIGHT_IN_INCHES 3
+#define WIDTH_IN_POINTS (WIDTH_IN_INCHES * 72.0)
+#define HEIGHT_IN_POINTS (HEIGHT_IN_INCHES * 72.0)
+#define BASENAME "multi-page.out"
+
+static void
+draw_smiley (cairo_t *cr, double width, double height, double smile_ratio)
+{
+#define STROKE_WIDTH .04
+ double size;
+
+ double theta = M_PI / 4 * smile_ratio;
+ double dx = sqrt (0.005) * cos (theta);
+ double dy = sqrt (0.005) * sin (theta);
+
+ cairo_save (cr);
+
+ if (width > height)
+ size = height;
+ else
+ size = width;
+
+ cairo_translate (cr, (width - size) / 2.0, (height - size) / 2.0);
+ cairo_scale (cr, size, size);
+
+ /* Fill face */
+ cairo_arc (cr, 0.5, 0.5, 0.5 - STROKE_WIDTH, 0, 2 * M_PI);
+ cairo_set_source_rgb (cr, 1, 1, 0);
+ cairo_fill_preserve (cr);
+
+ cairo_set_source_rgb (cr, 0, 0, 0);
+
+ /* Stroke face */
+ cairo_set_line_width (cr, STROKE_WIDTH / 2.0);
+ cairo_stroke (cr);
+
+ /* Eyes */
+ cairo_set_line_width (cr, STROKE_WIDTH);
+ cairo_arc (cr, 0.3, 0.4, STROKE_WIDTH, 0, 2 * M_PI);
+ cairo_fill (cr);
+ cairo_arc (cr, 0.7, 0.4, STROKE_WIDTH, 0, 2 * M_PI);
+ cairo_fill (cr);
+
+ /* Mouth */
+ cairo_move_to (cr,
+ 0.35 - dx, 0.75 - dy);
+ cairo_curve_to (cr,
+ 0.35 + dx, 0.75 + dy,
+ 0.65 - dx, 0.75 + dy,
+ 0.65 + dx, 0.75 - dy);
+ cairo_stroke (cr);
+
+ cairo_restore (cr);
+}
+
+static void
+draw_some_pages (cairo_surface_t *surface)
+{
+ cairo_t *cr;
+ int i;
+
+ cr = cairo_create (surface);
+
+#define NUM_FRAMES 5
+ for (i=0; i < NUM_FRAMES; i++) {
+ draw_smiley (cr, WIDTH_IN_POINTS, HEIGHT_IN_POINTS,
+ (double) i / (NUM_FRAMES - 1));
+
+ /* Duplicate the last frame onto another page. (This is just a
+ * way to sneak cairo_copy_page into the test).
+ */
+ if (i == (NUM_FRAMES - 1))
+ cairo_copy_page (cr);
+
+ cairo_show_page (cr);
+ }
+
+ cairo_destroy (cr);
+}
+
+static cairo_test_status_t
+preamble (cairo_test_context_t *ctx)
+{
+ cairo_surface_t *surface;
+ cairo_status_t status;
+ char *filename;
+ cairo_test_status_t result = CAIRO_TEST_UNTESTED;
+ const char *path = cairo_test_mkdir (CAIRO_TEST_OUTPUT_DIR) ? CAIRO_TEST_OUTPUT_DIR : ".";
+
+#if CAIRO_HAS_PS_SURFACE
+ if (cairo_test_is_target_enabled (ctx, "ps2") ||
+ cairo_test_is_target_enabled (ctx, "ps3"))
+ {
+ if (result == CAIRO_TEST_UNTESTED)
+ result = CAIRO_TEST_SUCCESS;
+
+ xasprintf (&filename, "%s/%s", path, BASENAME ".ps");
+ surface = cairo_ps_surface_create (filename,
+ WIDTH_IN_POINTS, HEIGHT_IN_POINTS);
+ status = cairo_surface_status (surface);
+ if (status) {
+ cairo_test_log (ctx, "Failed to create ps surface for file %s: %s\n",
+ filename, cairo_status_to_string (status));
+ result = CAIRO_TEST_FAILURE;
+ }
+
+ draw_some_pages (surface);
+
+ cairo_surface_destroy (surface);
+
+ printf ("multi-page: Please check %s to ensure it looks happy.\n", filename);
+ free (filename);
+ }
+#endif
+
+#if CAIRO_HAS_PDF_SURFACE
+ if (cairo_test_is_target_enabled (ctx, "pdf")) {
+ if (result == CAIRO_TEST_UNTESTED)
+ result = CAIRO_TEST_SUCCESS;
+
+ xasprintf (&filename, "%s/%s", path, BASENAME ".pdf");
+ surface = cairo_pdf_surface_create (filename,
+ WIDTH_IN_POINTS, HEIGHT_IN_POINTS);
+ status = cairo_surface_status (surface);
+ if (status) {
+ cairo_test_log (ctx, "Failed to create pdf surface for file %s: %s\n",
+ filename, cairo_status_to_string (status));
+ result = CAIRO_TEST_FAILURE;
+ }
+
+ draw_some_pages (surface);
+
+ cairo_surface_destroy (surface);
+
+ printf ("multi-page: Please check %s to ensure it looks happy.\n", filename);
+ free (filename);
+ }
+#endif
+
+ return result;
+}
+
+CAIRO_TEST (multi_page,
+ "Check the paginated surfaces handle multiple pages.",
+ "paginated", /* keywords */
+ "target=vector", /* requirements */
+ 0, 0,
+ preamble, NULL)
diff --git a/test/negative-stride-image.c b/test/negative-stride-image.c
new file mode 100644
index 000000000..dfc8d644d
--- /dev/null
+++ b/test/negative-stride-image.c
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2012 Andrea Canciani
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Andrea Canciani <ranma42@gmail.com>
+ */
+
+#include "cairo-test.h"
+
+static const char *png_filename = "romedalen.png";
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ const cairo_test_context_t *ctx = cairo_test_get_context (cr);
+ cairo_format_t format = CAIRO_FORMAT_ARGB32;
+ cairo_t *cr_inv;
+ cairo_surface_t *png, *inv;
+ uint8_t *data;
+ int stride;
+
+ png = cairo_test_create_surface_from_png (ctx, png_filename);
+
+ stride = cairo_format_stride_for_width (format, width);
+ data = xcalloc (stride, height);
+ inv = cairo_image_surface_create_for_data (data + stride * (height - 1),
+ format, width, height, -stride);
+
+ cr_inv = cairo_create (inv);
+ cairo_set_source_surface (cr_inv, png, 0, 0);
+ cairo_paint (cr_inv);
+ cairo_destroy (cr_inv);
+
+ cairo_set_source_surface (cr, inv, 0, 0);
+ cairo_paint (cr);
+
+ cairo_surface_destroy (png);
+
+ cairo_surface_finish (inv);
+ cairo_surface_destroy (inv);
+
+ free (data);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (negative_stride_image,
+ "Test that images with a negative stride are handled correctly.",
+ "stride, image", /* keywords */
+ NULL, /* requirements */
+ 256, 192,
+ NULL, draw)
diff --git a/test/new-sub-path.c b/test/new-sub-path.c
new file mode 100644
index 000000000..f8f6bbe8d
--- /dev/null
+++ b/test/new-sub-path.c
@@ -0,0 +1,74 @@
+/*
+ * Copyright © 2005 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+#include "cairo-test.h"
+
+#define SIZE 10
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_set_source_rgb (cr, 0.0, 0.0, 1.0); /* blue */
+
+ /* Test cairo_new_sub_path followed by several different
+ * path-modification functions in turn...
+ */
+
+ /* ... cairo_move_to */
+ cairo_new_sub_path (cr);
+ cairo_move_to (cr, SIZE, SIZE);
+ cairo_line_to (cr, SIZE, 2 * SIZE);
+
+ /* ... cairo_line_to */
+ cairo_new_sub_path (cr);
+ cairo_line_to (cr, 2 * SIZE, 1.5 * SIZE);
+ cairo_line_to (cr, 3 * SIZE, 1.5 * SIZE);
+
+ /* ... cairo_curve_to */
+ cairo_new_sub_path (cr);
+ cairo_curve_to (cr,
+ 4.0 * SIZE, 1.5 * SIZE,
+ 4.5 * SIZE, 1.0 * SIZE,
+ 5.0 * SIZE, 1.5 * SIZE);
+
+ /* ... cairo_arc */
+ cairo_new_sub_path (cr);
+ cairo_arc (cr,
+ 6.5 * SIZE, 1.5 * SIZE,
+ 0.5 * SIZE,
+ 0.0, 2.0 * M_PI);
+
+ cairo_stroke (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (new_sub_path,
+ "Test the cairo_new_sub_path call",
+ "path", /* keywords */
+ NULL, /* requirements */
+ 8 * SIZE,
+ 3 * SIZE,
+ NULL, draw)
diff --git a/test/nil-surface.c b/test/nil-surface.c
new file mode 100644
index 000000000..30a1f97e5
--- /dev/null
+++ b/test/nil-surface.c
@@ -0,0 +1,170 @@
+/*
+ * Copyright © 2005 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+#include "cairo-test.h"
+#include <stddef.h>
+
+/* Test to verify fixes for the following similar bugs:
+ *
+ * https://bugs.freedesktop.org/show_bug.cgi?id=4088
+ * https://bugs.freedesktop.org/show_bug.cgi?id=3915
+ * https://bugs.freedesktop.org/show_bug.cgi?id=9906
+ */
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ const cairo_test_context_t *ctx = cairo_test_get_context (cr);
+ cairo_surface_t *surface;
+ cairo_pattern_t *pattern;
+ cairo_t *cr2;
+
+ /*
+ * 1. Test file-not-found from surface->pattern->cairo_t
+ */
+
+ /* Make a custom context to not interfere with the one passed in. */
+ cr2 = cairo_create (cairo_get_target (cr));
+
+ /* First, let's make a nil surface. */
+ surface = cairo_image_surface_create_from_png ("___THIS_FILE_DOES_NOT_EXIST___");
+
+ /* Let the error propagate into a nil pattern. */
+ pattern = cairo_pattern_create_for_surface (surface);
+
+ /* Then let it propagate into the cairo_t. */
+ cairo_set_source (cr2, pattern);
+ cairo_paint (cr2);
+
+ cairo_pattern_destroy (pattern);
+ cairo_surface_destroy (surface);
+
+ /* Check that the error made it all that way. */
+ if (cairo_status (cr2) != CAIRO_STATUS_FILE_NOT_FOUND) {
+ cairo_test_log (ctx, "Error: Received status of \"%s\" rather than expected \"%s\"\n",
+ cairo_status_to_string (cairo_status (cr2)),
+ cairo_status_to_string (CAIRO_STATUS_FILE_NOT_FOUND));
+ cairo_destroy (cr2);
+ return CAIRO_TEST_FAILURE;
+ }
+
+ cairo_destroy (cr2);
+
+ /*
+ * 2. Test NULL pointer pattern->cairo_t
+ */
+ cr2 = cairo_create (cairo_get_target (cr));
+
+ /* First, trigger the NULL pointer status. */
+ pattern = cairo_pattern_create_for_surface (NULL);
+
+ /* Then let it propagate into the cairo_t. */
+ cairo_set_source (cr2, pattern);
+ cairo_paint (cr2);
+
+ cairo_pattern_destroy (pattern);
+
+ /* Check that the error made it all that way. */
+ if (cairo_status (cr2) != CAIRO_STATUS_NULL_POINTER) {
+ cairo_test_log (ctx, "Error: Received status of \"%s\" rather than expected \"%s\"\n",
+ cairo_status_to_string (cairo_status (cr2)),
+ cairo_status_to_string (CAIRO_STATUS_NULL_POINTER));
+ cairo_destroy (cr2);
+ return CAIRO_TEST_FAILURE;
+ }
+
+ cairo_destroy (cr2);
+
+ /*
+ * 3. Test that cairo_surface_finish can accept NULL or a nil
+ * surface without crashing.
+ */
+
+ cairo_surface_finish (NULL);
+
+ surface = cairo_image_surface_create_from_png ("___THIS_FILE_DOES_NOT_EXIST___");
+ cairo_surface_finish (surface);
+ cairo_surface_destroy (surface);
+
+ /*
+ * 4. OK, we're straying from the original name, but it's still a
+ * similar kind of testing of error paths. Here we're making sure
+ * we can still call a cairo_get_* function after triggering an
+ * INVALID_RESTORE error.
+ */
+ cr2 = cairo_create (cairo_get_target (cr));
+
+ /* Trigger invalid restore. */
+ cairo_restore (cr2);
+ if (cairo_status (cr2) != CAIRO_STATUS_INVALID_RESTORE) {
+ cairo_test_log (ctx, "Error: Received status of \"%s\" rather than expected \"%s\"\n",
+ cairo_status_to_string (cairo_status (cr2)),
+ cairo_status_to_string (CAIRO_STATUS_INVALID_RESTORE));
+ cairo_destroy (cr2);
+ return CAIRO_TEST_FAILURE;
+ }
+
+ /* Test that we can still call cairo_get_fill_rule without crashing. */
+ cairo_get_fill_rule (cr2);
+
+ cairo_destroy (cr2);
+
+ /*
+ * 5. Create a cairo_t for the NULL surface.
+ */
+ cr2 = cairo_create (NULL);
+
+ if (cairo_status (cr2) != CAIRO_STATUS_NULL_POINTER) {
+ cairo_test_log (ctx, "Error: Received status of \"%s\" rather than expected \"%s\"\n",
+ cairo_status_to_string (cairo_status (cr2)),
+ cairo_status_to_string (CAIRO_STATUS_NULL_POINTER));
+ cairo_destroy (cr2);
+ return CAIRO_TEST_FAILURE;
+ }
+
+ /* Test that get_target returns something valid */
+ if (cairo_get_target (cr2) == NULL) {
+ cairo_test_log (ctx, "Error: cairo_get_target() returned NULL\n");
+ cairo_destroy (cr2);
+ return CAIRO_TEST_FAILURE;
+ }
+
+ /* Test that push_group doesn't crash */
+ cairo_push_group (cr2);
+ cairo_stroke (cr2);
+ pattern = cairo_pop_group (cr2);
+ cairo_pattern_destroy (pattern);
+
+ cairo_destroy (cr2);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (nil_surface,
+ "Test that nil surfaces do not make cairo crash.",
+ "api", /* keywords */
+ NULL, /* requirements */
+ 1, 1,
+ NULL, draw)
diff --git a/test/operator-alpha-alpha.c b/test/operator-alpha-alpha.c
new file mode 100644
index 000000000..2cef8585c
--- /dev/null
+++ b/test/operator-alpha-alpha.c
@@ -0,0 +1,166 @@
+/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */
+/* cairo - a vector graphics library with display and print output
+ *
+ * Copyright 2002 University of Southern California
+ * Copyright 2005 Red Hat, Inc.
+ * Copyright 2007 Emmanuel Pacaud
+ * Copyright 2008 Benjamin Otte
+ * Copyright 2008 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
+ * 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):
+ * Owen Taylor <otaylor@redhat.com>
+ * Kristian Høgsberg <krh@redhat.com>
+ * Emmanuel Pacaud <emmanuel.pacaud@lapp.in2p3.fr>
+ * Chris Wilson <chris@chris-wilson.co.uk>
+ * Andrea Canciani <ranma42@gmail.com>
+ */
+
+#include "cairo-test.h"
+
+#define STEPS 16
+#define START_OPERATOR CAIRO_OPERATOR_CLEAR
+#define STOP_OPERATOR CAIRO_OPERATOR_HSL_LUMINOSITY
+
+#define SIZE 3
+#define COUNT 6
+#define FULL_WIDTH ((STEPS + 1) * COUNT - 1)
+#define FULL_HEIGHT ((COUNT + STOP_OPERATOR - START_OPERATOR) / COUNT) * (STEPS + 1)
+
+static void
+create_patterns (cairo_t *bg, cairo_t *fg)
+{
+ int x;
+
+ for (x = 0; x < STEPS; x++) {
+ double i = (double) x / (STEPS - 1);
+ cairo_set_source_rgba (bg, 0, 0, 0, i);
+ cairo_rectangle (bg, x, 0, 1, STEPS);
+ cairo_fill (bg);
+
+ cairo_set_source_rgba (fg, 0, 0, 0, i);
+ cairo_rectangle (fg, 0, x, STEPS, 1);
+ cairo_fill (fg);
+ }
+}
+
+/* expects a STEP*STEP pixel rectangle */
+static void
+do_composite (cairo_t *cr, cairo_operator_t op, cairo_surface_t *bg, cairo_surface_t *fg)
+{
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_set_source_surface (cr, bg, 0, 0);
+ cairo_paint (cr);
+
+ cairo_set_operator (cr, op);
+ cairo_set_source_surface (cr, fg, 0, 0);
+ cairo_paint (cr);
+}
+
+static void
+subdraw (cairo_t *cr, int width, int height)
+{
+ size_t i = 0;
+ cairo_operator_t op;
+ cairo_t *bgcr, *fgcr;
+ cairo_surface_t *bg, *fg;
+
+ bg = cairo_surface_create_similar (cairo_get_target (cr),
+ CAIRO_CONTENT_ALPHA, SIZE * STEPS, SIZE * STEPS);
+ fg = cairo_surface_create_similar (cairo_get_target (cr),
+ CAIRO_CONTENT_ALPHA, SIZE * STEPS, SIZE * STEPS);
+ bgcr = cairo_create (bg);
+ fgcr = cairo_create (fg);
+ cairo_scale (bgcr, SIZE, SIZE);
+ cairo_scale (fgcr, SIZE, SIZE);
+ create_patterns (bgcr, fgcr);
+ cairo_destroy (bgcr);
+ cairo_destroy (fgcr);
+
+ for (op = START_OPERATOR; op <= STOP_OPERATOR; op++, i++) {
+ cairo_save (cr);
+ cairo_translate (cr,
+ SIZE * (STEPS + 1) * (i % COUNT),
+ SIZE * (STEPS + 1) * (i / COUNT));
+ cairo_rectangle (cr, 0, 0, SIZE * (STEPS + 1), SIZE * (STEPS+1));
+ cairo_clip (cr);
+ do_composite (cr, op, bg, fg);
+ cairo_restore (cr);
+ }
+
+ cairo_surface_destroy (fg);
+ cairo_surface_destroy (bg);
+}
+
+
+static cairo_surface_t *
+create_source (cairo_surface_t *target, int width, int height)
+{
+ cairo_surface_t *similar;
+ cairo_t *cr;
+
+ similar = cairo_surface_create_similar (target,
+ CAIRO_CONTENT_ALPHA,
+ width, height);
+ cr = cairo_create (similar);
+ cairo_surface_destroy (similar);
+
+ subdraw (cr, width, height);
+
+ similar = cairo_surface_reference (cairo_get_target (cr));
+ cairo_destroy (cr);
+
+ return similar;
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_surface_t *source;
+
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+ source = create_source (cairo_get_target (cr), width, height);
+ cairo_set_source_surface (cr, source, 0, 0);
+ cairo_surface_destroy (source);
+
+ cairo_paint (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (operator_alpha_alpha,
+ "Tests result of compositing pure-alpha surfaces"
+ "\nCompositing of pure-alpha sources is inconsistent across backends.",
+ "alpha, similar, operator", /* keywords */
+ NULL, /* requirements */
+ FULL_WIDTH * SIZE, FULL_HEIGHT * SIZE,
+ NULL, draw)
diff --git a/test/operator-alpha.c b/test/operator-alpha.c
new file mode 100644
index 000000000..1ce4ecdf2
--- /dev/null
+++ b/test/operator-alpha.c
@@ -0,0 +1,65 @@
+/*
+ * Copyright © 2008 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Chris Wilson not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Chris Wilson makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+#define N_OPERATORS (CAIRO_OPERATOR_SATURATE + 1)
+#define SIZE 10
+#define PAD 3
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ unsigned int n;
+
+ cairo_translate (cr, PAD, PAD);
+
+ for (n = 0; n < N_OPERATORS; n++) {
+ cairo_reset_clip (cr);
+ cairo_rectangle (cr, 0, 0, SIZE, SIZE);
+ cairo_clip (cr);
+
+ cairo_set_source_rgb (cr, 1, 0, 0);
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+ cairo_rectangle (cr, 0, 0, SIZE-PAD, SIZE-PAD);
+ cairo_fill (cr);
+
+ cairo_set_source_rgba (cr, 0, 0, 1, .33);
+ cairo_set_operator (cr, n);
+ cairo_rectangle (cr, PAD, PAD, SIZE-PAD, SIZE-PAD);
+ cairo_fill (cr);
+
+ cairo_translate (cr, SIZE+PAD, 0);
+ }
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (operator_alpha,
+ "Tests using set_operator() with an non-opaque source",
+ "operator, alpha", /* keywords */
+ NULL, /* requirements */
+ (SIZE+PAD) * N_OPERATORS + PAD, SIZE + 2*PAD,
+ NULL, draw)
diff --git a/test/operator-clear.c b/test/operator-clear.c
new file mode 100644
index 000000000..72a32c219
--- /dev/null
+++ b/test/operator-clear.c
@@ -0,0 +1,196 @@
+/*
+ * Copyright © 2005 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Kristian Høgsberg <krh@redhat.com>
+ * Owen Taylor <otaylor@redhat.com>
+ */
+
+#include "cairo-test.h"
+#include <math.h>
+#include <stdio.h>
+
+#define WIDTH 16
+#define HEIGHT 16
+#define PAD 2
+
+static void
+set_solid_pattern (cairo_t *cr, int x, int y)
+{
+ cairo_set_source_rgb (cr, 1.0, 0, 0.0);
+}
+
+static void
+set_gradient_pattern (cairo_t *cr, int x, int y)
+{
+ cairo_pattern_t *pattern;
+
+ pattern = cairo_pattern_create_linear (x, y, x + WIDTH, y + HEIGHT);
+ cairo_pattern_add_color_stop_rgba (pattern, 0.2, 1, 0, 0, 1);
+ cairo_pattern_add_color_stop_rgba (pattern, 0.8, 1, 0, 0, 0.0);
+ cairo_set_source (cr, pattern);
+ cairo_pattern_destroy (pattern);
+}
+
+static void
+draw_mask (cairo_t *cr, int x, int y)
+{
+ cairo_surface_t *mask_surface;
+ cairo_t *cr2;
+
+ double width = (int)(0.9 * WIDTH);
+ double height = (int)(0.9 * HEIGHT);
+ x += 0.05 * WIDTH;
+ y += 0.05 * HEIGHT;
+
+ mask_surface = cairo_surface_create_similar (cairo_get_group_target (cr),
+ CAIRO_CONTENT_ALPHA,
+ width, height);
+ cr2 = cairo_create (mask_surface);
+ cairo_surface_destroy (mask_surface);
+
+ cairo_set_source_rgb (cr2, 1, 1, 1); /* white */
+
+ cairo_arc (cr2, 0.5 * width, 0.5 * height, 0.45 * height, 0, 2 * M_PI);
+ cairo_fill (cr2);
+
+ cairo_mask_surface (cr, cairo_get_target (cr2), x, y);
+ cairo_destroy (cr2);
+}
+
+static void
+draw_glyphs (cairo_t *cr, int x, int y)
+{
+ cairo_text_extents_t extents;
+
+ cairo_set_font_size (cr, 0.8 * HEIGHT);
+
+ cairo_text_extents (cr, "FG", &extents);
+ cairo_move_to (cr,
+ x + floor ((WIDTH - extents.width) / 2 + 0.5) - extents.x_bearing,
+ y + floor ((HEIGHT - extents.height) / 2 + 0.5) - extents.y_bearing);
+ cairo_show_text (cr, "FG");
+}
+
+static void
+draw_polygon (cairo_t *cr, int x, int y)
+{
+ double width = (int)(0.9 * WIDTH);
+ double height = (int)(0.9 * HEIGHT);
+ x += 0.05 * WIDTH;
+ y += 0.05 * HEIGHT;
+
+ cairo_new_path (cr);
+ cairo_move_to (cr, x, y);
+ cairo_line_to (cr, x, y + height);
+ cairo_line_to (cr, x + width / 2, y + 3 * height / 4);
+ cairo_line_to (cr, x + width, y + height);
+ cairo_line_to (cr, x + width, y);
+ cairo_line_to (cr, x + width / 2, y + height / 4);
+ cairo_close_path (cr);
+ cairo_fill (cr);
+}
+
+static void
+draw_rects (cairo_t *cr, int x, int y)
+{
+ double block_width = (int)(0.33 * WIDTH + 0.5);
+ double block_height = (int)(0.33 * HEIGHT + 0.5);
+ int i, j;
+
+ for (i = 0; i < 3; i++)
+ for (j = 0; j < 3; j++)
+ if ((i + j) % 2 == 0)
+ cairo_rectangle (cr,
+ x + block_width * i, y + block_height * j,
+ block_width, block_height);
+
+ cairo_fill (cr);
+}
+
+static void (* const pattern_funcs[])(cairo_t *cr, int x, int y) = {
+ set_solid_pattern,
+ set_gradient_pattern,
+};
+
+static void (* const draw_funcs[])(cairo_t *cr, int x, int y) = {
+ draw_mask,
+ draw_glyphs,
+ draw_polygon,
+ draw_rects
+};
+
+#define IMAGE_WIDTH (ARRAY_LENGTH (pattern_funcs) * (WIDTH + PAD) + PAD)
+#define IMAGE_HEIGHT (ARRAY_LENGTH (draw_funcs) * (HEIGHT + PAD) + PAD)
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ const cairo_test_context_t *ctx = cairo_test_get_context (cr);
+ size_t i, j, x, y;
+ cairo_pattern_t *pattern;
+
+ cairo_select_font_face (cr, CAIRO_TEST_FONT_FAMILY " Sans",
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_NORMAL);
+
+ for (j = 0; j < ARRAY_LENGTH (draw_funcs); j++) {
+ for (i = 0; i < ARRAY_LENGTH (pattern_funcs); i++) {
+ x = i * (WIDTH + PAD) + PAD;
+ y = j * (HEIGHT + PAD) + PAD;
+
+ cairo_save (cr);
+
+ pattern = cairo_pattern_create_linear (x + WIDTH, y,
+ x, y + HEIGHT);
+ cairo_pattern_add_color_stop_rgba (pattern, 0.2,
+ 0.0, 0.0, 1.0, 1.0); /* Solid blue */
+ cairo_pattern_add_color_stop_rgba (pattern, 0.8,
+ 0.0, 0.0, 1.0, 0.0); /* Transparent blue */
+ cairo_set_source (cr, pattern);
+ cairo_pattern_destroy (pattern);
+
+ cairo_rectangle (cr, x, y, WIDTH, HEIGHT);
+ cairo_fill_preserve (cr);
+ cairo_clip (cr);
+
+ cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
+ pattern_funcs[i] (cr, x, y);
+ draw_funcs[j] (cr, x, y);
+ if (cairo_status (cr))
+ cairo_test_log (ctx, "%d %d HERE!\n", (int)i, (int)j);
+
+ cairo_restore (cr);
+ }
+ }
+
+ if (cairo_status (cr) != CAIRO_STATUS_SUCCESS)
+ cairo_test_log (ctx, "%d %d .HERE!\n", (int)i, (int)j);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (operator_clear,
+ "Test of CAIRO_OPERATOR_CLEAR",
+ "operator", /* keywords */
+ NULL, /* requirements */
+ IMAGE_WIDTH, IMAGE_HEIGHT,
+ NULL, draw)
diff --git a/test/operator-source.c b/test/operator-source.c
new file mode 100644
index 000000000..9330a65d1
--- /dev/null
+++ b/test/operator-source.c
@@ -0,0 +1,250 @@
+/*
+ * Copyright © 2005 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Kristian Høgsberg <krh@redhat.com>
+ * Owen Taylor <otaylor@redhat.com>
+ * Uli Schlachter <psychon@znc.in>
+ */
+
+#include "cairo-test.h"
+#include <math.h>
+#include <stdio.h>
+
+#define WIDTH 16
+#define HEIGHT 16
+#define PAD 2
+
+static void
+set_solid_pattern (cairo_t *cr, int x, int y)
+{
+ cairo_set_source_rgb (cr, 1.0, 0, 0.0);
+}
+
+static void
+set_translucent_pattern (cairo_t *cr, int x, int y)
+{
+ cairo_set_source_rgba (cr, 1, 0, 0, 0.5);
+}
+
+static void
+set_gradient_pattern (cairo_t *cr, int x, int y)
+{
+ cairo_pattern_t *pattern;
+
+ pattern = cairo_pattern_create_linear (x, y, x + WIDTH, y + HEIGHT);
+ cairo_pattern_add_color_stop_rgba (pattern, 0.2, 1, 0, 0, 1);
+ cairo_pattern_add_color_stop_rgba (pattern, 0.8, 1, 0, 0, 0.0);
+ cairo_set_source (cr, pattern);
+ cairo_pattern_destroy (pattern);
+}
+
+static void
+set_surface_pattern (cairo_t *cr, int x, int y)
+{
+ cairo_surface_t *source_surface;
+ cairo_t *cr2;
+
+ double width = (int)(0.6 * WIDTH);
+ double height = (int)(0.6 * HEIGHT);
+ x += 0.2 * WIDTH;
+ y += 0.2 * HEIGHT;
+
+ source_surface = cairo_surface_create_similar (cairo_get_group_target (cr),
+ CAIRO_CONTENT_COLOR_ALPHA,
+ width, height);
+ cr2 = cairo_create (source_surface);
+ cairo_surface_destroy (source_surface);
+
+ cairo_set_source_rgb (cr2, 1, 0, 0); /* red */
+ cairo_paint (cr2);
+
+ cairo_set_source_rgb (cr2, 1, 1, 1); /* white */
+
+ cairo_arc (cr2, 0.5 * width, 0.5 * height, 0.5 * height, 0, 2 * M_PI);
+ cairo_fill (cr2);
+
+ cairo_set_source_surface (cr, cairo_get_target (cr2), x, y);
+ cairo_destroy (cr2);
+}
+
+static void
+draw_mask (cairo_t *cr, int x, int y)
+{
+ cairo_surface_t *mask_surface;
+ cairo_t *cr2;
+
+ double width = (int)(0.9 * WIDTH);
+ double height = (int)(0.9 * HEIGHT);
+ x += 0.05 * WIDTH;
+ y += 0.05 * HEIGHT;
+
+ mask_surface = cairo_surface_create_similar (cairo_get_group_target (cr),
+ CAIRO_CONTENT_ALPHA,
+ width, height);
+ cr2 = cairo_create (mask_surface);
+ cairo_surface_destroy (mask_surface);
+
+ cairo_set_source_rgb (cr2, 1, 1, 1); /* white */
+
+ cairo_arc (cr2, 0.5 * width, 0.5 * height, 0.45 * height, 0, 2 * M_PI);
+ cairo_fill (cr2);
+
+ cairo_mask_surface (cr, cairo_get_target (cr2), x, y);
+ cairo_destroy (cr2);
+}
+
+static void
+draw_glyphs (cairo_t *cr, int x, int y)
+{
+ cairo_text_extents_t extents;
+
+ cairo_set_font_size (cr, 0.8 * HEIGHT);
+
+ cairo_text_extents (cr, "FG", &extents);
+ cairo_move_to (cr,
+ x + floor ((WIDTH - extents.width) / 2 + 0.5) - extents.x_bearing,
+ y + floor ((HEIGHT - extents.height) / 2 + 0.5) - extents.y_bearing);
+ cairo_show_text (cr, "FG");
+}
+
+static void
+draw_polygon (cairo_t *cr, int x, int y)
+{
+ double width = (int)(0.9 * WIDTH);
+ double height = (int)(0.9 * HEIGHT);
+ x += 0.05 * WIDTH;
+ y += 0.05 * HEIGHT;
+
+ cairo_new_path (cr);
+ cairo_move_to (cr, x, y);
+ cairo_line_to (cr, x, y + height);
+ cairo_line_to (cr, x + width / 2, y + 3 * height / 4);
+ cairo_line_to (cr, x + width, y + height);
+ cairo_line_to (cr, x + width, y);
+ cairo_line_to (cr, x + width / 2, y + height / 4);
+ cairo_close_path (cr);
+ cairo_fill (cr);
+}
+
+static void
+draw_rects (cairo_t *cr, int x, int y, double offset)
+{
+ double block_width = (int)(0.33 * WIDTH + 0.5) - offset/3;
+ double block_height = (int)(0.33 * HEIGHT + 0.5) - offset/3;
+ int i, j;
+
+ x += offset/2;
+ y += offset/2;
+
+ for (i = 0; i < 3; i++)
+ for (j = 0; j < 3; j++)
+ if ((i + j) % 2 == 0)
+ cairo_rectangle (cr,
+ x + block_width * i, y + block_height * j,
+ block_width, block_height);
+
+ cairo_fill (cr);
+}
+
+static void
+draw_aligned_rects (cairo_t *cr, int x, int y)
+{
+ draw_rects (cr, x, y, 0);
+}
+
+static void
+draw_unaligned_rects (cairo_t *cr, int x, int y)
+{
+ draw_rects (cr, x, y, 2.1);
+}
+
+static void (* const pattern_funcs[])(cairo_t *cr, int x, int y) = {
+ set_solid_pattern,
+ set_translucent_pattern,
+ set_gradient_pattern,
+ set_surface_pattern,
+};
+
+static void (* const draw_funcs[])(cairo_t *cr, int x, int y) = {
+ draw_mask,
+ draw_glyphs,
+ draw_polygon,
+ draw_aligned_rects,
+ draw_unaligned_rects
+};
+
+#define IMAGE_WIDTH (ARRAY_LENGTH (pattern_funcs) * (WIDTH + PAD) + PAD)
+#define IMAGE_HEIGHT (ARRAY_LENGTH (draw_funcs) * (HEIGHT + PAD) + PAD)
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ const cairo_test_context_t *ctx = cairo_test_get_context (cr);
+ size_t i, j, x, y;
+ cairo_pattern_t *pattern;
+
+ cairo_select_font_face (cr, CAIRO_TEST_FONT_FAMILY " Sans",
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_NORMAL);
+
+ for (j = 0; j < ARRAY_LENGTH (draw_funcs); j++) {
+ for (i = 0; i < ARRAY_LENGTH (pattern_funcs); i++) {
+ x = i * (WIDTH + PAD) + PAD;
+ y = j * (HEIGHT + PAD) + PAD;
+
+ cairo_save (cr);
+
+ pattern = cairo_pattern_create_linear (x + WIDTH, y,
+ x, y + HEIGHT);
+ cairo_pattern_add_color_stop_rgba (pattern, 0.2,
+ 0.0, 0.0, 1.0, 1.0); /* Solid blue */
+ cairo_pattern_add_color_stop_rgba (pattern, 0.8,
+ 0.0, 0.0, 1.0, 0.0); /* Transparent blue */
+ cairo_set_source (cr, pattern);
+ cairo_pattern_destroy (pattern);
+
+ cairo_rectangle (cr, x, y, WIDTH, HEIGHT);
+ cairo_fill_preserve (cr);
+ cairo_clip (cr);
+
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ pattern_funcs[i] (cr, x, y);
+ draw_funcs[j] (cr, x, y);
+ if (cairo_status (cr))
+ cairo_test_log (ctx, "%d %d HERE!\n", (int)i, (int)j);
+
+ cairo_restore (cr);
+ }
+ }
+
+ if (cairo_status (cr) != CAIRO_STATUS_SUCCESS)
+ cairo_test_log (ctx, "%d %d .HERE!\n", (int)i, (int)j);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (operator_source,
+ "Test of CAIRO_OPERATOR_SOURCE",
+ "operator", /* keywords */
+ NULL, /* requirements */
+ IMAGE_WIDTH, IMAGE_HEIGHT,
+ NULL, draw)
diff --git a/test/operator.c b/test/operator.c
new file mode 100644
index 000000000..666fcafd6
--- /dev/null
+++ b/test/operator.c
@@ -0,0 +1,65 @@
+/*
+ * Copyright © 2008 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Chris Wilson not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Chris Wilson makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+#define N_OPERATORS (CAIRO_OPERATOR_SATURATE + 1)
+#define SIZE 10
+#define PAD 3
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ unsigned int n;
+
+ cairo_translate (cr, PAD, PAD);
+
+ for (n = 0; n < N_OPERATORS; n++) {
+ cairo_reset_clip (cr);
+ cairo_rectangle (cr, 0, 0, SIZE, SIZE);
+ cairo_clip (cr);
+
+ cairo_set_source_rgb (cr, 1, 0, 0);
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+ cairo_rectangle (cr, 0, 0, SIZE-PAD, SIZE-PAD);
+ cairo_fill (cr);
+
+ cairo_set_source_rgb (cr, 0, 0, 1);
+ cairo_set_operator (cr, n);
+ cairo_rectangle (cr, PAD, PAD, SIZE-PAD, SIZE-PAD);
+ cairo_fill (cr);
+
+ cairo_translate (cr, SIZE+PAD, 0);
+ }
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (operator,
+ "Tests using set_operator()",
+ "operator", /* keywords */
+ NULL, /* requirements */
+ (SIZE+PAD) * N_OPERATORS + PAD, SIZE + 2*PAD,
+ NULL, draw)
diff --git a/test/outline-tolerance.c b/test/outline-tolerance.c
new file mode 100644
index 000000000..6453f5c96
--- /dev/null
+++ b/test/outline-tolerance.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright © 2012 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+/* An assertion failure found by Rico Tzschichholz */
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_set_source_rgb (cr, 0, 1, 0);
+ cairo_paint (cr);
+ cairo_set_source_rgb (cr, 1, 0, 0);
+
+ cairo_set_line_join (cr, CAIRO_LINE_JOIN_MITER);
+ cairo_set_line_width (cr, 200);
+ cairo_set_miter_limit (cr, 1.5);
+ cairo_rectangle (cr, 100, 25, 1000, 0);
+ cairo_stroke (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (outline_tolerance,
+ "Rectangle drawn incorrectly when it has zero height and miter limit greater than 1.414",
+ "stroke", /* keywords */
+ NULL, /* requirements */
+ 100, 50,
+ NULL, draw)
diff --git a/test/over-above-source.c b/test/over-above-source.c
new file mode 100644
index 000000000..7191c8da3
--- /dev/null
+++ b/test/over-above-source.c
@@ -0,0 +1,72 @@
+/*
+ * Copyright © 2007 Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+#include "cairo-test.h"
+
+#define SIZE 40
+#define PAD 2
+#define WIDTH (PAD + SIZE + PAD)
+#define HEIGHT WIDTH
+
+/* This test is designed to explore the interactions of "native" and
+ * "fallback" objects. For the ps surface, OVER with non-1.0 opacity
+ * will be a fallback while SOURCE will be native. For the pdf
+ * surface, it's the reverse where OVER is native while SOURCE is a
+ * fallback. */
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_translate (cr, PAD, PAD);
+
+ /* A red triangle with SOURCE */
+ cairo_move_to (cr, SIZE / 2, SIZE / 2);
+ cairo_rel_line_to (cr, SIZE / 2, 0);
+ cairo_rel_line_to (cr, -SIZE / 2, SIZE / 2);
+ cairo_close_path (cr);
+
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_set_source_rgba (cr, 1., 0., 0., 0.5); /* 50% red */
+
+ cairo_fill (cr);
+
+ /* A green circle with OVER */
+ cairo_arc (cr, SIZE / 2, SIZE / 2, SIZE / 4, 0., 2. * M_PI);
+
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+ cairo_set_source_rgba (cr, 0., 1., 0., 0.5); /* 50% green */
+
+ cairo_fill (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (over_above_source,
+ "A simple test drawing a circle with OVER after a triangle drawn with SOURCE",
+ "operator", /* keywords */
+ NULL, /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw)
diff --git a/test/over-around-source.c b/test/over-around-source.c
new file mode 100644
index 000000000..531eda804
--- /dev/null
+++ b/test/over-around-source.c
@@ -0,0 +1,83 @@
+/*
+ * Copyright © 2007 Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+#include "cairo-test.h"
+
+#define SIZE 40
+#define PAD 2
+#define WIDTH (PAD + SIZE + PAD)
+#define HEIGHT WIDTH
+
+/* This test is designed to explore the interactions of "native" and
+ * "fallback" objects. For the ps surface, OVER with non-1.0 opacity
+ * will be a fallback while SOURCE will be native. For the pdf
+ * surface, it's the reverse where OVER is native while SOURCE is a
+ * fallback. */
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_translate (cr, PAD, PAD);
+
+ /* A green triangle with OVER */
+ cairo_move_to (cr, SIZE / 5, SIZE / 5);
+ cairo_rel_line_to (cr, SIZE / 2, 0);
+ cairo_rel_line_to (cr, -SIZE / 2, SIZE / 2);
+ cairo_close_path (cr);
+
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+ cairo_set_source_rgba (cr, 0., 1., 0., 0.5); /* 50% green */
+
+ cairo_fill (cr);
+
+ /* A red circle with SOURCE */
+ cairo_arc (cr, SIZE / 2, SIZE / 2, SIZE / 4, 0., 2. * M_PI);
+
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_set_source_rgba (cr, 1., 0., 0., 0.5); /* 50% red */
+
+ cairo_fill (cr);
+
+ /* Another green triangle with OVER */
+ cairo_move_to (cr, SIZE / 2, SIZE / 2);
+ cairo_rel_line_to (cr, SIZE / 2, 0);
+ cairo_rel_line_to (cr, -SIZE / 2, SIZE / 2);
+ cairo_close_path (cr);
+
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+ cairo_set_source_rgba (cr, 0., 1., 0., 0.5); /* 50% green */
+
+ cairo_fill (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (over_around_source,
+ "A simple test drawing a triangle with SOURCE between two circles drawn with OVER",
+ "operator", /* keywords */
+ NULL, /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw)
diff --git a/test/over-below-source.c b/test/over-below-source.c
new file mode 100644
index 000000000..7fe5bd889
--- /dev/null
+++ b/test/over-below-source.c
@@ -0,0 +1,72 @@
+/*
+ * Copyright © 2007 Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+#include "cairo-test.h"
+
+#define SIZE 40
+#define PAD 2
+#define WIDTH (PAD + SIZE + PAD)
+#define HEIGHT WIDTH
+
+/* This test is designed to explore the interactions of "native" and
+ * "fallback" objects. For the ps surface, OVER with non-1.0 opacity
+ * will be a fallback while SOURCE will be native. For the pdf
+ * surface, it's the reverse where OVER is native while SOURCE is a
+ * fallback. */
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_translate (cr, PAD, PAD);
+
+ /* A green circle with OVER */
+ cairo_arc (cr, SIZE / 2, SIZE / 2, SIZE / 4, 0., 2. * M_PI);
+
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+ cairo_set_source_rgba (cr, 0., 1., 0., 0.5); /* 50% green */
+
+ cairo_fill (cr);
+
+ /* A red triangle with SOURCE */
+ cairo_move_to (cr, SIZE / 2, SIZE / 2);
+ cairo_line_to (cr, SIZE, SIZE / 2);
+ cairo_line_to (cr, SIZE / 2, SIZE);
+ cairo_close_path (cr);
+
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_set_source_rgba (cr, 1., 0., 0., 0.5); /* 50% red */
+
+ cairo_fill (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (over_below_source,
+ "A simple test drawing a circle with OVER before a triangle drawn with SOURCE",
+ "operator", /* keywords */
+ NULL, /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw)
diff --git a/test/over-between-source.c b/test/over-between-source.c
new file mode 100644
index 000000000..ffb657208
--- /dev/null
+++ b/test/over-between-source.c
@@ -0,0 +1,83 @@
+/*
+ * Copyright © 2007 Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+#include "cairo-test.h"
+
+#define SIZE 40
+#define PAD 2
+#define WIDTH (PAD + SIZE + PAD)
+#define HEIGHT WIDTH
+
+/* This test is designed to explore the interactions of "native" and
+ * "fallback" objects. For the ps surface, OVER with non-1.0 opacity
+ * will be a fallback while SOURCE will be native. For the pdf
+ * surface, it's the reverse where OVER is native while SOURCE is a
+ * fallback. */
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_translate (cr, PAD, PAD);
+
+ /* A red triangle with SOURCE */
+ cairo_move_to (cr, SIZE / 5, SIZE / 5);
+ cairo_rel_line_to (cr, SIZE / 2, 0);
+ cairo_rel_line_to (cr, -SIZE / 2, SIZE / 2);
+ cairo_close_path (cr);
+
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_set_source_rgba (cr, 1., 0., 0., 0.5); /* 50% red */
+
+ cairo_fill (cr);
+
+ /* A green circle with OVER */
+ cairo_arc (cr, SIZE / 2, SIZE / 2, SIZE / 4, 0., 2. * M_PI);
+
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+ cairo_set_source_rgba (cr, 0., 1., 0., 0.5); /* 50% green */
+
+ cairo_fill (cr);
+
+ /* Another red triangle with SOURCE */
+ cairo_move_to (cr, SIZE / 2, SIZE / 2);
+ cairo_rel_line_to (cr, SIZE / 2, 0);
+ cairo_rel_line_to (cr, -SIZE / 2, SIZE / 2);
+ cairo_close_path (cr);
+
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_set_source_rgba (cr, 1., 0., 0., 0.5); /* 50% red */
+
+ cairo_fill (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (over_between_source,
+ "A simple test drawing a circle with OVER between two triangles drawn with SOURCE",
+ "operator", /* keywords */
+ NULL, /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw)
diff --git a/test/overlapping-boxes.c b/test/overlapping-boxes.c
new file mode 100644
index 000000000..92211ee06
--- /dev/null
+++ b/test/overlapping-boxes.c
@@ -0,0 +1,96 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+/* Not strictly overlapping, but it does highlight the error in
+ * an optimisation of fill-box handling that I frequently am
+ * tempted to write.
+ */
+
+#include "cairo-test.h"
+
+#define WIDTH (20)
+#define HEIGHT (20)
+
+static void
+border (cairo_t *cr)
+{
+ cairo_rectangle (cr, 1, 1, 8, 8);
+ cairo_rectangle (cr, 1.25, 1.25, 7.5, 7.5);
+ cairo_rectangle (cr, 1.75, 1.75, 6.5, 6.5);
+ cairo_rectangle (cr, 2, 2, 6, 6);
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
+
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+ border (cr);
+ cairo_set_source_rgb (cr, 1, 0, 0);
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+ cairo_fill (cr);
+
+ cairo_translate (cr, 10, 0);
+
+ border (cr);
+ cairo_set_source_rgb (cr, 0, 0, 1);
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_fill (cr);
+
+ cairo_translate (cr, 0, 10);
+
+ cairo_rectangle (cr, 0, 0, 10, 10);
+ cairo_clip (cr);
+
+ border (cr);
+ cairo_set_source_rgb (cr, 0, 1, 0);
+ cairo_set_operator (cr, CAIRO_OPERATOR_IN);
+ cairo_fill (cr);
+
+ cairo_reset_clip (cr);
+
+ cairo_translate (cr, -10, 0);
+
+ cairo_rectangle (cr, 0, 0, 10, 10);
+ cairo_clip (cr);
+
+ border (cr);
+ cairo_set_source_rgb (cr, 0, 0, 1);
+ cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
+ cairo_fill (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (overlapping_boxes,
+ "A sub-pixel double border to highlight the danger in an easy optimisation",
+ "fill", /* keywords */
+ NULL, /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw)
diff --git a/test/overlapping-dash-caps.c b/test/overlapping-dash-caps.c
new file mode 100644
index 000000000..f7ba248c2
--- /dev/null
+++ b/test/overlapping-dash-caps.c
@@ -0,0 +1,67 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+#define SIZE 100
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ double dashes1[] = {20, 10};
+ double dashes2[] = {10, 1};
+
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+ cairo_set_line_width (cr, 15);
+
+ cairo_set_dash (cr, dashes1, 2, 0);
+ cairo_new_sub_path (cr);
+ cairo_arc (cr, SIZE/2, SIZE/2, SIZE/2-10, 0, 2*M_PI);
+
+ cairo_set_source_rgba (cr, 1, 0, 0, 0.5);
+ cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
+ cairo_stroke (cr);
+
+ cairo_set_dash (cr, dashes2, 2, 0);
+ cairo_new_sub_path (cr);
+ cairo_arc (cr, SIZE/2, SIZE/2, SIZE/4-5, 0, 2*M_PI);
+
+ cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE);
+ cairo_set_source_rgba (cr, 0, 1, 0, 0.5);
+ cairo_stroke (cr);
+
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (overlapping_dash_caps,
+ "Test intersections between neighbouring dash segments",
+ "overlap, dash", /* keywords */
+ NULL, /* requirements */
+ SIZE, SIZE,
+ NULL, draw)
diff --git a/test/overlapping-glyphs.c b/test/overlapping-glyphs.c
new file mode 100644
index 000000000..93067abc7
--- /dev/null
+++ b/test/overlapping-glyphs.c
@@ -0,0 +1,123 @@
+/*
+ * Copyright © 2009 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Chris Wilson not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Chris Wilson makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+#include <assert.h>
+
+#define TEXT_SIZE 12
+#define HEIGHT (TEXT_SIZE + 4)
+#define WIDTH 50
+
+#define MAX_GLYPHS 80
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_glyph_t glyphs_stack[MAX_GLYPHS], *glyphs;
+ const char *cairo = "Cairo";
+ const char *giza = "Giza";
+ cairo_text_extents_t cairo_extents;
+ cairo_text_extents_t giza_extents;
+ int count, num_glyphs;
+ double x0, y0;
+
+ /* We draw in the default black, so paint white first. */
+ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */
+ cairo_paint (cr);
+
+ cairo_select_font_face (cr, CAIRO_TEST_FONT_FAMILY " Sans",
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_NORMAL);
+ cairo_set_font_size (cr, TEXT_SIZE);
+
+ /* We want to overlap two strings, so compute overlapping glyphs. */
+
+ cairo_text_extents (cr, cairo, &cairo_extents);
+ cairo_text_extents (cr, giza, &giza_extents);
+
+ x0 = WIDTH/2. - (cairo_extents.width/2. + cairo_extents.x_bearing);
+ y0 = HEIGHT/2. - (cairo_extents.height/2. + cairo_extents.y_bearing);
+ glyphs = glyphs_stack;
+ count = MAX_GLYPHS;
+ cairo_scaled_font_text_to_glyphs (cairo_get_scaled_font (cr),
+ x0, y0,
+ cairo, strlen (cairo),
+ &glyphs, &count,
+ NULL, NULL,
+ NULL);
+ assert (glyphs == glyphs_stack);
+ num_glyphs = count;
+
+ x0 = WIDTH/2. - (giza_extents.width/2. + giza_extents.x_bearing);
+ y0 = HEIGHT/2. - (giza_extents.height/2. + giza_extents.y_bearing);
+ glyphs = glyphs_stack + count;
+ count = MAX_GLYPHS - count;
+ cairo_scaled_font_text_to_glyphs (cairo_get_scaled_font (cr),
+ x0, y0,
+ giza, strlen (giza),
+ &glyphs, &count,
+ NULL, NULL,
+ NULL);
+ assert (glyphs == glyphs_stack + num_glyphs);
+ glyphs = glyphs_stack;
+ num_glyphs += count;
+
+ cairo_set_source_rgba (cr, 0, 0, 0, .5); /* translucent black, gray! */
+ cairo_show_glyphs (cr, glyphs, num_glyphs);
+
+ /* and compare with filling */
+ cairo_translate (cr, 0, HEIGHT);
+ cairo_glyph_path (cr, glyphs, num_glyphs);
+ cairo_fill (cr);
+
+ /* switch to using an unbounded operator for added complexity */
+ cairo_set_operator (cr, CAIRO_OPERATOR_IN);
+
+ cairo_translate (cr, WIDTH, -HEIGHT);
+ cairo_save (cr);
+ cairo_rectangle (cr, 0, 0, WIDTH, HEIGHT);
+ cairo_clip (cr);
+ cairo_show_glyphs (cr, glyphs, num_glyphs);
+ cairo_restore (cr);
+
+ cairo_translate (cr, 0, HEIGHT);
+ cairo_save (cr);
+ cairo_rectangle (cr, 0, 0, WIDTH, HEIGHT);
+ cairo_clip (cr);
+ cairo_glyph_path (cr, glyphs, num_glyphs);
+ cairo_fill (cr);
+ cairo_restore (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (overlapping_glyphs,
+ "Test handing of overlapping glyphs",
+ "text, glyphs", /* keywords */
+ NULL, /* requirements */
+ 2 * WIDTH, 2 * HEIGHT,
+ NULL, draw)
+
diff --git a/test/paint-clip-fill.c b/test/paint-clip-fill.c
new file mode 100644
index 000000000..5a9e24ffb
--- /dev/null
+++ b/test/paint-clip-fill.c
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2011 SCore Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Taekyun Kim <podain77@gmail.com>
+ */
+
+#include "cairo-test.h"
+
+static void
+rounded_rectangle(cairo_t *cr,
+ double x, double y,
+ double width, double height,
+ double radius)
+{
+ cairo_move_to (cr, x, y + radius);
+ cairo_line_to (cr, x, y + height - radius);
+ cairo_curve_to (cr, x, y + height - radius/2.0,
+ x + radius/2.0, y + height,
+ x + radius, y + height);
+ cairo_line_to (cr, x + width - radius, y + height);
+ cairo_curve_to (cr, x + width - radius/2.0, y + height,
+ x + width, y + height - radius/2.0,
+ x + width, y + height - radius);
+ cairo_line_to (cr, x + width, y + radius);
+ cairo_curve_to (cr, x + width, y + radius/2.0,
+ x + width - radius/2.0, y,
+ x + width - radius, y);
+ cairo_line_to (cr, x + radius, y);
+ cairo_curve_to (cr, x + radius/2.0, y, x, y + radius/2.0, x, y + radius);
+ cairo_close_path(cr);
+}
+
+static cairo_test_status_t
+draw_mono (cairo_t *cr, int width, int height)
+{
+ cairo_set_antialias(cr, CAIRO_ANTIALIAS_NONE);
+ cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
+ cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 1.0);
+ cairo_paint(cr);
+
+ cairo_rectangle(cr, 20, 20, 60, 60);
+ cairo_clip(cr);
+
+ rounded_rectangle(cr, 0, 0, 100, 100, 10);
+ cairo_clip(cr);
+
+ cairo_set_source_rgba(cr, 1.0, 0.0, 0.0, 1.0);
+ cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
+ cairo_paint(cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+draw_aa (cairo_t *cr, int width, int height)
+{
+ cairo_set_antialias(cr, CAIRO_ANTIALIAS_DEFAULT);
+ cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
+ cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 1.0);
+ cairo_paint(cr);
+
+ cairo_rectangle(cr, 20, 20, 60, 60);
+ cairo_clip(cr);
+
+ rounded_rectangle(cr, 0, 0, 100, 100, 10);
+ cairo_clip(cr);
+
+ cairo_set_source_rgba(cr, 1.0, 0.0, 0.0, 1.0);
+ cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
+ cairo_paint(cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (paint_clip_fill_mono,
+ "Test reduction of a paint with a clip",
+ "paint, clip", /* keywords */
+ NULL, /* requirements */
+ 100, 100,
+ NULL, draw_mono)
+CAIRO_TEST (paint_clip_fill_aa,
+ "Test reduction of a paint with a clip",
+ "paint, clip", /* keywords */
+ NULL, /* requirements */
+ 100, 100,
+ NULL, draw_aa)
diff --git a/test/paint-repeat.c b/test/paint-repeat.c
new file mode 100644
index 000000000..c48d84c0e
--- /dev/null
+++ b/test/paint-repeat.c
@@ -0,0 +1,61 @@
+/*
+ * Copyright © 2005 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+#include "cairo-test.h"
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_surface_t *surface;
+ uint32_t data[16] = {
+ 0xffffffff, 0xffffffff, 0xffff0000, 0xffff0000,
+ 0xffffffff, 0xffffffff, 0xffff0000, 0xffff0000,
+
+ 0xff00ff00, 0xff00ff00, 0xff0000ff, 0xff0000ff,
+ 0xff00ff00, 0xff00ff00, 0xff0000ff, 0xff0000ff
+ };
+
+ surface = cairo_image_surface_create_for_data ((unsigned char *) data,
+ CAIRO_FORMAT_RGB24, 4, 4, 16);
+
+ /* We use a non-zero offset larger than the source surface size to
+ * stress cairo out a bit more. */
+ cairo_set_source_surface (cr, surface, 10, 10);
+ cairo_pattern_set_filter (cairo_get_source (cr), CAIRO_FILTER_NEAREST);
+ cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_REPEAT);
+ cairo_paint (cr);
+
+ cairo_surface_finish (surface); /* data will go out of scope */
+ cairo_surface_destroy (surface);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (paint_repeat,
+ "Test calls to cairo_paint with a repeating source surface pattern",
+ "paint", /* keywords */
+ NULL, /* requirements */
+ 8, 8,
+ NULL, draw)
diff --git a/test/paint-source-alpha.c b/test/paint-source-alpha.c
new file mode 100644
index 000000000..cb2d488ca
--- /dev/null
+++ b/test/paint-source-alpha.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright © 2005 Red Hat, Inc.
+ * Copyright © 2006 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+#include "cairo-test.h"
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_surface_t *surface;
+ uint32_t data[16] = {
+ 0x80808080, 0x80808080, 0x80800000, 0x80800000,
+ 0x80808080, 0x80808080, 0x80800000, 0x80800000,
+
+ 0x80008000, 0x80008000, 0x80000080, 0x80000080,
+ 0x80008000, 0x80008000, 0x80000080, 0x80000080
+ };
+
+ surface = cairo_image_surface_create_for_data ((unsigned char *) data,
+ CAIRO_FORMAT_ARGB32, 4, 4, 16);
+
+ cairo_test_paint_checkered (cr);
+
+ cairo_scale (cr, 4, 4);
+
+ cairo_set_source_surface (cr, surface, 2 , 2);
+ cairo_pattern_set_filter (cairo_get_source (cr), CAIRO_FILTER_NEAREST);
+ cairo_paint (cr);
+
+ cairo_surface_finish (surface); /* data will go out of scope */
+ cairo_surface_destroy (surface);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (paint_source_alpha,
+ "Simple test of cairo_paint with a source surface with non-opaque alpha",
+ "paint, alpha", /* keywords */
+ NULL, /* requirements */
+ 32, 32,
+ NULL, draw)
diff --git a/test/paint-with-alpha-group-clip.c b/test/paint-with-alpha-group-clip.c
new file mode 100644
index 000000000..e1e438330
--- /dev/null
+++ b/test/paint-with-alpha-group-clip.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright © 2013 Adrian Johnson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Adrian Johnson <ajohnson@redneon.com>
+ */
+
+/*
+ * This attempts to exercise the bug found in
+ *
+ * https://bugs.launchpad.net/inkscape/+bug/1258265
+ */
+
+
+#include "cairo-test.h"
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+ cairo_push_group (cr);
+ cairo_push_group (cr);
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ cairo_paint (cr);
+ cairo_pop_group_to_source (cr);
+ cairo_paint_with_alpha (cr, 0.25);
+ cairo_pop_group_to_source (cr);
+ cairo_rectangle (cr, 5, 5, 20, 20);
+ cairo_clip (cr);
+ cairo_paint (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (paint_with_alpha_group_clip,
+ "Test paint with alpha and clipping",
+ "paint alpha clip group record", /* keywords */
+ NULL, /* requirements */
+ 30, 30,
+ NULL, draw)
diff --git a/test/paint-with-alpha.c b/test/paint-with-alpha.c
new file mode 100644
index 000000000..8daa935f7
--- /dev/null
+++ b/test/paint-with-alpha.c
@@ -0,0 +1,148 @@
+/*
+ * Copyright © 2005 Red Hat, Inc.
+ * Copyright © 2006 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+#include "cairo-test.h"
+
+static uint32_t data[16] = {
+ 0xffffffff, 0xffffffff, 0xffff0000, 0xffff0000,
+ 0xffffffff, 0xffffffff, 0xffff0000, 0xffff0000,
+
+ 0xff00ff00, 0xff00ff00, 0xff0000ff, 0xff0000ff,
+ 0xff00ff00, 0xff00ff00, 0xff0000ff, 0xff0000ff
+};
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_surface_t *surface;
+
+ surface = cairo_image_surface_create_for_data ((unsigned char *) data,
+ CAIRO_FORMAT_RGB24, 4, 4, 16);
+
+ cairo_test_paint_checkered (cr);
+
+ cairo_scale (cr, 4, 4);
+
+ cairo_set_source_surface (cr, surface, 2 , 2);
+ cairo_pattern_set_filter (cairo_get_source (cr), CAIRO_FILTER_NEAREST);
+ cairo_paint_with_alpha (cr, 0.5);
+
+ cairo_surface_finish (surface); /* data will go out of scope */
+ cairo_surface_destroy (surface);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+draw_solid_clip (cairo_t *cr, int width, int height)
+{
+ cairo_test_paint_checkered (cr);
+
+ cairo_rectangle (cr, 2.5, 2.5, 27, 27);
+ cairo_clip (cr);
+
+ cairo_set_source_rgb (cr, 1., 0.,0.);
+ cairo_paint_with_alpha (cr, 0.5);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+draw_clip (cairo_t *cr, int width, int height)
+{
+ cairo_surface_t *surface;
+
+ surface = cairo_image_surface_create_for_data ((unsigned char *) data,
+ CAIRO_FORMAT_RGB24, 4, 4, 16);
+
+ cairo_test_paint_checkered (cr);
+
+ cairo_rectangle (cr, 10.5, 10.5, 11, 11);
+ cairo_clip (cr);
+
+ cairo_scale (cr, 4, 4);
+
+ cairo_set_source_surface (cr, surface, 2 , 2);
+ cairo_pattern_set_filter (cairo_get_source (cr), CAIRO_FILTER_NEAREST);
+ cairo_paint_with_alpha (cr, 0.5);
+
+ cairo_surface_finish (surface); /* data will go out of scope */
+ cairo_surface_destroy (surface);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+draw_clip_mask (cairo_t *cr, int width, int height)
+{
+ cairo_surface_t *surface;
+
+ surface = cairo_image_surface_create_for_data ((unsigned char *) data,
+ CAIRO_FORMAT_RGB24, 4, 4, 16);
+
+ cairo_test_paint_checkered (cr);
+
+ cairo_move_to (cr, 16, 5);
+ cairo_line_to (cr, 5, 16);
+ cairo_line_to (cr, 16, 27);
+ cairo_line_to (cr, 27, 16);
+ cairo_clip (cr);
+
+ cairo_scale (cr, 4, 4);
+
+ cairo_set_source_surface (cr, surface, 2 , 2);
+ cairo_pattern_set_filter (cairo_get_source (cr), CAIRO_FILTER_NEAREST);
+ cairo_paint_with_alpha (cr, 0.5);
+
+ cairo_surface_finish (surface); /* data will go out of scope */
+ cairo_surface_destroy (surface);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (paint_with_alpha,
+ "Simple test of cairo_paint_with_alpha",
+ "paint, alpha", /* keywords */
+ NULL, /* requirements */
+ 32, 32,
+ NULL, draw)
+CAIRO_TEST (paint_with_alpha_solid_clip,
+ "Simple test of cairo_paint_with_alpha+unaligned clip",
+ "paint, alpha, clip", /* keywords */
+ NULL, /* requirements */
+ 32, 32,
+ NULL, draw_solid_clip)
+CAIRO_TEST (paint_with_alpha_clip,
+ "Simple test of cairo_paint_with_alpha+unaligned clip",
+ "paint, alpha, clip", /* keywords */
+ NULL, /* requirements */
+ 32, 32,
+ NULL, draw_clip)
+CAIRO_TEST (paint_with_alpha_clip_mask,
+ "Simple test of cairo_paint_with_alpha+unaligned clip",
+ "paint, alpha, clip", /* keywords */
+ NULL, /* requirements */
+ 32, 32,
+ NULL, draw_clip_mask)
diff --git a/test/paint.c b/test/paint.c
new file mode 100644
index 000000000..c5fd648e3
--- /dev/null
+++ b/test/paint.c
@@ -0,0 +1,48 @@
+/*
+ * Copyright © 2005 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+#include "cairo-test.h"
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_set_source_rgb (cr, 0, 0, 1);
+ cairo_paint (cr);
+
+ cairo_translate (cr, 2, 2);
+ cairo_scale (cr, 0.5, 0.5);
+
+ cairo_set_source_rgb (cr, 1, 0, 0);
+ cairo_paint (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (paint,
+ "Test calls to cairo_paint",
+ "paint", /* keywords */
+ NULL, /* requirements */
+ 8, 8,
+ NULL, draw)
diff --git a/test/partial-clip-text.c b/test/partial-clip-text.c
new file mode 100644
index 000000000..4d8bae077
--- /dev/null
+++ b/test/partial-clip-text.c
@@ -0,0 +1,120 @@
+/*
+ * Copyright 2010 Igor Nikitin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Igor Nikitin <igor_nikitin@valentina-db.com>
+ */
+
+#include "cairo-test.h"
+
+#define HEIGHT 15
+#define WIDTH 40
+
+static void background (cairo_t *cr)
+{
+ cairo_set_source_rgb( cr, 0, 0, 0 );
+ cairo_paint (cr);
+}
+
+static void text (cairo_t *cr)
+{
+ cairo_move_to (cr, 0, 12);
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_show_text (cr, "CAIRO");
+}
+
+static cairo_test_status_t
+top (cairo_t *cr, int width, int height)
+{
+ background (cr);
+
+ cairo_rectangle (cr, 0, 0, WIDTH, 5);
+ cairo_clip (cr);
+
+ text (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+bottom (cairo_t *cr, int width, int height)
+{
+ background (cr);
+
+ cairo_rectangle (cr, 0, HEIGHT-5, WIDTH, 5);
+ cairo_clip (cr);
+
+ text (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+left (cairo_t *cr, int width, int height)
+{
+ background (cr);
+
+ cairo_rectangle (cr, 0, 0, 10, HEIGHT);
+ cairo_clip (cr);
+
+ text (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+right (cairo_t *cr, int width, int height)
+{
+ background (cr);
+
+ cairo_rectangle (cr, WIDTH-10, 0, 10, HEIGHT);
+ cairo_clip (cr);
+
+ text (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (partial_clip_text_top,
+ "Tests drawing text through a single, partial clip.",
+ "clip, text", /* keywords */
+ NULL, /* requirements */
+ WIDTH, HEIGHT,
+ NULL, top)
+CAIRO_TEST (partial_clip_text_bottom,
+ "Tests drawing text through a single, partial clip.",
+ "clip, text", /* keywords */
+ NULL, /* requirements */
+ WIDTH, HEIGHT,
+ NULL, bottom)
+CAIRO_TEST (partial_clip_text_left,
+ "Tests drawing text through a single, partial clip.",
+ "clip, text", /* keywords */
+ NULL, /* requirements */
+ WIDTH, HEIGHT,
+ NULL, left)
+CAIRO_TEST (partial_clip_text_right,
+ "Tests drawing text through a single, partial clip.",
+ "clip, text", /* keywords */
+ NULL, /* requirements */
+ WIDTH, HEIGHT,
+ NULL, right)
diff --git a/test/partial-coverage.c b/test/partial-coverage.c
new file mode 100644
index 000000000..7e67a5e16
--- /dev/null
+++ b/test/partial-coverage.c
@@ -0,0 +1,680 @@
+/*
+ * Copyright 2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+/* Test the sampling stratagems of the rasterisers by creating pixels
+ * containing minute holes and seeing how close to the expected
+ * coverage each rasteriser approaches.
+ */
+
+#define SIZE 64
+
+#include "../src/cairo-fixed-type-private.h"
+#define SAMPLE (1 << CAIRO_FIXED_FRAC_BITS)
+
+static uint32_t state;
+
+static uint32_t
+hars_petruska_f54_1_random (void)
+{
+#define rol(x,k) ((x << k) | (x >> (32-k)))
+ return state = (state ^ rol (state, 5) ^ rol (state, 24)) + 0x37798849;
+#undef rol
+}
+
+static double
+uniform_random (void)
+{
+ return hars_petruska_f54_1_random() / (double) UINT32_MAX;
+}
+
+/* coverage is given in [0,sample] */
+static void
+compute_occupancy (uint8_t *occupancy, int coverage, int sample)
+{
+ int i, c;
+
+ if (coverage < sample/2) {
+ memset (occupancy, 0, sample);
+ if (coverage == 0)
+ return;
+
+ for (i = c = 0; i < sample; i++) {
+ if ((sample - i) * uniform_random() < coverage - c) {
+ occupancy[i] = 0xff;
+ if (++c == coverage)
+ return;
+ }
+ }
+ } else {
+ coverage = sample - coverage;
+ memset (occupancy, 0xff, sample);
+ if (coverage == 0)
+ return;
+
+ for (i = c = 0; i < sample; i++) {
+ if ((sample - i) * uniform_random() < coverage - c) {
+ occupancy[i] = 0;
+ if (++c == coverage)
+ return;
+ }
+ }
+ }
+}
+
+static cairo_test_status_t
+reference (cairo_t *cr, int width, int height)
+{
+ int i;
+
+ cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
+ cairo_paint (cr);
+
+ for (i = 0; i < SIZE*SIZE; i++) {
+ cairo_set_source_rgba (cr, 1., 1., 1.,
+ i / (double) (SIZE * SIZE));
+ cairo_rectangle (cr, i % SIZE, i / SIZE, 1, 1);
+ cairo_fill (cr);
+ }
+
+ return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_test_status_t
+three_quarter_reference (cairo_t *cr, int width, int height)
+{
+ int i;
+
+ cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
+ cairo_paint (cr);
+
+ for (i = 0; i < SIZE*SIZE; i++) {
+ cairo_set_source_rgba (cr, 1., 1., 1.,
+ .75 * i / (double) (SIZE * SIZE));
+ cairo_rectangle (cr, i % SIZE, i / SIZE, 1, 1);
+ cairo_fill (cr);
+ }
+
+ return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_test_status_t
+half_reference (cairo_t *cr, int width, int height)
+{
+ int i;
+
+ cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
+ cairo_paint (cr);
+
+ for (i = 0; i < SIZE*SIZE; i++) {
+ cairo_set_source_rgba (cr, 1., 1., 1.,
+ .5 * i / (double) (SIZE * SIZE));
+ cairo_rectangle (cr, i % SIZE, i / SIZE, 1, 1);
+ cairo_fill (cr);
+ }
+
+ return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_test_status_t
+rectangles (cairo_t *cr, int width, int height)
+{
+ uint8_t *occupancy;
+ int i, j, channel;
+
+ state = 0x12345678;
+ occupancy = xmalloc (SAMPLE*SAMPLE);
+
+ cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
+ cairo_paint (cr);
+
+ cairo_set_operator (cr, CAIRO_OPERATOR_ADD);
+ for (channel = 0; channel < 3; channel++) {
+ switch (channel) {
+ default:
+ case 0: cairo_set_source_rgb (cr, 1.0, 0.0, 0.0); break;
+ case 1: cairo_set_source_rgb (cr, 0.0, 1.0, 0.0); break;
+ case 2: cairo_set_source_rgb (cr, 0.0, 0.0, 1.0); break;
+ }
+
+ for (i = 0; i < SIZE*SIZE; i++) {
+ int xs, ys;
+
+ compute_occupancy (occupancy, SAMPLE*SAMPLE * i / (SIZE * SIZE), SAMPLE*SAMPLE);
+
+ xs = i % SIZE * SAMPLE;
+ ys = i / SIZE * SAMPLE;
+ for (j = 0; j < SAMPLE*SAMPLE; j++) {
+ if (occupancy[j]) {
+ cairo_rectangle (cr,
+ (j % SAMPLE + xs) / (double) SAMPLE,
+ (j / SAMPLE + ys) / (double) SAMPLE,
+ 1 / (double) SAMPLE,
+ 1 / (double) SAMPLE);
+ }
+ }
+ cairo_fill (cr);
+ }
+ }
+
+ free (occupancy);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+intersecting_quads (cairo_t *cr, int width, int height)
+{
+ uint8_t *occupancy;
+ int i, j, channel;
+
+ state = 0x12345678;
+ occupancy = xmalloc (SAMPLE*SAMPLE);
+
+ cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
+ cairo_paint (cr);
+
+ cairo_set_operator (cr, CAIRO_OPERATOR_ADD);
+ for (channel = 0; channel < 3; channel++) {
+ switch (channel) {
+ default:
+ case 0: cairo_set_source_rgb (cr, 1.0, 0.0, 0.0); break;
+ case 1: cairo_set_source_rgb (cr, 0.0, 1.0, 0.0); break;
+ case 2: cairo_set_source_rgb (cr, 0.0, 0.0, 1.0); break;
+ }
+
+ for (i = 0; i < SIZE*SIZE; i++) {
+ int xs, ys;
+
+ compute_occupancy (occupancy, SAMPLE*SAMPLE * i / (SIZE * SIZE), SAMPLE*SAMPLE);
+
+ xs = i % SIZE * SAMPLE;
+ ys = i / SIZE * SAMPLE;
+ for (j = 0; j < SAMPLE*SAMPLE; j++) {
+ if (occupancy[j]) {
+ cairo_move_to (cr,
+ (j % SAMPLE + xs) / (double) SAMPLE,
+ (j / SAMPLE + ys) / (double) SAMPLE);
+ cairo_rel_line_to (cr, 1 / (double) SAMPLE, 1 / (double) SAMPLE);
+ cairo_rel_line_to (cr, 0, -1 / (double) SAMPLE);
+ cairo_rel_line_to (cr, -1 / (double) SAMPLE, 1 / (double) SAMPLE);
+ cairo_close_path (cr);
+ }
+ }
+ cairo_fill (cr);
+ }
+ }
+
+ free (occupancy);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+half_triangles (cairo_t *cr, int width, int height)
+{
+ uint8_t *occupancy;
+ int i, j, channel;
+
+ state = 0x12345678;
+ occupancy = xmalloc (SAMPLE*SAMPLE);
+
+ cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
+ cairo_paint (cr);
+
+ cairo_set_operator (cr, CAIRO_OPERATOR_ADD);
+ for (channel = 0; channel < 3; channel++) {
+ switch (channel) {
+ default:
+ case 0: cairo_set_source_rgb (cr, 1.0, 0.0, 0.0); break;
+ case 1: cairo_set_source_rgb (cr, 0.0, 1.0, 0.0); break;
+ case 2: cairo_set_source_rgb (cr, 0.0, 0.0, 1.0); break;
+ }
+
+ for (i = 0; i < SIZE*SIZE; i++) {
+ int xs, ys;
+
+ compute_occupancy (occupancy, SAMPLE*SAMPLE * i / (SIZE * SIZE), SAMPLE*SAMPLE);
+
+ xs = i % SIZE * SAMPLE;
+ ys = i / SIZE * SAMPLE;
+ for (j = 0; j < SAMPLE*SAMPLE; j++) {
+ if (occupancy[j]) {
+ int x = j % SAMPLE + xs;
+ int y = j / SAMPLE + ys;
+ cairo_move_to (cr, x / (double) SAMPLE, y / (double) SAMPLE);
+ cairo_line_to (cr, (x+1) / (double) SAMPLE, (y+1) / (double) SAMPLE);
+ cairo_line_to (cr, (x+1) / (double) SAMPLE, y / (double) SAMPLE);
+ cairo_close_path (cr);
+ }
+ }
+ cairo_fill (cr);
+ }
+ }
+
+ free (occupancy);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+overlap_half_triangles (cairo_t *cr, int width, int height)
+{
+ uint8_t *occupancy;
+ int i, j, channel;
+
+ state = 0x12345678;
+ occupancy = xmalloc (SAMPLE*SAMPLE);
+
+ cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
+ cairo_paint (cr);
+
+ cairo_set_operator (cr, CAIRO_OPERATOR_ADD);
+ for (channel = 0; channel < 3; channel++) {
+ switch (channel) {
+ default:
+ case 0: cairo_set_source_rgb (cr, 1.0, 0.0, 0.0); break;
+ case 1: cairo_set_source_rgb (cr, 0.0, 1.0, 0.0); break;
+ case 2: cairo_set_source_rgb (cr, 0.0, 0.0, 1.0); break;
+ }
+
+ for (i = 0; i < SIZE*SIZE; i++) {
+ int xs, ys;
+
+ compute_occupancy (occupancy, SAMPLE/2*SAMPLE/2 * i / (SIZE * SIZE), SAMPLE/2*SAMPLE/2);
+
+ xs = i % SIZE * SAMPLE;
+ ys = i / SIZE * SAMPLE;
+ for (j = 0; j < SAMPLE/2*SAMPLE/2; j++) {
+ if (occupancy[j]) {
+ int x = 2 * (j % (SAMPLE/2)) + xs;
+ int y = 2 * (j / (SAMPLE/2)) + ys;
+
+ /* Add a 4-tile composed of two overlapping triangles.
+ * .__.__.
+ * |\ /|
+ * | \ / |
+ * . x |
+ * | / \ |
+ * |/ \|
+ * . .
+ *
+ * Coverage should be computable as 50% (due to counter-winding).
+ */
+
+ cairo_move_to (cr, (x) / (double) SAMPLE, (y) / (double) SAMPLE);
+ cairo_line_to (cr, (x) / (double) SAMPLE, (y+2) / (double) SAMPLE);
+ cairo_line_to (cr, (x+2) / (double) SAMPLE, (y) / (double) SAMPLE);
+ cairo_close_path (cr);
+
+ cairo_move_to (cr, (x) / (double) SAMPLE, (y) / (double) SAMPLE);
+ cairo_line_to (cr, (x+2) / (double) SAMPLE, (y) / (double) SAMPLE);
+ cairo_line_to (cr, (x+2) / (double) SAMPLE, (y+2) / (double) SAMPLE);
+ cairo_close_path (cr);
+ }
+ }
+ cairo_fill (cr);
+ }
+ }
+
+ free (occupancy);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+overlap_half_triangles_eo (cairo_t *cr, int width, int height)
+{
+ uint8_t *occupancy;
+ int i, j, channel;
+
+ state = 0x12345678;
+ occupancy = xmalloc (SAMPLE*SAMPLE);
+
+ cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
+ cairo_paint (cr);
+
+ cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
+
+ cairo_set_operator (cr, CAIRO_OPERATOR_ADD);
+ for (channel = 0; channel < 3; channel++) {
+ switch (channel) {
+ default:
+ case 0: cairo_set_source_rgb (cr, 1.0, 0.0, 0.0); break;
+ case 1: cairo_set_source_rgb (cr, 0.0, 1.0, 0.0); break;
+ case 2: cairo_set_source_rgb (cr, 0.0, 0.0, 1.0); break;
+ }
+
+ for (i = 0; i < SIZE*SIZE; i++) {
+ int xs, ys;
+
+ compute_occupancy (occupancy, SAMPLE/2*SAMPLE/2 * i / (SIZE * SIZE), SAMPLE/2*SAMPLE/2);
+
+ xs = i % SIZE * SAMPLE;
+ ys = i / SIZE * SAMPLE;
+ for (j = 0; j < SAMPLE/2*SAMPLE/2; j++) {
+ if (occupancy[j]) {
+ int x = 2 * (j % (SAMPLE/2)) + xs;
+ int y = 2 * (j / (SAMPLE/2)) + ys;
+
+ /* Add a 4-tile composed of two overlapping triangles.
+ * .__.__.
+ * |\ /|
+ * | \ / |
+ * . x |
+ * | / \ |
+ * |/ \|
+ * . .
+ *
+ * Coverage should be computable as 50%, due to even-odd fill rule.
+ */
+
+ cairo_move_to (cr, (x) / (double) SAMPLE, (y) / (double) SAMPLE);
+ cairo_line_to (cr, (x) / (double) SAMPLE, (y+2) / (double) SAMPLE);
+ cairo_line_to (cr, (x+2) / (double) SAMPLE, (y) / (double) SAMPLE);
+ cairo_close_path (cr);
+
+ cairo_move_to (cr, (x) / (double) SAMPLE, (y) / (double) SAMPLE);
+ cairo_line_to (cr, (x+2) / (double) SAMPLE, (y+2) / (double) SAMPLE);
+ cairo_line_to (cr, (x+2) / (double) SAMPLE, (y) / (double) SAMPLE);
+ cairo_close_path (cr);
+ }
+ }
+ cairo_fill (cr);
+ }
+ }
+
+ free (occupancy);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+overlap_three_quarter_triangles (cairo_t *cr, int width, int height)
+{
+ uint8_t *occupancy;
+ int i, j, channel;
+
+ state = 0x12345678;
+ occupancy = xmalloc (SAMPLE*SAMPLE);
+
+ cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
+ cairo_paint (cr);
+
+ cairo_set_operator (cr, CAIRO_OPERATOR_ADD);
+ for (channel = 0; channel < 3; channel++) {
+ switch (channel) {
+ default:
+ case 0: cairo_set_source_rgb (cr, 1.0, 0.0, 0.0); break;
+ case 1: cairo_set_source_rgb (cr, 0.0, 1.0, 0.0); break;
+ case 2: cairo_set_source_rgb (cr, 0.0, 0.0, 1.0); break;
+ }
+
+ for (i = 0; i < SIZE*SIZE; i++) {
+ int xs, ys;
+
+ compute_occupancy (occupancy, SAMPLE/2*SAMPLE/2 * i / (SIZE * SIZE), SAMPLE/2*SAMPLE/2);
+
+ xs = i % SIZE * SAMPLE;
+ ys = i / SIZE * SAMPLE;
+ for (j = 0; j < SAMPLE/2*SAMPLE/2; j++) {
+ if (occupancy[j]) {
+ int x = 2 * (j % (SAMPLE/2)) + xs;
+ int y = 2 * (j / (SAMPLE/2)) + ys;
+
+ /* Add a 4-tile composed of two overlapping triangles.
+ * .__.__.
+ * |\ /|
+ * | \ / |
+ * . x |
+ * | / \ |
+ * |/ \|
+ * . .
+ *
+ * Coverage should be computable as 75%.
+ */
+
+ cairo_move_to (cr, (x) / (double) SAMPLE, (y) / (double) SAMPLE);
+ cairo_line_to (cr, (x) / (double) SAMPLE, (y+2) / (double) SAMPLE);
+ cairo_line_to (cr, (x+2) / (double) SAMPLE, (y) / (double) SAMPLE);
+ cairo_close_path (cr);
+
+ cairo_move_to (cr, (x) / (double) SAMPLE, (y) / (double) SAMPLE);
+ cairo_line_to (cr, (x+2) / (double) SAMPLE, (y+2) / (double) SAMPLE);
+ cairo_line_to (cr, (x+2) / (double) SAMPLE, (y) / (double) SAMPLE);
+ cairo_close_path (cr);
+ }
+ }
+ cairo_fill (cr);
+ }
+ }
+
+ free (occupancy);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+triangles (cairo_t *cr, int width, int height)
+{
+ uint8_t *occupancy;
+ int i, j, channel;
+
+ state = 0x12345678;
+ occupancy = xmalloc (SAMPLE*SAMPLE);
+
+ cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
+ cairo_paint (cr);
+
+ cairo_set_operator (cr, CAIRO_OPERATOR_ADD);
+ for (channel = 0; channel < 3; channel++) {
+ switch (channel) {
+ default:
+ case 0: cairo_set_source_rgb (cr, 1.0, 0.0, 0.0); break;
+ case 1: cairo_set_source_rgb (cr, 0.0, 1.0, 0.0); break;
+ case 2: cairo_set_source_rgb (cr, 0.0, 0.0, 1.0); break;
+ }
+
+ for (i = 0; i < SIZE*SIZE; i++) {
+ int xs, ys;
+
+ compute_occupancy (occupancy, SAMPLE*SAMPLE * i / (SIZE * SIZE), SAMPLE*SAMPLE);
+
+ xs = i % SIZE * SAMPLE;
+ ys = i / SIZE * SAMPLE;
+ for (j = 0; j < SAMPLE*SAMPLE; j++) {
+ if (occupancy[j]) {
+ /* Add a tile composed of two non-overlapping triangles.
+ * .__.
+ * | /|
+ * |/ |
+ * .--.
+ */
+ int x = j % SAMPLE + xs;
+ int y = j / SAMPLE + ys;
+
+ /* top-left triangle */
+ cairo_move_to (cr, (x) / (double) SAMPLE, (y) / (double) SAMPLE);
+ cairo_line_to (cr, (x+1) / (double) SAMPLE, (y) / (double) SAMPLE);
+ cairo_line_to (cr, (x) / (double) SAMPLE, (y+1) / (double) SAMPLE);
+ cairo_close_path (cr);
+
+ /* bottom-right triangle */
+ cairo_move_to (cr, (x) / (double) SAMPLE, (y+1) / (double) SAMPLE);
+ cairo_line_to (cr, (x+1) / (double) SAMPLE, (y+1) / (double) SAMPLE);
+ cairo_line_to (cr, (x+1) / (double) SAMPLE, (y) / (double) SAMPLE);
+ cairo_close_path (cr);
+ }
+ }
+ cairo_fill (cr);
+ }
+ }
+
+ free (occupancy);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+intersecting_triangles (cairo_t *cr, int width, int height)
+{
+ uint8_t *occupancy;
+ int i, j, channel;
+
+ state = 0x12345678;
+ occupancy = xmalloc (SAMPLE*SAMPLE);
+
+ cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
+ cairo_paint (cr);
+
+ cairo_set_operator (cr, CAIRO_OPERATOR_ADD);
+ for (channel = 0; channel < 3; channel++) {
+ switch (channel) {
+ default:
+ case 0: cairo_set_source_rgb (cr, 1.0, 0.0, 0.0); break;
+ case 1: cairo_set_source_rgb (cr, 0.0, 1.0, 0.0); break;
+ case 2: cairo_set_source_rgb (cr, 0.0, 0.0, 1.0); break;
+ }
+
+ for (i = 0; i < SIZE*SIZE; i++) {
+ int xs, ys;
+
+ compute_occupancy (occupancy, SAMPLE*SAMPLE * i / (SIZE * SIZE), SAMPLE*SAMPLE);
+
+ xs = i % SIZE * SAMPLE;
+ ys = i / SIZE * SAMPLE;
+ for (j = 0; j < SAMPLE*SAMPLE; j++) {
+ if (occupancy[j]) {
+ /* Add 2 overlapping tiles in a single cell, each composed
+ * of two non-overlapping triangles.
+ * .--. .--.
+ * | /| |\ |
+ * |/ | + | \|
+ * .--. .--.
+ */
+ int x = j % SAMPLE + xs;
+ int y = j / SAMPLE + ys;
+
+ /* first pair of triangles, diagonal bottom-left to top-right */
+ cairo_move_to (cr, (x) / (double) SAMPLE, (y) / (double) SAMPLE);
+ cairo_line_to (cr, (x+1) / (double) SAMPLE, (y) / (double) SAMPLE);
+ cairo_line_to (cr, (x) / (double) SAMPLE, (y+1) / (double) SAMPLE);
+ cairo_close_path (cr);
+ cairo_move_to (cr, (x) / (double) SAMPLE, (y+1) / (double) SAMPLE);
+ cairo_line_to (cr, (x+1) / (double) SAMPLE, (y+1) / (double) SAMPLE);
+ cairo_line_to (cr, (x+1) / (double) SAMPLE, (y) / (double) SAMPLE);
+ cairo_close_path (cr);
+
+ /* second pair of triangles, diagonal top-left to bottom-right */
+ cairo_move_to (cr, (x) / (double) SAMPLE, (y) / (double) SAMPLE);
+ cairo_line_to (cr, (x+1) / (double) SAMPLE, (y+1) / (double) SAMPLE);
+ cairo_line_to (cr, (x+1) / (double) SAMPLE, (y) / (double) SAMPLE);
+ cairo_close_path (cr);
+ cairo_move_to (cr, (x) / (double) SAMPLE, (y) / (double) SAMPLE);
+ cairo_line_to (cr, (x+1) / (double) SAMPLE, (y+1) / (double) SAMPLE);
+ cairo_line_to (cr, (x) / (double) SAMPLE, (y+1) / (double) SAMPLE);
+ cairo_close_path (cr);
+ }
+ }
+ cairo_fill (cr);
+ }
+ }
+
+ free (occupancy);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (partial_coverage_rectangles,
+ "Check the fidelity of the rasterisation.",
+ "coverage, raster", /* keywords */
+ "target=raster slow", /* requirements */
+ SIZE, SIZE,
+ NULL, rectangles)
+
+CAIRO_TEST (partial_coverage_intersecting_quads,
+ "Check the fidelity of the rasterisation.",
+ "coverage, raster", /* keywords */
+ "target=raster slow", /* requirements */
+ SIZE, SIZE,
+ NULL, intersecting_quads)
+
+CAIRO_TEST (partial_coverage_intersecting_triangles,
+ "Check the fidelity of the rasterisation.",
+ "coverage, raster", /* keywords */
+ "target=raster slow", /* requirements */
+ SIZE, SIZE,
+ NULL, intersecting_triangles)
+CAIRO_TEST (partial_coverage_triangles,
+ "Check the fidelity of the rasterisation.",
+ "coverage, raster", /* keywords */
+ "target=raster slow", /* requirements */
+ SIZE, SIZE,
+ NULL, triangles)
+CAIRO_TEST (partial_coverage_overlap_three_quarter_triangles,
+ "Check the fidelity of the rasterisation.",
+ "coverage, raster", /* keywords */
+ "target=raster slow", /* requirements */
+ SIZE, SIZE,
+ NULL, overlap_three_quarter_triangles)
+CAIRO_TEST (partial_coverage_overlap_half_triangles_eo,
+ "Check the fidelity of the rasterisation.",
+ "coverage, raster", /* keywords */
+ "target=raster slow", /* requirements */
+ SIZE, SIZE,
+ NULL, overlap_half_triangles_eo)
+CAIRO_TEST (partial_coverage_overlap_half_triangles,
+ "Check the fidelity of the rasterisation.",
+ "coverage, raster", /* keywords */
+ "target=raster slow", /* requirements */
+ SIZE, SIZE,
+ NULL, overlap_half_triangles)
+CAIRO_TEST (partial_coverage_half_triangles,
+ "Check the fidelity of the rasterisation.",
+ "coverage, raster", /* keywords */
+ "target=raster slow", /* requirements */
+ SIZE, SIZE,
+ NULL, half_triangles)
+
+CAIRO_TEST (partial_coverage_reference,
+ "Check the fidelity of this test.",
+ "coverage, raster", /* keywords */
+ "target=raster", /* requirements */
+ SIZE, SIZE,
+ NULL, reference)
+CAIRO_TEST (partial_coverage_three_quarter_reference,
+ "Check the fidelity of this test.",
+ "coverage, raster", /* keywords */
+ "target=raster", /* requirements */
+ SIZE, SIZE,
+ NULL, three_quarter_reference)
+CAIRO_TEST (partial_coverage_half_reference,
+ "Check the fidelity of this test.",
+ "coverage, raster", /* keywords */
+ "target=raster", /* requirements */
+ SIZE, SIZE,
+ NULL, half_reference)
diff --git a/test/pass-through.c b/test/pass-through.c
new file mode 100644
index 000000000..17a38db99
--- /dev/null
+++ b/test/pass-through.c
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2008 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Chris Wilson not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Chris Wilson makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ int n;
+
+ for (n = 0; n < 256; n++) {
+ cairo_set_source_rgba (cr, 1, 1, 1, n / 255.);
+ cairo_rectangle (cr, 0, n, 2, 1);
+ cairo_fill (cr);
+ }
+ for (n = 0; n < 256; n++) {
+ cairo_set_source_rgb (cr, n / 255., n / 255., n / 255.);
+ cairo_rectangle (cr, 2, n, 2, 1);
+ cairo_fill (cr);
+ }
+
+ cairo_translate (cr, 4, 0);
+
+ for (n = 0; n < 256; n++) {
+ cairo_set_source_rgba (cr, 1, 0, 0, n / 255.);
+ cairo_rectangle (cr, 0, n, 2, 1);
+ cairo_fill (cr);
+ }
+ for (n = 0; n < 256; n++) {
+ cairo_set_source_rgb (cr, n / 255., 0, 0);
+ cairo_rectangle (cr, 2, n, 2, 1);
+ cairo_fill (cr);
+ }
+
+ cairo_translate (cr, 4, 0);
+
+ for (n = 0; n < 256; n++) {
+ cairo_set_source_rgba (cr, 0, 1, 0, n / 255.);
+ cairo_rectangle (cr, 0, n, 2, 1);
+ cairo_fill (cr);
+ }
+ for (n = 0; n < 256; n++) {
+ cairo_set_source_rgb (cr, 0, n / 255., 0);
+ cairo_rectangle (cr, 2, n, 2, 1);
+ cairo_fill (cr);
+ }
+
+ cairo_translate (cr, 4, 0);
+
+ for (n = 0; n < 256; n++) {
+ cairo_set_source_rgba (cr, 0, 0, 1, n / 255.);
+ cairo_rectangle (cr, 0, n, 2, 1);
+ cairo_fill (cr);
+ }
+ for (n = 0; n < 256; n++) {
+ cairo_set_source_rgb (cr, 0, 0, n / 255.);
+ cairo_rectangle (cr, 2, n, 2, 1);
+ cairo_fill (cr);
+ }
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (pass_through,
+ "tests pixel values",
+ "color", /* keywords */
+ NULL, /* requirements */
+ 16, 256,
+ NULL, draw)
diff --git a/test/path-append.c b/test/path-append.c
new file mode 100644
index 000000000..bdcc63abf
--- /dev/null
+++ b/test/path-append.c
@@ -0,0 +1,81 @@
+/*
+ * Copyright © 2009 Jeff Muizelaar
+ * Copyright © 2009 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#include "cairo-test.h"
+#include <stdlib.h>
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_matrix_t m;
+ int xoffset = 50;
+ int yoffset = 50;
+
+ cairo_surface_t *shadow;
+ cairo_t *shadow_cr;
+ cairo_path_t *path;
+
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+ cairo_translate (cr, 130, 130);
+ cairo_rotate (cr, .5);//2*M_PI*angle/360);
+ cairo_rectangle (cr, 0, 0, 50, 100);
+ cairo_get_matrix (cr, &m);
+
+ shadow = cairo_surface_create_similar (cairo_get_target (cr),
+ CAIRO_CONTENT_COLOR_ALPHA,
+ 600 - xoffset,
+ 600 - yoffset);
+ cairo_surface_set_device_offset (shadow, xoffset, yoffset);
+ shadow_cr = cairo_create (shadow);
+ cairo_surface_destroy (shadow);
+
+ cairo_set_source_rgb (shadow_cr, 0, 1, 0);
+ cairo_set_matrix (shadow_cr, &m);
+
+ path = cairo_copy_path (cr);
+ cairo_new_path (shadow_cr);
+ cairo_append_path (shadow_cr, path);
+ cairo_fill (shadow_cr);
+ cairo_path_destroy (path);
+
+ cairo_identity_matrix (cr);
+ cairo_translate (cr, 10, 50);
+ cairo_set_source_surface (cr, cairo_get_target (shadow_cr), 0, 0);
+ cairo_paint (cr);
+ cairo_set_matrix (cr, &m);
+ cairo_set_source_rgb (cr, 1, 0, 0);
+ cairo_fill (cr);
+
+ cairo_destroy (shadow_cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (path_append,
+ "Test appending path to a context, in particular to exercise a regression in 005436",
+ "path", /* keywords */
+ NULL, /* requirements */
+ 600, 600,
+ NULL, draw)
diff --git a/test/path-currentpoint.c b/test/path-currentpoint.c
new file mode 100644
index 000000000..ccd44b1c8
--- /dev/null
+++ b/test/path-currentpoint.c
@@ -0,0 +1,89 @@
+/*
+ * Copyright © 2014 Google, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "cairo-test.h"
+
+#include <assert.h>
+
+static void
+assert_point (cairo_t *cr, double expected_x, double expected_y) {
+ double x, y;
+ assert (cairo_has_current_point (cr));
+ cairo_get_current_point (cr, &x, &y);
+ assert (x == expected_x);
+ assert (y == expected_y);
+}
+
+static void
+assert_point_maintained (cairo_t *cr, double expected_x, double expected_y) {
+ cairo_path_t *path;
+
+ assert_point (cr, expected_x, expected_y);
+
+ path = cairo_copy_path (cr);
+
+ cairo_new_path (cr);
+ cairo_rectangle (cr, 5, 5, 10, 20);
+ cairo_stroke (cr);
+
+ cairo_new_path (cr);
+ cairo_append_path (cr, path);
+ cairo_path_destroy (path);
+
+ assert_point (cr, expected_x, expected_y);
+}
+
+static cairo_test_status_t
+preamble (cairo_test_context_t *ctx)
+{
+ cairo_surface_t *surface;
+ cairo_t *cr;
+
+ surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 20, 20);
+ cr = cairo_create (surface);
+
+ cairo_new_path (cr);
+ cairo_move_to (cr, 1., 2.);
+ assert_point_maintained (cr, 1., 2.);
+
+ cairo_line_to (cr, 4., 5.);
+ cairo_move_to (cr, 2., 1.);
+ assert_point_maintained (cr, 2., 1.);
+
+ cairo_move_to (cr, 5, 5);
+ cairo_arc (cr, 5, 5, 10, 0, M_PI / 3);
+ cairo_close_path (cr);
+ assert_point_maintained (cr, 5, 5);
+
+ cairo_destroy (cr);
+ cairo_surface_destroy (surface);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (path_currentpoint,
+ "Test save/restore path maintains current point",
+ "api", /* keywords */
+ NULL, /* requirements */
+ 0, 0,
+ preamble, NULL)
diff --git a/test/path-precision.c b/test/path-precision.c
new file mode 100644
index 000000000..3a7fb11c8
--- /dev/null
+++ b/test/path-precision.c
@@ -0,0 +1,111 @@
+/*
+ * Copyright © 2008 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Chris Wilson not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Chris Wilson makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ *
+ * Based on an example by Dirk "krit" Schulze found during WebKit integration.
+ */
+
+#include "cairo-test.h"
+
+/* we know that this is an inherent limitation in cairo */
+#define FAIL CAIRO_TEST_XFAILURE
+
+/* Test the idempotency of path construction and copying */
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_path_data_t path_data[] = {
+ { { CAIRO_PATH_MOVE_TO, 2 }, },
+ { { 95.000000, 40.000000 }, },
+
+ { { CAIRO_PATH_LINE_TO, 2 }, },
+ { { 94.960533, 41.255810 }, },
+
+ { { CAIRO_PATH_LINE_TO, 2 }, },
+ { { 94.842293, 42.50666 }, },
+
+ { { CAIRO_PATH_LINE_TO, 2 }, },
+ { { 94.645744, 43.747627 }, },
+
+ { { CAIRO_PATH_LINE_TO, 2 }, },
+ { { 94.371666, 44.973797 }, },
+ };
+ const cairo_test_context_t *ctx = cairo_test_get_context (cr);
+ cairo_path_t path, *path_copy;
+ int i, j, n;
+ cairo_test_status_t result = CAIRO_TEST_SUCCESS;
+
+ path.status = CAIRO_STATUS_SUCCESS;
+ path.num_data = ARRAY_LENGTH (path_data);
+ path.data = path_data;
+
+ cairo_new_path (cr);
+ cairo_append_path (cr, &path);
+ path_copy = cairo_copy_path (cr);
+
+ if (path_copy->status)
+ return cairo_test_status_from_status (ctx, path_copy->status);
+
+ for (i = j = n = 0;
+ i < path.num_data && j < path_copy->num_data;
+ i += path.data[i].header.length,
+ j += path_copy->data[j].header.length,
+ n++)
+ {
+ const cairo_path_data_t *src, *dst;
+
+ src = &path.data[i];
+ dst = &path_copy->data[j];
+
+ if (src->header.type != dst->header.type) {
+ cairo_test_log (ctx,
+ "Paths differ in header type after %d operations.\n"
+ "Expected path operation %d, found %d.\n",
+ n, src->header.type, dst->header.type);
+ result = FAIL;
+ break;
+ }
+
+ if (memcmp (&src[1].point, &dst[1].point, sizeof (src->point))) {
+ cairo_test_log (ctx,
+ "Paths differ in coordinates after %d operations.\n"
+ "Expected point (%f, %f), found (%f, %f).\n",
+ n,
+ src[1].point.x, src[1].point.y,
+ dst[1].point.x, dst[1].point.y);
+ result = FAIL;
+ break;
+ }
+ }
+
+ cairo_path_destroy (path_copy);
+ return result;
+}
+
+CAIRO_TEST (path_precision,
+ "Check that the path append/copy is idempotent.",
+ "api", /* keywords */
+ NULL, /* requirements */
+ 0, 0,
+ NULL, draw)
diff --git a/test/path-stroke-twice.c b/test/path-stroke-twice.c
new file mode 100644
index 000000000..10bbbf8b0
--- /dev/null
+++ b/test/path-stroke-twice.c
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2010 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Chris Wilson not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Chris Wilson makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+/* Exercises a bug found by alois@astro.ch:
+ * http://bugs.freedesktop.org/show_bug.cgi?id=26010
+ * cairo_line_to optimizes away path segment
+ */
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ cairo_move_to (cr, 10, 10);
+ cairo_line_to (cr, 10, 20);
+ cairo_line_to (cr, 20, 30);
+ cairo_line_to (cr, 10, 20);
+ cairo_stroke (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (path_stroke_twice,
+ "Tests stroking of a path containing a segment drawn twice",
+ "path, stroke", /* keywords */
+ NULL, /* requirements */
+ 40, 40,
+ NULL, draw)
diff --git a/test/pattern-get-type.c b/test/pattern-get-type.c
new file mode 100644
index 000000000..c807b14e8
--- /dev/null
+++ b/test/pattern-get-type.c
@@ -0,0 +1,79 @@
+/*
+ * Copyright © 2006 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+#include "cairo-test.h"
+
+static cairo_test_status_t
+preamble (cairo_test_context_t *Ctx)
+{
+ cairo_surface_t *surface;
+ cairo_pattern_t *solid_rgb, *solid_rgba, *surface_pattern, *linear, *radial, *mesh;
+ cairo_test_status_t result = CAIRO_TEST_SUCCESS;
+
+ solid_rgb = cairo_pattern_create_rgb (0.0, 0.1, 0.2);
+ solid_rgba = cairo_pattern_create_rgba (0.3, 0.4, 0.5, 0.6);
+ surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
+ 1, 1);
+ surface_pattern = cairo_pattern_create_for_surface (surface);
+ linear = cairo_pattern_create_linear (0.0, 0.0, 10.0, 10.0);
+ radial = cairo_pattern_create_radial (10.0, 10.0, 0.1,
+ 10.0, 10.0, 1.0);
+ mesh = cairo_pattern_create_mesh ();
+
+ if (cairo_pattern_get_type (solid_rgb) != CAIRO_PATTERN_TYPE_SOLID)
+ result = CAIRO_TEST_FAILURE;
+
+ if (cairo_pattern_get_type (solid_rgba) != CAIRO_PATTERN_TYPE_SOLID)
+ result = CAIRO_TEST_FAILURE;
+
+ if (cairo_pattern_get_type (surface_pattern) != CAIRO_PATTERN_TYPE_SURFACE)
+ result = CAIRO_TEST_FAILURE;
+
+ if (cairo_pattern_get_type (linear) != CAIRO_PATTERN_TYPE_LINEAR)
+ result = CAIRO_TEST_FAILURE;
+
+ if (cairo_pattern_get_type (radial) != CAIRO_PATTERN_TYPE_RADIAL)
+ result = CAIRO_TEST_FAILURE;
+
+ if (cairo_pattern_get_type (mesh) != CAIRO_PATTERN_TYPE_MESH)
+ result = CAIRO_TEST_FAILURE;
+
+ cairo_pattern_destroy (solid_rgb);
+ cairo_pattern_destroy (solid_rgba);
+ cairo_pattern_destroy (surface_pattern);
+ cairo_surface_destroy (surface);
+ cairo_pattern_destroy (linear);
+ cairo_pattern_destroy (radial);
+ cairo_pattern_destroy (mesh);
+
+ return result;
+}
+
+CAIRO_TEST (pattern_get_type,
+ "Creating patterns of all types",
+ "pattern, api", /* keywords */
+ NULL, /* requirements */
+ 0, 0,
+ preamble, NULL)
diff --git a/test/pattern-getters.c b/test/pattern-getters.c
new file mode 100644
index 000000000..08508d7d4
--- /dev/null
+++ b/test/pattern-getters.c
@@ -0,0 +1,279 @@
+/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */
+/*
+ * Copyright © 2005 Mozilla Corporation, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Mozilla Corporation not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Mozilla Corporation makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * MOZILLA CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL MOZILLA CORPORATION BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Vladimir Vukicevic <vladimir@pobox.com>
+ */
+
+#include "cairo-test.h"
+#include <stdlib.h>
+
+#define CHECK_SUCCESS do { \
+ if (status) { \
+ cairo_pattern_destroy (pat); \
+ return cairo_test_status_from_status (ctx, status); \
+ } \
+} while (0)
+
+static int
+double_buf_equal (const cairo_test_context_t *ctx, double *a, double *b, int nc)
+{
+ int i;
+ for (i = 0; i < nc; i++) {
+ if (!CAIRO_TEST_DOUBLE_EQUALS(a[i],b[i])) {
+ cairo_test_log (ctx, "Error: doubles not equal: %g, %g\n",
+ a[i], b[i]);
+ return 0;
+ }
+ }
+ return 1;
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ const cairo_test_context_t *ctx = cairo_test_get_context (cr);
+ cairo_status_t status;
+ cairo_pattern_t *pat;
+
+ /* Test pattern_get_rgba */
+ {
+ double r, g, b, a;
+ pat = cairo_pattern_create_rgba (0.2, 0.3, 0.4, 0.5);
+
+ status = cairo_pattern_get_rgba (pat, &r, &g, &b, &a);
+ CHECK_SUCCESS;
+
+ if (!CAIRO_TEST_DOUBLE_EQUALS(r,0.2) ||
+ !CAIRO_TEST_DOUBLE_EQUALS(g,0.3) ||
+ !CAIRO_TEST_DOUBLE_EQUALS(b,0.4) ||
+ !CAIRO_TEST_DOUBLE_EQUALS(a,0.5)) {
+ cairo_test_log (ctx, "Error: cairo_pattern_get_rgba returned unexepcted results: %g, %g, %g, %g\n",
+ r, g, b, a);
+ cairo_pattern_destroy (pat);
+ return CAIRO_TEST_FAILURE;
+ }
+
+ cairo_pattern_destroy (pat);
+ }
+
+ /* Test pattern_get_surface */
+ {
+ cairo_surface_t *surf;
+
+ pat = cairo_pattern_create_for_surface (cairo_get_target (cr));
+
+ status = cairo_pattern_get_surface (pat, &surf);
+ CHECK_SUCCESS;
+
+ if (surf != cairo_get_target (cr)) {
+ cairo_test_log (ctx, "Error: cairo_pattern_get_resurface returned wrong surface\n");
+ cairo_pattern_destroy (pat);
+ return CAIRO_TEST_FAILURE;
+ }
+
+ cairo_pattern_destroy (pat);
+ }
+
+ /* Test get_color_stops & linear_get_points */
+ {
+ int i;
+ double x0, y0, x1, y1;
+ double expected_values[15] = { 0.0, 0.2, 0.4, 0.2, 1.0,
+ 0.5, 0.4, 0.5, 0.2, 0.5,
+ 1.0, 0.2, 0.4, 0.5, 0.2 };
+ double new_buf[15];
+
+ pat = cairo_pattern_create_linear (1.0, 2.0, 3.0, 4.0);
+
+ for (i = 0; i < 3; i++) {
+ cairo_pattern_add_color_stop_rgba (pat,
+ expected_values[i*5+0],
+ expected_values[i*5+1],
+ expected_values[i*5+2],
+ expected_values[i*5+3],
+ expected_values[i*5+4]);
+ }
+
+ status = cairo_pattern_get_linear_points (pat, &x0, &y0, &x1, &y1);
+ CHECK_SUCCESS;
+
+ if (!CAIRO_TEST_DOUBLE_EQUALS(x0,1.0) ||
+ !CAIRO_TEST_DOUBLE_EQUALS(y0,2.0) ||
+ !CAIRO_TEST_DOUBLE_EQUALS(x1,3.0) ||
+ !CAIRO_TEST_DOUBLE_EQUALS(y1,4.0))
+ {
+ cairo_pattern_destroy (pat);
+ return CAIRO_TEST_FAILURE;
+ }
+
+ status = cairo_pattern_get_color_stop_count (pat, &i);
+ CHECK_SUCCESS;
+
+ if (i != 3) {
+ cairo_pattern_destroy (pat);
+ return CAIRO_TEST_FAILURE;
+ }
+
+ for (i = 0; i < 3; i++) {
+ status = cairo_pattern_get_color_stop_rgba (pat, i,
+ &new_buf[i*5+0],
+ &new_buf[i*5+1],
+ &new_buf[i*5+2],
+ &new_buf[i*5+3],
+ &new_buf[i*5+4]);
+ CHECK_SUCCESS;
+ }
+
+ status = cairo_pattern_get_color_stop_rgba (pat, 5, NULL, NULL, NULL, NULL, NULL);
+ if (status != CAIRO_STATUS_INVALID_INDEX) {
+ cairo_pattern_destroy (pat);
+ return CAIRO_TEST_FAILURE;
+ }
+
+ if (!double_buf_equal (ctx, new_buf, expected_values,
+ ARRAY_LENGTH (expected_values)) != 0)
+ {
+ cairo_pattern_destroy (pat);
+ return CAIRO_TEST_FAILURE;
+ }
+
+ cairo_pattern_destroy (pat);
+ }
+
+ /* Test radial_get_circles */
+ {
+ double a, b, c, d, e, f;
+ pat = cairo_pattern_create_radial (1, 2, 3,
+ 4, 5, 6);
+
+ status = cairo_pattern_get_radial_circles (pat, &a, &b, &c, &d, &e, &f);
+ CHECK_SUCCESS;
+
+ if (!CAIRO_TEST_DOUBLE_EQUALS(a,1.0) ||
+ !CAIRO_TEST_DOUBLE_EQUALS(b,2.0) ||
+ !CAIRO_TEST_DOUBLE_EQUALS(c,3.0) ||
+ !CAIRO_TEST_DOUBLE_EQUALS(d,4.0) ||
+ !CAIRO_TEST_DOUBLE_EQUALS(e,5.0) ||
+ !CAIRO_TEST_DOUBLE_EQUALS(f,6.0))
+ {
+ cairo_pattern_destroy (pat);
+ return CAIRO_TEST_FAILURE;
+ }
+
+ cairo_pattern_destroy (pat);
+ }
+
+ /* Test mesh getters */
+ {
+ unsigned int count;
+ int i;
+ pat = cairo_pattern_create_mesh ();
+
+ status = cairo_mesh_pattern_get_patch_count (pat, &count);
+ CHECK_SUCCESS;
+
+ if (count != 0) {
+ cairo_pattern_destroy (pat);
+ return CAIRO_TEST_FAILURE;
+ }
+
+ cairo_mesh_pattern_begin_patch (pat);
+ cairo_mesh_pattern_move_to (pat, 0, 0);
+ cairo_mesh_pattern_line_to (pat, 0, 3);
+ cairo_mesh_pattern_line_to (pat, 3, 3);
+ cairo_mesh_pattern_line_to (pat, 3, 0);
+
+ status = cairo_mesh_pattern_get_patch_count (pat, &count);
+ CHECK_SUCCESS;
+
+ if (count != 0) {
+ cairo_pattern_destroy (pat);
+ return CAIRO_TEST_FAILURE;
+ }
+
+ cairo_mesh_pattern_end_patch (pat);
+
+ status = cairo_mesh_pattern_get_patch_count (pat, &count);
+ CHECK_SUCCESS;
+
+ if (count != 1) {
+ cairo_pattern_destroy (pat);
+ return CAIRO_TEST_FAILURE;
+ }
+
+ for (i = 0; i < 4; i++) {
+ double cp_x[4] = { 1, 1, 2, 2 };
+ double cp_y[4] = { 1, 2, 2, 1 };
+ double x, y;
+
+ status = cairo_mesh_pattern_get_control_point (pat, 0, i, &x, &y);
+ CHECK_SUCCESS;
+
+ if (!CAIRO_TEST_DOUBLE_EQUALS(x,cp_x[i]) ||
+ !CAIRO_TEST_DOUBLE_EQUALS(y,cp_y[i]))
+ {
+ cairo_pattern_destroy (pat);
+ return CAIRO_TEST_FAILURE;
+ }
+ }
+
+ cairo_mesh_pattern_begin_patch (pat);
+ cairo_mesh_pattern_move_to (pat, 0, 0);
+ cairo_mesh_pattern_line_to (pat, 1, 0);
+ cairo_mesh_pattern_line_to (pat, 1, 1);
+ cairo_mesh_pattern_set_corner_color_rgb (pat, 0, 1, 1, 1);
+ cairo_mesh_pattern_end_patch (pat);
+
+ for (i = 0; i < 4; i++) {
+ double corner_color[4] = { 1, 0, 0, 1 };
+ double a, r, g, b;
+
+ status = cairo_mesh_pattern_get_corner_color_rgba (pat, 1, i,
+ &r, &g, &b, &a);
+ CHECK_SUCCESS;
+
+ if (!CAIRO_TEST_DOUBLE_EQUALS(a,corner_color[i]) ||
+ !CAIRO_TEST_DOUBLE_EQUALS(r,corner_color[i]) ||
+ !CAIRO_TEST_DOUBLE_EQUALS(g,corner_color[i]) ||
+ !CAIRO_TEST_DOUBLE_EQUALS(b,corner_color[i]))
+ {
+ cairo_pattern_destroy (pat);
+ return CAIRO_TEST_FAILURE;
+ }
+ }
+
+ cairo_pattern_destroy (pat);
+ }
+
+ cairo_set_source_rgb (cr, 0, 1, 0);
+ cairo_paint (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (pattern_getters,
+ "Tests calls to pattern getter functions",
+ "pattern, api", /* keywords */
+ NULL, /* requirements */
+ 1, 1,
+ NULL, draw)
diff --git a/test/pdf-features.c b/test/pdf-features.c
new file mode 100644
index 000000000..b9c2bd07a
--- /dev/null
+++ b/test/pdf-features.c
@@ -0,0 +1,148 @@
+/*
+ * Copyright © 2006 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+#include "cairo-test.h"
+
+#include <stdio.h>
+#include <cairo.h>
+#include <cairo-pdf.h>
+
+/* This test exists to test the various features of cairo-pdf.h.
+ *
+ * Currently, this test exercises the following function calls:
+ *
+ * cairo_pdf_surface_set_size
+ */
+
+#define INCHES_TO_POINTS(in) ((in) * 72.0)
+#define MM_TO_POINTS(mm) ((mm) / 25.4 * 72.0)
+#define TEXT_SIZE 12
+#define BASENAME "pdf-features.out"
+
+static struct {
+ const char *page_size;
+ const char *page_size_alias;
+ const char *orientation;
+ double width_in_points;
+ double height_in_points;
+} pages[] = {
+ {"na_letter_8.5x11in", "letter", "portrait",
+ INCHES_TO_POINTS(8.5), INCHES_TO_POINTS(11)},
+ {"na_letter_8.5x11in", "letter", "landscape",
+ INCHES_TO_POINTS(11), INCHES_TO_POINTS(8.5)},
+ {"iso_a4_210x297mm", "a4", "portrait",
+ MM_TO_POINTS(210), MM_TO_POINTS(297)},
+ {"iso_a4_210x297mm", "a4", "landscape",
+ MM_TO_POINTS(297), MM_TO_POINTS(210)},
+ {"iso_a5_148x210mm", "a5", "portrait",
+ MM_TO_POINTS(148), MM_TO_POINTS(210)},
+ {"iso_a5_148x210mm", "a5", "landscape",
+ MM_TO_POINTS(210), MM_TO_POINTS(148)},
+ {"iso_a6_105x148mm", "a6", "portrait",
+ MM_TO_POINTS(105), MM_TO_POINTS(148)},
+ {"iso_a6_105x148mm", "a6", "landscape",
+ MM_TO_POINTS(148), MM_TO_POINTS(105)},
+ {"iso_a7_74x105mm", "a7", "portrait",
+ MM_TO_POINTS(74), MM_TO_POINTS(105)},
+ {"iso_a7_74x105mm", "a7", "landscape",
+ MM_TO_POINTS(105), MM_TO_POINTS(74)},
+ {"iso_a8_52x74mm", "a8", "portrait",
+ MM_TO_POINTS(52), MM_TO_POINTS(74)},
+ {"iso_a8_52x74mm", "a8", "landscape",
+ MM_TO_POINTS(74), MM_TO_POINTS(52)},
+ {"iso_a9_37x52mm", "a9", "portrait",
+ MM_TO_POINTS(37), MM_TO_POINTS(52)},
+ {"iso_a9_37x52mm", "a9", "landscape",
+ MM_TO_POINTS(52), MM_TO_POINTS(37)},
+ {"iso_a10_26x37mm", "a10", "portrait",
+ MM_TO_POINTS(26), MM_TO_POINTS(37)},
+ {"iso_a10_26x37mm", "a10", "landscape",
+ MM_TO_POINTS(37), MM_TO_POINTS(26)}
+};
+
+static cairo_test_status_t
+preamble (cairo_test_context_t *ctx)
+{
+ cairo_surface_t *surface;
+ cairo_t *cr;
+ cairo_status_t status;
+ size_t i;
+ char *filename;
+ const char *path = cairo_test_mkdir (CAIRO_TEST_OUTPUT_DIR) ? CAIRO_TEST_OUTPUT_DIR : ".";
+
+ if (! cairo_test_is_target_enabled (ctx, "pdf"))
+ return CAIRO_TEST_UNTESTED;
+
+ xasprintf (&filename, "%s/%s.pdf", path, BASENAME);
+
+ /* The initial size passed here is the default size that will be
+ * inheritable by each page. That is, any page for which this
+ * initial size applies will not have its own /MediaBox entry in
+ * its dictionary. */
+ surface = cairo_pdf_surface_create (filename,
+ INCHES_TO_POINTS(8.5),
+ INCHES_TO_POINTS(11));
+
+ cr = cairo_create (surface);
+
+ cairo_select_font_face (cr, CAIRO_TEST_FONT_FAMILY " Sans",
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_NORMAL);
+ cairo_set_font_size (cr, TEXT_SIZE);
+
+ for (i = 0; i < ARRAY_LENGTH (pages); i++) {
+ cairo_pdf_surface_set_size (surface,
+ pages[i].width_in_points,
+ pages[i].height_in_points);
+
+ cairo_move_to (cr, TEXT_SIZE, TEXT_SIZE);
+ cairo_show_text (cr, pages[i].page_size);
+ cairo_show_text (cr, " - ");
+ cairo_show_text (cr, pages[i].orientation);
+ cairo_show_page (cr);
+ }
+
+ status = cairo_status (cr);
+
+ cairo_destroy (cr);
+ cairo_surface_destroy (surface);
+ free (filename);
+
+ if (status) {
+ cairo_test_log (ctx, "Failed to create pdf surface for file %s: %s\n",
+ filename, cairo_status_to_string (status));
+ return CAIRO_TEST_FAILURE;
+ }
+
+ printf ("pdf-features: Please check %s to ensure it looks/prints correctly.\n", filename);
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (pdf_features,
+ "Check PDF specific API",
+ "pdf", /* keywords */
+ NULL, /* requirements */
+ 0, 0,
+ preamble, NULL)
diff --git a/test/pdf-isolated-group.c b/test/pdf-isolated-group.c
new file mode 100644
index 000000000..e74a346a2
--- /dev/null
+++ b/test/pdf-isolated-group.c
@@ -0,0 +1,73 @@
+/*
+ * Copyright © 2012 Adrian Johnson
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Adrian Johnson <ajohnson@redneon.com>
+ */
+
+#include "cairo-test.h"
+
+#define SIZE 60
+#define WIDTH SIZE
+#define HEIGHT SIZE
+
+
+/* PDF transparency groups can be isolated or non-isolated. This test
+ * checks that the PDF output is using isolated groups. If the group
+ * is non-isolated the bottom half of the inner rectangle will be
+ * red. Note poppler-cairo currently ignores the isolated flag and
+ * treats the group as isolated.
+ *
+ * Refer to http://www.pdfvt.com/PDFVT_TransparencyGuide.html for an
+ * explanation isolated vs non-isolated.
+ */
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+ cairo_set_source_rgb (cr, 1, 0.5, 0);
+ cairo_rectangle (cr, 0, SIZE/2, SIZE, SIZE/2);
+ cairo_fill (cr);
+
+ cairo_set_operator (cr, CAIRO_OPERATOR_MULTIPLY);
+
+ cairo_push_group (cr);
+
+ cairo_set_source_rgb (cr, 0.7, 0.7, 0.7);
+ cairo_rectangle (cr, SIZE/4, SIZE/4, SIZE/2, SIZE/2);
+ cairo_fill (cr);
+
+ cairo_pop_group_to_source (cr);
+ cairo_paint (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (pdf_isolated_group,
+ "Check that transparency groups in PDF output are isolated",
+ "group, operator", /* keywords */
+ NULL, /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw)
diff --git a/test/pdf-mime-data.c b/test/pdf-mime-data.c
new file mode 100644
index 000000000..fd5af1f7f
--- /dev/null
+++ b/test/pdf-mime-data.c
@@ -0,0 +1,187 @@
+/*
+ * Copyright © 2008 Adrian Johnson
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Adrian Johnson <ajohnson@redneon.com>
+ */
+
+#include "cairo-test.h"
+
+#include <stdio.h>
+#include <errno.h>
+#include <cairo.h>
+#include <cairo-pdf.h>
+
+/* This test checks that the mime data is correctly used by the PDF
+ * surface when embedding images..
+ */
+
+/* Both a *.png and *.jpg file with this name is required since we
+ * are not using a jpeg library */
+#define IMAGE_FILE "romedalen"
+
+#define BASENAME "pdf-mime-data.out"
+
+static cairo_test_status_t
+read_file (const cairo_test_context_t *ctx,
+ const char *file,
+ unsigned char **data,
+ unsigned int *len)
+{
+ FILE *fp;
+
+ fp = fopen (file, "rb");
+ if (fp == NULL) {
+ char filename[4096];
+
+ /* try again with srcdir */
+ snprintf (filename, sizeof (filename),
+ "%s/%s", ctx->srcdir, file);
+ fp = fopen (filename, "rb");
+ }
+ if (fp == NULL) {
+ switch (errno) {
+ case ENOMEM:
+ cairo_test_log (ctx, "Could not create file handle for %s due to \
+ lack of memory\n", file);
+ return CAIRO_TEST_NO_MEMORY;
+ default:
+ cairo_test_log (ctx, "Could not get the file handle for %s\n", file);
+ return CAIRO_TEST_FAILURE;
+ }
+ }
+
+ fseek (fp, 0, SEEK_END);
+ *len = ftell(fp);
+ fseek (fp, 0, SEEK_SET);
+ *data = malloc (*len);
+ if (*data == NULL) {
+ fclose(fp);
+ cairo_test_log (ctx, "Could not allocate memory for buffer to read \
+ from file %s\n", file);
+ return CAIRO_TEST_NO_MEMORY;
+ }
+
+ if (fread(*data, *len, 1, fp) != 1) {
+ free (data);
+ fclose(fp);
+ cairo_test_log (ctx, "Could not read data from file %s\n", file);
+ return CAIRO_TEST_FAILURE;
+ }
+
+ fclose(fp);
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+preamble (cairo_test_context_t *ctx)
+{
+ cairo_surface_t *image;
+ cairo_surface_t *surface;
+ cairo_t *cr;
+ cairo_status_t status, status2;
+ cairo_test_status_t test_status;
+ int width, height;
+ unsigned char *data;
+ unsigned char *out_data;
+ unsigned int len, out_len;
+ char command[4096];
+ int exit_status;
+ char *filename;
+ const char *path = cairo_test_mkdir (CAIRO_TEST_OUTPUT_DIR) ? CAIRO_TEST_OUTPUT_DIR : ".";
+
+ if (! cairo_test_is_target_enabled (ctx, "pdf"))
+ return CAIRO_TEST_UNTESTED;
+
+ image = cairo_image_surface_create_from_png (IMAGE_FILE ".png");
+ test_status = read_file (ctx, IMAGE_FILE ".jpg", &data, &len);
+ if (test_status) {
+ return test_status;
+ }
+
+ cairo_surface_set_mime_data (image, CAIRO_MIME_TYPE_JPEG,
+ data, len,
+ free, data);
+ width = cairo_image_surface_get_width (image);
+ height = cairo_image_surface_get_height (image);
+
+ xasprintf (&filename, "%s/%s.pdf", path, BASENAME);
+ surface = cairo_pdf_surface_create (filename, width + 20, height + 20);
+ cr = cairo_create (surface);
+ cairo_translate (cr, 10, 10);
+ cairo_set_source_surface (cr, image, 0, 0);
+ cairo_paint (cr);
+ status = cairo_status (cr);
+ cairo_destroy (cr);
+ cairo_surface_finish (surface);
+ status2 = cairo_surface_status (surface);
+ if (status != CAIRO_STATUS_SUCCESS)
+ status = status2;
+ cairo_surface_destroy (surface);
+ cairo_surface_destroy (image);
+
+ if (status) {
+ free (filename);
+ cairo_test_log (ctx, "Failed to create pdf surface for file %s: %s\n",
+ filename, cairo_status_to_string (status));
+ return CAIRO_TEST_FAILURE;
+ }
+
+ printf ("pdf-mime-data: Please check %s to ensure it looks/prints correctly.\n", filename);
+
+ sprintf (command, "pdfimages -j %s %s", filename, CAIRO_TEST_OUTPUT_DIR "/" BASENAME);
+ exit_status = system (command);
+ free (filename);
+ if (exit_status) {
+ cairo_test_log (ctx, "pdfimages failed with exit status %d\n", exit_status);
+ return CAIRO_TEST_FAILURE;
+ }
+
+ test_status = read_file (ctx, IMAGE_FILE ".jpg", &data, &len);
+ if (test_status) {
+ return test_status;
+ }
+
+ test_status = read_file (ctx, CAIRO_TEST_OUTPUT_DIR "/" BASENAME "-000.jpg", &out_data, &out_len);
+ if (test_status) {
+ return test_status;
+ }
+
+ if (len != out_len || memcmp(data, out_data, len) != 0) {
+ free (data);
+ free (out_data);
+ cairo_test_log (ctx, "output mime data does not match source mime data\n");
+ return CAIRO_TEST_FAILURE;
+ }
+
+ free (data);
+ free (out_data);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (pdf_mime_data,
+ "Check mime data correctly used by PDF surface",
+ "pdf, mime-data", /* keywords */
+ NULL, /* requirements */
+ 0, 0,
+ preamble, NULL)
diff --git a/test/pdf-surface-source.c b/test/pdf-surface-source.c
new file mode 100644
index 000000000..354a7259a
--- /dev/null
+++ b/test/pdf-surface-source.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright © 2008 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Chris Wilson not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Chris Wilson makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+#include <cairo-pdf.h>
+
+#include "surface-source.c"
+
+#define BASENAME "pdf-surface-source.out"
+
+static cairo_surface_t *
+create_source_surface (int size)
+{
+ cairo_surface_t *surface;
+ char *filename;
+ const char *path = cairo_test_mkdir (CAIRO_TEST_OUTPUT_DIR) ? CAIRO_TEST_OUTPUT_DIR : ".";
+
+ xasprintf (&filename, "%s/%s.pdf", path, BASENAME);
+ surface = cairo_pdf_surface_create (filename, size, size);
+ cairo_surface_set_fallback_resolution (surface, 72., 72.);
+ free (filename);
+
+ return surface;
+}
+
+CAIRO_TEST (pdf_surface_source,
+ "Test using a PDF surface as the source",
+ "source", /* keywords */
+ NULL, /* requirements */
+ SIZE, SIZE,
+ preamble, draw)
diff --git a/test/pdf2png.c b/test/pdf2png.c
new file mode 100644
index 000000000..06fa05b18
--- /dev/null
+++ b/test/pdf2png.c
@@ -0,0 +1,99 @@
+/*
+ * Copyright © 2005 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Kristian Høgsberg <krh@redhat.com>
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <poppler.h>
+
+#define FAIL(msg) \
+ do { fprintf (stderr, "FAIL: %s\n", msg); exit (-1); } while (0)
+
+#define PIXELS_PER_POINT 1
+
+int main (int argc, char *argv[])
+{
+ PopplerDocument *document;
+ PopplerPage *page;
+ double width, height;
+ const char *filename = argv[1];
+ const char *output_filename = argv[2];
+ const char *page_label = argv[3];
+ gchar *absolute, *uri;
+ cairo_surface_t *surface;
+ cairo_t *cr;
+ cairo_status_t status;
+ GError *error = NULL;
+
+ if (argc != 4)
+ FAIL ("usage: pdf2png input_file.pdf output_file.png page");
+
+ g_type_init ();
+
+ if (g_path_is_absolute(filename)) {
+ absolute = g_strdup (filename);
+ } else {
+ gchar *dir = g_get_current_dir ();
+ absolute = g_build_filename (dir, filename, (gchar *) 0);
+ g_free (dir);
+ }
+
+ uri = g_filename_to_uri (absolute, NULL, &error);
+ g_free (absolute);
+ if (uri == NULL)
+ FAIL (error->message);
+
+ document = poppler_document_new_from_file (uri, NULL, &error);
+ if (document == NULL)
+ FAIL (error->message);
+
+ page = poppler_document_get_page_by_label (document, page_label);
+ if (page == NULL)
+ FAIL ("page not found");
+
+ poppler_page_get_size (page, &width, &height);
+
+ surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, width, height);
+ cr = cairo_create (surface);
+ cairo_surface_destroy (surface);
+
+ cairo_set_source_rgb (cr, 1,1,1);
+ cairo_paint (cr);
+ cairo_push_group_with_content (cr, CAIRO_CONTENT_COLOR_ALPHA);
+
+ poppler_page_render (page, cr);
+ g_object_unref (page);
+
+ cairo_pop_group_to_source (cr);
+ cairo_paint (cr);
+
+ status = cairo_surface_write_to_png (cairo_get_target (cr),
+ output_filename);
+ cairo_destroy (cr);
+
+ if (status)
+ FAIL (cairo_status_to_string (status));
+
+ return 0;
+}
diff --git a/test/pdiff/.gitignore b/test/pdiff/.gitignore
new file mode 100644
index 000000000..f44ed659a
--- /dev/null
+++ b/test/pdiff/.gitignore
@@ -0,0 +1,3 @@
+TAGS
+tags
+perceptualdiff
diff --git a/test/pdiff/CMakeLists.txt b/test/pdiff/CMakeLists.txt
new file mode 100644
index 000000000..6e4fa7a8a
--- /dev/null
+++ b/test/pdiff/CMakeLists.txt
@@ -0,0 +1,55 @@
+PROJECT (PerceptualDiff)
+SET(DIFF_SRC PerceptualDiff.cpp LPyramid.cpp RGBAImage.cpp
+CompareArgs.cpp Metric.cpp)
+
+ADD_EXECUTABLE (perceptualdiff ${DIFF_SRC})
+
+# look for libtiff
+FIND_PATH(TIFF_INCLUDE_DIR tiff.h
+ /usr/local/include
+ /usr/include
+ /opt/local/include
+)
+
+FIND_LIBRARY(TIFF_LIBRARY tiff
+ /usr/lib
+ /usr/local/lib
+ /opt/local/lib
+)
+
+IF(TIFF_INCLUDE_DIR)
+ IF(TIFF_LIBRARY)
+ SET( TIFF_FOUND "YES" )
+ SET( TIFF_LIBRARIES ${TIFF_LIBRARY} )
+ ENDIF(TIFF_LIBRARY)
+ENDIF(TIFF_INCLUDE_DIR)
+
+IF(TIFF_FOUND)
+ INCLUDE_DIRECTORIES(${TIFF_INCLUDE_DIR})
+ TARGET_LINK_LIBRARIES(perceptualdiff ${TIFF_LIBRARY})
+ENDIF(TIFF_FOUND)
+
+# look for libpng
+FIND_PATH(PNG_INCLUDE_DIR png.h
+ /usr/local/include
+ /usr/include
+ /opt/local/include
+)
+
+FIND_LIBRARY(PNG_LIBRARY png
+ /usr/lib
+ /usr/local/lib
+ /opt/local/lib
+)
+
+IF(PNG_INCLUDE_DIR)
+ IF(PNG_LIBRARY)
+ SET( PNG_FOUND "YES" )
+ SET( PNG_LIBRARIES ${PNG_LIBRARY} )
+ ENDIF(PNG_LIBRARY)
+ENDIF(PNG_INCLUDE_DIR)
+
+IF(PNG_FOUND)
+ INCLUDE_DIRECTORIES(${PNG_INCLUDE_DIR})
+ TARGET_LINK_LIBRARIES(perceptualdiff ${PNG_LIBRARY})
+ENDIF(PNG_FOUND) \ No newline at end of file
diff --git a/test/pdiff/Makefile.am b/test/pdiff/Makefile.am
new file mode 100644
index 000000000..73098da78
--- /dev/null
+++ b/test/pdiff/Makefile.am
@@ -0,0 +1,19 @@
+include $(top_srcdir)/build/Makefile.am.common
+
+EXTRA_PROGRAMS += perceptualdiff
+EXTRA_DIST += gpl.txt
+
+noinst_LTLIBRARIES = libpdiff.la
+libpdiff_la_SOURCES = \
+ pdiff.h \
+ lpyramid.c \
+ lpyramid.h \
+ pdiff.c
+
+perceptualdiff_SOURCES = \
+ args.c \
+ args.h \
+ perceptualdiff.c
+
+AM_CPPFLAGS = -I$(top_srcdir)/src -I$(top_builddir)/src $(CAIRO_CFLAGS)
+LDADD = libpdiff.la $(top_builddir)/src/libcairo.la
diff --git a/test/pdiff/Makefile.win32 b/test/pdiff/Makefile.win32
new file mode 100644
index 000000000..3d64676da
--- /dev/null
+++ b/test/pdiff/Makefile.win32
@@ -0,0 +1,14 @@
+top_srcdir = ../..
+include $(top_srcdir)/build/Makefile.win32.common
+
+SOURCES = \
+ lpyramid.c \
+ pdiff.c \
+ $(NULL)
+
+OBJECTS = $(patsubst %.c, $(CFG)/%-static.obj, $(SOURCES))
+
+all: $(CFG)/pdiff.lib
+
+$(CFG)/pdiff.lib: $(OBJECTS)
+ @$(AR) $(CAIRO_ARFLAGS) -OUT:$@ $(OBJECTS)
diff --git a/test/pdiff/README.txt b/test/pdiff/README.txt
new file mode 100644
index 000000000..922ddafbf
--- /dev/null
+++ b/test/pdiff/README.txt
@@ -0,0 +1,45 @@
+pdiff - a program that compares two images using
+a perceptually based image metric.
+Copyright (C) 2006 Yangli Hector Yee
+yeehector@users.sourceforge.net
+http://pdiff.sourceforge.net/
+
+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 2 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 in the file gpl.txt.
+
+Build Instructions
+1. Download cross platform make from http://www.cmake.org
+2. Download libtiff from http://www.libtiff.org. Download libpng from http://www.libpng.org
+3. Edit CMakeLists.txt to tell it where to find your tiff library
+4. Type cmake .
+5. Type make . (or on Windows systems cmake makes a Visual Studio
+Project file)
+6. To specify the install directory, use make install DESTDIR="/home/me/mydist"
+
+Usage
+
+pdiff image1.(tif | png) image2.(tif | png) [options]
+-verbose : Turns on verbose mode
+-fov deg: field of view, deg, in degrees. Usually between 10.0 to 85.0.
+This controls how much of the screen the oberserver is seeing. Front row of
+a theatre has a field of view of around 25 degrees. Back row has a field of
+ view of around 60 degrees.
+-threshold p : Sets the number of pixels, p, to reject. For example if p is
+ 100, then the test fails if 100 or more pixels are perceptably different.
+-gamma g : The gamma to use to convert to RGB linear space. Default is 2.2
+-luminance l: The luminance of the display the observer is seeing. Default
+ is 100 candela per meter squared
+
+Credits
+
+Hector Yee, project administrator and originator - hectorgon.blogspot.com
+Scott Corley, for png file IO code
+Mick Weiss, Linux build and release & QA
+Carl Worth, Rewrite as library, depend on cairo, and port to C \ No newline at end of file
diff --git a/test/pdiff/args.c b/test/pdiff/args.c
new file mode 100644
index 000000000..ac3aa83a9
--- /dev/null
+++ b/test/pdiff/args.c
@@ -0,0 +1,119 @@
+/*
+ Comapre Args
+ Copyright (C) 2006 Yangli Hector Yee
+
+ 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 2 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
+*/
+
+#include "args.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+static const char* copyright =
+"PerceptualDiff version 1.0, Copyright (C) 2006 Yangli Hector Yee\n\
+PerceptualDiff comes with ABSOLUTELY NO WARRANTY;\n\
+This is free software, and you are welcome\n\
+to redistribute it under certain conditions;\n\
+See the GPL page for details: http://www.gnu.org/copyleft/gpl.html\n\n";
+
+static const char *usage =
+"PeceptualDiff image1.tif image2.tif\n\n\
+ Compares image1.tif and image2.tif using a perceptually based image metric\n\
+ Options:\n\
+\t-verbose : Turns on verbose mode\n\
+\t-fov deg : Field of view in degrees (0.1 to 89.9)\n\
+\t-threshold p : #pixels p below which differences are ignored\n\
+\t-gamma g : Value to convert rgb into linear space (default 2.2)\n\
+\t-luminance l : White luminance (default 100.0 cdm^-2)\n\
+\n\
+\n Note: Input files can also be in the PNG format\
+\n";
+
+void
+args_init (args_t *args)
+{
+ args->surface_a = NULL;
+ args->surface_b = NULL;
+ args->Verbose = false;
+ args->FieldOfView = 45.0f;
+ args->Gamma = 2.2f;
+ args->ThresholdPixels = 100;
+ args->Luminance = 100.0f;
+}
+
+void
+args_fini (args_t *args)
+{
+ cairo_surface_destroy (args->surface_a);
+ cairo_surface_destroy (args->surface_b);
+}
+
+bool
+args_parse (args_t *args, int argc, char **argv)
+{
+ int i;
+ if (argc < 3) {
+ fprintf (stderr, "%s", copyright);
+ fprintf (stderr, "%s", usage);
+ return false;
+ }
+ for (i = 0; i < argc; i++) {
+ if (i == 1) {
+ args->surface_a = cairo_image_surface_create_from_png (argv[1]);
+ if (cairo_surface_status (args->surface_a))
+ {
+ fprintf (stderr, "FAIL: Cannot open %s: %s\n",
+ argv[1], cairo_status_to_string (cairo_surface_status (args->surface_a)));
+ return false;
+ }
+ } else if (i == 2) {
+ args->surface_b = cairo_image_surface_create_from_png (argv[2]);
+ if (cairo_surface_status (args->surface_b))
+ {
+ fprintf (stderr, "FAIL: Cannot open %s: %s\n",
+ argv[2], cairo_status_to_string (cairo_surface_status (args->surface_b)));
+ return false;
+ }
+ } else {
+ if (strstr(argv[i], "-fov")) {
+ if (i + 1 < argc) {
+ args->FieldOfView = (float) atof(argv[i + 1]);
+ }
+ } else if (strstr(argv[i], "-verbose")) {
+ args->Verbose = true;
+ } else if (strstr(argv[i], "-threshold")) {
+ if (i + 1 < argc) {
+ args->ThresholdPixels = atoi(argv[i + 1]);
+ }
+ } else if (strstr(argv[i], "-gamma")) {
+ if (i + 1 < argc) {
+ args->Gamma = (float) atof(argv[i + 1]);
+ }
+ }else if (strstr(argv[i], "-luminance")) {
+ if (i + 1 < argc) {
+ args->Luminance = (float) atof(argv[i + 1]);
+ }
+ }
+ }
+ } /* i */
+ return true;
+}
+
+void
+args_print (args_t *args)
+{
+ printf("Field of view is %f degrees\n", args->FieldOfView);
+ printf("Threshold pixels is %d pixels\n", args->ThresholdPixels);
+ printf("The Gamma is %f\n", args->Gamma);
+ printf("The Display's luminance is %f candela per meter squared\n", args->Luminance);
+}
diff --git a/test/pdiff/args.h b/test/pdiff/args.h
new file mode 100644
index 000000000..502023915
--- /dev/null
+++ b/test/pdiff/args.h
@@ -0,0 +1,46 @@
+/*
+ Comapre Args
+ Copyright (C) 2006 Yangli Hector Yee
+
+ 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 2 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
+*/
+
+#ifndef _ARGS_H
+#define _ARGS_H
+
+#include "pdiff.h"
+
+/* Args to pass into the comparison function */
+typedef struct _args
+{
+ cairo_surface_t *surface_a; /* Image A */
+ cairo_surface_t *surface_b; /* Image B */
+ bool Verbose; /* Print lots of text or not */
+ float FieldOfView; /* Field of view in degrees */
+ float Gamma; /* The gamma to convert to linear color space */
+ float Luminance; /* the display's luminance */
+ unsigned int ThresholdPixels; /* How many pixels different to ignore */
+} args_t;
+
+void
+args_init (args_t *args);
+
+void
+args_fini (args_t *args);
+
+bool
+args_parse (args_t *args, int argc, char **argv);
+
+void
+args_print (args_t *args);
+
+#endif
diff --git a/test/pdiff/gpl.txt b/test/pdiff/gpl.txt
new file mode 100644
index 000000000..f90922eea
--- /dev/null
+++ b/test/pdiff/gpl.txt
@@ -0,0 +1,340 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ 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 2 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, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
diff --git a/test/pdiff/lpyramid.c b/test/pdiff/lpyramid.c
new file mode 100644
index 000000000..bd402c7da
--- /dev/null
+++ b/test/pdiff/lpyramid.c
@@ -0,0 +1,116 @@
+/*
+ Laplacian Pyramid
+ Copyright (C) 2006 Yangli Hector Yee
+
+ 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 2 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
+*/
+
+#include "lpyramid.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+struct _lpyramid {
+ /* Successively blurred versions of the original image */
+ float *levels[MAX_PYR_LEVELS];
+
+ int width;
+ int height;
+};
+
+static void
+convolve (lpyramid_t *pyramid, float *a, const float *b)
+/* convolves image b with the filter kernel and stores it in a */
+{
+ int y,x,i,j;
+ const float Kernel[] = {0.05f, 0.25f, 0.4f, 0.25f, 0.05f};
+ int width = pyramid->width;
+ int height = pyramid->height;
+
+ for (y=0; y<height; y++) {
+ for (x=0; x<width; x++) {
+ float sum = 0.f;
+ for (j=-2; j<=2; j++) {
+ float sum_i = 0.f;
+ int ny=y+j;
+ if (ny<0) ny=-ny;
+ if (ny>=height) ny=2*height - ny - 1;
+ ny *= width;
+ for (i=-2; i<=2; i++) {
+ int nx=x+i;
+ if (nx<0) nx=-nx;
+ if (nx>=width) nx=2*width - nx - 1;
+ sum_i += Kernel[i+2] * b[ny + nx];
+ }
+ sum += sum_i * Kernel[j+2];
+ }
+ *a++ = sum;
+ }
+ }
+}
+
+/*
+ * Construction/Destruction
+ */
+
+lpyramid_t *
+lpyramid_create (float *image, int width, int height)
+{
+ lpyramid_t *pyramid;
+ int i;
+
+ pyramid = malloc (sizeof (lpyramid_t));
+ if (pyramid == NULL) {
+ fprintf (stderr, "Out of memory.\n");
+ exit (1);
+ }
+ pyramid->width = width;
+ pyramid->height = height;
+
+ /* Make the Laplacian pyramid by successively
+ * copying the earlier levels and blurring them */
+ for (i=0; i<MAX_PYR_LEVELS; i++) {
+ pyramid->levels[i] = malloc (width * height * sizeof (float));
+ if (pyramid->levels[i] == NULL) {
+ fprintf (stderr, "Out of memory.\n");
+ exit (1);
+ }
+ if (i == 0) {
+ memcpy (pyramid->levels[i], image, width * height * sizeof (float));
+ } else {
+ convolve(pyramid, pyramid->levels[i], pyramid->levels[i - 1]);
+ }
+ }
+
+ return pyramid;
+}
+
+void
+lpyramid_destroy (lpyramid_t *pyramid)
+{
+ int i;
+
+ for (i=0; i<MAX_PYR_LEVELS; i++)
+ free (pyramid->levels[i]);
+
+ free (pyramid);
+}
+
+float
+lpyramid_get_value (lpyramid_t *pyramid, int x, int y, int level)
+{
+ int index = x + y * pyramid->width;
+ int l = level;
+ if (l > MAX_PYR_LEVELS)
+ l = MAX_PYR_LEVELS;
+ return pyramid->levels[l][index];
+}
diff --git a/test/pdiff/lpyramid.h b/test/pdiff/lpyramid.h
new file mode 100644
index 000000000..e47a66e20
--- /dev/null
+++ b/test/pdiff/lpyramid.h
@@ -0,0 +1,32 @@
+/*
+ Laplacian Pyramid
+ Copyright (C) 2006 Yangli Hector Yee
+
+ 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 2 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
+*/
+#ifndef _LPYRAMID_H
+#define _LPYRAMID_H
+
+#define MAX_PYR_LEVELS 8
+
+typedef struct _lpyramid lpyramid_t;
+
+lpyramid_t *
+lpyramid_create (float *image, int width, int height);
+
+void
+lpyramid_destroy (lpyramid_t *pyramid);
+
+float
+lpyramid_get_value (lpyramid_t *pyramid, int x, int y, int level);
+
+#endif /* _LPYRAMID_H */
diff --git a/test/pdiff/pdiff.c b/test/pdiff/pdiff.c
new file mode 100644
index 000000000..eb5f15682
--- /dev/null
+++ b/test/pdiff/pdiff.c
@@ -0,0 +1,420 @@
+/*
+ Metric
+ Copyright (C) 2006 Yangli Hector Yee
+
+ 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 2 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
+*/
+
+#define _GNU_SOURCE
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "lpyramid.h"
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#if HAVE_STDINT_H
+# include <stdint.h>
+#elif HAVE_INTTYPES_H
+# include <inttypes.h>
+#elif HAVE_SYS_INT_TYPES_H
+# include <sys/int_types.h>
+#elif defined(_MSC_VER)
+ typedef __int8 int8_t;
+ typedef unsigned __int8 uint8_t;
+ typedef __int16 int16_t;
+ typedef unsigned __int16 uint16_t;
+ typedef __int32 int32_t;
+ typedef unsigned __int32 uint32_t;
+ typedef __int64 int64_t;
+ typedef unsigned __int64 uint64_t;
+# ifndef HAVE_UINT64_T
+# define HAVE_UINT64_T 1
+# endif
+# ifndef INT16_MIN
+# define INT16_MIN (-32767-1)
+# endif
+# ifndef INT16_MAX
+# define INT16_MAX (32767)
+# endif
+# ifndef UINT16_MAX
+# define UINT16_MAX (65535)
+# endif
+#else
+#error Cannot find definitions for fixed-width integral types (uint8_t, uint32_t, etc.)
+#endif
+
+#include "pdiff.h"
+
+#ifndef M_PI
+#define M_PI 3.14159265f
+#endif
+
+#ifndef __USE_ISOC99
+#define expf exp
+#define powf pow
+#define fabsf fabs
+#define sqrtf sqrt
+#define log10f log10
+#endif
+
+/*
+ * Given the adaptation luminance, this function returns the
+ * threshold of visibility in cd per m^2
+ * TVI means Threshold vs Intensity function
+ * This version comes from Ward Larson Siggraph 1997
+ */
+static float
+tvi (float adaptation_luminance)
+{
+ /* returns the threshold luminance given the adaptation luminance
+ units are candelas per meter squared
+ */
+ float log_a, r, result;
+ log_a = log10f(adaptation_luminance);
+
+ if (log_a < -3.94f) {
+ r = -2.86f;
+ } else if (log_a < -1.44f) {
+ r = powf(0.405f * log_a + 1.6f , 2.18f) - 2.86f;
+ } else if (log_a < -0.0184f) {
+ r = log_a - 0.395f;
+ } else if (log_a < 1.9f) {
+ r = powf(0.249f * log_a + 0.65f, 2.7f) - 0.72f;
+ } else {
+ r = log_a - 1.255f;
+ }
+
+ result = powf(10.0f , r);
+
+ return result;
+}
+
+/* computes the contrast sensitivity function (Barten SPIE 1989)
+ * given the cycles per degree (cpd) and luminance (lum)
+ */
+static float
+csf (float cpd, float lum)
+{
+ float a, b, result;
+
+ a = 440.0f * powf((1.0f + 0.7f / lum), -0.2f);
+ b = 0.3f * powf((1.0f + 100.0f / lum), 0.15f);
+
+ result = a * cpd * expf(-b * cpd) * sqrtf(1.0f + 0.06f * expf(b * cpd));
+
+ return result;
+}
+
+/*
+ * Visual Masking Function
+ * from Daly 1993
+ */
+static float
+mask (float contrast)
+{
+ float a, b, result;
+ a = powf(392.498f * contrast, 0.7f);
+ b = powf(0.0153f * a, 4.0f);
+ result = powf(1.0f + b, 0.25f);
+
+ return result;
+}
+
+/* convert Adobe RGB (1998) with reference white D65 to XYZ */
+static void
+AdobeRGBToXYZ (float r, float g, float b, float *x, float *y, float *z)
+{
+ /* matrix is from http://www.brucelindbloom.com/ */
+ *x = r * 0.576700f + g * 0.185556f + b * 0.188212f;
+ *y = r * 0.297361f + g * 0.627355f + b * 0.0752847f;
+ *z = r * 0.0270328f + g * 0.0706879f + b * 0.991248f;
+}
+
+static void
+XYZToLAB (float x, float y, float z, float *L, float *A, float *B)
+{
+ static float xw = -1;
+ static float yw;
+ static float zw;
+ const float epsilon = 216.0f / 24389.0f;
+ const float kappa = 24389.0f / 27.0f;
+ float f[3];
+ float r[3];
+ int i;
+
+ /* reference white */
+ if (xw < 0) {
+ AdobeRGBToXYZ(1, 1, 1, &xw, &yw, &zw);
+ }
+ r[0] = x / xw;
+ r[1] = y / yw;
+ r[2] = z / zw;
+ for (i = 0; i < 3; i++) {
+ if (r[i] > epsilon) {
+ f[i] = powf(r[i], 1.0f / 3.0f);
+ } else {
+ f[i] = (kappa * r[i] + 16.0f) / 116.0f;
+ }
+ }
+ *L = 116.0f * f[1] - 16.0f;
+ *A = 500.0f * (f[0] - f[1]);
+ *B = 200.0f * (f[1] - f[2]);
+}
+
+static uint32_t
+_get_pixel (const uint32_t *data, int i)
+{
+ return data[i];
+}
+
+static unsigned char
+_get_red (const uint32_t *data, int i)
+{
+ uint32_t pixel;
+ uint8_t alpha;
+
+ pixel = _get_pixel (data, i);
+ alpha = (pixel & 0xff000000) >> 24;
+ if (alpha == 0)
+ return 0;
+ else
+ return (((pixel & 0x00ff0000) >> 16) * 255 + alpha / 2) / alpha;
+}
+
+static unsigned char
+_get_green (const uint32_t *data, int i)
+{
+ uint32_t pixel;
+ uint8_t alpha;
+
+ pixel = _get_pixel (data, i);
+ alpha = (pixel & 0xff000000) >> 24;
+ if (alpha == 0)
+ return 0;
+ else
+ return (((pixel & 0x0000ff00) >> 8) * 255 + alpha / 2) / alpha;
+}
+
+static unsigned char
+_get_blue (const uint32_t *data, int i)
+{
+ uint32_t pixel;
+ uint8_t alpha;
+
+ pixel = _get_pixel (data, i);
+ alpha = (pixel & 0xff000000) >> 24;
+ if (alpha == 0)
+ return 0;
+ else
+ return (((pixel & 0x000000ff) >> 0) * 255 + alpha / 2) / alpha;
+}
+
+static void *
+xmalloc (size_t size)
+{
+ void *buf;
+
+ buf = malloc (size);
+ if (buf == NULL) {
+ fprintf (stderr, "Out of memory.\n");
+ exit (1);
+ }
+
+ return buf;
+}
+
+int
+pdiff_compare (cairo_surface_t *surface_a,
+ cairo_surface_t *surface_b,
+ double gamma,
+ double luminance,
+ double field_of_view)
+{
+ unsigned int dim = (cairo_image_surface_get_width (surface_a)
+ * cairo_image_surface_get_height (surface_a));
+ unsigned int i;
+
+ /* assuming colorspaces are in Adobe RGB (1998) convert to XYZ */
+ float *aX;
+ float *aY;
+ float *aZ;
+ float *bX;
+ float *bY;
+ float *bZ;
+ float *aLum;
+ float *bLum;
+
+ float *aA;
+ float *bA;
+ float *aB;
+ float *bB;
+
+ unsigned int x, y, w, h;
+
+ lpyramid_t *la, *lb;
+
+ float num_one_degree_pixels, pixels_per_degree, num_pixels;
+ unsigned int adaptation_level;
+
+ float cpd[MAX_PYR_LEVELS];
+ float F_freq[MAX_PYR_LEVELS - 2];
+ float csf_max;
+ const uint32_t *data_a, *data_b;
+
+ unsigned int pixels_failed;
+
+ w = cairo_image_surface_get_width (surface_a);
+ h = cairo_image_surface_get_height (surface_a);
+ if (w < 3 || h < 3) /* too small for the Laplacian convolution */
+ return -1;
+
+ aX = xmalloc (dim * sizeof (float));
+ aY = xmalloc (dim * sizeof (float));
+ aZ = xmalloc (dim * sizeof (float));
+ bX = xmalloc (dim * sizeof (float));
+ bY = xmalloc (dim * sizeof (float));
+ bZ = xmalloc (dim * sizeof (float));
+ aLum = xmalloc (dim * sizeof (float));
+ bLum = xmalloc (dim * sizeof (float));
+
+ aA = xmalloc (dim * sizeof (float));
+ bA = xmalloc (dim * sizeof (float));
+ aB = xmalloc (dim * sizeof (float));
+ bB = xmalloc (dim * sizeof (float));
+
+ data_a = (uint32_t *) cairo_image_surface_get_data (surface_a);
+ data_b = (uint32_t *) cairo_image_surface_get_data (surface_b);
+ for (y = 0; y < h; y++) {
+ for (x = 0; x < w; x++) {
+ float r, g, b, l;
+ i = x + y * w;
+ r = powf(_get_red (data_a, i) / 255.0f, gamma);
+ g = powf(_get_green (data_a, i) / 255.0f, gamma);
+ b = powf(_get_blue (data_a, i) / 255.0f, gamma);
+
+ AdobeRGBToXYZ(r,g,b,&aX[i],&aY[i],&aZ[i]);
+ XYZToLAB(aX[i], aY[i], aZ[i], &l, &aA[i], &aB[i]);
+ r = powf(_get_red (data_b, i) / 255.0f, gamma);
+ g = powf(_get_green (data_b, i) / 255.0f, gamma);
+ b = powf(_get_blue (data_b, i) / 255.0f, gamma);
+
+ AdobeRGBToXYZ(r,g,b,&bX[i],&bY[i],&bZ[i]);
+ XYZToLAB(bX[i], bY[i], bZ[i], &l, &bA[i], &bB[i]);
+ aLum[i] = aY[i] * luminance;
+ bLum[i] = bY[i] * luminance;
+ }
+ }
+
+ la = lpyramid_create (aLum, w, h);
+ lb = lpyramid_create (bLum, w, h);
+
+ num_one_degree_pixels = (float) (2 * tan(field_of_view * 0.5 * M_PI / 180) * 180 / M_PI);
+ pixels_per_degree = w / num_one_degree_pixels;
+
+ num_pixels = 1;
+ adaptation_level = 0;
+ for (i = 0; i < MAX_PYR_LEVELS; i++) {
+ adaptation_level = i;
+ if (num_pixels > num_one_degree_pixels) break;
+ num_pixels *= 2;
+ }
+
+ cpd[0] = 0.5f * pixels_per_degree;
+ for (i = 1; i < MAX_PYR_LEVELS; i++) cpd[i] = 0.5f * cpd[i - 1];
+ csf_max = csf(3.248f, 100.0f);
+
+ for (i = 0; i < MAX_PYR_LEVELS - 2; i++) F_freq[i] = csf_max / csf( cpd[i], 100.0f);
+
+ pixels_failed = 0;
+ for (y = 0; y < h; y++) {
+ for (x = 0; x < w; x++) {
+ int index = x + y * w;
+ float contrast[MAX_PYR_LEVELS - 2];
+ float F_mask[MAX_PYR_LEVELS - 2];
+ float factor;
+ float delta;
+ float adapt;
+ bool pass;
+ float sum_contrast = 0;
+ for (i = 0; i < MAX_PYR_LEVELS - 2; i++) {
+ float n1 = fabsf(lpyramid_get_value (la,x,y,i) - lpyramid_get_value (la,x,y,i + 1));
+ float n2 = fabsf(lpyramid_get_value (lb,x,y,i) - lpyramid_get_value (lb,x,y,i + 1));
+ float numerator = (n1 > n2) ? n1 : n2;
+ float d1 = fabsf(lpyramid_get_value(la,x,y,i+2));
+ float d2 = fabsf(lpyramid_get_value(lb,x,y,i+2));
+ float denominator = (d1 > d2) ? d1 : d2;
+ if (denominator < 1e-5f) denominator = 1e-5f;
+ contrast[i] = numerator / denominator;
+ sum_contrast += contrast[i];
+ }
+ if (sum_contrast < 1e-5) sum_contrast = 1e-5f;
+ adapt = lpyramid_get_value(la,x,y,adaptation_level) + lpyramid_get_value(lb,x,y,adaptation_level);
+ adapt *= 0.5f;
+ if (adapt < 1e-5) adapt = 1e-5f;
+ for (i = 0; i < MAX_PYR_LEVELS - 2; i++) {
+ F_mask[i] = mask(contrast[i] * csf(cpd[i], adapt));
+ }
+ factor = 0;
+ for (i = 0; i < MAX_PYR_LEVELS - 2; i++) {
+ factor += contrast[i] * F_freq[i] * F_mask[i] / sum_contrast;
+ }
+ if (factor < 1) factor = 1;
+ if (factor > 10) factor = 10;
+ delta = fabsf(lpyramid_get_value(la,x,y,0) - lpyramid_get_value(lb,x,y,0));
+ pass = true;
+ /* pure luminance test */
+ if (delta > factor * tvi(adapt)) {
+ pass = false;
+ } else {
+ /* CIE delta E test with modifications */
+ float color_scale = 1.0f;
+ float da = aA[index] - bA[index];
+ float db = aB[index] - bB[index];
+ float delta_e;
+ /* ramp down the color test in scotopic regions */
+ if (adapt < 10.0f) {
+ color_scale = 1.0f - (10.0f - color_scale) / 10.0f;
+ color_scale = color_scale * color_scale;
+ }
+ da = da * da;
+ db = db * db;
+ delta_e = (da + db) * color_scale;
+ if (delta_e > factor) {
+ pass = false;
+ }
+ }
+ if (!pass)
+ pixels_failed++;
+ }
+ }
+
+ free (aX);
+ free (aY);
+ free (aZ);
+ free (bX);
+ free (bY);
+ free (bZ);
+ free (aLum);
+ free (bLum);
+ lpyramid_destroy (la);
+ lpyramid_destroy (lb);
+ free (aA);
+ free (bA);
+ free (aB);
+ free (bB);
+
+ return pixels_failed;
+}
diff --git a/test/pdiff/pdiff.h b/test/pdiff/pdiff.h
new file mode 100644
index 000000000..30fec06cf
--- /dev/null
+++ b/test/pdiff/pdiff.h
@@ -0,0 +1,40 @@
+/*
+ Copyright (C) 2006 Yangli Hector Yee
+ Copyright (C) 2006 Red Hat, Inc.
+
+ 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 2 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
+*/
+
+#ifndef _PDIFF_H
+#define _PDIFF_H
+
+#include <cairo.h>
+
+typedef int bool;
+#ifndef true
+#define true 1
+#endif
+#ifndef false
+#define false 0
+#endif
+
+/* Image comparison metric using Yee's method (and a cairo interface)
+ * References: A Perceptual Metric for Production Testing, Hector Yee, Journal of Graphics Tools 2004
+ */
+int
+pdiff_compare (cairo_surface_t *surface_a,
+ cairo_surface_t *surface_b,
+ double gamma,
+ double luminance,
+ double field_of_view);
+
+#endif
diff --git a/test/pdiff/perceptualdiff.c b/test/pdiff/perceptualdiff.c
new file mode 100644
index 000000000..5850dc916
--- /dev/null
+++ b/test/pdiff/perceptualdiff.c
@@ -0,0 +1,101 @@
+/*
+ PerceptualDiff - a program that compares two images using a perceptual metric
+ based on the paper :
+ A perceptual metric for production testing. Journal of graphics tools, 9(4):33-40, 2004, Hector Yee
+ Copyright (C) 2006 Yangli Hector Yee
+
+ 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 2 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
+*/
+
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <math.h>
+#include "lpyramid.h"
+#include "args.h"
+#include "pdiff.h"
+
+static bool Yee_Compare(args_t *args)
+{
+ unsigned int width_a, height_a, stride_a;
+ unsigned char *data_a, *row_a;
+ uint32_t *pixel_a;
+ unsigned int width_b, height_b, stride_b;
+ unsigned char *data_b, *row_b;
+ uint32_t *pixel_b;
+ unsigned int x, y, pixels_failed;
+ bool identical = true;
+
+ width_a = cairo_image_surface_get_width (args->surface_a);
+ height_a = cairo_image_surface_get_height (args->surface_a);
+ stride_a = cairo_image_surface_get_stride (args->surface_a);
+ data_a = cairo_image_surface_get_data (args->surface_a);
+
+ width_b = cairo_image_surface_get_width (args->surface_b);
+ height_b = cairo_image_surface_get_height (args->surface_b);
+ stride_b = cairo_image_surface_get_stride (args->surface_b);
+ data_b = cairo_image_surface_get_data (args->surface_b);
+
+ if ((width_a != width_b) || (height_a != height_b)) {
+ printf ("FAIL: Image dimensions do not match\n");
+ return false;
+ }
+
+ identical = true;
+
+ for (y = 0; y < height_a; y++) {
+ row_a = data_a + y * stride_a;
+ row_b = data_b + y * stride_b;
+ pixel_a = (uint32_t *) row_a;
+ pixel_b = (uint32_t *) row_b;
+ for (x = 0; x < width_a; x++) {
+ if (*pixel_a != *pixel_b) {
+ identical = false;
+ }
+ pixel_a++;
+ pixel_b++;
+ }
+ }
+ if (identical) {
+ printf ("PASS: Images are binary identical\n");
+ return true;
+ }
+
+ pixels_failed = pdiff_compare (args->surface_a, args->surface_b,
+ args->Gamma, args->Luminance,
+ args->FieldOfView);
+
+ if (pixels_failed < args->ThresholdPixels) {
+ printf ("PASS: Images are perceptually indistinguishable\n");
+ return true;
+ }
+
+ printf("FAIL: Images are visibly different\n"
+ "%d pixels are different\n", pixels_failed);
+
+ return false;
+}
+
+int main(int argc, char **argv)
+{
+ args_t args;
+
+ args_init (&args);
+
+ if (!args_parse (&args, argc, argv)) {
+ return -1;
+ } else {
+ if (args.Verbose)
+ args_print (&args);
+ }
+ return ! Yee_Compare(&args);
+}
diff --git a/test/pixman-downscale.c b/test/pixman-downscale.c
new file mode 100644
index 000000000..6b653d223
--- /dev/null
+++ b/test/pixman-downscale.c
@@ -0,0 +1,203 @@
+/*
+ * Copyright © 2013 Samsung Electronics
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Bryce Harrington <b.harrington@samsung.com>
+ */
+
+/* This test exercises scaling a png image to smaller pixel dimensions
+ *
+ * Currently, this exercises several of pixman's scaling filters.
+ */
+
+#include "cairo-test.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <cairo.h>
+
+static const char png_filename[] = "quad-color.png";
+
+/* Draw an image scaled down, with antialiasing disabled */
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height, cairo_filter_t filter)
+{
+ const cairo_test_context_t *ctx = cairo_test_get_context (cr);
+ cairo_surface_t *image;
+ double x_scale, y_scale, scale;
+
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ image = cairo_test_create_surface_from_png (ctx, png_filename);
+ x_scale = width * 1.0 / cairo_image_surface_get_width (image);
+ y_scale = height * 1.0 / cairo_image_surface_get_height (image);
+ scale = x_scale < y_scale ? x_scale : y_scale;
+
+ cairo_save (cr);
+ cairo_scale (cr, scale, scale);
+ cairo_set_source_surface (cr, image, 0, 0);
+ cairo_pattern_set_filter (cairo_get_source (cr), filter);
+ cairo_paint (cr);
+ cairo_restore (cr);
+ cairo_surface_destroy (image);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+draw_fast (cairo_t *cr, int width, int height)
+{
+ return draw (cr, width, height, CAIRO_FILTER_FAST);
+}
+
+static cairo_test_status_t
+draw_good (cairo_t *cr, int width, int height)
+{
+ return draw (cr, width, height, CAIRO_FILTER_GOOD);
+}
+
+static cairo_test_status_t
+draw_best (cairo_t *cr, int width, int height)
+{
+ return draw (cr, width, height, CAIRO_FILTER_BEST);
+}
+
+static cairo_test_status_t
+draw_nearest (cairo_t *cr, int width, int height)
+{
+ return draw (cr, width, height, CAIRO_FILTER_NEAREST);
+}
+
+static cairo_test_status_t
+draw_bilinear (cairo_t *cr, int width, int height)
+{
+ return draw (cr, width, height, CAIRO_FILTER_BILINEAR);
+}
+
+CAIRO_TEST (pixman_downscale_fast_96,
+ "Tests scaling to equivalent size using the fast filter",
+ "image, transform, raster, downscale", /* keywords */
+ NULL, /* requirements */
+ 96, 96,
+ NULL, draw_fast)
+
+CAIRO_TEST (pixman_downscale_fast_95,
+ "Tests downscaling by a single pixel using the fast filter",
+ "image, transform, raster, downscale", /* keywords */
+ NULL, /* requirements */
+ 95, 95,
+ NULL, draw_fast)
+
+CAIRO_TEST (pixman_downscale_fast_24,
+ "Tests downscaling by an even multiple using the fast filter",
+ "image, transform, raster, downscale", /* keywords */
+ NULL, /* requirements */
+ 24, 24,
+ NULL, draw_fast)
+
+
+CAIRO_TEST (pixman_downscale_good_96,
+ "Tests scaling to equivalent size using the good filter",
+ "image, transform, raster, downscale", /* keywords */
+ NULL, /* requirements */
+ 96, 96,
+ NULL, draw_good)
+
+CAIRO_TEST (pixman_downscale_good_95,
+ "Tests downscaling by a single pixel using the good filter",
+ "image, transform, raster, downscale", /* keywords */
+ NULL, /* requirements */
+ 95, 95,
+ NULL, draw_good)
+
+CAIRO_TEST (pixman_downscale_good_24,
+ "Tests downscaling by an even multiple using the good filter",
+ "image, transform, raster, downscale", /* keywords */
+ NULL, /* requirements */
+ 24, 24,
+ NULL, draw_good)
+
+
+CAIRO_TEST (pixman_downscale_best_96,
+ "Tests scaling to equivalent size using the best filter",
+ "image, transform, raster, downscale", /* keywords */
+ NULL, /* requirements */
+ 96, 96,
+ NULL, draw_best)
+
+CAIRO_TEST (pixman_downscale_best_95,
+ "Tests downscaling by a single pixel using the best filter",
+ "image, transform, raster, downscale", /* keywords */
+ NULL, /* requirements */
+ 95, 95,
+ NULL, draw_best)
+
+CAIRO_TEST (pixman_downscale_best_24,
+ "Tests downscaling by an even multiple using the best filter",
+ "image, transform, raster, downscale", /* keywords */
+ NULL, /* requirements */
+ 24, 24,
+ NULL, draw_best)
+
+
+CAIRO_TEST (pixman_downscale_nearest_96,
+ "Tests scaling to equivalent size using the nearest filter",
+ "image, transform, raster, downscale", /* keywords */
+ NULL, /* requirements */
+ 96, 96,
+ NULL, draw_nearest)
+
+CAIRO_TEST (pixman_downscale_nearest_95,
+ "Tests downscaling by a single pixel using the nearest filter",
+ "image, transform, raster, downscale", /* keywords */
+ NULL, /* requirements */
+ 95, 95,
+ NULL, draw_nearest)
+
+CAIRO_TEST (pixman_downscale_nearest_24,
+ "Tests downscaling by an even multiple using the nearest filter",
+ "image, transform, raster, downscale", /* keywords */
+ NULL, /* requirements */
+ 24, 24,
+ NULL, draw_nearest)
+
+
+CAIRO_TEST (pixman_downscale_bilinear_96,
+ "Tests scaling to equivalent size using the bilinear filter",
+ "image, transform, raster, downscale", /* keywords */
+ NULL, /* requirements */
+ 96, 96,
+ NULL, draw_bilinear)
+
+CAIRO_TEST (pixman_downscale_bilinear_95,
+ "Tests downscaling by a single pixel using the bilinear filter",
+ "image, transform, raster, downscale", /* keywords */
+ NULL, /* requirements */
+ 95, 95,
+ NULL, draw_bilinear)
+
+CAIRO_TEST (pixman_downscale_bilinear_24,
+ "Tests downscaling by an even multiple using the bilinear filter",
+ "image, transform, raster, downscale", /* keywords */
+ NULL, /* requirements */
+ 24, 24,
+ NULL, draw_bilinear)
diff --git a/test/pixman-rotate.c b/test/pixman-rotate.c
new file mode 100644
index 000000000..e0d0fc885
--- /dev/null
+++ b/test/pixman-rotate.c
@@ -0,0 +1,92 @@
+/*
+ * Copyright © 2007 Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Kristian Høgsberg <krh@redhat.com>
+ */
+
+#include "cairo-test.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+#include <cairo.h>
+
+#define WIDTH 32
+#define HEIGHT WIDTH
+
+#define IMAGE_WIDTH (3 * WIDTH)
+#define IMAGE_HEIGHT IMAGE_WIDTH
+
+/* Draw the word cairo at NUM_TEXT different angles */
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_surface_t *stamp;
+ cairo_t *cr2;
+
+ /* Draw a translucent rectangle for reference where the rotated
+ * image should be. */
+ cairo_new_path (cr);
+ cairo_rectangle (cr, WIDTH, HEIGHT, WIDTH, HEIGHT);
+ cairo_set_source_rgba (cr, 1, 1, 0, 0.3);
+ cairo_fill (cr);
+
+#if 1 /* Set to 0 to generate reference image */
+ cairo_translate (cr, 2 * WIDTH, 2 * HEIGHT);
+ cairo_rotate (cr, M_PI);
+#else
+ cairo_translate (cr, WIDTH, HEIGHT);
+#endif
+
+ stamp = cairo_surface_create_similar (cairo_get_group_target (cr),
+ CAIRO_CONTENT_COLOR_ALPHA,
+ WIDTH, HEIGHT);
+ cr2 = cairo_create (stamp);
+ cairo_surface_destroy (stamp);
+ {
+ cairo_new_path (cr2);
+ cairo_rectangle (cr2, WIDTH / 4, HEIGHT / 4, WIDTH / 2, HEIGHT / 2);
+ cairo_set_source_rgba (cr2, 1, 0, 0, 0.8);
+ cairo_fill (cr2);
+
+ cairo_rectangle (cr2, 0, 0, WIDTH, HEIGHT);
+ cairo_set_line_width (cr2, 2);
+ cairo_set_source_rgb (cr2, 0, 0, 0);
+ cairo_stroke (cr2);
+ }
+ cairo_set_source_surface (cr, cairo_get_target (cr2), 0, 0);
+ cairo_destroy (cr2);
+
+ cairo_paint (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (pixman_rotate,
+ "Exposes pixman off-by-one error when rotating",
+ "image, transform", /* keywords */
+ NULL, /* requirements */
+ IMAGE_WIDTH, IMAGE_HEIGHT,
+ NULL, draw)
diff --git a/test/png-flatten.c b/test/png-flatten.c
new file mode 100644
index 000000000..2ce804ea6
--- /dev/null
+++ b/test/png-flatten.c
@@ -0,0 +1,77 @@
+/*
+ * Copyright © 2005 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl Worth <cworth@cworth.org>
+ */
+
+#include <stdio.h>
+
+#include <cairo.h>
+
+int
+main (int argc, char *argv[])
+{
+ cairo_t *cr;
+ cairo_surface_t *argb, *rgb24;
+ cairo_status_t status;
+ const char *input, *output;
+
+ if (argc != 3) {
+ fprintf (stderr, "usage: %s input.png output.png", argv[0]);
+ fprintf (stderr, "Loads a PNG image (potentially with alpha) and writes out a flattened (no alpha)\nPNG image by first blending over white.\n");
+ return 1;
+ }
+
+ input = argv[1];
+ output = argv[2];
+
+ argb = cairo_image_surface_create_from_png (input);
+ status = cairo_surface_status (argb);
+ if (status) {
+ fprintf (stderr, "%s: Error: Failed to load %s: %s\n",
+ argv[0], input, cairo_status_to_string (status));
+ return 1;
+ }
+
+ rgb24 = cairo_image_surface_create (CAIRO_FORMAT_RGB24,
+ cairo_image_surface_get_width (argb),
+ cairo_image_surface_get_height (argb));
+
+ cr = cairo_create (rgb24);
+
+ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */
+ cairo_paint (cr);
+
+ cairo_set_source_surface (cr, argb, 0, 0);
+ cairo_paint (cr);
+
+ cairo_destroy (cr);
+
+ status = cairo_surface_write_to_png (rgb24, output);
+ if (status) {
+ fprintf (stderr, "%s: Error: Failed to write %s: %s\n",
+ argv[0], output, cairo_status_to_string (status));
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/test/png.c b/test/png.c
new file mode 100644
index 000000000..c01fbd7bd
--- /dev/null
+++ b/test/png.c
@@ -0,0 +1,172 @@
+/*
+ * Copyright © 2008 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Chris Wilson not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Chris Wilson makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+#include <assert.h>
+
+/* Test the idempotency of write_png->read_png */
+
+#define RGB_MASK 0x00ffffff
+#define BASENAME "png.out"
+
+static cairo_bool_t
+image_surface_equals (cairo_surface_t *A, cairo_surface_t *B)
+{
+ if (cairo_image_surface_get_format (A) !=
+ cairo_image_surface_get_format (B))
+ return 0;
+
+ if (cairo_image_surface_get_width (A) !=
+ cairo_image_surface_get_width (B))
+ return 0;
+
+ if (cairo_image_surface_get_height (A) !=
+ cairo_image_surface_get_height (B))
+ return 0;
+
+ return 1;
+}
+
+static const char *
+format_to_string (cairo_format_t format)
+{
+ switch (format) {
+ case CAIRO_FORMAT_A1: return "a1";
+ case CAIRO_FORMAT_A8: return "a8";
+ case CAIRO_FORMAT_RGB16_565: return "rgb16";
+ case CAIRO_FORMAT_RGB24: return "rgb24";
+ case CAIRO_FORMAT_RGB30: return "rgb30";
+ case CAIRO_FORMAT_ARGB32: return "argb32";
+ case CAIRO_FORMAT_INVALID:
+ default: return "???";
+ }
+}
+
+static void
+print_surface (const cairo_test_context_t *ctx, cairo_surface_t *surface)
+{
+ cairo_test_log (ctx,
+ "%s (%dx%d)\n",
+ format_to_string (cairo_image_surface_get_format (surface)),
+ cairo_image_surface_get_width (surface),
+ cairo_image_surface_get_height (surface));
+}
+
+static cairo_test_status_t
+preamble (cairo_test_context_t *ctx)
+{
+ cairo_surface_t *surface0, *surface1;
+ cairo_status_t status;
+ uint32_t argb32 = 0xdeadbede;
+ char *filename;
+ const char *path = cairo_test_mkdir (CAIRO_TEST_OUTPUT_DIR) ? CAIRO_TEST_OUTPUT_DIR : ".";
+
+ xasprintf (&filename, "%s/%s.png", path, BASENAME);
+ surface0 = cairo_image_surface_create_for_data ((unsigned char *) &argb32,
+ CAIRO_FORMAT_ARGB32,
+ 1, 1, 4);
+ status = cairo_surface_write_to_png (surface0, filename);
+ if (status) {
+ cairo_test_log (ctx, "Error writing '%s': %s\n",
+ filename, cairo_status_to_string (status));
+
+ cairo_surface_destroy (surface0);
+ free (filename);
+ return cairo_test_status_from_status (ctx, status);
+ }
+ surface1 = cairo_image_surface_create_from_png (filename);
+ status = cairo_surface_status (surface1);
+ if (status) {
+ cairo_test_log (ctx, "Error reading '%s': %s\n",
+ filename, cairo_status_to_string (status));
+
+ cairo_surface_destroy (surface1);
+ cairo_surface_destroy (surface0);
+ free (filename);
+ return cairo_test_status_from_status (ctx, status);
+ }
+
+ if (! image_surface_equals (surface0, surface1)) {
+ cairo_test_log (ctx, "Error surface mismatch.\n");
+ cairo_test_log (ctx, "to png: "); print_surface (ctx, surface0);
+ cairo_test_log (ctx, "from png: "); print_surface (ctx, surface1);
+
+ cairo_surface_destroy (surface0);
+ cairo_surface_destroy (surface1);
+ free (filename);
+ return CAIRO_TEST_FAILURE;
+ }
+ assert (*(uint32_t *) cairo_image_surface_get_data (surface1) == argb32);
+
+ cairo_surface_destroy (surface0);
+ cairo_surface_destroy (surface1);
+
+ surface0 = cairo_image_surface_create_for_data ((unsigned char *) &argb32,
+ CAIRO_FORMAT_RGB24,
+ 1, 1, 4);
+ status = cairo_surface_write_to_png (surface0, filename);
+ if (status) {
+ cairo_test_log (ctx, "Error writing '%s': %s\n",
+ filename, cairo_status_to_string (status));
+ cairo_surface_destroy (surface0);
+ return cairo_test_status_from_status (ctx, status);
+ }
+ surface1 = cairo_image_surface_create_from_png (filename);
+ status = cairo_surface_status (surface1);
+ free (filename);
+ if (status) {
+ cairo_test_log (ctx, "Error reading '%s': %s\n",
+ filename, cairo_status_to_string (status));
+
+ cairo_surface_destroy (surface1);
+ cairo_surface_destroy (surface0);
+ return cairo_test_status_from_status (ctx, status);
+ }
+
+ if (! image_surface_equals (surface0, surface1)) {
+ cairo_test_log (ctx, "Error surface mismatch.\n");
+ cairo_test_log (ctx, "to png: "); print_surface (ctx, surface0);
+ cairo_test_log (ctx, "from png: "); print_surface (ctx, surface1);
+
+ cairo_surface_destroy (surface0);
+ cairo_surface_destroy (surface1);
+ return CAIRO_TEST_FAILURE;
+ }
+ assert ((*(uint32_t *) cairo_image_surface_get_data (surface1) & RGB_MASK)
+ == (argb32 & RGB_MASK));
+
+ cairo_surface_destroy (surface0);
+ cairo_surface_destroy (surface1);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (png,
+ "Check that the png export/import is idempotent.",
+ "png, api", /* keywords */
+ NULL, /* requirements */
+ 0, 0,
+ preamble, NULL)
diff --git a/test/png.png b/test/png.png
new file mode 100644
index 000000000..56c428e12
--- /dev/null
+++ b/test/png.png
Binary files differ
diff --git a/test/ps-eps.c b/test/ps-eps.c
new file mode 100644
index 000000000..de1248d81
--- /dev/null
+++ b/test/ps-eps.c
@@ -0,0 +1,354 @@
+/*
+ * Copyright © 2006 Red Hat, Inc.
+ * Copyright © 2009 Adrian Johnson
+ * Copyright © 2008 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ * Adrian Johnson <ajohnson@redneon.com>
+ * Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <cairo.h>
+#include <cairo-ps.h>
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#include <errno.h>
+#endif
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+
+#include "cairo-test.h"
+#include "buffer-diff.h"
+
+/* Test EPS output.
+ */
+
+#define WIDTH 595
+#define HEIGHT 842
+
+/* Reference Bounding Box */
+#define LLX 95
+#define LLY 687
+#define URX 155
+#define URY 747
+
+static void
+_xunlink (const cairo_test_context_t *ctx, const char *pathname)
+{
+ if (unlink (pathname) < 0 && errno != ENOENT) {
+ cairo_test_log (ctx, "Error: Cannot remove %s: %s\n",
+ pathname, strerror (errno));
+ exit (1);
+ }
+}
+
+static cairo_bool_t
+check_result (cairo_test_context_t *ctx,
+ const cairo_boilerplate_target_t *target,
+ const char *test_name,
+ const char *base_name,
+ cairo_surface_t *surface)
+{
+ const char *format;
+ char *ref_name;
+ char *png_name;
+ char *diff_name;
+ cairo_surface_t *test_image, *ref_image, *diff_image;
+ buffer_diff_result_t result;
+ cairo_status_t status;
+ cairo_bool_t ret;
+
+ /* XXX log target, OUTPUT, REFERENCE, DIFFERENCE for index.html */
+
+ if (target->finish_surface != NULL) {
+ status = target->finish_surface (surface);
+ if (status) {
+ cairo_test_log (ctx, "Error: Failed to finish surface: %s\n",
+ cairo_status_to_string (status));
+ cairo_surface_destroy (surface);
+ return FALSE;
+ }
+ }
+
+ xasprintf (&png_name, "%s.out.png", base_name);
+ xasprintf (&diff_name, "%s.diff.png", base_name);
+
+ test_image = target->get_image_surface (surface, 0, WIDTH, HEIGHT);
+ if (cairo_surface_status (test_image)) {
+ cairo_test_log (ctx, "Error: Failed to extract page: %s\n",
+ cairo_status_to_string (cairo_surface_status (test_image)));
+ cairo_surface_destroy (test_image);
+ free (png_name);
+ free (diff_name);
+ return FALSE;
+ }
+
+ _xunlink (ctx, png_name);
+ status = cairo_surface_write_to_png (test_image, png_name);
+ if (status) {
+ cairo_test_log (ctx, "Error: Failed to write output image: %s\n",
+ cairo_status_to_string (status));
+ cairo_surface_destroy (test_image);
+ free (png_name);
+ free (diff_name);
+ return FALSE;
+ }
+
+ format = cairo_boilerplate_content_name (target->content);
+ ref_name = cairo_test_reference_filename (ctx,
+ base_name,
+ test_name,
+ target->name,
+ target->basename,
+ format,
+ CAIRO_TEST_REF_SUFFIX,
+ CAIRO_TEST_PNG_EXTENSION);
+ if (ref_name == NULL) {
+ cairo_test_log (ctx, "Error: Cannot find reference image for %s\n",
+ base_name);
+ cairo_surface_destroy (test_image);
+ free (png_name);
+ free (diff_name);
+ return FALSE;
+ }
+
+ ref_image = cairo_test_get_reference_image (ctx, ref_name,
+ target->content == CAIRO_TEST_CONTENT_COLOR_ALPHA_FLATTENED);
+ if (cairo_surface_status (ref_image)) {
+ cairo_test_log (ctx, "Error: Cannot open reference image for %s: %s\n",
+ ref_name,
+ cairo_status_to_string (cairo_surface_status (ref_image)));
+ cairo_surface_destroy (ref_image);
+ cairo_surface_destroy (test_image);
+ free (png_name);
+ free (diff_name);
+ free (ref_name);
+ return FALSE;
+ }
+
+ diff_image = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
+ WIDTH, HEIGHT);
+
+ ret = TRUE;
+ status = image_diff (ctx,
+ test_image, ref_image, diff_image,
+ &result);
+ _xunlink (ctx, diff_name);
+ if (status) {
+ cairo_test_log (ctx, "Error: Failed to compare images: %s\n",
+ cairo_status_to_string (status));
+ ret = FALSE;
+ } else if (image_diff_is_failure (&result, target->error_tolerance))
+ {
+ ret = FALSE;
+
+ status = cairo_surface_write_to_png (diff_image, diff_name);
+ if (status) {
+ cairo_test_log (ctx, "Error: Failed to write differences image: %s\n",
+ cairo_status_to_string (status));
+ }
+ }
+
+ cairo_surface_destroy (test_image);
+ cairo_surface_destroy (diff_image);
+ free (png_name);
+ free (diff_name);
+ free (ref_name);
+
+ return ret;
+}
+
+
+#define DOCUMENT_BBOX "%%BoundingBox:"
+#define PAGE_BBOX "%%PageBoundingBox:"
+
+static cairo_bool_t
+check_bbox (cairo_test_context_t *ctx,
+ const char *base_name)
+{
+ char *filename;
+ FILE *f;
+ char buf[256];
+ cairo_bool_t bbox_pass, page_bbox_pass;
+ int llx, lly, urx, ury;
+ int ret;
+
+ xasprintf (&filename, "%s.out.ps", base_name);
+ f = fopen (filename, "r");
+ if (!f) {
+ cairo_test_log (ctx, "Error: Cannot open EPS output: %s\n",
+ base_name);
+ free (filename);
+ return FALSE;
+ }
+
+ bbox_pass = FALSE;
+ page_bbox_pass = FALSE;
+ while (!feof(f)) {
+ if (fgets (buf, sizeof(buf), f) == (char *)EOF) {
+ cairo_test_log (ctx, "Error: Unexpected EOF in %s\n",
+ filename);
+ break;
+ }
+
+ if (strncmp (buf, DOCUMENT_BBOX, strlen (DOCUMENT_BBOX)) == 0) {
+ ret = sscanf (buf+strlen (DOCUMENT_BBOX), "%d %d %d %d", &llx, &lly, &urx, &ury);
+ if (ret == 4 && llx == LLX && lly == LLY && urx == URX && ury == URY)
+ bbox_pass = TRUE;
+ }
+
+ if (strncmp (buf, PAGE_BBOX, strlen (PAGE_BBOX)) == 0) {
+ ret = sscanf (buf+strlen (PAGE_BBOX), "%d %d %d %d", &llx, &lly, &urx, &ury);
+ if (ret == 4 && llx == LLX && lly == LLY && urx == URX && ury == URY)
+ page_bbox_pass = TRUE;
+ }
+ }
+ fclose (f);
+
+ if (!bbox_pass || !page_bbox_pass) {
+ cairo_test_log (ctx, "Error: EPS Bounding Box does not match reference Bounding Box\n");
+ return FALSE;
+ }
+
+ free (filename);
+
+ return TRUE;
+}
+
+static cairo_test_status_t
+preamble (cairo_test_context_t *ctx)
+{
+ cairo_t *cr;
+ cairo_test_status_t ret = CAIRO_TEST_UNTESTED;
+ unsigned int i;
+ const char *path = cairo_test_mkdir (CAIRO_TEST_OUTPUT_DIR) ? CAIRO_TEST_OUTPUT_DIR : ".";
+
+ for (i = 0; i < ctx->num_targets; i++) {
+ const cairo_boilerplate_target_t *target = ctx->targets_to_test[i];
+ cairo_surface_t *surface = NULL;
+ char *base_name;
+ void *closure;
+ const char *format;
+ cairo_status_t status;
+ cairo_bool_t pass;
+ char *test_name;
+
+ if (! cairo_test_is_target_enabled (ctx, target->name))
+ continue;
+
+ format = cairo_boilerplate_content_name (target->content);
+ xasprintf (&test_name, "ps-eps");
+ xasprintf (&base_name, "%s/ps-eps.%s.%s",
+ path, target->name, format);
+
+ surface = (target->create_surface) (base_name,
+ target->content,
+ WIDTH, HEIGHT,
+ WIDTH, HEIGHT,
+ CAIRO_BOILERPLATE_MODE_TEST,
+ &closure);
+
+ if (surface == NULL) {
+ free (base_name);
+ free (test_name);
+ continue;
+ }
+
+ cairo_ps_surface_set_eps (surface, TRUE);
+ if (!cairo_ps_surface_get_eps (surface)) {
+ cairo_surface_destroy (surface);
+ if (target->cleanup)
+ target->cleanup (closure);
+
+ free (base_name);
+ free (test_name);
+ continue;
+ }
+
+ cairo_test_log (ctx,
+ "Testing ps-eps with %s target\n",
+ target->name);
+ printf ("%s:\t", base_name);
+ fflush (stdout);
+
+ cairo_surface_set_device_offset (surface, 25, 25);
+ cr = cairo_create (surface);
+
+ cairo_new_sub_path (cr);
+ cairo_arc (cr, 100, 100, 25, 0, 2*M_PI);
+ cairo_set_line_width (cr, 10);
+ cairo_stroke (cr);
+
+ cairo_show_page (cr);
+
+ status = cairo_status (cr);
+ cairo_destroy (cr);
+
+ if (status) {
+ cairo_test_log (ctx, "Error: Failed to create target surface: %s\n",
+ cairo_status_to_string (status));
+ pass = FALSE;
+ } else {
+ pass = TRUE;
+ /* extract the image and compare it to our reference */
+ if (! check_result (ctx, target, test_name, base_name, surface))
+ pass = FALSE;
+
+ /* check the bounding box of the EPS file and compare it to our reference */
+ if (! check_bbox (ctx, base_name))
+ pass = FALSE;
+ }
+ cairo_surface_destroy (surface);
+ if (target->cleanup)
+ target->cleanup (closure);
+
+ free (base_name);
+ free (test_name);
+
+ if (pass) {
+ printf ("PASS\n");
+ ret = CAIRO_TEST_SUCCESS;
+ } else {
+ printf ("FAIL\n");
+ ret = CAIRO_TEST_FAILURE;
+ }
+ fflush (stdout);
+ }
+
+ return ret;
+}
+
+CAIRO_TEST (ps_eps,
+ "Check EPS output from PS surface",
+ "ps, api", /* keywords */
+ NULL, /* requirements */
+ 0, 0,
+ preamble, NULL)
diff --git a/test/ps-features.c b/test/ps-features.c
new file mode 100644
index 000000000..d1abf91fe
--- /dev/null
+++ b/test/ps-features.c
@@ -0,0 +1,166 @@
+/*
+ * Copyright © 2006 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+#include "cairo-test.h"
+
+#include <stdio.h>
+#include <cairo.h>
+#include <cairo-ps.h>
+
+/* This test exists to test the various features of cairo-ps.h.
+ *
+ * Currently, this test exercises the following function calls:
+ *
+ * cairo_ps_surface_set_size
+ * cairo_ps_surface_dsc_comment
+ * cairo_ps_surface_dsc_begin_setup
+ * cairo_ps_surface_dsc_begin_page_setup
+ */
+
+#define INCHES_TO_POINTS(in) ((in) * 72.0)
+#define MM_TO_POINTS(mm) ((mm) / 25.4 * 72.0)
+#define TEXT_SIZE 12
+#define BASENAME "ps-features.out"
+
+static struct {
+ const char *page_size;
+ const char *page_size_alias;
+ const char *orientation;
+ double width_in_points;
+ double height_in_points;
+} pages[] = {
+ {"na_letter_8.5x11in", "letter", "portrait",
+ INCHES_TO_POINTS(8.5), INCHES_TO_POINTS(11)},
+ {"na_letter_8.5x11in", "letter", "landscape",
+ INCHES_TO_POINTS(11), INCHES_TO_POINTS(8.5)},
+ {"iso_a4_210x297mm", "a4", "portrait",
+ MM_TO_POINTS(210), MM_TO_POINTS(297)},
+ {"iso_a4_210x297mm", "a4", "landscape",
+ MM_TO_POINTS(297), MM_TO_POINTS(210)},
+ {"iso_a5_148x210mm", "a5", "portrait",
+ MM_TO_POINTS(148), MM_TO_POINTS(210)},
+ {"iso_a5_148x210mm", "a5", "landscape",
+ MM_TO_POINTS(210), MM_TO_POINTS(148)},
+ {"iso_a6_105x148mm", "a6", "portrait",
+ MM_TO_POINTS(105), MM_TO_POINTS(148)},
+ {"iso_a6_105x148mm", "a6", "landscape",
+ MM_TO_POINTS(148), MM_TO_POINTS(105)},
+ {"iso_a7_74x105mm", "a7", "portrait",
+ MM_TO_POINTS(74), MM_TO_POINTS(105)},
+ {"iso_a7_74x105mm", "a7", "landscape",
+ MM_TO_POINTS(105), MM_TO_POINTS(74)},
+ {"iso_a8_52x74mm", "a8", "portrait",
+ MM_TO_POINTS(52), MM_TO_POINTS(74)},
+ {"iso_a8_52x74mm", "a8", "landscape",
+ MM_TO_POINTS(74), MM_TO_POINTS(52)},
+ {"iso_a9_37x52mm", "a9", "portrait",
+ MM_TO_POINTS(37), MM_TO_POINTS(52)},
+ {"iso_a9_37x52mm", "a9", "landscape",
+ MM_TO_POINTS(52), MM_TO_POINTS(37)},
+ {"iso_a10_26x37mm", "a10", "portrait",
+ MM_TO_POINTS(26), MM_TO_POINTS(37)},
+ {"iso_a10_26x37mm", "a10", "landscape",
+ MM_TO_POINTS(37), MM_TO_POINTS(26)}
+};
+
+static cairo_test_status_t
+preamble (cairo_test_context_t *ctx)
+{
+ cairo_surface_t *surface;
+ cairo_t *cr;
+ cairo_status_t status;
+ size_t i;
+ char dsc[255];
+ char *filename;
+ const char *path = cairo_test_mkdir (CAIRO_TEST_OUTPUT_DIR) ? CAIRO_TEST_OUTPUT_DIR : ".";
+
+ if (! (cairo_test_is_target_enabled (ctx, "ps2") ||
+ cairo_test_is_target_enabled (ctx, "ps3")))
+ {
+ return CAIRO_TEST_UNTESTED;
+ }
+
+ xasprintf (&filename, "%s/%s.ps", path, BASENAME);
+ /* We demonstrate that the initial size doesn't matter (we're
+ * passing 0,0), if we use cairo_ps_surface_set_size on the first
+ * page. */
+ surface = cairo_ps_surface_create (filename, 0, 0);
+
+ cairo_ps_surface_dsc_comment (surface, "%%Title: ps-features");
+ cairo_ps_surface_dsc_comment (surface, "%%Copyright: Copyright (C) 2006 Red Hat, Inc.");
+
+ cairo_ps_surface_dsc_begin_setup (surface);
+ cairo_ps_surface_dsc_comment (surface, "%%IncludeFeature: *PageSize letter");
+ cairo_ps_surface_dsc_comment (surface, "%%IncludeFeature: *MediaColor White");
+
+ cr = cairo_create (surface);
+
+ cairo_select_font_face (cr, CAIRO_TEST_FONT_FAMILY " Sans",
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_NORMAL);
+ cairo_set_font_size (cr, TEXT_SIZE);
+
+ for (i = 0; i < ARRAY_LENGTH (pages); i++) {
+ cairo_ps_surface_set_size (surface,
+ pages[i].width_in_points,
+ pages[i].height_in_points);
+ cairo_ps_surface_dsc_begin_page_setup (surface);
+ snprintf (dsc, 255, "%%IncludeFeature: *PageSize %s", pages[i].page_size_alias);
+ cairo_ps_surface_dsc_comment (surface, dsc);
+ if (i % 2) {
+ snprintf (dsc, 255, "%%IncludeFeature: *MediaType Glossy");
+ cairo_ps_surface_dsc_comment (surface, dsc);
+ }
+
+ cairo_move_to (cr, TEXT_SIZE, TEXT_SIZE);
+ cairo_show_text (cr, pages[i].page_size);
+ cairo_show_text (cr, " - ");
+ cairo_show_text (cr, pages[i].orientation);
+ cairo_show_page (cr);
+ }
+
+ status = cairo_status (cr);
+
+ cairo_destroy (cr);
+ cairo_surface_destroy (surface);
+
+ if (status) {
+ cairo_test_log (ctx, "Failed to create ps surface for file %s: %s\n",
+ filename, cairo_status_to_string (status));
+ free (filename);
+ return CAIRO_TEST_FAILURE;
+ }
+
+ printf ("ps-features: Please check %s to ensure it looks/prints correctly.\n", filename);
+ free (filename);
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (ps_features,
+ "Check PS specific API",
+ "ps, api", /* keywords */
+ NULL, /* requirements */
+ 0, 0,
+ preamble, NULL)
diff --git a/test/ps-surface-source.c b/test/ps-surface-source.c
new file mode 100644
index 000000000..16c677674
--- /dev/null
+++ b/test/ps-surface-source.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright © 2008 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Chris Wilson not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Chris Wilson makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+#include <cairo-ps.h>
+
+#include "surface-source.c"
+
+#define BASENAME "ps-surface-source.out"
+
+static cairo_surface_t *
+create_source_surface (int size)
+{
+ cairo_surface_t *surface;
+ char *filename;
+ const char *path = cairo_test_mkdir (CAIRO_TEST_OUTPUT_DIR) ? CAIRO_TEST_OUTPUT_DIR : ".";
+
+ xasprintf (&filename, "%s/%s.ps", path, BASENAME);
+ surface = cairo_ps_surface_create (filename, size, size);
+ cairo_surface_set_fallback_resolution (surface, 72., 72.);
+ free (filename);
+
+ return surface;
+}
+
+CAIRO_TEST (ps_surface_source,
+ "Test using a PS surface as the source",
+ "source", /* keywords */
+ NULL, /* requirements */
+ SIZE, SIZE,
+ preamble, draw)
diff --git a/test/ps2png.c b/test/ps2png.c
new file mode 100644
index 000000000..cf98aed3b
--- /dev/null
+++ b/test/ps2png.c
@@ -0,0 +1,113 @@
+/*
+ * Copyright © 2008 Carlos Garcia Campos
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Carlos Garcia Campos <carlosgc@gnome.org>
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <cairo.h>
+#include <libspectre/spectre.h>
+
+#define FAIL(msg) \
+ do { fprintf (stderr, "FAIL: %s\n", msg); exit (-1); } while (0)
+
+static const char *
+_spectre_render_page (const char *filename,
+ const char *page_label,
+ cairo_surface_t **surface_out)
+{
+ static const cairo_user_data_key_t key;
+
+ SpectreDocument *document;
+ SpectreStatus status;
+ int width, height, stride;
+ unsigned char *pixels;
+ cairo_surface_t *surface;
+
+ document = spectre_document_new ();
+ spectre_document_load (document, filename);
+ status = spectre_document_status (document);
+ if (status) {
+ spectre_document_free (document);
+ return spectre_status_to_string (status);
+ }
+
+ if (page_label) {
+ SpectrePage *page;
+ SpectreRenderContext *rc;
+
+ page = spectre_document_get_page_by_label (document, page_label);
+ spectre_document_free (document);
+ if (page == NULL)
+ return "page not found";
+
+ spectre_page_get_size (page, &width, &height);
+ rc = spectre_render_context_new ();
+ spectre_render_context_set_page_size (rc, width, height);
+ spectre_page_render (page, rc, &pixels, &stride);
+ spectre_render_context_free (rc);
+ status = spectre_page_status (page);
+ spectre_page_free (page);
+ if (status) {
+ free (pixels);
+ return spectre_status_to_string (status);
+ }
+ } else {
+ spectre_document_get_page_size (document, &width, &height);
+ spectre_document_render (document, &pixels, &stride);
+ spectre_document_free (document);
+ }
+
+ surface = cairo_image_surface_create_for_data (pixels,
+ CAIRO_FORMAT_RGB24,
+ width, height,
+ stride);
+ cairo_surface_set_user_data (surface, &key,
+ pixels, (cairo_destroy_func_t) free);
+ *surface_out = surface;
+ return NULL;
+}
+
+int main
+(int argc, char *argv[])
+{
+ const char *err;
+ cairo_surface_t *surface = NULL; /* silence compiler warning */
+ cairo_status_t status;
+
+ if (argc < 3 || argc > 4)
+ FAIL ("usage: ps2png input_file.ps output_file.png [page]");
+
+ err = _spectre_render_page (argv[1], argv[3], &surface);
+ if (err != NULL)
+ FAIL (err);
+
+ status = cairo_surface_write_to_png (surface, argv[2]);
+ cairo_surface_destroy (surface);
+
+ if (status != CAIRO_STATUS_SUCCESS)
+ FAIL (cairo_status_to_string (status));
+
+ return 0;
+}
diff --git a/test/pthread-same-source.c b/test/pthread-same-source.c
new file mode 100644
index 000000000..2b26d187d
--- /dev/null
+++ b/test/pthread-same-source.c
@@ -0,0 +1,192 @@
+/*
+ * Copyright 2009 Benjamin Otte
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Benjamin Otte <otte@gnome.org>
+ */
+
+#define GENERATE_REFERENCE 0
+
+#include "cairo-test.h"
+#if !GENERATE_REFERENCE
+#include <pthread.h>
+#endif
+
+#define N_THREADS 8
+
+#define WIDTH 64
+#define HEIGHT 8
+
+typedef struct {
+ cairo_surface_t *target;
+ cairo_surface_t *source;
+ int id;
+} thread_data_t;
+
+static void *
+draw_thread (void *arg)
+{
+ thread_data_t *thread_data = arg;
+ cairo_surface_t *surface;
+ cairo_pattern_t *pattern;
+ cairo_matrix_t pattern_matrix = { 2, 0, 0, 2, 0, 0 };
+ cairo_t *cr;
+ int x, y;
+
+ cr = cairo_create (thread_data->target);
+ cairo_surface_destroy (thread_data->target);
+
+ pattern = cairo_pattern_create_for_surface (thread_data->source);
+ cairo_surface_destroy (thread_data->source);
+ cairo_pattern_set_extend (pattern, thread_data->id % 4);
+ cairo_pattern_set_filter (pattern, thread_data->id >= 4 ? CAIRO_FILTER_BILINEAR : CAIRO_FILTER_NEAREST);
+ cairo_pattern_set_matrix (pattern, &pattern_matrix);
+
+ for (y = 0; y < HEIGHT; y++) {
+ for (x = 0; x < WIDTH; x++) {
+ cairo_save (cr);
+ cairo_translate (cr, 4 * x + 1, 4 * y + 1);
+ cairo_rectangle (cr, 0, 0, 2, 2);
+ cairo_set_source (cr, pattern);
+ cairo_fill (cr);
+ cairo_restore (cr);
+ }
+ }
+ cairo_pattern_destroy (pattern);
+
+ surface = cairo_surface_reference (cairo_get_target (cr));
+ cairo_destroy (cr);
+
+ return surface;
+}
+
+static cairo_surface_t *
+create_source (cairo_surface_t *similar)
+{
+ cairo_surface_t *source;
+ cairo_t *cr;
+ double colors[4][3] = {
+ { 0.75, 0, 0 },
+ { 0, 0.75, 0 },
+ { 0, 0, 0.75 },
+ { 0.75, 0.75, 0 }
+ };
+ int i;
+
+ source = cairo_surface_create_similar (similar,
+ CAIRO_CONTENT_COLOR_ALPHA,
+ 2, 2);
+
+ cr = cairo_create (source);
+ cairo_surface_destroy (source);
+
+ for (i = 0; i < 4; i++) {
+ cairo_set_source_rgb (cr, colors[i][0], colors[i][1], colors[i][2]);
+ cairo_rectangle (cr, i % 2, i / 2, 1, 1);
+ cairo_fill (cr);
+ }
+
+ source = cairo_surface_reference (cairo_get_target (cr));
+ cairo_destroy (cr);
+
+ return source;
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+#if !GENERATE_REFERENCE
+ pthread_t threads[N_THREADS];
+#endif
+ thread_data_t thread_data[N_THREADS];
+ cairo_test_status_t test_status = CAIRO_TEST_SUCCESS;
+ cairo_surface_t *source;
+ cairo_status_t status;
+ int i;
+
+ source = create_source (cairo_get_target (cr));
+ status = cairo_surface_status (source);
+ if (status) {
+ cairo_surface_destroy (source);
+ return cairo_test_status_from_status (cairo_test_get_context (cr),
+ status);
+ }
+
+ cairo_set_source_rgb (cr, 0.5, 0.5, 0.5);
+ cairo_paint (cr);
+
+ for (i = 0; i < N_THREADS; i++) {
+ thread_data[i].target = cairo_surface_create_similar (cairo_get_target (cr),
+ CAIRO_CONTENT_COLOR_ALPHA,
+ 4 * WIDTH, 4 * HEIGHT);
+ thread_data[i].source = cairo_surface_reference (source);
+ thread_data[i].id = i;
+#if !GENERATE_REFERENCE
+ if (pthread_create (&threads[i], NULL, draw_thread, &thread_data[i]) != 0) {
+ threads[i] = pthread_self (); /* to indicate error */
+ cairo_surface_destroy (thread_data[i].target);
+ cairo_surface_destroy (thread_data[i].source);
+ test_status = CAIRO_TEST_FAILURE;
+ break;
+ }
+#else
+ {
+ cairo_surface_t *surface = draw_thread(&thread_data[i]);
+ cairo_set_source_surface (cr, surface, 0, 0);
+ cairo_surface_destroy (surface);
+ cairo_paint (cr);
+
+ cairo_translate (cr, 0, 4 * HEIGHT);
+ }
+#endif
+ }
+
+ cairo_surface_destroy (source);
+
+#if !GENERATE_REFERENCE
+ for (i = 0; i < N_THREADS; i++) {
+ void *surface;
+
+ if (pthread_equal (threads[i], pthread_self ()))
+ break;
+
+ if (pthread_join (threads[i], &surface) == 0) {
+ cairo_set_source_surface (cr, surface, 0, 0);
+ cairo_surface_destroy (surface);
+ cairo_paint (cr);
+
+ cairo_translate (cr, 0, 4 * HEIGHT);
+ } else {
+ test_status = CAIRO_TEST_FAILURE;
+ }
+ }
+#endif
+
+ return test_status;
+}
+
+CAIRO_TEST (pthread_same_source,
+ "Use the same source for drawing in different threads",
+ "threads", /* keywords */
+ NULL, /* requirements */
+ 4 * WIDTH, 4 * HEIGHT * N_THREADS,
+ NULL, draw)
diff --git a/test/pthread-show-text.c b/test/pthread-show-text.c
new file mode 100644
index 000000000..0e070b7b7
--- /dev/null
+++ b/test/pthread-show-text.c
@@ -0,0 +1,142 @@
+/*
+ * Copyright © 2005 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+/* Test case for bug #4299:
+
+ Assertion fails in "cairo-font.c" when using multithreads
+ https://bugs.freedesktop.org/show_bug.cgi?id=4299
+*/
+
+#include "cairo-test.h"
+
+#include <string.h>
+#include <stdlib.h>
+#include <pthread.h>
+
+#define N_THREADS 8
+#define NUM_ITERATIONS 40
+
+#define WIDTH 400
+#define HEIGHT 42
+
+typedef struct {
+ cairo_surface_t *target;
+ int id;
+} thread_data_t;
+
+static void *
+draw_thread (void *arg)
+{
+ const char *text = "Hello world. ";
+ thread_data_t *thread_data = arg;
+ cairo_surface_t *surface;
+ cairo_font_extents_t extents;
+ cairo_t *cr;
+ int i;
+
+ cr = cairo_create (thread_data->target);
+ cairo_surface_destroy (thread_data->target);
+
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+ cairo_set_source_rgb (cr, 0, 0, 0);
+
+ cairo_select_font_face (cr, "serif",
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_NORMAL);
+ cairo_set_font_size (cr, NUM_ITERATIONS);
+ cairo_font_extents (cr, &extents);
+
+ cairo_move_to (cr, 1, HEIGHT - extents.descent - 1);
+
+ for (i = 0; i < NUM_ITERATIONS; i++) {
+ char buf[2];
+
+ cairo_select_font_face (cr, "serif",
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_NORMAL);
+ cairo_set_font_size (cr, i);
+
+ buf[0] = text[i%strlen(text)];
+ buf[1] = '\0';
+ cairo_show_text (cr, buf);
+ }
+
+ surface = cairo_surface_reference (cairo_get_target (cr));
+ cairo_destroy (cr);
+
+ return surface;
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ pthread_t threads[N_THREADS];
+ thread_data_t thread_data[N_THREADS];
+ cairo_test_status_t test_status = CAIRO_TEST_SUCCESS;
+ int i;
+
+ for (i = 0; i < N_THREADS; i++) {
+ thread_data[i].target = cairo_surface_create_similar (cairo_get_target (cr),
+ cairo_surface_get_content (cairo_get_target (cr)),
+ WIDTH, HEIGHT);
+ thread_data[i].id = i;
+ if (pthread_create (&threads[i], NULL, draw_thread, &thread_data[i]) != 0) {
+ threads[i] = pthread_self (); /* to indicate error */
+ cairo_surface_destroy (thread_data[i].target);
+ test_status = CAIRO_TEST_FAILURE;
+ break;
+ }
+ }
+
+ cairo_set_source_rgb (cr, 0.5, 0.5, 0.5);
+ cairo_paint (cr);
+
+ for (i = 0; i < N_THREADS; i++) {
+ void *surface;
+
+ if (pthread_equal (threads[i], pthread_self ()))
+ break;
+
+ if (pthread_join (threads[i], &surface) == 0) {
+ cairo_set_source_surface (cr, surface, 0, 0);
+ cairo_surface_destroy (surface);
+ cairo_paint (cr);
+
+ cairo_translate (cr, 0, HEIGHT);
+ } else {
+ test_status = CAIRO_TEST_FAILURE;
+ }
+ }
+
+ return test_status;
+}
+
+CAIRO_TEST (pthread_show_text,
+ "Concurrent stress test of the cairo_show_text().",
+ "thread, text", /* keywords */
+ NULL, /* requirements */
+ WIDTH, HEIGHT * N_THREADS,
+ NULL, draw)
diff --git a/test/pthread-similar.c b/test/pthread-similar.c
new file mode 100644
index 000000000..a5f5e3bf4
--- /dev/null
+++ b/test/pthread-similar.c
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2009 Benjamin Otte
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Benjamin Otte <otte@gnome.org>
+ */
+
+#include "cairo-test.h"
+#include <pthread.h>
+
+#define N_THREADS 8
+
+#define WIDTH 64
+#define HEIGHT 8
+
+static void *
+draw_thread (void *arg)
+{
+ cairo_surface_t *surface = arg;
+ cairo_t *cr;
+ int x, y;
+
+ cr = cairo_create (surface);
+ cairo_surface_destroy (surface);
+
+ for (y = 0; y < HEIGHT; y++) {
+ for (x = 0; x < WIDTH; x++) {
+ cairo_rectangle (cr, x, y, 1, 1);
+ cairo_set_source_rgba (cr, 0, 0.75, 0.75, (double) x / WIDTH);
+ cairo_fill (cr);
+ }
+ }
+
+ surface = cairo_surface_reference (cairo_get_target (cr));
+ cairo_destroy (cr);
+
+ return surface;
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ pthread_t threads[N_THREADS];
+ cairo_test_status_t test_status = CAIRO_TEST_SUCCESS;
+ int i;
+
+ for (i = 0; i < N_THREADS; i++) {
+ cairo_surface_t *surface;
+
+ surface = cairo_surface_create_similar (cairo_get_target (cr),
+ CAIRO_CONTENT_COLOR,
+ WIDTH, HEIGHT);
+ if (pthread_create (&threads[i], NULL, draw_thread, surface) != 0) {
+ threads[i] = pthread_self ();
+ test_status = cairo_test_status_from_status (cairo_test_get_context (cr),
+ cairo_surface_status (surface));
+ cairo_surface_destroy (surface);
+ break;
+ }
+ }
+
+ for (i = 0; i < N_THREADS; i++) {
+ void *surface;
+
+ if (pthread_equal (threads[i], pthread_self ()))
+ break;
+
+ if (pthread_join (threads[i], &surface) == 0) {
+ cairo_set_source_surface (cr, surface, 0, 0);
+ cairo_surface_destroy (surface);
+ cairo_paint (cr);
+
+ cairo_translate (cr, 0, HEIGHT);
+ } else {
+ test_status = CAIRO_TEST_FAILURE;
+ }
+ }
+
+ return test_status;
+}
+
+CAIRO_TEST (pthread_similar,
+ "Draw lots of 1x1 rectangles on similar surfaces in lots of threads",
+ "threads", /* keywords */
+ NULL, /* requirements */
+ WIDTH, HEIGHT * N_THREADS,
+ NULL, draw)
diff --git a/test/push-group-color.c b/test/push-group-color.c
new file mode 100644
index 000000000..1bc5bca9b
--- /dev/null
+++ b/test/push-group-color.c
@@ -0,0 +1,141 @@
+/*
+ * Copyright © 2005 Mozilla Corporation
+ * Copyright © 2009 Intel Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Mozilla Corporation not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Mozilla Corporation makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * MOZILLA CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL MOZILLA CORPORATION BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Vladimir Vukicevic <vladimir@pobox.com>
+ * Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+#define UNIT_SIZE 100
+#define PAD 5
+#define INNER_PAD 10
+
+#define WIDTH (UNIT_SIZE + PAD) + PAD
+#define HEIGHT (UNIT_SIZE + PAD) + PAD
+
+static cairo_pattern_t *
+argb32_source (void)
+{
+ cairo_surface_t *surface;
+ cairo_pattern_t *pattern;
+ cairo_t *cr;
+
+ surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 16, 16);
+ cr = cairo_create (surface);
+ cairo_surface_destroy (surface);
+
+ cairo_set_source_rgb (cr, 1, 0, 0);
+ cairo_rectangle (cr, 8, 0, 8, 8);
+ cairo_fill (cr);
+
+ cairo_set_source_rgb (cr, 0, 1, 0);
+ cairo_rectangle (cr, 0, 8, 8, 8);
+ cairo_fill (cr);
+
+ cairo_set_source_rgb (cr, 0, 0, 1);
+ cairo_rectangle (cr, 8, 8, 8, 8);
+ cairo_fill (cr);
+
+ pattern = cairo_pattern_create_for_surface (cairo_get_target (cr));
+ cairo_destroy (cr);
+
+ return pattern;
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_pattern_t *gradient, *image;
+
+ cairo_set_source_rgb (cr, 1,1,1);
+ cairo_paint (cr);
+
+ cairo_translate (cr, PAD, PAD);
+
+ /* clip to the unit size */
+ cairo_rectangle (cr, 0, 0,
+ UNIT_SIZE, UNIT_SIZE);
+ cairo_clip (cr);
+
+ cairo_rectangle (cr, 0, 0,
+ UNIT_SIZE, UNIT_SIZE);
+ cairo_set_source_rgba (cr, 0, 0, 0, 1);
+ cairo_set_line_width (cr, 2);
+ cairo_stroke (cr);
+
+ /* start a group */
+ cairo_push_group_with_content (cr, CAIRO_CONTENT_COLOR);
+
+ /* draw a gradient background */
+ cairo_save (cr);
+ cairo_translate (cr, INNER_PAD, INNER_PAD);
+ cairo_new_path (cr);
+ cairo_rectangle (cr, 0, 0,
+ UNIT_SIZE - (INNER_PAD*2), UNIT_SIZE - (INNER_PAD*2));
+ gradient = cairo_pattern_create_linear (UNIT_SIZE - (INNER_PAD*2), 0,
+ UNIT_SIZE - (INNER_PAD*2), UNIT_SIZE - (INNER_PAD*2));
+ cairo_pattern_add_color_stop_rgba (gradient, 0.0, 0.3, 0.3, 0.3, 1.0);
+ cairo_pattern_add_color_stop_rgba (gradient, 1.0, 1.0, 1.0, 1.0, 1.0);
+ cairo_set_source (cr, gradient);
+ cairo_pattern_destroy (gradient);
+ cairo_fill (cr);
+ cairo_restore (cr);
+
+ /* draw diamond */
+ cairo_move_to (cr, UNIT_SIZE / 2, 0);
+ cairo_line_to (cr, UNIT_SIZE , UNIT_SIZE / 2);
+ cairo_line_to (cr, UNIT_SIZE / 2, UNIT_SIZE);
+ cairo_line_to (cr, 0 , UNIT_SIZE / 2);
+ cairo_close_path (cr);
+ cairo_set_source_rgba (cr, 0, 0, 1, 1);
+ cairo_fill (cr);
+
+ /* draw circle */
+ cairo_arc (cr,
+ UNIT_SIZE / 2, UNIT_SIZE / 2,
+ UNIT_SIZE / 3.5,
+ 0, M_PI * 2);
+ cairo_set_source_rgba (cr, 1, 0, 0, 1);
+ cairo_fill (cr);
+
+ /* and put the image on top */
+ cairo_translate (cr, UNIT_SIZE/2 - 8, UNIT_SIZE/2 - 8);
+ image = argb32_source ();
+ cairo_set_source (cr, image);
+ cairo_pattern_destroy (image);
+ cairo_paint (cr);
+
+ cairo_pop_group_to_source (cr);
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_paint (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (push_group_color,
+ "Verify that cairo_push_group_with_content works.",
+ "group", /* keywords */
+ NULL, /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw)
diff --git a/test/push-group-path-offset.c b/test/push-group-path-offset.c
new file mode 100644
index 000000000..6b73ca4fa
--- /dev/null
+++ b/test/push-group-path-offset.c
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2010 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Benjamin Otte <otte@gnome.org>
+ */
+
+#include "cairo-test.h"
+
+#define CLIP_OFFSET 15
+#define CLIP_SIZE 20
+
+#define WIDTH 50
+#define HEIGHT 50
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ /* Neutral gray background */
+ cairo_set_source_rgb (cr, 0.51613, 0.55555, 0.51613);
+ cairo_paint (cr);
+
+ /* the rest uses CAIRO_OPERATOR_SOURCE so we see better when something goes wrong */
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+
+ /* add a rectangle */
+ cairo_rectangle (cr, CLIP_OFFSET, CLIP_OFFSET, CLIP_SIZE, CLIP_SIZE);
+
+ /* clip to the rectangle */
+ cairo_clip_preserve (cr);
+
+ /* push a group. We now have a device offset. */
+ cairo_push_group (cr);
+
+ /* push a group again. This is where the bug used to happen. */
+ cairo_push_group (cr);
+
+ /* draw something */
+ cairo_set_source_rgb (cr, 1, 0, 0);
+ cairo_fill_preserve (cr);
+
+ /* make sure the stuff we drew ends up on the output */
+ cairo_pop_group_to_source (cr);
+ cairo_fill_preserve (cr);
+
+ cairo_pop_group_to_source (cr);
+ cairo_fill_preserve (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (push_group_path_offset,
+ "Exercises a bug in Cairo 1.9 where existing paths applied the target's"
+ " device offset twice when cairo_push_group() was called.",
+ "group, path", /* keywords */
+ NULL, /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw)
diff --git a/test/push-group.c b/test/push-group.c
new file mode 100644
index 000000000..8e6ce1924
--- /dev/null
+++ b/test/push-group.c
@@ -0,0 +1,113 @@
+/*
+ * Copyright © 2005 Mozilla Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Mozilla Corporation not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Mozilla Corporation makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * MOZILLA CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL MOZILLA CORPORATION BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Vladimir Vukicevic <vladimir@pobox.com>
+ */
+
+#include "cairo-test.h"
+
+#define UNIT_SIZE 100
+#define PAD 5
+#define INNER_PAD 10
+
+#define WIDTH (UNIT_SIZE + PAD) + PAD
+#define HEIGHT (UNIT_SIZE + PAD) + PAD
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_pattern_t *gradient;
+ int i, j;
+
+ gradient = cairo_pattern_create_linear (UNIT_SIZE - (INNER_PAD*2), 0,
+ UNIT_SIZE - (INNER_PAD*2), UNIT_SIZE - (INNER_PAD*2));
+ cairo_pattern_add_color_stop_rgba (gradient, 0.0, 0.3, 0.3, 0.3, 1.0);
+ cairo_pattern_add_color_stop_rgba (gradient, 1.0, 1.0, 1.0, 1.0, 1.0);
+
+ for (j = 0; j < 1; j++) {
+ for (i = 0; i < 1; i++) {
+ double x = (i * UNIT_SIZE) + (i + 1) * PAD;
+ double y = (j * UNIT_SIZE) + (j + 1) * PAD;
+
+ cairo_save (cr);
+
+ cairo_translate (cr, x, y);
+
+ /* draw a gradient background */
+ cairo_save (cr);
+ cairo_translate (cr, INNER_PAD, INNER_PAD);
+ cairo_new_path (cr);
+ cairo_rectangle (cr, 0, 0,
+ UNIT_SIZE - (INNER_PAD*2), UNIT_SIZE - (INNER_PAD*2));
+ cairo_set_source (cr, gradient);
+ cairo_fill (cr);
+ cairo_restore (cr);
+
+ /* clip to the unit size */
+ cairo_rectangle (cr, 0, 0,
+ UNIT_SIZE, UNIT_SIZE);
+ cairo_clip (cr);
+
+ cairo_rectangle (cr, 0, 0,
+ UNIT_SIZE, UNIT_SIZE);
+ cairo_set_source_rgba (cr, 0, 0, 0, 1);
+ cairo_set_line_width (cr, 2);
+ cairo_stroke (cr);
+
+ /* start a group */
+ cairo_push_group (cr);
+
+ /* draw diamond */
+ cairo_move_to (cr, UNIT_SIZE / 2, 0);
+ cairo_line_to (cr, UNIT_SIZE , UNIT_SIZE / 2);
+ cairo_line_to (cr, UNIT_SIZE / 2, UNIT_SIZE);
+ cairo_line_to (cr, 0 , UNIT_SIZE / 2);
+ cairo_close_path (cr);
+ cairo_set_source_rgba (cr, 0, 0, 1, 1);
+ cairo_fill (cr);
+
+ /* draw circle */
+ cairo_arc (cr,
+ UNIT_SIZE / 2, UNIT_SIZE / 2,
+ UNIT_SIZE / 3.5,
+ 0, M_PI * 2);
+ cairo_set_source_rgba (cr, 1, 0, 0, 1);
+ cairo_fill (cr);
+
+ cairo_pop_group_to_source (cr);
+ cairo_paint_with_alpha (cr, 0.5);
+
+ cairo_restore (cr);
+ }
+ }
+
+ cairo_pattern_destroy (gradient);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (push_group,
+ "Verify that cairo_push_group works.",
+ "group", /* keywords */
+ NULL, /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw)
diff --git a/test/quad-color.png b/test/quad-color.png
new file mode 100644
index 000000000..0d68a82cc
--- /dev/null
+++ b/test/quad-color.png
Binary files differ
diff --git a/test/quartz-surface-source.c b/test/quartz-surface-source.c
new file mode 100644
index 000000000..b0c86d0f9
--- /dev/null
+++ b/test/quartz-surface-source.c
@@ -0,0 +1,42 @@
+/*
+ * Copyright © 2008 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Chris Wilson not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Chris Wilson makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+#include "cairo-quartz.h"
+
+#include "surface-source.c"
+
+static cairo_surface_t *
+create_source_surface (int size)
+{
+ return cairo_quartz_surface_create (CAIRO_FORMAT_ARGB32, size, size);
+}
+
+CAIRO_TEST (quartz_surface_source,
+ "Test using a Quartz surface as the source",
+ "source", /* keywords */
+ NULL, /* requirements */
+ SIZE, SIZE,
+ preamble, draw)
diff --git a/test/radial-gradient-extend.c b/test/radial-gradient-extend.c
new file mode 100644
index 000000000..c32a2c37b
--- /dev/null
+++ b/test/radial-gradient-extend.c
@@ -0,0 +1,92 @@
+/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */
+/*
+ * Copyright 2010 Andrea Canciani
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Andrea Canciani <ranma42@gmail.com>
+ */
+
+#include "cairo-test.h"
+
+#define NUM_EXTEND 4
+#define HEIGHT 16
+#define WIDTH 16
+#define PAD 3
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_pattern_t *pattern;
+ unsigned int i, j;
+
+ cairo_extend_t extend[NUM_EXTEND] = {
+ CAIRO_EXTEND_NONE,
+ CAIRO_EXTEND_REPEAT,
+ CAIRO_EXTEND_REFLECT,
+ CAIRO_EXTEND_PAD
+ };
+
+ cairo_test_paint_checkered (cr);
+
+ pattern = cairo_pattern_create_radial (WIDTH / 2, HEIGHT / 2, 0, WIDTH / 2, HEIGHT / 2, 2 * PAD);
+
+ cairo_pattern_add_color_stop_rgb (pattern, 0, 0, 0, 1);
+ cairo_pattern_add_color_stop_rgb (pattern, 1, 0, 0, 1);
+
+ cairo_translate (cr, PAD, PAD);
+
+ for (i = 0; i < 2; i++) {
+ cairo_save (cr);
+
+ for (j = 0; j < NUM_EXTEND; j++) {
+ cairo_pattern_set_extend (pattern, extend[j]);
+
+ cairo_reset_clip (cr);
+ cairo_rectangle (cr, 0, 0, WIDTH, HEIGHT);
+ cairo_clip (cr);
+
+ if (i & 1) {
+ cairo_set_source_rgb (cr, 0, 1, 0);
+ cairo_mask (cr, pattern);
+ } else {
+ cairo_set_source (cr, pattern);
+ cairo_paint (cr);
+ }
+
+ cairo_translate (cr, WIDTH+PAD, 0);
+ }
+
+ cairo_restore (cr);
+ cairo_translate (cr, 0, HEIGHT+PAD);
+ }
+
+ cairo_pattern_destroy (pattern);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (radial_gradient_extend,
+ "Tests gradient to solid reduction of radial gradients",
+ "radial, pattern, extend", /* keywords */
+ NULL, /* requirements */
+ (WIDTH+PAD) * NUM_EXTEND + PAD, 2*(HEIGHT + PAD) + PAD,
+ NULL, draw)
diff --git a/test/radial-gradient.c b/test/radial-gradient.c
new file mode 100644
index 000000000..026876b1b
--- /dev/null
+++ b/test/radial-gradient.c
@@ -0,0 +1,256 @@
+/*
+ * Copyright © 2005, 2007 Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+#include "cairo-test.h"
+
+#define NUM_GRADIENTS 7
+#define NUM_EXTEND 4
+#define SIZE 120
+#define WIDTH (SIZE * NUM_GRADIENTS)
+#define HEIGHT (SIZE * NUM_EXTEND)
+
+typedef void (*composite_t)(cairo_t *cr, cairo_pattern_t *pattern);
+typedef void (*add_stops_t)(cairo_pattern_t *pattern);
+
+/*
+ * We want to test all the possible relative positions of the start
+ * and end circle:
+ *
+ * - The start circle can be smaller/equal/bigger than the end
+ * circle. A radial gradient can be classified in one of these
+ * three cases depending on the sign of dr.
+ *
+ * - The smaller circle can be completely inside/internally
+ * tangent/outside (at least in part) of the bigger circle. This
+ * classification is the same as the one which can be computed by
+ * examining the sign of a = (dx^2 + dy^2 - dr^2).
+ *
+ * - If the two circles have the same size, neither can be inside or
+ * internally tangent
+ *
+ * This test draws radial gradients whose circles always have the same
+ * centers (0, 0) and (1, 0), but with different radiuses. From left
+ * to right:
+ *
+ * - Small start circle completely inside the end circle
+ * 0.25 -> 1.75; dr = 1.5 > 0; a = 1 - 1.50^2 < 0
+ *
+ * - Small start circle internally tangent to the end circle
+ * 0.50 -> 1.50; dr = 1.0 > 0; a = 1 - 1.00^2 = 0
+ *
+ * - Small start circle outside of the end circle
+ * 0.50 -> 1.00; dr = 0.5 > 0; a = 1 - 0.50^2 > 0
+ *
+ * - Start circle with the same size as the end circle
+ * 1.00 -> 1.00; dr = 0.0 = 0; a = 1 - 0.00^2 > 0
+ *
+ * - Small end circle outside of the start circle
+ * 1.00 -> 0.50; dr = -0.5 > 0; a = 1 - 0.50^2 > 0
+ *
+ * - Small end circle internally tangent to the start circle
+ * 1.50 -> 0.50; dr = -1.0 > 0; a = 1 - 1.00^2 = 0
+ *
+ * - Small end circle completely inside the start circle
+ * 1.75 -> 0.25; dr = -1.5 > 0; a = 1 - 1.50^2 < 0
+ *
+ */
+
+static const double radiuses[NUM_GRADIENTS] = {
+ 0.25,
+ 0.50,
+ 0.50,
+ 1.00,
+ 1.00,
+ 1.50,
+ 1.75
+};
+
+static cairo_pattern_t *
+create_pattern (int index)
+{
+ double x0, x1, radius0, radius1, left, right, center;
+
+ x0 = 0;
+ x1 = 1;
+ radius0 = radiuses[index];
+ radius1 = radiuses[NUM_GRADIENTS - index - 1];
+
+ /* center the gradient */
+ left = MIN (x0 - radius0, x1 - radius1);
+ right = MAX (x0 + radius0, x1 + radius1);
+ center = (left + right) * 0.5;
+ x0 -= center;
+ x1 -= center;
+
+ /* scale to make it fit within a 1x1 rect centered in (0,0) */
+ x0 *= 0.25;
+ x1 *= 0.25;
+ radius0 *= 0.25;
+ radius1 *= 0.25;
+
+ return cairo_pattern_create_radial (x0, 0, radius0, x1, 0, radius1);
+}
+
+static void
+pattern_add_stops (cairo_pattern_t *pattern)
+{
+ cairo_pattern_add_color_stop_rgba (pattern, 0.0, 1, 0, 0, 0.75);
+ cairo_pattern_add_color_stop_rgba (pattern, sqrt (0.5), 0, 1, 0, 0);
+ cairo_pattern_add_color_stop_rgba (pattern, 1.0, 0, 0, 1, 1);
+}
+
+static void
+pattern_add_single_stop (cairo_pattern_t *pattern)
+{
+ cairo_pattern_add_color_stop_rgba (pattern, 0.25, 1, 0, 0, 1);
+}
+
+
+static cairo_test_status_t
+draw (cairo_t *cr, add_stops_t add_stops, composite_t composite)
+{
+ int i, j;
+ cairo_extend_t extend[NUM_EXTEND] = {
+ CAIRO_EXTEND_NONE,
+ CAIRO_EXTEND_REPEAT,
+ CAIRO_EXTEND_REFLECT,
+ CAIRO_EXTEND_PAD
+ };
+
+ cairo_scale (cr, SIZE, SIZE);
+ cairo_translate (cr, 0.5, 0.5);
+
+ for (j = 0; j < NUM_EXTEND; j++) {
+ cairo_save (cr);
+ for (i = 0; i < NUM_GRADIENTS; i++) {
+ cairo_pattern_t *pattern;
+
+ pattern = create_pattern (i);
+ add_stops (pattern);
+ cairo_pattern_set_extend (pattern, extend[j]);
+
+ cairo_save (cr);
+ cairo_rectangle (cr, -0.5, -0.5, 1, 1);
+ cairo_clip (cr);
+ composite (cr, pattern);
+ cairo_restore (cr);
+ cairo_pattern_destroy (pattern);
+
+ cairo_translate (cr, 1, 0);
+ }
+ cairo_restore (cr);
+ cairo_translate (cr, 0, 1);
+ }
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+
+static void
+composite_simple (cairo_t *cr, cairo_pattern_t *pattern)
+{
+ cairo_set_source (cr, pattern);
+ cairo_paint (cr);
+}
+
+static void
+composite_mask (cairo_t *cr, cairo_pattern_t *pattern)
+{
+ cairo_set_source_rgb (cr, 1, 0, 1);
+ cairo_mask (cr, pattern);
+}
+
+
+static cairo_test_status_t
+draw_simple (cairo_t *cr, int width, int height)
+{
+ cairo_test_paint_checkered (cr);
+ return draw (cr, pattern_add_stops, composite_simple);
+}
+
+static cairo_test_status_t
+draw_mask (cairo_t *cr, int width, int height)
+{
+ cairo_test_paint_checkered (cr);
+ return draw (cr, pattern_add_stops, composite_mask);
+}
+
+static cairo_test_status_t
+draw_source (cairo_t *cr, int width, int height)
+{
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ return draw (cr, pattern_add_stops, composite_simple);
+}
+
+
+static cairo_test_status_t
+draw_mask_source (cairo_t *cr, int width, int height)
+{
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ return draw (cr, pattern_add_stops, composite_mask);
+}
+
+static cairo_test_status_t
+draw_one_stop (cairo_t *cr, int width, int height)
+{
+ cairo_test_paint_checkered (cr);
+ return draw (cr, pattern_add_single_stop, composite_simple);
+}
+
+CAIRO_TEST (radial_gradient,
+ "Simple test of radial gradients",
+ "gradient", /* keywords */
+ NULL, /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw_simple)
+
+CAIRO_TEST (radial_gradient_mask,
+ "Simple test of radial gradients using a MASK",
+ "gradient,mask", /* keywords */
+ NULL, /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw_mask)
+
+CAIRO_TEST (radial_gradient_source,
+ "Simple test of radial gradients using the SOURCE operator",
+ "gradient,source", /* keywords */
+ NULL, /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw_source)
+
+CAIRO_TEST (radial_gradient_mask_source,
+ "Simple test of radial gradients using a MASK with a SOURCE operator",
+ "gradient,mask,source", /* keywords */
+ NULL, /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw_mask_source)
+
+CAIRO_TEST (radial_gradient_one_stop,
+ "Tests radial gradients with a single stop",
+ "gradient,radial", /* keywords */
+ NULL, /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw_one_stop)
diff --git a/test/radial-outer-focus.c b/test/radial-outer-focus.c
new file mode 100644
index 000000000..e03894745
--- /dev/null
+++ b/test/radial-outer-focus.c
@@ -0,0 +1,72 @@
+/*
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Krzysztof Kosi\u0144ski <tweenk.pl@gmail.com>
+ */
+
+/* Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=40918 */
+
+#include "cairo-test.h"
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_pattern_t *radial;
+ double angle;
+ int i, j;
+
+ cairo_set_source_rgb (cr, 0, 0, 1);
+ cairo_paint (cr);
+
+ angle = 0.0;
+
+ for (i = 0; i < 4; i++) {
+ for (j = 0; j < 4; j++) {
+ cairo_save (cr);
+ cairo_rectangle (cr, 100*i, 100*j, 100, 100);
+ cairo_clip (cr);
+
+ radial = cairo_pattern_create_radial (cos (angle), sin (angle), 0,
+ 0, 0, 1);
+ cairo_pattern_add_color_stop_rgb (radial, 0.0, 1, 0, 0);
+ cairo_pattern_add_color_stop_rgb (radial, 1.0, 0, 1, 0);
+
+ cairo_translate (cr, 100*i+50, 100*j+50);
+ cairo_scale (cr, 50, -50);
+ cairo_set_source (cr, radial);
+ cairo_pattern_destroy (radial);
+
+ cairo_paint(cr);
+ cairo_restore (cr);
+
+ angle += M_PI/17;
+ }
+ }
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (radial_outer_focus,
+ "Exercises the condition of rendering a radial gradial on its outer focus",
+ "radial", /* keywords */
+ NULL, /* requirements */
+ 400, 400,
+ NULL, draw)
diff --git a/test/random-clips.c b/test/random-clips.c
new file mode 100644
index 000000000..31d7d6df0
--- /dev/null
+++ b/test/random-clips.c
@@ -0,0 +1,232 @@
+/*
+ * Copyright © 2006 M Joonas Pihlaja
+ * Copyright © 2011 Chris Wilson
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ * M Joonas Pihlaja <jpihlaja@cc.helsinki.fi>
+ * Chris Wilson <chris@chris-wilson.co.uk>
+ */
+#include "cairo-test.h"
+
+#define SIZE 512
+#define STEP (512+2)
+#define NUM_SEGMENTS 128
+
+static uint32_t state;
+
+static double
+uniform_random (double minval, double maxval)
+{
+ static uint32_t const poly = 0x9a795537U;
+ uint32_t n = 32;
+ while (n-->0)
+ state = 2*state < state ? (2*state ^ poly) : 2*state;
+ return minval + state * (maxval - minval) / 4294967296.0;
+}
+
+static void nz_path (cairo_t *cr)
+{
+ int i;
+
+ state = 0xc0ffee;
+
+ cairo_move_to (cr, 0, 0);
+ for (i = 0; i < NUM_SEGMENTS; i++) {
+ double x = uniform_random (0, SIZE);
+ double y = uniform_random (0, SIZE);
+ cairo_line_to (cr, x, y);
+ }
+ cairo_close_path (cr);
+}
+
+static void region_path (cairo_t *cr)
+{
+ int i;
+
+ state = 0xc0ffee;
+
+ for (i = 0; i < NUM_SEGMENTS; i++) {
+ int x = uniform_random (0, SIZE);
+ int y = uniform_random (0, SIZE);
+ int w = uniform_random (0, 40);
+ int h = uniform_random (0, 40);
+ cairo_rectangle (cr, x, y, w, h);
+ }
+}
+
+static void rectangle_path (cairo_t *cr)
+{
+ int i;
+
+ state = 0xc0ffee;
+
+ for (i = 0; i < NUM_SEGMENTS; i++) {
+ double x = uniform_random (0, SIZE);
+ double y = uniform_random (0, SIZE);
+ double w = uniform_random (0, 40);
+ double h = uniform_random (0, 40);
+ cairo_rectangle (cr, x, y, w, h);
+ }
+}
+
+static void arc_path (cairo_t *cr)
+{
+ int i;
+
+ state = 0xc0ffee;
+
+ for (i = 0; i < NUM_SEGMENTS; i++) {
+ double x = uniform_random (0, SIZE);
+ double y = uniform_random (0, SIZE);
+ double r = uniform_random (0, 20);
+ cairo_new_sub_path (cr);
+ cairo_arc (cr, x, y, r, 0, 2*M_PI);
+ }
+}
+
+
+static void nz_fill_stroke (cairo_t *cr)
+{
+ nz_path (cr);
+
+ cairo_set_source_rgb (cr, 1, 0, 0);
+ cairo_fill_preserve (cr);
+ cairo_set_source_rgb (cr, 0, 1, 0);
+ cairo_set_line_width (cr, 1.0);
+ cairo_stroke (cr);
+}
+
+static void clip_to_quadrant (cairo_t *cr)
+{
+ cairo_rectangle (cr, 0, 0, SIZE, SIZE);
+ cairo_clip (cr);
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ cairo_paint (cr);
+
+ cairo_set_fill_rule (cr, CAIRO_FILL_RULE_WINDING);
+
+ state = 0xc0ffee;
+ cairo_translate (cr, 1, 1);
+
+ /* no clipping */
+ cairo_save (cr); {
+ clip_to_quadrant (cr);
+
+ nz_fill_stroke (cr);
+ } cairo_restore (cr);
+
+ cairo_translate (cr, STEP, 0);
+
+ /* random clipping */
+ cairo_save (cr); {
+ clip_to_quadrant (cr);
+
+ nz_path (cr);
+ cairo_clip (cr);
+
+ nz_fill_stroke (cr);
+
+ cairo_set_source_rgba (cr, 1, 1, 1, 0.5);
+ cairo_paint (cr);
+ } cairo_restore (cr);
+
+ cairo_translate (cr, STEP, 0);
+
+ /* regional clipping */
+ cairo_save (cr); {
+ clip_to_quadrant (cr);
+
+ region_path (cr);
+ cairo_clip (cr);
+
+ nz_fill_stroke (cr);
+
+ cairo_set_source_rgba (cr, 1, 1, 1, 0.5);
+ cairo_paint (cr);
+ } cairo_restore (cr);
+
+ cairo_translate (cr, -2*STEP, STEP);
+
+ /* rectangular clipping */
+ cairo_save (cr); {
+ clip_to_quadrant (cr);
+
+ rectangle_path (cr);
+ cairo_clip (cr);
+
+ nz_fill_stroke (cr);
+
+ cairo_set_source_rgba (cr, 1, 1, 1, 0.5);
+ cairo_paint (cr);
+ } cairo_restore (cr);
+
+ cairo_translate (cr, STEP, 0);
+
+ /* circular clipping */
+ cairo_save (cr); {
+ clip_to_quadrant (cr);
+
+ arc_path (cr);
+ cairo_clip (cr);
+
+ nz_fill_stroke (cr);
+
+ cairo_set_source_rgba (cr, 1, 1, 1, 0.5);
+ cairo_paint (cr);
+ } cairo_restore (cr);
+
+ cairo_translate (cr, STEP, 0);
+
+ /* all-of-the-above clipping */
+ cairo_save (cr); {
+ clip_to_quadrant (cr);
+
+ nz_path (cr);
+ cairo_clip (cr);
+ region_path (cr);
+ cairo_clip (cr);
+ rectangle_path (cr);
+ cairo_clip (cr);
+ arc_path (cr);
+ cairo_clip (cr);
+
+ nz_fill_stroke (cr);
+
+ cairo_set_source_rgba (cr, 1, 1, 1, 0.5);
+ cairo_paint (cr);
+ } cairo_restore (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (random_clip,
+ "Tests the clip generation and intersection computation",
+ "trap, clip", /* keywords */
+ NULL, /* requirements */
+ 3*STEP+2, 2*STEP+2,
+ NULL, draw)
diff --git a/test/random-intersections-curves-eo.c b/test/random-intersections-curves-eo.c
new file mode 100644
index 000000000..84e9a75de
--- /dev/null
+++ b/test/random-intersections-curves-eo.c
@@ -0,0 +1,84 @@
+/*
+ * Copyright © 2006 M Joonas Pihlaja
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: M Joonas Pihlaja <jpihlaja@cc.helsinki.fi>
+ */
+#include "cairo-test.h"
+
+#define SIZE 512
+#define NUM_SEGMENTS 128
+
+static uint32_t state;
+
+static double
+uniform_random (double minval, double maxval)
+{
+ static uint32_t const poly = 0x9a795537U;
+ uint32_t n = 32;
+ while (n-->0)
+ state = 2*state < state ? (2*state ^ poly) : 2*state;
+ return minval + state * (maxval - minval) / 4294967296.0;
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ int i;
+
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ cairo_paint (cr);
+
+ state = 0x12345678;
+ cairo_translate (cr, 1, 1);
+ cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
+
+ cairo_move_to (cr, 0, 0);
+ for (i = 0; i < NUM_SEGMENTS; i++) {
+ double y3 = uniform_random (0, SIZE);
+ double x3 = uniform_random (0, SIZE);
+ double y2 = uniform_random (-SIZE, SIZE);
+ double x2 = uniform_random (-SIZE, SIZE);
+ double y1 = uniform_random (-SIZE, SIZE);
+ double x1 = uniform_random (-SIZE, SIZE);
+ cairo_curve_to (cr,
+ x1, y1,
+ x2, y2,
+ x3, y3);
+ }
+ cairo_close_path (cr);
+
+ cairo_set_source_rgb (cr, 1, 0, 0);
+ cairo_fill_preserve (cr);
+ cairo_set_source_rgb (cr, 0, 1, 0);
+ cairo_set_line_width (cr, 0.5);
+ cairo_stroke (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (random_intersections_curves_eo,
+ "Tests the tessellator trapezoid generation and intersection computation",
+ "trap", /* keywords */
+ NULL, /* requirements */
+ SIZE+3, SIZE+3,
+ NULL, draw)
diff --git a/test/random-intersections-curves-nz.c b/test/random-intersections-curves-nz.c
new file mode 100644
index 000000000..5265e4a73
--- /dev/null
+++ b/test/random-intersections-curves-nz.c
@@ -0,0 +1,85 @@
+/*
+ * Copyright © 2006 M Joonas Pihlaja
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: M Joonas Pihlaja <jpihlaja@cc.helsinki.fi>
+ */
+#include "cairo-test.h"
+
+#define SIZE 512
+#define NUM_SEGMENTS 128
+
+static uint32_t state;
+
+static double
+uniform_random (double minval, double maxval)
+{
+ static uint32_t const poly = 0x9a795537U;
+ uint32_t n = 32;
+ while (n-->0)
+ state = 2*state < state ? (2*state ^ poly) : 2*state;
+ return minval + state * (maxval - minval) / 4294967296.0;
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ int i;
+
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ cairo_paint (cr);
+
+ state = 0x12345678;
+ cairo_translate (cr, 1, 1);
+ cairo_set_fill_rule (cr, CAIRO_FILL_RULE_WINDING);
+
+ cairo_move_to (cr, 0, 0);
+ for (i = 0; i < NUM_SEGMENTS; i++) {
+ double y3 = uniform_random (0, SIZE);
+ double x3 = uniform_random (0, SIZE);
+ double y2 = uniform_random (-SIZE, SIZE);
+ double x2 = uniform_random (-SIZE, SIZE);
+ double y1 = uniform_random (-SIZE, SIZE);
+ double x1 = uniform_random (-SIZE, SIZE);
+ cairo_curve_to (cr,
+ x1, y1,
+ x2, y2,
+ x3, y3);
+ }
+ cairo_close_path (cr);
+
+ cairo_set_source_rgb (cr, 1, 0, 0);
+ cairo_fill_preserve (cr);
+ cairo_set_source_rgb (cr, 0, 1, 0);
+ cairo_set_line_width (cr, 0.5);
+ cairo_stroke (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (random_intersections_curves_nz,
+ "Tests the tessellator trapezoid generation and intersection computation",
+ "trap", /* keywords */
+ NULL, /* requirements */
+ SIZE+3, SIZE+3,
+ NULL, draw)
+
diff --git a/test/random-intersections-eo.c b/test/random-intersections-eo.c
new file mode 100644
index 000000000..d35894f33
--- /dev/null
+++ b/test/random-intersections-eo.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright © 2006 M Joonas Pihlaja
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: M Joonas Pihlaja <jpihlaja@cc.helsinki.fi>
+ */
+#include "cairo-test.h"
+
+#define SIZE 512
+#define NUM_SEGMENTS 128
+
+static uint32_t state;
+
+static double
+uniform_random (double minval, double maxval)
+{
+ static uint32_t const poly = 0x9a795537U;
+ uint32_t n = 32;
+ while (n-->0)
+ state = 2*state < state ? (2*state ^ poly) : 2*state;
+ return minval + state * (maxval - minval) / 4294967296.0;
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ int i;
+
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ cairo_paint (cr);
+
+ state = 0x12345678;
+ cairo_translate (cr, 1, 1);
+ cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
+
+ cairo_move_to (cr, 0, 0);
+ for (i = 0; i < NUM_SEGMENTS; i++) {
+ double x = uniform_random (0, width);
+ double y = uniform_random (0, height);
+ cairo_line_to (cr, x, y);
+ }
+ cairo_close_path (cr);
+
+ cairo_set_source_rgb (cr, 1, 0, 0);
+ cairo_fill_preserve (cr);
+ cairo_set_source_rgb (cr, 0, 1, 0);
+ cairo_set_line_width (cr, 0.5);
+ cairo_stroke (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (random_intersections_eo,
+ "Tests the tessellator trapezoid generation and intersection computation",
+ "trap", /* keywords */
+ NULL, /* requirements */
+ SIZE+3, SIZE+3,
+ NULL, draw)
+
diff --git a/test/random-intersections-nonzero.c b/test/random-intersections-nonzero.c
new file mode 100644
index 000000000..cad047e04
--- /dev/null
+++ b/test/random-intersections-nonzero.c
@@ -0,0 +1,79 @@
+/*
+ * Copyright © 2006 M Joonas Pihlaja
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: M Joonas Pihlaja <jpihlaja@cc.helsinki.fi>
+ */
+#include "cairo-test.h"
+
+#define SIZE 512
+#define NUM_SEGMENTS 128
+
+static uint32_t state;
+
+static double
+uniform_random (double minval, double maxval)
+{
+ static uint32_t const poly = 0x9a795537U;
+ uint32_t n = 32;
+ while (n-->0)
+ state = 2*state < state ? (2*state ^ poly) : 2*state;
+ return minval + state * (maxval - minval) / 4294967296.0;
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ int i;
+
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ cairo_paint (cr);
+
+ state = 0x12345678;
+ cairo_translate (cr, 1, 1);
+ cairo_set_fill_rule (cr, CAIRO_FILL_RULE_WINDING);
+
+ cairo_move_to (cr, 0, 0);
+ for (i = 0; i < NUM_SEGMENTS; i++) {
+ double x = uniform_random (0, width);
+ double y = uniform_random (0, height);
+ cairo_line_to (cr, x, y);
+ }
+ cairo_close_path (cr);
+
+ cairo_set_source_rgb (cr, 1, 0, 0);
+ cairo_fill_preserve (cr);
+ cairo_set_source_rgb (cr, 0, 1, 0);
+ cairo_set_line_width (cr, 0.5);
+ cairo_stroke (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (random_intersections_nonzero,
+ "Tests the tessellator trapezoid generation and intersection computation",
+ "trap", /* keywords */
+ NULL, /* requirements */
+ SIZE+3, SIZE+3,
+ NULL, draw)
+
+
diff --git a/test/raster-source.c b/test/raster-source.c
new file mode 100644
index 000000000..5a7646e8a
--- /dev/null
+++ b/test/raster-source.c
@@ -0,0 +1,134 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+#include <stdio.h>
+#include <errno.h>
+
+/* Basic test to exercise the new mime-surface callback. */
+
+#define WIDTH 200
+#define HEIGHT 80
+
+/* Lazy way of determining PNG dimensions... */
+static void
+png_dimensions (const char *filename,
+ cairo_content_t *content, int *width, int *height)
+{
+ cairo_surface_t *surface;
+
+ surface = cairo_image_surface_create_from_png (filename);
+ *content = cairo_surface_get_content (surface);
+ *width = cairo_image_surface_get_width (surface);
+ *height = cairo_image_surface_get_height (surface);
+ cairo_surface_destroy (surface);
+}
+
+static cairo_surface_t *
+png_acquire (cairo_pattern_t *pattern, void *closure,
+ cairo_surface_t *target,
+ const cairo_rectangle_int_t *extents)
+{
+ return cairo_image_surface_create_from_png (closure);
+}
+
+static cairo_surface_t *
+red_acquire (cairo_pattern_t *pattern, void *closure,
+ cairo_surface_t *target,
+ const cairo_rectangle_int_t *extents)
+{
+ cairo_surface_t *image;
+ cairo_t *cr;
+
+ image = cairo_surface_create_similar_image (target,
+ CAIRO_FORMAT_RGB24,
+ extents->width,
+ extents->height);
+ cairo_surface_set_device_offset (image, extents->x, extents->y);
+
+ cr = cairo_create (image);
+ cairo_set_source_rgb (cr, 1, 0, 0);
+ cairo_paint (cr);
+ cairo_destroy (cr);
+
+ return image;
+}
+
+static void
+release (cairo_pattern_t *pattern, void *closure, cairo_surface_t *image)
+{
+ cairo_surface_destroy (image);
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ const char *png_filename = "png.png";
+ cairo_pattern_t *png, *red;
+ cairo_content_t content;
+ int png_width, png_height;
+ int i, j;
+
+ png_dimensions (png_filename, &content, &png_width, &png_height);
+
+ png = cairo_pattern_create_raster_source ((void*)png_filename,
+ content, png_width, png_height);
+ cairo_raster_source_pattern_set_acquire (png, png_acquire, release);
+
+ red = cairo_pattern_create_raster_source (NULL,
+ CAIRO_CONTENT_COLOR, WIDTH, HEIGHT);
+ cairo_raster_source_pattern_set_acquire (red, red_acquire, release);
+
+ cairo_set_source_rgb (cr, 0, 0, 1);
+ cairo_paint (cr);
+
+ cairo_translate (cr, 0, (HEIGHT-png_height)/2);
+ for (i = 0; i < 4; i++) {
+ for (j = 0; j < 4; j++) {
+ cairo_pattern_t *source;
+ if ((i ^ j) & 1)
+ source = red;
+ else
+ source = png;
+ cairo_set_source (cr, source);
+ cairo_rectangle (cr, i * WIDTH/4, j * png_height/4, WIDTH/4, png_height/4);
+ cairo_fill (cr);
+ }
+ }
+
+ cairo_pattern_destroy (red);
+ cairo_pattern_destroy (png);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (raster_source,
+ "Check that the mime-surface embedding works",
+ "api", /* keywords */
+ NULL, /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw)
diff --git a/test/record-extend.c b/test/record-extend.c
new file mode 100644
index 000000000..8e8387151
--- /dev/null
+++ b/test/record-extend.c
@@ -0,0 +1,288 @@
+/*
+ * Copyright © 2007 Red Hat, Inc.
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ * Behdad Esfahbod <behdad@behdad.org>
+ * Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+#include <math.h>
+#include <stdio.h>
+
+#define SIZE 90
+
+/* This is written using clip+paint to exercise a bug that once was in the
+ * recording surface.
+ */
+
+static cairo_surface_t *
+source (cairo_surface_t *surface)
+{
+ cairo_t *cr;
+
+ /* Create a 4-pixel image surface with my favorite four colors in each
+ * quadrant. */
+ cr = cairo_create (surface);
+ cairo_surface_destroy (surface);
+
+ /* upper-left = white */
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_rectangle (cr, 0, 0, 1, 1);
+ cairo_fill (cr);
+
+ /* upper-right = red */
+ cairo_set_source_rgb (cr, 1, 0, 0);
+ cairo_rectangle (cr, 1, 0, 1, 1);
+ cairo_fill (cr);
+
+ /* lower-left = green */
+ cairo_set_source_rgb (cr, 0, 1, 0);
+ cairo_rectangle (cr, 0, 1, 1, 1);
+ cairo_fill (cr);
+
+ /* lower-right = blue */
+ cairo_set_source_rgb (cr, 0, 0, 1);
+ cairo_rectangle (cr, 1, 1, 1, 1);
+ cairo_fill (cr);
+
+ surface = cairo_surface_reference (cairo_get_target (cr));
+ cairo_destroy (cr);
+
+ return surface;
+}
+
+static cairo_surface_t *
+image (cairo_t *cr)
+{
+ return source (cairo_image_surface_create (CAIRO_FORMAT_RGB24, 2, 2));
+}
+
+static cairo_surface_t *
+similar (cairo_t *cr)
+{
+ return source (cairo_surface_create_similar (cairo_get_target (cr),
+ CAIRO_CONTENT_COLOR, 2, 2));
+}
+
+static cairo_t *
+extend (cairo_t *cr, cairo_surface_t *(*surface)(cairo_t *), cairo_extend_t mode)
+{
+ cairo_surface_t *s;
+
+ cairo_set_source_rgb (cr, 0, 1, 1);
+ cairo_paint (cr);
+
+ /* Now use extend modes to cover most of the surface with those 4 colors */
+ s = surface (cr);
+ cairo_set_source_surface (cr, s, SIZE/2 - 1, SIZE/2 - 1);
+ cairo_surface_destroy (s);
+
+ cairo_pattern_set_extend (cairo_get_source (cr), mode);
+
+ cairo_rectangle (cr, 10, 10, SIZE-20, SIZE-20);
+ cairo_clip (cr);
+ cairo_paint (cr);
+
+ return cr;
+}
+
+static cairo_t *
+extend_none (cairo_t *cr,
+ cairo_surface_t *(*pattern)(cairo_t *))
+{
+ return extend (cr, pattern, CAIRO_EXTEND_NONE);
+}
+
+static cairo_t *
+extend_pad (cairo_t *cr,
+ cairo_surface_t *(*pattern)(cairo_t *))
+{
+ return extend (cr, pattern, CAIRO_EXTEND_PAD);
+}
+
+static cairo_t *
+extend_repeat (cairo_t *cr,
+ cairo_surface_t *(*pattern)(cairo_t *))
+{
+ return extend (cr, pattern, CAIRO_EXTEND_REPEAT);
+}
+
+static cairo_t *
+extend_reflect (cairo_t *cr,
+ cairo_surface_t *(*pattern)(cairo_t *))
+{
+ return extend (cr, pattern, CAIRO_EXTEND_REFLECT);
+}
+
+static cairo_t *
+record_create (cairo_t *target)
+{
+ cairo_surface_t *surface;
+ cairo_t *cr;
+
+ surface = cairo_recording_surface_create (cairo_surface_get_content (cairo_get_target (target)), NULL);
+ cr = cairo_create (surface);
+ cairo_surface_destroy (surface);
+
+ return cr;
+}
+
+static cairo_surface_t *
+record_get (cairo_t *target)
+{
+ cairo_surface_t *surface;
+
+ surface = cairo_surface_reference (cairo_get_target (target));
+ cairo_destroy (target);
+
+ return surface;
+}
+
+static cairo_test_status_t
+record_replay (cairo_t *cr,
+ cairo_t *(*func)(cairo_t *,
+ cairo_surface_t *(*pattern)(cairo_t *)),
+ cairo_surface_t *(*pattern)(cairo_t *),
+ int width, int height)
+{
+ cairo_surface_t *surface;
+ int x, y;
+
+ surface = record_get (func (record_create (cr), pattern));
+
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_set_source_surface (cr, surface, 0, 0);
+ cairo_surface_destroy (surface);
+ cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_NONE);
+
+ for (y = 0; y < height; y += 2) {
+ for (x = 0; x < width; x += 2) {
+ cairo_rectangle (cr, x, y, 2, 2);
+ cairo_clip (cr);
+ cairo_paint (cr);
+ cairo_reset_clip (cr);
+ }
+ }
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+record_extend_none (cairo_t *cr, int width, int height)
+{
+ return record_replay (cr, extend_none, image, width, height);
+}
+
+static cairo_test_status_t
+record_extend_pad (cairo_t *cr, int width, int height)
+{
+ return record_replay (cr, extend_pad, image, width, height);
+}
+
+static cairo_test_status_t
+record_extend_repeat (cairo_t *cr, int width, int height)
+{
+ return record_replay (cr, extend_repeat, image, width, height);
+}
+
+static cairo_test_status_t
+record_extend_reflect (cairo_t *cr, int width, int height)
+{
+ return record_replay (cr, extend_reflect, image, width, height);
+}
+
+static cairo_test_status_t
+record_extend_none_similar (cairo_t *cr, int width, int height)
+{
+ return record_replay (cr, extend_none, similar, width, height);
+}
+
+static cairo_test_status_t
+record_extend_pad_similar (cairo_t *cr, int width, int height)
+{
+ return record_replay (cr, extend_pad, similar, width, height);
+}
+
+static cairo_test_status_t
+record_extend_repeat_similar (cairo_t *cr, int width, int height)
+{
+ return record_replay (cr, extend_repeat, similar, width, height);
+}
+
+static cairo_test_status_t
+record_extend_reflect_similar (cairo_t *cr, int width, int height)
+{
+ return record_replay (cr, extend_reflect, similar, width, height);
+}
+
+CAIRO_TEST (record_extend_none,
+ "Test CAIRO_EXTEND_NONE for recorded surface patterns",
+ "record, extend", /* keywords */
+ NULL, /* requirements */
+ SIZE, SIZE,
+ NULL, record_extend_none)
+CAIRO_TEST (record_extend_pad,
+ "Test CAIRO_EXTEND_PAD for recorded surface patterns",
+ "record, extend", /* keywords */
+ NULL, /* requirements */
+ SIZE, SIZE,
+ NULL, record_extend_pad)
+CAIRO_TEST (record_extend_repeat,
+ "Test CAIRO_EXTEND_REPEAT for recorded surface patterns",
+ "record, extend", /* keywords */
+ NULL, /* requirements */
+ SIZE, SIZE,
+ NULL, record_extend_repeat)
+CAIRO_TEST (record_extend_reflect,
+ "Test CAIRO_EXTEND_REFLECT for recorded surface patterns",
+ "record, extend", /* keywords */
+ NULL, /* requirements */
+ SIZE, SIZE,
+ NULL, record_extend_reflect)
+
+CAIRO_TEST (record_extend_none_similar,
+ "Test CAIRO_EXTEND_NONE for recorded surface patterns",
+ "record, extend", /* keywords */
+ NULL, /* requirements */
+ SIZE, SIZE,
+ NULL, record_extend_none_similar)
+CAIRO_TEST (record_extend_pad_similar,
+ "Test CAIRO_EXTEND_PAD for recorded surface patterns",
+ "record, extend", /* keywords */
+ NULL, /* requirements */
+ SIZE, SIZE,
+ NULL, record_extend_pad_similar)
+CAIRO_TEST (record_extend_repeat_similar,
+ "Test CAIRO_EXTEND_REPEAT for recorded surface patterns",
+ "record, extend", /* keywords */
+ NULL, /* requirements */
+ SIZE, SIZE,
+ NULL, record_extend_repeat_similar)
+CAIRO_TEST (record_extend_reflect_similar,
+ "Test CAIRO_EXTEND_REFLECT for recorded surface patterns",
+ "record, extend", /* keywords */
+ NULL, /* requirements */
+ SIZE, SIZE,
+ NULL, record_extend_reflect_similar)
diff --git a/test/record-mesh.c b/test/record-mesh.c
new file mode 100644
index 000000000..754a1d430
--- /dev/null
+++ b/test/record-mesh.c
@@ -0,0 +1,166 @@
+/*
+ * Copyright © 2007 Red Hat, Inc.
+ * Copyright © 2009 Adrian Johnson
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ * Behdad Esfahbod <behdad@behdad.org>
+ * Adrian Johnson <ajohnson@redneon.com>
+ * Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+#include <math.h>
+#include <stdio.h>
+
+#define PAT_WIDTH 170
+#define PAT_HEIGHT 170
+#define SIZE PAT_WIDTH
+#define PAD 2
+#define WIDTH (PAD + SIZE + PAD)
+#define HEIGHT WIDTH
+
+/* This test is designed to paint a mesh pattern. The mesh contains
+ * two overlapping patches */
+
+static cairo_pattern_t *
+mesh (void)
+{
+ cairo_pattern_t *pattern;
+
+ pattern = cairo_pattern_create_mesh ();
+
+ cairo_mesh_pattern_begin_patch (pattern);
+
+ cairo_mesh_pattern_move_to (pattern, 0, 0);
+ cairo_mesh_pattern_curve_to (pattern, 30, -30, 60, 30, 100, 0);
+ cairo_mesh_pattern_curve_to (pattern, 60, 30, 130, 60, 100, 100);
+ cairo_mesh_pattern_curve_to (pattern, 60, 70, 30, 130, 0, 100);
+ cairo_mesh_pattern_curve_to (pattern, 30, 70, -30, 30, 0, 0);
+
+ cairo_mesh_pattern_set_corner_color_rgb (pattern, 0, 1, 0, 0);
+ cairo_mesh_pattern_set_corner_color_rgb (pattern, 1, 0, 1, 0);
+ cairo_mesh_pattern_set_corner_color_rgb (pattern, 2, 0, 0, 1);
+ cairo_mesh_pattern_set_corner_color_rgb (pattern, 3, 1, 1, 0);
+
+ cairo_mesh_pattern_end_patch (pattern);
+
+ cairo_mesh_pattern_begin_patch (pattern);
+
+ cairo_mesh_pattern_move_to (pattern, 50, 50);
+ cairo_mesh_pattern_curve_to (pattern, 80, 20, 110, 80, 150, 50);
+ cairo_mesh_pattern_curve_to (pattern, 110, 80, 180, 110, 150, 150);
+ cairo_mesh_pattern_curve_to (pattern, 110, 120, 80, 180, 50, 150);
+ cairo_mesh_pattern_curve_to (pattern, 80, 120, 20, 80, 50, 50);
+
+ cairo_mesh_pattern_set_corner_color_rgba (pattern, 0, 1, 0, 0, 0.3);
+ cairo_mesh_pattern_set_corner_color_rgb (pattern, 1, 0, 1, 0);
+ cairo_mesh_pattern_set_corner_color_rgba (pattern, 2, 0, 0, 1, 0.3);
+ cairo_mesh_pattern_set_corner_color_rgb (pattern, 3, 1, 1, 0);
+
+ cairo_mesh_pattern_end_patch (pattern);
+
+ return pattern;
+}
+
+static cairo_t *
+draw (cairo_t *cr)
+{
+ cairo_pattern_t *source;
+
+ cairo_set_source_rgb (cr, 0, 1, 1);
+ cairo_paint (cr);
+
+ source = mesh ();
+ cairo_set_source (cr, source);
+ cairo_pattern_destroy (source);
+
+ cairo_rectangle (cr, 10, 10, SIZE-20, SIZE-20);
+ cairo_clip (cr);
+ cairo_paint (cr);
+
+ return cr;
+}
+
+static cairo_t *
+record_create (cairo_t *target)
+{
+ cairo_surface_t *surface;
+ cairo_t *cr;
+
+ surface = cairo_recording_surface_create (cairo_surface_get_content (cairo_get_target (target)), NULL);
+ cr = cairo_create (surface);
+ cairo_surface_destroy (surface);
+
+ return cr;
+}
+
+static cairo_surface_t *
+record_get (cairo_t *target)
+{
+ cairo_surface_t *surface;
+
+ surface = cairo_surface_reference (cairo_get_target (target));
+ cairo_destroy (target);
+
+ return surface;
+}
+
+static cairo_test_status_t
+record_replay (cairo_t *cr, cairo_t *(*func)(cairo_t *), int width, int height)
+{
+ cairo_surface_t *surface;
+ int x, y;
+
+ surface = record_get (func (record_create (cr)));
+
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_set_source_surface (cr, surface, 0, 0);
+ cairo_surface_destroy (surface);
+ cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_NONE);
+
+ for (y = 0; y < height; y += 2) {
+ for (x = 0; x < width; x += 2) {
+ cairo_rectangle (cr, x, y, 2, 2);
+ cairo_clip (cr);
+ cairo_paint (cr);
+ cairo_reset_clip (cr);
+ }
+ }
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+record_mesh (cairo_t *cr, int width, int height)
+{
+ return record_replay (cr, draw, width, height);
+}
+
+CAIRO_TEST (record_mesh,
+ "Paint mesh pattern through a recording surface",
+ "record,mesh,pattern", /* keywords */
+ NULL, /* requirements */
+ WIDTH, HEIGHT,
+ NULL, record_mesh)
+
diff --git a/test/record.c b/test/record.c
new file mode 100644
index 000000000..b1baadace
--- /dev/null
+++ b/test/record.c
@@ -0,0 +1,491 @@
+/*
+ * Copyright © 2005 Red Hat, Inc.
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors:
+ * Carl D. Worth <cworth@cworth.org>
+ * Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+#define TEXT_SIZE 12
+#define SIZE 60 /* needs to be big to check large area effects (dithering) */
+#define PAD 2
+
+#define TT_SIZE 100
+#define TT_PAD 5
+#define TT_FONT_SIZE 32.0
+
+#define GENERATE_REF 0
+
+static uint32_t data[16] = {
+ 0xffffffff, 0xffffffff, 0xffff0000, 0xffff0000,
+ 0xffffffff, 0xffffffff, 0xffff0000, 0xffff0000,
+
+ 0xff00ff00, 0xff00ff00, 0xff0000ff, 0xff0000ff,
+ 0xff00ff00, 0xff00ff00, 0xff0000ff, 0xff0000ff
+};
+
+static const char *png_filename = "romedalen.png";
+
+static cairo_t *
+paint (cairo_t *cr)
+{
+ cairo_set_source_rgb (cr, 0, 0, 1);
+ cairo_paint (cr);
+
+ cairo_translate (cr, 2, 2);
+ cairo_scale (cr, 0.5, 0.5);
+
+ cairo_set_source_rgb (cr, 1, 0, 0);
+ cairo_paint (cr);
+
+ return cr;
+}
+
+static cairo_t *
+paint_alpha (cairo_t *cr)
+{
+ cairo_surface_t *surface;
+
+ surface = cairo_image_surface_create_for_data ((unsigned char *) data,
+ CAIRO_FORMAT_RGB24, 4, 4, 16);
+
+ cairo_test_paint_checkered (cr);
+
+ cairo_scale (cr, 4, 4);
+
+ cairo_set_source_surface (cr, surface, 2 , 2);
+ cairo_pattern_set_filter (cairo_get_source (cr), CAIRO_FILTER_NEAREST);
+ cairo_paint_with_alpha (cr, 0.5);
+
+ cairo_surface_finish (surface); /* data will go out of scope */
+ cairo_surface_destroy (surface);
+
+ return cr;
+}
+
+static cairo_t *
+paint_alpha_solid_clip (cairo_t *cr)
+{
+ cairo_test_paint_checkered (cr);
+
+ cairo_rectangle (cr, 2.5, 2.5, 27, 27);
+ cairo_clip (cr);
+
+ cairo_set_source_rgb (cr, 1., 0.,0.);
+ cairo_paint_with_alpha (cr, 0.5);
+
+ return cr;
+}
+
+static cairo_t *
+paint_alpha_clip (cairo_t *cr)
+{
+ cairo_surface_t *surface;
+
+ surface = cairo_image_surface_create_for_data ((unsigned char *) data,
+ CAIRO_FORMAT_RGB24, 4, 4, 16);
+
+ cairo_test_paint_checkered (cr);
+
+ cairo_rectangle (cr, 10.5, 10.5, 11, 11);
+ cairo_clip (cr);
+
+ cairo_scale (cr, 4, 4);
+
+ cairo_set_source_surface (cr, surface, 2 , 2);
+ cairo_pattern_set_filter (cairo_get_source (cr), CAIRO_FILTER_NEAREST);
+ cairo_paint_with_alpha (cr, 0.5);
+
+ cairo_surface_finish (surface); /* data will go out of scope */
+ cairo_surface_destroy (surface);
+
+ return cr;
+}
+
+static cairo_t *
+paint_alpha_clip_mask (cairo_t *cr)
+{
+ cairo_surface_t *surface;
+
+ surface = cairo_image_surface_create_for_data ((unsigned char *) data,
+ CAIRO_FORMAT_RGB24, 4, 4, 16);
+
+ cairo_test_paint_checkered (cr);
+
+ cairo_move_to (cr, 16, 5);
+ cairo_line_to (cr, 5, 16);
+ cairo_line_to (cr, 16, 27);
+ cairo_line_to (cr, 27, 16);
+ cairo_clip (cr);
+
+ cairo_scale (cr, 4, 4);
+
+ cairo_set_source_surface (cr, surface, 2 , 2);
+ cairo_pattern_set_filter (cairo_get_source (cr), CAIRO_FILTER_NEAREST);
+ cairo_paint_with_alpha (cr, 0.5);
+
+ cairo_surface_finish (surface); /* data will go out of scope */
+ cairo_surface_destroy (surface);
+
+ return cr;
+}
+
+static cairo_t *
+select_font_face (cairo_t *cr)
+{
+ /* We draw in the default black, so paint white first. */
+ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */
+ cairo_paint (cr);
+
+ cairo_set_source_rgb (cr, 0, 0, 0); /* black */
+
+ cairo_set_font_size (cr, TEXT_SIZE);
+ cairo_move_to (cr, 0, TEXT_SIZE);
+
+ cairo_select_font_face (cr, CAIRO_TEST_FONT_FAMILY " Serif",
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_NORMAL);
+ cairo_show_text (cr, "i-am-serif");
+
+ cairo_select_font_face (cr, CAIRO_TEST_FONT_FAMILY " Sans",
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_NORMAL);
+ cairo_show_text (cr, " i-am-sans");
+
+ cairo_select_font_face (cr, CAIRO_TEST_FONT_FAMILY " Sans Mono",
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_NORMAL);
+ cairo_show_text (cr, " i-am-mono");
+
+ return cr;
+}
+
+static cairo_t *
+fill_alpha (cairo_t *cr)
+{
+ const double alpha = 1./3;
+ int n;
+
+ /* flatten to white */
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+ /* square */
+ cairo_rectangle (cr, PAD, PAD, SIZE, SIZE);
+ cairo_set_source_rgba (cr, 1, 0, 0, alpha);
+ cairo_fill (cr);
+
+ /* circle */
+ cairo_translate (cr, SIZE + 2 * PAD, 0);
+ cairo_arc (cr, PAD + SIZE / 2., PAD + SIZE / 2., SIZE / 2., 0, 2 * M_PI);
+ cairo_set_source_rgba (cr, 0, 1, 0, alpha);
+ cairo_fill (cr);
+
+ /* triangle */
+ cairo_translate (cr, 0, SIZE + 2 * PAD);
+ cairo_move_to (cr, PAD + SIZE / 2, PAD);
+ cairo_line_to (cr, PAD + SIZE, PAD + SIZE);
+ cairo_line_to (cr, PAD, PAD + SIZE);
+ cairo_set_source_rgba (cr, 0, 0, 1, alpha);
+ cairo_fill (cr);
+
+ /* star */
+ cairo_translate (cr, -(SIZE + 2 * PAD) + SIZE/2., SIZE/2.);
+ for (n = 0; n < 5; n++) {
+ cairo_line_to (cr,
+ SIZE/2 * cos (2*n * 2*M_PI / 10),
+ SIZE/2 * sin (2*n * 2*M_PI / 10));
+
+ cairo_line_to (cr,
+ SIZE/4 * cos ((2*n+1)*2*M_PI / 10),
+ SIZE/4 * sin ((2*n+1)*2*M_PI / 10));
+ }
+ cairo_set_source_rgba (cr, 0, 0, 0, alpha);
+ cairo_fill (cr);
+
+ return cr;
+}
+
+static cairo_t *
+self_intersecting (cairo_t *cr)
+{
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+ cairo_translate (cr, 1.0, 1.0);
+
+ cairo_set_source_rgb (cr, 1, 0, 0); /* red */
+
+ /* First draw the desired shape with a fill */
+ cairo_rectangle (cr, 0.5, 0.5, 4.0, 4.0);
+ cairo_rectangle (cr, 3.5, 3.5, 4.0, 4.0);
+ cairo_rectangle (cr, 3.5, 1.5, -2.0, 2.0);
+ cairo_rectangle (cr, 6.5, 4.5, -2.0, 2.0);
+
+ cairo_fill (cr);
+
+ /* Then try the same thing with a stroke */
+ cairo_translate (cr, 0, 10);
+ cairo_move_to (cr, 1.0, 1.0);
+ cairo_rel_line_to (cr, 3.0, 0.0);
+ cairo_rel_line_to (cr, 0.0, 6.0);
+ cairo_rel_line_to (cr, 3.0, 0.0);
+ cairo_rel_line_to (cr, 0.0, -3.0);
+ cairo_rel_line_to (cr, -6.0, 0.0);
+ cairo_close_path (cr);
+
+ cairo_set_line_width (cr, 1.0);
+ cairo_stroke (cr);
+
+ return cr;
+}
+
+static void
+draw_text_transform (cairo_t *cr)
+{
+ cairo_matrix_t tm;
+
+ /* skew */
+ cairo_matrix_init (&tm, 1, 0,
+ -0.25, 1,
+ 0, 0);
+ cairo_matrix_scale (&tm, TT_FONT_SIZE, TT_FONT_SIZE);
+ cairo_set_font_matrix (cr, &tm);
+
+ cairo_new_path (cr);
+ cairo_move_to (cr, 50, TT_SIZE-TT_PAD);
+ cairo_show_text (cr, "A");
+
+ /* rotate and scale */
+ cairo_matrix_init_rotate (&tm, M_PI / 2);
+ cairo_matrix_scale (&tm, TT_FONT_SIZE, TT_FONT_SIZE * 2.0);
+ cairo_set_font_matrix (cr, &tm);
+
+ cairo_new_path (cr);
+ cairo_move_to (cr, TT_PAD, TT_PAD + 25);
+ cairo_show_text (cr, "A");
+
+ cairo_matrix_init_rotate (&tm, M_PI / 2);
+ cairo_matrix_scale (&tm, TT_FONT_SIZE * 2.0, TT_FONT_SIZE);
+ cairo_set_font_matrix (cr, &tm);
+
+ cairo_new_path (cr);
+ cairo_move_to (cr, TT_PAD, TT_PAD + 50);
+ cairo_show_text (cr, "A");
+}
+
+static cairo_t *
+text_transform (cairo_t *cr)
+{
+ const cairo_test_context_t *ctx = cairo_test_get_context (cr);
+ cairo_pattern_t *pattern;
+
+ cairo_set_source_rgb (cr, 1., 1., 1.);
+ cairo_paint (cr);
+
+ cairo_set_source_rgb (cr, 0., 0., 0.);
+
+ cairo_select_font_face (cr, CAIRO_TEST_FONT_FAMILY " Sans",
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_NORMAL);
+
+ draw_text_transform (cr);
+
+ cairo_translate (cr, TT_SIZE, TT_SIZE);
+ cairo_rotate (cr, M_PI);
+
+ pattern = cairo_test_create_pattern_from_png (ctx, png_filename);
+ cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT);
+ cairo_set_source (cr, pattern);
+ cairo_pattern_destroy (pattern);
+
+ draw_text_transform (cr);
+
+ return cr;
+}
+
+/* And here begins the recording and replaying... */
+
+static cairo_t *
+record_create (cairo_t *target)
+{
+ cairo_surface_t *surface;
+ cairo_t *cr;
+
+ surface = cairo_recording_surface_create (cairo_surface_get_content (cairo_get_target (target)), NULL);
+ cr = cairo_create (surface);
+ cairo_surface_destroy (surface);
+
+ return cr;
+}
+
+static cairo_surface_t *
+record_get (cairo_t *target)
+{
+ cairo_surface_t *surface;
+
+ surface = cairo_surface_reference (cairo_get_target (target));
+ cairo_destroy (target);
+
+ return surface;
+}
+
+static cairo_test_status_t
+record_replay (cairo_t *cr, cairo_t *(*func)(cairo_t *), int width, int height)
+{
+ cairo_surface_t *surface;
+ int x, y;
+
+#if GENERATE_REF
+ func(cr);
+#else
+ surface = record_get (func (record_create (cr)));
+
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_set_source_surface (cr, surface, 0, 0);
+ cairo_surface_destroy (surface);
+ cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_NONE);
+
+ for (y = 0; y < height; y += 2) {
+ for (x = 0; x < width; x += 2) {
+ cairo_rectangle (cr, x, y, 2, 2);
+ cairo_clip (cr);
+ cairo_paint (cr);
+ cairo_reset_clip (cr);
+ }
+ }
+#endif
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+record_paint (cairo_t *cr, int width, int height)
+{
+ return record_replay (cr, paint, width, height);
+}
+
+static cairo_test_status_t
+record_paint_alpha (cairo_t *cr, int width, int height)
+{
+ return record_replay (cr, paint_alpha, width, height);
+}
+
+static cairo_test_status_t
+record_paint_alpha_solid_clip (cairo_t *cr, int width, int height)
+{
+ return record_replay (cr, paint_alpha_solid_clip, width, height);
+}
+
+static cairo_test_status_t
+record_paint_alpha_clip (cairo_t *cr, int width, int height)
+{
+ return record_replay (cr, paint_alpha_clip, width, height);
+}
+
+static cairo_test_status_t
+record_paint_alpha_clip_mask (cairo_t *cr, int width, int height)
+{
+ return record_replay (cr, paint_alpha_clip_mask, width, height);
+}
+
+static cairo_test_status_t
+record_fill_alpha (cairo_t *cr, int width, int height)
+{
+ return record_replay (cr, fill_alpha, width, height);
+}
+
+static cairo_test_status_t
+record_self_intersecting (cairo_t *cr, int width, int height)
+{
+ return record_replay (cr, self_intersecting, width, height);
+}
+
+static cairo_test_status_t
+record_select_font_face (cairo_t *cr, int width, int height)
+{
+ return record_replay (cr, select_font_face, width, height);
+}
+
+static cairo_test_status_t
+record_text_transform (cairo_t *cr, int width, int height)
+{
+ return record_replay (cr, text_transform, width, height);
+}
+
+CAIRO_TEST (record_paint,
+ "Test replayed calls to cairo_paint",
+ "paint,record", /* keywords */
+ NULL, /* requirements */
+ 8, 8,
+ NULL, record_paint)
+CAIRO_TEST (record_paint_alpha,
+ "Simple test of cairo_paint_with_alpha",
+ "record, paint, alpha", /* keywords */
+ NULL, /* requirements */
+ 32, 32,
+ NULL, record_paint_alpha)
+CAIRO_TEST (record_paint_alpha_solid_clip,
+ "Simple test of cairo_paint_with_alpha+unaligned clip",
+ "record, paint, alpha, clip", /* keywords */
+ NULL, /* requirements */
+ 32, 32,
+ NULL, record_paint_alpha_solid_clip)
+CAIRO_TEST (record_paint_alpha_clip,
+ "Simple test of cairo_paint_with_alpha+unaligned clip",
+ "record, paint, alpha, clip", /* keywords */
+ NULL, /* requirements */
+ 32, 32,
+ NULL, record_paint_alpha_clip)
+CAIRO_TEST (record_paint_alpha_clip_mask,
+ "Simple test of cairo_paint_with_alpha+triangular clip",
+ "record, paint, alpha, clip", /* keywords */
+ NULL, /* requirements */
+ 32, 32,
+ NULL, record_paint_alpha_clip_mask)
+CAIRO_TEST (record_fill_alpha,
+ "Tests using set_rgba();fill()",
+ "record,fill, alpha", /* keywords */
+ NULL, /* requirements */
+ 2*SIZE + 4*PAD, 2*SIZE + 4*PAD,
+ NULL, record_fill_alpha)
+CAIRO_TEST (record_select_font_face,
+ "Tests using cairo_select_font_face to draw text in different faces",
+ "record, font", /* keywords */
+ NULL, /* requirements */
+ 192, TEXT_SIZE + 4,
+ NULL, record_select_font_face)
+CAIRO_TEST (record_self_intersecting,
+ "Test strokes of self-intersecting paths",
+ "record, stroke, trap", /* keywords */
+ NULL, /* requirements */
+ 10, 20,
+ NULL, record_self_intersecting)
+CAIRO_TEST (record_text_transform,
+ "Test various applications of the font matrix",
+ "record, text, transform", /* keywords */
+ NULL, /* requirements */
+ TT_SIZE, TT_SIZE,
+ NULL, record_text_transform)
diff --git a/test/record1414x.c b/test/record1414x.c
new file mode 100644
index 000000000..029e5a4d6
--- /dev/null
+++ b/test/record1414x.c
@@ -0,0 +1,498 @@
+/*
+ * Copyright © 2005 Red Hat, Inc.
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors:
+ * Carl D. Worth <cworth@cworth.org>
+ * Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+#ifndef M_SQRT2
+#define M_SQRT2 1.41421345623730951
+#endif
+
+#define TEXT_SIZE 12
+#define SIZE 60 /* needs to be big to check large area effects (dithering) */
+#define PAD 2
+
+#define TT_SIZE 100
+#define TT_PAD 5
+#define TT_FONT_SIZE 32.0
+
+#define GENERATE_REF 0
+
+static uint32_t data[16] = {
+ 0xffffffff, 0xffffffff, 0xffff0000, 0xffff0000,
+ 0xffffffff, 0xffffffff, 0xffff0000, 0xffff0000,
+
+ 0xff00ff00, 0xff00ff00, 0xff0000ff, 0xff0000ff,
+ 0xff00ff00, 0xff00ff00, 0xff0000ff, 0xff0000ff
+};
+
+static const char *png_filename = "romedalen.png";
+
+static cairo_t *
+paint (cairo_t *cr)
+{
+ cairo_set_source_rgb (cr, 0, 0, 1);
+ cairo_paint (cr);
+
+ cairo_translate (cr, 2, 2);
+ cairo_scale (cr, 0.5, 0.5);
+
+ cairo_set_source_rgb (cr, 1, 0, 0);
+ cairo_paint (cr);
+
+ return cr;
+}
+
+static cairo_t *
+paint_alpha (cairo_t *cr)
+{
+ cairo_surface_t *surface;
+
+ surface = cairo_image_surface_create_for_data ((unsigned char *) data,
+ CAIRO_FORMAT_RGB24, 4, 4, 16);
+
+ cairo_test_paint_checkered (cr);
+
+ cairo_scale (cr, 4, 4);
+
+ cairo_set_source_surface (cr, surface, 2 , 2);
+ cairo_pattern_set_filter (cairo_get_source (cr), CAIRO_FILTER_NEAREST);
+ cairo_paint_with_alpha (cr, 0.5);
+
+ cairo_surface_finish (surface); /* data will go out of scope */
+ cairo_surface_destroy (surface);
+
+ return cr;
+}
+
+static cairo_t *
+paint_alpha_solid_clip (cairo_t *cr)
+{
+ cairo_test_paint_checkered (cr);
+
+ cairo_rectangle (cr, 2.5, 2.5, 27, 27);
+ cairo_clip (cr);
+
+ cairo_set_source_rgb (cr, 1., 0.,0.);
+ cairo_paint_with_alpha (cr, 0.5);
+
+ return cr;
+}
+
+static cairo_t *
+paint_alpha_clip (cairo_t *cr)
+{
+ cairo_surface_t *surface;
+
+ surface = cairo_image_surface_create_for_data ((unsigned char *) data,
+ CAIRO_FORMAT_RGB24, 4, 4, 16);
+
+ cairo_test_paint_checkered (cr);
+
+ cairo_rectangle (cr, 10.5, 10.5, 11, 11);
+ cairo_clip (cr);
+
+ cairo_scale (cr, 4, 4);
+
+ cairo_set_source_surface (cr, surface, 2 , 2);
+ cairo_pattern_set_filter (cairo_get_source (cr), CAIRO_FILTER_NEAREST);
+ cairo_paint_with_alpha (cr, 0.5);
+
+ cairo_surface_finish (surface); /* data will go out of scope */
+ cairo_surface_destroy (surface);
+
+ return cr;
+}
+
+static cairo_t *
+paint_alpha_clip_mask (cairo_t *cr)
+{
+ cairo_surface_t *surface;
+
+ surface = cairo_image_surface_create_for_data ((unsigned char *) data,
+ CAIRO_FORMAT_RGB24, 4, 4, 16);
+
+ cairo_test_paint_checkered (cr);
+
+ cairo_move_to (cr, 16, 5);
+ cairo_line_to (cr, 5, 16);
+ cairo_line_to (cr, 16, 27);
+ cairo_line_to (cr, 27, 16);
+ cairo_clip (cr);
+
+ cairo_scale (cr, 4, 4);
+
+ cairo_set_source_surface (cr, surface, 2 , 2);
+ cairo_pattern_set_filter (cairo_get_source (cr), CAIRO_FILTER_NEAREST);
+ cairo_paint_with_alpha (cr, 0.5);
+
+ cairo_surface_finish (surface); /* data will go out of scope */
+ cairo_surface_destroy (surface);
+
+ return cr;
+}
+
+static cairo_t *
+select_font_face (cairo_t *cr)
+{
+ /* We draw in the default black, so paint white first. */
+ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */
+ cairo_paint (cr);
+
+ cairo_set_source_rgb (cr, 0, 0, 0); /* black */
+
+ cairo_set_font_size (cr, TEXT_SIZE);
+ cairo_move_to (cr, 0, TEXT_SIZE);
+
+ cairo_select_font_face (cr, CAIRO_TEST_FONT_FAMILY " Serif",
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_NORMAL);
+ cairo_show_text (cr, "i-am-serif");
+
+ cairo_select_font_face (cr, CAIRO_TEST_FONT_FAMILY " Sans",
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_NORMAL);
+ cairo_show_text (cr, " i-am-sans");
+
+ cairo_select_font_face (cr, CAIRO_TEST_FONT_FAMILY " Sans Mono",
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_NORMAL);
+ cairo_show_text (cr, " i-am-mono");
+
+ return cr;
+}
+
+static cairo_t *
+fill_alpha (cairo_t *cr)
+{
+ const double alpha = 1./3;
+ int n;
+
+ /* flatten to white */
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+ /* square */
+ cairo_rectangle (cr, PAD, PAD, SIZE, SIZE);
+ cairo_set_source_rgba (cr, 1, 0, 0, alpha);
+ cairo_fill (cr);
+
+ /* circle */
+ cairo_translate (cr, SIZE + 2 * PAD, 0);
+ cairo_arc (cr, PAD + SIZE / 2., PAD + SIZE / 2., SIZE / 2., 0, 2 * M_PI);
+ cairo_set_source_rgba (cr, 0, 1, 0, alpha);
+ cairo_fill (cr);
+
+ /* triangle */
+ cairo_translate (cr, 0, SIZE + 2 * PAD);
+ cairo_move_to (cr, PAD + SIZE / 2, PAD);
+ cairo_line_to (cr, PAD + SIZE, PAD + SIZE);
+ cairo_line_to (cr, PAD, PAD + SIZE);
+ cairo_set_source_rgba (cr, 0, 0, 1, alpha);
+ cairo_fill (cr);
+
+ /* star */
+ cairo_translate (cr, -(SIZE + 2 * PAD) + SIZE/2., SIZE/2.);
+ for (n = 0; n < 5; n++) {
+ cairo_line_to (cr,
+ SIZE/2 * cos (2*n * 2*M_PI / 10),
+ SIZE/2 * sin (2*n * 2*M_PI / 10));
+
+ cairo_line_to (cr,
+ SIZE/4 * cos ((2*n+1)*2*M_PI / 10),
+ SIZE/4 * sin ((2*n+1)*2*M_PI / 10));
+ }
+ cairo_set_source_rgba (cr, 0, 0, 0, alpha);
+ cairo_fill (cr);
+
+ return cr;
+}
+
+static cairo_t *
+self_intersecting (cairo_t *cr)
+{
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+ cairo_translate (cr, 1.0, 1.0);
+
+ cairo_set_source_rgb (cr, 1, 0, 0); /* red */
+
+ /* First draw the desired shape with a fill */
+ cairo_rectangle (cr, 0.5, 0.5, 4.0, 4.0);
+ cairo_rectangle (cr, 3.5, 3.5, 4.0, 4.0);
+ cairo_rectangle (cr, 3.5, 1.5, -2.0, 2.0);
+ cairo_rectangle (cr, 6.5, 4.5, -2.0, 2.0);
+
+ cairo_fill (cr);
+
+ /* Then try the same thing with a stroke */
+ cairo_translate (cr, 0, 10);
+ cairo_move_to (cr, 1.0, 1.0);
+ cairo_rel_line_to (cr, 3.0, 0.0);
+ cairo_rel_line_to (cr, 0.0, 6.0);
+ cairo_rel_line_to (cr, 3.0, 0.0);
+ cairo_rel_line_to (cr, 0.0, -3.0);
+ cairo_rel_line_to (cr, -6.0, 0.0);
+ cairo_close_path (cr);
+
+ cairo_set_line_width (cr, 1.0);
+ cairo_stroke (cr);
+
+ return cr;
+}
+
+static void
+draw_text_transform (cairo_t *cr)
+{
+ cairo_matrix_t tm;
+
+ /* skew */
+ cairo_matrix_init (&tm, 1, 0,
+ -0.25, 1,
+ 0, 0);
+ cairo_matrix_scale (&tm, TT_FONT_SIZE, TT_FONT_SIZE);
+ cairo_set_font_matrix (cr, &tm);
+
+ cairo_new_path (cr);
+ cairo_move_to (cr, 50, TT_SIZE-TT_PAD);
+ cairo_show_text (cr, "A");
+
+ /* rotate and scale */
+ cairo_matrix_init_rotate (&tm, M_PI / 2);
+ cairo_matrix_scale (&tm, TT_FONT_SIZE, TT_FONT_SIZE * 2.0);
+ cairo_set_font_matrix (cr, &tm);
+
+ cairo_new_path (cr);
+ cairo_move_to (cr, TT_PAD, TT_PAD + 25);
+ cairo_show_text (cr, "A");
+
+ cairo_matrix_init_rotate (&tm, M_PI / 2);
+ cairo_matrix_scale (&tm, TT_FONT_SIZE * 2.0, TT_FONT_SIZE);
+ cairo_set_font_matrix (cr, &tm);
+
+ cairo_new_path (cr);
+ cairo_move_to (cr, TT_PAD, TT_PAD + 50);
+ cairo_show_text (cr, "A");
+}
+
+static cairo_t *
+text_transform (cairo_t *cr)
+{
+ const cairo_test_context_t *ctx = cairo_test_get_context (cr);
+ cairo_pattern_t *pattern;
+
+ cairo_set_source_rgb (cr, 1., 1., 1.);
+ cairo_paint (cr);
+
+ cairo_set_source_rgb (cr, 0., 0., 0.);
+
+ cairo_select_font_face (cr, CAIRO_TEST_FONT_FAMILY " Sans",
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_NORMAL);
+
+ draw_text_transform (cr);
+
+ cairo_translate (cr, TT_SIZE, TT_SIZE);
+ cairo_rotate (cr, M_PI);
+
+ pattern = cairo_test_create_pattern_from_png (ctx, png_filename);
+ cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT);
+ cairo_set_source (cr, pattern);
+ cairo_pattern_destroy (pattern);
+
+ draw_text_transform (cr);
+
+ return cr;
+}
+
+/* And here begins the recording and replaying... */
+
+static cairo_t *
+record_create (cairo_t *target)
+{
+ cairo_surface_t *surface;
+ cairo_t *cr;
+
+ surface = cairo_recording_surface_create (cairo_surface_get_content (cairo_get_target (target)), NULL);
+ cr = cairo_create (surface);
+ cairo_surface_destroy (surface);
+
+ return cr;
+}
+
+static cairo_surface_t *
+record_get (cairo_t *target)
+{
+ cairo_surface_t *surface;
+
+ surface = cairo_surface_reference (cairo_get_target (target));
+ cairo_destroy (target);
+
+ return surface;
+}
+
+static cairo_test_status_t
+record_replay (cairo_t *cr, cairo_t *(*func)(cairo_t *), int width, int height)
+{
+ cairo_surface_t *surface;
+ int x, y;
+
+#if GENERATE_REF
+ cairo_scale (cr, M_SQRT2, M_SQRT2);
+ func (cr);
+#else
+ surface = record_get (func (record_create (cr)));
+
+ cairo_scale (cr, M_SQRT2, M_SQRT2);
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_set_source_surface (cr, surface, 0, 0);
+ cairo_surface_destroy (surface);
+ cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_NONE);
+
+ cairo_identity_matrix (cr); /* make sure the clip is pixel-aligned */
+ for (y = 0; y < height; y += 2) {
+ for (x = 0; x < width; x += 2) {
+ cairo_rectangle (cr, x, y, 2, 2);
+ cairo_clip (cr);
+ cairo_paint (cr);
+ cairo_reset_clip (cr);
+ }
+ }
+#endif
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+record_paint (cairo_t *cr, int width, int height)
+{
+ return record_replay (cr, paint, width, height);
+}
+
+static cairo_test_status_t
+record_paint_alpha (cairo_t *cr, int width, int height)
+{
+ return record_replay (cr, paint_alpha, width, height);
+}
+
+static cairo_test_status_t
+record_paint_alpha_solid_clip (cairo_t *cr, int width, int height)
+{
+ return record_replay (cr, paint_alpha_solid_clip, width, height);
+}
+
+static cairo_test_status_t
+record_paint_alpha_clip (cairo_t *cr, int width, int height)
+{
+ return record_replay (cr, paint_alpha_clip, width, height);
+}
+
+static cairo_test_status_t
+record_paint_alpha_clip_mask (cairo_t *cr, int width, int height)
+{
+ return record_replay (cr, paint_alpha_clip_mask, width, height);
+}
+
+static cairo_test_status_t
+record_fill_alpha (cairo_t *cr, int width, int height)
+{
+ return record_replay (cr, fill_alpha, width, height);
+}
+
+static cairo_test_status_t
+record_self_intersecting (cairo_t *cr, int width, int height)
+{
+ return record_replay (cr, self_intersecting, width, height);
+}
+
+static cairo_test_status_t
+record_select_font_face (cairo_t *cr, int width, int height)
+{
+ return record_replay (cr, select_font_face, width, height);
+}
+
+static cairo_test_status_t
+record_text_transform (cairo_t *cr, int width, int height)
+{
+ return record_replay (cr, text_transform, width, height);
+}
+
+CAIRO_TEST (record1414x_paint,
+ "Test replayed calls to cairo_paint",
+ "paint, record", /* keywords */
+ NULL, /* requirements */
+ M_SQRT2*8, M_SQRT2*8,
+ NULL, record_paint)
+CAIRO_TEST (record1414x_paint_alpha,
+ "Simple test of cairo_paint_with_alpha",
+ "record, paint, alpha", /* keywords */
+ NULL, /* requirements */
+ M_SQRT2*32, M_SQRT2*32,
+ NULL, record_paint_alpha)
+CAIRO_TEST (record1414x_paint_alpha_solid_clip,
+ "Simple test of cairo_paint_with_alpha+unaligned clip",
+ "record, paint, alpha, clip", /* keywords */
+ NULL, /* requirements */
+ M_SQRT2*32, M_SQRT2*32,
+ NULL, record_paint_alpha_solid_clip)
+CAIRO_TEST (record1414x_paint_alpha_clip,
+ "Simple test of cairo_paint_with_alpha+unaligned clip",
+ "record, paint, alpha, clip", /* keywords */
+ NULL, /* requirements */
+ M_SQRT2*32, M_SQRT2*32,
+ NULL, record_paint_alpha_clip)
+CAIRO_TEST (record1414x_paint_alpha_clip_mask,
+ "Simple test of cairo_paint_with_alpha+triangular clip",
+ "record, paint, alpha, clip", /* keywords */
+ NULL, /* requirements */
+ M_SQRT2*32, M_SQRT2*32,
+ NULL, record_paint_alpha_clip_mask)
+CAIRO_TEST (record1414x_fill_alpha,
+ "Tests using set_rgba();fill()",
+ "record, fill, alpha", /* keywords */
+ NULL, /* requirements */
+ M_SQRT2*(2*SIZE + 4*PAD), M_SQRT2*(2*SIZE + 4*PAD),
+ NULL, record_fill_alpha)
+CAIRO_TEST (record1414x_select_font_face,
+ "Tests using cairo_select_font_face to draw text in different faces",
+ "record, font", /* keywords */
+ NULL, /* requirements */
+ M_SQRT2*192, M_SQRT2*(TEXT_SIZE + 4),
+ NULL, record_select_font_face)
+CAIRO_TEST (record1414x_self_intersecting,
+ "Test strokes of self-intersecting paths",
+ "record, stroke, trap", /* keywords */
+ NULL, /* requirements */
+ M_SQRT2*10, M_SQRT2*20,
+ NULL, record_self_intersecting)
+CAIRO_TEST (record1414x_text_transform,
+ "Test various applications of the font matrix",
+ "record, text, transform", /* keywords */
+ NULL, /* requirements */
+ M_SQRT2*TT_SIZE, M_SQRT2*TT_SIZE,
+ NULL, record_text_transform)
diff --git a/test/record2x.c b/test/record2x.c
new file mode 100644
index 000000000..7fe037732
--- /dev/null
+++ b/test/record2x.c
@@ -0,0 +1,493 @@
+/*
+ * Copyright © 2005 Red Hat, Inc.
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors:
+ * Carl D. Worth <cworth@cworth.org>
+ * Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+#define TEXT_SIZE 12
+#define SIZE 60 /* needs to be big to check large area effects (dithering) */
+#define PAD 2
+
+#define TT_SIZE 100
+#define TT_PAD 5
+#define TT_FONT_SIZE 32.0
+
+#define GENERATE_REF 0
+
+static uint32_t data[16] = {
+ 0xffffffff, 0xffffffff, 0xffff0000, 0xffff0000,
+ 0xffffffff, 0xffffffff, 0xffff0000, 0xffff0000,
+
+ 0xff00ff00, 0xff00ff00, 0xff0000ff, 0xff0000ff,
+ 0xff00ff00, 0xff00ff00, 0xff0000ff, 0xff0000ff
+};
+
+static const char *png_filename = "romedalen.png";
+
+static cairo_t *
+paint (cairo_t *cr)
+{
+ cairo_set_source_rgb (cr, 0, 0, 1);
+ cairo_paint (cr);
+
+ cairo_translate (cr, 2, 2);
+ cairo_scale (cr, 0.5, 0.5);
+
+ cairo_set_source_rgb (cr, 1, 0, 0);
+ cairo_paint (cr);
+
+ return cr;
+}
+
+static cairo_t *
+paint_alpha (cairo_t *cr)
+{
+ cairo_surface_t *surface;
+
+ surface = cairo_image_surface_create_for_data ((unsigned char *) data,
+ CAIRO_FORMAT_RGB24, 4, 4, 16);
+
+ cairo_test_paint_checkered (cr);
+
+ cairo_scale (cr, 4, 4);
+
+ cairo_set_source_surface (cr, surface, 2 , 2);
+ cairo_pattern_set_filter (cairo_get_source (cr), CAIRO_FILTER_NEAREST);
+ cairo_paint_with_alpha (cr, 0.5);
+
+ cairo_surface_finish (surface); /* data will go out of scope */
+ cairo_surface_destroy (surface);
+
+ return cr;
+}
+
+static cairo_t *
+paint_alpha_solid_clip (cairo_t *cr)
+{
+ cairo_test_paint_checkered (cr);
+
+ cairo_rectangle (cr, 2.5, 2.5, 27, 27);
+ cairo_clip (cr);
+
+ cairo_set_source_rgb (cr, 1., 0.,0.);
+ cairo_paint_with_alpha (cr, 0.5);
+
+ return cr;
+}
+
+static cairo_t *
+paint_alpha_clip (cairo_t *cr)
+{
+ cairo_surface_t *surface;
+
+ surface = cairo_image_surface_create_for_data ((unsigned char *) data,
+ CAIRO_FORMAT_RGB24, 4, 4, 16);
+
+ cairo_test_paint_checkered (cr);
+
+ cairo_rectangle (cr, 10.5, 10.5, 11, 11);
+ cairo_clip (cr);
+
+ cairo_scale (cr, 4, 4);
+
+ cairo_set_source_surface (cr, surface, 2 , 2);
+ cairo_pattern_set_filter (cairo_get_source (cr), CAIRO_FILTER_NEAREST);
+ cairo_paint_with_alpha (cr, 0.5);
+
+ cairo_surface_finish (surface); /* data will go out of scope */
+ cairo_surface_destroy (surface);
+
+ return cr;
+}
+
+static cairo_t *
+paint_alpha_clip_mask (cairo_t *cr)
+{
+ cairo_surface_t *surface;
+
+ surface = cairo_image_surface_create_for_data ((unsigned char *) data,
+ CAIRO_FORMAT_RGB24, 4, 4, 16);
+
+ cairo_test_paint_checkered (cr);
+
+ cairo_move_to (cr, 16, 5);
+ cairo_line_to (cr, 5, 16);
+ cairo_line_to (cr, 16, 27);
+ cairo_line_to (cr, 27, 16);
+ cairo_clip (cr);
+
+ cairo_scale (cr, 4, 4);
+
+ cairo_set_source_surface (cr, surface, 2 , 2);
+ cairo_pattern_set_filter (cairo_get_source (cr), CAIRO_FILTER_NEAREST);
+ cairo_paint_with_alpha (cr, 0.5);
+
+ cairo_surface_finish (surface); /* data will go out of scope */
+ cairo_surface_destroy (surface);
+
+ return cr;
+}
+
+static cairo_t *
+select_font_face (cairo_t *cr)
+{
+ /* We draw in the default black, so paint white first. */
+ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */
+ cairo_paint (cr);
+
+ cairo_set_source_rgb (cr, 0, 0, 0); /* black */
+
+ cairo_set_font_size (cr, TEXT_SIZE);
+ cairo_move_to (cr, 0, TEXT_SIZE);
+
+ cairo_select_font_face (cr, CAIRO_TEST_FONT_FAMILY " Serif",
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_NORMAL);
+ cairo_show_text (cr, "i-am-serif");
+
+ cairo_select_font_face (cr, CAIRO_TEST_FONT_FAMILY " Sans",
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_NORMAL);
+ cairo_show_text (cr, " i-am-sans");
+
+ cairo_select_font_face (cr, CAIRO_TEST_FONT_FAMILY " Sans Mono",
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_NORMAL);
+ cairo_show_text (cr, " i-am-mono");
+
+ return cr;
+}
+
+static cairo_t *
+fill_alpha (cairo_t *cr)
+{
+ const double alpha = 1./3;
+ int n;
+
+ /* flatten to white */
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+ /* square */
+ cairo_rectangle (cr, PAD, PAD, SIZE, SIZE);
+ cairo_set_source_rgba (cr, 1, 0, 0, alpha);
+ cairo_fill (cr);
+
+ /* circle */
+ cairo_translate (cr, SIZE + 2 * PAD, 0);
+ cairo_arc (cr, PAD + SIZE / 2., PAD + SIZE / 2., SIZE / 2., 0, 2 * M_PI);
+ cairo_set_source_rgba (cr, 0, 1, 0, alpha);
+ cairo_fill (cr);
+
+ /* triangle */
+ cairo_translate (cr, 0, SIZE + 2 * PAD);
+ cairo_move_to (cr, PAD + SIZE / 2, PAD);
+ cairo_line_to (cr, PAD + SIZE, PAD + SIZE);
+ cairo_line_to (cr, PAD, PAD + SIZE);
+ cairo_set_source_rgba (cr, 0, 0, 1, alpha);
+ cairo_fill (cr);
+
+ /* star */
+ cairo_translate (cr, -(SIZE + 2 * PAD) + SIZE/2., SIZE/2.);
+ for (n = 0; n < 5; n++) {
+ cairo_line_to (cr,
+ SIZE/2 * cos (2*n * 2*M_PI / 10),
+ SIZE/2 * sin (2*n * 2*M_PI / 10));
+
+ cairo_line_to (cr,
+ SIZE/4 * cos ((2*n+1)*2*M_PI / 10),
+ SIZE/4 * sin ((2*n+1)*2*M_PI / 10));
+ }
+ cairo_set_source_rgba (cr, 0, 0, 0, alpha);
+ cairo_fill (cr);
+
+ return cr;
+}
+
+static cairo_t *
+self_intersecting (cairo_t *cr)
+{
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+ cairo_translate (cr, 1.0, 1.0);
+
+ cairo_set_source_rgb (cr, 1, 0, 0); /* red */
+
+ /* First draw the desired shape with a fill */
+ cairo_rectangle (cr, 0.5, 0.5, 4.0, 4.0);
+ cairo_rectangle (cr, 3.5, 3.5, 4.0, 4.0);
+ cairo_rectangle (cr, 3.5, 1.5, -2.0, 2.0);
+ cairo_rectangle (cr, 6.5, 4.5, -2.0, 2.0);
+
+ cairo_fill (cr);
+
+ /* Then try the same thing with a stroke */
+ cairo_translate (cr, 0, 10);
+ cairo_move_to (cr, 1.0, 1.0);
+ cairo_rel_line_to (cr, 3.0, 0.0);
+ cairo_rel_line_to (cr, 0.0, 6.0);
+ cairo_rel_line_to (cr, 3.0, 0.0);
+ cairo_rel_line_to (cr, 0.0, -3.0);
+ cairo_rel_line_to (cr, -6.0, 0.0);
+ cairo_close_path (cr);
+
+ cairo_set_line_width (cr, 1.0);
+ cairo_stroke (cr);
+
+ return cr;
+}
+
+static void
+draw_text_transform (cairo_t *cr)
+{
+ cairo_matrix_t tm;
+
+ /* skew */
+ cairo_matrix_init (&tm, 1, 0,
+ -0.25, 1,
+ 0, 0);
+ cairo_matrix_scale (&tm, TT_FONT_SIZE, TT_FONT_SIZE);
+ cairo_set_font_matrix (cr, &tm);
+
+ cairo_new_path (cr);
+ cairo_move_to (cr, 50, TT_SIZE-TT_PAD);
+ cairo_show_text (cr, "A");
+
+ /* rotate and scale */
+ cairo_matrix_init_rotate (&tm, M_PI / 2);
+ cairo_matrix_scale (&tm, TT_FONT_SIZE, TT_FONT_SIZE * 2.0);
+ cairo_set_font_matrix (cr, &tm);
+
+ cairo_new_path (cr);
+ cairo_move_to (cr, TT_PAD, TT_PAD + 25);
+ cairo_show_text (cr, "A");
+
+ cairo_matrix_init_rotate (&tm, M_PI / 2);
+ cairo_matrix_scale (&tm, TT_FONT_SIZE * 2.0, TT_FONT_SIZE);
+ cairo_set_font_matrix (cr, &tm);
+
+ cairo_new_path (cr);
+ cairo_move_to (cr, TT_PAD, TT_PAD + 50);
+ cairo_show_text (cr, "A");
+}
+
+static cairo_t *
+text_transform (cairo_t *cr)
+{
+ const cairo_test_context_t *ctx = cairo_test_get_context (cr);
+ cairo_pattern_t *pattern;
+
+ cairo_set_source_rgb (cr, 1., 1., 1.);
+ cairo_paint (cr);
+
+ cairo_set_source_rgb (cr, 0., 0., 0.);
+
+ cairo_select_font_face (cr, CAIRO_TEST_FONT_FAMILY " Sans",
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_NORMAL);
+
+ draw_text_transform (cr);
+
+ cairo_translate (cr, TT_SIZE, TT_SIZE);
+ cairo_rotate (cr, M_PI);
+
+ pattern = cairo_test_create_pattern_from_png (ctx, png_filename);
+ cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT);
+ cairo_set_source (cr, pattern);
+ cairo_pattern_destroy (pattern);
+
+ draw_text_transform (cr);
+
+ return cr;
+}
+
+/* And here begins the recording and replaying... */
+
+static cairo_t *
+record_create (cairo_t *target)
+{
+ cairo_surface_t *surface;
+ cairo_t *cr;
+
+ surface = cairo_recording_surface_create (cairo_surface_get_content (cairo_get_target (target)), NULL);
+ cr = cairo_create (surface);
+ cairo_surface_destroy (surface);
+
+ return cr;
+}
+
+static cairo_surface_t *
+record_get (cairo_t *target)
+{
+ cairo_surface_t *surface;
+
+ surface = cairo_surface_reference (cairo_get_target (target));
+ cairo_destroy (target);
+
+ return surface;
+}
+
+static cairo_test_status_t
+record_replay (cairo_t *cr, cairo_t *(*func)(cairo_t *), int width, int height)
+{
+ cairo_surface_t *surface;
+ int x, y;
+
+#if GENERATE_REF
+ cairo_scale (cr, 2, 2);
+ func(cr);
+#else
+ surface = record_get (func (record_create (cr)));
+
+ cairo_scale (cr, 2, 2);
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_set_source_surface (cr, surface, 0, 0);
+ cairo_surface_destroy (surface);
+ cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_NONE);
+
+ for (y = 0; y < height; y += 2) {
+ for (x = 0; x < width; x += 2) {
+ cairo_rectangle (cr, x, y, 2, 2);
+ cairo_clip (cr);
+ cairo_paint (cr);
+ cairo_reset_clip (cr);
+ }
+ }
+#endif
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+record_paint (cairo_t *cr, int width, int height)
+{
+ return record_replay (cr, paint, width, height);
+}
+
+static cairo_test_status_t
+record_paint_alpha (cairo_t *cr, int width, int height)
+{
+ return record_replay (cr, paint_alpha, width, height);
+}
+
+static cairo_test_status_t
+record_paint_alpha_solid_clip (cairo_t *cr, int width, int height)
+{
+ return record_replay (cr, paint_alpha_solid_clip, width, height);
+}
+
+static cairo_test_status_t
+record_paint_alpha_clip (cairo_t *cr, int width, int height)
+{
+ return record_replay (cr, paint_alpha_clip, width, height);
+}
+
+static cairo_test_status_t
+record_paint_alpha_clip_mask (cairo_t *cr, int width, int height)
+{
+ return record_replay (cr, paint_alpha_clip_mask, width, height);
+}
+
+static cairo_test_status_t
+record_fill_alpha (cairo_t *cr, int width, int height)
+{
+ return record_replay (cr, fill_alpha, width, height);
+}
+
+static cairo_test_status_t
+record_self_intersecting (cairo_t *cr, int width, int height)
+{
+ return record_replay (cr, self_intersecting, width, height);
+}
+
+static cairo_test_status_t
+record_select_font_face (cairo_t *cr, int width, int height)
+{
+ return record_replay (cr, select_font_face, width, height);
+}
+
+static cairo_test_status_t
+record_text_transform (cairo_t *cr, int width, int height)
+{
+ return record_replay (cr, text_transform, width, height);
+}
+
+CAIRO_TEST (record2x_paint,
+ "Test replayed calls to cairo_paint",
+ "paint,record", /* keywords */
+ NULL, /* requirements */
+ 2*8, 2*8,
+ NULL, record_paint)
+CAIRO_TEST (record2x_paint_alpha,
+ "Simple test of cairo_paint_with_alpha",
+ "record, paint, alpha", /* keywords */
+ NULL, /* requirements */
+ 2*32, 2*32,
+ NULL, record_paint_alpha)
+CAIRO_TEST (record2x_paint_alpha_solid_clip,
+ "Simple test of cairo_paint_with_alpha+unaligned clip",
+ "record, paint, alpha, clip", /* keywords */
+ NULL, /* requirements */
+ 2*32, 2*32,
+ NULL, record_paint_alpha_solid_clip)
+CAIRO_TEST (record2x_paint_alpha_clip,
+ "Simple test of cairo_paint_with_alpha+unaligned clip",
+ "record, paint, alpha, clip", /* keywords */
+ NULL, /* requirements */
+ 2*32, 2*32,
+ NULL, record_paint_alpha_clip)
+CAIRO_TEST (record2x_paint_alpha_clip_mask,
+ "Simple test of cairo_paint_with_alpha+triangular clip",
+ "record, paint, alpha, clip", /* keywords */
+ NULL, /* requirements */
+ 2*32, 2*32,
+ NULL, record_paint_alpha_clip_mask)
+CAIRO_TEST (record2x_fill_alpha,
+ "Tests using set_rgba();fill()",
+ "record,fill, alpha", /* keywords */
+ NULL, /* requirements */
+ 2*(2*SIZE + 4*PAD), 2*(2*SIZE + 4*PAD),
+ NULL, record_fill_alpha)
+CAIRO_TEST (record2x_select_font_face,
+ "Tests using cairo_select_font_face to draw text in different faces",
+ "record, font", /* keywords */
+ NULL, /* requirements */
+ 2*192, 2*(TEXT_SIZE + 4),
+ NULL, record_select_font_face)
+CAIRO_TEST (record2x_self_intersecting,
+ "Test strokes of self-intersecting paths",
+ "record, stroke, trap", /* keywords */
+ NULL, /* requirements */
+ 2*10, 2*20,
+ NULL, record_self_intersecting)
+CAIRO_TEST (record2x_text_transform,
+ "Test various applications of the font matrix",
+ "record, text, transform", /* keywords */
+ NULL, /* requirements */
+ 2*TT_SIZE, 2*TT_SIZE,
+ NULL, record_text_transform)
diff --git a/test/record90.c b/test/record90.c
new file mode 100644
index 000000000..95ba3b1b1
--- /dev/null
+++ b/test/record90.c
@@ -0,0 +1,495 @@
+/*
+ * Copyright © 2005 Red Hat, Inc.
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors:
+ * Carl D. Worth <cworth@cworth.org>
+ * Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+#define TEXT_SIZE 12
+#define SIZE 60 /* needs to be big to check large area effects (dithering) */
+#define PAD 2
+
+#define TT_SIZE 100
+#define TT_PAD 5
+#define TT_FONT_SIZE 32.0
+
+#define GENERATE_REF 0
+
+static uint32_t data[16] = {
+ 0xffffffff, 0xffffffff, 0xffff0000, 0xffff0000,
+ 0xffffffff, 0xffffffff, 0xffff0000, 0xffff0000,
+
+ 0xff00ff00, 0xff00ff00, 0xff0000ff, 0xff0000ff,
+ 0xff00ff00, 0xff00ff00, 0xff0000ff, 0xff0000ff
+};
+
+static const char *png_filename = "romedalen.png";
+
+static cairo_t *
+paint (cairo_t *cr)
+{
+ cairo_set_source_rgb (cr, 0, 0, 1);
+ cairo_paint (cr);
+
+ cairo_translate (cr, 2, 2);
+ cairo_scale (cr, 0.5, 0.5);
+
+ cairo_set_source_rgb (cr, 1, 0, 0);
+ cairo_paint (cr);
+
+ return cr;
+}
+
+static cairo_t *
+paint_alpha (cairo_t *cr)
+{
+ cairo_surface_t *surface;
+
+ surface = cairo_image_surface_create_for_data ((unsigned char *) data,
+ CAIRO_FORMAT_RGB24, 4, 4, 16);
+
+ cairo_test_paint_checkered (cr);
+
+ cairo_scale (cr, 4, 4);
+
+ cairo_set_source_surface (cr, surface, 2 , 2);
+ cairo_pattern_set_filter (cairo_get_source (cr), CAIRO_FILTER_NEAREST);
+ cairo_paint_with_alpha (cr, 0.5);
+
+ cairo_surface_finish (surface); /* data will go out of scope */
+ cairo_surface_destroy (surface);
+
+ return cr;
+}
+
+static cairo_t *
+paint_alpha_solid_clip (cairo_t *cr)
+{
+ cairo_test_paint_checkered (cr);
+
+ cairo_rectangle (cr, 2.5, 2.5, 27, 27);
+ cairo_clip (cr);
+
+ cairo_set_source_rgb (cr, 1., 0.,0.);
+ cairo_paint_with_alpha (cr, 0.5);
+
+ return cr;
+}
+
+static cairo_t *
+paint_alpha_clip (cairo_t *cr)
+{
+ cairo_surface_t *surface;
+
+ surface = cairo_image_surface_create_for_data ((unsigned char *) data,
+ CAIRO_FORMAT_RGB24, 4, 4, 16);
+
+ cairo_test_paint_checkered (cr);
+
+ cairo_rectangle (cr, 10.5, 10.5, 11, 11);
+ cairo_clip (cr);
+
+ cairo_scale (cr, 4, 4);
+
+ cairo_set_source_surface (cr, surface, 2 , 2);
+ cairo_pattern_set_filter (cairo_get_source (cr), CAIRO_FILTER_NEAREST);
+ cairo_paint_with_alpha (cr, 0.5);
+
+ cairo_surface_finish (surface); /* data will go out of scope */
+ cairo_surface_destroy (surface);
+
+ return cr;
+}
+
+static cairo_t *
+paint_alpha_clip_mask (cairo_t *cr)
+{
+ cairo_surface_t *surface;
+
+ surface = cairo_image_surface_create_for_data ((unsigned char *) data,
+ CAIRO_FORMAT_RGB24, 4, 4, 16);
+
+ cairo_test_paint_checkered (cr);
+
+ cairo_move_to (cr, 16, 5);
+ cairo_line_to (cr, 5, 16);
+ cairo_line_to (cr, 16, 27);
+ cairo_line_to (cr, 27, 16);
+ cairo_clip (cr);
+
+ cairo_scale (cr, 4, 4);
+
+ cairo_set_source_surface (cr, surface, 2 , 2);
+ cairo_pattern_set_filter (cairo_get_source (cr), CAIRO_FILTER_NEAREST);
+ cairo_paint_with_alpha (cr, 0.5);
+
+ cairo_surface_finish (surface); /* data will go out of scope */
+ cairo_surface_destroy (surface);
+
+ return cr;
+}
+
+static cairo_t *
+select_font_face (cairo_t *cr)
+{
+ /* We draw in the default black, so paint white first. */
+ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */
+ cairo_paint (cr);
+
+ cairo_set_source_rgb (cr, 0, 0, 0); /* black */
+
+ cairo_set_font_size (cr, TEXT_SIZE);
+ cairo_move_to (cr, 0, TEXT_SIZE);
+
+ cairo_select_font_face (cr, CAIRO_TEST_FONT_FAMILY " Serif",
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_NORMAL);
+ cairo_show_text (cr, "i-am-serif");
+
+ cairo_select_font_face (cr, CAIRO_TEST_FONT_FAMILY " Sans",
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_NORMAL);
+ cairo_show_text (cr, " i-am-sans");
+
+ cairo_select_font_face (cr, CAIRO_TEST_FONT_FAMILY " Sans Mono",
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_NORMAL);
+ cairo_show_text (cr, " i-am-mono");
+
+ return cr;
+}
+
+static cairo_t *
+fill_alpha (cairo_t *cr)
+{
+ const double alpha = 1./3;
+ int n;
+
+ /* flatten to white */
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+ /* square */
+ cairo_rectangle (cr, PAD, PAD, SIZE, SIZE);
+ cairo_set_source_rgba (cr, 1, 0, 0, alpha);
+ cairo_fill (cr);
+
+ /* circle */
+ cairo_translate (cr, SIZE + 2 * PAD, 0);
+ cairo_arc (cr, PAD + SIZE / 2., PAD + SIZE / 2., SIZE / 2., 0, 2 * M_PI);
+ cairo_set_source_rgba (cr, 0, 1, 0, alpha);
+ cairo_fill (cr);
+
+ /* triangle */
+ cairo_translate (cr, 0, SIZE + 2 * PAD);
+ cairo_move_to (cr, PAD + SIZE / 2, PAD);
+ cairo_line_to (cr, PAD + SIZE, PAD + SIZE);
+ cairo_line_to (cr, PAD, PAD + SIZE);
+ cairo_set_source_rgba (cr, 0, 0, 1, alpha);
+ cairo_fill (cr);
+
+ /* star */
+ cairo_translate (cr, -(SIZE + 2 * PAD) + SIZE/2., SIZE/2.);
+ for (n = 0; n < 5; n++) {
+ cairo_line_to (cr,
+ SIZE/2 * cos (2*n * 2*M_PI / 10),
+ SIZE/2 * sin (2*n * 2*M_PI / 10));
+
+ cairo_line_to (cr,
+ SIZE/4 * cos ((2*n+1)*2*M_PI / 10),
+ SIZE/4 * sin ((2*n+1)*2*M_PI / 10));
+ }
+ cairo_set_source_rgba (cr, 0, 0, 0, alpha);
+ cairo_fill (cr);
+
+ return cr;
+}
+
+static cairo_t *
+self_intersecting (cairo_t *cr)
+{
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+ cairo_translate (cr, 1.0, 1.0);
+
+ cairo_set_source_rgb (cr, 1, 0, 0); /* red */
+
+ /* First draw the desired shape with a fill */
+ cairo_rectangle (cr, 0.5, 0.5, 4.0, 4.0);
+ cairo_rectangle (cr, 3.5, 3.5, 4.0, 4.0);
+ cairo_rectangle (cr, 3.5, 1.5, -2.0, 2.0);
+ cairo_rectangle (cr, 6.5, 4.5, -2.0, 2.0);
+
+ cairo_fill (cr);
+
+ /* Then try the same thing with a stroke */
+ cairo_translate (cr, 0, 10);
+ cairo_move_to (cr, 1.0, 1.0);
+ cairo_rel_line_to (cr, 3.0, 0.0);
+ cairo_rel_line_to (cr, 0.0, 6.0);
+ cairo_rel_line_to (cr, 3.0, 0.0);
+ cairo_rel_line_to (cr, 0.0, -3.0);
+ cairo_rel_line_to (cr, -6.0, 0.0);
+ cairo_close_path (cr);
+
+ cairo_set_line_width (cr, 1.0);
+ cairo_stroke (cr);
+
+ return cr;
+}
+
+static void
+draw_text_transform (cairo_t *cr)
+{
+ cairo_matrix_t tm;
+
+ /* skew */
+ cairo_matrix_init (&tm, 1, 0,
+ -0.25, 1,
+ 0, 0);
+ cairo_matrix_scale (&tm, TT_FONT_SIZE, TT_FONT_SIZE);
+ cairo_set_font_matrix (cr, &tm);
+
+ cairo_new_path (cr);
+ cairo_move_to (cr, 50, TT_SIZE-TT_PAD);
+ cairo_show_text (cr, "A");
+
+ /* rotate and scale */
+ cairo_matrix_init_rotate (&tm, M_PI / 2);
+ cairo_matrix_scale (&tm, TT_FONT_SIZE, TT_FONT_SIZE * 2.0);
+ cairo_set_font_matrix (cr, &tm);
+
+ cairo_new_path (cr);
+ cairo_move_to (cr, TT_PAD, TT_PAD + 25);
+ cairo_show_text (cr, "A");
+
+ cairo_matrix_init_rotate (&tm, M_PI / 2);
+ cairo_matrix_scale (&tm, TT_FONT_SIZE * 2.0, TT_FONT_SIZE);
+ cairo_set_font_matrix (cr, &tm);
+
+ cairo_new_path (cr);
+ cairo_move_to (cr, TT_PAD, TT_PAD + 50);
+ cairo_show_text (cr, "A");
+}
+
+static cairo_t *
+text_transform (cairo_t *cr)
+{
+ const cairo_test_context_t *ctx = cairo_test_get_context (cr);
+ cairo_pattern_t *pattern;
+
+ cairo_set_source_rgb (cr, 1., 1., 1.);
+ cairo_paint (cr);
+
+ cairo_set_source_rgb (cr, 0., 0., 0.);
+
+ cairo_select_font_face (cr, CAIRO_TEST_FONT_FAMILY " Sans",
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_NORMAL);
+
+ draw_text_transform (cr);
+
+ cairo_translate (cr, TT_SIZE, TT_SIZE);
+ cairo_rotate (cr, M_PI);
+
+ pattern = cairo_test_create_pattern_from_png (ctx, png_filename);
+ cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT);
+ cairo_set_source (cr, pattern);
+ cairo_pattern_destroy (pattern);
+
+ draw_text_transform (cr);
+
+ return cr;
+}
+
+/* And here begins the recording and replaying... */
+
+static cairo_t *
+record_create (cairo_t *target)
+{
+ cairo_surface_t *surface;
+ cairo_t *cr;
+
+ surface = cairo_recording_surface_create (cairo_surface_get_content (cairo_get_target (target)), NULL);
+ cr = cairo_create (surface);
+ cairo_surface_destroy (surface);
+
+ return cr;
+}
+
+static cairo_surface_t *
+record_get (cairo_t *target)
+{
+ cairo_surface_t *surface;
+
+ surface = cairo_surface_reference (cairo_get_target (target));
+ cairo_destroy (target);
+
+ return surface;
+}
+
+static cairo_test_status_t
+record_replay (cairo_t *cr, cairo_t *(*func)(cairo_t *), int width, int height)
+{
+ cairo_surface_t *surface;
+ int x, y;
+
+#if GENERATE_REF
+ cairo_translate(cr, width, 0);
+ cairo_rotate (cr, M_PI/2);
+ func(cr);
+#else
+ surface = record_get (func (record_create (cr)));
+
+ cairo_translate(cr, width, 0);
+ cairo_rotate (cr, M_PI/2);
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_set_source_surface (cr, surface, 0, 0);
+ cairo_surface_destroy (surface);
+ cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_NONE);
+
+ for (y = 0; y < width; y += 2) {
+ for (x = 0; x < height; x += 2) {
+ cairo_rectangle (cr, x, y, 2, 2);
+ cairo_clip (cr);
+ cairo_paint (cr);
+ cairo_reset_clip (cr);
+ }
+ }
+#endif
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+record_paint (cairo_t *cr, int width, int height)
+{
+ return record_replay (cr, paint, width, height);
+}
+
+static cairo_test_status_t
+record_paint_alpha (cairo_t *cr, int width, int height)
+{
+ return record_replay (cr, paint_alpha, width, height);
+}
+
+static cairo_test_status_t
+record_paint_alpha_solid_clip (cairo_t *cr, int width, int height)
+{
+ return record_replay (cr, paint_alpha_solid_clip, width, height);
+}
+
+static cairo_test_status_t
+record_paint_alpha_clip (cairo_t *cr, int width, int height)
+{
+ return record_replay (cr, paint_alpha_clip, width, height);
+}
+
+static cairo_test_status_t
+record_paint_alpha_clip_mask (cairo_t *cr, int width, int height)
+{
+ return record_replay (cr, paint_alpha_clip_mask, width, height);
+}
+
+static cairo_test_status_t
+record_fill_alpha (cairo_t *cr, int width, int height)
+{
+ return record_replay (cr, fill_alpha, width, height);
+}
+
+static cairo_test_status_t
+record_self_intersecting (cairo_t *cr, int width, int height)
+{
+ return record_replay (cr, self_intersecting, width, height);
+}
+
+static cairo_test_status_t
+record_select_font_face (cairo_t *cr, int width, int height)
+{
+ return record_replay (cr, select_font_face, width, height);
+}
+
+static cairo_test_status_t
+record_text_transform (cairo_t *cr, int width, int height)
+{
+ return record_replay (cr, text_transform, width, height);
+}
+
+CAIRO_TEST (record90_paint,
+ "Test replayed calls to cairo_paint",
+ "paint,record", /* keywords */
+ NULL, /* requirements */
+ 8, 8,
+ NULL, record_paint)
+CAIRO_TEST (record90_paint_alpha,
+ "Simple test of cairo_paint_with_alpha",
+ "record, paint, alpha", /* keywords */
+ NULL, /* requirements */
+ 2, 32,
+ NULL, record_paint_alpha)
+CAIRO_TEST (record90_paint_alpha_solid_clip,
+ "Simple test of cairo_paint_with_alpha+unaligned clip",
+ "record, paint, alpha, clip", /* keywords */
+ NULL, /* requirements */
+ 32, 32,
+ NULL, record_paint_alpha_solid_clip)
+CAIRO_TEST (record90_paint_alpha_clip,
+ "Simple test of cairo_paint_with_alpha+unaligned clip",
+ "record, paint, alpha, clip", /* keywords */
+ NULL, /* requirements */
+ 32, 32,
+ NULL, record_paint_alpha_clip)
+CAIRO_TEST (record90_paint_alpha_clip_mask,
+ "Simple test of cairo_paint_with_alpha+triangular clip",
+ "record, paint, alpha, clip", /* keywords */
+ NULL, /* requirements */
+ 32, 32,
+ NULL, record_paint_alpha_clip_mask)
+CAIRO_TEST (record90_fill_alpha,
+ "Tests using set_rgba();fill()",
+ "record,fill, alpha", /* keywords */
+ NULL, /* requirements */
+ 2*SIZE + 4*PAD, 2*SIZE + 4*PAD,
+ NULL, record_fill_alpha)
+CAIRO_TEST (record90_select_font_face,
+ "Tests using cairo_select_font_face to draw text in different faces",
+ "record, font", /* keywords */
+ NULL, /* requirements */
+ TEXT_SIZE + 4, 192,
+ NULL, record_select_font_face)
+CAIRO_TEST (record90_self_intersecting,
+ "Test strokes of self-intersecting paths",
+ "record, stroke, trap", /* keywords */
+ NULL, /* requirements */
+ 20, 10,
+ NULL, record_self_intersecting)
+CAIRO_TEST (record90_text_transform,
+ "Test various applications of the font matrix",
+ "record, text, transform", /* keywords */
+ NULL, /* requirements */
+ TT_SIZE, TT_SIZE,
+ NULL, record_text_transform)
diff --git a/test/recordflip.c b/test/recordflip.c
new file mode 100644
index 000000000..e923c8a2a
--- /dev/null
+++ b/test/recordflip.c
@@ -0,0 +1,733 @@
+/*
+ * Copyright © 2011,2013 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+#define TEXT_SIZE 12
+#define SIZE 60 /* needs to be big to check large area effects (dithering) */
+#define PAD 2
+
+#define TT_SIZE 100
+#define TT_PAD 5
+#define TT_FONT_SIZE 32.0
+
+#define GENERATE_REF 0
+
+static uint32_t data[16] = {
+ 0xffffffff, 0xffffffff, 0xffff0000, 0xffff0000,
+ 0xffffffff, 0xffffffff, 0xffff0000, 0xffff0000,
+
+ 0xff00ff00, 0xff00ff00, 0xff0000ff, 0xff0000ff,
+ 0xff00ff00, 0xff00ff00, 0xff0000ff, 0xff0000ff
+};
+
+static const char *png_filename = "romedalen.png";
+
+static cairo_t *
+paint (cairo_t *cr)
+{
+ cairo_set_source_rgb (cr, 0, 0, 1);
+ cairo_paint (cr);
+
+ cairo_translate (cr, 2, 2);
+ cairo_scale (cr, 0.5, 0.5);
+
+ cairo_set_source_rgb (cr, 1, 0, 0);
+ cairo_paint (cr);
+
+ return cr;
+}
+
+static cairo_t *
+paint_alpha (cairo_t *cr)
+{
+ cairo_surface_t *surface;
+
+ surface = cairo_image_surface_create_for_data ((unsigned char *) data,
+ CAIRO_FORMAT_RGB24, 4, 4, 16);
+
+ cairo_test_paint_checkered (cr);
+
+ cairo_scale (cr, 4, 4);
+
+ cairo_set_source_surface (cr, surface, 2 , 2);
+ cairo_pattern_set_filter (cairo_get_source (cr), CAIRO_FILTER_NEAREST);
+ cairo_paint_with_alpha (cr, 0.5);
+
+ cairo_surface_finish (surface); /* data will go out of scope */
+ cairo_surface_destroy (surface);
+
+ return cr;
+}
+
+static cairo_t *
+paint_alpha_solid_clip (cairo_t *cr)
+{
+ cairo_test_paint_checkered (cr);
+
+ cairo_rectangle (cr, 2.5, 2.5, 27, 27);
+ cairo_clip (cr);
+
+ cairo_set_source_rgb (cr, 1., 0.,0.);
+ cairo_paint_with_alpha (cr, 0.5);
+
+ return cr;
+}
+
+static cairo_t *
+paint_alpha_clip (cairo_t *cr)
+{
+ cairo_surface_t *surface;
+
+ surface = cairo_image_surface_create_for_data ((unsigned char *) data,
+ CAIRO_FORMAT_RGB24, 4, 4, 16);
+
+ cairo_test_paint_checkered (cr);
+
+ cairo_rectangle (cr, 10.5, 10.5, 11, 11);
+ cairo_clip (cr);
+
+ cairo_scale (cr, 4, 4);
+
+ cairo_set_source_surface (cr, surface, 2 , 2);
+ cairo_pattern_set_filter (cairo_get_source (cr), CAIRO_FILTER_NEAREST);
+ cairo_paint_with_alpha (cr, 0.5);
+
+ cairo_surface_finish (surface); /* data will go out of scope */
+ cairo_surface_destroy (surface);
+
+ return cr;
+}
+
+static cairo_t *
+paint_alpha_clip_mask (cairo_t *cr)
+{
+ cairo_surface_t *surface;
+
+ surface = cairo_image_surface_create_for_data ((unsigned char *) data,
+ CAIRO_FORMAT_RGB24, 4, 4, 16);
+
+ cairo_test_paint_checkered (cr);
+
+ cairo_move_to (cr, 16, 5);
+ cairo_line_to (cr, 5, 16);
+ cairo_line_to (cr, 16, 27);
+ cairo_line_to (cr, 27, 16);
+ cairo_clip (cr);
+
+ cairo_scale (cr, 4, 4);
+
+ cairo_set_source_surface (cr, surface, 2 , 2);
+ cairo_pattern_set_filter (cairo_get_source (cr), CAIRO_FILTER_NEAREST);
+ cairo_paint_with_alpha (cr, 0.5);
+
+ cairo_surface_finish (surface); /* data will go out of scope */
+ cairo_surface_destroy (surface);
+
+ return cr;
+}
+
+static cairo_t *
+select_font_face (cairo_t *cr)
+{
+ /* We draw in the default black, so paint white first. */
+ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */
+ cairo_paint (cr);
+
+ cairo_set_source_rgb (cr, 0, 0, 0); /* black */
+
+ cairo_set_font_size (cr, TEXT_SIZE);
+ cairo_move_to (cr, 0, TEXT_SIZE);
+
+ cairo_select_font_face (cr, CAIRO_TEST_FONT_FAMILY " Serif",
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_NORMAL);
+ cairo_show_text (cr, "i-am-serif");
+
+ cairo_select_font_face (cr, CAIRO_TEST_FONT_FAMILY " Sans",
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_NORMAL);
+ cairo_show_text (cr, " i-am-sans");
+
+ cairo_select_font_face (cr, CAIRO_TEST_FONT_FAMILY " Sans Mono",
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_NORMAL);
+ cairo_show_text (cr, " i-am-mono");
+
+ return cr;
+}
+
+static cairo_t *
+fill_alpha (cairo_t *cr)
+{
+ const double alpha = 1./3;
+ int n;
+
+ /* flatten to white */
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+ /* square */
+ cairo_rectangle (cr, PAD, PAD, SIZE, SIZE);
+ cairo_set_source_rgba (cr, 1, 0, 0, alpha);
+ cairo_fill (cr);
+
+ /* circle */
+ cairo_translate (cr, SIZE + 2 * PAD, 0);
+ cairo_arc (cr, PAD + SIZE / 2., PAD + SIZE / 2., SIZE / 2., 0, 2 * M_PI);
+ cairo_set_source_rgba (cr, 0, 1, 0, alpha);
+ cairo_fill (cr);
+
+ /* triangle */
+ cairo_translate (cr, 0, SIZE + 2 * PAD);
+ cairo_move_to (cr, PAD + SIZE / 2, PAD);
+ cairo_line_to (cr, PAD + SIZE, PAD + SIZE);
+ cairo_line_to (cr, PAD, PAD + SIZE);
+ cairo_set_source_rgba (cr, 0, 0, 1, alpha);
+ cairo_fill (cr);
+
+ /* star */
+ cairo_translate (cr, -(SIZE + 2 * PAD) + SIZE/2., SIZE/2.);
+ for (n = 0; n < 5; n++) {
+ cairo_line_to (cr,
+ SIZE/2 * cos (2*n * 2*M_PI / 10),
+ SIZE/2 * sin (2*n * 2*M_PI / 10));
+
+ cairo_line_to (cr,
+ SIZE/4 * cos ((2*n+1)*2*M_PI / 10),
+ SIZE/4 * sin ((2*n+1)*2*M_PI / 10));
+ }
+ cairo_set_source_rgba (cr, 0, 0, 0, alpha);
+ cairo_fill (cr);
+
+ return cr;
+}
+
+static cairo_t *
+self_intersecting (cairo_t *cr)
+{
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+ cairo_translate (cr, 1.0, 1.0);
+
+ cairo_set_source_rgb (cr, 1, 0, 0); /* red */
+
+ /* First draw the desired shape with a fill */
+ cairo_rectangle (cr, 0.5, 0.5, 4.0, 4.0);
+ cairo_rectangle (cr, 3.5, 3.5, 4.0, 4.0);
+ cairo_rectangle (cr, 3.5, 1.5, -2.0, 2.0);
+ cairo_rectangle (cr, 6.5, 4.5, -2.0, 2.0);
+
+ cairo_fill (cr);
+
+ /* Then try the same thing with a stroke */
+ cairo_translate (cr, 0, 10);
+ cairo_move_to (cr, 1.0, 1.0);
+ cairo_rel_line_to (cr, 3.0, 0.0);
+ cairo_rel_line_to (cr, 0.0, 6.0);
+ cairo_rel_line_to (cr, 3.0, 0.0);
+ cairo_rel_line_to (cr, 0.0, -3.0);
+ cairo_rel_line_to (cr, -6.0, 0.0);
+ cairo_close_path (cr);
+
+ cairo_set_line_width (cr, 1.0);
+ cairo_stroke (cr);
+
+ return cr;
+}
+
+static void
+draw_text_transform (cairo_t *cr)
+{
+ cairo_matrix_t tm;
+
+ /* skew */
+ cairo_matrix_init (&tm, 1, 0,
+ -0.25, 1,
+ 0, 0);
+ cairo_matrix_scale (&tm, TT_FONT_SIZE, TT_FONT_SIZE);
+ cairo_set_font_matrix (cr, &tm);
+
+ cairo_new_path (cr);
+ cairo_move_to (cr, 50, TT_SIZE-TT_PAD);
+ cairo_show_text (cr, "A");
+
+ /* rotate and scale */
+ cairo_matrix_init_rotate (&tm, M_PI / 2);
+ cairo_matrix_scale (&tm, TT_FONT_SIZE, TT_FONT_SIZE * 2.0);
+ cairo_set_font_matrix (cr, &tm);
+
+ cairo_new_path (cr);
+ cairo_move_to (cr, TT_PAD, TT_PAD + 25);
+ cairo_show_text (cr, "A");
+
+ cairo_matrix_init_rotate (&tm, M_PI / 2);
+ cairo_matrix_scale (&tm, TT_FONT_SIZE * 2.0, TT_FONT_SIZE);
+ cairo_set_font_matrix (cr, &tm);
+
+ cairo_new_path (cr);
+ cairo_move_to (cr, TT_PAD, TT_PAD + 50);
+ cairo_show_text (cr, "A");
+}
+
+static cairo_t *
+text_transform (cairo_t *cr)
+{
+ const cairo_test_context_t *ctx = cairo_test_get_context (cr);
+ cairo_pattern_t *pattern;
+
+ cairo_set_source_rgb (cr, 1., 1., 1.);
+ cairo_paint (cr);
+
+ cairo_set_source_rgb (cr, 0., 0., 0.);
+
+ cairo_select_font_face (cr, CAIRO_TEST_FONT_FAMILY " Sans",
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_NORMAL);
+
+ draw_text_transform (cr);
+
+ cairo_translate (cr, TT_SIZE, TT_SIZE);
+ cairo_rotate (cr, M_PI);
+
+ pattern = cairo_test_create_pattern_from_png (ctx, png_filename);
+ cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT);
+ cairo_set_source (cr, pattern);
+ cairo_pattern_destroy (pattern);
+
+ draw_text_transform (cr);
+
+ return cr;
+}
+
+/* And here begins the recording and replaying... */
+
+static cairo_t *
+record_create (cairo_t *target)
+{
+ cairo_surface_t *surface;
+ cairo_t *cr;
+
+ surface = cairo_recording_surface_create (cairo_surface_get_content (cairo_get_target (target)), NULL);
+ cr = cairo_create (surface);
+ cairo_surface_destroy (surface);
+
+ return cr;
+}
+
+static cairo_surface_t *
+record_get (cairo_t *target)
+{
+ cairo_surface_t *surface;
+
+ surface = cairo_surface_reference (cairo_get_target (target));
+ cairo_destroy (target);
+
+ return surface;
+}
+
+static cairo_test_status_t
+record_replay (cairo_t *cr, cairo_t *(*func)(cairo_t *), int width, int height)
+{
+ cairo_surface_t *surface;
+ int x, y;
+
+#if GENERATE_REF
+ {
+ cairo_surface_t *image;
+ uint8_t *data, *tmp;
+ int stride, bpp;
+
+ surface = cairo_get_target (cr);
+
+ func(cr);
+
+ image = cairo_surface_map_to_image (surface, NULL);
+
+ switch (cairo_image_surface_get_format (image)) {
+ case CAIRO_FORMAT_ARGB32:
+ case CAIRO_FORMAT_RGB24:
+ case CAIRO_FORMAT_RGB30:
+ bpp=4;
+ break;
+ case CAIRO_FORMAT_RGB16_565:
+ bpp=2;
+ break;
+ case CAIRO_FORMAT_A8:
+ bpp=1;
+ break;
+ case CAIRO_FORMAT_A1:
+ case CAIRO_FORMAT_INVALID:
+ default:
+ return CAIRO_TEST_FAILURE;
+ }
+
+ data = cairo_image_surface_get_data (image);
+ stride = cairo_image_surface_get_stride (image);
+
+ tmp = malloc (stride);
+ if (tmp == NULL)
+ return CAIRO_TEST_FAILURE;
+
+ for (y = 0; y < height; y++) {
+ uint8_t *row = data + y * stride;
+ for (x = 0; x < width/2; x++) {
+ memcpy (tmp, row + bpp * x, bpp);
+ memcpy (row + bpp * x, row + bpp * (width - x - 1), bpp);
+ memcpy (row + bpp * (width - x - 1), tmp, bpp);
+ }
+ }
+
+ for (y = 0; y < height/2; y++) {
+ memcpy (tmp, data + y * stride, stride);
+ memcpy (data + y * stride, data + (height - y - 1) * stride, stride);
+ memcpy (data + (height - y - 1) * stride, tmp, stride);
+ }
+
+ free (tmp);
+
+ cairo_surface_unmap_image (surface, image);
+ }
+#else
+ surface = record_get (func (record_create (cr)));
+
+ cairo_scale (cr, -1, -1);
+ cairo_translate (cr, -width, -height);
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_set_source_surface (cr, surface, 0, 0);
+ cairo_surface_destroy (surface);
+ cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_NONE);
+
+ for (y = 0; y < height; y += 2) {
+ for (x = 0; x < width; x += 2) {
+ cairo_rectangle (cr, x, y, 2, 2);
+ cairo_clip (cr);
+ cairo_paint (cr);
+ cairo_reset_clip (cr);
+ }
+ }
+#endif
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+record_whole_replay (cairo_t *cr, cairo_t *(*func)(cairo_t *), int width, int height)
+{
+ cairo_surface_t *surface;
+
+#if GENERATE_REF
+ {
+ cairo_surface_t *image;
+ uint8_t *data, *tmp;
+ int stride, bpp;
+ int x, y;
+
+ surface = cairo_get_target (cr);
+
+ func(cr);
+
+ image = cairo_surface_map_to_image (surface, NULL);
+
+ switch (cairo_image_surface_get_format (image)) {
+ case CAIRO_FORMAT_ARGB32:
+ case CAIRO_FORMAT_RGB24:
+ case CAIRO_FORMAT_RGB30:
+ bpp=4;
+ break;
+ case CAIRO_FORMAT_RGB16_565:
+ bpp=2;
+ break;
+ case CAIRO_FORMAT_A8:
+ bpp=1;
+ break;
+ case CAIRO_FORMAT_A1:
+ case CAIRO_FORMAT_INVALID:
+ default:
+ return CAIRO_TEST_FAILURE;
+ }
+
+ data = cairo_image_surface_get_data (image);
+ stride = cairo_image_surface_get_stride (image);
+
+ tmp = malloc (stride);
+ if (tmp == NULL)
+ return CAIRO_TEST_FAILURE;
+
+ for (y = 0; y < height; y++) {
+ uint8_t *row = data + y * stride;
+ for (x = 0; x < width/2; x++) {
+ memcpy (tmp, row + bpp * x, bpp);
+ memcpy (row + bpp * x, row + bpp * (width - x - 1), bpp);
+ memcpy (row + bpp * (width - x - 1), tmp, bpp);
+ }
+ }
+
+ for (y = 0; y < height/2; y++) {
+ memcpy (tmp, data + y * stride, stride);
+ memcpy (data + y * stride, data + (height - y - 1) * stride, stride);
+ memcpy (data + (height - y - 1) * stride, tmp, stride);
+ }
+
+ free (tmp);
+
+ cairo_surface_unmap_image (surface, image);
+ }
+#else
+ surface = record_get (func (record_create (cr)));
+
+ cairo_scale (cr, -1, -1);
+ cairo_translate (cr, -width, -height);
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_set_source_surface (cr, surface, 0, 0);
+ cairo_surface_destroy (surface);
+ cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_NONE);
+
+ cairo_paint (cr);
+#endif
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+record_paint (cairo_t *cr, int width, int height)
+{
+ return record_replay (cr, paint, width, height);
+}
+
+static cairo_test_status_t
+record_paint_alpha (cairo_t *cr, int width, int height)
+{
+ return record_replay (cr, paint_alpha, width, height);
+}
+
+static cairo_test_status_t
+record_paint_alpha_solid_clip (cairo_t *cr, int width, int height)
+{
+ return record_replay (cr, paint_alpha_solid_clip, width, height);
+}
+
+static cairo_test_status_t
+record_paint_alpha_clip (cairo_t *cr, int width, int height)
+{
+ return record_replay (cr, paint_alpha_clip, width, height);
+}
+
+static cairo_test_status_t
+record_paint_alpha_clip_mask (cairo_t *cr, int width, int height)
+{
+ return record_replay (cr, paint_alpha_clip_mask, width, height);
+}
+
+static cairo_test_status_t
+record_fill_alpha (cairo_t *cr, int width, int height)
+{
+ return record_replay (cr, fill_alpha, width, height);
+}
+
+static cairo_test_status_t
+record_self_intersecting (cairo_t *cr, int width, int height)
+{
+ return record_replay (cr, self_intersecting, width, height);
+}
+
+static cairo_test_status_t
+record_select_font_face (cairo_t *cr, int width, int height)
+{
+ return record_replay (cr, select_font_face, width, height);
+}
+
+static cairo_test_status_t
+record_text_transform (cairo_t *cr, int width, int height)
+{
+ return record_replay (cr, text_transform, width, height);
+}
+
+static cairo_test_status_t
+record_whole_paint (cairo_t *cr, int width, int height)
+{
+ return record_whole_replay (cr, paint, width, height);
+}
+
+static cairo_test_status_t
+record_whole_paint_alpha (cairo_t *cr, int width, int height)
+{
+ return record_whole_replay (cr, paint_alpha, width, height);
+}
+
+static cairo_test_status_t
+record_whole_paint_alpha_solid_clip (cairo_t *cr, int width, int height)
+{
+ return record_whole_replay (cr, paint_alpha_solid_clip, width, height);
+}
+
+static cairo_test_status_t
+record_whole_paint_alpha_clip (cairo_t *cr, int width, int height)
+{
+ return record_whole_replay (cr, paint_alpha_clip, width, height);
+}
+
+static cairo_test_status_t
+record_whole_paint_alpha_clip_mask (cairo_t *cr, int width, int height)
+{
+ return record_whole_replay (cr, paint_alpha_clip_mask, width, height);
+}
+
+static cairo_test_status_t
+record_whole_fill_alpha (cairo_t *cr, int width, int height)
+{
+ return record_whole_replay (cr, fill_alpha, width, height);
+}
+
+static cairo_test_status_t
+record_whole_self_intersecting (cairo_t *cr, int width, int height)
+{
+ return record_whole_replay (cr, self_intersecting, width, height);
+}
+
+static cairo_test_status_t
+record_whole_select_font_face (cairo_t *cr, int width, int height)
+{
+ return record_whole_replay (cr, select_font_face, width, height);
+}
+
+static cairo_test_status_t
+record_whole_text_transform (cairo_t *cr, int width, int height)
+{
+ return record_whole_replay (cr, text_transform, width, height);
+}
+
+CAIRO_TEST (recordflip_whole_paint,
+ "Test replayed calls to cairo_paint",
+ "paint,record", /* keywords */
+ NULL, /* requirements */
+ 8, 8,
+ NULL, record_whole_paint)
+CAIRO_TEST (recordflip_whole_paint_alpha,
+ "Simple test of cairo_paint_with_alpha",
+ "record, paint, alpha", /* keywords */
+ NULL, /* requirements */
+ 32, 32,
+ NULL, record_whole_paint_alpha)
+CAIRO_TEST (recordflip_whole_paint_alpha_solid_clip,
+ "Simple test of cairo_paint_with_alpha+unaligned clip",
+ "record, paint, alpha, clip", /* keywords */
+ NULL, /* requirements */
+ 32, 32,
+ NULL, record_whole_paint_alpha_solid_clip)
+CAIRO_TEST (recordflip_whole_paint_alpha_clip,
+ "Simple test of cairo_paint_with_alpha+unaligned clip",
+ "record, paint, alpha, clip", /* keywords */
+ NULL, /* requirements */
+ 32, 32,
+ NULL, record_whole_paint_alpha_clip)
+CAIRO_TEST (recordflip_whole_paint_alpha_clip_mask,
+ "Simple test of cairo_paint_with_alpha+triangular clip",
+ "record, paint, alpha, clip", /* keywords */
+ NULL, /* requirements */
+ 32, 32,
+ NULL, record_whole_paint_alpha_clip_mask)
+CAIRO_TEST (recordflip_whole_fill_alpha,
+ "Tests using set_rgba();fill()",
+ "record,fill, alpha", /* keywords */
+ NULL, /* requirements */
+ (2*SIZE + 4*PAD), (2*SIZE + 4*PAD),
+ NULL, record_whole_fill_alpha)
+CAIRO_TEST (recordflip_whole_select_font_face,
+ "Tests using cairo_select_font_face to draw text in different faces",
+ "record, font", /* keywords */
+ NULL, /* requirements */
+ 192, (TEXT_SIZE + 4),
+ NULL, record_whole_select_font_face)
+CAIRO_TEST (recordflip_whole_self_intersecting,
+ "Test strokes of self-intersecting paths",
+ "record, stroke, trap", /* keywords */
+ NULL, /* requirements */
+ 10, 20,
+ NULL, record_whole_self_intersecting)
+CAIRO_TEST (recordflip_whole_text_transform,
+ "Test various applications of the font matrix",
+ "record, text, transform", /* keywords */
+ NULL, /* requirements */
+ TT_SIZE, TT_SIZE,
+ NULL, record_whole_text_transform)
+
+
+CAIRO_TEST (recordflip_paint,
+ "Test replayed calls to cairo_paint",
+ "paint,record", /* keywords */
+ NULL, /* requirements */
+ 8, 8,
+ NULL, record_paint)
+CAIRO_TEST (recordflip_paint_alpha,
+ "Simple test of cairo_paint_with_alpha",
+ "record, paint, alpha", /* keywords */
+ NULL, /* requirements */
+ 32, 32,
+ NULL, record_paint_alpha)
+CAIRO_TEST (recordflip_paint_alpha_solid_clip,
+ "Simple test of cairo_paint_with_alpha+unaligned clip",
+ "record, paint, alpha, clip", /* keywords */
+ NULL, /* requirements */
+ 32, 32,
+ NULL, record_paint_alpha_solid_clip)
+CAIRO_TEST (recordflip_paint_alpha_clip,
+ "Simple test of cairo_paint_with_alpha+unaligned clip",
+ "record, paint, alpha, clip", /* keywords */
+ NULL, /* requirements */
+ 32, 32,
+ NULL, record_paint_alpha_clip)
+CAIRO_TEST (recordflip_paint_alpha_clip_mask,
+ "Simple test of cairo_paint_with_alpha+triangular clip",
+ "record, paint, alpha, clip", /* keywords */
+ NULL, /* requirements */
+ 32, 32,
+ NULL, record_paint_alpha_clip_mask)
+CAIRO_TEST (recordflip_fill_alpha,
+ "Tests using set_rgba();fill()",
+ "record,fill, alpha", /* keywords */
+ NULL, /* requirements */
+ (2*SIZE + 4*PAD), (2*SIZE + 4*PAD),
+ NULL, record_fill_alpha)
+CAIRO_TEST (recordflip_select_font_face,
+ "Tests using cairo_select_font_face to draw text in different faces",
+ "record, font", /* keywords */
+ NULL, /* requirements */
+ 192, (TEXT_SIZE + 4),
+ NULL, record_select_font_face)
+CAIRO_TEST (recordflip_self_intersecting,
+ "Test strokes of self-intersecting paths",
+ "record, stroke, trap", /* keywords */
+ NULL, /* requirements */
+ 10, 20,
+ NULL, record_self_intersecting)
+CAIRO_TEST (recordflip_text_transform,
+ "Test various applications of the font matrix",
+ "record, text, transform", /* keywords */
+ NULL, /* requirements */
+ TT_SIZE, TT_SIZE,
+ NULL, record_text_transform)
diff --git a/test/recording-surface-extend.c b/test/recording-surface-extend.c
new file mode 100644
index 000000000..056654530
--- /dev/null
+++ b/test/recording-surface-extend.c
@@ -0,0 +1,174 @@
+/*
+ * Copyright © 2007 Adrian Johnson
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ * Adrian Johnson <ajohnson@redneon.com>
+ * Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+#define PAT_WIDTH 120
+#define PAT_HEIGHT 120
+#define SIZE (PAT_WIDTH*2)
+#define PAD 2
+#define WIDTH (PAD + SIZE + PAD)
+#define HEIGHT WIDTH
+
+
+/* This test is designed to test painting a recording surface pattern with
+ * CAIRO_EXTEND_NONE and a non identity pattern matrix.
+ */
+static cairo_pattern_t *create_pattern (cairo_t *target)
+{
+ cairo_surface_t *surface;
+ cairo_pattern_t *pattern;
+ cairo_t *cr;
+
+ surface = cairo_surface_create_similar (cairo_get_group_target (target),
+ CAIRO_CONTENT_COLOR_ALPHA,
+ PAT_WIDTH, PAT_HEIGHT);
+ cr = cairo_create (surface);
+ cairo_surface_destroy (surface);
+
+ cairo_set_source_rgba (cr, 1, 0, 1, 0.5);
+ cairo_rectangle (cr, PAT_WIDTH/6.0, PAT_HEIGHT/6.0, PAT_WIDTH/4.0, PAT_HEIGHT/4.0);
+ cairo_fill (cr);
+
+ cairo_set_source_rgba (cr, 0, 1, 1, 0.5);
+ cairo_rectangle (cr, PAT_WIDTH/2.0, PAT_HEIGHT/2.0, PAT_WIDTH/4.0, PAT_HEIGHT/4.0);
+ cairo_fill (cr);
+
+ cairo_set_line_width (cr, 1);
+ cairo_move_to (cr, PAT_WIDTH/6.0, 0);
+ cairo_line_to (cr, 0, 0);
+ cairo_line_to (cr, 0, PAT_HEIGHT/6.0);
+ cairo_set_source_rgb (cr, 1, 0, 0);
+ cairo_stroke (cr);
+ cairo_move_to (cr, PAT_WIDTH/6.0, PAT_HEIGHT);
+ cairo_line_to (cr, 0, PAT_HEIGHT);
+ cairo_line_to (cr, 0, 5*PAT_HEIGHT/6.0);
+ cairo_set_source_rgb (cr, 0, 1, 0);
+ cairo_stroke (cr);
+ cairo_move_to (cr, 5*PAT_WIDTH/6.0, 0);
+ cairo_line_to (cr, PAT_WIDTH, 0);
+ cairo_line_to (cr, PAT_WIDTH, PAT_HEIGHT/6.0);
+ cairo_set_source_rgb (cr, 0, 0, 1);
+ cairo_stroke (cr);
+ cairo_move_to (cr, 5*PAT_WIDTH/6.0, PAT_HEIGHT);
+ cairo_line_to (cr, PAT_WIDTH, PAT_HEIGHT);
+ cairo_line_to (cr, PAT_WIDTH, 5*PAT_HEIGHT/6.0);
+ cairo_set_source_rgb (cr, 1, 1, 0);
+ cairo_stroke (cr);
+
+ cairo_set_source_rgb (cr, 0.5, 0.5, 0.5);
+ cairo_set_line_width (cr, PAT_WIDTH/10.0);
+
+ cairo_move_to (cr, 0, PAT_HEIGHT/4.0);
+ cairo_line_to (cr, PAT_WIDTH, PAT_HEIGHT/4.0);
+ cairo_stroke (cr);
+
+ cairo_move_to (cr, PAT_WIDTH/4.0, 0);
+ cairo_line_to (cr, PAT_WIDTH/4.0, PAT_WIDTH);
+ cairo_stroke (cr);
+
+ pattern = cairo_pattern_create_for_surface (cairo_get_target (cr));
+ cairo_destroy (cr);
+
+ return pattern;
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, cairo_extend_t extend)
+{
+ cairo_pattern_t *pattern;
+ cairo_matrix_t mat;
+
+ cairo_translate (cr, PAD, PAD);
+
+ pattern = create_pattern (cr);
+
+ cairo_matrix_init_identity (&mat);
+ cairo_matrix_scale (&mat, 2, 1.5);
+ cairo_matrix_rotate (&mat, 1);
+ cairo_matrix_translate (&mat, -PAT_WIDTH/4.0, -PAT_WIDTH/2.0);
+ cairo_pattern_set_matrix (pattern, &mat);
+ cairo_pattern_set_extend (pattern, extend);
+
+ cairo_set_source (cr, pattern);
+ cairo_paint (cr);
+
+ cairo_pattern_destroy (pattern);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+none (cairo_t *cr, int width, int height)
+{
+ return draw (cr, CAIRO_EXTEND_NONE);
+}
+
+static cairo_test_status_t
+repeat (cairo_t *cr, int width, int height)
+{
+ return draw (cr, CAIRO_EXTEND_REPEAT);
+}
+
+static cairo_test_status_t
+reflect (cairo_t *cr, int width, int height)
+{
+ return draw (cr, CAIRO_EXTEND_REFLECT);
+}
+
+static cairo_test_status_t
+pad (cairo_t *cr, int width, int height)
+{
+ return draw (cr, CAIRO_EXTEND_PAD);
+}
+
+CAIRO_TEST (recording_surface_extend_none,
+ "Paint recording surface pattern with extend modes",
+ "recording, extend", /* keywords */
+ NULL, /* requirements */
+ WIDTH, HEIGHT,
+ NULL, none)
+CAIRO_TEST (recording_surface_extend_repeat,
+ "Paint recording surface pattern with extend modes",
+ "recording, extend", /* keywords */
+ NULL, /* requirements */
+ WIDTH, HEIGHT,
+ NULL, repeat)
+CAIRO_TEST (recording_surface_extend_reflect,
+ "Paint recording surface pattern with extend modes",
+ "recording, extend", /* keywords */
+ NULL, /* requirements */
+ WIDTH, HEIGHT,
+ NULL, reflect)
+CAIRO_TEST (recording_surface_extend_pad,
+ "Paint recording surface pattern with extend modes",
+ "recording, extend", /* keywords */
+ NULL, /* requirements */
+ WIDTH, HEIGHT,
+ NULL, pad)
diff --git a/test/recording-surface-pattern.c b/test/recording-surface-pattern.c
new file mode 100644
index 000000000..5a5fee2b0
--- /dev/null
+++ b/test/recording-surface-pattern.c
@@ -0,0 +1,162 @@
+/*
+ * Copyright © 2007 Adrian Johnson
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Adrian Johnson <ajohnson@redneon.com>
+ */
+
+#include "cairo-test.h"
+
+#define PAT_WIDTH 120
+#define PAT_HEIGHT 120
+#define SIZE (PAT_WIDTH*2)
+#define PAD 2
+#define WIDTH (PAD + SIZE + PAD)
+#define HEIGHT WIDTH
+
+
+/* This test is designed to test painting a recording surface pattern with
+ * CAIRO_EXTEND_NONE and a non identity pattern matrix.
+ */
+static cairo_pattern_t *create_pattern (cairo_t *target)
+{
+ cairo_surface_t *surface;
+ cairo_pattern_t *pattern;
+ cairo_t *cr;
+
+ surface = cairo_surface_create_similar (cairo_get_group_target (target),
+ CAIRO_CONTENT_COLOR_ALPHA,
+ PAT_WIDTH, PAT_HEIGHT);
+ cr = cairo_create (surface);
+ cairo_surface_destroy (surface);
+
+ cairo_set_source_rgba (cr, 1, 0, 1, 0.5);
+ cairo_rectangle (cr, PAT_WIDTH/6.0, PAT_HEIGHT/6.0, PAT_WIDTH/4.0, PAT_HEIGHT/4.0);
+ cairo_fill (cr);
+
+ cairo_set_source_rgba (cr, 0, 1, 1, 0.5);
+ cairo_rectangle (cr, PAT_WIDTH/2.0, PAT_HEIGHT/2.0, PAT_WIDTH/4.0, PAT_HEIGHT/4.0);
+ cairo_fill (cr);
+
+ cairo_set_line_width (cr, 1);
+ cairo_move_to (cr, PAT_WIDTH/6.0, 0);
+ cairo_line_to (cr, 0, 0);
+ cairo_line_to (cr, 0, PAT_HEIGHT/6.0);
+ cairo_set_source_rgb (cr, 1, 0, 0);
+ cairo_stroke (cr);
+ cairo_move_to (cr, PAT_WIDTH/6.0, PAT_HEIGHT);
+ cairo_line_to (cr, 0, PAT_HEIGHT);
+ cairo_line_to (cr, 0, 5*PAT_HEIGHT/6.0);
+ cairo_set_source_rgb (cr, 0, 1, 0);
+ cairo_stroke (cr);
+ cairo_move_to (cr, 5*PAT_WIDTH/6.0, 0);
+ cairo_line_to (cr, PAT_WIDTH, 0);
+ cairo_line_to (cr, PAT_WIDTH, PAT_HEIGHT/6.0);
+ cairo_set_source_rgb (cr, 0, 0, 1);
+ cairo_stroke (cr);
+ cairo_move_to (cr, 5*PAT_WIDTH/6.0, PAT_HEIGHT);
+ cairo_line_to (cr, PAT_WIDTH, PAT_HEIGHT);
+ cairo_line_to (cr, PAT_WIDTH, 5*PAT_HEIGHT/6.0);
+ cairo_set_source_rgb (cr, 1, 1, 0);
+ cairo_stroke (cr);
+
+ cairo_set_source_rgb (cr, 0.5, 0.5, 0.5);
+ cairo_set_line_width (cr, PAT_WIDTH/10.0);
+
+ cairo_move_to (cr, 0, PAT_HEIGHT/4.0);
+ cairo_line_to (cr, PAT_WIDTH, PAT_HEIGHT/4.0);
+ cairo_stroke (cr);
+
+ cairo_move_to (cr, PAT_WIDTH/4.0, 0);
+ cairo_line_to (cr, PAT_WIDTH/4.0, PAT_WIDTH);
+ cairo_stroke (cr);
+
+ pattern = cairo_pattern_create_for_surface (cairo_get_target (cr));
+ cairo_destroy (cr);
+
+ return pattern;
+}
+
+static cairo_test_status_t
+over (cairo_t *cr, int width, int height)
+{
+ cairo_pattern_t *pattern;
+ cairo_matrix_t mat;
+
+ cairo_translate (cr, PAD, PAD);
+
+ pattern = create_pattern (cr);
+
+ cairo_matrix_init_identity (&mat);
+ cairo_matrix_scale (&mat, 2, 1.5);
+ cairo_matrix_rotate (&mat, 1);
+ cairo_matrix_translate (&mat, -PAT_WIDTH/4.0, -PAT_WIDTH/2.0);
+ cairo_pattern_set_matrix (pattern, &mat);
+ cairo_pattern_set_extend (pattern, CAIRO_EXTEND_NONE);
+
+ cairo_set_source (cr, pattern);
+ cairo_paint (cr);
+
+ cairo_pattern_destroy (pattern);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+source (cairo_t *cr, int width, int height)
+{
+ cairo_pattern_t *pattern;
+ cairo_matrix_t mat;
+
+ cairo_translate (cr, PAD, PAD);
+
+ pattern = create_pattern (cr);
+
+ cairo_matrix_init_identity (&mat);
+ cairo_matrix_scale (&mat, 2, 1.5);
+ cairo_matrix_rotate (&mat, 1);
+ cairo_matrix_translate (&mat, -PAT_WIDTH/4.0, -PAT_WIDTH/2.0);
+ cairo_pattern_set_matrix (pattern, &mat);
+ cairo_pattern_set_extend (pattern, CAIRO_EXTEND_NONE);
+
+ cairo_set_source (cr, pattern);
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_paint (cr);
+
+ cairo_pattern_destroy (pattern);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (recording_surface_over,
+ "Paint recording surface pattern with non identity pattern matrix",
+ "recording", /* keywords */
+ NULL, /* requirements */
+ WIDTH, HEIGHT,
+ NULL, over)
+
+CAIRO_TEST (recording_surface_source,
+ "Paint recording surface pattern with non identity pattern matrix",
+ "recording", /* keywords */
+ NULL, /* requirements */
+ WIDTH, HEIGHT,
+ NULL, source)
diff --git a/test/rectangle-rounding-error.c b/test/rectangle-rounding-error.c
new file mode 100644
index 000000000..6ad99ae20
--- /dev/null
+++ b/test/rectangle-rounding-error.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright © 2005 Bertram Felgenhauer
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * the author not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. The author makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THE AUTHOR. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Bertram Felgenhauer <int-e@gmx.de>
+ */
+
+#include "cairo-test.h"
+
+/* Test case for:
+ *
+ * https://bugs.freedesktop.org/show_bug.cgi?id=4137
+ */
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+ cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE);
+ cairo_set_source_rgb (cr, 0, 0, 0);
+
+ cairo_translate(cr, -300, -300);
+ cairo_scale(cr, 677.0/26, 677.0/26);
+ cairo_translate(cr, 1, 1);
+
+ /* this should draw a seamless 2x2 rectangle */
+ cairo_rectangle(cr, 11, 11, 1, 1);
+ cairo_rectangle(cr, 11, 12, 1, 1);
+ cairo_rectangle(cr, 12, 11, 1, 1);
+ cairo_rectangle(cr, 12, 12, 1, 1);
+
+ cairo_set_source_rgb(cr, 0, 0, 0);
+ cairo_fill(cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (rectangle_rounding_error,
+ "This demonstrates (or not) a rounding error that causes a gap between "
+ "two neighbouring rectangles.",
+ "trap", /* keywords */
+ "target=raster", /* requirements */
+ 76, 76,
+ NULL, draw)
diff --git a/test/rectilinear-dash-scale.c b/test/rectilinear-dash-scale.c
new file mode 100644
index 000000000..34f334561
--- /dev/null
+++ b/test/rectilinear-dash-scale.c
@@ -0,0 +1,196 @@
+/*
+ * Copyright © 2006 Red Hat, Inc.
+ * Copyright © 2008 Chris Wilson
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ * Chris Wilson <chris@chris-wilson.co.uk>
+ *
+ * Based on the original test/rectilinear-stroke.c by Carl D. Worth.
+ */
+
+#include "cairo-test.h"
+
+#define SIZE 50
+
+static void
+draw_dashes (cairo_t *cr)
+{
+ const double dash_square[4] = {4, 2, 2, 2};
+ const double dash_butt[4] = {5, 1, 3, 1};
+
+ cairo_save (cr);
+
+ cairo_set_dash (cr, dash_square, 4, 0);
+
+ cairo_set_line_width (cr, 1.0);
+ cairo_translate (cr, 1, 1);
+
+ /* Draw everything first with square caps. */
+ cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE);
+
+ /* Draw horizontal and vertical segments, each in both
+ * directions. */
+ cairo_move_to (cr, 4.5, 0.5);
+ cairo_rel_line_to (cr, 2.0, 0.0);
+
+ cairo_move_to (cr, 10.5, 4.5);
+ cairo_rel_line_to (cr, 0.0, 2.0);
+
+ cairo_move_to (cr, 6.5, 10.5);
+ cairo_rel_line_to (cr, -2.0, 0.0);
+
+ cairo_move_to (cr, 0.5, 6.5);
+ cairo_rel_line_to (cr, 0.0, -2.0);
+
+ /* Draw right angle turns in four directions. */
+ cairo_move_to (cr, 0.5, 2.5);
+ cairo_rel_line_to (cr, 0.0, -2.0);
+ cairo_rel_line_to (cr, 2.0, 0.0);
+
+ cairo_move_to (cr, 8.5, 0.5);
+ cairo_rel_line_to (cr, 2.0, 0.0);
+ cairo_rel_line_to (cr, 0.0, 2.0);
+
+ cairo_move_to (cr, 10.5, 8.5);
+ cairo_rel_line_to (cr, 0.0, 2.0);
+ cairo_rel_line_to (cr, -2.0, 0.0);
+
+ cairo_move_to (cr, 2.5, 10.5);
+ cairo_rel_line_to (cr, -2.0, 0.0);
+ cairo_rel_line_to (cr, 0.0, -2.0);
+
+ cairo_stroke (cr);
+
+ /* Draw a closed-path rectangle */
+ cairo_rectangle (cr, 0.5, 12.5, 10.0, 10.0);
+ cairo_set_dash (cr, dash_square, 4, 2);
+ cairo_stroke (cr);
+
+ cairo_translate (cr, 12, 0);
+
+ /* Now draw the same results, but with butt caps. */
+ cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT);
+ cairo_set_dash (cr, dash_butt, 4, 0.0);
+
+ /* Draw horizontal and vertical segments, each in both
+ * directions. */
+ cairo_move_to (cr, 4.0, 0.5);
+ cairo_rel_line_to (cr, 3.0, 0.0);
+
+ cairo_move_to (cr, 10.5, 4.0);
+ cairo_rel_line_to (cr, 0.0, 3.0);
+
+ cairo_move_to (cr, 7.0, 10.5);
+ cairo_rel_line_to (cr, -3.0, 0.0);
+
+ cairo_move_to (cr, 0.5, 7.0);
+ cairo_rel_line_to (cr, 0.0, -3.0);
+
+ /* Draw right angle turns in four directions. */
+ cairo_move_to (cr, 0.5, 3.0);
+ cairo_rel_line_to (cr, 0.0, -2.5);
+ cairo_rel_line_to (cr, 2.5, 0.0);
+
+ cairo_move_to (cr, 8.0, 0.5);
+ cairo_rel_line_to (cr, 2.5, 0.0);
+ cairo_rel_line_to (cr, 0.0, 2.5);
+
+ cairo_move_to (cr, 10.5, 8.0);
+ cairo_rel_line_to (cr, 0.0, 2.5);
+ cairo_rel_line_to (cr, -2.5, 0.0);
+
+ cairo_move_to (cr, 3.0, 10.5);
+ cairo_rel_line_to (cr, -2.5, 0.0);
+ cairo_rel_line_to (cr, 0.0, -2.5);
+
+ cairo_stroke (cr);
+
+ /* Draw a closed-path rectangle */
+ cairo_set_dash (cr, dash_butt, 4, 2.5);
+ cairo_rectangle (cr, 0.5, 12.5, 10.0, 10.0);
+ cairo_stroke (cr);
+
+ cairo_restore (cr);
+}
+
+static cairo_test_status_t
+dashes (cairo_t *cr)
+{
+ /* Paint background white, then draw in black. */
+ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
+ cairo_paint (cr);
+
+ cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
+ draw_dashes (cr);
+
+ cairo_save (cr);
+ cairo_set_source_rgb (cr, 1.0, 0.0, 0.0);
+ cairo_translate (cr, 0, SIZE);
+ cairo_scale (cr, 1, -1);
+ draw_dashes (cr);
+ cairo_restore (cr);
+
+ cairo_save (cr);
+ cairo_set_source_rgb (cr, 0.0, 1.0, 0.0);
+ cairo_translate (cr, SIZE, 0);
+ cairo_scale (cr, -1, 1);
+ draw_dashes (cr);
+ cairo_restore (cr);
+
+ cairo_save (cr);
+ cairo_set_source_rgb (cr, 0.0, 0.0, 1.0);
+ cairo_translate (cr, SIZE, SIZE);
+ cairo_scale (cr, -1, -1);
+ draw_dashes (cr);
+ cairo_restore (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+aligned (cairo_t *cr, int width, int height)
+{
+ cairo_scale (cr, 4, 2);
+ return dashes(cr);
+}
+
+static cairo_test_status_t
+unaligned (cairo_t *cr, int width, int height)
+{
+ cairo_scale (cr, 3.9, 1.9);
+ return dashes(cr);
+}
+
+CAIRO_TEST (rectilinear_dash_scale,
+ "Test dashed rectilinear stroke operations (covering only whole pixels) after scaling",
+ "stroke, dash", /* keywords */
+ NULL, /* requirements */
+ 4*SIZE, 2*SIZE,
+ NULL, aligned)
+
+CAIRO_TEST (rectilinear_dash_scale_unaligned,
+ "Test dashed rectilinear stroke operations (covering partial pixels) after scaling",
+ "stroke, dash", /* keywords */
+ NULL, /* requirements */
+ 4*SIZE, 2*SIZE,
+ NULL, unaligned)
diff --git a/test/rectilinear-dash.c b/test/rectilinear-dash.c
new file mode 100644
index 000000000..954a2a042
--- /dev/null
+++ b/test/rectilinear-dash.c
@@ -0,0 +1,176 @@
+/*
+ * Copyright © 2006 Red Hat, Inc.
+ * Copyright © 2008 Chris Wilson
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ * Chris Wilson <chris@chris-wilson.co.uk>
+ *
+ * Based on the original test/rectilinear-stroke.c by Carl D. Worth.
+ */
+
+#include "cairo-test.h"
+
+#define SIZE 50
+
+static void
+draw_dashes (cairo_t *cr)
+{
+ const double dash_square[4] = {4, 2, 2, 2};
+ const double dash_butt[4] = {5, 1, 3, 1};
+
+ cairo_save (cr);
+
+ cairo_set_dash (cr, dash_square, 4, 0);
+
+ cairo_set_line_width (cr, 1.0);
+ cairo_translate (cr, 1, 1);
+
+ /* Draw everything first with square caps. */
+ cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE);
+
+ /* Draw horizontal and vertical segments, each in both
+ * directions. */
+ cairo_move_to (cr, 4.5, 0.5);
+ cairo_rel_line_to (cr, 2.0, 0.0);
+
+ cairo_move_to (cr, 10.5, 4.5);
+ cairo_rel_line_to (cr, 0.0, 2.0);
+
+ cairo_move_to (cr, 6.5, 10.5);
+ cairo_rel_line_to (cr, -2.0, 0.0);
+
+ cairo_move_to (cr, 0.5, 6.5);
+ cairo_rel_line_to (cr, 0.0, -2.0);
+
+ /* Draw right angle turns in four directions. */
+ cairo_move_to (cr, 0.5, 2.5);
+ cairo_rel_line_to (cr, 0.0, -2.0);
+ cairo_rel_line_to (cr, 2.0, 0.0);
+
+ cairo_move_to (cr, 8.5, 0.5);
+ cairo_rel_line_to (cr, 2.0, 0.0);
+ cairo_rel_line_to (cr, 0.0, 2.0);
+
+ cairo_move_to (cr, 10.5, 8.5);
+ cairo_rel_line_to (cr, 0.0, 2.0);
+ cairo_rel_line_to (cr, -2.0, 0.0);
+
+ cairo_move_to (cr, 2.5, 10.5);
+ cairo_rel_line_to (cr, -2.0, 0.0);
+ cairo_rel_line_to (cr, 0.0, -2.0);
+
+ cairo_stroke (cr);
+
+ /* Draw a closed-path rectangle */
+ cairo_rectangle (cr, 0.5, 12.5, 10.0, 10.0);
+ cairo_set_dash (cr, dash_square, 4, 2);
+ cairo_stroke (cr);
+
+ cairo_translate (cr, 12, 0);
+
+ /* Now draw the same results, but with butt caps. */
+ cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT);
+ cairo_set_dash (cr, dash_butt, 4, 0.0);
+
+ /* Draw horizontal and vertical segments, each in both
+ * directions. */
+ cairo_move_to (cr, 4.0, 0.5);
+ cairo_rel_line_to (cr, 3.0, 0.0);
+
+ cairo_move_to (cr, 10.5, 4.0);
+ cairo_rel_line_to (cr, 0.0, 3.0);
+
+ cairo_move_to (cr, 7.0, 10.5);
+ cairo_rel_line_to (cr, -3.0, 0.0);
+
+ cairo_move_to (cr, 0.5, 7.0);
+ cairo_rel_line_to (cr, 0.0, -3.0);
+
+ /* Draw right angle turns in four directions. */
+ cairo_move_to (cr, 0.5, 3.0);
+ cairo_rel_line_to (cr, 0.0, -2.5);
+ cairo_rel_line_to (cr, 2.5, 0.0);
+
+ cairo_move_to (cr, 8.0, 0.5);
+ cairo_rel_line_to (cr, 2.5, 0.0);
+ cairo_rel_line_to (cr, 0.0, 2.5);
+
+ cairo_move_to (cr, 10.5, 8.0);
+ cairo_rel_line_to (cr, 0.0, 2.5);
+ cairo_rel_line_to (cr, -2.5, 0.0);
+
+ cairo_move_to (cr, 3.0, 10.5);
+ cairo_rel_line_to (cr, -2.5, 0.0);
+ cairo_rel_line_to (cr, 0.0, -2.5);
+
+ cairo_stroke (cr);
+
+ /* Draw a closed-path rectangle */
+ cairo_set_dash (cr, dash_butt, 4, 2.5);
+ cairo_rectangle (cr, 0.5, 12.5, 10.0, 10.0);
+ cairo_stroke (cr);
+
+ cairo_restore (cr);
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ /* Paint background white, then draw in black. */
+ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
+ cairo_paint (cr);
+
+ cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
+ draw_dashes (cr);
+
+ cairo_save (cr);
+ cairo_set_source_rgb (cr, 1.0, 0.0, 0.0);
+ cairo_translate (cr, 0, height);
+ cairo_scale (cr, 1, -1);
+ draw_dashes (cr);
+ cairo_restore (cr);
+
+ cairo_save (cr);
+ cairo_set_source_rgb (cr, 0.0, 1.0, 0.0);
+ cairo_translate (cr, width, 0);
+ cairo_scale (cr, -1, 1);
+ draw_dashes (cr);
+ cairo_restore (cr);
+
+ cairo_save (cr);
+ cairo_set_source_rgb (cr, 0.0, 0.0, 1.0);
+ cairo_translate (cr, width, height);
+ cairo_scale (cr, -1, -1);
+ draw_dashes (cr);
+ cairo_restore (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (rectilinear_dash,
+ "Test dashed rectilinear stroke operations (covering only whole pixels)",
+ "stroke, dash", /* keywords */
+ NULL, /* requirements */
+ SIZE, SIZE,
+ NULL, draw)
+
diff --git a/test/rectilinear-fill.c b/test/rectilinear-fill.c
new file mode 100644
index 000000000..3678379ee
--- /dev/null
+++ b/test/rectilinear-fill.c
@@ -0,0 +1,84 @@
+/*
+ * Copyright © 2008 Chris Wilson
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+#define SIZE 24
+
+static void
+draw_rectangles (cairo_t *cr)
+{
+ cairo_save (cr);
+
+ /* test constructing single rectangles */
+ cairo_rectangle (cr, 0, 0, SIZE/2, 2);
+ cairo_fill (cr);
+
+ cairo_rectangle (cr, 0, 5, SIZE/2, -2);
+ cairo_fill (cr);
+
+ cairo_rectangle (cr, SIZE/2, 6, -SIZE/2, 2);
+ cairo_fill (cr);
+
+ cairo_rectangle (cr, SIZE/2, 11, -SIZE/2, -2);
+ cairo_fill (cr);
+
+ /* test constructing multiple rectangles */
+ cairo_translate (cr, 0, 12);
+ cairo_rectangle (cr, 0, 0, SIZE/2, 2);
+ cairo_rectangle (cr, 0, 5, SIZE/2, -2);
+ cairo_rectangle (cr, SIZE/2, 6, -SIZE/2, 2);
+ cairo_rectangle (cr, SIZE/2, 11, -SIZE/2, -2);
+ cairo_fill (cr);
+
+ cairo_restore (cr);
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ /* Paint background white, then draw in black. */
+ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */
+ cairo_paint (cr);
+ cairo_set_source_rgb (cr, 0.0, 0.0, 0.0); /* black */
+
+ draw_rectangles (cr);
+
+ /* and check using cw winding */
+ cairo_translate (cr, SIZE, SIZE);
+ cairo_scale (cr, -1, 1);
+
+ draw_rectangles (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (rectilinear_fill,
+ "Test rectilinear fill operations (covering only whole pixels)",
+ "fill, rectilinear", /* keywords */
+ NULL, /* requirements */
+ SIZE, 2 * SIZE,
+ NULL, draw)
diff --git a/test/rectilinear-grid.c b/test/rectilinear-grid.c
new file mode 100644
index 000000000..6d37c6b8a
--- /dev/null
+++ b/test/rectilinear-grid.c
@@ -0,0 +1,92 @@
+/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */
+/*
+ * Copyright 2010 Andrea Canciani
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Andrea Canciani <ranma42@gmail.com>
+ */
+
+#include "cairo-test.h"
+
+#define SIZE 52
+#define OFFSET 5
+#define DISTANCE 10.25
+
+/*
+ This test checks that boxes not aligned to pixels are drawn
+ correctly.
+
+ In particular the corners of the boxes are drawn incorrectly by
+ cairo-image in cairo 1.10.0, because overlapping boxes are passed to
+ a span converter which assumes disjoint boxes as input.
+
+ This results in corners to be drawn with the wrong shade.
+*/
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ int i;
+
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ cairo_set_line_width (cr, 4);
+ cairo_translate (cr, 2*OFFSET, 2*OFFSET);
+
+ for (i = 0; i < 4; i++) {
+ double x = i * DISTANCE;
+
+ cairo_move_to (cr, x, -OFFSET-0.75);
+ cairo_line_to (cr, x, SIZE-3*OFFSET-0.25);
+
+ cairo_move_to (cr, -OFFSET-0.75, x);
+ cairo_line_to (cr, SIZE-3*OFFSET-0.25, x);
+ }
+
+ cairo_stroke (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+aligned (cairo_t *cr, int width, int height)
+{
+ cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE);
+ return draw (cr, width, height);
+}
+
+CAIRO_TEST (rectilinear_grid,
+ "Test rectilinear rasterizer (covering partial pixels)",
+ "rectilinear", /* keywords */
+ NULL, /* requirements */
+ SIZE, SIZE,
+ NULL, draw)
+
+CAIRO_TEST (a1_rectilinear_grid,
+ "Test rectilinear rasterizer (covering whole pixels)",
+ "rectilinear", /* keywords */
+ "target=raster", /* requirements */
+ SIZE, SIZE,
+ NULL, aligned)
diff --git a/test/rectilinear-miter-limit.c b/test/rectilinear-miter-limit.c
new file mode 100644
index 000000000..581d98bad
--- /dev/null
+++ b/test/rectilinear-miter-limit.c
@@ -0,0 +1,72 @@
+/*
+ * Copyright © 2008 Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+#include "cairo-test.h"
+
+#define LINE_WIDTH 10
+#define PAD 2
+#define WIDTH (PAD + LINE_WIDTH + PAD)
+#define HEIGHT (WIDTH)
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_translate (cr, PAD, PAD);
+
+ /* Paint background white, then draw in black. */
+ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */
+ cairo_paint (cr);
+ cairo_set_source_rgb (cr, 0.0, 0.0, 0.0); /* black */
+
+ cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT);
+ cairo_set_line_width (cr, LINE_WIDTH);
+
+ /* The default miter limit value of 10.0 guarantees that
+ * right-angle turns, (in fact, any angle greater than 11
+ * degrees), gets a miter rather than a bevel join. The
+ * rectilinear stroke optimization was originally written in a
+ * buggy way that did not respect the miter limit, (that is,
+ * inappropriately drawing miter joins when the miter limit would
+ * turn them into bevels). So we draw here with a miter limit of
+ * 1.0 to force all miter joins into bevels. */
+ cairo_set_line_join (cr, CAIRO_LINE_JOIN_MITER);
+ cairo_set_miter_limit (cr, 1.0);
+
+ cairo_move_to (cr, LINE_WIDTH / 2.0, LINE_WIDTH);
+ cairo_rel_line_to (cr, 0, - LINE_WIDTH / 2.0);
+ cairo_rel_line_to (cr, LINE_WIDTH / 2.0, 0);
+
+ cairo_stroke (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (rectilinear_miter_limit,
+ "Test that the rectilinear stroke optimization doesn't break cairo_set_miter_limit",
+ "miter, stroke, stress", /* keywords */
+ NULL, /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw)
diff --git a/test/rectilinear-stroke.c b/test/rectilinear-stroke.c
new file mode 100644
index 000000000..e05ff8c2e
--- /dev/null
+++ b/test/rectilinear-stroke.c
@@ -0,0 +1,139 @@
+/*
+ * Copyright © 2006 Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+#include "cairo-test.h"
+
+#define SIZE 25
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ /* Paint background white, then draw in black. */
+ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */
+ cairo_paint (cr);
+ cairo_set_source_rgb (cr, 0.0, 0.0, 0.0); /* black */
+
+ cairo_set_line_width (cr, 1.0);
+ cairo_translate (cr, 1, 1);
+
+ /* Draw everything first with square caps. */
+ cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE);
+
+ /* Draw horizontal and vertical segments, each in both
+ * directions. */
+ cairo_move_to (cr, 4.5, 0.5);
+ cairo_rel_line_to (cr, 2.0, 0.0);
+
+ cairo_move_to (cr, 10.5, 4.5);
+ cairo_rel_line_to (cr, 0.0, 2.0);
+
+ cairo_move_to (cr, 6.5, 10.5);
+ cairo_rel_line_to (cr, -2.0, 0.0);
+
+ cairo_move_to (cr, 0.5, 6.5);
+ cairo_rel_line_to (cr, 0.0, -2.0);
+
+ /* Draw right angle turns in four directions. */
+ cairo_move_to (cr, 0.5, 2.5);
+ cairo_rel_line_to (cr, 0.0, -2.0);
+ cairo_rel_line_to (cr, 2.0, 0.0);
+
+ cairo_move_to (cr, 8.5, 0.5);
+ cairo_rel_line_to (cr, 2.0, 0.0);
+ cairo_rel_line_to (cr, 0.0, 2.0);
+
+ cairo_move_to (cr, 10.5, 8.5);
+ cairo_rel_line_to (cr, 0.0, 2.0);
+ cairo_rel_line_to (cr, -2.0, 0.0);
+
+ cairo_move_to (cr, 2.5, 10.5);
+ cairo_rel_line_to (cr, -2.0, 0.0);
+ cairo_rel_line_to (cr, 0.0, -2.0);
+
+ /* Draw a closed-path rectangle */
+ cairo_rectangle (cr, 0.5, 12.5, 10.0, 10.0);
+
+ cairo_stroke (cr);
+
+ cairo_translate (cr, 12, 0);
+
+ /* Now draw the same results, but with butt caps. */
+ cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT);
+
+ /* Draw horizontal and vertical segments, each in both
+ * directions. */
+ cairo_move_to (cr, 4.0, 0.5);
+ cairo_rel_line_to (cr, 3.0, 0.0);
+
+ cairo_move_to (cr, 10.5, 4.0);
+ cairo_rel_line_to (cr, 0.0, 3.0);
+
+ cairo_move_to (cr, 7.0, 10.5);
+ cairo_rel_line_to (cr, -3.0, 0.0);
+
+ cairo_move_to (cr, 0.5, 7.0);
+ cairo_rel_line_to (cr, 0.0, -3.0);
+
+ /* Draw right angle turns in four directions. */
+ cairo_move_to (cr, 0.5, 3.0);
+ cairo_rel_line_to (cr, 0.0, -2.5);
+ cairo_rel_line_to (cr, 2.5, 0.0);
+
+ cairo_move_to (cr, 8.0, 0.5);
+ cairo_rel_line_to (cr, 2.5, 0.0);
+ cairo_rel_line_to (cr, 0.0, 2.5);
+
+ cairo_move_to (cr, 10.5, 8.0);
+ cairo_rel_line_to (cr, 0.0, 2.5);
+ cairo_rel_line_to (cr, -2.5, 0.0);
+
+ cairo_move_to (cr, 3.0, 10.5);
+ cairo_rel_line_to (cr, -2.5, 0.0);
+ cairo_rel_line_to (cr, 0.0, -2.5);
+
+ /* Draw a closed-path rectangle */
+ cairo_rectangle (cr, 0.5, 12.5, 10.0, 10.0);
+
+ /* Draw a path that is rectilinear initially, but not completely */
+ /* We draw this out of the target window. The bug that caused this
+ * addition was leaks if part of the path was rectilinear but not
+ * completely */
+ cairo_move_to (cr, 3.0, 30.5);
+ cairo_rel_line_to (cr, -2.5, 0.0);
+ cairo_rel_line_to (cr, +2.5, +2.5);
+
+ cairo_stroke (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (rectilinear_stroke,
+ "Test rectilinear stroke operations (covering only whole pixels)",
+ "stroke", /* keywords */
+ NULL, /* requirements */
+ SIZE, SIZE,
+ NULL, draw)
+
diff --git a/test/reference/a1-bug.base.argb32.ref.png b/test/reference/a1-bug.base.argb32.ref.png
new file mode 100644
index 000000000..4b08e0683
--- /dev/null
+++ b/test/reference/a1-bug.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/a1-bug.base.rgb24.ref.png b/test/reference/a1-bug.base.rgb24.ref.png
new file mode 100644
index 000000000..4b08e0683
--- /dev/null
+++ b/test/reference/a1-bug.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/a1-bug.image16.ref.png b/test/reference/a1-bug.image16.ref.png
new file mode 100644
index 000000000..48ce4b65a
--- /dev/null
+++ b/test/reference/a1-bug.image16.ref.png
Binary files differ
diff --git a/test/reference/a1-bug.mask.argb32.ref.png b/test/reference/a1-bug.mask.argb32.ref.png
new file mode 100644
index 000000000..f9ae8a87e
--- /dev/null
+++ b/test/reference/a1-bug.mask.argb32.ref.png
Binary files differ
diff --git a/test/reference/a1-bug.mask.rgb24.ref.png b/test/reference/a1-bug.mask.rgb24.ref.png
new file mode 100644
index 000000000..f9ae8a87e
--- /dev/null
+++ b/test/reference/a1-bug.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/a1-bug.quartz.xfail.png b/test/reference/a1-bug.quartz.xfail.png
new file mode 100644
index 000000000..4ed379365
--- /dev/null
+++ b/test/reference/a1-bug.quartz.xfail.png
Binary files differ
diff --git a/test/reference/a1-bug.ref.png b/test/reference/a1-bug.ref.png
new file mode 100644
index 000000000..dc6ff931b
--- /dev/null
+++ b/test/reference/a1-bug.ref.png
Binary files differ
diff --git a/test/reference/a1-bug.traps.argb32.ref.png b/test/reference/a1-bug.traps.argb32.ref.png
new file mode 100644
index 000000000..4b08e0683
--- /dev/null
+++ b/test/reference/a1-bug.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/a1-bug.traps.rgb24.ref.png b/test/reference/a1-bug.traps.rgb24.ref.png
new file mode 100644
index 000000000..4b08e0683
--- /dev/null
+++ b/test/reference/a1-bug.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/a1-clip-fill-equal.base.argb32.ref.png b/test/reference/a1-clip-fill-equal.base.argb32.ref.png
new file mode 100644
index 000000000..384ba4a04
--- /dev/null
+++ b/test/reference/a1-clip-fill-equal.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/a1-clip-fill-equal.base.rgb24.ref.png b/test/reference/a1-clip-fill-equal.base.rgb24.ref.png
new file mode 100644
index 000000000..384ba4a04
--- /dev/null
+++ b/test/reference/a1-clip-fill-equal.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/a1-clip-fill-equal.ref.png b/test/reference/a1-clip-fill-equal.ref.png
new file mode 100644
index 000000000..384ba4a04
--- /dev/null
+++ b/test/reference/a1-clip-fill-equal.ref.png
Binary files differ
diff --git a/test/reference/a1-clip-fill-rule.base.argb32.ref.png b/test/reference/a1-clip-fill-rule.base.argb32.ref.png
new file mode 100644
index 000000000..c3ba9dd5f
--- /dev/null
+++ b/test/reference/a1-clip-fill-rule.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/a1-clip-fill-rule.base.rgb24.ref.png b/test/reference/a1-clip-fill-rule.base.rgb24.ref.png
new file mode 100644
index 000000000..6fe9346ba
--- /dev/null
+++ b/test/reference/a1-clip-fill-rule.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/a1-clip-fill-rule.ref.png b/test/reference/a1-clip-fill-rule.ref.png
new file mode 100644
index 000000000..c3ba9dd5f
--- /dev/null
+++ b/test/reference/a1-clip-fill-rule.ref.png
Binary files differ
diff --git a/test/reference/a1-clip-fill.base.argb32.ref.png b/test/reference/a1-clip-fill.base.argb32.ref.png
new file mode 100644
index 000000000..384ba4a04
--- /dev/null
+++ b/test/reference/a1-clip-fill.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/a1-clip-fill.base.rgb24.ref.png b/test/reference/a1-clip-fill.base.rgb24.ref.png
new file mode 100644
index 000000000..384ba4a04
--- /dev/null
+++ b/test/reference/a1-clip-fill.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/a1-clip-fill.ref.png b/test/reference/a1-clip-fill.ref.png
new file mode 100644
index 000000000..384ba4a04
--- /dev/null
+++ b/test/reference/a1-clip-fill.ref.png
Binary files differ
diff --git a/test/reference/a1-clip-paint.base.argb32.ref.png b/test/reference/a1-clip-paint.base.argb32.ref.png
new file mode 100644
index 000000000..384ba4a04
--- /dev/null
+++ b/test/reference/a1-clip-paint.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/a1-clip-paint.base.rgb24.ref.png b/test/reference/a1-clip-paint.base.rgb24.ref.png
new file mode 100644
index 000000000..384ba4a04
--- /dev/null
+++ b/test/reference/a1-clip-paint.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/a1-clip-paint.ref.png b/test/reference/a1-clip-paint.ref.png
new file mode 100644
index 000000000..384ba4a04
--- /dev/null
+++ b/test/reference/a1-clip-paint.ref.png
Binary files differ
diff --git a/test/reference/a1-clip-stroke.base.argb32.ref.png b/test/reference/a1-clip-stroke.base.argb32.ref.png
new file mode 100644
index 000000000..384ba4a04
--- /dev/null
+++ b/test/reference/a1-clip-stroke.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/a1-clip-stroke.base.rgb24.ref.png b/test/reference/a1-clip-stroke.base.rgb24.ref.png
new file mode 100644
index 000000000..384ba4a04
--- /dev/null
+++ b/test/reference/a1-clip-stroke.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/a1-clip-stroke.ref.png b/test/reference/a1-clip-stroke.ref.png
new file mode 100644
index 000000000..384ba4a04
--- /dev/null
+++ b/test/reference/a1-clip-stroke.ref.png
Binary files differ
diff --git a/test/reference/a1-fill.base.argb32.ref.png b/test/reference/a1-fill.base.argb32.ref.png
new file mode 100644
index 000000000..e40202bf9
--- /dev/null
+++ b/test/reference/a1-fill.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/a1-fill.base.rgb24.ref.png b/test/reference/a1-fill.base.rgb24.ref.png
new file mode 100644
index 000000000..e40202bf9
--- /dev/null
+++ b/test/reference/a1-fill.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/a1-fill.ref.png b/test/reference/a1-fill.ref.png
new file mode 100644
index 000000000..e40202bf9
--- /dev/null
+++ b/test/reference/a1-fill.ref.png
Binary files differ
diff --git a/test/reference/a1-image-sample.base.argb32.ref.png b/test/reference/a1-image-sample.base.argb32.ref.png
new file mode 100644
index 000000000..b8fd4570d
--- /dev/null
+++ b/test/reference/a1-image-sample.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/a1-image-sample.base.rgb24.ref.png b/test/reference/a1-image-sample.base.rgb24.ref.png
new file mode 100644
index 000000000..b8fd4570d
--- /dev/null
+++ b/test/reference/a1-image-sample.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/a1-image-sample.gl.xfail.png b/test/reference/a1-image-sample.gl.xfail.png
new file mode 100644
index 000000000..384ba4a04
--- /dev/null
+++ b/test/reference/a1-image-sample.gl.xfail.png
Binary files differ
diff --git a/test/reference/a1-image-sample.ref.png b/test/reference/a1-image-sample.ref.png
new file mode 100644
index 000000000..b4e81eb35
--- /dev/null
+++ b/test/reference/a1-image-sample.ref.png
Binary files differ
diff --git a/test/reference/a1-line-width.base.argb32.ref.png b/test/reference/a1-line-width.base.argb32.ref.png
new file mode 100644
index 000000000..35d9cad60
--- /dev/null
+++ b/test/reference/a1-line-width.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/a1-line-width.base.rgb24.ref.png b/test/reference/a1-line-width.base.rgb24.ref.png
new file mode 100644
index 000000000..35d9cad60
--- /dev/null
+++ b/test/reference/a1-line-width.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/a1-line-width.pdf.ref.png b/test/reference/a1-line-width.pdf.ref.png
new file mode 100644
index 000000000..41a06e769
--- /dev/null
+++ b/test/reference/a1-line-width.pdf.ref.png
Binary files differ
diff --git a/test/reference/a1-line-width.ps.ref.png b/test/reference/a1-line-width.ps.ref.png
new file mode 100644
index 000000000..c52f8d874
--- /dev/null
+++ b/test/reference/a1-line-width.ps.ref.png
Binary files differ
diff --git a/test/reference/a1-line-width.ref.png b/test/reference/a1-line-width.ref.png
new file mode 100644
index 000000000..35d9cad60
--- /dev/null
+++ b/test/reference/a1-line-width.ref.png
Binary files differ
diff --git a/test/reference/a1-mask-sample.base.argb32.ref.png b/test/reference/a1-mask-sample.base.argb32.ref.png
new file mode 100644
index 000000000..b8fd4570d
--- /dev/null
+++ b/test/reference/a1-mask-sample.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/a1-mask-sample.base.rgb24.ref.png b/test/reference/a1-mask-sample.base.rgb24.ref.png
new file mode 100644
index 000000000..b8fd4570d
--- /dev/null
+++ b/test/reference/a1-mask-sample.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/a1-mask-sample.ref.png b/test/reference/a1-mask-sample.ref.png
new file mode 100644
index 000000000..b4e81eb35
--- /dev/null
+++ b/test/reference/a1-mask-sample.ref.png
Binary files differ
diff --git a/test/reference/a1-mask.base.argb32.ref.png b/test/reference/a1-mask.base.argb32.ref.png
new file mode 100644
index 000000000..864fc1031
--- /dev/null
+++ b/test/reference/a1-mask.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/a1-mask.base.rgb24.ref.png b/test/reference/a1-mask.base.rgb24.ref.png
new file mode 100644
index 000000000..864fc1031
--- /dev/null
+++ b/test/reference/a1-mask.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/a1-mask.ref.png b/test/reference/a1-mask.ref.png
new file mode 100644
index 000000000..ac4d97aca
--- /dev/null
+++ b/test/reference/a1-mask.ref.png
Binary files differ
diff --git a/test/reference/a1-rasterisation-rectangles.base.argb32.ref.png b/test/reference/a1-rasterisation-rectangles.base.argb32.ref.png
new file mode 100644
index 000000000..784cf873e
--- /dev/null
+++ b/test/reference/a1-rasterisation-rectangles.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/a1-rasterisation-rectangles.base.rgb24.ref.png b/test/reference/a1-rasterisation-rectangles.base.rgb24.ref.png
new file mode 100644
index 000000000..784cf873e
--- /dev/null
+++ b/test/reference/a1-rasterisation-rectangles.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/a1-rasterisation-rectangles.quartz.xfail.png b/test/reference/a1-rasterisation-rectangles.quartz.xfail.png
new file mode 100644
index 000000000..f8f3bf865
--- /dev/null
+++ b/test/reference/a1-rasterisation-rectangles.quartz.xfail.png
Binary files differ
diff --git a/test/reference/a1-rasterisation-rectangles.ref.png b/test/reference/a1-rasterisation-rectangles.ref.png
new file mode 100644
index 000000000..784cf873e
--- /dev/null
+++ b/test/reference/a1-rasterisation-rectangles.ref.png
Binary files differ
diff --git a/test/reference/a1-rasterisation-triangles.base.argb32.ref.png b/test/reference/a1-rasterisation-triangles.base.argb32.ref.png
new file mode 100644
index 000000000..784cf873e
--- /dev/null
+++ b/test/reference/a1-rasterisation-triangles.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/a1-rasterisation-triangles.base.rgb24.ref.png b/test/reference/a1-rasterisation-triangles.base.rgb24.ref.png
new file mode 100644
index 000000000..784cf873e
--- /dev/null
+++ b/test/reference/a1-rasterisation-triangles.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/a1-rasterisation-triangles.quartz.xfail.png b/test/reference/a1-rasterisation-triangles.quartz.xfail.png
new file mode 100644
index 000000000..f8f3bf865
--- /dev/null
+++ b/test/reference/a1-rasterisation-triangles.quartz.xfail.png
Binary files differ
diff --git a/test/reference/a1-rasterisation-triangles.ref.png b/test/reference/a1-rasterisation-triangles.ref.png
new file mode 100644
index 000000000..784cf873e
--- /dev/null
+++ b/test/reference/a1-rasterisation-triangles.ref.png
Binary files differ
diff --git a/test/reference/a1-rectilinear-grid.base.argb32.ref.png b/test/reference/a1-rectilinear-grid.base.argb32.ref.png
new file mode 100644
index 000000000..2dfb85e13
--- /dev/null
+++ b/test/reference/a1-rectilinear-grid.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/a1-rectilinear-grid.base.rgb24.ref.png b/test/reference/a1-rectilinear-grid.base.rgb24.ref.png
new file mode 100644
index 000000000..2dfb85e13
--- /dev/null
+++ b/test/reference/a1-rectilinear-grid.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/a1-rectilinear-grid.ref.png b/test/reference/a1-rectilinear-grid.ref.png
new file mode 100644
index 000000000..2dfb85e13
--- /dev/null
+++ b/test/reference/a1-rectilinear-grid.ref.png
Binary files differ
diff --git a/test/reference/a1-sample.base.argb32.ref.png b/test/reference/a1-sample.base.argb32.ref.png
new file mode 100644
index 000000000..4c6131ce0
--- /dev/null
+++ b/test/reference/a1-sample.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/a1-sample.base.rgb24.ref.png b/test/reference/a1-sample.base.rgb24.ref.png
new file mode 100644
index 000000000..4c6131ce0
--- /dev/null
+++ b/test/reference/a1-sample.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/a1-sample.ref.png b/test/reference/a1-sample.ref.png
new file mode 100644
index 000000000..4c6131ce0
--- /dev/null
+++ b/test/reference/a1-sample.ref.png
Binary files differ
diff --git a/test/reference/a1-tiger.base.argb32.ref.png b/test/reference/a1-tiger.base.argb32.ref.png
new file mode 100644
index 000000000..38472822f
--- /dev/null
+++ b/test/reference/a1-tiger.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/a1-tiger.base.rgb24.ref.png b/test/reference/a1-tiger.base.rgb24.ref.png
new file mode 100644
index 000000000..38472822f
--- /dev/null
+++ b/test/reference/a1-tiger.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/a1-tiger.mask.argb32.ref.png b/test/reference/a1-tiger.mask.argb32.ref.png
new file mode 100644
index 000000000..9a62af760
--- /dev/null
+++ b/test/reference/a1-tiger.mask.argb32.ref.png
Binary files differ
diff --git a/test/reference/a1-tiger.mask.rgb24.ref.png b/test/reference/a1-tiger.mask.rgb24.ref.png
new file mode 100644
index 000000000..9a62af760
--- /dev/null
+++ b/test/reference/a1-tiger.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/a1-tiger.ref.png b/test/reference/a1-tiger.ref.png
new file mode 100644
index 000000000..cc641e290
--- /dev/null
+++ b/test/reference/a1-tiger.ref.png
Binary files differ
diff --git a/test/reference/a1-tiger.traps.argb32.ref.png b/test/reference/a1-tiger.traps.argb32.ref.png
new file mode 100644
index 000000000..cc641e290
--- /dev/null
+++ b/test/reference/a1-tiger.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/a1-tiger.traps.rgb24.ref.png b/test/reference/a1-tiger.traps.rgb24.ref.png
new file mode 100644
index 000000000..cc641e290
--- /dev/null
+++ b/test/reference/a1-tiger.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/a1-traps-sample.base.argb32.ref.png b/test/reference/a1-traps-sample.base.argb32.ref.png
new file mode 100644
index 000000000..384ba4a04
--- /dev/null
+++ b/test/reference/a1-traps-sample.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/a1-traps-sample.base.rgb24.ref.png b/test/reference/a1-traps-sample.base.rgb24.ref.png
new file mode 100644
index 000000000..384ba4a04
--- /dev/null
+++ b/test/reference/a1-traps-sample.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/a1-traps-sample.quartz.xfail.png b/test/reference/a1-traps-sample.quartz.xfail.png
new file mode 100644
index 000000000..c89f4fe05
--- /dev/null
+++ b/test/reference/a1-traps-sample.quartz.xfail.png
Binary files differ
diff --git a/test/reference/a1-traps-sample.ref.png b/test/reference/a1-traps-sample.ref.png
new file mode 100644
index 000000000..384ba4a04
--- /dev/null
+++ b/test/reference/a1-traps-sample.ref.png
Binary files differ
diff --git a/test/reference/a8-clear.base.argb32.ref.png b/test/reference/a8-clear.base.argb32.ref.png
new file mode 100644
index 000000000..52010808c
--- /dev/null
+++ b/test/reference/a8-clear.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/a8-clear.base.rgb24.ref.png b/test/reference/a8-clear.base.rgb24.ref.png
new file mode 100644
index 000000000..52010808c
--- /dev/null
+++ b/test/reference/a8-clear.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/a8-clear.quartz.ref.png b/test/reference/a8-clear.quartz.ref.png
new file mode 100644
index 000000000..5b7c67fe9
--- /dev/null
+++ b/test/reference/a8-clear.quartz.ref.png
Binary files differ
diff --git a/test/reference/a8-clear.ref.png b/test/reference/a8-clear.ref.png
new file mode 100644
index 000000000..dbf45492c
--- /dev/null
+++ b/test/reference/a8-clear.ref.png
Binary files differ
diff --git a/test/reference/a8-clear.traps.argb32.ref.png b/test/reference/a8-clear.traps.argb32.ref.png
new file mode 100644
index 000000000..52010808c
--- /dev/null
+++ b/test/reference/a8-clear.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/a8-clear.traps.rgb24.ref.png b/test/reference/a8-clear.traps.rgb24.ref.png
new file mode 100644
index 000000000..52010808c
--- /dev/null
+++ b/test/reference/a8-clear.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/a8-mask.base.argb32.ref.png b/test/reference/a8-mask.base.argb32.ref.png
new file mode 100644
index 000000000..e0503d93e
--- /dev/null
+++ b/test/reference/a8-mask.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/a8-mask.base.rgb24.ref.png b/test/reference/a8-mask.base.rgb24.ref.png
new file mode 100644
index 000000000..e0503d93e
--- /dev/null
+++ b/test/reference/a8-mask.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/a8-mask.ref.png b/test/reference/a8-mask.ref.png
new file mode 100644
index 000000000..38556156c
--- /dev/null
+++ b/test/reference/a8-mask.ref.png
Binary files differ
diff --git a/test/reference/aliasing.base.argb32.ref.png b/test/reference/aliasing.base.argb32.ref.png
new file mode 100644
index 000000000..a88dbe272
--- /dev/null
+++ b/test/reference/aliasing.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/aliasing.base.rgb24.ref.png b/test/reference/aliasing.base.rgb24.ref.png
new file mode 100644
index 000000000..a88dbe272
--- /dev/null
+++ b/test/reference/aliasing.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/aliasing.image16.ref.png b/test/reference/aliasing.image16.ref.png
new file mode 100644
index 000000000..c76333337
--- /dev/null
+++ b/test/reference/aliasing.image16.ref.png
Binary files differ
diff --git a/test/reference/aliasing.quartz.ref.png b/test/reference/aliasing.quartz.ref.png
new file mode 100644
index 000000000..f4b6e2217
--- /dev/null
+++ b/test/reference/aliasing.quartz.ref.png
Binary files differ
diff --git a/test/reference/aliasing.ref.png b/test/reference/aliasing.ref.png
new file mode 100644
index 000000000..35bdb1857
--- /dev/null
+++ b/test/reference/aliasing.ref.png
Binary files differ
diff --git a/test/reference/aliasing.traps.argb32.ref.png b/test/reference/aliasing.traps.argb32.ref.png
new file mode 100644
index 000000000..a88dbe272
--- /dev/null
+++ b/test/reference/aliasing.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/aliasing.traps.rgb24.ref.png b/test/reference/aliasing.traps.rgb24.ref.png
new file mode 100644
index 000000000..a88dbe272
--- /dev/null
+++ b/test/reference/aliasing.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/alpha-similar.base.argb32.ref.png b/test/reference/alpha-similar.base.argb32.ref.png
new file mode 100644
index 000000000..9e1bfaace
--- /dev/null
+++ b/test/reference/alpha-similar.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/alpha-similar.base.rgb24.ref.png b/test/reference/alpha-similar.base.rgb24.ref.png
new file mode 100644
index 000000000..a1f5280a4
--- /dev/null
+++ b/test/reference/alpha-similar.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/alpha-similar.gl.argb32.xfail.png b/test/reference/alpha-similar.gl.argb32.xfail.png
new file mode 100644
index 000000000..579aae131
--- /dev/null
+++ b/test/reference/alpha-similar.gl.argb32.xfail.png
Binary files differ
diff --git a/test/reference/alpha-similar.gl.rgb24.xfail.png b/test/reference/alpha-similar.gl.rgb24.xfail.png
new file mode 100644
index 000000000..86366d26f
--- /dev/null
+++ b/test/reference/alpha-similar.gl.rgb24.xfail.png
Binary files differ
diff --git a/test/reference/alpha-similar.pdf.argb32.xfail.png b/test/reference/alpha-similar.pdf.argb32.xfail.png
new file mode 100644
index 000000000..75aa6005c
--- /dev/null
+++ b/test/reference/alpha-similar.pdf.argb32.xfail.png
Binary files differ
diff --git a/test/reference/alpha-similar.pdf.rgb24.xfail.png b/test/reference/alpha-similar.pdf.rgb24.xfail.png
new file mode 100644
index 000000000..86366d26f
--- /dev/null
+++ b/test/reference/alpha-similar.pdf.rgb24.xfail.png
Binary files differ
diff --git a/test/reference/alpha-similar.ps.argb32.xfail.png b/test/reference/alpha-similar.ps.argb32.xfail.png
new file mode 100644
index 000000000..75aa6005c
--- /dev/null
+++ b/test/reference/alpha-similar.ps.argb32.xfail.png
Binary files differ
diff --git a/test/reference/alpha-similar.ps.rgb24.xfail.png b/test/reference/alpha-similar.ps.rgb24.xfail.png
new file mode 100644
index 000000000..15a6aa114
--- /dev/null
+++ b/test/reference/alpha-similar.ps.rgb24.xfail.png
Binary files differ
diff --git a/test/reference/alpha-similar.ref.png b/test/reference/alpha-similar.ref.png
new file mode 100644
index 000000000..9e1bfaace
--- /dev/null
+++ b/test/reference/alpha-similar.ref.png
Binary files differ
diff --git a/test/reference/alpha-similar.svg.argb32.xfail.png b/test/reference/alpha-similar.svg.argb32.xfail.png
new file mode 100644
index 000000000..2ade632d6
--- /dev/null
+++ b/test/reference/alpha-similar.svg.argb32.xfail.png
Binary files differ
diff --git a/test/reference/alpha-similar.svg.rgb24.xfail.png b/test/reference/alpha-similar.svg.rgb24.xfail.png
new file mode 100644
index 000000000..c23689855
--- /dev/null
+++ b/test/reference/alpha-similar.svg.rgb24.xfail.png
Binary files differ
diff --git a/test/reference/api-special-cases.base.argb32.ref.png b/test/reference/api-special-cases.base.argb32.ref.png
new file mode 100644
index 000000000..56b88a935
--- /dev/null
+++ b/test/reference/api-special-cases.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/api-special-cases.base.rgb24.ref.png b/test/reference/api-special-cases.base.rgb24.ref.png
new file mode 100644
index 000000000..56b88a935
--- /dev/null
+++ b/test/reference/api-special-cases.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/api-special-cases.ref.png b/test/reference/api-special-cases.ref.png
new file mode 100644
index 000000000..56b88a935
--- /dev/null
+++ b/test/reference/api-special-cases.ref.png
Binary files differ
diff --git a/test/reference/arc-direction.base.argb32.ref.png b/test/reference/arc-direction.base.argb32.ref.png
new file mode 100644
index 000000000..2790a2b75
--- /dev/null
+++ b/test/reference/arc-direction.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/arc-direction.base.rgb24.ref.png b/test/reference/arc-direction.base.rgb24.ref.png
new file mode 100644
index 000000000..2790a2b75
--- /dev/null
+++ b/test/reference/arc-direction.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/arc-direction.ps.ref.png b/test/reference/arc-direction.ps.ref.png
new file mode 100644
index 000000000..902ab4578
--- /dev/null
+++ b/test/reference/arc-direction.ps.ref.png
Binary files differ
diff --git a/test/reference/arc-direction.ref.png b/test/reference/arc-direction.ref.png
new file mode 100644
index 000000000..05ff4107c
--- /dev/null
+++ b/test/reference/arc-direction.ref.png
Binary files differ
diff --git a/test/reference/arc-direction.traps.ref.png b/test/reference/arc-direction.traps.ref.png
new file mode 100644
index 000000000..2790a2b75
--- /dev/null
+++ b/test/reference/arc-direction.traps.ref.png
Binary files differ
diff --git a/test/reference/arc-infinite-loop.base.argb32.ref.png b/test/reference/arc-infinite-loop.base.argb32.ref.png
new file mode 100644
index 000000000..82d645f30
--- /dev/null
+++ b/test/reference/arc-infinite-loop.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/arc-infinite-loop.base.rgb24.ref.png b/test/reference/arc-infinite-loop.base.rgb24.ref.png
new file mode 100644
index 000000000..82d645f30
--- /dev/null
+++ b/test/reference/arc-infinite-loop.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/arc-infinite-loop.ref.png b/test/reference/arc-infinite-loop.ref.png
new file mode 100644
index 000000000..82d645f30
--- /dev/null
+++ b/test/reference/arc-infinite-loop.ref.png
Binary files differ
diff --git a/test/reference/arc-looping-dash.image16.ref.png b/test/reference/arc-looping-dash.image16.ref.png
new file mode 100644
index 000000000..addc93c13
--- /dev/null
+++ b/test/reference/arc-looping-dash.image16.ref.png
Binary files differ
diff --git a/test/reference/arc-looping-dash.mask.argb32.ref.png b/test/reference/arc-looping-dash.mask.argb32.ref.png
new file mode 100644
index 000000000..516e66ce0
--- /dev/null
+++ b/test/reference/arc-looping-dash.mask.argb32.ref.png
Binary files differ
diff --git a/test/reference/arc-looping-dash.mask.rgb24.ref.png b/test/reference/arc-looping-dash.mask.rgb24.ref.png
new file mode 100644
index 000000000..516e66ce0
--- /dev/null
+++ b/test/reference/arc-looping-dash.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/arc-looping-dash.ps.ref.png b/test/reference/arc-looping-dash.ps.ref.png
new file mode 100644
index 000000000..ab19b199f
--- /dev/null
+++ b/test/reference/arc-looping-dash.ps.ref.png
Binary files differ
diff --git a/test/reference/arc-looping-dash.quartz.ref.png b/test/reference/arc-looping-dash.quartz.ref.png
new file mode 100644
index 000000000..70304ca85
--- /dev/null
+++ b/test/reference/arc-looping-dash.quartz.ref.png
Binary files differ
diff --git a/test/reference/arc-looping-dash.ref.png b/test/reference/arc-looping-dash.ref.png
new file mode 100644
index 000000000..516e66ce0
--- /dev/null
+++ b/test/reference/arc-looping-dash.ref.png
Binary files differ
diff --git a/test/reference/arc-looping-dash.traps.argb32.ref.png b/test/reference/arc-looping-dash.traps.argb32.ref.png
new file mode 100644
index 000000000..58801ccd0
--- /dev/null
+++ b/test/reference/arc-looping-dash.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/arc-looping-dash.traps.rgb24.ref.png b/test/reference/arc-looping-dash.traps.rgb24.ref.png
new file mode 100644
index 000000000..58801ccd0
--- /dev/null
+++ b/test/reference/arc-looping-dash.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/big-empty-box.base.argb32.ref.png b/test/reference/big-empty-box.base.argb32.ref.png
new file mode 100644
index 000000000..a88d3b6de
--- /dev/null
+++ b/test/reference/big-empty-box.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/big-empty-box.base.rgb24.ref.png b/test/reference/big-empty-box.base.rgb24.ref.png
new file mode 100644
index 000000000..6c2ca32f0
--- /dev/null
+++ b/test/reference/big-empty-box.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/big-empty-box.ref.png b/test/reference/big-empty-box.ref.png
new file mode 100644
index 000000000..a88d3b6de
--- /dev/null
+++ b/test/reference/big-empty-box.ref.png
Binary files differ
diff --git a/test/reference/big-empty-triangle.base.argb32.ref.png b/test/reference/big-empty-triangle.base.argb32.ref.png
new file mode 100644
index 000000000..a88d3b6de
--- /dev/null
+++ b/test/reference/big-empty-triangle.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/big-empty-triangle.base.rgb24.ref.png b/test/reference/big-empty-triangle.base.rgb24.ref.png
new file mode 100644
index 000000000..6c2ca32f0
--- /dev/null
+++ b/test/reference/big-empty-triangle.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/big-empty-triangle.ref.png b/test/reference/big-empty-triangle.ref.png
new file mode 100644
index 000000000..a88d3b6de
--- /dev/null
+++ b/test/reference/big-empty-triangle.ref.png
Binary files differ
diff --git a/test/reference/big-line.base.argb32.ref.png b/test/reference/big-line.base.argb32.ref.png
new file mode 100644
index 000000000..35d2e36ab
--- /dev/null
+++ b/test/reference/big-line.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/big-line.base.rgb24.ref.png b/test/reference/big-line.base.rgb24.ref.png
new file mode 100644
index 000000000..35d2e36ab
--- /dev/null
+++ b/test/reference/big-line.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/big-line.image16.ref.png b/test/reference/big-line.image16.ref.png
new file mode 100644
index 000000000..47e33b8da
--- /dev/null
+++ b/test/reference/big-line.image16.ref.png
Binary files differ
diff --git a/test/reference/big-line.ps.ref.png b/test/reference/big-line.ps.ref.png
new file mode 100644
index 000000000..7b7e875d4
--- /dev/null
+++ b/test/reference/big-line.ps.ref.png
Binary files differ
diff --git a/test/reference/big-line.quartz.ref.png b/test/reference/big-line.quartz.ref.png
new file mode 100644
index 000000000..a6f72404a
--- /dev/null
+++ b/test/reference/big-line.quartz.ref.png
Binary files differ
diff --git a/test/reference/big-line.ref.png b/test/reference/big-line.ref.png
new file mode 100644
index 000000000..2f35bfa56
--- /dev/null
+++ b/test/reference/big-line.ref.png
Binary files differ
diff --git a/test/reference/big-line.traps.argb32.ref.png b/test/reference/big-line.traps.argb32.ref.png
new file mode 100644
index 000000000..35d2e36ab
--- /dev/null
+++ b/test/reference/big-line.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/big-line.traps.rgb24.ref.png b/test/reference/big-line.traps.rgb24.ref.png
new file mode 100644
index 000000000..35d2e36ab
--- /dev/null
+++ b/test/reference/big-line.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/big-little-box.base.argb32.ref.png b/test/reference/big-little-box.base.argb32.ref.png
new file mode 100644
index 000000000..928c5e690
--- /dev/null
+++ b/test/reference/big-little-box.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/big-little-box.base.rgb24.ref.png b/test/reference/big-little-box.base.rgb24.ref.png
new file mode 100644
index 000000000..c069d6fdc
--- /dev/null
+++ b/test/reference/big-little-box.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/big-little-box.ref.png b/test/reference/big-little-box.ref.png
new file mode 100644
index 000000000..928c5e690
--- /dev/null
+++ b/test/reference/big-little-box.ref.png
Binary files differ
diff --git a/test/reference/big-little-triangle.argb32.ref.png b/test/reference/big-little-triangle.argb32.ref.png
new file mode 100644
index 000000000..5308ccedb
--- /dev/null
+++ b/test/reference/big-little-triangle.argb32.ref.png
Binary files differ
diff --git a/test/reference/big-little-triangle.base.argb32.ref.png b/test/reference/big-little-triangle.base.argb32.ref.png
new file mode 100644
index 000000000..5308ccedb
--- /dev/null
+++ b/test/reference/big-little-triangle.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/big-little-triangle.base.rgb24.ref.png b/test/reference/big-little-triangle.base.rgb24.ref.png
new file mode 100644
index 000000000..9e4773b2d
--- /dev/null
+++ b/test/reference/big-little-triangle.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/big-little-triangle.rgb24.ref.png b/test/reference/big-little-triangle.rgb24.ref.png
new file mode 100644
index 000000000..9e4773b2d
--- /dev/null
+++ b/test/reference/big-little-triangle.rgb24.ref.png
Binary files differ
diff --git a/test/reference/big-little-triangle.traps.argb32.ref.png b/test/reference/big-little-triangle.traps.argb32.ref.png
new file mode 100644
index 000000000..5308ccedb
--- /dev/null
+++ b/test/reference/big-little-triangle.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/big-little-triangle.traps.rgb24.ref.png b/test/reference/big-little-triangle.traps.rgb24.ref.png
new file mode 100644
index 000000000..9e4773b2d
--- /dev/null
+++ b/test/reference/big-little-triangle.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/big-trap.base.argb32.ref.png b/test/reference/big-trap.base.argb32.ref.png
new file mode 100644
index 000000000..c0975c9b5
--- /dev/null
+++ b/test/reference/big-trap.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/big-trap.base.rgb24.ref.png b/test/reference/big-trap.base.rgb24.ref.png
new file mode 100644
index 000000000..c0975c9b5
--- /dev/null
+++ b/test/reference/big-trap.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/big-trap.mask.argb32.ref.png b/test/reference/big-trap.mask.argb32.ref.png
new file mode 100644
index 000000000..c0975c9b5
--- /dev/null
+++ b/test/reference/big-trap.mask.argb32.ref.png
Binary files differ
diff --git a/test/reference/big-trap.mask.rgb24.ref.png b/test/reference/big-trap.mask.rgb24.ref.png
new file mode 100644
index 000000000..c0975c9b5
--- /dev/null
+++ b/test/reference/big-trap.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/big-trap.traps.argb32.ref.png b/test/reference/big-trap.traps.argb32.ref.png
new file mode 100644
index 000000000..c0975c9b5
--- /dev/null
+++ b/test/reference/big-trap.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/big-trap.traps.rgb24.ref.png b/test/reference/big-trap.traps.rgb24.ref.png
new file mode 100644
index 000000000..c0975c9b5
--- /dev/null
+++ b/test/reference/big-trap.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/bilevel-image.base.argb32.ref.png b/test/reference/bilevel-image.base.argb32.ref.png
new file mode 100644
index 000000000..3fb25c2e5
--- /dev/null
+++ b/test/reference/bilevel-image.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/bilevel-image.base.rgb24.ref.png b/test/reference/bilevel-image.base.rgb24.ref.png
new file mode 100644
index 000000000..3fb25c2e5
--- /dev/null
+++ b/test/reference/bilevel-image.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/bilevel-image.ref.png b/test/reference/bilevel-image.ref.png
new file mode 100644
index 000000000..cae76d69d
--- /dev/null
+++ b/test/reference/bilevel-image.ref.png
Binary files differ
diff --git a/test/reference/bilevel-xlib-fallback.rgb24.ref.png b/test/reference/bilevel-xlib-fallback.rgb24.ref.png
new file mode 100644
index 000000000..3fb25c2e5
--- /dev/null
+++ b/test/reference/bilevel-xlib-fallback.rgb24.ref.png
Binary files differ
diff --git a/test/reference/bilevel-xlib-window.rgb24.ref.png b/test/reference/bilevel-xlib-window.rgb24.ref.png
new file mode 100644
index 000000000..3fb25c2e5
--- /dev/null
+++ b/test/reference/bilevel-xlib-window.rgb24.ref.png
Binary files differ
diff --git a/test/reference/bilevel-xlib.ref.png b/test/reference/bilevel-xlib.ref.png
new file mode 100644
index 000000000..3fb25c2e5
--- /dev/null
+++ b/test/reference/bilevel-xlib.ref.png
Binary files differ
diff --git a/test/reference/bitmap-font.base.argb32.ref.png b/test/reference/bitmap-font.base.argb32.ref.png
new file mode 100644
index 000000000..bc2bc52e0
--- /dev/null
+++ b/test/reference/bitmap-font.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/bitmap-font.base.rgb24.ref.png b/test/reference/bitmap-font.base.rgb24.ref.png
new file mode 100644
index 000000000..285d74288
--- /dev/null
+++ b/test/reference/bitmap-font.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/bitmap-font.ref.png b/test/reference/bitmap-font.ref.png
new file mode 100644
index 000000000..0718bf96a
--- /dev/null
+++ b/test/reference/bitmap-font.ref.png
Binary files differ
diff --git a/test/reference/blur.ref.png b/test/reference/blur.ref.png
new file mode 100644
index 000000000..40b923592
--- /dev/null
+++ b/test/reference/blur.ref.png
Binary files differ
diff --git a/test/reference/bug-40410.base.argb32.ref.png b/test/reference/bug-40410.base.argb32.ref.png
new file mode 100644
index 000000000..a31593536
--- /dev/null
+++ b/test/reference/bug-40410.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/bug-40410.base.rgb24.ref.png b/test/reference/bug-40410.base.rgb24.ref.png
new file mode 100644
index 000000000..a31593536
--- /dev/null
+++ b/test/reference/bug-40410.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/bug-40410.ref.png b/test/reference/bug-40410.ref.png
new file mode 100644
index 000000000..ae4420a70
--- /dev/null
+++ b/test/reference/bug-40410.ref.png
Binary files differ
diff --git a/test/reference/bug-40410.traps.argb32.ref.png b/test/reference/bug-40410.traps.argb32.ref.png
new file mode 100644
index 000000000..a31593536
--- /dev/null
+++ b/test/reference/bug-40410.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/bug-40410.traps.rgb24.ref.png b/test/reference/bug-40410.traps.rgb24.ref.png
new file mode 100644
index 000000000..a31593536
--- /dev/null
+++ b/test/reference/bug-40410.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/bug-51910.ref.png b/test/reference/bug-51910.ref.png
new file mode 100644
index 000000000..7f55eaae5
--- /dev/null
+++ b/test/reference/bug-51910.ref.png
Binary files differ
diff --git a/test/reference/bug-84115.ref.png b/test/reference/bug-84115.ref.png
new file mode 100644
index 000000000..df16257ad
--- /dev/null
+++ b/test/reference/bug-84115.ref.png
Binary files differ
diff --git a/test/reference/bug-84115.xlib.ref.png b/test/reference/bug-84115.xlib.ref.png
new file mode 100644
index 000000000..2e17a6570
--- /dev/null
+++ b/test/reference/bug-84115.xlib.ref.png
Binary files differ
diff --git a/test/reference/bug-bo-collins.ref.png b/test/reference/bug-bo-collins.ref.png
new file mode 100644
index 000000000..72e5c1d7c
--- /dev/null
+++ b/test/reference/bug-bo-collins.ref.png
Binary files differ
diff --git a/test/reference/bug-bo-rectangular.base.argb32.ref.png b/test/reference/bug-bo-rectangular.base.argb32.ref.png
new file mode 100644
index 000000000..ffa4edef6
--- /dev/null
+++ b/test/reference/bug-bo-rectangular.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/bug-bo-rectangular.base.rgb24.ref.png b/test/reference/bug-bo-rectangular.base.rgb24.ref.png
new file mode 100644
index 000000000..ffa4edef6
--- /dev/null
+++ b/test/reference/bug-bo-rectangular.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/bug-bo-rectangular.image16.ref.png b/test/reference/bug-bo-rectangular.image16.ref.png
new file mode 100644
index 000000000..d468d59ef
--- /dev/null
+++ b/test/reference/bug-bo-rectangular.image16.ref.png
Binary files differ
diff --git a/test/reference/bug-bo-rectangular.ps.xfail.png b/test/reference/bug-bo-rectangular.ps.xfail.png
new file mode 100644
index 000000000..44b8c0331
--- /dev/null
+++ b/test/reference/bug-bo-rectangular.ps.xfail.png
Binary files differ
diff --git a/test/reference/bug-bo-rectangular.ref.png b/test/reference/bug-bo-rectangular.ref.png
new file mode 100644
index 000000000..ffa4edef6
--- /dev/null
+++ b/test/reference/bug-bo-rectangular.ref.png
Binary files differ
diff --git a/test/reference/bug-bo-ricotz.base.argb32.ref.png b/test/reference/bug-bo-ricotz.base.argb32.ref.png
new file mode 100644
index 000000000..ff7a552f7
--- /dev/null
+++ b/test/reference/bug-bo-ricotz.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/bug-bo-ricotz.base.rgb24.ref.png b/test/reference/bug-bo-ricotz.base.rgb24.ref.png
new file mode 100644
index 000000000..ff7a552f7
--- /dev/null
+++ b/test/reference/bug-bo-ricotz.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/bug-bo-ricotz.ref.png b/test/reference/bug-bo-ricotz.ref.png
new file mode 100644
index 000000000..0e52b2454
--- /dev/null
+++ b/test/reference/bug-bo-ricotz.ref.png
Binary files differ
diff --git a/test/reference/bug-bo-ricotz.traps.ref.png b/test/reference/bug-bo-ricotz.traps.ref.png
new file mode 100644
index 000000000..ff7a552f7
--- /dev/null
+++ b/test/reference/bug-bo-ricotz.traps.ref.png
Binary files differ
diff --git a/test/reference/bug-extents.base.argb32.ref.png b/test/reference/bug-extents.base.argb32.ref.png
new file mode 100644
index 000000000..e07f8aa49
--- /dev/null
+++ b/test/reference/bug-extents.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/bug-extents.base.rgb24.ref.png b/test/reference/bug-extents.base.rgb24.ref.png
new file mode 100644
index 000000000..e07f8aa49
--- /dev/null
+++ b/test/reference/bug-extents.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/bug-extents.image16.ref.png b/test/reference/bug-extents.image16.ref.png
new file mode 100644
index 000000000..8eb3d4bcd
--- /dev/null
+++ b/test/reference/bug-extents.image16.ref.png
Binary files differ
diff --git a/test/reference/bug-extents.ps.ref.png b/test/reference/bug-extents.ps.ref.png
new file mode 100644
index 000000000..2d5540565
--- /dev/null
+++ b/test/reference/bug-extents.ps.ref.png
Binary files differ
diff --git a/test/reference/bug-extents.quartz.ref.png b/test/reference/bug-extents.quartz.ref.png
new file mode 100644
index 000000000..29734483d
--- /dev/null
+++ b/test/reference/bug-extents.quartz.ref.png
Binary files differ
diff --git a/test/reference/bug-extents.ref.png b/test/reference/bug-extents.ref.png
new file mode 100644
index 000000000..e85561183
--- /dev/null
+++ b/test/reference/bug-extents.ref.png
Binary files differ
diff --git a/test/reference/bug-extents.traps.argb32.ref.png b/test/reference/bug-extents.traps.argb32.ref.png
new file mode 100644
index 000000000..e07f8aa49
--- /dev/null
+++ b/test/reference/bug-extents.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/bug-extents.traps.rgb24.ref.png b/test/reference/bug-extents.traps.rgb24.ref.png
new file mode 100644
index 000000000..e07f8aa49
--- /dev/null
+++ b/test/reference/bug-extents.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/bug-seams.base.argb32.ref.png b/test/reference/bug-seams.base.argb32.ref.png
new file mode 100644
index 000000000..ac8065120
--- /dev/null
+++ b/test/reference/bug-seams.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/bug-seams.base.rgb24.ref.png b/test/reference/bug-seams.base.rgb24.ref.png
new file mode 100644
index 000000000..ac8065120
--- /dev/null
+++ b/test/reference/bug-seams.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/bug-seams.image.xfail.png b/test/reference/bug-seams.image.xfail.png
new file mode 100644
index 000000000..99098db8c
--- /dev/null
+++ b/test/reference/bug-seams.image.xfail.png
Binary files differ
diff --git a/test/reference/bug-seams.mask.argb32.ref.png b/test/reference/bug-seams.mask.argb32.ref.png
new file mode 100644
index 000000000..99098db8c
--- /dev/null
+++ b/test/reference/bug-seams.mask.argb32.ref.png
Binary files differ
diff --git a/test/reference/bug-seams.mask.rgb24.ref.png b/test/reference/bug-seams.mask.rgb24.ref.png
new file mode 100644
index 000000000..99098db8c
--- /dev/null
+++ b/test/reference/bug-seams.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/bug-seams.ref.png b/test/reference/bug-seams.ref.png
new file mode 100644
index 000000000..e4e72faf4
--- /dev/null
+++ b/test/reference/bug-seams.ref.png
Binary files differ
diff --git a/test/reference/bug-seams.traps.argb32.ref.png b/test/reference/bug-seams.traps.argb32.ref.png
new file mode 100644
index 000000000..ac8065120
--- /dev/null
+++ b/test/reference/bug-seams.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/bug-seams.traps.rgb24.ref.png b/test/reference/bug-seams.traps.rgb24.ref.png
new file mode 100644
index 000000000..ac8065120
--- /dev/null
+++ b/test/reference/bug-seams.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/bug-seams.xlib-fallback.ref.png b/test/reference/bug-seams.xlib-fallback.ref.png
new file mode 100644
index 000000000..e81fc6caa
--- /dev/null
+++ b/test/reference/bug-seams.xlib-fallback.ref.png
Binary files differ
diff --git a/test/reference/bug-source-cu.ref.png b/test/reference/bug-source-cu.ref.png
new file mode 100644
index 000000000..808feb5f2
--- /dev/null
+++ b/test/reference/bug-source-cu.ref.png
Binary files differ
diff --git a/test/reference/bug-source-cu.traps.argb32.ref.png b/test/reference/bug-source-cu.traps.argb32.ref.png
new file mode 100644
index 000000000..d8837c30d
--- /dev/null
+++ b/test/reference/bug-source-cu.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/bug-source-cu.traps.rgb24.ref.png b/test/reference/bug-source-cu.traps.rgb24.ref.png
new file mode 100644
index 000000000..75e3b326e
--- /dev/null
+++ b/test/reference/bug-source-cu.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/bug-spline.ref.png b/test/reference/bug-spline.ref.png
new file mode 100644
index 000000000..26d560953
--- /dev/null
+++ b/test/reference/bug-spline.ref.png
Binary files differ
diff --git a/test/reference/caps-05.ref.png b/test/reference/caps-05.ref.png
new file mode 100644
index 000000000..946adcbfa
--- /dev/null
+++ b/test/reference/caps-05.ref.png
Binary files differ
diff --git a/test/reference/caps-05.traps.ref.png b/test/reference/caps-05.traps.ref.png
new file mode 100644
index 000000000..409bdab07
--- /dev/null
+++ b/test/reference/caps-05.traps.ref.png
Binary files differ
diff --git a/test/reference/caps-1.ref.png b/test/reference/caps-1.ref.png
new file mode 100644
index 000000000..dfb111808
--- /dev/null
+++ b/test/reference/caps-1.ref.png
Binary files differ
diff --git a/test/reference/caps-1.traps.ref.png b/test/reference/caps-1.traps.ref.png
new file mode 100644
index 000000000..10f7d57a3
--- /dev/null
+++ b/test/reference/caps-1.traps.ref.png
Binary files differ
diff --git a/test/reference/caps-2.ref.png b/test/reference/caps-2.ref.png
new file mode 100644
index 000000000..ca420bcab
--- /dev/null
+++ b/test/reference/caps-2.ref.png
Binary files differ
diff --git a/test/reference/caps-2.traps.ref.png b/test/reference/caps-2.traps.ref.png
new file mode 100644
index 000000000..1c5d88574
--- /dev/null
+++ b/test/reference/caps-2.traps.ref.png
Binary files differ
diff --git a/test/reference/caps-joins-05.ref.png b/test/reference/caps-joins-05.ref.png
new file mode 100644
index 000000000..8814acede
--- /dev/null
+++ b/test/reference/caps-joins-05.ref.png
Binary files differ
diff --git a/test/reference/caps-joins-05.traps.ref.png b/test/reference/caps-joins-05.traps.ref.png
new file mode 100644
index 000000000..938fb6d1b
--- /dev/null
+++ b/test/reference/caps-joins-05.traps.ref.png
Binary files differ
diff --git a/test/reference/caps-joins-1.ref.png b/test/reference/caps-joins-1.ref.png
new file mode 100644
index 000000000..d7cdf2c86
--- /dev/null
+++ b/test/reference/caps-joins-1.ref.png
Binary files differ
diff --git a/test/reference/caps-joins-1.traps.ref.png b/test/reference/caps-joins-1.traps.ref.png
new file mode 100644
index 000000000..d9721f29f
--- /dev/null
+++ b/test/reference/caps-joins-1.traps.ref.png
Binary files differ
diff --git a/test/reference/caps-joins-2.ref.png b/test/reference/caps-joins-2.ref.png
new file mode 100644
index 000000000..1416a54e4
--- /dev/null
+++ b/test/reference/caps-joins-2.ref.png
Binary files differ
diff --git a/test/reference/caps-joins-2.traps.ref.png b/test/reference/caps-joins-2.traps.ref.png
new file mode 100644
index 000000000..e7089a8de
--- /dev/null
+++ b/test/reference/caps-joins-2.traps.ref.png
Binary files differ
diff --git a/test/reference/caps-joins-alpha.image16.ref.png b/test/reference/caps-joins-alpha.image16.ref.png
new file mode 100644
index 000000000..ddefea81c
--- /dev/null
+++ b/test/reference/caps-joins-alpha.image16.ref.png
Binary files differ
diff --git a/test/reference/caps-joins-alpha.mask.argb32.ref.png b/test/reference/caps-joins-alpha.mask.argb32.ref.png
new file mode 100644
index 000000000..964a70f37
--- /dev/null
+++ b/test/reference/caps-joins-alpha.mask.argb32.ref.png
Binary files differ
diff --git a/test/reference/caps-joins-alpha.mask.rgb24.ref.png b/test/reference/caps-joins-alpha.mask.rgb24.ref.png
new file mode 100644
index 000000000..964a70f37
--- /dev/null
+++ b/test/reference/caps-joins-alpha.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/caps-joins-alpha.quartz.ref.png b/test/reference/caps-joins-alpha.quartz.ref.png
new file mode 100644
index 000000000..190c1e96c
--- /dev/null
+++ b/test/reference/caps-joins-alpha.quartz.ref.png
Binary files differ
diff --git a/test/reference/caps-joins-alpha.ref.png b/test/reference/caps-joins-alpha.ref.png
new file mode 100644
index 000000000..9479bf247
--- /dev/null
+++ b/test/reference/caps-joins-alpha.ref.png
Binary files differ
diff --git a/test/reference/caps-joins-alpha.traps.argb32.ref.png b/test/reference/caps-joins-alpha.traps.argb32.ref.png
new file mode 100644
index 000000000..e17c4a197
--- /dev/null
+++ b/test/reference/caps-joins-alpha.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/caps-joins-alpha.traps.rgb24.ref.png b/test/reference/caps-joins-alpha.traps.rgb24.ref.png
new file mode 100644
index 000000000..e17c4a197
--- /dev/null
+++ b/test/reference/caps-joins-alpha.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/caps-joins-curve.image16.ref.png b/test/reference/caps-joins-curve.image16.ref.png
new file mode 100644
index 000000000..060b3dcb1
--- /dev/null
+++ b/test/reference/caps-joins-curve.image16.ref.png
Binary files differ
diff --git a/test/reference/caps-joins-curve.mask.argb32.ref.png b/test/reference/caps-joins-curve.mask.argb32.ref.png
new file mode 100644
index 000000000..35959002c
--- /dev/null
+++ b/test/reference/caps-joins-curve.mask.argb32.ref.png
Binary files differ
diff --git a/test/reference/caps-joins-curve.mask.rgb24.ref.png b/test/reference/caps-joins-curve.mask.rgb24.ref.png
new file mode 100644
index 000000000..35959002c
--- /dev/null
+++ b/test/reference/caps-joins-curve.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/caps-joins-curve.ps.ref.png b/test/reference/caps-joins-curve.ps.ref.png
new file mode 100644
index 000000000..7fbb826a1
--- /dev/null
+++ b/test/reference/caps-joins-curve.ps.ref.png
Binary files differ
diff --git a/test/reference/caps-joins-curve.quartz.ref.png b/test/reference/caps-joins-curve.quartz.ref.png
new file mode 100644
index 000000000..ec3d30796
--- /dev/null
+++ b/test/reference/caps-joins-curve.quartz.ref.png
Binary files differ
diff --git a/test/reference/caps-joins-curve.ref.png b/test/reference/caps-joins-curve.ref.png
new file mode 100644
index 000000000..a9f66a04b
--- /dev/null
+++ b/test/reference/caps-joins-curve.ref.png
Binary files differ
diff --git a/test/reference/caps-joins-curve.traps.argb32.ref.png b/test/reference/caps-joins-curve.traps.argb32.ref.png
new file mode 100644
index 000000000..7ce1acc3d
--- /dev/null
+++ b/test/reference/caps-joins-curve.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/caps-joins-curve.traps.rgb24.ref.png b/test/reference/caps-joins-curve.traps.rgb24.ref.png
new file mode 100644
index 000000000..7ce1acc3d
--- /dev/null
+++ b/test/reference/caps-joins-curve.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/caps-joins.base.argb32.ref.png b/test/reference/caps-joins.base.argb32.ref.png
new file mode 100644
index 000000000..470eec3b1
--- /dev/null
+++ b/test/reference/caps-joins.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/caps-joins.base.rgb24.ref.png b/test/reference/caps-joins.base.rgb24.ref.png
new file mode 100644
index 000000000..470eec3b1
--- /dev/null
+++ b/test/reference/caps-joins.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/caps-joins.image16.ref.png b/test/reference/caps-joins.image16.ref.png
new file mode 100644
index 000000000..0c452f29e
--- /dev/null
+++ b/test/reference/caps-joins.image16.ref.png
Binary files differ
diff --git a/test/reference/caps-joins.ps.ref.png b/test/reference/caps-joins.ps.ref.png
new file mode 100644
index 000000000..f6c85cef7
--- /dev/null
+++ b/test/reference/caps-joins.ps.ref.png
Binary files differ
diff --git a/test/reference/caps-joins.ref.png b/test/reference/caps-joins.ref.png
new file mode 100644
index 000000000..6d7122ee1
--- /dev/null
+++ b/test/reference/caps-joins.ref.png
Binary files differ
diff --git a/test/reference/caps-joins.traps.argb32.ref.png b/test/reference/caps-joins.traps.argb32.ref.png
new file mode 100644
index 000000000..470eec3b1
--- /dev/null
+++ b/test/reference/caps-joins.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/caps-joins.traps.rgb24.ref.png b/test/reference/caps-joins.traps.rgb24.ref.png
new file mode 100644
index 000000000..470eec3b1
--- /dev/null
+++ b/test/reference/caps-joins.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/caps-sub-paths.base.argb32.ref.png b/test/reference/caps-sub-paths.base.argb32.ref.png
new file mode 100644
index 000000000..1e4a83f0b
--- /dev/null
+++ b/test/reference/caps-sub-paths.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/caps-sub-paths.base.rgb24.ref.png b/test/reference/caps-sub-paths.base.rgb24.ref.png
new file mode 100644
index 000000000..1e4a83f0b
--- /dev/null
+++ b/test/reference/caps-sub-paths.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/caps-sub-paths.image16.ref.png b/test/reference/caps-sub-paths.image16.ref.png
new file mode 100644
index 000000000..c0cc4d74b
--- /dev/null
+++ b/test/reference/caps-sub-paths.image16.ref.png
Binary files differ
diff --git a/test/reference/caps-sub-paths.ps.ref.png b/test/reference/caps-sub-paths.ps.ref.png
new file mode 100644
index 000000000..197b443cd
--- /dev/null
+++ b/test/reference/caps-sub-paths.ps.ref.png
Binary files differ
diff --git a/test/reference/caps-sub-paths.ref.png b/test/reference/caps-sub-paths.ref.png
new file mode 100644
index 000000000..744338957
--- /dev/null
+++ b/test/reference/caps-sub-paths.ref.png
Binary files differ
diff --git a/test/reference/caps-sub-paths.traps.argb32.ref.png b/test/reference/caps-sub-paths.traps.argb32.ref.png
new file mode 100644
index 000000000..1e4a83f0b
--- /dev/null
+++ b/test/reference/caps-sub-paths.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/caps-sub-paths.traps.rgb24.ref.png b/test/reference/caps-sub-paths.traps.rgb24.ref.png
new file mode 100644
index 000000000..1e4a83f0b
--- /dev/null
+++ b/test/reference/caps-sub-paths.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/caps-tails-curve.mask.argb32.ref.png b/test/reference/caps-tails-curve.mask.argb32.ref.png
new file mode 100644
index 000000000..b0f477df9
--- /dev/null
+++ b/test/reference/caps-tails-curve.mask.argb32.ref.png
Binary files differ
diff --git a/test/reference/caps-tails-curve.mask.rgb24.ref.png b/test/reference/caps-tails-curve.mask.rgb24.ref.png
new file mode 100644
index 000000000..b0f477df9
--- /dev/null
+++ b/test/reference/caps-tails-curve.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/caps-tails-curve.ps.ref.png b/test/reference/caps-tails-curve.ps.ref.png
new file mode 100644
index 000000000..fca77c345
--- /dev/null
+++ b/test/reference/caps-tails-curve.ps.ref.png
Binary files differ
diff --git a/test/reference/caps-tails-curve.ref.png b/test/reference/caps-tails-curve.ref.png
new file mode 100644
index 000000000..df036d273
--- /dev/null
+++ b/test/reference/caps-tails-curve.ref.png
Binary files differ
diff --git a/test/reference/caps-tails-curve.traps.argb32.ref.png b/test/reference/caps-tails-curve.traps.argb32.ref.png
new file mode 100644
index 000000000..9d579998a
--- /dev/null
+++ b/test/reference/caps-tails-curve.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/caps-tails-curve.traps.rgb24.ref.png b/test/reference/caps-tails-curve.traps.rgb24.ref.png
new file mode 100644
index 000000000..9d579998a
--- /dev/null
+++ b/test/reference/caps-tails-curve.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/caps-tails-curve.xcb.ref.png b/test/reference/caps-tails-curve.xcb.ref.png
new file mode 100644
index 000000000..89022033c
--- /dev/null
+++ b/test/reference/caps-tails-curve.xcb.ref.png
Binary files differ
diff --git a/test/reference/caps.base.argb32.ref.png b/test/reference/caps.base.argb32.ref.png
new file mode 100644
index 000000000..b3504abcb
--- /dev/null
+++ b/test/reference/caps.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/caps.base.rgb24.ref.png b/test/reference/caps.base.rgb24.ref.png
new file mode 100644
index 000000000..b3504abcb
--- /dev/null
+++ b/test/reference/caps.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/caps.image16.ref.png b/test/reference/caps.image16.ref.png
new file mode 100644
index 000000000..a33a5ef73
--- /dev/null
+++ b/test/reference/caps.image16.ref.png
Binary files differ
diff --git a/test/reference/caps.ps.ref.png b/test/reference/caps.ps.ref.png
new file mode 100644
index 000000000..c91b8aa3b
--- /dev/null
+++ b/test/reference/caps.ps.ref.png
Binary files differ
diff --git a/test/reference/caps.ref.png b/test/reference/caps.ref.png
new file mode 100644
index 000000000..bf784fd40
--- /dev/null
+++ b/test/reference/caps.ref.png
Binary files differ
diff --git a/test/reference/caps.traps.argb32.ref.png b/test/reference/caps.traps.argb32.ref.png
new file mode 100644
index 000000000..b3504abcb
--- /dev/null
+++ b/test/reference/caps.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/caps.traps.rgb24.ref.png b/test/reference/caps.traps.rgb24.ref.png
new file mode 100644
index 000000000..b3504abcb
--- /dev/null
+++ b/test/reference/caps.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/checkerboard.base.argb32.ref.png b/test/reference/checkerboard.base.argb32.ref.png
new file mode 100644
index 000000000..1444bc41b
--- /dev/null
+++ b/test/reference/checkerboard.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/checkerboard.base.rgb24.ref.png b/test/reference/checkerboard.base.rgb24.ref.png
new file mode 100644
index 000000000..1444bc41b
--- /dev/null
+++ b/test/reference/checkerboard.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/checkerboard.ref.png b/test/reference/checkerboard.ref.png
new file mode 100644
index 000000000..1444bc41b
--- /dev/null
+++ b/test/reference/checkerboard.ref.png
Binary files differ
diff --git a/test/reference/clear-source.base.argb32.ref.png b/test/reference/clear-source.base.argb32.ref.png
new file mode 100644
index 000000000..293411c47
--- /dev/null
+++ b/test/reference/clear-source.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/clear-source.base.rgb24.ref.png b/test/reference/clear-source.base.rgb24.ref.png
new file mode 100644
index 000000000..293411c47
--- /dev/null
+++ b/test/reference/clear-source.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clear-source.image16.ref.png b/test/reference/clear-source.image16.ref.png
new file mode 100644
index 000000000..4055b95fe
--- /dev/null
+++ b/test/reference/clear-source.image16.ref.png
Binary files differ
diff --git a/test/reference/clear-source.pdf.xfail.png b/test/reference/clear-source.pdf.xfail.png
new file mode 100644
index 000000000..8e1bdd76e
--- /dev/null
+++ b/test/reference/clear-source.pdf.xfail.png
Binary files differ
diff --git a/test/reference/clear-source.ps.xfail.png b/test/reference/clear-source.ps.xfail.png
new file mode 100644
index 000000000..b515751d6
--- /dev/null
+++ b/test/reference/clear-source.ps.xfail.png
Binary files differ
diff --git a/test/reference/clear-source.ref.png b/test/reference/clear-source.ref.png
new file mode 100644
index 000000000..352bf4503
--- /dev/null
+++ b/test/reference/clear-source.ref.png
Binary files differ
diff --git a/test/reference/clear-source.traps.argb32.ref.png b/test/reference/clear-source.traps.argb32.ref.png
new file mode 100644
index 000000000..293411c47
--- /dev/null
+++ b/test/reference/clear-source.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/clear-source.traps.rgb24.ref.png b/test/reference/clear-source.traps.rgb24.ref.png
new file mode 100644
index 000000000..293411c47
--- /dev/null
+++ b/test/reference/clear-source.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clear.argb32.ref.png b/test/reference/clear.argb32.ref.png
new file mode 100644
index 000000000..64d89c1cb
--- /dev/null
+++ b/test/reference/clear.argb32.ref.png
Binary files differ
diff --git a/test/reference/clear.base.argb32.ref.png b/test/reference/clear.base.argb32.ref.png
new file mode 100644
index 000000000..1caca6dfb
--- /dev/null
+++ b/test/reference/clear.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/clear.base.rgb24.ref.png b/test/reference/clear.base.rgb24.ref.png
new file mode 100644
index 000000000..7d789b0bb
--- /dev/null
+++ b/test/reference/clear.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clear.pdf.argb32.ref.png b/test/reference/clear.pdf.argb32.ref.png
new file mode 100644
index 000000000..0960f4851
--- /dev/null
+++ b/test/reference/clear.pdf.argb32.ref.png
Binary files differ
diff --git a/test/reference/clear.ps.argb32.ref.png b/test/reference/clear.ps.argb32.ref.png
new file mode 100644
index 000000000..0960f4851
--- /dev/null
+++ b/test/reference/clear.ps.argb32.ref.png
Binary files differ
diff --git a/test/reference/clear.quartz.argb32.ref.png b/test/reference/clear.quartz.argb32.ref.png
new file mode 100644
index 000000000..12e604312
--- /dev/null
+++ b/test/reference/clear.quartz.argb32.ref.png
Binary files differ
diff --git a/test/reference/clear.quartz.rgb24.ref.png b/test/reference/clear.quartz.rgb24.ref.png
new file mode 100644
index 000000000..6ea449094
--- /dev/null
+++ b/test/reference/clear.quartz.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clear.rgb24.ref.png b/test/reference/clear.rgb24.ref.png
new file mode 100644
index 000000000..d59e44e11
--- /dev/null
+++ b/test/reference/clear.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clear.svg12.argb32.xfail.png b/test/reference/clear.svg12.argb32.xfail.png
new file mode 100644
index 000000000..cb25bcb40
--- /dev/null
+++ b/test/reference/clear.svg12.argb32.xfail.png
Binary files differ
diff --git a/test/reference/clear.svg12.rgb24.xfail.png b/test/reference/clear.svg12.rgb24.xfail.png
new file mode 100644
index 000000000..cb25bcb40
--- /dev/null
+++ b/test/reference/clear.svg12.rgb24.xfail.png
Binary files differ
diff --git a/test/reference/clear.traps.argb32.ref.png b/test/reference/clear.traps.argb32.ref.png
new file mode 100644
index 000000000..1caca6dfb
--- /dev/null
+++ b/test/reference/clear.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/clear.traps.rgb24.ref.png b/test/reference/clear.traps.rgb24.ref.png
new file mode 100644
index 000000000..7d789b0bb
--- /dev/null
+++ b/test/reference/clear.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-all.base.argb32.ref.png b/test/reference/clip-all.base.argb32.ref.png
new file mode 100644
index 000000000..1ed070cae
--- /dev/null
+++ b/test/reference/clip-all.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-all.base.rgb24.ref.png b/test/reference/clip-all.base.rgb24.ref.png
new file mode 100644
index 000000000..1ed070cae
--- /dev/null
+++ b/test/reference/clip-all.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-all.ref.png b/test/reference/clip-all.ref.png
new file mode 100644
index 000000000..6c14df51f
--- /dev/null
+++ b/test/reference/clip-all.ref.png
Binary files differ
diff --git a/test/reference/clip-complex-bug61492.ref.png b/test/reference/clip-complex-bug61492.ref.png
new file mode 100644
index 000000000..8e2e982be
--- /dev/null
+++ b/test/reference/clip-complex-bug61492.ref.png
Binary files differ
diff --git a/test/reference/clip-complex-shape-eo-aa.base.argb32.ref.png b/test/reference/clip-complex-shape-eo-aa.base.argb32.ref.png
new file mode 100644
index 000000000..bafbb8ad1
--- /dev/null
+++ b/test/reference/clip-complex-shape-eo-aa.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-complex-shape-eo-aa.base.rgb24.ref.png b/test/reference/clip-complex-shape-eo-aa.base.rgb24.ref.png
new file mode 100644
index 000000000..bafbb8ad1
--- /dev/null
+++ b/test/reference/clip-complex-shape-eo-aa.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-complex-shape-eo-aa.ref.png b/test/reference/clip-complex-shape-eo-aa.ref.png
new file mode 100644
index 000000000..d575aa9ad
--- /dev/null
+++ b/test/reference/clip-complex-shape-eo-aa.ref.png
Binary files differ
diff --git a/test/reference/clip-complex-shape-eo-mono.base.argb32.ref.png b/test/reference/clip-complex-shape-eo-mono.base.argb32.ref.png
new file mode 100644
index 000000000..bafbb8ad1
--- /dev/null
+++ b/test/reference/clip-complex-shape-eo-mono.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-complex-shape-eo-mono.base.rgb24.ref.png b/test/reference/clip-complex-shape-eo-mono.base.rgb24.ref.png
new file mode 100644
index 000000000..bafbb8ad1
--- /dev/null
+++ b/test/reference/clip-complex-shape-eo-mono.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-complex-shape-eo-mono.ref.png b/test/reference/clip-complex-shape-eo-mono.ref.png
new file mode 100644
index 000000000..d575aa9ad
--- /dev/null
+++ b/test/reference/clip-complex-shape-eo-mono.ref.png
Binary files differ
diff --git a/test/reference/clip-contexts.base.argb32.ref.png b/test/reference/clip-contexts.base.argb32.ref.png
new file mode 100644
index 000000000..0d575a628
--- /dev/null
+++ b/test/reference/clip-contexts.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-contexts.base.rgb24.ref.png b/test/reference/clip-contexts.base.rgb24.ref.png
new file mode 100644
index 000000000..0d575a628
--- /dev/null
+++ b/test/reference/clip-contexts.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-contexts.ref.png b/test/reference/clip-contexts.ref.png
new file mode 100644
index 000000000..0d575a628
--- /dev/null
+++ b/test/reference/clip-contexts.ref.png
Binary files differ
diff --git a/test/reference/clip-device-offset.base.argb32.ref.png b/test/reference/clip-device-offset.base.argb32.ref.png
new file mode 100644
index 000000000..06be98519
--- /dev/null
+++ b/test/reference/clip-device-offset.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-device-offset.base.rgb24.ref.png b/test/reference/clip-device-offset.base.rgb24.ref.png
new file mode 100644
index 000000000..241938459
--- /dev/null
+++ b/test/reference/clip-device-offset.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-device-offset.ref.png b/test/reference/clip-device-offset.ref.png
new file mode 100644
index 000000000..06be98519
--- /dev/null
+++ b/test/reference/clip-device-offset.ref.png
Binary files differ
diff --git a/test/reference/clip-disjoint-hatching.base.argb32.ref.png b/test/reference/clip-disjoint-hatching.base.argb32.ref.png
new file mode 100644
index 000000000..55f26d0b5
--- /dev/null
+++ b/test/reference/clip-disjoint-hatching.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-disjoint-hatching.base.rgb24.ref.png b/test/reference/clip-disjoint-hatching.base.rgb24.ref.png
new file mode 100644
index 000000000..55f26d0b5
--- /dev/null
+++ b/test/reference/clip-disjoint-hatching.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-disjoint-hatching.mask.argb32.ref.png b/test/reference/clip-disjoint-hatching.mask.argb32.ref.png
new file mode 100644
index 000000000..a29f04ac9
--- /dev/null
+++ b/test/reference/clip-disjoint-hatching.mask.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-disjoint-hatching.mask.rgb24.ref.png b/test/reference/clip-disjoint-hatching.mask.rgb24.ref.png
new file mode 100644
index 000000000..a29f04ac9
--- /dev/null
+++ b/test/reference/clip-disjoint-hatching.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-disjoint-hatching.ref.png b/test/reference/clip-disjoint-hatching.ref.png
new file mode 100644
index 000000000..ff47816f8
--- /dev/null
+++ b/test/reference/clip-disjoint-hatching.ref.png
Binary files differ
diff --git a/test/reference/clip-disjoint-hatching.traps.argb32.ref.png b/test/reference/clip-disjoint-hatching.traps.argb32.ref.png
new file mode 100644
index 000000000..6226d931e
--- /dev/null
+++ b/test/reference/clip-disjoint-hatching.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-disjoint-hatching.traps.rgb24.ref.png b/test/reference/clip-disjoint-hatching.traps.rgb24.ref.png
new file mode 100644
index 000000000..6226d931e
--- /dev/null
+++ b/test/reference/clip-disjoint-hatching.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-disjoint-quad.ref.png b/test/reference/clip-disjoint-quad.ref.png
new file mode 100644
index 000000000..25fbf0b1c
--- /dev/null
+++ b/test/reference/clip-disjoint-quad.ref.png
Binary files differ
diff --git a/test/reference/clip-disjoint-quad.traps.ref.png b/test/reference/clip-disjoint-quad.traps.ref.png
new file mode 100644
index 000000000..de5ceb77b
--- /dev/null
+++ b/test/reference/clip-disjoint-quad.traps.ref.png
Binary files differ
diff --git a/test/reference/clip-disjoint.base.argb32.ref.png b/test/reference/clip-disjoint.base.argb32.ref.png
new file mode 100644
index 000000000..74ae9d869
--- /dev/null
+++ b/test/reference/clip-disjoint.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-disjoint.base.rgb24.ref.png b/test/reference/clip-disjoint.base.rgb24.ref.png
new file mode 100644
index 000000000..74ae9d869
--- /dev/null
+++ b/test/reference/clip-disjoint.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-disjoint.image16.ref.png b/test/reference/clip-disjoint.image16.ref.png
new file mode 100644
index 000000000..79aaf7164
--- /dev/null
+++ b/test/reference/clip-disjoint.image16.ref.png
Binary files differ
diff --git a/test/reference/clip-disjoint.mask.argb32.ref.png b/test/reference/clip-disjoint.mask.argb32.ref.png
new file mode 100644
index 000000000..4e18b7c7c
--- /dev/null
+++ b/test/reference/clip-disjoint.mask.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-disjoint.mask.rgb24.ref.png b/test/reference/clip-disjoint.mask.rgb24.ref.png
new file mode 100644
index 000000000..4e18b7c7c
--- /dev/null
+++ b/test/reference/clip-disjoint.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-disjoint.ps.ref.png b/test/reference/clip-disjoint.ps.ref.png
new file mode 100644
index 000000000..5410d0aa3
--- /dev/null
+++ b/test/reference/clip-disjoint.ps.ref.png
Binary files differ
diff --git a/test/reference/clip-disjoint.quartz.ref.png b/test/reference/clip-disjoint.quartz.ref.png
new file mode 100644
index 000000000..10068152e
--- /dev/null
+++ b/test/reference/clip-disjoint.quartz.ref.png
Binary files differ
diff --git a/test/reference/clip-disjoint.ref.png b/test/reference/clip-disjoint.ref.png
new file mode 100644
index 000000000..c0d1c0640
--- /dev/null
+++ b/test/reference/clip-disjoint.ref.png
Binary files differ
diff --git a/test/reference/clip-disjoint.traps.argb32.ref.png b/test/reference/clip-disjoint.traps.argb32.ref.png
new file mode 100644
index 000000000..74ae9d869
--- /dev/null
+++ b/test/reference/clip-disjoint.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-disjoint.traps.rgb24.ref.png b/test/reference/clip-disjoint.traps.rgb24.ref.png
new file mode 100644
index 000000000..74ae9d869
--- /dev/null
+++ b/test/reference/clip-disjoint.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-empty-group.base.argb32.ref.png b/test/reference/clip-empty-group.base.argb32.ref.png
new file mode 100644
index 000000000..a59ca472d
--- /dev/null
+++ b/test/reference/clip-empty-group.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-empty-group.base.rgb24.ref.png b/test/reference/clip-empty-group.base.rgb24.ref.png
new file mode 100644
index 000000000..a59ca472d
--- /dev/null
+++ b/test/reference/clip-empty-group.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-empty-group.ref.png b/test/reference/clip-empty-group.ref.png
new file mode 100644
index 000000000..a59ca472d
--- /dev/null
+++ b/test/reference/clip-empty-group.ref.png
Binary files differ
diff --git a/test/reference/clip-empty-save.base.argb32.ref.png b/test/reference/clip-empty-save.base.argb32.ref.png
new file mode 100644
index 000000000..1ed070cae
--- /dev/null
+++ b/test/reference/clip-empty-save.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-empty-save.base.rgb24.ref.png b/test/reference/clip-empty-save.base.rgb24.ref.png
new file mode 100644
index 000000000..1ed070cae
--- /dev/null
+++ b/test/reference/clip-empty-save.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-empty-save.ref.png b/test/reference/clip-empty-save.ref.png
new file mode 100644
index 000000000..6c14df51f
--- /dev/null
+++ b/test/reference/clip-empty-save.ref.png
Binary files differ
diff --git a/test/reference/clip-empty.base.argb32.ref.png b/test/reference/clip-empty.base.argb32.ref.png
new file mode 100644
index 000000000..1ed070cae
--- /dev/null
+++ b/test/reference/clip-empty.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-empty.base.rgb24.ref.png b/test/reference/clip-empty.base.rgb24.ref.png
new file mode 100644
index 000000000..1ed070cae
--- /dev/null
+++ b/test/reference/clip-empty.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-empty.ref.png b/test/reference/clip-empty.ref.png
new file mode 100644
index 000000000..6c14df51f
--- /dev/null
+++ b/test/reference/clip-empty.ref.png
Binary files differ
diff --git a/test/reference/clip-fill-eo-unbounded.argb32.ref.png b/test/reference/clip-fill-eo-unbounded.argb32.ref.png
new file mode 100644
index 000000000..be56f728d
--- /dev/null
+++ b/test/reference/clip-fill-eo-unbounded.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-fill-eo-unbounded.base.argb32.ref.png b/test/reference/clip-fill-eo-unbounded.base.argb32.ref.png
new file mode 100644
index 000000000..81ecfb9a6
--- /dev/null
+++ b/test/reference/clip-fill-eo-unbounded.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-fill-eo-unbounded.base.rgb24.ref.png b/test/reference/clip-fill-eo-unbounded.base.rgb24.ref.png
new file mode 100644
index 000000000..d6a5939b7
--- /dev/null
+++ b/test/reference/clip-fill-eo-unbounded.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-fill-eo-unbounded.image16.ref.png b/test/reference/clip-fill-eo-unbounded.image16.ref.png
new file mode 100644
index 000000000..e0e66ff7b
--- /dev/null
+++ b/test/reference/clip-fill-eo-unbounded.image16.ref.png
Binary files differ
diff --git a/test/reference/clip-fill-eo-unbounded.mask.argb32.ref.png b/test/reference/clip-fill-eo-unbounded.mask.argb32.ref.png
new file mode 100644
index 000000000..2340bdf12
--- /dev/null
+++ b/test/reference/clip-fill-eo-unbounded.mask.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-fill-eo-unbounded.mask.rgb24.ref.png b/test/reference/clip-fill-eo-unbounded.mask.rgb24.ref.png
new file mode 100644
index 000000000..299bd72a8
--- /dev/null
+++ b/test/reference/clip-fill-eo-unbounded.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-fill-eo-unbounded.quartz.argb32.ref.png b/test/reference/clip-fill-eo-unbounded.quartz.argb32.ref.png
new file mode 100644
index 000000000..342300095
--- /dev/null
+++ b/test/reference/clip-fill-eo-unbounded.quartz.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-fill-eo-unbounded.quartz.rgb24.ref.png b/test/reference/clip-fill-eo-unbounded.quartz.rgb24.ref.png
new file mode 100644
index 000000000..1612801bd
--- /dev/null
+++ b/test/reference/clip-fill-eo-unbounded.quartz.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-fill-eo-unbounded.rgb24.ref.png b/test/reference/clip-fill-eo-unbounded.rgb24.ref.png
new file mode 100644
index 000000000..e78ef0a32
--- /dev/null
+++ b/test/reference/clip-fill-eo-unbounded.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-fill-eo-unbounded.svg12.rgb24.xfail.png b/test/reference/clip-fill-eo-unbounded.svg12.rgb24.xfail.png
new file mode 100644
index 000000000..f949de1ad
--- /dev/null
+++ b/test/reference/clip-fill-eo-unbounded.svg12.rgb24.xfail.png
Binary files differ
diff --git a/test/reference/clip-fill-eo-unbounded.traps.argb32.ref.png b/test/reference/clip-fill-eo-unbounded.traps.argb32.ref.png
new file mode 100644
index 000000000..19b9f0909
--- /dev/null
+++ b/test/reference/clip-fill-eo-unbounded.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-fill-eo-unbounded.traps.rgb24.ref.png b/test/reference/clip-fill-eo-unbounded.traps.rgb24.ref.png
new file mode 100644
index 000000000..1ad0b176b
--- /dev/null
+++ b/test/reference/clip-fill-eo-unbounded.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-fill-eo-unbounded.xlib-fallback.rgb24.ref.png b/test/reference/clip-fill-eo-unbounded.xlib-fallback.rgb24.ref.png
new file mode 100644
index 000000000..ec258968e
--- /dev/null
+++ b/test/reference/clip-fill-eo-unbounded.xlib-fallback.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-fill-no-op.base.argb32.ref.png b/test/reference/clip-fill-no-op.base.argb32.ref.png
new file mode 100644
index 000000000..2256461a9
--- /dev/null
+++ b/test/reference/clip-fill-no-op.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-fill-no-op.base.rgb24.ref.png b/test/reference/clip-fill-no-op.base.rgb24.ref.png
new file mode 100644
index 000000000..2256461a9
--- /dev/null
+++ b/test/reference/clip-fill-no-op.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-fill-no-op.image16.ref.png b/test/reference/clip-fill-no-op.image16.ref.png
new file mode 100644
index 000000000..cf0c74ad8
--- /dev/null
+++ b/test/reference/clip-fill-no-op.image16.ref.png
Binary files differ
diff --git a/test/reference/clip-fill-no-op.ref.png b/test/reference/clip-fill-no-op.ref.png
new file mode 100644
index 000000000..2256461a9
--- /dev/null
+++ b/test/reference/clip-fill-no-op.ref.png
Binary files differ
diff --git a/test/reference/clip-fill-nz-unbounded.argb32.ref.png b/test/reference/clip-fill-nz-unbounded.argb32.ref.png
new file mode 100644
index 000000000..be56f728d
--- /dev/null
+++ b/test/reference/clip-fill-nz-unbounded.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-fill-nz-unbounded.base.argb32.ref.png b/test/reference/clip-fill-nz-unbounded.base.argb32.ref.png
new file mode 100644
index 000000000..81ecfb9a6
--- /dev/null
+++ b/test/reference/clip-fill-nz-unbounded.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-fill-nz-unbounded.base.rgb24.ref.png b/test/reference/clip-fill-nz-unbounded.base.rgb24.ref.png
new file mode 100644
index 000000000..d6a5939b7
--- /dev/null
+++ b/test/reference/clip-fill-nz-unbounded.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-fill-nz-unbounded.image16.ref.png b/test/reference/clip-fill-nz-unbounded.image16.ref.png
new file mode 100644
index 000000000..e0e66ff7b
--- /dev/null
+++ b/test/reference/clip-fill-nz-unbounded.image16.ref.png
Binary files differ
diff --git a/test/reference/clip-fill-nz-unbounded.mask.argb32.ref.png b/test/reference/clip-fill-nz-unbounded.mask.argb32.ref.png
new file mode 100644
index 000000000..05b26282c
--- /dev/null
+++ b/test/reference/clip-fill-nz-unbounded.mask.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-fill-nz-unbounded.mask.rgb24.ref.png b/test/reference/clip-fill-nz-unbounded.mask.rgb24.ref.png
new file mode 100644
index 000000000..9ce760b13
--- /dev/null
+++ b/test/reference/clip-fill-nz-unbounded.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-fill-nz-unbounded.quartz.argb32.ref.png b/test/reference/clip-fill-nz-unbounded.quartz.argb32.ref.png
new file mode 100644
index 000000000..342300095
--- /dev/null
+++ b/test/reference/clip-fill-nz-unbounded.quartz.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-fill-nz-unbounded.quartz.rgb24.ref.png b/test/reference/clip-fill-nz-unbounded.quartz.rgb24.ref.png
new file mode 100644
index 000000000..1612801bd
--- /dev/null
+++ b/test/reference/clip-fill-nz-unbounded.quartz.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-fill-nz-unbounded.rgb24.ref.png b/test/reference/clip-fill-nz-unbounded.rgb24.ref.png
new file mode 100644
index 000000000..e78ef0a32
--- /dev/null
+++ b/test/reference/clip-fill-nz-unbounded.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-fill-nz-unbounded.svg12.rgb24.xfail.png b/test/reference/clip-fill-nz-unbounded.svg12.rgb24.xfail.png
new file mode 100644
index 000000000..f949de1ad
--- /dev/null
+++ b/test/reference/clip-fill-nz-unbounded.svg12.rgb24.xfail.png
Binary files differ
diff --git a/test/reference/clip-fill-nz-unbounded.traps.argb32.ref.png b/test/reference/clip-fill-nz-unbounded.traps.argb32.ref.png
new file mode 100644
index 000000000..19b9f0909
--- /dev/null
+++ b/test/reference/clip-fill-nz-unbounded.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-fill-nz-unbounded.traps.rgb24.ref.png b/test/reference/clip-fill-nz-unbounded.traps.rgb24.ref.png
new file mode 100644
index 000000000..1ad0b176b
--- /dev/null
+++ b/test/reference/clip-fill-nz-unbounded.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-fill-nz-unbounded.xlib-fallback.rgb24.ref.png b/test/reference/clip-fill-nz-unbounded.xlib-fallback.rgb24.ref.png
new file mode 100644
index 000000000..ec258968e
--- /dev/null
+++ b/test/reference/clip-fill-nz-unbounded.xlib-fallback.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-fill-rule-pixel-aligned.base.argb32.ref.png b/test/reference/clip-fill-rule-pixel-aligned.base.argb32.ref.png
new file mode 100644
index 000000000..9b82c4b5f
--- /dev/null
+++ b/test/reference/clip-fill-rule-pixel-aligned.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-fill-rule-pixel-aligned.base.rgb24.ref.png b/test/reference/clip-fill-rule-pixel-aligned.base.rgb24.ref.png
new file mode 100644
index 000000000..0b4f06883
--- /dev/null
+++ b/test/reference/clip-fill-rule-pixel-aligned.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-fill-rule-pixel-aligned.ref.png b/test/reference/clip-fill-rule-pixel-aligned.ref.png
new file mode 100644
index 000000000..66eb6852e
--- /dev/null
+++ b/test/reference/clip-fill-rule-pixel-aligned.ref.png
Binary files differ
diff --git a/test/reference/clip-fill-rule.argb32.ref.png b/test/reference/clip-fill-rule.argb32.ref.png
new file mode 100644
index 000000000..f32db7c36
--- /dev/null
+++ b/test/reference/clip-fill-rule.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-fill-rule.base.argb32.ref.png b/test/reference/clip-fill-rule.base.argb32.ref.png
new file mode 100644
index 000000000..cb23ea61d
--- /dev/null
+++ b/test/reference/clip-fill-rule.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-fill-rule.base.rgb24.ref.png b/test/reference/clip-fill-rule.base.rgb24.ref.png
new file mode 100644
index 000000000..5265ddea9
--- /dev/null
+++ b/test/reference/clip-fill-rule.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-fill-rule.image16.ref.png b/test/reference/clip-fill-rule.image16.ref.png
new file mode 100644
index 000000000..101449d33
--- /dev/null
+++ b/test/reference/clip-fill-rule.image16.ref.png
Binary files differ
diff --git a/test/reference/clip-fill-rule.pdf.argb32.ref.png b/test/reference/clip-fill-rule.pdf.argb32.ref.png
new file mode 100644
index 000000000..0d9938e77
--- /dev/null
+++ b/test/reference/clip-fill-rule.pdf.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-fill-rule.ps.argb32.ref.png b/test/reference/clip-fill-rule.ps.argb32.ref.png
new file mode 100644
index 000000000..1b8943491
--- /dev/null
+++ b/test/reference/clip-fill-rule.ps.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-fill-rule.ps.rgb24.ref.png b/test/reference/clip-fill-rule.ps.rgb24.ref.png
new file mode 100644
index 000000000..1b061b718
--- /dev/null
+++ b/test/reference/clip-fill-rule.ps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-fill-rule.quartz.rgb24.ref.png b/test/reference/clip-fill-rule.quartz.rgb24.ref.png
new file mode 100644
index 000000000..c95f290d8
--- /dev/null
+++ b/test/reference/clip-fill-rule.quartz.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-fill-rule.rgb24.ref.png b/test/reference/clip-fill-rule.rgb24.ref.png
new file mode 100644
index 000000000..e180fccbd
--- /dev/null
+++ b/test/reference/clip-fill-rule.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-fill-rule.test-paginated.rgb24.ref.png b/test/reference/clip-fill-rule.test-paginated.rgb24.ref.png
new file mode 100644
index 000000000..d21472dc5
--- /dev/null
+++ b/test/reference/clip-fill-rule.test-paginated.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-fill-rule.traps.argb32.ref.png b/test/reference/clip-fill-rule.traps.argb32.ref.png
new file mode 100644
index 000000000..6b083a787
--- /dev/null
+++ b/test/reference/clip-fill-rule.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-fill-rule.traps.rgb24.ref.png b/test/reference/clip-fill-rule.traps.rgb24.ref.png
new file mode 100644
index 000000000..d21472dc5
--- /dev/null
+++ b/test/reference/clip-fill-rule.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-fill.base.argb32.ref.png b/test/reference/clip-fill.base.argb32.ref.png
new file mode 100644
index 000000000..72dc2298a
--- /dev/null
+++ b/test/reference/clip-fill.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-fill.base.rgb24.ref.png b/test/reference/clip-fill.base.rgb24.ref.png
new file mode 100644
index 000000000..72dc2298a
--- /dev/null
+++ b/test/reference/clip-fill.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-fill.image16.ref.png b/test/reference/clip-fill.image16.ref.png
new file mode 100644
index 000000000..24595ba2a
--- /dev/null
+++ b/test/reference/clip-fill.image16.ref.png
Binary files differ
diff --git a/test/reference/clip-fill.mask.argb32.ref.png b/test/reference/clip-fill.mask.argb32.ref.png
new file mode 100644
index 000000000..c3f27003c
--- /dev/null
+++ b/test/reference/clip-fill.mask.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-fill.mask.rgb24.ref.png b/test/reference/clip-fill.mask.rgb24.ref.png
new file mode 100644
index 000000000..c3f27003c
--- /dev/null
+++ b/test/reference/clip-fill.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-fill.ps.xfail.png b/test/reference/clip-fill.ps.xfail.png
new file mode 100644
index 000000000..d0aeaf142
--- /dev/null
+++ b/test/reference/clip-fill.ps.xfail.png
Binary files differ
diff --git a/test/reference/clip-fill.quartz.ref.png b/test/reference/clip-fill.quartz.ref.png
new file mode 100644
index 000000000..4f235b4dc
--- /dev/null
+++ b/test/reference/clip-fill.quartz.ref.png
Binary files differ
diff --git a/test/reference/clip-fill.ref.png b/test/reference/clip-fill.ref.png
new file mode 100644
index 000000000..7f0785725
--- /dev/null
+++ b/test/reference/clip-fill.ref.png
Binary files differ
diff --git a/test/reference/clip-fill.traps.argb32.ref.png b/test/reference/clip-fill.traps.argb32.ref.png
new file mode 100644
index 000000000..d6e84a3ef
--- /dev/null
+++ b/test/reference/clip-fill.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-fill.traps.rgb24.ref.png b/test/reference/clip-fill.traps.rgb24.ref.png
new file mode 100644
index 000000000..d6e84a3ef
--- /dev/null
+++ b/test/reference/clip-fill.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-fill.xlib-fallback.ref.png b/test/reference/clip-fill.xlib-fallback.ref.png
new file mode 100644
index 000000000..064b0cfb0
--- /dev/null
+++ b/test/reference/clip-fill.xlib-fallback.ref.png
Binary files differ
diff --git a/test/reference/clip-group-shapes-aligned-rectangles.base.argb32.ref.png b/test/reference/clip-group-shapes-aligned-rectangles.base.argb32.ref.png
new file mode 100644
index 000000000..cba75078a
--- /dev/null
+++ b/test/reference/clip-group-shapes-aligned-rectangles.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-group-shapes-aligned-rectangles.base.rgb24.ref.png b/test/reference/clip-group-shapes-aligned-rectangles.base.rgb24.ref.png
new file mode 100644
index 000000000..cba75078a
--- /dev/null
+++ b/test/reference/clip-group-shapes-aligned-rectangles.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-group-shapes-aligned-rectangles.ref.png b/test/reference/clip-group-shapes-aligned-rectangles.ref.png
new file mode 100644
index 000000000..cba75078a
--- /dev/null
+++ b/test/reference/clip-group-shapes-aligned-rectangles.ref.png
Binary files differ
diff --git a/test/reference/clip-group-shapes-circles.base.argb32.ref.png b/test/reference/clip-group-shapes-circles.base.argb32.ref.png
new file mode 100644
index 000000000..7dd6a8353
--- /dev/null
+++ b/test/reference/clip-group-shapes-circles.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-group-shapes-circles.base.rgb24.ref.png b/test/reference/clip-group-shapes-circles.base.rgb24.ref.png
new file mode 100644
index 000000000..7dd6a8353
--- /dev/null
+++ b/test/reference/clip-group-shapes-circles.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-group-shapes-circles.mask.argb32.ref.png b/test/reference/clip-group-shapes-circles.mask.argb32.ref.png
new file mode 100644
index 000000000..7dd6a8353
--- /dev/null
+++ b/test/reference/clip-group-shapes-circles.mask.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-group-shapes-circles.mask.rgb24.ref.png b/test/reference/clip-group-shapes-circles.mask.rgb24.ref.png
new file mode 100644
index 000000000..7dd6a8353
--- /dev/null
+++ b/test/reference/clip-group-shapes-circles.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-group-shapes-circles.ps.ref.png b/test/reference/clip-group-shapes-circles.ps.ref.png
new file mode 100644
index 000000000..be6203f25
--- /dev/null
+++ b/test/reference/clip-group-shapes-circles.ps.ref.png
Binary files differ
diff --git a/test/reference/clip-group-shapes-circles.quartz.ref.png b/test/reference/clip-group-shapes-circles.quartz.ref.png
new file mode 100644
index 000000000..c2ac9ea49
--- /dev/null
+++ b/test/reference/clip-group-shapes-circles.quartz.ref.png
Binary files differ
diff --git a/test/reference/clip-group-shapes-circles.ref.png b/test/reference/clip-group-shapes-circles.ref.png
new file mode 100644
index 000000000..abb11e52e
--- /dev/null
+++ b/test/reference/clip-group-shapes-circles.ref.png
Binary files differ
diff --git a/test/reference/clip-group-shapes-circles.traps.argb32.ref.png b/test/reference/clip-group-shapes-circles.traps.argb32.ref.png
new file mode 100644
index 000000000..3b8114691
--- /dev/null
+++ b/test/reference/clip-group-shapes-circles.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-group-shapes-circles.traps.rgb24.ref.png b/test/reference/clip-group-shapes-circles.traps.rgb24.ref.png
new file mode 100644
index 000000000..3b8114691
--- /dev/null
+++ b/test/reference/clip-group-shapes-circles.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-group-shapes-unaligned-rectangles.base.argb32.ref.png b/test/reference/clip-group-shapes-unaligned-rectangles.base.argb32.ref.png
new file mode 100644
index 000000000..2ad411824
--- /dev/null
+++ b/test/reference/clip-group-shapes-unaligned-rectangles.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-group-shapes-unaligned-rectangles.base.rgb24.ref.png b/test/reference/clip-group-shapes-unaligned-rectangles.base.rgb24.ref.png
new file mode 100644
index 000000000..2ad411824
--- /dev/null
+++ b/test/reference/clip-group-shapes-unaligned-rectangles.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-group-shapes-unaligned-rectangles.mask.argb32.ref.png b/test/reference/clip-group-shapes-unaligned-rectangles.mask.argb32.ref.png
new file mode 100644
index 000000000..877e78bd7
--- /dev/null
+++ b/test/reference/clip-group-shapes-unaligned-rectangles.mask.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-group-shapes-unaligned-rectangles.mask.rgb24.ref.png b/test/reference/clip-group-shapes-unaligned-rectangles.mask.rgb24.ref.png
new file mode 100644
index 000000000..877e78bd7
--- /dev/null
+++ b/test/reference/clip-group-shapes-unaligned-rectangles.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-group-shapes-unaligned-rectangles.ref.png b/test/reference/clip-group-shapes-unaligned-rectangles.ref.png
new file mode 100644
index 000000000..2ad411824
--- /dev/null
+++ b/test/reference/clip-group-shapes-unaligned-rectangles.ref.png
Binary files differ
diff --git a/test/reference/clip-group-shapes-unaligned-rectangles.traps.argb32.ref.png b/test/reference/clip-group-shapes-unaligned-rectangles.traps.argb32.ref.png
new file mode 100644
index 000000000..877e78bd7
--- /dev/null
+++ b/test/reference/clip-group-shapes-unaligned-rectangles.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-group-shapes-unaligned-rectangles.traps.rgb24.ref.png b/test/reference/clip-group-shapes-unaligned-rectangles.traps.rgb24.ref.png
new file mode 100644
index 000000000..877e78bd7
--- /dev/null
+++ b/test/reference/clip-group-shapes-unaligned-rectangles.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-image.base.argb32.ref.png b/test/reference/clip-image.base.argb32.ref.png
new file mode 100644
index 000000000..0f71f7360
--- /dev/null
+++ b/test/reference/clip-image.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-image.base.rgb24.ref.png b/test/reference/clip-image.base.rgb24.ref.png
new file mode 100644
index 000000000..0f71f7360
--- /dev/null
+++ b/test/reference/clip-image.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-image.image16.ref.png b/test/reference/clip-image.image16.ref.png
new file mode 100644
index 000000000..770891aab
--- /dev/null
+++ b/test/reference/clip-image.image16.ref.png
Binary files differ
diff --git a/test/reference/clip-image.mask.argb32.ref.png b/test/reference/clip-image.mask.argb32.ref.png
new file mode 100644
index 000000000..86c28afd7
--- /dev/null
+++ b/test/reference/clip-image.mask.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-image.mask.rgb24.ref.png b/test/reference/clip-image.mask.rgb24.ref.png
new file mode 100644
index 000000000..86c28afd7
--- /dev/null
+++ b/test/reference/clip-image.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-image.ps.ref.png b/test/reference/clip-image.ps.ref.png
new file mode 100644
index 000000000..b2422495f
--- /dev/null
+++ b/test/reference/clip-image.ps.ref.png
Binary files differ
diff --git a/test/reference/clip-image.ref.png b/test/reference/clip-image.ref.png
new file mode 100644
index 000000000..0f71f7360
--- /dev/null
+++ b/test/reference/clip-image.ref.png
Binary files differ
diff --git a/test/reference/clip-image.traps.argb32.ref.png b/test/reference/clip-image.traps.argb32.ref.png
new file mode 100644
index 000000000..062c721f5
--- /dev/null
+++ b/test/reference/clip-image.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-image.traps.rgb24.ref.png b/test/reference/clip-image.traps.rgb24.ref.png
new file mode 100644
index 000000000..062c721f5
--- /dev/null
+++ b/test/reference/clip-image.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-intersect.base.argb32.ref.png b/test/reference/clip-intersect.base.argb32.ref.png
new file mode 100644
index 000000000..6627b3a50
--- /dev/null
+++ b/test/reference/clip-intersect.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-intersect.base.rgb24.ref.png b/test/reference/clip-intersect.base.rgb24.ref.png
new file mode 100644
index 000000000..6627b3a50
--- /dev/null
+++ b/test/reference/clip-intersect.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-intersect.ref.png b/test/reference/clip-intersect.ref.png
new file mode 100644
index 000000000..5f2de3764
--- /dev/null
+++ b/test/reference/clip-intersect.ref.png
Binary files differ
diff --git a/test/reference/clip-intersect.traps.argb32.ref.png b/test/reference/clip-intersect.traps.argb32.ref.png
new file mode 100644
index 000000000..2e97b5414
--- /dev/null
+++ b/test/reference/clip-intersect.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-intersect.traps.rgb24.ref.png b/test/reference/clip-intersect.traps.rgb24.ref.png
new file mode 100644
index 000000000..2e97b5414
--- /dev/null
+++ b/test/reference/clip-intersect.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-mixed-antialias.base.argb32.ref.png b/test/reference/clip-mixed-antialias.base.argb32.ref.png
new file mode 100644
index 000000000..982530cb8
--- /dev/null
+++ b/test/reference/clip-mixed-antialias.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-mixed-antialias.base.rgb24.ref.png b/test/reference/clip-mixed-antialias.base.rgb24.ref.png
new file mode 100644
index 000000000..982530cb8
--- /dev/null
+++ b/test/reference/clip-mixed-antialias.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-mixed-antialias.ref.png b/test/reference/clip-mixed-antialias.ref.png
new file mode 100644
index 000000000..243c4dde6
--- /dev/null
+++ b/test/reference/clip-mixed-antialias.ref.png
Binary files differ
diff --git a/test/reference/clip-mixed-antialias.traps.argb32.ref.png b/test/reference/clip-mixed-antialias.traps.argb32.ref.png
new file mode 100644
index 000000000..982530cb8
--- /dev/null
+++ b/test/reference/clip-mixed-antialias.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-mixed-antialias.traps.rgb24.ref.png b/test/reference/clip-mixed-antialias.traps.rgb24.ref.png
new file mode 100644
index 000000000..982530cb8
--- /dev/null
+++ b/test/reference/clip-mixed-antialias.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-nesting.argb32.ref.png b/test/reference/clip-nesting.argb32.ref.png
new file mode 100644
index 000000000..c82ed463b
--- /dev/null
+++ b/test/reference/clip-nesting.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-nesting.base.argb32.ref.png b/test/reference/clip-nesting.base.argb32.ref.png
new file mode 100644
index 000000000..ce0cc0d08
--- /dev/null
+++ b/test/reference/clip-nesting.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-nesting.base.rgb24.ref.png b/test/reference/clip-nesting.base.rgb24.ref.png
new file mode 100644
index 000000000..524784371
--- /dev/null
+++ b/test/reference/clip-nesting.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-nesting.mask.rgb24.ref.png b/test/reference/clip-nesting.mask.rgb24.ref.png
new file mode 100644
index 000000000..524784371
--- /dev/null
+++ b/test/reference/clip-nesting.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-nesting.pdf.argb32.ref.png b/test/reference/clip-nesting.pdf.argb32.ref.png
new file mode 100644
index 000000000..78ae6e080
--- /dev/null
+++ b/test/reference/clip-nesting.pdf.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-nesting.ps.argb32.ref.png b/test/reference/clip-nesting.ps.argb32.ref.png
new file mode 100644
index 000000000..8a0239be5
--- /dev/null
+++ b/test/reference/clip-nesting.ps.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-nesting.ps.rgb24.ref.png b/test/reference/clip-nesting.ps.rgb24.ref.png
new file mode 100644
index 000000000..f9e1ac9fc
--- /dev/null
+++ b/test/reference/clip-nesting.ps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-nesting.quartz.argb32.ref.png b/test/reference/clip-nesting.quartz.argb32.ref.png
new file mode 100644
index 000000000..7bc187c7e
--- /dev/null
+++ b/test/reference/clip-nesting.quartz.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-nesting.quartz.rgb24.ref.png b/test/reference/clip-nesting.quartz.rgb24.ref.png
new file mode 100644
index 000000000..926f5f590
--- /dev/null
+++ b/test/reference/clip-nesting.quartz.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-nesting.rgb24.ref.png b/test/reference/clip-nesting.rgb24.ref.png
new file mode 100644
index 000000000..93c5b1713
--- /dev/null
+++ b/test/reference/clip-nesting.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-nesting.test-paginated.rgb24.ref.png b/test/reference/clip-nesting.test-paginated.rgb24.ref.png
new file mode 100644
index 000000000..d087ab6c1
--- /dev/null
+++ b/test/reference/clip-nesting.test-paginated.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-nesting.traps.argb32.ref.png b/test/reference/clip-nesting.traps.argb32.ref.png
new file mode 100644
index 000000000..01168dfe8
--- /dev/null
+++ b/test/reference/clip-nesting.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-nesting.traps.rgb24.ref.png b/test/reference/clip-nesting.traps.rgb24.ref.png
new file mode 100644
index 000000000..d087ab6c1
--- /dev/null
+++ b/test/reference/clip-nesting.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-operator.argb32.ref.png b/test/reference/clip-operator.argb32.ref.png
new file mode 100644
index 000000000..d041a2f6b
--- /dev/null
+++ b/test/reference/clip-operator.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-operator.base.argb32.ref.png b/test/reference/clip-operator.base.argb32.ref.png
new file mode 100644
index 000000000..f7697bafe
--- /dev/null
+++ b/test/reference/clip-operator.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-operator.base.rgb24.ref.png b/test/reference/clip-operator.base.rgb24.ref.png
new file mode 100644
index 000000000..eed34690e
--- /dev/null
+++ b/test/reference/clip-operator.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-operator.gl.argb32.ref.png b/test/reference/clip-operator.gl.argb32.ref.png
new file mode 100644
index 000000000..92d8b755c
--- /dev/null
+++ b/test/reference/clip-operator.gl.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-operator.image16.ref.png b/test/reference/clip-operator.image16.ref.png
new file mode 100644
index 000000000..ab8cd9b89
--- /dev/null
+++ b/test/reference/clip-operator.image16.ref.png
Binary files differ
diff --git a/test/reference/clip-operator.mask.argb32.ref.png b/test/reference/clip-operator.mask.argb32.ref.png
new file mode 100644
index 000000000..8db1a07c2
--- /dev/null
+++ b/test/reference/clip-operator.mask.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-operator.mask.rgb24.ref.png b/test/reference/clip-operator.mask.rgb24.ref.png
new file mode 100644
index 000000000..ddd1ec376
--- /dev/null
+++ b/test/reference/clip-operator.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-operator.pdf.argb32.ref.png b/test/reference/clip-operator.pdf.argb32.ref.png
new file mode 100644
index 000000000..7f8c93eaa
--- /dev/null
+++ b/test/reference/clip-operator.pdf.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-operator.pdf.rgb24.ref.png b/test/reference/clip-operator.pdf.rgb24.ref.png
new file mode 100644
index 000000000..fc4f431d6
--- /dev/null
+++ b/test/reference/clip-operator.pdf.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-operator.ps2.rgb24.ref.png b/test/reference/clip-operator.ps2.rgb24.ref.png
new file mode 100644
index 000000000..52452993a
--- /dev/null
+++ b/test/reference/clip-operator.ps2.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-operator.ps3.argb32.ref.png b/test/reference/clip-operator.ps3.argb32.ref.png
new file mode 100644
index 000000000..cd207d924
--- /dev/null
+++ b/test/reference/clip-operator.ps3.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-operator.ps3.ref.png b/test/reference/clip-operator.ps3.ref.png
new file mode 100644
index 000000000..dee12ca8c
--- /dev/null
+++ b/test/reference/clip-operator.ps3.ref.png
Binary files differ
diff --git a/test/reference/clip-operator.ps3.rgb24.ref.png b/test/reference/clip-operator.ps3.rgb24.ref.png
new file mode 100644
index 000000000..52452993a
--- /dev/null
+++ b/test/reference/clip-operator.ps3.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-operator.quartz.argb32.ref.png b/test/reference/clip-operator.quartz.argb32.ref.png
new file mode 100644
index 000000000..ecf6ee2af
--- /dev/null
+++ b/test/reference/clip-operator.quartz.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-operator.quartz.rgb24.ref.png b/test/reference/clip-operator.quartz.rgb24.ref.png
new file mode 100644
index 000000000..67c628f91
--- /dev/null
+++ b/test/reference/clip-operator.quartz.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-operator.rgb24.ref.png b/test/reference/clip-operator.rgb24.ref.png
new file mode 100644
index 000000000..7e3a640ad
--- /dev/null
+++ b/test/reference/clip-operator.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-operator.svg12.argb32.xfail.png b/test/reference/clip-operator.svg12.argb32.xfail.png
new file mode 100644
index 000000000..a1b807226
--- /dev/null
+++ b/test/reference/clip-operator.svg12.argb32.xfail.png
Binary files differ
diff --git a/test/reference/clip-operator.svg12.rgb24.xfail.png b/test/reference/clip-operator.svg12.rgb24.xfail.png
new file mode 100644
index 000000000..95227701b
--- /dev/null
+++ b/test/reference/clip-operator.svg12.rgb24.xfail.png
Binary files differ
diff --git a/test/reference/clip-operator.test-paginated.argb32.ref.png b/test/reference/clip-operator.test-paginated.argb32.ref.png
new file mode 100644
index 000000000..0203b1db5
--- /dev/null
+++ b/test/reference/clip-operator.test-paginated.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-operator.traps.argb32.ref.png b/test/reference/clip-operator.traps.argb32.ref.png
new file mode 100644
index 000000000..76f9ee8dd
--- /dev/null
+++ b/test/reference/clip-operator.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-operator.traps.rgb24.ref.png b/test/reference/clip-operator.traps.rgb24.ref.png
new file mode 100644
index 000000000..f35c9d5d9
--- /dev/null
+++ b/test/reference/clip-operator.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-operator.xlib-fallback.ref.png b/test/reference/clip-operator.xlib-fallback.ref.png
new file mode 100644
index 000000000..9ef8637b6
--- /dev/null
+++ b/test/reference/clip-operator.xlib-fallback.ref.png
Binary files differ
diff --git a/test/reference/clip-polygons.base.argb32.ref.png b/test/reference/clip-polygons.base.argb32.ref.png
new file mode 100644
index 000000000..e139ef3f5
--- /dev/null
+++ b/test/reference/clip-polygons.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-polygons.base.rgb24.ref.png b/test/reference/clip-polygons.base.rgb24.ref.png
new file mode 100644
index 000000000..e139ef3f5
--- /dev/null
+++ b/test/reference/clip-polygons.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-polygons.mask.argb32.ref.png b/test/reference/clip-polygons.mask.argb32.ref.png
new file mode 100644
index 000000000..e139ef3f5
--- /dev/null
+++ b/test/reference/clip-polygons.mask.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-polygons.mask.rgb24.ref.png b/test/reference/clip-polygons.mask.rgb24.ref.png
new file mode 100644
index 000000000..e139ef3f5
--- /dev/null
+++ b/test/reference/clip-polygons.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-polygons.ref.png b/test/reference/clip-polygons.ref.png
new file mode 100644
index 000000000..1b76cd071
--- /dev/null
+++ b/test/reference/clip-polygons.ref.png
Binary files differ
diff --git a/test/reference/clip-polygons.traps.ref.png b/test/reference/clip-polygons.traps.ref.png
new file mode 100644
index 000000000..a8c5734bc
--- /dev/null
+++ b/test/reference/clip-polygons.traps.ref.png
Binary files differ
diff --git a/test/reference/clip-push-group.base.argb32.ref.png b/test/reference/clip-push-group.base.argb32.ref.png
new file mode 100644
index 000000000..86724a23b
--- /dev/null
+++ b/test/reference/clip-push-group.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-push-group.base.rgb24.ref.png b/test/reference/clip-push-group.base.rgb24.ref.png
new file mode 100644
index 000000000..86724a23b
--- /dev/null
+++ b/test/reference/clip-push-group.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-push-group.image16.ref.png b/test/reference/clip-push-group.image16.ref.png
new file mode 100644
index 000000000..24f4424fc
--- /dev/null
+++ b/test/reference/clip-push-group.image16.ref.png
Binary files differ
diff --git a/test/reference/clip-push-group.pdf.ref.png b/test/reference/clip-push-group.pdf.ref.png
new file mode 100644
index 000000000..37b58c598
--- /dev/null
+++ b/test/reference/clip-push-group.pdf.ref.png
Binary files differ
diff --git a/test/reference/clip-push-group.ps.ref.png b/test/reference/clip-push-group.ps.ref.png
new file mode 100644
index 000000000..7af9fe526
--- /dev/null
+++ b/test/reference/clip-push-group.ps.ref.png
Binary files differ
diff --git a/test/reference/clip-push-group.quartz.ref.png b/test/reference/clip-push-group.quartz.ref.png
new file mode 100644
index 000000000..22e15255d
--- /dev/null
+++ b/test/reference/clip-push-group.quartz.ref.png
Binary files differ
diff --git a/test/reference/clip-push-group.ref.png b/test/reference/clip-push-group.ref.png
new file mode 100644
index 000000000..6a90fb433
--- /dev/null
+++ b/test/reference/clip-push-group.ref.png
Binary files differ
diff --git a/test/reference/clip-push-group.svg.ref.png b/test/reference/clip-push-group.svg.ref.png
new file mode 100644
index 000000000..291b4738b
--- /dev/null
+++ b/test/reference/clip-push-group.svg.ref.png
Binary files differ
diff --git a/test/reference/clip-push-group.traps.argb32.ref.png b/test/reference/clip-push-group.traps.argb32.ref.png
new file mode 100644
index 000000000..de6ac632c
--- /dev/null
+++ b/test/reference/clip-push-group.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-push-group.traps.rgb24.ref.png b/test/reference/clip-push-group.traps.rgb24.ref.png
new file mode 100644
index 000000000..de6ac632c
--- /dev/null
+++ b/test/reference/clip-push-group.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-rectilinear.base.argb32.ref.png b/test/reference/clip-rectilinear.base.argb32.ref.png
new file mode 100644
index 000000000..9d910db57
--- /dev/null
+++ b/test/reference/clip-rectilinear.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-rectilinear.base.rgb24.ref.png b/test/reference/clip-rectilinear.base.rgb24.ref.png
new file mode 100644
index 000000000..9d910db57
--- /dev/null
+++ b/test/reference/clip-rectilinear.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-rectilinear.mask.argb32.ref.png b/test/reference/clip-rectilinear.mask.argb32.ref.png
new file mode 100644
index 000000000..2a27beca3
--- /dev/null
+++ b/test/reference/clip-rectilinear.mask.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-rectilinear.mask.rgb24.ref.png b/test/reference/clip-rectilinear.mask.rgb24.ref.png
new file mode 100644
index 000000000..2a27beca3
--- /dev/null
+++ b/test/reference/clip-rectilinear.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-rectilinear.ref.png b/test/reference/clip-rectilinear.ref.png
new file mode 100644
index 000000000..9d910db57
--- /dev/null
+++ b/test/reference/clip-rectilinear.ref.png
Binary files differ
diff --git a/test/reference/clip-rectilinear.traps.ref.png b/test/reference/clip-rectilinear.traps.ref.png
new file mode 100644
index 000000000..2a27beca3
--- /dev/null
+++ b/test/reference/clip-rectilinear.traps.ref.png
Binary files differ
diff --git a/test/reference/clip-rotate-image-surface-paint.base.argb32.ref.png b/test/reference/clip-rotate-image-surface-paint.base.argb32.ref.png
new file mode 100644
index 000000000..1093804d7
--- /dev/null
+++ b/test/reference/clip-rotate-image-surface-paint.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-rotate-image-surface-paint.base.rgb24.ref.png b/test/reference/clip-rotate-image-surface-paint.base.rgb24.ref.png
new file mode 100644
index 000000000..1093804d7
--- /dev/null
+++ b/test/reference/clip-rotate-image-surface-paint.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-rotate-image-surface-paint.ref.png b/test/reference/clip-rotate-image-surface-paint.ref.png
new file mode 100644
index 000000000..1093804d7
--- /dev/null
+++ b/test/reference/clip-rotate-image-surface-paint.ref.png
Binary files differ
diff --git a/test/reference/clip-shape.base.argb32.ref.png b/test/reference/clip-shape.base.argb32.ref.png
new file mode 100644
index 000000000..5d79521a9
--- /dev/null
+++ b/test/reference/clip-shape.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-shape.base.rgb24.ref.png b/test/reference/clip-shape.base.rgb24.ref.png
new file mode 100644
index 000000000..5d79521a9
--- /dev/null
+++ b/test/reference/clip-shape.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-shape.image16.ref.png b/test/reference/clip-shape.image16.ref.png
new file mode 100644
index 000000000..0ef06b238
--- /dev/null
+++ b/test/reference/clip-shape.image16.ref.png
Binary files differ
diff --git a/test/reference/clip-shape.mask.argb32.ref.png b/test/reference/clip-shape.mask.argb32.ref.png
new file mode 100644
index 000000000..03edf68f0
--- /dev/null
+++ b/test/reference/clip-shape.mask.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-shape.mask.rgb24.ref.png b/test/reference/clip-shape.mask.rgb24.ref.png
new file mode 100644
index 000000000..03edf68f0
--- /dev/null
+++ b/test/reference/clip-shape.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-shape.ps.ref.png b/test/reference/clip-shape.ps.ref.png
new file mode 100644
index 000000000..1125fb595
--- /dev/null
+++ b/test/reference/clip-shape.ps.ref.png
Binary files differ
diff --git a/test/reference/clip-shape.quartz.ref.png b/test/reference/clip-shape.quartz.ref.png
new file mode 100644
index 000000000..292340676
--- /dev/null
+++ b/test/reference/clip-shape.quartz.ref.png
Binary files differ
diff --git a/test/reference/clip-shape.ref.png b/test/reference/clip-shape.ref.png
new file mode 100644
index 000000000..83190e616
--- /dev/null
+++ b/test/reference/clip-shape.ref.png
Binary files differ
diff --git a/test/reference/clip-shape.traps.argb32.ref.png b/test/reference/clip-shape.traps.argb32.ref.png
new file mode 100644
index 000000000..362f24f91
--- /dev/null
+++ b/test/reference/clip-shape.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-shape.traps.rgb24.ref.png b/test/reference/clip-shape.traps.rgb24.ref.png
new file mode 100644
index 000000000..362f24f91
--- /dev/null
+++ b/test/reference/clip-shape.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-shape.xlib-fallback.ref.png b/test/reference/clip-shape.xlib-fallback.ref.png
new file mode 100644
index 000000000..e9aa94770
--- /dev/null
+++ b/test/reference/clip-shape.xlib-fallback.ref.png
Binary files differ
diff --git a/test/reference/clip-stroke-no-op.base.argb32.ref.png b/test/reference/clip-stroke-no-op.base.argb32.ref.png
new file mode 100644
index 000000000..2256461a9
--- /dev/null
+++ b/test/reference/clip-stroke-no-op.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-stroke-no-op.base.rgb24.ref.png b/test/reference/clip-stroke-no-op.base.rgb24.ref.png
new file mode 100644
index 000000000..2256461a9
--- /dev/null
+++ b/test/reference/clip-stroke-no-op.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-stroke-no-op.image16.ref.png b/test/reference/clip-stroke-no-op.image16.ref.png
new file mode 100644
index 000000000..cf0c74ad8
--- /dev/null
+++ b/test/reference/clip-stroke-no-op.image16.ref.png
Binary files differ
diff --git a/test/reference/clip-stroke-no-op.ref.png b/test/reference/clip-stroke-no-op.ref.png
new file mode 100644
index 000000000..2256461a9
--- /dev/null
+++ b/test/reference/clip-stroke-no-op.ref.png
Binary files differ
diff --git a/test/reference/clip-stroke-unbounded.argb32.ref.png b/test/reference/clip-stroke-unbounded.argb32.ref.png
new file mode 100644
index 000000000..7f603b70b
--- /dev/null
+++ b/test/reference/clip-stroke-unbounded.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-stroke-unbounded.base.argb32.ref.png b/test/reference/clip-stroke-unbounded.base.argb32.ref.png
new file mode 100644
index 000000000..de0d5892f
--- /dev/null
+++ b/test/reference/clip-stroke-unbounded.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-stroke-unbounded.base.rgb24.ref.png b/test/reference/clip-stroke-unbounded.base.rgb24.ref.png
new file mode 100644
index 000000000..7d204ee14
--- /dev/null
+++ b/test/reference/clip-stroke-unbounded.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-stroke-unbounded.image16.rgb24.ref.png b/test/reference/clip-stroke-unbounded.image16.rgb24.ref.png
new file mode 100644
index 000000000..2dfd48bac
--- /dev/null
+++ b/test/reference/clip-stroke-unbounded.image16.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-stroke-unbounded.mask.argb32.ref.png b/test/reference/clip-stroke-unbounded.mask.argb32.ref.png
new file mode 100644
index 000000000..274feb641
--- /dev/null
+++ b/test/reference/clip-stroke-unbounded.mask.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-stroke-unbounded.mask.rgb24.ref.png b/test/reference/clip-stroke-unbounded.mask.rgb24.ref.png
new file mode 100644
index 000000000..a9a8f7be4
--- /dev/null
+++ b/test/reference/clip-stroke-unbounded.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-stroke-unbounded.quartz.argb32.ref.png b/test/reference/clip-stroke-unbounded.quartz.argb32.ref.png
new file mode 100644
index 000000000..8bd5b3681
--- /dev/null
+++ b/test/reference/clip-stroke-unbounded.quartz.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-stroke-unbounded.quartz.rgb24.ref.png b/test/reference/clip-stroke-unbounded.quartz.rgb24.ref.png
new file mode 100644
index 000000000..5349f8494
--- /dev/null
+++ b/test/reference/clip-stroke-unbounded.quartz.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-stroke-unbounded.rgb24.ref.png b/test/reference/clip-stroke-unbounded.rgb24.ref.png
new file mode 100644
index 000000000..4a06c4bbc
--- /dev/null
+++ b/test/reference/clip-stroke-unbounded.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-stroke-unbounded.svg12.rgb24.xfail.png b/test/reference/clip-stroke-unbounded.svg12.rgb24.xfail.png
new file mode 100644
index 000000000..c35fc8326
--- /dev/null
+++ b/test/reference/clip-stroke-unbounded.svg12.rgb24.xfail.png
Binary files differ
diff --git a/test/reference/clip-stroke-unbounded.traps.argb32.ref.png b/test/reference/clip-stroke-unbounded.traps.argb32.ref.png
new file mode 100644
index 000000000..aea8cba70
--- /dev/null
+++ b/test/reference/clip-stroke-unbounded.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-stroke-unbounded.traps.rgb24.ref.png b/test/reference/clip-stroke-unbounded.traps.rgb24.ref.png
new file mode 100644
index 000000000..70cddacfa
--- /dev/null
+++ b/test/reference/clip-stroke-unbounded.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-stroke-unbounded.xlib-fallback.rgb24.ref.png b/test/reference/clip-stroke-unbounded.xlib-fallback.rgb24.ref.png
new file mode 100644
index 000000000..20ebfe443
--- /dev/null
+++ b/test/reference/clip-stroke-unbounded.xlib-fallback.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-stroke.base.argb32.ref.png b/test/reference/clip-stroke.base.argb32.ref.png
new file mode 100644
index 000000000..31ed15e32
--- /dev/null
+++ b/test/reference/clip-stroke.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-stroke.base.rgb24.ref.png b/test/reference/clip-stroke.base.rgb24.ref.png
new file mode 100644
index 000000000..31ed15e32
--- /dev/null
+++ b/test/reference/clip-stroke.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-stroke.image16.ref.png b/test/reference/clip-stroke.image16.ref.png
new file mode 100644
index 000000000..ad62af406
--- /dev/null
+++ b/test/reference/clip-stroke.image16.ref.png
Binary files differ
diff --git a/test/reference/clip-stroke.mask.argb32.ref.png b/test/reference/clip-stroke.mask.argb32.ref.png
new file mode 100644
index 000000000..afa7fc0dc
--- /dev/null
+++ b/test/reference/clip-stroke.mask.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-stroke.mask.rgb24.ref.png b/test/reference/clip-stroke.mask.rgb24.ref.png
new file mode 100644
index 000000000..afa7fc0dc
--- /dev/null
+++ b/test/reference/clip-stroke.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-stroke.ps.xfail.png b/test/reference/clip-stroke.ps.xfail.png
new file mode 100644
index 000000000..cc67b0882
--- /dev/null
+++ b/test/reference/clip-stroke.ps.xfail.png
Binary files differ
diff --git a/test/reference/clip-stroke.quartz.ref.png b/test/reference/clip-stroke.quartz.ref.png
new file mode 100644
index 000000000..994e31707
--- /dev/null
+++ b/test/reference/clip-stroke.quartz.ref.png
Binary files differ
diff --git a/test/reference/clip-stroke.ref.png b/test/reference/clip-stroke.ref.png
new file mode 100644
index 000000000..c29680713
--- /dev/null
+++ b/test/reference/clip-stroke.ref.png
Binary files differ
diff --git a/test/reference/clip-stroke.traps.argb32.ref.png b/test/reference/clip-stroke.traps.argb32.ref.png
new file mode 100644
index 000000000..36b113adc
--- /dev/null
+++ b/test/reference/clip-stroke.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-stroke.traps.rgb24.ref.png b/test/reference/clip-stroke.traps.rgb24.ref.png
new file mode 100644
index 000000000..36b113adc
--- /dev/null
+++ b/test/reference/clip-stroke.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-stroke.xlib-fallback.ref.png b/test/reference/clip-stroke.xlib-fallback.ref.png
new file mode 100644
index 000000000..cef5000f5
--- /dev/null
+++ b/test/reference/clip-stroke.xlib-fallback.ref.png
Binary files differ
diff --git a/test/reference/clip-text.base.argb32.ref.png b/test/reference/clip-text.base.argb32.ref.png
new file mode 100644
index 000000000..e2b2ca701
--- /dev/null
+++ b/test/reference/clip-text.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-text.base.rgb24.ref.png b/test/reference/clip-text.base.rgb24.ref.png
new file mode 100644
index 000000000..e2b2ca701
--- /dev/null
+++ b/test/reference/clip-text.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-text.image16.ref.png b/test/reference/clip-text.image16.ref.png
new file mode 100644
index 000000000..212295411
--- /dev/null
+++ b/test/reference/clip-text.image16.ref.png
Binary files differ
diff --git a/test/reference/clip-text.mask.argb32.ref.png b/test/reference/clip-text.mask.argb32.ref.png
new file mode 100644
index 000000000..98484cdd4
--- /dev/null
+++ b/test/reference/clip-text.mask.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-text.mask.rgb24.ref.png b/test/reference/clip-text.mask.rgb24.ref.png
new file mode 100644
index 000000000..98484cdd4
--- /dev/null
+++ b/test/reference/clip-text.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-text.ps.xfail.png b/test/reference/clip-text.ps.xfail.png
new file mode 100644
index 000000000..b50217d88
--- /dev/null
+++ b/test/reference/clip-text.ps.xfail.png
Binary files differ
diff --git a/test/reference/clip-text.quartz.ref.png b/test/reference/clip-text.quartz.ref.png
new file mode 100644
index 000000000..d251bfa08
--- /dev/null
+++ b/test/reference/clip-text.quartz.ref.png
Binary files differ
diff --git a/test/reference/clip-text.ref.png b/test/reference/clip-text.ref.png
new file mode 100644
index 000000000..c73d1fd35
--- /dev/null
+++ b/test/reference/clip-text.ref.png
Binary files differ
diff --git a/test/reference/clip-text.svg.ref.png b/test/reference/clip-text.svg.ref.png
new file mode 100644
index 000000000..a113b14ed
--- /dev/null
+++ b/test/reference/clip-text.svg.ref.png
Binary files differ
diff --git a/test/reference/clip-text.traps.argb32.ref.png b/test/reference/clip-text.traps.argb32.ref.png
new file mode 100644
index 000000000..2a682981c
--- /dev/null
+++ b/test/reference/clip-text.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-text.traps.rgb24.ref.png b/test/reference/clip-text.traps.rgb24.ref.png
new file mode 100644
index 000000000..2a682981c
--- /dev/null
+++ b/test/reference/clip-text.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-twice-rectangle.base.argb32.ref.png b/test/reference/clip-twice-rectangle.base.argb32.ref.png
new file mode 100644
index 000000000..d0e65ead3
--- /dev/null
+++ b/test/reference/clip-twice-rectangle.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-twice-rectangle.base.rgb24.ref.png b/test/reference/clip-twice-rectangle.base.rgb24.ref.png
new file mode 100644
index 000000000..d0e65ead3
--- /dev/null
+++ b/test/reference/clip-twice-rectangle.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-twice-rectangle.ref.png b/test/reference/clip-twice-rectangle.ref.png
new file mode 100644
index 000000000..d0e65ead3
--- /dev/null
+++ b/test/reference/clip-twice-rectangle.ref.png
Binary files differ
diff --git a/test/reference/clip-twice.argb32.ref.png b/test/reference/clip-twice.argb32.ref.png
new file mode 100644
index 000000000..03dc4a5be
--- /dev/null
+++ b/test/reference/clip-twice.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-twice.base.argb32.ref.png b/test/reference/clip-twice.base.argb32.ref.png
new file mode 100644
index 000000000..a3dcca4b4
--- /dev/null
+++ b/test/reference/clip-twice.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-twice.base.rgb24.ref.png b/test/reference/clip-twice.base.rgb24.ref.png
new file mode 100644
index 000000000..0c4aaba37
--- /dev/null
+++ b/test/reference/clip-twice.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-twice.image16.ref.png b/test/reference/clip-twice.image16.ref.png
new file mode 100644
index 000000000..d5a3f455a
--- /dev/null
+++ b/test/reference/clip-twice.image16.ref.png
Binary files differ
diff --git a/test/reference/clip-twice.mask.argb32.ref.png b/test/reference/clip-twice.mask.argb32.ref.png
new file mode 100644
index 000000000..828dd23b7
--- /dev/null
+++ b/test/reference/clip-twice.mask.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-twice.mask.rgb24.ref.png b/test/reference/clip-twice.mask.rgb24.ref.png
new file mode 100644
index 000000000..8b6baed5e
--- /dev/null
+++ b/test/reference/clip-twice.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-twice.pdf.argb32.ref.png b/test/reference/clip-twice.pdf.argb32.ref.png
new file mode 100644
index 000000000..2a7541fe2
--- /dev/null
+++ b/test/reference/clip-twice.pdf.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-twice.ps.argb32.ref.png b/test/reference/clip-twice.ps.argb32.ref.png
new file mode 100644
index 000000000..5d29d17f7
--- /dev/null
+++ b/test/reference/clip-twice.ps.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-twice.ps.rgb24.ref.png b/test/reference/clip-twice.ps.rgb24.ref.png
new file mode 100644
index 000000000..85eb890c5
--- /dev/null
+++ b/test/reference/clip-twice.ps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-twice.quartz.argb32.ref.png b/test/reference/clip-twice.quartz.argb32.ref.png
new file mode 100644
index 000000000..04b588d80
--- /dev/null
+++ b/test/reference/clip-twice.quartz.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-twice.quartz.rgb24.ref.png b/test/reference/clip-twice.quartz.rgb24.ref.png
new file mode 100644
index 000000000..eb4f62c2f
--- /dev/null
+++ b/test/reference/clip-twice.quartz.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-twice.rgb24.ref.png b/test/reference/clip-twice.rgb24.ref.png
new file mode 100644
index 000000000..c25fffa57
--- /dev/null
+++ b/test/reference/clip-twice.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-twice.test-paginated.argb32.ref.png b/test/reference/clip-twice.test-paginated.argb32.ref.png
new file mode 100644
index 000000000..ffd59aaf8
--- /dev/null
+++ b/test/reference/clip-twice.test-paginated.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-twice.test-paginated.rgb24.ref.png b/test/reference/clip-twice.test-paginated.rgb24.ref.png
new file mode 100644
index 000000000..e3d0ae49f
--- /dev/null
+++ b/test/reference/clip-twice.test-paginated.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-twice.traps.argb32.ref.png b/test/reference/clip-twice.traps.argb32.ref.png
new file mode 100644
index 000000000..057fc31f8
--- /dev/null
+++ b/test/reference/clip-twice.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-twice.traps.rgb24.ref.png b/test/reference/clip-twice.traps.rgb24.ref.png
new file mode 100644
index 000000000..6002d34ca
--- /dev/null
+++ b/test/reference/clip-twice.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-unbounded.base.argb32.ref.png b/test/reference/clip-unbounded.base.argb32.ref.png
new file mode 100644
index 000000000..0b6590565
--- /dev/null
+++ b/test/reference/clip-unbounded.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-unbounded.base.rgb24.ref.png b/test/reference/clip-unbounded.base.rgb24.ref.png
new file mode 100644
index 000000000..2baf9f464
--- /dev/null
+++ b/test/reference/clip-unbounded.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-unbounded.pdf.argb32.xfail.png b/test/reference/clip-unbounded.pdf.argb32.xfail.png
new file mode 100644
index 000000000..1ed070cae
--- /dev/null
+++ b/test/reference/clip-unbounded.pdf.argb32.xfail.png
Binary files differ
diff --git a/test/reference/clip-unbounded.pdf.rgb24.xfail.png b/test/reference/clip-unbounded.pdf.rgb24.xfail.png
new file mode 100644
index 000000000..1ed070cae
--- /dev/null
+++ b/test/reference/clip-unbounded.pdf.rgb24.xfail.png
Binary files differ
diff --git a/test/reference/clip-unbounded.ref.png b/test/reference/clip-unbounded.ref.png
new file mode 100644
index 000000000..0b6590565
--- /dev/null
+++ b/test/reference/clip-unbounded.ref.png
Binary files differ
diff --git a/test/reference/clip-unbounded.svg12.rgb24.xfail.png b/test/reference/clip-unbounded.svg12.rgb24.xfail.png
new file mode 100644
index 000000000..0b6590565
--- /dev/null
+++ b/test/reference/clip-unbounded.svg12.rgb24.xfail.png
Binary files differ
diff --git a/test/reference/clip-xlib-fallback.rgb24.ref.png b/test/reference/clip-xlib-fallback.rgb24.ref.png
new file mode 100644
index 000000000..062c721f5
--- /dev/null
+++ b/test/reference/clip-xlib-fallback.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-xlib-window.rgb24.ref.png b/test/reference/clip-xlib-window.rgb24.ref.png
new file mode 100644
index 000000000..062c721f5
--- /dev/null
+++ b/test/reference/clip-xlib-window.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-xlib.ref.png b/test/reference/clip-xlib.ref.png
new file mode 100644
index 000000000..062c721f5
--- /dev/null
+++ b/test/reference/clip-xlib.ref.png
Binary files differ
diff --git a/test/reference/clipped-group.base.argb32.ref.png b/test/reference/clipped-group.base.argb32.ref.png
new file mode 100644
index 000000000..bea4c751e
--- /dev/null
+++ b/test/reference/clipped-group.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/clipped-group.base.rgb24.ref.png b/test/reference/clipped-group.base.rgb24.ref.png
new file mode 100644
index 000000000..bea4c751e
--- /dev/null
+++ b/test/reference/clipped-group.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clipped-group.image16.ref.png b/test/reference/clipped-group.image16.ref.png
new file mode 100644
index 000000000..bf419f683
--- /dev/null
+++ b/test/reference/clipped-group.image16.ref.png
Binary files differ
diff --git a/test/reference/clipped-group.mask.argb32.ref.png b/test/reference/clipped-group.mask.argb32.ref.png
new file mode 100644
index 000000000..53b149fc8
--- /dev/null
+++ b/test/reference/clipped-group.mask.argb32.ref.png
Binary files differ
diff --git a/test/reference/clipped-group.mask.rgb24.ref.png b/test/reference/clipped-group.mask.rgb24.ref.png
new file mode 100644
index 000000000..53b149fc8
--- /dev/null
+++ b/test/reference/clipped-group.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clipped-group.pdf.ref.png b/test/reference/clipped-group.pdf.ref.png
new file mode 100644
index 000000000..23db5a4fd
--- /dev/null
+++ b/test/reference/clipped-group.pdf.ref.png
Binary files differ
diff --git a/test/reference/clipped-group.ps2.ref.png b/test/reference/clipped-group.ps2.ref.png
new file mode 100644
index 000000000..7a0f45c16
--- /dev/null
+++ b/test/reference/clipped-group.ps2.ref.png
Binary files differ
diff --git a/test/reference/clipped-group.ps3.ref.png b/test/reference/clipped-group.ps3.ref.png
new file mode 100644
index 000000000..7a0f45c16
--- /dev/null
+++ b/test/reference/clipped-group.ps3.ref.png
Binary files differ
diff --git a/test/reference/clipped-group.quartz.ref.png b/test/reference/clipped-group.quartz.ref.png
new file mode 100644
index 000000000..10e22f7a1
--- /dev/null
+++ b/test/reference/clipped-group.quartz.ref.png
Binary files differ
diff --git a/test/reference/clipped-group.ref.png b/test/reference/clipped-group.ref.png
new file mode 100644
index 000000000..245b16e56
--- /dev/null
+++ b/test/reference/clipped-group.ref.png
Binary files differ
diff --git a/test/reference/clipped-group.svg.ref.png b/test/reference/clipped-group.svg.ref.png
new file mode 100644
index 000000000..196aec049
--- /dev/null
+++ b/test/reference/clipped-group.svg.ref.png
Binary files differ
diff --git a/test/reference/clipped-group.traps.argb32.ref.png b/test/reference/clipped-group.traps.argb32.ref.png
new file mode 100644
index 000000000..b25c9f4db
--- /dev/null
+++ b/test/reference/clipped-group.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/clipped-group.traps.rgb24.ref.png b/test/reference/clipped-group.traps.rgb24.ref.png
new file mode 100644
index 000000000..b25c9f4db
--- /dev/null
+++ b/test/reference/clipped-group.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clipped-group.xlib-fallback.ref.png b/test/reference/clipped-group.xlib-fallback.ref.png
new file mode 100644
index 000000000..e0a5dc097
--- /dev/null
+++ b/test/reference/clipped-group.xlib-fallback.ref.png
Binary files differ
diff --git a/test/reference/clipped-surface.base.argb32.ref.png b/test/reference/clipped-surface.base.argb32.ref.png
new file mode 100644
index 000000000..8e8b0083e
--- /dev/null
+++ b/test/reference/clipped-surface.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/clipped-surface.base.rgb24.ref.png b/test/reference/clipped-surface.base.rgb24.ref.png
new file mode 100644
index 000000000..8e8b0083e
--- /dev/null
+++ b/test/reference/clipped-surface.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clipped-surface.image16.ref.png b/test/reference/clipped-surface.image16.ref.png
new file mode 100644
index 000000000..e9ad5723b
--- /dev/null
+++ b/test/reference/clipped-surface.image16.ref.png
Binary files differ
diff --git a/test/reference/clipped-surface.ref.png b/test/reference/clipped-surface.ref.png
new file mode 100644
index 000000000..7fed5a3e0
--- /dev/null
+++ b/test/reference/clipped-surface.ref.png
Binary files differ
diff --git a/test/reference/clipped-trapezoids.ref.png b/test/reference/clipped-trapezoids.ref.png
new file mode 100644
index 000000000..975a692d8
--- /dev/null
+++ b/test/reference/clipped-trapezoids.ref.png
Binary files differ
diff --git a/test/reference/close-path-current-point.base.argb32.ref.png b/test/reference/close-path-current-point.base.argb32.ref.png
new file mode 100644
index 000000000..373eb1176
--- /dev/null
+++ b/test/reference/close-path-current-point.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/close-path-current-point.base.rgb24.ref.png b/test/reference/close-path-current-point.base.rgb24.ref.png
new file mode 100644
index 000000000..373eb1176
--- /dev/null
+++ b/test/reference/close-path-current-point.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/close-path-current-point.image16.ref.png b/test/reference/close-path-current-point.image16.ref.png
new file mode 100644
index 000000000..6aacf3e1b
--- /dev/null
+++ b/test/reference/close-path-current-point.image16.ref.png
Binary files differ
diff --git a/test/reference/close-path-current-point.mask.argb32.ref.png b/test/reference/close-path-current-point.mask.argb32.ref.png
new file mode 100644
index 000000000..ab3124b79
--- /dev/null
+++ b/test/reference/close-path-current-point.mask.argb32.ref.png
Binary files differ
diff --git a/test/reference/close-path-current-point.mask.rgb24.ref.png b/test/reference/close-path-current-point.mask.rgb24.ref.png
new file mode 100644
index 000000000..ab3124b79
--- /dev/null
+++ b/test/reference/close-path-current-point.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/close-path-current-point.ps.ref.png b/test/reference/close-path-current-point.ps.ref.png
new file mode 100644
index 000000000..1442f01f7
--- /dev/null
+++ b/test/reference/close-path-current-point.ps.ref.png
Binary files differ
diff --git a/test/reference/close-path-current-point.ref.png b/test/reference/close-path-current-point.ref.png
new file mode 100644
index 000000000..3ae490031
--- /dev/null
+++ b/test/reference/close-path-current-point.ref.png
Binary files differ
diff --git a/test/reference/close-path-current-point.traps.argb32.ref.png b/test/reference/close-path-current-point.traps.argb32.ref.png
new file mode 100644
index 000000000..373eb1176
--- /dev/null
+++ b/test/reference/close-path-current-point.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/close-path-current-point.traps.rgb24.ref.png b/test/reference/close-path-current-point.traps.rgb24.ref.png
new file mode 100644
index 000000000..373eb1176
--- /dev/null
+++ b/test/reference/close-path-current-point.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/close-path.base.argb32.ref.png b/test/reference/close-path.base.argb32.ref.png
new file mode 100644
index 000000000..b53fab252
--- /dev/null
+++ b/test/reference/close-path.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/close-path.base.rgb24.ref.png b/test/reference/close-path.base.rgb24.ref.png
new file mode 100644
index 000000000..b53fab252
--- /dev/null
+++ b/test/reference/close-path.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/close-path.ps2.ref.png b/test/reference/close-path.ps2.ref.png
new file mode 100644
index 000000000..e43821c86
--- /dev/null
+++ b/test/reference/close-path.ps2.ref.png
Binary files differ
diff --git a/test/reference/close-path.ps3.ref.png b/test/reference/close-path.ps3.ref.png
new file mode 100644
index 000000000..e43821c86
--- /dev/null
+++ b/test/reference/close-path.ps3.ref.png
Binary files differ
diff --git a/test/reference/close-path.ref.png b/test/reference/close-path.ref.png
new file mode 100644
index 000000000..5506ff8bd
--- /dev/null
+++ b/test/reference/close-path.ref.png
Binary files differ
diff --git a/test/reference/close-path.traps.argb32.ref.png b/test/reference/close-path.traps.argb32.ref.png
new file mode 100644
index 000000000..b53fab252
--- /dev/null
+++ b/test/reference/close-path.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/close-path.traps.rgb24.ref.png b/test/reference/close-path.traps.rgb24.ref.png
new file mode 100644
index 000000000..b53fab252
--- /dev/null
+++ b/test/reference/close-path.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/composite-integer-translate-over-repeat.base.argb32.ref.png b/test/reference/composite-integer-translate-over-repeat.base.argb32.ref.png
new file mode 100644
index 000000000..c42574988
--- /dev/null
+++ b/test/reference/composite-integer-translate-over-repeat.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/composite-integer-translate-over-repeat.base.rgb24.ref.png b/test/reference/composite-integer-translate-over-repeat.base.rgb24.ref.png
new file mode 100644
index 000000000..c42574988
--- /dev/null
+++ b/test/reference/composite-integer-translate-over-repeat.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/composite-integer-translate-over-repeat.ps2.ref.png b/test/reference/composite-integer-translate-over-repeat.ps2.ref.png
new file mode 100644
index 000000000..f0e7b8401
--- /dev/null
+++ b/test/reference/composite-integer-translate-over-repeat.ps2.ref.png
Binary files differ
diff --git a/test/reference/composite-integer-translate-over-repeat.ps3.ref.png b/test/reference/composite-integer-translate-over-repeat.ps3.ref.png
new file mode 100644
index 000000000..f0e7b8401
--- /dev/null
+++ b/test/reference/composite-integer-translate-over-repeat.ps3.ref.png
Binary files differ
diff --git a/test/reference/composite-integer-translate-over-repeat.ref.png b/test/reference/composite-integer-translate-over-repeat.ref.png
new file mode 100644
index 000000000..c04db2631
--- /dev/null
+++ b/test/reference/composite-integer-translate-over-repeat.ref.png
Binary files differ
diff --git a/test/reference/composite-integer-translate-over.base.argb32.ref.png b/test/reference/composite-integer-translate-over.base.argb32.ref.png
new file mode 100644
index 000000000..7ac3ddf4c
--- /dev/null
+++ b/test/reference/composite-integer-translate-over.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/composite-integer-translate-over.base.rgb24.ref.png b/test/reference/composite-integer-translate-over.base.rgb24.ref.png
new file mode 100644
index 000000000..7ac3ddf4c
--- /dev/null
+++ b/test/reference/composite-integer-translate-over.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/composite-integer-translate-over.image16.ref.png b/test/reference/composite-integer-translate-over.image16.ref.png
new file mode 100644
index 000000000..acb0917db
--- /dev/null
+++ b/test/reference/composite-integer-translate-over.image16.ref.png
Binary files differ
diff --git a/test/reference/composite-integer-translate-over.ps2.ref.png b/test/reference/composite-integer-translate-over.ps2.ref.png
new file mode 100644
index 000000000..8c8cc0de0
--- /dev/null
+++ b/test/reference/composite-integer-translate-over.ps2.ref.png
Binary files differ
diff --git a/test/reference/composite-integer-translate-over.ps3.ref.png b/test/reference/composite-integer-translate-over.ps3.ref.png
new file mode 100644
index 000000000..8c8cc0de0
--- /dev/null
+++ b/test/reference/composite-integer-translate-over.ps3.ref.png
Binary files differ
diff --git a/test/reference/composite-integer-translate-over.ref.png b/test/reference/composite-integer-translate-over.ref.png
new file mode 100644
index 000000000..630d99351
--- /dev/null
+++ b/test/reference/composite-integer-translate-over.ref.png
Binary files differ
diff --git a/test/reference/composite-integer-translate-source.base.argb32.ref.png b/test/reference/composite-integer-translate-source.base.argb32.ref.png
new file mode 100644
index 000000000..7ac3ddf4c
--- /dev/null
+++ b/test/reference/composite-integer-translate-source.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/composite-integer-translate-source.base.rgb24.ref.png b/test/reference/composite-integer-translate-source.base.rgb24.ref.png
new file mode 100644
index 000000000..7ac3ddf4c
--- /dev/null
+++ b/test/reference/composite-integer-translate-source.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/composite-integer-translate-source.image16.ref.png b/test/reference/composite-integer-translate-source.image16.ref.png
new file mode 100644
index 000000000..acb0917db
--- /dev/null
+++ b/test/reference/composite-integer-translate-source.image16.ref.png
Binary files differ
diff --git a/test/reference/composite-integer-translate-source.ps2.ref.png b/test/reference/composite-integer-translate-source.ps2.ref.png
new file mode 100644
index 000000000..8c8cc0de0
--- /dev/null
+++ b/test/reference/composite-integer-translate-source.ps2.ref.png
Binary files differ
diff --git a/test/reference/composite-integer-translate-source.ps3.ref.png b/test/reference/composite-integer-translate-source.ps3.ref.png
new file mode 100644
index 000000000..8c8cc0de0
--- /dev/null
+++ b/test/reference/composite-integer-translate-source.ps3.ref.png
Binary files differ
diff --git a/test/reference/composite-integer-translate-source.ref.png b/test/reference/composite-integer-translate-source.ref.png
new file mode 100644
index 000000000..da9a3986a
--- /dev/null
+++ b/test/reference/composite-integer-translate-source.ref.png
Binary files differ
diff --git a/test/reference/composite-integer-translate-source.svg12.argb32.xfail.png b/test/reference/composite-integer-translate-source.svg12.argb32.xfail.png
new file mode 100644
index 000000000..c4f319701
--- /dev/null
+++ b/test/reference/composite-integer-translate-source.svg12.argb32.xfail.png
Binary files differ
diff --git a/test/reference/composite-integer-translate-source.svg12.rgb24.xfail.png b/test/reference/composite-integer-translate-source.svg12.rgb24.xfail.png
new file mode 100644
index 000000000..c4f319701
--- /dev/null
+++ b/test/reference/composite-integer-translate-source.svg12.rgb24.xfail.png
Binary files differ
diff --git a/test/reference/copy-disjoint.base.argb32.ref.png b/test/reference/copy-disjoint.base.argb32.ref.png
new file mode 100644
index 000000000..da9a3b112
--- /dev/null
+++ b/test/reference/copy-disjoint.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/copy-disjoint.base.rgb24.ref.png b/test/reference/copy-disjoint.base.rgb24.ref.png
new file mode 100644
index 000000000..da9a3b112
--- /dev/null
+++ b/test/reference/copy-disjoint.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/copy-disjoint.ref.png b/test/reference/copy-disjoint.ref.png
new file mode 100644
index 000000000..da9a3b112
--- /dev/null
+++ b/test/reference/copy-disjoint.ref.png
Binary files differ
diff --git a/test/reference/copy-path.base.argb32.ref.png b/test/reference/copy-path.base.argb32.ref.png
new file mode 100644
index 000000000..6ca6f48e6
--- /dev/null
+++ b/test/reference/copy-path.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/copy-path.base.rgb24.ref.png b/test/reference/copy-path.base.rgb24.ref.png
new file mode 100644
index 000000000..6ca6f48e6
--- /dev/null
+++ b/test/reference/copy-path.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/copy-path.image16.ref.png b/test/reference/copy-path.image16.ref.png
new file mode 100644
index 000000000..1b3cabc63
--- /dev/null
+++ b/test/reference/copy-path.image16.ref.png
Binary files differ
diff --git a/test/reference/copy-path.ps.ref.png b/test/reference/copy-path.ps.ref.png
new file mode 100644
index 000000000..41423a09a
--- /dev/null
+++ b/test/reference/copy-path.ps.ref.png
Binary files differ
diff --git a/test/reference/copy-path.ref.png b/test/reference/copy-path.ref.png
new file mode 100644
index 000000000..b50e9e47b
--- /dev/null
+++ b/test/reference/copy-path.ref.png
Binary files differ
diff --git a/test/reference/copy-path.traps.argb32.ref.png b/test/reference/copy-path.traps.argb32.ref.png
new file mode 100644
index 000000000..6ca6f48e6
--- /dev/null
+++ b/test/reference/copy-path.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/copy-path.traps.rgb24.ref.png b/test/reference/copy-path.traps.rgb24.ref.png
new file mode 100644
index 000000000..6ca6f48e6
--- /dev/null
+++ b/test/reference/copy-path.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/coverage-abutting.ref.png b/test/reference/coverage-abutting.ref.png
new file mode 100644
index 000000000..8e37ca313
--- /dev/null
+++ b/test/reference/coverage-abutting.ref.png
Binary files differ
diff --git a/test/reference/coverage-column-triangles.ref.png b/test/reference/coverage-column-triangles.ref.png
new file mode 100644
index 000000000..aa61031b7
--- /dev/null
+++ b/test/reference/coverage-column-triangles.ref.png
Binary files differ
diff --git a/test/reference/coverage-column-triangles.xfail.png b/test/reference/coverage-column-triangles.xfail.png
new file mode 100644
index 000000000..566b41544
--- /dev/null
+++ b/test/reference/coverage-column-triangles.xfail.png
Binary files differ
diff --git a/test/reference/coverage-column-triangles.xlib.xfail.png b/test/reference/coverage-column-triangles.xlib.xfail.png
new file mode 100644
index 000000000..f433b7a84
--- /dev/null
+++ b/test/reference/coverage-column-triangles.xlib.xfail.png
Binary files differ
diff --git a/test/reference/coverage-intersecting-quads.ref.png b/test/reference/coverage-intersecting-quads.ref.png
new file mode 100644
index 000000000..f56cb5570
--- /dev/null
+++ b/test/reference/coverage-intersecting-quads.ref.png
Binary files differ
diff --git a/test/reference/coverage-intersecting-quads.xlib.xfail.png b/test/reference/coverage-intersecting-quads.xlib.xfail.png
new file mode 100644
index 000000000..d6b8c2ef2
--- /dev/null
+++ b/test/reference/coverage-intersecting-quads.xlib.xfail.png
Binary files differ
diff --git a/test/reference/coverage-intersecting-triangles.ref.png b/test/reference/coverage-intersecting-triangles.ref.png
new file mode 100644
index 000000000..40a48c138
--- /dev/null
+++ b/test/reference/coverage-intersecting-triangles.ref.png
Binary files differ
diff --git a/test/reference/coverage-intersecting-triangles.xfail.png b/test/reference/coverage-intersecting-triangles.xfail.png
new file mode 100644
index 000000000..c0290e492
--- /dev/null
+++ b/test/reference/coverage-intersecting-triangles.xfail.png
Binary files differ
diff --git a/test/reference/coverage-intersecting-triangles.xlib.xfail.png b/test/reference/coverage-intersecting-triangles.xlib.xfail.png
new file mode 100644
index 000000000..e64cd4741
--- /dev/null
+++ b/test/reference/coverage-intersecting-triangles.xlib.xfail.png
Binary files differ
diff --git a/test/reference/coverage-rectangles.ref.png b/test/reference/coverage-rectangles.ref.png
new file mode 100644
index 000000000..cc1d31cf8
--- /dev/null
+++ b/test/reference/coverage-rectangles.ref.png
Binary files differ
diff --git a/test/reference/coverage-rectangles.xlib.xfail.png b/test/reference/coverage-rectangles.xlib.xfail.png
new file mode 100644
index 000000000..622c2d75e
--- /dev/null
+++ b/test/reference/coverage-rectangles.xlib.xfail.png
Binary files differ
diff --git a/test/reference/coverage-rhombus.ref.png b/test/reference/coverage-rhombus.ref.png
new file mode 100644
index 000000000..51e08353e
--- /dev/null
+++ b/test/reference/coverage-rhombus.ref.png
Binary files differ
diff --git a/test/reference/coverage-rhombus.xfail.png b/test/reference/coverage-rhombus.xfail.png
new file mode 100644
index 000000000..cbfc10afa
--- /dev/null
+++ b/test/reference/coverage-rhombus.xfail.png
Binary files differ
diff --git a/test/reference/coverage-row-triangles.ref.png b/test/reference/coverage-row-triangles.ref.png
new file mode 100644
index 000000000..aa61031b7
--- /dev/null
+++ b/test/reference/coverage-row-triangles.ref.png
Binary files differ
diff --git a/test/reference/coverage-row-triangles.xfail.png b/test/reference/coverage-row-triangles.xfail.png
new file mode 100644
index 000000000..d451ba96a
--- /dev/null
+++ b/test/reference/coverage-row-triangles.xfail.png
Binary files differ
diff --git a/test/reference/coverage-row-triangles.xlib.xfail.png b/test/reference/coverage-row-triangles.xlib.xfail.png
new file mode 100644
index 000000000..f8582fbb9
--- /dev/null
+++ b/test/reference/coverage-row-triangles.xlib.xfail.png
Binary files differ
diff --git a/test/reference/coverage-triangles.ref.png b/test/reference/coverage-triangles.ref.png
new file mode 100644
index 000000000..f56cb5570
--- /dev/null
+++ b/test/reference/coverage-triangles.ref.png
Binary files differ
diff --git a/test/reference/coverage-triangles.xfail.png b/test/reference/coverage-triangles.xfail.png
new file mode 100644
index 000000000..dea5983ae
--- /dev/null
+++ b/test/reference/coverage-triangles.xfail.png
Binary files differ
diff --git a/test/reference/coverage-triangles.xlib.xfail.png b/test/reference/coverage-triangles.xlib.xfail.png
new file mode 100644
index 000000000..133fd3384
--- /dev/null
+++ b/test/reference/coverage-triangles.xlib.xfail.png
Binary files differ
diff --git a/test/reference/create-from-png-stream.base.argb32.ref.png b/test/reference/create-from-png-stream.base.argb32.ref.png
new file mode 100644
index 000000000..0a145d918
--- /dev/null
+++ b/test/reference/create-from-png-stream.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/create-from-png-stream.base.rgb24.ref.png b/test/reference/create-from-png-stream.base.rgb24.ref.png
new file mode 100644
index 000000000..0a145d918
--- /dev/null
+++ b/test/reference/create-from-png-stream.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/create-from-png-stream.ref.png b/test/reference/create-from-png-stream.ref.png
new file mode 100644
index 000000000..765adc4a4
--- /dev/null
+++ b/test/reference/create-from-png-stream.ref.png
Binary files differ
diff --git a/test/reference/create-from-png.alpha.ref.png b/test/reference/create-from-png.alpha.ref.png
new file mode 100644
index 000000000..a5175a1eb
--- /dev/null
+++ b/test/reference/create-from-png.alpha.ref.png
Binary files differ
diff --git a/test/reference/create-from-png.base.argb32.ref.png b/test/reference/create-from-png.base.argb32.ref.png
new file mode 100644
index 000000000..0a145d918
--- /dev/null
+++ b/test/reference/create-from-png.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/create-from-png.base.rgb24.ref.png b/test/reference/create-from-png.base.rgb24.ref.png
new file mode 100644
index 000000000..0a145d918
--- /dev/null
+++ b/test/reference/create-from-png.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/create-from-png.gray-alpha.ref.png b/test/reference/create-from-png.gray-alpha.ref.png
new file mode 100644
index 000000000..f5d47dc4b
--- /dev/null
+++ b/test/reference/create-from-png.gray-alpha.ref.png
Binary files differ
diff --git a/test/reference/create-from-png.gray.ref.png b/test/reference/create-from-png.gray.ref.png
new file mode 100644
index 000000000..12dc90bc3
--- /dev/null
+++ b/test/reference/create-from-png.gray.ref.png
Binary files differ
diff --git a/test/reference/create-from-png.indexed-alpha.ref.png b/test/reference/create-from-png.indexed-alpha.ref.png
new file mode 100644
index 000000000..9f32c6986
--- /dev/null
+++ b/test/reference/create-from-png.indexed-alpha.ref.png
Binary files differ
diff --git a/test/reference/create-from-png.indexed.ref.png b/test/reference/create-from-png.indexed.ref.png
new file mode 100644
index 000000000..6b1d71316
--- /dev/null
+++ b/test/reference/create-from-png.indexed.ref.png
Binary files differ
diff --git a/test/reference/create-from-png.mask.argb32.ref.png b/test/reference/create-from-png.mask.argb32.ref.png
new file mode 100644
index 000000000..0a145d918
--- /dev/null
+++ b/test/reference/create-from-png.mask.argb32.ref.png
Binary files differ
diff --git a/test/reference/create-from-png.mask.rgb24.ref.png b/test/reference/create-from-png.mask.rgb24.ref.png
new file mode 100644
index 000000000..0a145d918
--- /dev/null
+++ b/test/reference/create-from-png.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/create-from-png.ref.png b/test/reference/create-from-png.ref.png
new file mode 100644
index 000000000..0a145d918
--- /dev/null
+++ b/test/reference/create-from-png.ref.png
Binary files differ
diff --git a/test/reference/create-from-png.traps.argb32.ref.png b/test/reference/create-from-png.traps.argb32.ref.png
new file mode 100644
index 000000000..0a145d918
--- /dev/null
+++ b/test/reference/create-from-png.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/create-from-png.traps.rgb24.ref.png b/test/reference/create-from-png.traps.rgb24.ref.png
new file mode 100644
index 000000000..0a145d918
--- /dev/null
+++ b/test/reference/create-from-png.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/culled-glyphs.base.argb32.ref.png b/test/reference/culled-glyphs.base.argb32.ref.png
new file mode 100644
index 000000000..6701295be
--- /dev/null
+++ b/test/reference/culled-glyphs.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/culled-glyphs.base.rgb24.ref.png b/test/reference/culled-glyphs.base.rgb24.ref.png
new file mode 100644
index 000000000..6701295be
--- /dev/null
+++ b/test/reference/culled-glyphs.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/culled-glyphs.image16.ref.png b/test/reference/culled-glyphs.image16.ref.png
new file mode 100644
index 000000000..724cb8ff9
--- /dev/null
+++ b/test/reference/culled-glyphs.image16.ref.png
Binary files differ
diff --git a/test/reference/culled-glyphs.ps.ref.png b/test/reference/culled-glyphs.ps.ref.png
new file mode 100644
index 000000000..f34fb9566
--- /dev/null
+++ b/test/reference/culled-glyphs.ps.ref.png
Binary files differ
diff --git a/test/reference/culled-glyphs.quartz.ref.png b/test/reference/culled-glyphs.quartz.ref.png
new file mode 100644
index 000000000..1aa234219
--- /dev/null
+++ b/test/reference/culled-glyphs.quartz.ref.png
Binary files differ
diff --git a/test/reference/culled-glyphs.ref.png b/test/reference/culled-glyphs.ref.png
new file mode 100644
index 000000000..6701295be
--- /dev/null
+++ b/test/reference/culled-glyphs.ref.png
Binary files differ
diff --git a/test/reference/curve-to-as-line-to.base.argb32.ref.png b/test/reference/curve-to-as-line-to.base.argb32.ref.png
new file mode 100644
index 000000000..15589db2e
--- /dev/null
+++ b/test/reference/curve-to-as-line-to.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/curve-to-as-line-to.base.rgb24.ref.png b/test/reference/curve-to-as-line-to.base.rgb24.ref.png
new file mode 100644
index 000000000..15589db2e
--- /dev/null
+++ b/test/reference/curve-to-as-line-to.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/curve-to-as-line-to.mask.argb32.ref.png b/test/reference/curve-to-as-line-to.mask.argb32.ref.png
new file mode 100644
index 000000000..d2411832e
--- /dev/null
+++ b/test/reference/curve-to-as-line-to.mask.argb32.ref.png
Binary files differ
diff --git a/test/reference/curve-to-as-line-to.mask.rgb24.ref.png b/test/reference/curve-to-as-line-to.mask.rgb24.ref.png
new file mode 100644
index 000000000..d2411832e
--- /dev/null
+++ b/test/reference/curve-to-as-line-to.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/curve-to-as-line-to.ps.xfail.png b/test/reference/curve-to-as-line-to.ps.xfail.png
new file mode 100644
index 000000000..3f31058e3
--- /dev/null
+++ b/test/reference/curve-to-as-line-to.ps.xfail.png
Binary files differ
diff --git a/test/reference/curve-to-as-line-to.ref.png b/test/reference/curve-to-as-line-to.ref.png
new file mode 100644
index 000000000..15589db2e
--- /dev/null
+++ b/test/reference/curve-to-as-line-to.ref.png
Binary files differ
diff --git a/test/reference/curve-to-as-line-to.traps.argb32.ref.png b/test/reference/curve-to-as-line-to.traps.argb32.ref.png
new file mode 100644
index 000000000..15589db2e
--- /dev/null
+++ b/test/reference/curve-to-as-line-to.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/curve-to-as-line-to.traps.rgb24.ref.png b/test/reference/curve-to-as-line-to.traps.rgb24.ref.png
new file mode 100644
index 000000000..15589db2e
--- /dev/null
+++ b/test/reference/curve-to-as-line-to.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/dash-caps-joins.base.argb32.ref.png b/test/reference/dash-caps-joins.base.argb32.ref.png
new file mode 100644
index 000000000..b85b03360
--- /dev/null
+++ b/test/reference/dash-caps-joins.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/dash-caps-joins.base.rgb24.ref.png b/test/reference/dash-caps-joins.base.rgb24.ref.png
new file mode 100644
index 000000000..b85b03360
--- /dev/null
+++ b/test/reference/dash-caps-joins.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/dash-caps-joins.image16.ref.png b/test/reference/dash-caps-joins.image16.ref.png
new file mode 100644
index 000000000..1f8d04877
--- /dev/null
+++ b/test/reference/dash-caps-joins.image16.ref.png
Binary files differ
diff --git a/test/reference/dash-caps-joins.mask.argb32.ref.png b/test/reference/dash-caps-joins.mask.argb32.ref.png
new file mode 100644
index 000000000..b09b86fce
--- /dev/null
+++ b/test/reference/dash-caps-joins.mask.argb32.ref.png
Binary files differ
diff --git a/test/reference/dash-caps-joins.mask.rgb24.ref.png b/test/reference/dash-caps-joins.mask.rgb24.ref.png
new file mode 100644
index 000000000..b09b86fce
--- /dev/null
+++ b/test/reference/dash-caps-joins.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/dash-caps-joins.ps.ref.png b/test/reference/dash-caps-joins.ps.ref.png
new file mode 100644
index 000000000..466bc62d7
--- /dev/null
+++ b/test/reference/dash-caps-joins.ps.ref.png
Binary files differ
diff --git a/test/reference/dash-caps-joins.quartz.xfail.png b/test/reference/dash-caps-joins.quartz.xfail.png
new file mode 100644
index 000000000..0dc54336b
--- /dev/null
+++ b/test/reference/dash-caps-joins.quartz.xfail.png
Binary files differ
diff --git a/test/reference/dash-caps-joins.ref.png b/test/reference/dash-caps-joins.ref.png
new file mode 100644
index 000000000..0600125bf
--- /dev/null
+++ b/test/reference/dash-caps-joins.ref.png
Binary files differ
diff --git a/test/reference/dash-caps-joins.traps.argb32.ref.png b/test/reference/dash-caps-joins.traps.argb32.ref.png
new file mode 100644
index 000000000..b85b03360
--- /dev/null
+++ b/test/reference/dash-caps-joins.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/dash-caps-joins.traps.rgb24.ref.png b/test/reference/dash-caps-joins.traps.rgb24.ref.png
new file mode 100644
index 000000000..b85b03360
--- /dev/null
+++ b/test/reference/dash-caps-joins.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/dash-curve.image16.ref.png b/test/reference/dash-curve.image16.ref.png
new file mode 100644
index 000000000..d89cedace
--- /dev/null
+++ b/test/reference/dash-curve.image16.ref.png
Binary files differ
diff --git a/test/reference/dash-curve.mask.argb32.ref.png b/test/reference/dash-curve.mask.argb32.ref.png
new file mode 100644
index 000000000..8bebde204
--- /dev/null
+++ b/test/reference/dash-curve.mask.argb32.ref.png
Binary files differ
diff --git a/test/reference/dash-curve.mask.rgb24.ref.png b/test/reference/dash-curve.mask.rgb24.ref.png
new file mode 100644
index 000000000..8bebde204
--- /dev/null
+++ b/test/reference/dash-curve.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/dash-curve.ps2.ref.png b/test/reference/dash-curve.ps2.ref.png
new file mode 100644
index 000000000..ffb402fe3
--- /dev/null
+++ b/test/reference/dash-curve.ps2.ref.png
Binary files differ
diff --git a/test/reference/dash-curve.ps3.ref.png b/test/reference/dash-curve.ps3.ref.png
new file mode 100644
index 000000000..ffb402fe3
--- /dev/null
+++ b/test/reference/dash-curve.ps3.ref.png
Binary files differ
diff --git a/test/reference/dash-curve.quartz.xfail.png b/test/reference/dash-curve.quartz.xfail.png
new file mode 100644
index 000000000..b68d7a735
--- /dev/null
+++ b/test/reference/dash-curve.quartz.xfail.png
Binary files differ
diff --git a/test/reference/dash-curve.ref.png b/test/reference/dash-curve.ref.png
new file mode 100644
index 000000000..8eefce2f9
--- /dev/null
+++ b/test/reference/dash-curve.ref.png
Binary files differ
diff --git a/test/reference/dash-curve.traps.argb32.ref.png b/test/reference/dash-curve.traps.argb32.ref.png
new file mode 100644
index 000000000..a29f43dc6
--- /dev/null
+++ b/test/reference/dash-curve.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/dash-curve.traps.rgb24.ref.png b/test/reference/dash-curve.traps.rgb24.ref.png
new file mode 100644
index 000000000..a29f43dc6
--- /dev/null
+++ b/test/reference/dash-curve.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/dash-infinite-loop.base.argb32.ref.png b/test/reference/dash-infinite-loop.base.argb32.ref.png
new file mode 100644
index 000000000..c0cc7391e
--- /dev/null
+++ b/test/reference/dash-infinite-loop.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/dash-infinite-loop.base.rgb24.ref.png b/test/reference/dash-infinite-loop.base.rgb24.ref.png
new file mode 100644
index 000000000..c0cc7391e
--- /dev/null
+++ b/test/reference/dash-infinite-loop.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/dash-infinite-loop.ps.ref.png b/test/reference/dash-infinite-loop.ps.ref.png
new file mode 100644
index 000000000..bab313a73
--- /dev/null
+++ b/test/reference/dash-infinite-loop.ps.ref.png
Binary files differ
diff --git a/test/reference/dash-infinite-loop.ref.png b/test/reference/dash-infinite-loop.ref.png
new file mode 100644
index 000000000..2ae1717a1
--- /dev/null
+++ b/test/reference/dash-infinite-loop.ref.png
Binary files differ
diff --git a/test/reference/dash-infinite-loop.traps.argb32.ref.png b/test/reference/dash-infinite-loop.traps.argb32.ref.png
new file mode 100644
index 000000000..c0cc7391e
--- /dev/null
+++ b/test/reference/dash-infinite-loop.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/dash-infinite-loop.traps.rgb24.ref.png b/test/reference/dash-infinite-loop.traps.rgb24.ref.png
new file mode 100644
index 000000000..c0cc7391e
--- /dev/null
+++ b/test/reference/dash-infinite-loop.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/dash-no-dash.base.argb32.ref.png b/test/reference/dash-no-dash.base.argb32.ref.png
new file mode 100644
index 000000000..c150a4f02
--- /dev/null
+++ b/test/reference/dash-no-dash.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/dash-no-dash.base.rgb24.ref.png b/test/reference/dash-no-dash.base.rgb24.ref.png
new file mode 100644
index 000000000..c150a4f02
--- /dev/null
+++ b/test/reference/dash-no-dash.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/dash-no-dash.ref.png b/test/reference/dash-no-dash.ref.png
new file mode 100644
index 000000000..9afd045db
--- /dev/null
+++ b/test/reference/dash-no-dash.ref.png
Binary files differ
diff --git a/test/reference/dash-offset-negative.base.argb32.ref.png b/test/reference/dash-offset-negative.base.argb32.ref.png
new file mode 100644
index 000000000..77b929164
--- /dev/null
+++ b/test/reference/dash-offset-negative.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/dash-offset-negative.base.rgb24.ref.png b/test/reference/dash-offset-negative.base.rgb24.ref.png
new file mode 100644
index 000000000..77b929164
--- /dev/null
+++ b/test/reference/dash-offset-negative.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/dash-offset-negative.pdf.ref.png b/test/reference/dash-offset-negative.pdf.ref.png
new file mode 100644
index 000000000..df22d08b2
--- /dev/null
+++ b/test/reference/dash-offset-negative.pdf.ref.png
Binary files differ
diff --git a/test/reference/dash-offset-negative.ref.png b/test/reference/dash-offset-negative.ref.png
new file mode 100644
index 000000000..df22d08b2
--- /dev/null
+++ b/test/reference/dash-offset-negative.ref.png
Binary files differ
diff --git a/test/reference/dash-offset-negative.traps.argb32.ref.png b/test/reference/dash-offset-negative.traps.argb32.ref.png
new file mode 100644
index 000000000..77b929164
--- /dev/null
+++ b/test/reference/dash-offset-negative.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/dash-offset-negative.traps.rgb24.ref.png b/test/reference/dash-offset-negative.traps.rgb24.ref.png
new file mode 100644
index 000000000..77b929164
--- /dev/null
+++ b/test/reference/dash-offset-negative.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/dash-offset.base.argb32.ref.png b/test/reference/dash-offset.base.argb32.ref.png
new file mode 100644
index 000000000..52600c435
--- /dev/null
+++ b/test/reference/dash-offset.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/dash-offset.base.rgb24.ref.png b/test/reference/dash-offset.base.rgb24.ref.png
new file mode 100644
index 000000000..52600c435
--- /dev/null
+++ b/test/reference/dash-offset.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/dash-offset.ref.png b/test/reference/dash-offset.ref.png
new file mode 100644
index 000000000..52600c435
--- /dev/null
+++ b/test/reference/dash-offset.ref.png
Binary files differ
diff --git a/test/reference/dash-scale.image16.ref.png b/test/reference/dash-scale.image16.ref.png
new file mode 100644
index 000000000..2b4fca560
--- /dev/null
+++ b/test/reference/dash-scale.image16.ref.png
Binary files differ
diff --git a/test/reference/dash-scale.mask.argb32.ref.png b/test/reference/dash-scale.mask.argb32.ref.png
new file mode 100644
index 000000000..deef9dcd2
--- /dev/null
+++ b/test/reference/dash-scale.mask.argb32.ref.png
Binary files differ
diff --git a/test/reference/dash-scale.mask.rgb24.ref.png b/test/reference/dash-scale.mask.rgb24.ref.png
new file mode 100644
index 000000000..deef9dcd2
--- /dev/null
+++ b/test/reference/dash-scale.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/dash-scale.ps.ref.png b/test/reference/dash-scale.ps.ref.png
new file mode 100644
index 000000000..f8c25277c
--- /dev/null
+++ b/test/reference/dash-scale.ps.ref.png
Binary files differ
diff --git a/test/reference/dash-scale.quartz.ref.png b/test/reference/dash-scale.quartz.ref.png
new file mode 100644
index 000000000..62ccdf52d
--- /dev/null
+++ b/test/reference/dash-scale.quartz.ref.png
Binary files differ
diff --git a/test/reference/dash-scale.ref.png b/test/reference/dash-scale.ref.png
new file mode 100644
index 000000000..a169364fd
--- /dev/null
+++ b/test/reference/dash-scale.ref.png
Binary files differ
diff --git a/test/reference/dash-scale.traps.argb32.ref.png b/test/reference/dash-scale.traps.argb32.ref.png
new file mode 100644
index 000000000..c87cad468
--- /dev/null
+++ b/test/reference/dash-scale.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/dash-scale.traps.rgb24.ref.png b/test/reference/dash-scale.traps.rgb24.ref.png
new file mode 100644
index 000000000..c87cad468
--- /dev/null
+++ b/test/reference/dash-scale.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/dash-state.base.argb32.ref.png b/test/reference/dash-state.base.argb32.ref.png
new file mode 100644
index 000000000..53341102b
--- /dev/null
+++ b/test/reference/dash-state.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/dash-state.base.rgb24.ref.png b/test/reference/dash-state.base.rgb24.ref.png
new file mode 100644
index 000000000..53341102b
--- /dev/null
+++ b/test/reference/dash-state.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/dash-state.image16.ref.png b/test/reference/dash-state.image16.ref.png
new file mode 100644
index 000000000..07c77dacc
--- /dev/null
+++ b/test/reference/dash-state.image16.ref.png
Binary files differ
diff --git a/test/reference/dash-state.ps2.ref.png b/test/reference/dash-state.ps2.ref.png
new file mode 100644
index 000000000..88e208c58
--- /dev/null
+++ b/test/reference/dash-state.ps2.ref.png
Binary files differ
diff --git a/test/reference/dash-state.ps3.ref.png b/test/reference/dash-state.ps3.ref.png
new file mode 100644
index 000000000..88e208c58
--- /dev/null
+++ b/test/reference/dash-state.ps3.ref.png
Binary files differ
diff --git a/test/reference/dash-state.quartz.xfail.png b/test/reference/dash-state.quartz.xfail.png
new file mode 100644
index 000000000..993498ceb
--- /dev/null
+++ b/test/reference/dash-state.quartz.xfail.png
Binary files differ
diff --git a/test/reference/dash-state.ref.png b/test/reference/dash-state.ref.png
new file mode 100644
index 000000000..31551cfee
--- /dev/null
+++ b/test/reference/dash-state.ref.png
Binary files differ
diff --git a/test/reference/dash-state.traps.argb32.ref.png b/test/reference/dash-state.traps.argb32.ref.png
new file mode 100644
index 000000000..53341102b
--- /dev/null
+++ b/test/reference/dash-state.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/dash-state.traps.rgb24.ref.png b/test/reference/dash-state.traps.rgb24.ref.png
new file mode 100644
index 000000000..53341102b
--- /dev/null
+++ b/test/reference/dash-state.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/dash-zero-length.base.argb32.ref.png b/test/reference/dash-zero-length.base.argb32.ref.png
new file mode 100644
index 000000000..367fe3c91
--- /dev/null
+++ b/test/reference/dash-zero-length.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/dash-zero-length.base.rgb24.ref.png b/test/reference/dash-zero-length.base.rgb24.ref.png
new file mode 100644
index 000000000..9bd4e93b1
--- /dev/null
+++ b/test/reference/dash-zero-length.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/dash-zero-length.mask.rgb24.ref.png b/test/reference/dash-zero-length.mask.rgb24.ref.png
new file mode 100644
index 000000000..b14bd8dca
--- /dev/null
+++ b/test/reference/dash-zero-length.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/dash-zero-length.ps2.ref.png b/test/reference/dash-zero-length.ps2.ref.png
new file mode 100644
index 000000000..68fd3fb2e
--- /dev/null
+++ b/test/reference/dash-zero-length.ps2.ref.png
Binary files differ
diff --git a/test/reference/dash-zero-length.ps2.rgb24.ref.png b/test/reference/dash-zero-length.ps2.rgb24.ref.png
new file mode 100644
index 000000000..8a4a40fd4
--- /dev/null
+++ b/test/reference/dash-zero-length.ps2.rgb24.ref.png
Binary files differ
diff --git a/test/reference/dash-zero-length.ps3.ref.png b/test/reference/dash-zero-length.ps3.ref.png
new file mode 100644
index 000000000..68fd3fb2e
--- /dev/null
+++ b/test/reference/dash-zero-length.ps3.ref.png
Binary files differ
diff --git a/test/reference/dash-zero-length.ps3.rgb24.ref.png b/test/reference/dash-zero-length.ps3.rgb24.ref.png
new file mode 100644
index 000000000..8a4a40fd4
--- /dev/null
+++ b/test/reference/dash-zero-length.ps3.rgb24.ref.png
Binary files differ
diff --git a/test/reference/dash-zero-length.ref.png b/test/reference/dash-zero-length.ref.png
new file mode 100644
index 000000000..fdc5f5ef2
--- /dev/null
+++ b/test/reference/dash-zero-length.ref.png
Binary files differ
diff --git a/test/reference/dash-zero-length.traps.argb32.ref.png b/test/reference/dash-zero-length.traps.argb32.ref.png
new file mode 100644
index 000000000..367fe3c91
--- /dev/null
+++ b/test/reference/dash-zero-length.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/dash-zero-length.traps.rgb24.ref.png b/test/reference/dash-zero-length.traps.rgb24.ref.png
new file mode 100644
index 000000000..9bd4e93b1
--- /dev/null
+++ b/test/reference/dash-zero-length.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/degenerate-arc.base.argb32.ref.png b/test/reference/degenerate-arc.base.argb32.ref.png
new file mode 100644
index 000000000..9cf3b0793
--- /dev/null
+++ b/test/reference/degenerate-arc.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/degenerate-arc.base.rgb24.ref.png b/test/reference/degenerate-arc.base.rgb24.ref.png
new file mode 100644
index 000000000..9cf3b0793
--- /dev/null
+++ b/test/reference/degenerate-arc.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/degenerate-arc.image16.ref.png b/test/reference/degenerate-arc.image16.ref.png
new file mode 100644
index 000000000..690e4a4de
--- /dev/null
+++ b/test/reference/degenerate-arc.image16.ref.png
Binary files differ
diff --git a/test/reference/degenerate-arc.mask.argb32.ref.png b/test/reference/degenerate-arc.mask.argb32.ref.png
new file mode 100644
index 000000000..4da4fd6e4
--- /dev/null
+++ b/test/reference/degenerate-arc.mask.argb32.ref.png
Binary files differ
diff --git a/test/reference/degenerate-arc.mask.rgb24.ref.png b/test/reference/degenerate-arc.mask.rgb24.ref.png
new file mode 100644
index 000000000..4da4fd6e4
--- /dev/null
+++ b/test/reference/degenerate-arc.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/degenerate-arc.ps2.ref.png b/test/reference/degenerate-arc.ps2.ref.png
new file mode 100644
index 000000000..f6d913460
--- /dev/null
+++ b/test/reference/degenerate-arc.ps2.ref.png
Binary files differ
diff --git a/test/reference/degenerate-arc.ps3.ref.png b/test/reference/degenerate-arc.ps3.ref.png
new file mode 100644
index 000000000..f6d913460
--- /dev/null
+++ b/test/reference/degenerate-arc.ps3.ref.png
Binary files differ
diff --git a/test/reference/degenerate-arc.quartz.ref.png b/test/reference/degenerate-arc.quartz.ref.png
new file mode 100644
index 000000000..a43f6c9fd
--- /dev/null
+++ b/test/reference/degenerate-arc.quartz.ref.png
Binary files differ
diff --git a/test/reference/degenerate-arc.ref.png b/test/reference/degenerate-arc.ref.png
new file mode 100644
index 000000000..3242ca4e8
--- /dev/null
+++ b/test/reference/degenerate-arc.ref.png
Binary files differ
diff --git a/test/reference/degenerate-arc.traps.argb32.ref.png b/test/reference/degenerate-arc.traps.argb32.ref.png
new file mode 100644
index 000000000..9cf3b0793
--- /dev/null
+++ b/test/reference/degenerate-arc.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/degenerate-arc.traps.rgb24.ref.png b/test/reference/degenerate-arc.traps.rgb24.ref.png
new file mode 100644
index 000000000..9cf3b0793
--- /dev/null
+++ b/test/reference/degenerate-arc.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/degenerate-arcs.base.argb32.ref.png b/test/reference/degenerate-arcs.base.argb32.ref.png
new file mode 100644
index 000000000..fc1869dc1
--- /dev/null
+++ b/test/reference/degenerate-arcs.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/degenerate-arcs.base.rgb24.ref.png b/test/reference/degenerate-arcs.base.rgb24.ref.png
new file mode 100644
index 000000000..fc1869dc1
--- /dev/null
+++ b/test/reference/degenerate-arcs.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/degenerate-arcs.image16.ref.png b/test/reference/degenerate-arcs.image16.ref.png
new file mode 100644
index 000000000..595cb7b93
--- /dev/null
+++ b/test/reference/degenerate-arcs.image16.ref.png
Binary files differ
diff --git a/test/reference/degenerate-arcs.ref.png b/test/reference/degenerate-arcs.ref.png
new file mode 100644
index 000000000..fc1869dc1
--- /dev/null
+++ b/test/reference/degenerate-arcs.ref.png
Binary files differ
diff --git a/test/reference/degenerate-curve-to.base.argb32.ref.png b/test/reference/degenerate-curve-to.base.argb32.ref.png
new file mode 100644
index 000000000..b676a1a24
--- /dev/null
+++ b/test/reference/degenerate-curve-to.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/degenerate-curve-to.base.rgb24.ref.png b/test/reference/degenerate-curve-to.base.rgb24.ref.png
new file mode 100644
index 000000000..b676a1a24
--- /dev/null
+++ b/test/reference/degenerate-curve-to.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/degenerate-curve-to.image16.ref.png b/test/reference/degenerate-curve-to.image16.ref.png
new file mode 100644
index 000000000..8036d0f8c
--- /dev/null
+++ b/test/reference/degenerate-curve-to.image16.ref.png
Binary files differ
diff --git a/test/reference/degenerate-curve-to.mask.argb32.ref.png b/test/reference/degenerate-curve-to.mask.argb32.ref.png
new file mode 100644
index 000000000..18ab11ece
--- /dev/null
+++ b/test/reference/degenerate-curve-to.mask.argb32.ref.png
Binary files differ
diff --git a/test/reference/degenerate-curve-to.mask.rgb24.ref.png b/test/reference/degenerate-curve-to.mask.rgb24.ref.png
new file mode 100644
index 000000000..18ab11ece
--- /dev/null
+++ b/test/reference/degenerate-curve-to.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/degenerate-curve-to.ps.xfail.png b/test/reference/degenerate-curve-to.ps.xfail.png
new file mode 100644
index 000000000..1c07965fd
--- /dev/null
+++ b/test/reference/degenerate-curve-to.ps.xfail.png
Binary files differ
diff --git a/test/reference/degenerate-curve-to.quartz.ref.png b/test/reference/degenerate-curve-to.quartz.ref.png
new file mode 100644
index 000000000..04483436e
--- /dev/null
+++ b/test/reference/degenerate-curve-to.quartz.ref.png
Binary files differ
diff --git a/test/reference/degenerate-curve-to.ref.png b/test/reference/degenerate-curve-to.ref.png
new file mode 100644
index 000000000..f3fde8701
--- /dev/null
+++ b/test/reference/degenerate-curve-to.ref.png
Binary files differ
diff --git a/test/reference/degenerate-curve-to.traps.argb32.ref.png b/test/reference/degenerate-curve-to.traps.argb32.ref.png
new file mode 100644
index 000000000..b676a1a24
--- /dev/null
+++ b/test/reference/degenerate-curve-to.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/degenerate-curve-to.traps.rgb24.ref.png b/test/reference/degenerate-curve-to.traps.rgb24.ref.png
new file mode 100644
index 000000000..b676a1a24
--- /dev/null
+++ b/test/reference/degenerate-curve-to.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/degenerate-dash.base.argb32.ref.png b/test/reference/degenerate-dash.base.argb32.ref.png
new file mode 100644
index 000000000..ab8573a1a
--- /dev/null
+++ b/test/reference/degenerate-dash.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/degenerate-dash.base.rgb24.ref.png b/test/reference/degenerate-dash.base.rgb24.ref.png
new file mode 100644
index 000000000..ab8573a1a
--- /dev/null
+++ b/test/reference/degenerate-dash.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/degenerate-dash.mask.argb32.ref.png b/test/reference/degenerate-dash.mask.argb32.ref.png
new file mode 100644
index 000000000..2ddfc8bbf
--- /dev/null
+++ b/test/reference/degenerate-dash.mask.argb32.ref.png
Binary files differ
diff --git a/test/reference/degenerate-dash.mask.rgb24.ref.png b/test/reference/degenerate-dash.mask.rgb24.ref.png
new file mode 100644
index 000000000..2ddfc8bbf
--- /dev/null
+++ b/test/reference/degenerate-dash.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/degenerate-dash.ps.xfail.png b/test/reference/degenerate-dash.ps.xfail.png
new file mode 100644
index 000000000..d5f8884aa
--- /dev/null
+++ b/test/reference/degenerate-dash.ps.xfail.png
Binary files differ
diff --git a/test/reference/degenerate-dash.quartz.xfail.png b/test/reference/degenerate-dash.quartz.xfail.png
new file mode 100644
index 000000000..594437cca
--- /dev/null
+++ b/test/reference/degenerate-dash.quartz.xfail.png
Binary files differ
diff --git a/test/reference/degenerate-dash.ref.png b/test/reference/degenerate-dash.ref.png
new file mode 100644
index 000000000..e8635f1e0
--- /dev/null
+++ b/test/reference/degenerate-dash.ref.png
Binary files differ
diff --git a/test/reference/degenerate-dash.traps.argb32.ref.png b/test/reference/degenerate-dash.traps.argb32.ref.png
new file mode 100644
index 000000000..ab8573a1a
--- /dev/null
+++ b/test/reference/degenerate-dash.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/degenerate-dash.traps.rgb24.ref.png b/test/reference/degenerate-dash.traps.rgb24.ref.png
new file mode 100644
index 000000000..ab8573a1a
--- /dev/null
+++ b/test/reference/degenerate-dash.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/degenerate-linear-gradient.base.argb32.ref.png b/test/reference/degenerate-linear-gradient.base.argb32.ref.png
new file mode 100644
index 000000000..ceed48a72
--- /dev/null
+++ b/test/reference/degenerate-linear-gradient.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/degenerate-linear-gradient.base.rgb24.ref.png b/test/reference/degenerate-linear-gradient.base.rgb24.ref.png
new file mode 100644
index 000000000..ceed48a72
--- /dev/null
+++ b/test/reference/degenerate-linear-gradient.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/degenerate-linear-gradient.ref.png b/test/reference/degenerate-linear-gradient.ref.png
new file mode 100644
index 000000000..ceed48a72
--- /dev/null
+++ b/test/reference/degenerate-linear-gradient.ref.png
Binary files differ
diff --git a/test/reference/degenerate-path.base.argb32.ref.png b/test/reference/degenerate-path.base.argb32.ref.png
new file mode 100644
index 000000000..b0fef0e01
--- /dev/null
+++ b/test/reference/degenerate-path.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/degenerate-path.base.rgb24.ref.png b/test/reference/degenerate-path.base.rgb24.ref.png
new file mode 100644
index 000000000..33a8ac0b8
--- /dev/null
+++ b/test/reference/degenerate-path.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/degenerate-path.mask.argb32.ref.png b/test/reference/degenerate-path.mask.argb32.ref.png
new file mode 100644
index 000000000..045939719
--- /dev/null
+++ b/test/reference/degenerate-path.mask.argb32.ref.png
Binary files differ
diff --git a/test/reference/degenerate-path.mask.rgb24.ref.png b/test/reference/degenerate-path.mask.rgb24.ref.png
new file mode 100644
index 000000000..07fda634a
--- /dev/null
+++ b/test/reference/degenerate-path.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/degenerate-path.ps.argb32.xfail.png b/test/reference/degenerate-path.ps.argb32.xfail.png
new file mode 100644
index 000000000..33d713cbd
--- /dev/null
+++ b/test/reference/degenerate-path.ps.argb32.xfail.png
Binary files differ
diff --git a/test/reference/degenerate-path.ps.rgb24.xfail.png b/test/reference/degenerate-path.ps.rgb24.xfail.png
new file mode 100644
index 000000000..e73f3149b
--- /dev/null
+++ b/test/reference/degenerate-path.ps.rgb24.xfail.png
Binary files differ
diff --git a/test/reference/degenerate-path.quartz.argb32.xfail.png b/test/reference/degenerate-path.quartz.argb32.xfail.png
new file mode 100644
index 000000000..d655e2758
--- /dev/null
+++ b/test/reference/degenerate-path.quartz.argb32.xfail.png
Binary files differ
diff --git a/test/reference/degenerate-path.quartz.rgb24.xfail.png b/test/reference/degenerate-path.quartz.rgb24.xfail.png
new file mode 100644
index 000000000..525695111
--- /dev/null
+++ b/test/reference/degenerate-path.quartz.rgb24.xfail.png
Binary files differ
diff --git a/test/reference/degenerate-path.ref.png b/test/reference/degenerate-path.ref.png
new file mode 100644
index 000000000..f3dafe652
--- /dev/null
+++ b/test/reference/degenerate-path.ref.png
Binary files differ
diff --git a/test/reference/degenerate-path.traps.argb32.ref.png b/test/reference/degenerate-path.traps.argb32.ref.png
new file mode 100644
index 000000000..b0fef0e01
--- /dev/null
+++ b/test/reference/degenerate-path.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/degenerate-path.traps.rgb24.ref.png b/test/reference/degenerate-path.traps.rgb24.ref.png
new file mode 100644
index 000000000..33a8ac0b8
--- /dev/null
+++ b/test/reference/degenerate-path.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/degenerate-pen.base.argb32.ref.png b/test/reference/degenerate-pen.base.argb32.ref.png
new file mode 100644
index 000000000..103b8586a
--- /dev/null
+++ b/test/reference/degenerate-pen.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/degenerate-pen.base.rgb24.ref.png b/test/reference/degenerate-pen.base.rgb24.ref.png
new file mode 100644
index 000000000..103b8586a
--- /dev/null
+++ b/test/reference/degenerate-pen.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/degenerate-pen.image16.ref.png b/test/reference/degenerate-pen.image16.ref.png
new file mode 100644
index 000000000..55011270b
--- /dev/null
+++ b/test/reference/degenerate-pen.image16.ref.png
Binary files differ
diff --git a/test/reference/degenerate-pen.ps.ref.png b/test/reference/degenerate-pen.ps.ref.png
new file mode 100644
index 000000000..34d173b7d
--- /dev/null
+++ b/test/reference/degenerate-pen.ps.ref.png
Binary files differ
diff --git a/test/reference/degenerate-pen.ref.png b/test/reference/degenerate-pen.ref.png
new file mode 100644
index 000000000..ea65d2275
--- /dev/null
+++ b/test/reference/degenerate-pen.ref.png
Binary files differ
diff --git a/test/reference/degenerate-pen.traps.argb32.ref.png b/test/reference/degenerate-pen.traps.argb32.ref.png
new file mode 100644
index 000000000..103b8586a
--- /dev/null
+++ b/test/reference/degenerate-pen.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/degenerate-pen.traps.rgb24.ref.png b/test/reference/degenerate-pen.traps.rgb24.ref.png
new file mode 100644
index 000000000..103b8586a
--- /dev/null
+++ b/test/reference/degenerate-pen.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/degenerate-radial-gradient.base.argb32.ref.png b/test/reference/degenerate-radial-gradient.base.argb32.ref.png
new file mode 100644
index 000000000..9a5213b58
--- /dev/null
+++ b/test/reference/degenerate-radial-gradient.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/degenerate-radial-gradient.base.rgb24.ref.png b/test/reference/degenerate-radial-gradient.base.rgb24.ref.png
new file mode 100644
index 000000000..9a5213b58
--- /dev/null
+++ b/test/reference/degenerate-radial-gradient.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/degenerate-radial-gradient.ref.png b/test/reference/degenerate-radial-gradient.ref.png
new file mode 100644
index 000000000..9a5213b58
--- /dev/null
+++ b/test/reference/degenerate-radial-gradient.ref.png
Binary files differ
diff --git a/test/reference/degenerate-rel-curve-to.base.argb32.ref.png b/test/reference/degenerate-rel-curve-to.base.argb32.ref.png
new file mode 100644
index 000000000..0353520c9
--- /dev/null
+++ b/test/reference/degenerate-rel-curve-to.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/degenerate-rel-curve-to.base.rgb24.ref.png b/test/reference/degenerate-rel-curve-to.base.rgb24.ref.png
new file mode 100644
index 000000000..0353520c9
--- /dev/null
+++ b/test/reference/degenerate-rel-curve-to.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/degenerate-rel-curve-to.image16.ref.png b/test/reference/degenerate-rel-curve-to.image16.ref.png
new file mode 100644
index 000000000..ece894338
--- /dev/null
+++ b/test/reference/degenerate-rel-curve-to.image16.ref.png
Binary files differ
diff --git a/test/reference/degenerate-rel-curve-to.mask.argb32.ref.png b/test/reference/degenerate-rel-curve-to.mask.argb32.ref.png
new file mode 100644
index 000000000..c4293adf4
--- /dev/null
+++ b/test/reference/degenerate-rel-curve-to.mask.argb32.ref.png
Binary files differ
diff --git a/test/reference/degenerate-rel-curve-to.mask.rgb24.ref.png b/test/reference/degenerate-rel-curve-to.mask.rgb24.ref.png
new file mode 100644
index 000000000..c4293adf4
--- /dev/null
+++ b/test/reference/degenerate-rel-curve-to.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/degenerate-rel-curve-to.ps.ref.png b/test/reference/degenerate-rel-curve-to.ps.ref.png
new file mode 100644
index 000000000..98a1fc9ec
--- /dev/null
+++ b/test/reference/degenerate-rel-curve-to.ps.ref.png
Binary files differ
diff --git a/test/reference/degenerate-rel-curve-to.quartz.ref.png b/test/reference/degenerate-rel-curve-to.quartz.ref.png
new file mode 100644
index 000000000..2d21e0480
--- /dev/null
+++ b/test/reference/degenerate-rel-curve-to.quartz.ref.png
Binary files differ
diff --git a/test/reference/degenerate-rel-curve-to.ref.png b/test/reference/degenerate-rel-curve-to.ref.png
new file mode 100644
index 000000000..4284bfa5b
--- /dev/null
+++ b/test/reference/degenerate-rel-curve-to.ref.png
Binary files differ
diff --git a/test/reference/degenerate-rel-curve-to.traps.argb32.ref.png b/test/reference/degenerate-rel-curve-to.traps.argb32.ref.png
new file mode 100644
index 000000000..0353520c9
--- /dev/null
+++ b/test/reference/degenerate-rel-curve-to.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/degenerate-rel-curve-to.traps.rgb24.ref.png b/test/reference/degenerate-rel-curve-to.traps.rgb24.ref.png
new file mode 100644
index 000000000..0353520c9
--- /dev/null
+++ b/test/reference/degenerate-rel-curve-to.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/degenerate-solid-dash.ref.png b/test/reference/degenerate-solid-dash.ref.png
new file mode 100644
index 000000000..9511289b5
--- /dev/null
+++ b/test/reference/degenerate-solid-dash.ref.png
Binary files differ
diff --git a/test/reference/device-offset-fractional.base.argb32.ref.png b/test/reference/device-offset-fractional.base.argb32.ref.png
new file mode 100644
index 000000000..b1eef5f28
--- /dev/null
+++ b/test/reference/device-offset-fractional.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/device-offset-fractional.base.rgb24.ref.png b/test/reference/device-offset-fractional.base.rgb24.ref.png
new file mode 100644
index 000000000..b1eef5f28
--- /dev/null
+++ b/test/reference/device-offset-fractional.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/device-offset-fractional.gl.xfail.png b/test/reference/device-offset-fractional.gl.xfail.png
new file mode 100644
index 000000000..96b0a6a62
--- /dev/null
+++ b/test/reference/device-offset-fractional.gl.xfail.png
Binary files differ
diff --git a/test/reference/device-offset-fractional.pdf.xfail.png b/test/reference/device-offset-fractional.pdf.xfail.png
new file mode 100644
index 000000000..50bbd343c
--- /dev/null
+++ b/test/reference/device-offset-fractional.pdf.xfail.png
Binary files differ
diff --git a/test/reference/device-offset-fractional.ps2.ref.png b/test/reference/device-offset-fractional.ps2.ref.png
new file mode 100644
index 000000000..5b44082c2
--- /dev/null
+++ b/test/reference/device-offset-fractional.ps2.ref.png
Binary files differ
diff --git a/test/reference/device-offset-fractional.ps3.ref.png b/test/reference/device-offset-fractional.ps3.ref.png
new file mode 100644
index 000000000..5b44082c2
--- /dev/null
+++ b/test/reference/device-offset-fractional.ps3.ref.png
Binary files differ
diff --git a/test/reference/device-offset-fractional.ref.png b/test/reference/device-offset-fractional.ref.png
new file mode 100644
index 000000000..9250d33d3
--- /dev/null
+++ b/test/reference/device-offset-fractional.ref.png
Binary files differ
diff --git a/test/reference/device-offset-positive.base.argb32.ref.png b/test/reference/device-offset-positive.base.argb32.ref.png
new file mode 100644
index 000000000..1115bca7a
--- /dev/null
+++ b/test/reference/device-offset-positive.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/device-offset-positive.base.rgb24.ref.png b/test/reference/device-offset-positive.base.rgb24.ref.png
new file mode 100644
index 000000000..dcdd3324c
--- /dev/null
+++ b/test/reference/device-offset-positive.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/device-offset-positive.ref.png b/test/reference/device-offset-positive.ref.png
new file mode 100644
index 000000000..bdf63afdd
--- /dev/null
+++ b/test/reference/device-offset-positive.ref.png
Binary files differ
diff --git a/test/reference/device-offset-scale.base.argb32.ref.png b/test/reference/device-offset-scale.base.argb32.ref.png
new file mode 100644
index 000000000..fdffbf3c6
--- /dev/null
+++ b/test/reference/device-offset-scale.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/device-offset-scale.base.rgb24.ref.png b/test/reference/device-offset-scale.base.rgb24.ref.png
new file mode 100644
index 000000000..fdffbf3c6
--- /dev/null
+++ b/test/reference/device-offset-scale.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/device-offset-scale.ref.png b/test/reference/device-offset-scale.ref.png
new file mode 100644
index 000000000..66b29732e
--- /dev/null
+++ b/test/reference/device-offset-scale.ref.png
Binary files differ
diff --git a/test/reference/device-offset-scale.svg.xfail.png b/test/reference/device-offset-scale.svg.xfail.png
new file mode 100644
index 000000000..58a82d698
--- /dev/null
+++ b/test/reference/device-offset-scale.svg.xfail.png
Binary files differ
diff --git a/test/reference/device-offset.base.argb32.ref.png b/test/reference/device-offset.base.argb32.ref.png
new file mode 100644
index 000000000..43ced46b2
--- /dev/null
+++ b/test/reference/device-offset.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/device-offset.base.rgb24.ref.png b/test/reference/device-offset.base.rgb24.ref.png
new file mode 100644
index 000000000..f19acba17
--- /dev/null
+++ b/test/reference/device-offset.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/device-offset.ref.png b/test/reference/device-offset.ref.png
new file mode 100644
index 000000000..22cbfb4d7
--- /dev/null
+++ b/test/reference/device-offset.ref.png
Binary files differ
diff --git a/test/reference/drunkard-tails.base.argb32.ref.png b/test/reference/drunkard-tails.base.argb32.ref.png
new file mode 100644
index 000000000..92ab0b9f4
--- /dev/null
+++ b/test/reference/drunkard-tails.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/drunkard-tails.base.rgb24.ref.png b/test/reference/drunkard-tails.base.rgb24.ref.png
new file mode 100644
index 000000000..92ab0b9f4
--- /dev/null
+++ b/test/reference/drunkard-tails.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/drunkard-tails.mask.argb32.ref.png b/test/reference/drunkard-tails.mask.argb32.ref.png
new file mode 100644
index 000000000..053e47075
--- /dev/null
+++ b/test/reference/drunkard-tails.mask.argb32.ref.png
Binary files differ
diff --git a/test/reference/drunkard-tails.mask.rgb24.ref.png b/test/reference/drunkard-tails.mask.rgb24.ref.png
new file mode 100644
index 000000000..053e47075
--- /dev/null
+++ b/test/reference/drunkard-tails.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/drunkard-tails.ps.ref.png b/test/reference/drunkard-tails.ps.ref.png
new file mode 100644
index 000000000..f68c8b58c
--- /dev/null
+++ b/test/reference/drunkard-tails.ps.ref.png
Binary files differ
diff --git a/test/reference/drunkard-tails.ref.png b/test/reference/drunkard-tails.ref.png
new file mode 100644
index 000000000..b38b897aa
--- /dev/null
+++ b/test/reference/drunkard-tails.ref.png
Binary files differ
diff --git a/test/reference/drunkard-tails.traps.argb32.ref.png b/test/reference/drunkard-tails.traps.argb32.ref.png
new file mode 100644
index 000000000..92ab0b9f4
--- /dev/null
+++ b/test/reference/drunkard-tails.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/drunkard-tails.traps.rgb24.ref.png b/test/reference/drunkard-tails.traps.rgb24.ref.png
new file mode 100644
index 000000000..92ab0b9f4
--- /dev/null
+++ b/test/reference/drunkard-tails.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/egl-surface-source.base.argb32.ref.png b/test/reference/egl-surface-source.base.argb32.ref.png
new file mode 100644
index 000000000..018297208
--- /dev/null
+++ b/test/reference/egl-surface-source.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/egl-surface-source.base.rgb24.ref.png b/test/reference/egl-surface-source.base.rgb24.ref.png
new file mode 100644
index 000000000..0d68a82cc
--- /dev/null
+++ b/test/reference/egl-surface-source.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/egl-surface-source.image16.ref.png b/test/reference/egl-surface-source.image16.ref.png
new file mode 100644
index 000000000..2a7460e28
--- /dev/null
+++ b/test/reference/egl-surface-source.image16.ref.png
Binary files differ
diff --git a/test/reference/egl-surface-source.ref.png b/test/reference/egl-surface-source.ref.png
new file mode 100644
index 000000000..018297208
--- /dev/null
+++ b/test/reference/egl-surface-source.ref.png
Binary files differ
diff --git a/test/reference/extend-pad-border.base.argb32.ref.png b/test/reference/extend-pad-border.base.argb32.ref.png
new file mode 100644
index 000000000..f4fc524ac
--- /dev/null
+++ b/test/reference/extend-pad-border.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/extend-pad-border.base.rgb24.ref.png b/test/reference/extend-pad-border.base.rgb24.ref.png
new file mode 100644
index 000000000..f4fc524ac
--- /dev/null
+++ b/test/reference/extend-pad-border.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/extend-pad-border.image16.ref.png b/test/reference/extend-pad-border.image16.ref.png
new file mode 100644
index 000000000..2a1efd4d2
--- /dev/null
+++ b/test/reference/extend-pad-border.image16.ref.png
Binary files differ
diff --git a/test/reference/extend-pad-border.pdf.ref.png b/test/reference/extend-pad-border.pdf.ref.png
new file mode 100644
index 000000000..f4fc524ac
--- /dev/null
+++ b/test/reference/extend-pad-border.pdf.ref.png
Binary files differ
diff --git a/test/reference/extend-pad-border.ps.ref.png b/test/reference/extend-pad-border.ps.ref.png
new file mode 100644
index 000000000..b1f4c406c
--- /dev/null
+++ b/test/reference/extend-pad-border.ps.ref.png
Binary files differ
diff --git a/test/reference/extend-pad-border.quartz.ref.png b/test/reference/extend-pad-border.quartz.ref.png
new file mode 100644
index 000000000..4ad67a1de
--- /dev/null
+++ b/test/reference/extend-pad-border.quartz.ref.png
Binary files differ
diff --git a/test/reference/extend-pad-border.ref.png b/test/reference/extend-pad-border.ref.png
new file mode 100644
index 000000000..f4fc524ac
--- /dev/null
+++ b/test/reference/extend-pad-border.ref.png
Binary files differ
diff --git a/test/reference/extend-pad-border.svg.xfail.png b/test/reference/extend-pad-border.svg.xfail.png
new file mode 100644
index 000000000..0fde36d90
--- /dev/null
+++ b/test/reference/extend-pad-border.svg.xfail.png
Binary files differ
diff --git a/test/reference/extend-pad-similar.base.argb32.ref.png b/test/reference/extend-pad-similar.base.argb32.ref.png
new file mode 100644
index 000000000..934522189
--- /dev/null
+++ b/test/reference/extend-pad-similar.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/extend-pad-similar.base.rgb24.ref.png b/test/reference/extend-pad-similar.base.rgb24.ref.png
new file mode 100644
index 000000000..934522189
--- /dev/null
+++ b/test/reference/extend-pad-similar.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/extend-pad-similar.quartz.xfail.png b/test/reference/extend-pad-similar.quartz.xfail.png
new file mode 100644
index 000000000..a2cf3530c
--- /dev/null
+++ b/test/reference/extend-pad-similar.quartz.xfail.png
Binary files differ
diff --git a/test/reference/extend-pad-similar.ref.png b/test/reference/extend-pad-similar.ref.png
new file mode 100644
index 000000000..82da7b65a
--- /dev/null
+++ b/test/reference/extend-pad-similar.ref.png
Binary files differ
diff --git a/test/reference/extend-pad-similar.svg.xfail.png b/test/reference/extend-pad-similar.svg.xfail.png
new file mode 100644
index 000000000..a2cf3530c
--- /dev/null
+++ b/test/reference/extend-pad-similar.svg.xfail.png
Binary files differ
diff --git a/test/reference/extend-pad.base.argb32.ref.png b/test/reference/extend-pad.base.argb32.ref.png
new file mode 100644
index 000000000..934522189
--- /dev/null
+++ b/test/reference/extend-pad.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/extend-pad.base.rgb24.ref.png b/test/reference/extend-pad.base.rgb24.ref.png
new file mode 100644
index 000000000..934522189
--- /dev/null
+++ b/test/reference/extend-pad.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/extend-pad.ps.ref.png b/test/reference/extend-pad.ps.ref.png
new file mode 100644
index 000000000..a249ee209
--- /dev/null
+++ b/test/reference/extend-pad.ps.ref.png
Binary files differ
diff --git a/test/reference/extend-pad.quartz.xfail.png b/test/reference/extend-pad.quartz.xfail.png
new file mode 100644
index 000000000..a2cf3530c
--- /dev/null
+++ b/test/reference/extend-pad.quartz.xfail.png
Binary files differ
diff --git a/test/reference/extend-pad.ref.png b/test/reference/extend-pad.ref.png
new file mode 100644
index 000000000..82da7b65a
--- /dev/null
+++ b/test/reference/extend-pad.ref.png
Binary files differ
diff --git a/test/reference/extend-pad.svg.xfail.png b/test/reference/extend-pad.svg.xfail.png
new file mode 100644
index 000000000..a2cf3530c
--- /dev/null
+++ b/test/reference/extend-pad.svg.xfail.png
Binary files differ
diff --git a/test/reference/extend-reflect-similar.base.argb32.ref.png b/test/reference/extend-reflect-similar.base.argb32.ref.png
new file mode 100644
index 000000000..5fc3448fa
--- /dev/null
+++ b/test/reference/extend-reflect-similar.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/extend-reflect-similar.base.rgb24.ref.png b/test/reference/extend-reflect-similar.base.rgb24.ref.png
new file mode 100644
index 000000000..5fc3448fa
--- /dev/null
+++ b/test/reference/extend-reflect-similar.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/extend-reflect-similar.image16.ref.png b/test/reference/extend-reflect-similar.image16.ref.png
new file mode 100644
index 000000000..27c6594ea
--- /dev/null
+++ b/test/reference/extend-reflect-similar.image16.ref.png
Binary files differ
diff --git a/test/reference/extend-reflect-similar.ps2.ref.png b/test/reference/extend-reflect-similar.ps2.ref.png
new file mode 100644
index 000000000..acaee1b5a
--- /dev/null
+++ b/test/reference/extend-reflect-similar.ps2.ref.png
Binary files differ
diff --git a/test/reference/extend-reflect-similar.ps3.ref.png b/test/reference/extend-reflect-similar.ps3.ref.png
new file mode 100644
index 000000000..acaee1b5a
--- /dev/null
+++ b/test/reference/extend-reflect-similar.ps3.ref.png
Binary files differ
diff --git a/test/reference/extend-reflect-similar.ref.png b/test/reference/extend-reflect-similar.ref.png
new file mode 100644
index 000000000..93a8b001b
--- /dev/null
+++ b/test/reference/extend-reflect-similar.ref.png
Binary files differ
diff --git a/test/reference/extend-reflect.base.argb32.ref.png b/test/reference/extend-reflect.base.argb32.ref.png
new file mode 100644
index 000000000..5fc3448fa
--- /dev/null
+++ b/test/reference/extend-reflect.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/extend-reflect.base.rgb24.ref.png b/test/reference/extend-reflect.base.rgb24.ref.png
new file mode 100644
index 000000000..5fc3448fa
--- /dev/null
+++ b/test/reference/extend-reflect.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/extend-reflect.image16.ref.png b/test/reference/extend-reflect.image16.ref.png
new file mode 100644
index 000000000..27c6594ea
--- /dev/null
+++ b/test/reference/extend-reflect.image16.ref.png
Binary files differ
diff --git a/test/reference/extend-reflect.ps2.ref.png b/test/reference/extend-reflect.ps2.ref.png
new file mode 100644
index 000000000..acaee1b5a
--- /dev/null
+++ b/test/reference/extend-reflect.ps2.ref.png
Binary files differ
diff --git a/test/reference/extend-reflect.ps3.ref.png b/test/reference/extend-reflect.ps3.ref.png
new file mode 100644
index 000000000..acaee1b5a
--- /dev/null
+++ b/test/reference/extend-reflect.ps3.ref.png
Binary files differ
diff --git a/test/reference/extend-reflect.ref.png b/test/reference/extend-reflect.ref.png
new file mode 100644
index 000000000..93a8b001b
--- /dev/null
+++ b/test/reference/extend-reflect.ref.png
Binary files differ
diff --git a/test/reference/extend-repeat-similar.base.argb32.ref.png b/test/reference/extend-repeat-similar.base.argb32.ref.png
new file mode 100644
index 000000000..81f0503df
--- /dev/null
+++ b/test/reference/extend-repeat-similar.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/extend-repeat-similar.base.rgb24.ref.png b/test/reference/extend-repeat-similar.base.rgb24.ref.png
new file mode 100644
index 000000000..81f0503df
--- /dev/null
+++ b/test/reference/extend-repeat-similar.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/extend-repeat-similar.image16.ref.png b/test/reference/extend-repeat-similar.image16.ref.png
new file mode 100644
index 000000000..cdc742a74
--- /dev/null
+++ b/test/reference/extend-repeat-similar.image16.ref.png
Binary files differ
diff --git a/test/reference/extend-repeat-similar.ps2.ref.png b/test/reference/extend-repeat-similar.ps2.ref.png
new file mode 100644
index 000000000..8218211ee
--- /dev/null
+++ b/test/reference/extend-repeat-similar.ps2.ref.png
Binary files differ
diff --git a/test/reference/extend-repeat-similar.ps3.ref.png b/test/reference/extend-repeat-similar.ps3.ref.png
new file mode 100644
index 000000000..8218211ee
--- /dev/null
+++ b/test/reference/extend-repeat-similar.ps3.ref.png
Binary files differ
diff --git a/test/reference/extend-repeat-similar.ref.png b/test/reference/extend-repeat-similar.ref.png
new file mode 100644
index 000000000..ee2527fad
--- /dev/null
+++ b/test/reference/extend-repeat-similar.ref.png
Binary files differ
diff --git a/test/reference/extend-repeat.base.argb32.ref.png b/test/reference/extend-repeat.base.argb32.ref.png
new file mode 100644
index 000000000..81f0503df
--- /dev/null
+++ b/test/reference/extend-repeat.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/extend-repeat.base.rgb24.ref.png b/test/reference/extend-repeat.base.rgb24.ref.png
new file mode 100644
index 000000000..81f0503df
--- /dev/null
+++ b/test/reference/extend-repeat.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/extend-repeat.image16.ref.png b/test/reference/extend-repeat.image16.ref.png
new file mode 100644
index 000000000..cdc742a74
--- /dev/null
+++ b/test/reference/extend-repeat.image16.ref.png
Binary files differ
diff --git a/test/reference/extend-repeat.ps2.ref.png b/test/reference/extend-repeat.ps2.ref.png
new file mode 100644
index 000000000..8218211ee
--- /dev/null
+++ b/test/reference/extend-repeat.ps2.ref.png
Binary files differ
diff --git a/test/reference/extend-repeat.ps3.ref.png b/test/reference/extend-repeat.ps3.ref.png
new file mode 100644
index 000000000..8218211ee
--- /dev/null
+++ b/test/reference/extend-repeat.ps3.ref.png
Binary files differ
diff --git a/test/reference/extend-repeat.ref.png b/test/reference/extend-repeat.ref.png
new file mode 100644
index 000000000..ee2527fad
--- /dev/null
+++ b/test/reference/extend-repeat.ref.png
Binary files differ
diff --git a/test/reference/extended-blend-alpha-mask.argb32.ref.png b/test/reference/extended-blend-alpha-mask.argb32.ref.png
new file mode 100644
index 000000000..a1dd2a93f
--- /dev/null
+++ b/test/reference/extended-blend-alpha-mask.argb32.ref.png
Binary files differ
diff --git a/test/reference/extended-blend-alpha-mask.base.argb32.ref.png b/test/reference/extended-blend-alpha-mask.base.argb32.ref.png
new file mode 100644
index 000000000..a1dd2a93f
--- /dev/null
+++ b/test/reference/extended-blend-alpha-mask.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/extended-blend-alpha-mask.base.rgb24.ref.png b/test/reference/extended-blend-alpha-mask.base.rgb24.ref.png
new file mode 100644
index 000000000..b5f12f145
--- /dev/null
+++ b/test/reference/extended-blend-alpha-mask.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/extended-blend-alpha-mask.rgb24.ref.png b/test/reference/extended-blend-alpha-mask.rgb24.ref.png
new file mode 100644
index 000000000..b5f12f145
--- /dev/null
+++ b/test/reference/extended-blend-alpha-mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/extended-blend-alpha.argb32.ref.png b/test/reference/extended-blend-alpha.argb32.ref.png
new file mode 100644
index 000000000..4d56a21fc
--- /dev/null
+++ b/test/reference/extended-blend-alpha.argb32.ref.png
Binary files differ
diff --git a/test/reference/extended-blend-alpha.base.argb32.ref.png b/test/reference/extended-blend-alpha.base.argb32.ref.png
new file mode 100644
index 000000000..4d56a21fc
--- /dev/null
+++ b/test/reference/extended-blend-alpha.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/extended-blend-alpha.base.rgb24.ref.png b/test/reference/extended-blend-alpha.base.rgb24.ref.png
new file mode 100644
index 000000000..86d0e2d91
--- /dev/null
+++ b/test/reference/extended-blend-alpha.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/extended-blend-alpha.image16.ref.png b/test/reference/extended-blend-alpha.image16.ref.png
new file mode 100644
index 000000000..df9646977
--- /dev/null
+++ b/test/reference/extended-blend-alpha.image16.ref.png
Binary files differ
diff --git a/test/reference/extended-blend-alpha.quartz.argb32.ref.png b/test/reference/extended-blend-alpha.quartz.argb32.ref.png
new file mode 100644
index 000000000..e5701a652
--- /dev/null
+++ b/test/reference/extended-blend-alpha.quartz.argb32.ref.png
Binary files differ
diff --git a/test/reference/extended-blend-alpha.quartz.rgb24.ref.png b/test/reference/extended-blend-alpha.quartz.rgb24.ref.png
new file mode 100644
index 000000000..477d346c5
--- /dev/null
+++ b/test/reference/extended-blend-alpha.quartz.rgb24.ref.png
Binary files differ
diff --git a/test/reference/extended-blend-alpha.rgb24.ref.png b/test/reference/extended-blend-alpha.rgb24.ref.png
new file mode 100644
index 000000000..86d0e2d91
--- /dev/null
+++ b/test/reference/extended-blend-alpha.rgb24.ref.png
Binary files differ
diff --git a/test/reference/extended-blend-alpha.svg12.argb32.xfail.png b/test/reference/extended-blend-alpha.svg12.argb32.xfail.png
new file mode 100644
index 000000000..cc344164f
--- /dev/null
+++ b/test/reference/extended-blend-alpha.svg12.argb32.xfail.png
Binary files differ
diff --git a/test/reference/extended-blend-alpha.svg12.rgb24.xfail.png b/test/reference/extended-blend-alpha.svg12.rgb24.xfail.png
new file mode 100644
index 000000000..f80569e99
--- /dev/null
+++ b/test/reference/extended-blend-alpha.svg12.rgb24.xfail.png
Binary files differ
diff --git a/test/reference/extended-blend-mask.argb32.ref.png b/test/reference/extended-blend-mask.argb32.ref.png
new file mode 100644
index 000000000..79a6e5380
--- /dev/null
+++ b/test/reference/extended-blend-mask.argb32.ref.png
Binary files differ
diff --git a/test/reference/extended-blend-mask.base.argb32.ref.png b/test/reference/extended-blend-mask.base.argb32.ref.png
new file mode 100644
index 000000000..5fa78e4cc
--- /dev/null
+++ b/test/reference/extended-blend-mask.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/extended-blend-mask.base.rgb24.ref.png b/test/reference/extended-blend-mask.base.rgb24.ref.png
new file mode 100644
index 000000000..1c854745b
--- /dev/null
+++ b/test/reference/extended-blend-mask.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/extended-blend-mask.rgb24.ref.png b/test/reference/extended-blend-mask.rgb24.ref.png
new file mode 100644
index 000000000..400df6a20
--- /dev/null
+++ b/test/reference/extended-blend-mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/extended-blend-solid-alpha.argb32.ref.png b/test/reference/extended-blend-solid-alpha.argb32.ref.png
new file mode 100644
index 000000000..4d56a21fc
--- /dev/null
+++ b/test/reference/extended-blend-solid-alpha.argb32.ref.png
Binary files differ
diff --git a/test/reference/extended-blend-solid-alpha.base.argb32.ref.png b/test/reference/extended-blend-solid-alpha.base.argb32.ref.png
new file mode 100644
index 000000000..4d56a21fc
--- /dev/null
+++ b/test/reference/extended-blend-solid-alpha.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/extended-blend-solid-alpha.base.rgb24.ref.png b/test/reference/extended-blend-solid-alpha.base.rgb24.ref.png
new file mode 100644
index 000000000..86d0e2d91
--- /dev/null
+++ b/test/reference/extended-blend-solid-alpha.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/extended-blend-solid-alpha.image16.ref.png b/test/reference/extended-blend-solid-alpha.image16.ref.png
new file mode 100644
index 000000000..df9646977
--- /dev/null
+++ b/test/reference/extended-blend-solid-alpha.image16.ref.png
Binary files differ
diff --git a/test/reference/extended-blend-solid-alpha.rgb24.ref.png b/test/reference/extended-blend-solid-alpha.rgb24.ref.png
new file mode 100644
index 000000000..86d0e2d91
--- /dev/null
+++ b/test/reference/extended-blend-solid-alpha.rgb24.ref.png
Binary files differ
diff --git a/test/reference/extended-blend-solid.argb32.ref.png b/test/reference/extended-blend-solid.argb32.ref.png
new file mode 100644
index 000000000..573c16a26
--- /dev/null
+++ b/test/reference/extended-blend-solid.argb32.ref.png
Binary files differ
diff --git a/test/reference/extended-blend-solid.base.argb32.ref.png b/test/reference/extended-blend-solid.base.argb32.ref.png
new file mode 100644
index 000000000..902ef8845
--- /dev/null
+++ b/test/reference/extended-blend-solid.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/extended-blend-solid.base.rgb24.ref.png b/test/reference/extended-blend-solid.base.rgb24.ref.png
new file mode 100644
index 000000000..4580e0dad
--- /dev/null
+++ b/test/reference/extended-blend-solid.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/extended-blend-solid.image16.ref.png b/test/reference/extended-blend-solid.image16.ref.png
new file mode 100644
index 000000000..2052ea7cb
--- /dev/null
+++ b/test/reference/extended-blend-solid.image16.ref.png
Binary files differ
diff --git a/test/reference/extended-blend-solid.rgb24.ref.png b/test/reference/extended-blend-solid.rgb24.ref.png
new file mode 100644
index 000000000..cdcb6ad11
--- /dev/null
+++ b/test/reference/extended-blend-solid.rgb24.ref.png
Binary files differ
diff --git a/test/reference/extended-blend.argb32.ref.png b/test/reference/extended-blend.argb32.ref.png
new file mode 100644
index 000000000..573c16a26
--- /dev/null
+++ b/test/reference/extended-blend.argb32.ref.png
Binary files differ
diff --git a/test/reference/extended-blend.base.argb32.ref.png b/test/reference/extended-blend.base.argb32.ref.png
new file mode 100644
index 000000000..902ef8845
--- /dev/null
+++ b/test/reference/extended-blend.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/extended-blend.base.rgb24.ref.png b/test/reference/extended-blend.base.rgb24.ref.png
new file mode 100644
index 000000000..4580e0dad
--- /dev/null
+++ b/test/reference/extended-blend.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/extended-blend.image16.ref.png b/test/reference/extended-blend.image16.ref.png
new file mode 100644
index 000000000..2052ea7cb
--- /dev/null
+++ b/test/reference/extended-blend.image16.ref.png
Binary files differ
diff --git a/test/reference/extended-blend.quartz.argb32.ref.png b/test/reference/extended-blend.quartz.argb32.ref.png
new file mode 100644
index 000000000..173c6e23c
--- /dev/null
+++ b/test/reference/extended-blend.quartz.argb32.ref.png
Binary files differ
diff --git a/test/reference/extended-blend.quartz.rgb24.ref.png b/test/reference/extended-blend.quartz.rgb24.ref.png
new file mode 100644
index 000000000..56a1214ee
--- /dev/null
+++ b/test/reference/extended-blend.quartz.rgb24.ref.png
Binary files differ
diff --git a/test/reference/extended-blend.rgb24.ref.png b/test/reference/extended-blend.rgb24.ref.png
new file mode 100644
index 000000000..cdcb6ad11
--- /dev/null
+++ b/test/reference/extended-blend.rgb24.ref.png
Binary files differ
diff --git a/test/reference/extended-blend.svg12.argb32.xfail.png b/test/reference/extended-blend.svg12.argb32.xfail.png
new file mode 100644
index 000000000..93297a5c4
--- /dev/null
+++ b/test/reference/extended-blend.svg12.argb32.xfail.png
Binary files differ
diff --git a/test/reference/extended-blend.svg12.rgb24.xfail.png b/test/reference/extended-blend.svg12.rgb24.xfail.png
new file mode 100644
index 000000000..8db02c554
--- /dev/null
+++ b/test/reference/extended-blend.svg12.rgb24.xfail.png
Binary files differ
diff --git a/test/reference/fallback-resolution.ppi144x144.ps.ref.png b/test/reference/fallback-resolution.ppi144x144.ps.ref.png
new file mode 100644
index 000000000..0922f03d3
--- /dev/null
+++ b/test/reference/fallback-resolution.ppi144x144.ps.ref.png
Binary files differ
diff --git a/test/reference/fallback-resolution.ppi144x144.ref.png b/test/reference/fallback-resolution.ppi144x144.ref.png
new file mode 100644
index 000000000..fd0666a42
--- /dev/null
+++ b/test/reference/fallback-resolution.ppi144x144.ref.png
Binary files differ
diff --git a/test/reference/fallback-resolution.ppi144x72.ps.ref.png b/test/reference/fallback-resolution.ppi144x72.ps.ref.png
new file mode 100644
index 000000000..2f8d82d8d
--- /dev/null
+++ b/test/reference/fallback-resolution.ppi144x72.ps.ref.png
Binary files differ
diff --git a/test/reference/fallback-resolution.ppi144x72.ref.png b/test/reference/fallback-resolution.ppi144x72.ref.png
new file mode 100644
index 000000000..ec6685cc0
--- /dev/null
+++ b/test/reference/fallback-resolution.ppi144x72.ref.png
Binary files differ
diff --git a/test/reference/fallback-resolution.ppi288x288.pdf.ref.png b/test/reference/fallback-resolution.ppi288x288.pdf.ref.png
new file mode 100644
index 000000000..181e110fe
--- /dev/null
+++ b/test/reference/fallback-resolution.ppi288x288.pdf.ref.png
Binary files differ
diff --git a/test/reference/fallback-resolution.ppi288x288.ps.ref.png b/test/reference/fallback-resolution.ppi288x288.ps.ref.png
new file mode 100644
index 000000000..99bccef2a
--- /dev/null
+++ b/test/reference/fallback-resolution.ppi288x288.ps.ref.png
Binary files differ
diff --git a/test/reference/fallback-resolution.ppi288x288.svg.ref.png b/test/reference/fallback-resolution.ppi288x288.svg.ref.png
new file mode 100644
index 000000000..e71ff8157
--- /dev/null
+++ b/test/reference/fallback-resolution.ppi288x288.svg.ref.png
Binary files differ
diff --git a/test/reference/fallback-resolution.ppi288x72.ps.ref.png b/test/reference/fallback-resolution.ppi288x72.ps.ref.png
new file mode 100644
index 000000000..89b9c5176
--- /dev/null
+++ b/test/reference/fallback-resolution.ppi288x72.ps.ref.png
Binary files differ
diff --git a/test/reference/fallback-resolution.ppi288x72.ref.png b/test/reference/fallback-resolution.ppi288x72.ref.png
new file mode 100644
index 000000000..969c04f17
--- /dev/null
+++ b/test/reference/fallback-resolution.ppi288x72.ref.png
Binary files differ
diff --git a/test/reference/fallback-resolution.ppi576x576.pdf.ref.png b/test/reference/fallback-resolution.ppi576x576.pdf.ref.png
new file mode 100644
index 000000000..5b376199b
--- /dev/null
+++ b/test/reference/fallback-resolution.ppi576x576.pdf.ref.png
Binary files differ
diff --git a/test/reference/fallback-resolution.ppi576x576.ps.ref.png b/test/reference/fallback-resolution.ppi576x576.ps.ref.png
new file mode 100644
index 000000000..9dc473532
--- /dev/null
+++ b/test/reference/fallback-resolution.ppi576x576.ps.ref.png
Binary files differ
diff --git a/test/reference/fallback-resolution.ppi576x576.svg.ref.png b/test/reference/fallback-resolution.ppi576x576.svg.ref.png
new file mode 100644
index 000000000..b5a97e30d
--- /dev/null
+++ b/test/reference/fallback-resolution.ppi576x576.svg.ref.png
Binary files differ
diff --git a/test/reference/fallback-resolution.ppi576x72.ps.ref.png b/test/reference/fallback-resolution.ppi576x72.ps.ref.png
new file mode 100644
index 000000000..9ac6be4a5
--- /dev/null
+++ b/test/reference/fallback-resolution.ppi576x72.ps.ref.png
Binary files differ
diff --git a/test/reference/fallback-resolution.ppi576x72.ref.png b/test/reference/fallback-resolution.ppi576x72.ref.png
new file mode 100644
index 000000000..bbab0653e
--- /dev/null
+++ b/test/reference/fallback-resolution.ppi576x72.ref.png
Binary files differ
diff --git a/test/reference/fallback-resolution.ppi72x144.ps.ref.png b/test/reference/fallback-resolution.ppi72x144.ps.ref.png
new file mode 100644
index 000000000..50b5a9905
--- /dev/null
+++ b/test/reference/fallback-resolution.ppi72x144.ps.ref.png
Binary files differ
diff --git a/test/reference/fallback-resolution.ppi72x144.ref.png b/test/reference/fallback-resolution.ppi72x144.ref.png
new file mode 100644
index 000000000..3f5562967
--- /dev/null
+++ b/test/reference/fallback-resolution.ppi72x144.ref.png
Binary files differ
diff --git a/test/reference/fallback-resolution.ppi72x288.ps.ref.png b/test/reference/fallback-resolution.ppi72x288.ps.ref.png
new file mode 100644
index 000000000..b4ff82d72
--- /dev/null
+++ b/test/reference/fallback-resolution.ppi72x288.ps.ref.png
Binary files differ
diff --git a/test/reference/fallback-resolution.ppi72x288.ref.png b/test/reference/fallback-resolution.ppi72x288.ref.png
new file mode 100644
index 000000000..9d50b64d6
--- /dev/null
+++ b/test/reference/fallback-resolution.ppi72x288.ref.png
Binary files differ
diff --git a/test/reference/fallback-resolution.ppi72x576.ps.ref.png b/test/reference/fallback-resolution.ppi72x576.ps.ref.png
new file mode 100644
index 000000000..6a3ddcb5c
--- /dev/null
+++ b/test/reference/fallback-resolution.ppi72x576.ps.ref.png
Binary files differ
diff --git a/test/reference/fallback-resolution.ppi72x576.ref.png b/test/reference/fallback-resolution.ppi72x576.ref.png
new file mode 100644
index 000000000..7b4d62e19
--- /dev/null
+++ b/test/reference/fallback-resolution.ppi72x576.ref.png
Binary files differ
diff --git a/test/reference/fallback-resolution.ppi72x72.ref.png b/test/reference/fallback-resolution.ppi72x72.ref.png
new file mode 100644
index 000000000..690c0af2d
--- /dev/null
+++ b/test/reference/fallback-resolution.ppi72x72.ref.png
Binary files differ
diff --git a/test/reference/fallback.argb32.ref.png b/test/reference/fallback.argb32.ref.png
new file mode 100644
index 000000000..b96e90af6
--- /dev/null
+++ b/test/reference/fallback.argb32.ref.png
Binary files differ
diff --git a/test/reference/fallback.base.argb32.ref.png b/test/reference/fallback.base.argb32.ref.png
new file mode 100644
index 000000000..c0c5f4676
--- /dev/null
+++ b/test/reference/fallback.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/fallback.base.rgb24.ref.png b/test/reference/fallback.base.rgb24.ref.png
new file mode 100644
index 000000000..18b6a7c83
--- /dev/null
+++ b/test/reference/fallback.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/fallback.image16.rgb24.ref.png b/test/reference/fallback.image16.rgb24.ref.png
new file mode 100644
index 000000000..d90ab0e6b
--- /dev/null
+++ b/test/reference/fallback.image16.rgb24.ref.png
Binary files differ
diff --git a/test/reference/fallback.mask.argb32.ref.png b/test/reference/fallback.mask.argb32.ref.png
new file mode 100644
index 000000000..b7ce57363
--- /dev/null
+++ b/test/reference/fallback.mask.argb32.ref.png
Binary files differ
diff --git a/test/reference/fallback.mask.rgb24.ref.png b/test/reference/fallback.mask.rgb24.ref.png
new file mode 100644
index 000000000..16d3c14e4
--- /dev/null
+++ b/test/reference/fallback.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/fallback.rgb24.ref.png b/test/reference/fallback.rgb24.ref.png
new file mode 100644
index 000000000..3f9213219
--- /dev/null
+++ b/test/reference/fallback.rgb24.ref.png
Binary files differ
diff --git a/test/reference/fallback.traps.argb32.ref.png b/test/reference/fallback.traps.argb32.ref.png
new file mode 100644
index 000000000..c0c5f4676
--- /dev/null
+++ b/test/reference/fallback.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/fallback.traps.rgb24.ref.png b/test/reference/fallback.traps.rgb24.ref.png
new file mode 100644
index 000000000..18b6a7c83
--- /dev/null
+++ b/test/reference/fallback.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/fill-alpha-pattern.base.argb32.ref.png b/test/reference/fill-alpha-pattern.base.argb32.ref.png
new file mode 100644
index 000000000..4dafb8359
--- /dev/null
+++ b/test/reference/fill-alpha-pattern.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/fill-alpha-pattern.base.rgb24.ref.png b/test/reference/fill-alpha-pattern.base.rgb24.ref.png
new file mode 100644
index 000000000..4dafb8359
--- /dev/null
+++ b/test/reference/fill-alpha-pattern.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/fill-alpha-pattern.image16.ref.png b/test/reference/fill-alpha-pattern.image16.ref.png
new file mode 100644
index 000000000..f323c10ff
--- /dev/null
+++ b/test/reference/fill-alpha-pattern.image16.ref.png
Binary files differ
diff --git a/test/reference/fill-alpha-pattern.pdf.ref.png b/test/reference/fill-alpha-pattern.pdf.ref.png
new file mode 100644
index 000000000..ed7f40453
--- /dev/null
+++ b/test/reference/fill-alpha-pattern.pdf.ref.png
Binary files differ
diff --git a/test/reference/fill-alpha-pattern.ps3.argb32.ref.png b/test/reference/fill-alpha-pattern.ps3.argb32.ref.png
new file mode 100644
index 000000000..28689a381
--- /dev/null
+++ b/test/reference/fill-alpha-pattern.ps3.argb32.ref.png
Binary files differ
diff --git a/test/reference/fill-alpha-pattern.quartz.ref.png b/test/reference/fill-alpha-pattern.quartz.ref.png
new file mode 100644
index 000000000..b612e7a6b
--- /dev/null
+++ b/test/reference/fill-alpha-pattern.quartz.ref.png
Binary files differ
diff --git a/test/reference/fill-alpha-pattern.ref.png b/test/reference/fill-alpha-pattern.ref.png
new file mode 100644
index 000000000..e32eb90f1
--- /dev/null
+++ b/test/reference/fill-alpha-pattern.ref.png
Binary files differ
diff --git a/test/reference/fill-alpha-pattern.traps.argb32.ref.png b/test/reference/fill-alpha-pattern.traps.argb32.ref.png
new file mode 100644
index 000000000..4dafb8359
--- /dev/null
+++ b/test/reference/fill-alpha-pattern.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/fill-alpha-pattern.traps.rgb24.ref.png b/test/reference/fill-alpha-pattern.traps.rgb24.ref.png
new file mode 100644
index 000000000..4dafb8359
--- /dev/null
+++ b/test/reference/fill-alpha-pattern.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/fill-alpha.base.argb32.ref.png b/test/reference/fill-alpha.base.argb32.ref.png
new file mode 100644
index 000000000..85df9198c
--- /dev/null
+++ b/test/reference/fill-alpha.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/fill-alpha.base.rgb24.ref.png b/test/reference/fill-alpha.base.rgb24.ref.png
new file mode 100644
index 000000000..85df9198c
--- /dev/null
+++ b/test/reference/fill-alpha.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/fill-alpha.image16.ref.png b/test/reference/fill-alpha.image16.ref.png
new file mode 100644
index 000000000..08252b6c9
--- /dev/null
+++ b/test/reference/fill-alpha.image16.ref.png
Binary files differ
diff --git a/test/reference/fill-alpha.ps.argb32.ref.png b/test/reference/fill-alpha.ps.argb32.ref.png
new file mode 100644
index 000000000..8d70d53f8
--- /dev/null
+++ b/test/reference/fill-alpha.ps.argb32.ref.png
Binary files differ
diff --git a/test/reference/fill-alpha.quartz.ref.png b/test/reference/fill-alpha.quartz.ref.png
new file mode 100644
index 000000000..81cee81e2
--- /dev/null
+++ b/test/reference/fill-alpha.quartz.ref.png
Binary files differ
diff --git a/test/reference/fill-alpha.ref.png b/test/reference/fill-alpha.ref.png
new file mode 100644
index 000000000..25c1ac68f
--- /dev/null
+++ b/test/reference/fill-alpha.ref.png
Binary files differ
diff --git a/test/reference/fill-alpha.traps.argb32.ref.png b/test/reference/fill-alpha.traps.argb32.ref.png
new file mode 100644
index 000000000..85df9198c
--- /dev/null
+++ b/test/reference/fill-alpha.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/fill-alpha.traps.rgb24.ref.png b/test/reference/fill-alpha.traps.rgb24.ref.png
new file mode 100644
index 000000000..85df9198c
--- /dev/null
+++ b/test/reference/fill-alpha.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/fill-and-stroke-alpha-add.base.argb32.ref.png b/test/reference/fill-and-stroke-alpha-add.base.argb32.ref.png
new file mode 100644
index 000000000..71d2b2221
--- /dev/null
+++ b/test/reference/fill-and-stroke-alpha-add.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/fill-and-stroke-alpha-add.base.rgb24.ref.png b/test/reference/fill-and-stroke-alpha-add.base.rgb24.ref.png
new file mode 100644
index 000000000..71d2b2221
--- /dev/null
+++ b/test/reference/fill-and-stroke-alpha-add.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/fill-and-stroke-alpha-add.image16.ref.png b/test/reference/fill-and-stroke-alpha-add.image16.ref.png
new file mode 100644
index 000000000..3162c8115
--- /dev/null
+++ b/test/reference/fill-and-stroke-alpha-add.image16.ref.png
Binary files differ
diff --git a/test/reference/fill-and-stroke-alpha-add.quartz.ref.png b/test/reference/fill-and-stroke-alpha-add.quartz.ref.png
new file mode 100644
index 000000000..1d8975253
--- /dev/null
+++ b/test/reference/fill-and-stroke-alpha-add.quartz.ref.png
Binary files differ
diff --git a/test/reference/fill-and-stroke-alpha-add.ref.png b/test/reference/fill-and-stroke-alpha-add.ref.png
new file mode 100644
index 000000000..f10ffc2a3
--- /dev/null
+++ b/test/reference/fill-and-stroke-alpha-add.ref.png
Binary files differ
diff --git a/test/reference/fill-and-stroke-alpha-add.svg12.xfail.png b/test/reference/fill-and-stroke-alpha-add.svg12.xfail.png
new file mode 100644
index 000000000..c1d7d6fc7
--- /dev/null
+++ b/test/reference/fill-and-stroke-alpha-add.svg12.xfail.png
Binary files differ
diff --git a/test/reference/fill-and-stroke-alpha-add.traps.argb32.ref.png b/test/reference/fill-and-stroke-alpha-add.traps.argb32.ref.png
new file mode 100644
index 000000000..71d2b2221
--- /dev/null
+++ b/test/reference/fill-and-stroke-alpha-add.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/fill-and-stroke-alpha-add.traps.rgb24.ref.png b/test/reference/fill-and-stroke-alpha-add.traps.rgb24.ref.png
new file mode 100644
index 000000000..71d2b2221
--- /dev/null
+++ b/test/reference/fill-and-stroke-alpha-add.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/fill-and-stroke-alpha.base.argb32.ref.png b/test/reference/fill-and-stroke-alpha.base.argb32.ref.png
new file mode 100644
index 000000000..c85b933b0
--- /dev/null
+++ b/test/reference/fill-and-stroke-alpha.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/fill-and-stroke-alpha.base.rgb24.ref.png b/test/reference/fill-and-stroke-alpha.base.rgb24.ref.png
new file mode 100644
index 000000000..c85b933b0
--- /dev/null
+++ b/test/reference/fill-and-stroke-alpha.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/fill-and-stroke-alpha.image16.ref.png b/test/reference/fill-and-stroke-alpha.image16.ref.png
new file mode 100644
index 000000000..cde5bd92d
--- /dev/null
+++ b/test/reference/fill-and-stroke-alpha.image16.ref.png
Binary files differ
diff --git a/test/reference/fill-and-stroke-alpha.ref.png b/test/reference/fill-and-stroke-alpha.ref.png
new file mode 100644
index 000000000..8e811570e
--- /dev/null
+++ b/test/reference/fill-and-stroke-alpha.ref.png
Binary files differ
diff --git a/test/reference/fill-and-stroke-alpha.traps.argb32.ref.png b/test/reference/fill-and-stroke-alpha.traps.argb32.ref.png
new file mode 100644
index 000000000..c85b933b0
--- /dev/null
+++ b/test/reference/fill-and-stroke-alpha.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/fill-and-stroke-alpha.traps.rgb24.ref.png b/test/reference/fill-and-stroke-alpha.traps.rgb24.ref.png
new file mode 100644
index 000000000..c85b933b0
--- /dev/null
+++ b/test/reference/fill-and-stroke-alpha.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/fill-and-stroke.base.argb32.ref.png b/test/reference/fill-and-stroke.base.argb32.ref.png
new file mode 100644
index 000000000..3f32060f4
--- /dev/null
+++ b/test/reference/fill-and-stroke.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/fill-and-stroke.base.rgb24.ref.png b/test/reference/fill-and-stroke.base.rgb24.ref.png
new file mode 100644
index 000000000..2797921e4
--- /dev/null
+++ b/test/reference/fill-and-stroke.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/fill-and-stroke.image16.ref.png b/test/reference/fill-and-stroke.image16.ref.png
new file mode 100644
index 000000000..f562509f3
--- /dev/null
+++ b/test/reference/fill-and-stroke.image16.ref.png
Binary files differ
diff --git a/test/reference/fill-and-stroke.ps.argb32.ref.png b/test/reference/fill-and-stroke.ps.argb32.ref.png
new file mode 100644
index 000000000..8cf8d9cc6
--- /dev/null
+++ b/test/reference/fill-and-stroke.ps.argb32.ref.png
Binary files differ
diff --git a/test/reference/fill-and-stroke.ps.rgb24.ref.png b/test/reference/fill-and-stroke.ps.rgb24.ref.png
new file mode 100644
index 000000000..fceda260e
--- /dev/null
+++ b/test/reference/fill-and-stroke.ps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/fill-and-stroke.quartz.argb32.ref.png b/test/reference/fill-and-stroke.quartz.argb32.ref.png
new file mode 100644
index 000000000..944071919
--- /dev/null
+++ b/test/reference/fill-and-stroke.quartz.argb32.ref.png
Binary files differ
diff --git a/test/reference/fill-and-stroke.quartz.rgb24.ref.png b/test/reference/fill-and-stroke.quartz.rgb24.ref.png
new file mode 100644
index 000000000..5ba219756
--- /dev/null
+++ b/test/reference/fill-and-stroke.quartz.rgb24.ref.png
Binary files differ
diff --git a/test/reference/fill-and-stroke.ref.png b/test/reference/fill-and-stroke.ref.png
new file mode 100644
index 000000000..c71a4e589
--- /dev/null
+++ b/test/reference/fill-and-stroke.ref.png
Binary files differ
diff --git a/test/reference/fill-and-stroke.traps.argb32.ref.png b/test/reference/fill-and-stroke.traps.argb32.ref.png
new file mode 100644
index 000000000..3f32060f4
--- /dev/null
+++ b/test/reference/fill-and-stroke.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/fill-and-stroke.traps.rgb24.ref.png b/test/reference/fill-and-stroke.traps.rgb24.ref.png
new file mode 100644
index 000000000..2797921e4
--- /dev/null
+++ b/test/reference/fill-and-stroke.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/fill-degenerate-sort-order.argb32.ref.png b/test/reference/fill-degenerate-sort-order.argb32.ref.png
new file mode 100644
index 000000000..bed9b5ccd
--- /dev/null
+++ b/test/reference/fill-degenerate-sort-order.argb32.ref.png
Binary files differ
diff --git a/test/reference/fill-degenerate-sort-order.base.argb32.ref.png b/test/reference/fill-degenerate-sort-order.base.argb32.ref.png
new file mode 100644
index 000000000..860ee1b16
--- /dev/null
+++ b/test/reference/fill-degenerate-sort-order.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/fill-degenerate-sort-order.base.rgb24.ref.png b/test/reference/fill-degenerate-sort-order.base.rgb24.ref.png
new file mode 100644
index 000000000..18b08fc4b
--- /dev/null
+++ b/test/reference/fill-degenerate-sort-order.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/fill-degenerate-sort-order.image16.ref.png b/test/reference/fill-degenerate-sort-order.image16.ref.png
new file mode 100644
index 000000000..6dc207870
--- /dev/null
+++ b/test/reference/fill-degenerate-sort-order.image16.ref.png
Binary files differ
diff --git a/test/reference/fill-degenerate-sort-order.ps.argb32.xfail.png b/test/reference/fill-degenerate-sort-order.ps.argb32.xfail.png
new file mode 100644
index 000000000..79ea63071
--- /dev/null
+++ b/test/reference/fill-degenerate-sort-order.ps.argb32.xfail.png
Binary files differ
diff --git a/test/reference/fill-degenerate-sort-order.ps.rgb24.xfail.png b/test/reference/fill-degenerate-sort-order.ps.rgb24.xfail.png
new file mode 100644
index 000000000..b4c45f9a1
--- /dev/null
+++ b/test/reference/fill-degenerate-sort-order.ps.rgb24.xfail.png
Binary files differ
diff --git a/test/reference/fill-degenerate-sort-order.quartz.argb32.ref.png b/test/reference/fill-degenerate-sort-order.quartz.argb32.ref.png
new file mode 100644
index 000000000..a8b9f15bc
--- /dev/null
+++ b/test/reference/fill-degenerate-sort-order.quartz.argb32.ref.png
Binary files differ
diff --git a/test/reference/fill-degenerate-sort-order.quartz.rgb24.ref.png b/test/reference/fill-degenerate-sort-order.quartz.rgb24.ref.png
new file mode 100644
index 000000000..703467cf2
--- /dev/null
+++ b/test/reference/fill-degenerate-sort-order.quartz.rgb24.ref.png
Binary files differ
diff --git a/test/reference/fill-degenerate-sort-order.rgb24.ref.png b/test/reference/fill-degenerate-sort-order.rgb24.ref.png
new file mode 100644
index 000000000..3f26e302d
--- /dev/null
+++ b/test/reference/fill-degenerate-sort-order.rgb24.ref.png
Binary files differ
diff --git a/test/reference/fill-degenerate-sort-order.traps.argb32.ref.png b/test/reference/fill-degenerate-sort-order.traps.argb32.ref.png
new file mode 100644
index 000000000..860ee1b16
--- /dev/null
+++ b/test/reference/fill-degenerate-sort-order.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/fill-degenerate-sort-order.traps.rgb24.ref.png b/test/reference/fill-degenerate-sort-order.traps.rgb24.ref.png
new file mode 100644
index 000000000..18b08fc4b
--- /dev/null
+++ b/test/reference/fill-degenerate-sort-order.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/fill-disjoint.base.argb32.ref.png b/test/reference/fill-disjoint.base.argb32.ref.png
new file mode 100644
index 000000000..da9a3b112
--- /dev/null
+++ b/test/reference/fill-disjoint.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/fill-disjoint.base.rgb24.ref.png b/test/reference/fill-disjoint.base.rgb24.ref.png
new file mode 100644
index 000000000..da9a3b112
--- /dev/null
+++ b/test/reference/fill-disjoint.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/fill-disjoint.ref.png b/test/reference/fill-disjoint.ref.png
new file mode 100644
index 000000000..da9a3b112
--- /dev/null
+++ b/test/reference/fill-disjoint.ref.png
Binary files differ
diff --git a/test/reference/fill-empty.base.argb32.ref.png b/test/reference/fill-empty.base.argb32.ref.png
new file mode 100644
index 000000000..8c26f7ebf
--- /dev/null
+++ b/test/reference/fill-empty.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/fill-empty.base.rgb24.ref.png b/test/reference/fill-empty.base.rgb24.ref.png
new file mode 100644
index 000000000..dc7a8a0e4
--- /dev/null
+++ b/test/reference/fill-empty.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/fill-empty.ref.png b/test/reference/fill-empty.ref.png
new file mode 100644
index 000000000..8c26f7ebf
--- /dev/null
+++ b/test/reference/fill-empty.ref.png
Binary files differ
diff --git a/test/reference/fill-empty.svg12.rgb24.xfail.png b/test/reference/fill-empty.svg12.rgb24.xfail.png
new file mode 100644
index 000000000..8c26f7ebf
--- /dev/null
+++ b/test/reference/fill-empty.svg12.rgb24.xfail.png
Binary files differ
diff --git a/test/reference/fill-image.base.argb32.ref.png b/test/reference/fill-image.base.argb32.ref.png
new file mode 100644
index 000000000..1e67073df
--- /dev/null
+++ b/test/reference/fill-image.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/fill-image.base.rgb24.ref.png b/test/reference/fill-image.base.rgb24.ref.png
new file mode 100644
index 000000000..1e67073df
--- /dev/null
+++ b/test/reference/fill-image.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/fill-image.image16.ref.png b/test/reference/fill-image.image16.ref.png
new file mode 100644
index 000000000..3a9b7c794
--- /dev/null
+++ b/test/reference/fill-image.image16.ref.png
Binary files differ
diff --git a/test/reference/fill-image.ps.ref.png b/test/reference/fill-image.ps.ref.png
new file mode 100644
index 000000000..97137015e
--- /dev/null
+++ b/test/reference/fill-image.ps.ref.png
Binary files differ
diff --git a/test/reference/fill-image.quartz.ref.png b/test/reference/fill-image.quartz.ref.png
new file mode 100644
index 000000000..bb205a7d1
--- /dev/null
+++ b/test/reference/fill-image.quartz.ref.png
Binary files differ
diff --git a/test/reference/fill-image.ref.png b/test/reference/fill-image.ref.png
new file mode 100644
index 000000000..e521be4fd
--- /dev/null
+++ b/test/reference/fill-image.ref.png
Binary files differ
diff --git a/test/reference/fill-image.traps.argb32.ref.png b/test/reference/fill-image.traps.argb32.ref.png
new file mode 100644
index 000000000..1e67073df
--- /dev/null
+++ b/test/reference/fill-image.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/fill-image.traps.rgb24.ref.png b/test/reference/fill-image.traps.rgb24.ref.png
new file mode 100644
index 000000000..1e67073df
--- /dev/null
+++ b/test/reference/fill-image.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/fill-missed-stop.base.argb32.ref.png b/test/reference/fill-missed-stop.base.argb32.ref.png
new file mode 100644
index 000000000..223fb360e
--- /dev/null
+++ b/test/reference/fill-missed-stop.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/fill-missed-stop.base.rgb24.ref.png b/test/reference/fill-missed-stop.base.rgb24.ref.png
new file mode 100644
index 000000000..f56b4b2e9
--- /dev/null
+++ b/test/reference/fill-missed-stop.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/fill-missed-stop.pdf.argb32.ref.png b/test/reference/fill-missed-stop.pdf.argb32.ref.png
new file mode 100644
index 000000000..7d56e3e8c
--- /dev/null
+++ b/test/reference/fill-missed-stop.pdf.argb32.ref.png
Binary files differ
diff --git a/test/reference/fill-missed-stop.ps2.argb32.ref.png b/test/reference/fill-missed-stop.ps2.argb32.ref.png
new file mode 100644
index 000000000..b94a70899
--- /dev/null
+++ b/test/reference/fill-missed-stop.ps2.argb32.ref.png
Binary files differ
diff --git a/test/reference/fill-missed-stop.ps2.rgb24.ref.png b/test/reference/fill-missed-stop.ps2.rgb24.ref.png
new file mode 100644
index 000000000..fd54c7b1e
--- /dev/null
+++ b/test/reference/fill-missed-stop.ps2.rgb24.ref.png
Binary files differ
diff --git a/test/reference/fill-missed-stop.ps3.argb32.ref.png b/test/reference/fill-missed-stop.ps3.argb32.ref.png
new file mode 100644
index 000000000..b94a70899
--- /dev/null
+++ b/test/reference/fill-missed-stop.ps3.argb32.ref.png
Binary files differ
diff --git a/test/reference/fill-missed-stop.ps3.rgb24.ref.png b/test/reference/fill-missed-stop.ps3.rgb24.ref.png
new file mode 100644
index 000000000..fd54c7b1e
--- /dev/null
+++ b/test/reference/fill-missed-stop.ps3.rgb24.ref.png
Binary files differ
diff --git a/test/reference/fill-missed-stop.ref.png b/test/reference/fill-missed-stop.ref.png
new file mode 100644
index 000000000..477eec9a5
--- /dev/null
+++ b/test/reference/fill-missed-stop.ref.png
Binary files differ
diff --git a/test/reference/fill-missed-stop.traps.argb32.ref.png b/test/reference/fill-missed-stop.traps.argb32.ref.png
new file mode 100644
index 000000000..223fb360e
--- /dev/null
+++ b/test/reference/fill-missed-stop.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/fill-missed-stop.traps.rgb24.ref.png b/test/reference/fill-missed-stop.traps.rgb24.ref.png
new file mode 100644
index 000000000..f56b4b2e9
--- /dev/null
+++ b/test/reference/fill-missed-stop.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/fill-rule.argb32.ref.png b/test/reference/fill-rule.argb32.ref.png
new file mode 100644
index 000000000..9a0ea401f
--- /dev/null
+++ b/test/reference/fill-rule.argb32.ref.png
Binary files differ
diff --git a/test/reference/fill-rule.base.argb32.ref.png b/test/reference/fill-rule.base.argb32.ref.png
new file mode 100644
index 000000000..e2e10d4a8
--- /dev/null
+++ b/test/reference/fill-rule.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/fill-rule.base.rgb24.ref.png b/test/reference/fill-rule.base.rgb24.ref.png
new file mode 100644
index 000000000..49fb39c76
--- /dev/null
+++ b/test/reference/fill-rule.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/fill-rule.image16.ref.png b/test/reference/fill-rule.image16.ref.png
new file mode 100644
index 000000000..27613f70a
--- /dev/null
+++ b/test/reference/fill-rule.image16.ref.png
Binary files differ
diff --git a/test/reference/fill-rule.ps2.argb32.ref.png b/test/reference/fill-rule.ps2.argb32.ref.png
new file mode 100644
index 000000000..c9bdf9054
--- /dev/null
+++ b/test/reference/fill-rule.ps2.argb32.ref.png
Binary files differ
diff --git a/test/reference/fill-rule.ps2.rgb24.ref.png b/test/reference/fill-rule.ps2.rgb24.ref.png
new file mode 100644
index 000000000..617a20bda
--- /dev/null
+++ b/test/reference/fill-rule.ps2.rgb24.ref.png
Binary files differ
diff --git a/test/reference/fill-rule.ps3.argb32.ref.png b/test/reference/fill-rule.ps3.argb32.ref.png
new file mode 100644
index 000000000..c9bdf9054
--- /dev/null
+++ b/test/reference/fill-rule.ps3.argb32.ref.png
Binary files differ
diff --git a/test/reference/fill-rule.ps3.rgb24.ref.png b/test/reference/fill-rule.ps3.rgb24.ref.png
new file mode 100644
index 000000000..617a20bda
--- /dev/null
+++ b/test/reference/fill-rule.ps3.rgb24.ref.png
Binary files differ
diff --git a/test/reference/fill-rule.quartz.argb32.ref.png b/test/reference/fill-rule.quartz.argb32.ref.png
new file mode 100644
index 000000000..2ac534091
--- /dev/null
+++ b/test/reference/fill-rule.quartz.argb32.ref.png
Binary files differ
diff --git a/test/reference/fill-rule.quartz.rgb24.ref.png b/test/reference/fill-rule.quartz.rgb24.ref.png
new file mode 100644
index 000000000..bd671d62d
--- /dev/null
+++ b/test/reference/fill-rule.quartz.rgb24.ref.png
Binary files differ
diff --git a/test/reference/fill-rule.rgb24.ref.png b/test/reference/fill-rule.rgb24.ref.png
new file mode 100644
index 000000000..25023a28c
--- /dev/null
+++ b/test/reference/fill-rule.rgb24.ref.png
Binary files differ
diff --git a/test/reference/fill-rule.traps.argb32.ref.png b/test/reference/fill-rule.traps.argb32.ref.png
new file mode 100644
index 000000000..e2e10d4a8
--- /dev/null
+++ b/test/reference/fill-rule.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/fill-rule.traps.rgb24.ref.png b/test/reference/fill-rule.traps.rgb24.ref.png
new file mode 100644
index 000000000..49fb39c76
--- /dev/null
+++ b/test/reference/fill-rule.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/fill-xlib-fallback.rgb24.ref.png b/test/reference/fill-xlib-fallback.rgb24.ref.png
new file mode 100644
index 000000000..1e67073df
--- /dev/null
+++ b/test/reference/fill-xlib-fallback.rgb24.ref.png
Binary files differ
diff --git a/test/reference/fill-xlib-window.rgb24.ref.png b/test/reference/fill-xlib-window.rgb24.ref.png
new file mode 100644
index 000000000..1e67073df
--- /dev/null
+++ b/test/reference/fill-xlib-window.rgb24.ref.png
Binary files differ
diff --git a/test/reference/fill-xlib.ref.png b/test/reference/fill-xlib.ref.png
new file mode 100644
index 000000000..1e67073df
--- /dev/null
+++ b/test/reference/fill-xlib.ref.png
Binary files differ
diff --git a/test/reference/fill.image.argb32.ref.png b/test/reference/fill.image.argb32.ref.png
new file mode 100644
index 000000000..70c6bccc0
--- /dev/null
+++ b/test/reference/fill.image.argb32.ref.png
Binary files differ
diff --git a/test/reference/fill.image.rgb24.ref.png b/test/reference/fill.image.rgb24.ref.png
new file mode 100644
index 000000000..70c6bccc0
--- /dev/null
+++ b/test/reference/fill.image.rgb24.ref.png
Binary files differ
diff --git a/test/reference/filter-bilinear-extents.base.argb32.ref.png b/test/reference/filter-bilinear-extents.base.argb32.ref.png
new file mode 100644
index 000000000..797e7981f
--- /dev/null
+++ b/test/reference/filter-bilinear-extents.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/filter-bilinear-extents.base.rgb24.ref.png b/test/reference/filter-bilinear-extents.base.rgb24.ref.png
new file mode 100644
index 000000000..797e7981f
--- /dev/null
+++ b/test/reference/filter-bilinear-extents.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/filter-bilinear-extents.image16.ref.png b/test/reference/filter-bilinear-extents.image16.ref.png
new file mode 100644
index 000000000..5b7755bb3
--- /dev/null
+++ b/test/reference/filter-bilinear-extents.image16.ref.png
Binary files differ
diff --git a/test/reference/filter-bilinear-extents.pdf.xfail.png b/test/reference/filter-bilinear-extents.pdf.xfail.png
new file mode 100644
index 000000000..e6c4bb460
--- /dev/null
+++ b/test/reference/filter-bilinear-extents.pdf.xfail.png
Binary files differ
diff --git a/test/reference/filter-bilinear-extents.ps2.ref.png b/test/reference/filter-bilinear-extents.ps2.ref.png
new file mode 100644
index 000000000..97c105c9d
--- /dev/null
+++ b/test/reference/filter-bilinear-extents.ps2.ref.png
Binary files differ
diff --git a/test/reference/filter-bilinear-extents.ps3.ref.png b/test/reference/filter-bilinear-extents.ps3.ref.png
new file mode 100644
index 000000000..97c105c9d
--- /dev/null
+++ b/test/reference/filter-bilinear-extents.ps3.ref.png
Binary files differ
diff --git a/test/reference/filter-bilinear-extents.quartz.xfail.png b/test/reference/filter-bilinear-extents.quartz.xfail.png
new file mode 100644
index 000000000..312ee802d
--- /dev/null
+++ b/test/reference/filter-bilinear-extents.quartz.xfail.png
Binary files differ
diff --git a/test/reference/filter-bilinear-extents.ref.png b/test/reference/filter-bilinear-extents.ref.png
new file mode 100644
index 000000000..797e7981f
--- /dev/null
+++ b/test/reference/filter-bilinear-extents.ref.png
Binary files differ
diff --git a/test/reference/filter-nearest-offset.base.argb32.ref.png b/test/reference/filter-nearest-offset.base.argb32.ref.png
new file mode 100644
index 000000000..8cca9a1dc
--- /dev/null
+++ b/test/reference/filter-nearest-offset.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/filter-nearest-offset.base.rgb24.ref.png b/test/reference/filter-nearest-offset.base.rgb24.ref.png
new file mode 100644
index 000000000..8cca9a1dc
--- /dev/null
+++ b/test/reference/filter-nearest-offset.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/filter-nearest-offset.gl.xfail.png b/test/reference/filter-nearest-offset.gl.xfail.png
new file mode 100644
index 000000000..a777e7cc0
--- /dev/null
+++ b/test/reference/filter-nearest-offset.gl.xfail.png
Binary files differ
diff --git a/test/reference/filter-nearest-offset.pdf.xfail.png b/test/reference/filter-nearest-offset.pdf.xfail.png
new file mode 100644
index 000000000..3042821f4
--- /dev/null
+++ b/test/reference/filter-nearest-offset.pdf.xfail.png
Binary files differ
diff --git a/test/reference/filter-nearest-offset.ps2.ref.png b/test/reference/filter-nearest-offset.ps2.ref.png
new file mode 100644
index 000000000..185f77939
--- /dev/null
+++ b/test/reference/filter-nearest-offset.ps2.ref.png
Binary files differ
diff --git a/test/reference/filter-nearest-offset.ps3.ref.png b/test/reference/filter-nearest-offset.ps3.ref.png
new file mode 100644
index 000000000..185f77939
--- /dev/null
+++ b/test/reference/filter-nearest-offset.ps3.ref.png
Binary files differ
diff --git a/test/reference/filter-nearest-offset.ref.png b/test/reference/filter-nearest-offset.ref.png
new file mode 100644
index 000000000..af81aeea1
--- /dev/null
+++ b/test/reference/filter-nearest-offset.ref.png
Binary files differ
diff --git a/test/reference/filter-nearest-offset.svg.xfail.png b/test/reference/filter-nearest-offset.svg.xfail.png
new file mode 100644
index 000000000..a46dc76d5
--- /dev/null
+++ b/test/reference/filter-nearest-offset.svg.xfail.png
Binary files differ
diff --git a/test/reference/filter-nearest-transformed.base.argb32.ref.png b/test/reference/filter-nearest-transformed.base.argb32.ref.png
new file mode 100644
index 000000000..24adf8bc1
--- /dev/null
+++ b/test/reference/filter-nearest-transformed.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/filter-nearest-transformed.base.rgb24.ref.png b/test/reference/filter-nearest-transformed.base.rgb24.ref.png
new file mode 100644
index 000000000..24adf8bc1
--- /dev/null
+++ b/test/reference/filter-nearest-transformed.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/filter-nearest-transformed.gl.xfail.png b/test/reference/filter-nearest-transformed.gl.xfail.png
new file mode 100644
index 000000000..ba8170b0b
--- /dev/null
+++ b/test/reference/filter-nearest-transformed.gl.xfail.png
Binary files differ
diff --git a/test/reference/filter-nearest-transformed.image16.ref.png b/test/reference/filter-nearest-transformed.image16.ref.png
new file mode 100644
index 000000000..a02e1e11b
--- /dev/null
+++ b/test/reference/filter-nearest-transformed.image16.ref.png
Binary files differ
diff --git a/test/reference/filter-nearest-transformed.pdf.xfail.png b/test/reference/filter-nearest-transformed.pdf.xfail.png
new file mode 100644
index 000000000..e5b83784f
--- /dev/null
+++ b/test/reference/filter-nearest-transformed.pdf.xfail.png
Binary files differ
diff --git a/test/reference/filter-nearest-transformed.quartz.xfail.png b/test/reference/filter-nearest-transformed.quartz.xfail.png
new file mode 100644
index 000000000..246cdf421
--- /dev/null
+++ b/test/reference/filter-nearest-transformed.quartz.xfail.png
Binary files differ
diff --git a/test/reference/filter-nearest-transformed.ref.png b/test/reference/filter-nearest-transformed.ref.png
new file mode 100644
index 000000000..dc413b47e
--- /dev/null
+++ b/test/reference/filter-nearest-transformed.ref.png
Binary files differ
diff --git a/test/reference/filter-nearest-transformed.svg.xfail.png b/test/reference/filter-nearest-transformed.svg.xfail.png
new file mode 100644
index 000000000..e6bbe28e8
--- /dev/null
+++ b/test/reference/filter-nearest-transformed.svg.xfail.png
Binary files differ
diff --git a/test/reference/finer-grained-fallbacks.base.argb32.ref.png b/test/reference/finer-grained-fallbacks.base.argb32.ref.png
new file mode 100644
index 000000000..accb01be7
--- /dev/null
+++ b/test/reference/finer-grained-fallbacks.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/finer-grained-fallbacks.base.rgb24.ref.png b/test/reference/finer-grained-fallbacks.base.rgb24.ref.png
new file mode 100644
index 000000000..0e6094cd3
--- /dev/null
+++ b/test/reference/finer-grained-fallbacks.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/finer-grained-fallbacks.gl.argb32.ref.png b/test/reference/finer-grained-fallbacks.gl.argb32.ref.png
new file mode 100644
index 000000000..69ec48776
--- /dev/null
+++ b/test/reference/finer-grained-fallbacks.gl.argb32.ref.png
Binary files differ
diff --git a/test/reference/finer-grained-fallbacks.image16.ref.png b/test/reference/finer-grained-fallbacks.image16.ref.png
new file mode 100644
index 000000000..3b104ef8f
--- /dev/null
+++ b/test/reference/finer-grained-fallbacks.image16.ref.png
Binary files differ
diff --git a/test/reference/finer-grained-fallbacks.mask.argb32.ref.png b/test/reference/finer-grained-fallbacks.mask.argb32.ref.png
new file mode 100644
index 000000000..8cd99d0e4
--- /dev/null
+++ b/test/reference/finer-grained-fallbacks.mask.argb32.ref.png
Binary files differ
diff --git a/test/reference/finer-grained-fallbacks.mask.rgb24.ref.png b/test/reference/finer-grained-fallbacks.mask.rgb24.ref.png
new file mode 100644
index 000000000..5d6cd94f8
--- /dev/null
+++ b/test/reference/finer-grained-fallbacks.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/finer-grained-fallbacks.ps2.argb32.ref.png b/test/reference/finer-grained-fallbacks.ps2.argb32.ref.png
new file mode 100644
index 000000000..19c132f68
--- /dev/null
+++ b/test/reference/finer-grained-fallbacks.ps2.argb32.ref.png
Binary files differ
diff --git a/test/reference/finer-grained-fallbacks.ps2.ref.png b/test/reference/finer-grained-fallbacks.ps2.ref.png
new file mode 100644
index 000000000..1744100c9
--- /dev/null
+++ b/test/reference/finer-grained-fallbacks.ps2.ref.png
Binary files differ
diff --git a/test/reference/finer-grained-fallbacks.ps2.rgb24.ref.png b/test/reference/finer-grained-fallbacks.ps2.rgb24.ref.png
new file mode 100644
index 000000000..3f94a3a02
--- /dev/null
+++ b/test/reference/finer-grained-fallbacks.ps2.rgb24.ref.png
Binary files differ
diff --git a/test/reference/finer-grained-fallbacks.ps3.argb32.ref.png b/test/reference/finer-grained-fallbacks.ps3.argb32.ref.png
new file mode 100644
index 000000000..19c132f68
--- /dev/null
+++ b/test/reference/finer-grained-fallbacks.ps3.argb32.ref.png
Binary files differ
diff --git a/test/reference/finer-grained-fallbacks.ps3.ref.png b/test/reference/finer-grained-fallbacks.ps3.ref.png
new file mode 100644
index 000000000..1744100c9
--- /dev/null
+++ b/test/reference/finer-grained-fallbacks.ps3.ref.png
Binary files differ
diff --git a/test/reference/finer-grained-fallbacks.ps3.rgb24.ref.png b/test/reference/finer-grained-fallbacks.ps3.rgb24.ref.png
new file mode 100644
index 000000000..3f94a3a02
--- /dev/null
+++ b/test/reference/finer-grained-fallbacks.ps3.rgb24.ref.png
Binary files differ
diff --git a/test/reference/finer-grained-fallbacks.quartz.argb32.ref.png b/test/reference/finer-grained-fallbacks.quartz.argb32.ref.png
new file mode 100644
index 000000000..dc0576100
--- /dev/null
+++ b/test/reference/finer-grained-fallbacks.quartz.argb32.ref.png
Binary files differ
diff --git a/test/reference/finer-grained-fallbacks.quartz.rgb24.ref.png b/test/reference/finer-grained-fallbacks.quartz.rgb24.ref.png
new file mode 100644
index 000000000..1fdedd01f
--- /dev/null
+++ b/test/reference/finer-grained-fallbacks.quartz.rgb24.ref.png
Binary files differ
diff --git a/test/reference/finer-grained-fallbacks.ref.png b/test/reference/finer-grained-fallbacks.ref.png
new file mode 100644
index 000000000..cb18717f5
--- /dev/null
+++ b/test/reference/finer-grained-fallbacks.ref.png
Binary files differ
diff --git a/test/reference/finer-grained-fallbacks.svg12.argb32.ref.png b/test/reference/finer-grained-fallbacks.svg12.argb32.ref.png
new file mode 100644
index 000000000..5aaf86b27
--- /dev/null
+++ b/test/reference/finer-grained-fallbacks.svg12.argb32.ref.png
Binary files differ
diff --git a/test/reference/finer-grained-fallbacks.svg12.rgb24.ref.png b/test/reference/finer-grained-fallbacks.svg12.rgb24.ref.png
new file mode 100644
index 000000000..ad55366dd
--- /dev/null
+++ b/test/reference/finer-grained-fallbacks.svg12.rgb24.ref.png
Binary files differ
diff --git a/test/reference/finer-grained-fallbacks.traps.argb32.ref.png b/test/reference/finer-grained-fallbacks.traps.argb32.ref.png
new file mode 100644
index 000000000..accb01be7
--- /dev/null
+++ b/test/reference/finer-grained-fallbacks.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/finer-grained-fallbacks.traps.rgb24.ref.png b/test/reference/finer-grained-fallbacks.traps.rgb24.ref.png
new file mode 100644
index 000000000..0e6094cd3
--- /dev/null
+++ b/test/reference/finer-grained-fallbacks.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/finer-grained-fallbacks.xlib-fallback.ref.png b/test/reference/finer-grained-fallbacks.xlib-fallback.ref.png
new file mode 100644
index 000000000..c2af714cc
--- /dev/null
+++ b/test/reference/finer-grained-fallbacks.xlib-fallback.ref.png
Binary files differ
diff --git a/test/reference/font-matrix-translation.base.argb32.ref.png b/test/reference/font-matrix-translation.base.argb32.ref.png
new file mode 100644
index 000000000..a4a108206
--- /dev/null
+++ b/test/reference/font-matrix-translation.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/font-matrix-translation.base.rgb24.ref.png b/test/reference/font-matrix-translation.base.rgb24.ref.png
new file mode 100644
index 000000000..a4a108206
--- /dev/null
+++ b/test/reference/font-matrix-translation.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/font-matrix-translation.image16.ref.png b/test/reference/font-matrix-translation.image16.ref.png
new file mode 100644
index 000000000..f76b9ae80
--- /dev/null
+++ b/test/reference/font-matrix-translation.image16.ref.png
Binary files differ
diff --git a/test/reference/font-matrix-translation.ps2.argb32.ref.png b/test/reference/font-matrix-translation.ps2.argb32.ref.png
new file mode 100644
index 000000000..41d05a07d
--- /dev/null
+++ b/test/reference/font-matrix-translation.ps2.argb32.ref.png
Binary files differ
diff --git a/test/reference/font-matrix-translation.ps2.rgb24.ref.png b/test/reference/font-matrix-translation.ps2.rgb24.ref.png
new file mode 100644
index 000000000..41d05a07d
--- /dev/null
+++ b/test/reference/font-matrix-translation.ps2.rgb24.ref.png
Binary files differ
diff --git a/test/reference/font-matrix-translation.ps3.argb32.ref.png b/test/reference/font-matrix-translation.ps3.argb32.ref.png
new file mode 100644
index 000000000..41d05a07d
--- /dev/null
+++ b/test/reference/font-matrix-translation.ps3.argb32.ref.png
Binary files differ
diff --git a/test/reference/font-matrix-translation.ps3.rgb24.ref.png b/test/reference/font-matrix-translation.ps3.rgb24.ref.png
new file mode 100644
index 000000000..41d05a07d
--- /dev/null
+++ b/test/reference/font-matrix-translation.ps3.rgb24.ref.png
Binary files differ
diff --git a/test/reference/font-matrix-translation.quartz.ref.png b/test/reference/font-matrix-translation.quartz.ref.png
new file mode 100644
index 000000000..187e2c1aa
--- /dev/null
+++ b/test/reference/font-matrix-translation.quartz.ref.png
Binary files differ
diff --git a/test/reference/font-matrix-translation.ref.png b/test/reference/font-matrix-translation.ref.png
new file mode 100644
index 000000000..a4a108206
--- /dev/null
+++ b/test/reference/font-matrix-translation.ref.png
Binary files differ
diff --git a/test/reference/font-matrix-translation.svg.ref.png b/test/reference/font-matrix-translation.svg.ref.png
new file mode 100644
index 000000000..e35f9bea5
--- /dev/null
+++ b/test/reference/font-matrix-translation.svg.ref.png
Binary files differ
diff --git a/test/reference/font-matrix-translation.traps.ref.png b/test/reference/font-matrix-translation.traps.ref.png
new file mode 100644
index 000000000..a4a108206
--- /dev/null
+++ b/test/reference/font-matrix-translation.traps.ref.png
Binary files differ
diff --git a/test/reference/ft-show-glyphs-positioning.base.argb32.ref.png b/test/reference/ft-show-glyphs-positioning.base.argb32.ref.png
new file mode 100644
index 000000000..af6dcaf95
--- /dev/null
+++ b/test/reference/ft-show-glyphs-positioning.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/ft-show-glyphs-positioning.base.rgb24.ref.png b/test/reference/ft-show-glyphs-positioning.base.rgb24.ref.png
new file mode 100644
index 000000000..af6dcaf95
--- /dev/null
+++ b/test/reference/ft-show-glyphs-positioning.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/ft-show-glyphs-positioning.image16.ref.png b/test/reference/ft-show-glyphs-positioning.image16.ref.png
new file mode 100644
index 000000000..f3d9f0d1f
--- /dev/null
+++ b/test/reference/ft-show-glyphs-positioning.image16.ref.png
Binary files differ
diff --git a/test/reference/ft-show-glyphs-positioning.pdf.ref.png b/test/reference/ft-show-glyphs-positioning.pdf.ref.png
new file mode 100644
index 000000000..0d62fd378
--- /dev/null
+++ b/test/reference/ft-show-glyphs-positioning.pdf.ref.png
Binary files differ
diff --git a/test/reference/ft-show-glyphs-positioning.ps2.ref.png b/test/reference/ft-show-glyphs-positioning.ps2.ref.png
new file mode 100644
index 000000000..c5fbf30b5
--- /dev/null
+++ b/test/reference/ft-show-glyphs-positioning.ps2.ref.png
Binary files differ
diff --git a/test/reference/ft-show-glyphs-positioning.ps3.ref.png b/test/reference/ft-show-glyphs-positioning.ps3.ref.png
new file mode 100644
index 000000000..c5fbf30b5
--- /dev/null
+++ b/test/reference/ft-show-glyphs-positioning.ps3.ref.png
Binary files differ
diff --git a/test/reference/ft-show-glyphs-positioning.ref.png b/test/reference/ft-show-glyphs-positioning.ref.png
new file mode 100644
index 000000000..af6dcaf95
--- /dev/null
+++ b/test/reference/ft-show-glyphs-positioning.ref.png
Binary files differ
diff --git a/test/reference/ft-show-glyphs-positioning.svg.ref.png b/test/reference/ft-show-glyphs-positioning.svg.ref.png
new file mode 100644
index 000000000..04fe674d1
--- /dev/null
+++ b/test/reference/ft-show-glyphs-positioning.svg.ref.png
Binary files differ
diff --git a/test/reference/ft-show-glyphs-positioning.traps.ref.png b/test/reference/ft-show-glyphs-positioning.traps.ref.png
new file mode 100644
index 000000000..af6dcaf95
--- /dev/null
+++ b/test/reference/ft-show-glyphs-positioning.traps.ref.png
Binary files differ
diff --git a/test/reference/ft-show-glyphs-table.base.argb32.ref.png b/test/reference/ft-show-glyphs-table.base.argb32.ref.png
new file mode 100644
index 000000000..ed6912489
--- /dev/null
+++ b/test/reference/ft-show-glyphs-table.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/ft-show-glyphs-table.base.rgb24.ref.png b/test/reference/ft-show-glyphs-table.base.rgb24.ref.png
new file mode 100644
index 000000000..ed6912489
--- /dev/null
+++ b/test/reference/ft-show-glyphs-table.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/ft-show-glyphs-table.image16.ref.png b/test/reference/ft-show-glyphs-table.image16.ref.png
new file mode 100644
index 000000000..af01a49a0
--- /dev/null
+++ b/test/reference/ft-show-glyphs-table.image16.ref.png
Binary files differ
diff --git a/test/reference/ft-show-glyphs-table.ps2.ref.png b/test/reference/ft-show-glyphs-table.ps2.ref.png
new file mode 100644
index 000000000..5143663fc
--- /dev/null
+++ b/test/reference/ft-show-glyphs-table.ps2.ref.png
Binary files differ
diff --git a/test/reference/ft-show-glyphs-table.ps3.ref.png b/test/reference/ft-show-glyphs-table.ps3.ref.png
new file mode 100644
index 000000000..5143663fc
--- /dev/null
+++ b/test/reference/ft-show-glyphs-table.ps3.ref.png
Binary files differ
diff --git a/test/reference/ft-show-glyphs-table.quartz.xfail.png b/test/reference/ft-show-glyphs-table.quartz.xfail.png
new file mode 100644
index 000000000..0e131b26f
--- /dev/null
+++ b/test/reference/ft-show-glyphs-table.quartz.xfail.png
Binary files differ
diff --git a/test/reference/ft-show-glyphs-table.ref.png b/test/reference/ft-show-glyphs-table.ref.png
new file mode 100644
index 000000000..ed6912489
--- /dev/null
+++ b/test/reference/ft-show-glyphs-table.ref.png
Binary files differ
diff --git a/test/reference/ft-show-glyphs-table.svg.ref.png b/test/reference/ft-show-glyphs-table.svg.ref.png
new file mode 100644
index 000000000..e0654b7a0
--- /dev/null
+++ b/test/reference/ft-show-glyphs-table.svg.ref.png
Binary files differ
diff --git a/test/reference/ft-show-glyphs-table.traps.ref.png b/test/reference/ft-show-glyphs-table.traps.ref.png
new file mode 100644
index 000000000..ed6912489
--- /dev/null
+++ b/test/reference/ft-show-glyphs-table.traps.ref.png
Binary files differ
diff --git a/test/reference/ft-text-antialias-none.base.argb32.ref.png b/test/reference/ft-text-antialias-none.base.argb32.ref.png
new file mode 100644
index 000000000..c638c9ea6
--- /dev/null
+++ b/test/reference/ft-text-antialias-none.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/ft-text-antialias-none.base.rgb24.ref.png b/test/reference/ft-text-antialias-none.base.rgb24.ref.png
new file mode 100644
index 000000000..c638c9ea6
--- /dev/null
+++ b/test/reference/ft-text-antialias-none.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/ft-text-antialias-none.ps2.argb32.ref.png b/test/reference/ft-text-antialias-none.ps2.argb32.ref.png
new file mode 100644
index 000000000..4f7ee8324
--- /dev/null
+++ b/test/reference/ft-text-antialias-none.ps2.argb32.ref.png
Binary files differ
diff --git a/test/reference/ft-text-antialias-none.ps3.argb32.ref.png b/test/reference/ft-text-antialias-none.ps3.argb32.ref.png
new file mode 100644
index 000000000..4f7ee8324
--- /dev/null
+++ b/test/reference/ft-text-antialias-none.ps3.argb32.ref.png
Binary files differ
diff --git a/test/reference/ft-text-antialias-none.ref.png b/test/reference/ft-text-antialias-none.ref.png
new file mode 100644
index 000000000..cb0c13222
--- /dev/null
+++ b/test/reference/ft-text-antialias-none.ref.png
Binary files differ
diff --git a/test/reference/ft-text-vertical-layout-type1.base.argb32.ref.png b/test/reference/ft-text-vertical-layout-type1.base.argb32.ref.png
new file mode 100644
index 000000000..09c4cbbbe
--- /dev/null
+++ b/test/reference/ft-text-vertical-layout-type1.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/ft-text-vertical-layout-type1.base.rgb24.ref.png b/test/reference/ft-text-vertical-layout-type1.base.rgb24.ref.png
new file mode 100644
index 000000000..09c4cbbbe
--- /dev/null
+++ b/test/reference/ft-text-vertical-layout-type1.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/ft-text-vertical-layout-type1.image16.ref.png b/test/reference/ft-text-vertical-layout-type1.image16.ref.png
new file mode 100644
index 000000000..4985907c9
--- /dev/null
+++ b/test/reference/ft-text-vertical-layout-type1.image16.ref.png
Binary files differ
diff --git a/test/reference/ft-text-vertical-layout-type1.pdf.ref.png b/test/reference/ft-text-vertical-layout-type1.pdf.ref.png
new file mode 100644
index 000000000..1f52ff23b
--- /dev/null
+++ b/test/reference/ft-text-vertical-layout-type1.pdf.ref.png
Binary files differ
diff --git a/test/reference/ft-text-vertical-layout-type1.ps.ref.png b/test/reference/ft-text-vertical-layout-type1.ps.ref.png
new file mode 100644
index 000000000..bb99239b8
--- /dev/null
+++ b/test/reference/ft-text-vertical-layout-type1.ps.ref.png
Binary files differ
diff --git a/test/reference/ft-text-vertical-layout-type1.quartz.xfail.png b/test/reference/ft-text-vertical-layout-type1.quartz.xfail.png
new file mode 100644
index 000000000..a603b3597
--- /dev/null
+++ b/test/reference/ft-text-vertical-layout-type1.quartz.xfail.png
Binary files differ
diff --git a/test/reference/ft-text-vertical-layout-type1.ref.png b/test/reference/ft-text-vertical-layout-type1.ref.png
new file mode 100644
index 000000000..7a5670ee6
--- /dev/null
+++ b/test/reference/ft-text-vertical-layout-type1.ref.png
Binary files differ
diff --git a/test/reference/ft-text-vertical-layout-type1.svg.ref.png b/test/reference/ft-text-vertical-layout-type1.svg.ref.png
new file mode 100644
index 000000000..0be400c13
--- /dev/null
+++ b/test/reference/ft-text-vertical-layout-type1.svg.ref.png
Binary files differ
diff --git a/test/reference/ft-text-vertical-layout-type1.traps.argb32.ref.png b/test/reference/ft-text-vertical-layout-type1.traps.argb32.ref.png
new file mode 100644
index 000000000..09c4cbbbe
--- /dev/null
+++ b/test/reference/ft-text-vertical-layout-type1.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/ft-text-vertical-layout-type1.traps.rgb24.ref.png b/test/reference/ft-text-vertical-layout-type1.traps.rgb24.ref.png
new file mode 100644
index 000000000..09c4cbbbe
--- /dev/null
+++ b/test/reference/ft-text-vertical-layout-type1.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/ft-text-vertical-layout-type1.xfail.png b/test/reference/ft-text-vertical-layout-type1.xfail.png
new file mode 100644
index 000000000..063bbd967
--- /dev/null
+++ b/test/reference/ft-text-vertical-layout-type1.xfail.png
Binary files differ
diff --git a/test/reference/ft-text-vertical-layout-type3.base.argb32.ref.png b/test/reference/ft-text-vertical-layout-type3.base.argb32.ref.png
new file mode 100644
index 000000000..82374b70b
--- /dev/null
+++ b/test/reference/ft-text-vertical-layout-type3.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/ft-text-vertical-layout-type3.base.rgb24.ref.png b/test/reference/ft-text-vertical-layout-type3.base.rgb24.ref.png
new file mode 100644
index 000000000..82374b70b
--- /dev/null
+++ b/test/reference/ft-text-vertical-layout-type3.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/ft-text-vertical-layout-type3.image16.ref.png b/test/reference/ft-text-vertical-layout-type3.image16.ref.png
new file mode 100644
index 000000000..a5c3c1110
--- /dev/null
+++ b/test/reference/ft-text-vertical-layout-type3.image16.ref.png
Binary files differ
diff --git a/test/reference/ft-text-vertical-layout-type3.mask.argb32.ref.png b/test/reference/ft-text-vertical-layout-type3.mask.argb32.ref.png
new file mode 100644
index 000000000..7f7b428c1
--- /dev/null
+++ b/test/reference/ft-text-vertical-layout-type3.mask.argb32.ref.png
Binary files differ
diff --git a/test/reference/ft-text-vertical-layout-type3.mask.rgb24.ref.png b/test/reference/ft-text-vertical-layout-type3.mask.rgb24.ref.png
new file mode 100644
index 000000000..7f7b428c1
--- /dev/null
+++ b/test/reference/ft-text-vertical-layout-type3.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/ft-text-vertical-layout-type3.pdf.ref.png b/test/reference/ft-text-vertical-layout-type3.pdf.ref.png
new file mode 100644
index 000000000..a05ec1d74
--- /dev/null
+++ b/test/reference/ft-text-vertical-layout-type3.pdf.ref.png
Binary files differ
diff --git a/test/reference/ft-text-vertical-layout-type3.ps.ref.png b/test/reference/ft-text-vertical-layout-type3.ps.ref.png
new file mode 100644
index 000000000..f8aafa2d4
--- /dev/null
+++ b/test/reference/ft-text-vertical-layout-type3.ps.ref.png
Binary files differ
diff --git a/test/reference/ft-text-vertical-layout-type3.quartz.ref.png b/test/reference/ft-text-vertical-layout-type3.quartz.ref.png
new file mode 100644
index 000000000..4a063f3b5
--- /dev/null
+++ b/test/reference/ft-text-vertical-layout-type3.quartz.ref.png
Binary files differ
diff --git a/test/reference/ft-text-vertical-layout-type3.ref.png b/test/reference/ft-text-vertical-layout-type3.ref.png
new file mode 100644
index 000000000..5f64d8825
--- /dev/null
+++ b/test/reference/ft-text-vertical-layout-type3.ref.png
Binary files differ
diff --git a/test/reference/ft-text-vertical-layout-type3.svg.ref.png b/test/reference/ft-text-vertical-layout-type3.svg.ref.png
new file mode 100644
index 000000000..cddb955aa
--- /dev/null
+++ b/test/reference/ft-text-vertical-layout-type3.svg.ref.png
Binary files differ
diff --git a/test/reference/ft-text-vertical-layout-type3.traps.argb32.ref.png b/test/reference/ft-text-vertical-layout-type3.traps.argb32.ref.png
new file mode 100644
index 000000000..82374b70b
--- /dev/null
+++ b/test/reference/ft-text-vertical-layout-type3.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/ft-text-vertical-layout-type3.traps.rgb24.ref.png b/test/reference/ft-text-vertical-layout-type3.traps.rgb24.ref.png
new file mode 100644
index 000000000..82374b70b
--- /dev/null
+++ b/test/reference/ft-text-vertical-layout-type3.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/get-group-target.base.argb32.ref.png b/test/reference/get-group-target.base.argb32.ref.png
new file mode 100644
index 000000000..d162775e7
--- /dev/null
+++ b/test/reference/get-group-target.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/get-group-target.base.rgb24.ref.png b/test/reference/get-group-target.base.rgb24.ref.png
new file mode 100644
index 000000000..d162775e7
--- /dev/null
+++ b/test/reference/get-group-target.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/get-group-target.ref.png b/test/reference/get-group-target.ref.png
new file mode 100644
index 000000000..316a93f31
--- /dev/null
+++ b/test/reference/get-group-target.ref.png
Binary files differ
diff --git a/test/reference/gl-surface-source.base.argb32.ref.png b/test/reference/gl-surface-source.base.argb32.ref.png
new file mode 100644
index 000000000..018297208
--- /dev/null
+++ b/test/reference/gl-surface-source.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/gl-surface-source.base.rgb24.ref.png b/test/reference/gl-surface-source.base.rgb24.ref.png
new file mode 100644
index 000000000..0d68a82cc
--- /dev/null
+++ b/test/reference/gl-surface-source.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/gl-surface-source.image16.ref.png b/test/reference/gl-surface-source.image16.ref.png
new file mode 100644
index 000000000..2a7460e28
--- /dev/null
+++ b/test/reference/gl-surface-source.image16.ref.png
Binary files differ
diff --git a/test/reference/gl-surface-source.ref.png b/test/reference/gl-surface-source.ref.png
new file mode 100644
index 000000000..018297208
--- /dev/null
+++ b/test/reference/gl-surface-source.ref.png
Binary files differ
diff --git a/test/reference/glyph-cache-pressure.base.argb32.ref.png b/test/reference/glyph-cache-pressure.base.argb32.ref.png
new file mode 100644
index 000000000..a6e1b061f
--- /dev/null
+++ b/test/reference/glyph-cache-pressure.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/glyph-cache-pressure.base.rgb24.ref.png b/test/reference/glyph-cache-pressure.base.rgb24.ref.png
new file mode 100644
index 000000000..a6e1b061f
--- /dev/null
+++ b/test/reference/glyph-cache-pressure.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/glyph-cache-pressure.image16.ref.png b/test/reference/glyph-cache-pressure.image16.ref.png
new file mode 100644
index 000000000..f3985bdf0
--- /dev/null
+++ b/test/reference/glyph-cache-pressure.image16.ref.png
Binary files differ
diff --git a/test/reference/glyph-cache-pressure.ps2.ref.png b/test/reference/glyph-cache-pressure.ps2.ref.png
new file mode 100644
index 000000000..88fa4478b
--- /dev/null
+++ b/test/reference/glyph-cache-pressure.ps2.ref.png
Binary files differ
diff --git a/test/reference/glyph-cache-pressure.ps3.ref.png b/test/reference/glyph-cache-pressure.ps3.ref.png
new file mode 100644
index 000000000..88fa4478b
--- /dev/null
+++ b/test/reference/glyph-cache-pressure.ps3.ref.png
Binary files differ
diff --git a/test/reference/glyph-cache-pressure.quartz.ref.png b/test/reference/glyph-cache-pressure.quartz.ref.png
new file mode 100644
index 000000000..6291e84b4
--- /dev/null
+++ b/test/reference/glyph-cache-pressure.quartz.ref.png
Binary files differ
diff --git a/test/reference/glyph-cache-pressure.ref.png b/test/reference/glyph-cache-pressure.ref.png
new file mode 100644
index 000000000..a6e1b061f
--- /dev/null
+++ b/test/reference/glyph-cache-pressure.ref.png
Binary files differ
diff --git a/test/reference/glyph-cache-pressure.traps.ref.png b/test/reference/glyph-cache-pressure.traps.ref.png
new file mode 100644
index 000000000..a6e1b061f
--- /dev/null
+++ b/test/reference/glyph-cache-pressure.traps.ref.png
Binary files differ
diff --git a/test/reference/gradient-alpha.base.argb32.ref.png b/test/reference/gradient-alpha.base.argb32.ref.png
new file mode 100644
index 000000000..f64b26a76
--- /dev/null
+++ b/test/reference/gradient-alpha.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/gradient-alpha.base.rgb24.ref.png b/test/reference/gradient-alpha.base.rgb24.ref.png
new file mode 100644
index 000000000..3c7258d95
--- /dev/null
+++ b/test/reference/gradient-alpha.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/gradient-alpha.ps2.argb32.ref.png b/test/reference/gradient-alpha.ps2.argb32.ref.png
new file mode 100644
index 000000000..37eafba3c
--- /dev/null
+++ b/test/reference/gradient-alpha.ps2.argb32.ref.png
Binary files differ
diff --git a/test/reference/gradient-alpha.ps2.rgb24.ref.png b/test/reference/gradient-alpha.ps2.rgb24.ref.png
new file mode 100644
index 000000000..2432c2996
--- /dev/null
+++ b/test/reference/gradient-alpha.ps2.rgb24.ref.png
Binary files differ
diff --git a/test/reference/gradient-alpha.ps3.argb32.ref.png b/test/reference/gradient-alpha.ps3.argb32.ref.png
new file mode 100644
index 000000000..37eafba3c
--- /dev/null
+++ b/test/reference/gradient-alpha.ps3.argb32.ref.png
Binary files differ
diff --git a/test/reference/gradient-alpha.ps3.rgb24.ref.png b/test/reference/gradient-alpha.ps3.rgb24.ref.png
new file mode 100644
index 000000000..2432c2996
--- /dev/null
+++ b/test/reference/gradient-alpha.ps3.rgb24.ref.png
Binary files differ
diff --git a/test/reference/gradient-alpha.ref.png b/test/reference/gradient-alpha.ref.png
new file mode 100644
index 000000000..f64b26a76
--- /dev/null
+++ b/test/reference/gradient-alpha.ref.png
Binary files differ
diff --git a/test/reference/gradient-constant-alpha.base.argb32.ref.png b/test/reference/gradient-constant-alpha.base.argb32.ref.png
new file mode 100644
index 000000000..7f49e2c6f
--- /dev/null
+++ b/test/reference/gradient-constant-alpha.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/gradient-constant-alpha.base.rgb24.ref.png b/test/reference/gradient-constant-alpha.base.rgb24.ref.png
new file mode 100644
index 000000000..69cd5963a
--- /dev/null
+++ b/test/reference/gradient-constant-alpha.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/gradient-constant-alpha.ps3.ref.png b/test/reference/gradient-constant-alpha.ps3.ref.png
new file mode 100644
index 000000000..7089f4fdc
--- /dev/null
+++ b/test/reference/gradient-constant-alpha.ps3.ref.png
Binary files differ
diff --git a/test/reference/gradient-constant-alpha.ps3.rgb24.ref.png b/test/reference/gradient-constant-alpha.ps3.rgb24.ref.png
new file mode 100644
index 000000000..5962925f2
--- /dev/null
+++ b/test/reference/gradient-constant-alpha.ps3.rgb24.ref.png
Binary files differ
diff --git a/test/reference/gradient-constant-alpha.quartz.argb32.ref.png b/test/reference/gradient-constant-alpha.quartz.argb32.ref.png
new file mode 100644
index 000000000..a426f5ad0
--- /dev/null
+++ b/test/reference/gradient-constant-alpha.quartz.argb32.ref.png
Binary files differ
diff --git a/test/reference/gradient-constant-alpha.ref.png b/test/reference/gradient-constant-alpha.ref.png
new file mode 100644
index 000000000..7f49e2c6f
--- /dev/null
+++ b/test/reference/gradient-constant-alpha.ref.png
Binary files differ
diff --git a/test/reference/gradient-zero-stops-mask.base.argb32.ref.png b/test/reference/gradient-zero-stops-mask.base.argb32.ref.png
new file mode 100644
index 000000000..0a50f4cac
--- /dev/null
+++ b/test/reference/gradient-zero-stops-mask.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/gradient-zero-stops-mask.base.rgb24.ref.png b/test/reference/gradient-zero-stops-mask.base.rgb24.ref.png
new file mode 100644
index 000000000..21465ce4a
--- /dev/null
+++ b/test/reference/gradient-zero-stops-mask.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/gradient-zero-stops-mask.ref.png b/test/reference/gradient-zero-stops-mask.ref.png
new file mode 100644
index 000000000..0a50f4cac
--- /dev/null
+++ b/test/reference/gradient-zero-stops-mask.ref.png
Binary files differ
diff --git a/test/reference/gradient-zero-stops.base.argb32.ref.png b/test/reference/gradient-zero-stops.base.argb32.ref.png
new file mode 100644
index 000000000..0a50f4cac
--- /dev/null
+++ b/test/reference/gradient-zero-stops.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/gradient-zero-stops.base.rgb24.ref.png b/test/reference/gradient-zero-stops.base.rgb24.ref.png
new file mode 100644
index 000000000..21465ce4a
--- /dev/null
+++ b/test/reference/gradient-zero-stops.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/gradient-zero-stops.ref.png b/test/reference/gradient-zero-stops.ref.png
new file mode 100644
index 000000000..3f1867037
--- /dev/null
+++ b/test/reference/gradient-zero-stops.ref.png
Binary files differ
diff --git a/test/reference/group-clip.base.argb32.ref.png b/test/reference/group-clip.base.argb32.ref.png
new file mode 100644
index 000000000..7b8a7532f
--- /dev/null
+++ b/test/reference/group-clip.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/group-clip.base.rgb24.ref.png b/test/reference/group-clip.base.rgb24.ref.png
new file mode 100644
index 000000000..7b8a7532f
--- /dev/null
+++ b/test/reference/group-clip.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/group-clip.image16.ref.png b/test/reference/group-clip.image16.ref.png
new file mode 100644
index 000000000..98b66efa3
--- /dev/null
+++ b/test/reference/group-clip.image16.ref.png
Binary files differ
diff --git a/test/reference/group-clip.ref.png b/test/reference/group-clip.ref.png
new file mode 100644
index 000000000..7b8a7532f
--- /dev/null
+++ b/test/reference/group-clip.ref.png
Binary files differ
diff --git a/test/reference/group-paint.base.argb32.ref.png b/test/reference/group-paint.base.argb32.ref.png
new file mode 100644
index 000000000..1ed070cae
--- /dev/null
+++ b/test/reference/group-paint.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/group-paint.base.rgb24.ref.png b/test/reference/group-paint.base.rgb24.ref.png
new file mode 100644
index 000000000..1ed070cae
--- /dev/null
+++ b/test/reference/group-paint.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/group-paint.ref.png b/test/reference/group-paint.ref.png
new file mode 100644
index 000000000..f2e111b88
--- /dev/null
+++ b/test/reference/group-paint.ref.png
Binary files differ
diff --git a/test/reference/group-unaligned.base.argb32.ref.png b/test/reference/group-unaligned.base.argb32.ref.png
new file mode 100644
index 000000000..451e1713f
--- /dev/null
+++ b/test/reference/group-unaligned.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/group-unaligned.base.rgb24.ref.png b/test/reference/group-unaligned.base.rgb24.ref.png
new file mode 100644
index 000000000..451e1713f
--- /dev/null
+++ b/test/reference/group-unaligned.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/group-unaligned.image16.ref.png b/test/reference/group-unaligned.image16.ref.png
new file mode 100644
index 000000000..6a60a6ea4
--- /dev/null
+++ b/test/reference/group-unaligned.image16.ref.png
Binary files differ
diff --git a/test/reference/group-unaligned.ps.ref.png b/test/reference/group-unaligned.ps.ref.png
new file mode 100644
index 000000000..f10899879
--- /dev/null
+++ b/test/reference/group-unaligned.ps.ref.png
Binary files differ
diff --git a/test/reference/group-unaligned.ps.rgb24.xfail.png b/test/reference/group-unaligned.ps.rgb24.xfail.png
new file mode 100644
index 000000000..5672cb0bf
--- /dev/null
+++ b/test/reference/group-unaligned.ps.rgb24.xfail.png
Binary files differ
diff --git a/test/reference/group-unaligned.quartz.ref.png b/test/reference/group-unaligned.quartz.ref.png
new file mode 100644
index 000000000..1711025e9
--- /dev/null
+++ b/test/reference/group-unaligned.quartz.ref.png
Binary files differ
diff --git a/test/reference/group-unaligned.ref.png b/test/reference/group-unaligned.ref.png
new file mode 100644
index 000000000..6356e6c14
--- /dev/null
+++ b/test/reference/group-unaligned.ref.png
Binary files differ
diff --git a/test/reference/group-unaligned.svg.argb32.xfail.png b/test/reference/group-unaligned.svg.argb32.xfail.png
new file mode 100644
index 000000000..01c34bec4
--- /dev/null
+++ b/test/reference/group-unaligned.svg.argb32.xfail.png
Binary files differ
diff --git a/test/reference/group-unaligned.svg.rgb24.xfail.png b/test/reference/group-unaligned.svg.rgb24.xfail.png
new file mode 100644
index 000000000..c0f18619b
--- /dev/null
+++ b/test/reference/group-unaligned.svg.rgb24.xfail.png
Binary files differ
diff --git a/test/reference/group-unaligned.traps.argb32.ref.png b/test/reference/group-unaligned.traps.argb32.ref.png
new file mode 100644
index 000000000..451e1713f
--- /dev/null
+++ b/test/reference/group-unaligned.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/group-unaligned.traps.rgb24.ref.png b/test/reference/group-unaligned.traps.rgb24.ref.png
new file mode 100644
index 000000000..451e1713f
--- /dev/null
+++ b/test/reference/group-unaligned.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/group-unaligned.xlib-fallback.ref.png b/test/reference/group-unaligned.xlib-fallback.ref.png
new file mode 100644
index 000000000..5ddbc164f
--- /dev/null
+++ b/test/reference/group-unaligned.xlib-fallback.ref.png
Binary files differ
diff --git a/test/reference/halo-transform.base.argb32.ref.png b/test/reference/halo-transform.base.argb32.ref.png
new file mode 100644
index 000000000..45cb90ff0
--- /dev/null
+++ b/test/reference/halo-transform.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/halo-transform.base.rgb24.ref.png b/test/reference/halo-transform.base.rgb24.ref.png
new file mode 100644
index 000000000..45cb90ff0
--- /dev/null
+++ b/test/reference/halo-transform.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/halo-transform.image16.ref.png b/test/reference/halo-transform.image16.ref.png
new file mode 100644
index 000000000..b2268f01f
--- /dev/null
+++ b/test/reference/halo-transform.image16.ref.png
Binary files differ
diff --git a/test/reference/halo-transform.ps.ref.png b/test/reference/halo-transform.ps.ref.png
new file mode 100644
index 000000000..89e1f7629
--- /dev/null
+++ b/test/reference/halo-transform.ps.ref.png
Binary files differ
diff --git a/test/reference/halo-transform.quartz.ref.png b/test/reference/halo-transform.quartz.ref.png
new file mode 100644
index 000000000..91a99baaf
--- /dev/null
+++ b/test/reference/halo-transform.quartz.ref.png
Binary files differ
diff --git a/test/reference/halo-transform.ref.png b/test/reference/halo-transform.ref.png
new file mode 100644
index 000000000..f549c0dc2
--- /dev/null
+++ b/test/reference/halo-transform.ref.png
Binary files differ
diff --git a/test/reference/halo-transform.traps.ref.png b/test/reference/halo-transform.traps.ref.png
new file mode 100644
index 000000000..45cb90ff0
--- /dev/null
+++ b/test/reference/halo-transform.traps.ref.png
Binary files differ
diff --git a/test/reference/halo.base.argb32.ref.png b/test/reference/halo.base.argb32.ref.png
new file mode 100644
index 000000000..c915a242b
--- /dev/null
+++ b/test/reference/halo.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/halo.base.rgb24.ref.png b/test/reference/halo.base.rgb24.ref.png
new file mode 100644
index 000000000..c915a242b
--- /dev/null
+++ b/test/reference/halo.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/halo.image16.ref.png b/test/reference/halo.image16.ref.png
new file mode 100644
index 000000000..a813cd921
--- /dev/null
+++ b/test/reference/halo.image16.ref.png
Binary files differ
diff --git a/test/reference/halo.mask.argb32.ref.png b/test/reference/halo.mask.argb32.ref.png
new file mode 100644
index 000000000..191ee4794
--- /dev/null
+++ b/test/reference/halo.mask.argb32.ref.png
Binary files differ
diff --git a/test/reference/halo.mask.rgb24.ref.png b/test/reference/halo.mask.rgb24.ref.png
new file mode 100644
index 000000000..191ee4794
--- /dev/null
+++ b/test/reference/halo.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/halo.ps.ref.png b/test/reference/halo.ps.ref.png
new file mode 100644
index 000000000..1426d2e0c
--- /dev/null
+++ b/test/reference/halo.ps.ref.png
Binary files differ
diff --git a/test/reference/halo.quartz.ref.png b/test/reference/halo.quartz.ref.png
new file mode 100644
index 000000000..c5cf999c9
--- /dev/null
+++ b/test/reference/halo.quartz.ref.png
Binary files differ
diff --git a/test/reference/halo.ref.png b/test/reference/halo.ref.png
new file mode 100644
index 000000000..dc1316d5b
--- /dev/null
+++ b/test/reference/halo.ref.png
Binary files differ
diff --git a/test/reference/halo.traps.ref.png b/test/reference/halo.traps.ref.png
new file mode 100644
index 000000000..c915a242b
--- /dev/null
+++ b/test/reference/halo.traps.ref.png
Binary files differ
diff --git a/test/reference/hatchings.base.argb32.ref.png b/test/reference/hatchings.base.argb32.ref.png
new file mode 100644
index 000000000..73e156dd3
--- /dev/null
+++ b/test/reference/hatchings.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/hatchings.base.rgb24.ref.png b/test/reference/hatchings.base.rgb24.ref.png
new file mode 100644
index 000000000..73e156dd3
--- /dev/null
+++ b/test/reference/hatchings.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/hatchings.mask.argb32.ref.png b/test/reference/hatchings.mask.argb32.ref.png
new file mode 100644
index 000000000..77fe853a8
--- /dev/null
+++ b/test/reference/hatchings.mask.argb32.ref.png
Binary files differ
diff --git a/test/reference/hatchings.mask.rgb24.ref.png b/test/reference/hatchings.mask.rgb24.ref.png
new file mode 100644
index 000000000..77fe853a8
--- /dev/null
+++ b/test/reference/hatchings.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/hatchings.ref.png b/test/reference/hatchings.ref.png
new file mode 100644
index 000000000..215d61fa8
--- /dev/null
+++ b/test/reference/hatchings.ref.png
Binary files differ
diff --git a/test/reference/hatchings.traps.argb32.ref.png b/test/reference/hatchings.traps.argb32.ref.png
new file mode 100644
index 000000000..3b72949c1
--- /dev/null
+++ b/test/reference/hatchings.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/hatchings.traps.rgb24.ref.png b/test/reference/hatchings.traps.rgb24.ref.png
new file mode 100644
index 000000000..3b72949c1
--- /dev/null
+++ b/test/reference/hatchings.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/horizontal-clip.base.argb32.ref.png b/test/reference/horizontal-clip.base.argb32.ref.png
new file mode 100644
index 000000000..43dd07f15
--- /dev/null
+++ b/test/reference/horizontal-clip.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/horizontal-clip.base.rgb24.ref.png b/test/reference/horizontal-clip.base.rgb24.ref.png
new file mode 100644
index 000000000..43dd07f15
--- /dev/null
+++ b/test/reference/horizontal-clip.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/horizontal-clip.ref.png b/test/reference/horizontal-clip.ref.png
new file mode 100644
index 000000000..43dd07f15
--- /dev/null
+++ b/test/reference/horizontal-clip.ref.png
Binary files differ
diff --git a/test/reference/huge-linear.base.argb32.ref.png b/test/reference/huge-linear.base.argb32.ref.png
new file mode 100644
index 000000000..f89217b82
--- /dev/null
+++ b/test/reference/huge-linear.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/huge-linear.base.rgb24.ref.png b/test/reference/huge-linear.base.rgb24.ref.png
new file mode 100644
index 000000000..f89217b82
--- /dev/null
+++ b/test/reference/huge-linear.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/huge-linear.image16.ref.png b/test/reference/huge-linear.image16.ref.png
new file mode 100644
index 000000000..56dc58aca
--- /dev/null
+++ b/test/reference/huge-linear.image16.ref.png
Binary files differ
diff --git a/test/reference/huge-linear.pdf.ref.png b/test/reference/huge-linear.pdf.ref.png
new file mode 100644
index 000000000..8313470cc
--- /dev/null
+++ b/test/reference/huge-linear.pdf.ref.png
Binary files differ
diff --git a/test/reference/huge-linear.ps3.ref.png b/test/reference/huge-linear.ps3.ref.png
new file mode 100644
index 000000000..d55239bf4
--- /dev/null
+++ b/test/reference/huge-linear.ps3.ref.png
Binary files differ
diff --git a/test/reference/huge-linear.quartz.ref.png b/test/reference/huge-linear.quartz.ref.png
new file mode 100644
index 000000000..3d12f7bea
--- /dev/null
+++ b/test/reference/huge-linear.quartz.ref.png
Binary files differ
diff --git a/test/reference/huge-linear.ref.png b/test/reference/huge-linear.ref.png
new file mode 100644
index 000000000..c20a8b7de
--- /dev/null
+++ b/test/reference/huge-linear.ref.png
Binary files differ
diff --git a/test/reference/huge-radial.base.argb32.ref.png b/test/reference/huge-radial.base.argb32.ref.png
new file mode 100644
index 000000000..541bb309a
--- /dev/null
+++ b/test/reference/huge-radial.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/huge-radial.base.rgb24.ref.png b/test/reference/huge-radial.base.rgb24.ref.png
new file mode 100644
index 000000000..541bb309a
--- /dev/null
+++ b/test/reference/huge-radial.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/huge-radial.image16.ref.png b/test/reference/huge-radial.image16.ref.png
new file mode 100644
index 000000000..3913190fe
--- /dev/null
+++ b/test/reference/huge-radial.image16.ref.png
Binary files differ
diff --git a/test/reference/huge-radial.ps3.ref.png b/test/reference/huge-radial.ps3.ref.png
new file mode 100644
index 000000000..c2319487b
--- /dev/null
+++ b/test/reference/huge-radial.ps3.ref.png
Binary files differ
diff --git a/test/reference/huge-radial.quartz.ref.png b/test/reference/huge-radial.quartz.ref.png
new file mode 100644
index 000000000..d823f8651
--- /dev/null
+++ b/test/reference/huge-radial.quartz.ref.png
Binary files differ
diff --git a/test/reference/huge-radial.ref.png b/test/reference/huge-radial.ref.png
new file mode 100644
index 000000000..541bb309a
--- /dev/null
+++ b/test/reference/huge-radial.ref.png
Binary files differ
diff --git a/test/reference/image-bug-710072-aligned.base.argb32.ref.png b/test/reference/image-bug-710072-aligned.base.argb32.ref.png
new file mode 100644
index 000000000..42abd2054
--- /dev/null
+++ b/test/reference/image-bug-710072-aligned.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/image-bug-710072-aligned.base.rgb24.ref.png b/test/reference/image-bug-710072-aligned.base.rgb24.ref.png
new file mode 100644
index 000000000..42abd2054
--- /dev/null
+++ b/test/reference/image-bug-710072-aligned.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/image-bug-710072-aligned.ref.png b/test/reference/image-bug-710072-aligned.ref.png
new file mode 100644
index 000000000..42abd2054
--- /dev/null
+++ b/test/reference/image-bug-710072-aligned.ref.png
Binary files differ
diff --git a/test/reference/image-bug-710072-unaligned.base.argb32.ref.png b/test/reference/image-bug-710072-unaligned.base.argb32.ref.png
new file mode 100644
index 000000000..0a5a6e6cf
--- /dev/null
+++ b/test/reference/image-bug-710072-unaligned.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/image-bug-710072-unaligned.base.rgb24.ref.png b/test/reference/image-bug-710072-unaligned.base.rgb24.ref.png
new file mode 100644
index 000000000..0a5a6e6cf
--- /dev/null
+++ b/test/reference/image-bug-710072-unaligned.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/image-bug-710072-unaligned.ref.png b/test/reference/image-bug-710072-unaligned.ref.png
new file mode 100644
index 000000000..13efa30f8
--- /dev/null
+++ b/test/reference/image-bug-710072-unaligned.ref.png
Binary files differ
diff --git a/test/reference/image-bug-710072-unaligned.traps.argb32.ref.png b/test/reference/image-bug-710072-unaligned.traps.argb32.ref.png
new file mode 100644
index 000000000..0a5a6e6cf
--- /dev/null
+++ b/test/reference/image-bug-710072-unaligned.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/image-bug-710072-unaligned.traps.rgb24.ref.png b/test/reference/image-bug-710072-unaligned.traps.rgb24.ref.png
new file mode 100644
index 000000000..0a5a6e6cf
--- /dev/null
+++ b/test/reference/image-bug-710072-unaligned.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/image-bug-710072-unaligned.xlib-fallback.rgb24.ref.png b/test/reference/image-bug-710072-unaligned.xlib-fallback.rgb24.ref.png
new file mode 100644
index 000000000..0a5a6e6cf
--- /dev/null
+++ b/test/reference/image-bug-710072-unaligned.xlib-fallback.rgb24.ref.png
Binary files differ
diff --git a/test/reference/image-bug-710072-unaligned.xlib-window.rgb24.ref.png b/test/reference/image-bug-710072-unaligned.xlib-window.rgb24.ref.png
new file mode 100644
index 000000000..0a5a6e6cf
--- /dev/null
+++ b/test/reference/image-bug-710072-unaligned.xlib-window.rgb24.ref.png
Binary files differ
diff --git a/test/reference/image-surface-source.base.argb32.ref.png b/test/reference/image-surface-source.base.argb32.ref.png
new file mode 100644
index 000000000..018297208
--- /dev/null
+++ b/test/reference/image-surface-source.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/image-surface-source.base.rgb24.ref.png b/test/reference/image-surface-source.base.rgb24.ref.png
new file mode 100644
index 000000000..0d68a82cc
--- /dev/null
+++ b/test/reference/image-surface-source.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/image-surface-source.image16.ref.png b/test/reference/image-surface-source.image16.ref.png
new file mode 100644
index 000000000..2a7460e28
--- /dev/null
+++ b/test/reference/image-surface-source.image16.ref.png
Binary files differ
diff --git a/test/reference/image-surface-source.ps2.ref.png b/test/reference/image-surface-source.ps2.ref.png
new file mode 100644
index 000000000..10231581b
--- /dev/null
+++ b/test/reference/image-surface-source.ps2.ref.png
Binary files differ
diff --git a/test/reference/image-surface-source.ps3.ref.png b/test/reference/image-surface-source.ps3.ref.png
new file mode 100644
index 000000000..10231581b
--- /dev/null
+++ b/test/reference/image-surface-source.ps3.ref.png
Binary files differ
diff --git a/test/reference/image-surface-source.ref.png b/test/reference/image-surface-source.ref.png
new file mode 100644
index 000000000..018297208
--- /dev/null
+++ b/test/reference/image-surface-source.ref.png
Binary files differ
diff --git a/test/reference/image-surface-source.svg12.argb32.xfail.png b/test/reference/image-surface-source.svg12.argb32.xfail.png
new file mode 100644
index 000000000..6ebcaf9a1
--- /dev/null
+++ b/test/reference/image-surface-source.svg12.argb32.xfail.png
Binary files differ
diff --git a/test/reference/image-surface-source.svg12.rgb24.xfail.png b/test/reference/image-surface-source.svg12.rgb24.xfail.png
new file mode 100644
index 000000000..6ebcaf9a1
--- /dev/null
+++ b/test/reference/image-surface-source.svg12.rgb24.xfail.png
Binary files differ
diff --git a/test/reference/implicit-close.base.argb32.ref.png b/test/reference/implicit-close.base.argb32.ref.png
new file mode 100644
index 000000000..fdd756110
--- /dev/null
+++ b/test/reference/implicit-close.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/implicit-close.base.rgb24.ref.png b/test/reference/implicit-close.base.rgb24.ref.png
new file mode 100644
index 000000000..fdd756110
--- /dev/null
+++ b/test/reference/implicit-close.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/implicit-close.ps.ref.png b/test/reference/implicit-close.ps.ref.png
new file mode 100644
index 000000000..66baf2480
--- /dev/null
+++ b/test/reference/implicit-close.ps.ref.png
Binary files differ
diff --git a/test/reference/implicit-close.ref.png b/test/reference/implicit-close.ref.png
new file mode 100644
index 000000000..f15f8a3a0
--- /dev/null
+++ b/test/reference/implicit-close.ref.png
Binary files differ
diff --git a/test/reference/implicit-close.traps.argb32.ref.png b/test/reference/implicit-close.traps.argb32.ref.png
new file mode 100644
index 000000000..fdd756110
--- /dev/null
+++ b/test/reference/implicit-close.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/implicit-close.traps.rgb24.ref.png b/test/reference/implicit-close.traps.rgb24.ref.png
new file mode 100644
index 000000000..fdd756110
--- /dev/null
+++ b/test/reference/implicit-close.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/infinite-join.base.argb32.ref.png b/test/reference/infinite-join.base.argb32.ref.png
new file mode 100644
index 000000000..9e7572b93
--- /dev/null
+++ b/test/reference/infinite-join.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/infinite-join.base.rgb24.ref.png b/test/reference/infinite-join.base.rgb24.ref.png
new file mode 100644
index 000000000..9e7572b93
--- /dev/null
+++ b/test/reference/infinite-join.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/infinite-join.ps2.ref.png b/test/reference/infinite-join.ps2.ref.png
new file mode 100644
index 000000000..6fba8f4b1
--- /dev/null
+++ b/test/reference/infinite-join.ps2.ref.png
Binary files differ
diff --git a/test/reference/infinite-join.ps3.ref.png b/test/reference/infinite-join.ps3.ref.png
new file mode 100644
index 000000000..6fba8f4b1
--- /dev/null
+++ b/test/reference/infinite-join.ps3.ref.png
Binary files differ
diff --git a/test/reference/infinite-join.ref.png b/test/reference/infinite-join.ref.png
new file mode 100644
index 000000000..54a911241
--- /dev/null
+++ b/test/reference/infinite-join.ref.png
Binary files differ
diff --git a/test/reference/infinite-join.traps.argb32.ref.png b/test/reference/infinite-join.traps.argb32.ref.png
new file mode 100644
index 000000000..9e7572b93
--- /dev/null
+++ b/test/reference/infinite-join.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/infinite-join.traps.rgb24.ref.png b/test/reference/infinite-join.traps.rgb24.ref.png
new file mode 100644
index 000000000..9e7572b93
--- /dev/null
+++ b/test/reference/infinite-join.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/inverse-text.base.argb32.ref.png b/test/reference/inverse-text.base.argb32.ref.png
new file mode 100644
index 000000000..b7bbb972f
--- /dev/null
+++ b/test/reference/inverse-text.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/inverse-text.base.rgb24.ref.png b/test/reference/inverse-text.base.rgb24.ref.png
new file mode 100644
index 000000000..b7bbb972f
--- /dev/null
+++ b/test/reference/inverse-text.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/inverse-text.mask.argb32.ref.png b/test/reference/inverse-text.mask.argb32.ref.png
new file mode 100644
index 000000000..b7bbb972f
--- /dev/null
+++ b/test/reference/inverse-text.mask.argb32.ref.png
Binary files differ
diff --git a/test/reference/inverse-text.mask.rgb24.ref.png b/test/reference/inverse-text.mask.rgb24.ref.png
new file mode 100644
index 000000000..b7bbb972f
--- /dev/null
+++ b/test/reference/inverse-text.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/inverse-text.ref.png b/test/reference/inverse-text.ref.png
new file mode 100644
index 000000000..b7bbb972f
--- /dev/null
+++ b/test/reference/inverse-text.ref.png
Binary files differ
diff --git a/test/reference/inverse-text.traps.ref.png b/test/reference/inverse-text.traps.ref.png
new file mode 100644
index 000000000..b7bbb972f
--- /dev/null
+++ b/test/reference/inverse-text.traps.ref.png
Binary files differ
diff --git a/test/reference/inverted-clip.argb32.ref.png b/test/reference/inverted-clip.argb32.ref.png
new file mode 100644
index 000000000..f97d377d4
--- /dev/null
+++ b/test/reference/inverted-clip.argb32.ref.png
Binary files differ
diff --git a/test/reference/inverted-clip.base.xfail.png b/test/reference/inverted-clip.base.xfail.png
new file mode 100644
index 000000000..080b7825b
--- /dev/null
+++ b/test/reference/inverted-clip.base.xfail.png
Binary files differ
diff --git a/test/reference/inverted-clip.rgb24.ref.png b/test/reference/inverted-clip.rgb24.ref.png
new file mode 100644
index 000000000..df945ec2e
--- /dev/null
+++ b/test/reference/inverted-clip.rgb24.ref.png
Binary files differ
diff --git a/test/reference/inverted-clip.traps.xfail.png b/test/reference/inverted-clip.traps.xfail.png
new file mode 100644
index 000000000..5962795ac
--- /dev/null
+++ b/test/reference/inverted-clip.traps.xfail.png
Binary files differ
diff --git a/test/reference/inverted-clip.xfail.png b/test/reference/inverted-clip.xfail.png
new file mode 100644
index 000000000..080b7825b
--- /dev/null
+++ b/test/reference/inverted-clip.xfail.png
Binary files differ
diff --git a/test/reference/joins-loop.base.argb32.ref.png b/test/reference/joins-loop.base.argb32.ref.png
new file mode 100644
index 000000000..95400dfbd
--- /dev/null
+++ b/test/reference/joins-loop.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/joins-loop.base.rgb24.ref.png b/test/reference/joins-loop.base.rgb24.ref.png
new file mode 100644
index 000000000..95400dfbd
--- /dev/null
+++ b/test/reference/joins-loop.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/joins-loop.ref.png b/test/reference/joins-loop.ref.png
new file mode 100644
index 000000000..ecd6b23d0
--- /dev/null
+++ b/test/reference/joins-loop.ref.png
Binary files differ
diff --git a/test/reference/joins-loop.traps.argb32.ref.png b/test/reference/joins-loop.traps.argb32.ref.png
new file mode 100644
index 000000000..95400dfbd
--- /dev/null
+++ b/test/reference/joins-loop.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/joins-loop.traps.rgb24.ref.png b/test/reference/joins-loop.traps.rgb24.ref.png
new file mode 100644
index 000000000..95400dfbd
--- /dev/null
+++ b/test/reference/joins-loop.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/joins-retrace.base.argb32.ref.png b/test/reference/joins-retrace.base.argb32.ref.png
new file mode 100644
index 000000000..efbf91a6b
--- /dev/null
+++ b/test/reference/joins-retrace.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/joins-retrace.base.rgb24.ref.png b/test/reference/joins-retrace.base.rgb24.ref.png
new file mode 100644
index 000000000..efbf91a6b
--- /dev/null
+++ b/test/reference/joins-retrace.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/joins-retrace.mask.argb32.ref.png b/test/reference/joins-retrace.mask.argb32.ref.png
new file mode 100644
index 000000000..22b0ecf9a
--- /dev/null
+++ b/test/reference/joins-retrace.mask.argb32.ref.png
Binary files differ
diff --git a/test/reference/joins-retrace.mask.rgb24.ref.png b/test/reference/joins-retrace.mask.rgb24.ref.png
new file mode 100644
index 000000000..22b0ecf9a
--- /dev/null
+++ b/test/reference/joins-retrace.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/joins-retrace.ref.png b/test/reference/joins-retrace.ref.png
new file mode 100644
index 000000000..c21c80a6d
--- /dev/null
+++ b/test/reference/joins-retrace.ref.png
Binary files differ
diff --git a/test/reference/joins-retrace.traps.argb32.ref.png b/test/reference/joins-retrace.traps.argb32.ref.png
new file mode 100644
index 000000000..efbf91a6b
--- /dev/null
+++ b/test/reference/joins-retrace.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/joins-retrace.traps.rgb24.ref.png b/test/reference/joins-retrace.traps.rgb24.ref.png
new file mode 100644
index 000000000..efbf91a6b
--- /dev/null
+++ b/test/reference/joins-retrace.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/joins-star.base.argb32.ref.png b/test/reference/joins-star.base.argb32.ref.png
new file mode 100644
index 000000000..f1de705c3
--- /dev/null
+++ b/test/reference/joins-star.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/joins-star.base.rgb24.ref.png b/test/reference/joins-star.base.rgb24.ref.png
new file mode 100644
index 000000000..f1de705c3
--- /dev/null
+++ b/test/reference/joins-star.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/joins-star.ref.png b/test/reference/joins-star.ref.png
new file mode 100644
index 000000000..6fea13e3e
--- /dev/null
+++ b/test/reference/joins-star.ref.png
Binary files differ
diff --git a/test/reference/joins-star.traps.argb32.ref.png b/test/reference/joins-star.traps.argb32.ref.png
new file mode 100644
index 000000000..f1de705c3
--- /dev/null
+++ b/test/reference/joins-star.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/joins-star.traps.rgb24.ref.png b/test/reference/joins-star.traps.rgb24.ref.png
new file mode 100644
index 000000000..f1de705c3
--- /dev/null
+++ b/test/reference/joins-star.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/joins.base.argb32.ref.png b/test/reference/joins.base.argb32.ref.png
new file mode 100644
index 000000000..0b190c22b
--- /dev/null
+++ b/test/reference/joins.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/joins.base.rgb24.ref.png b/test/reference/joins.base.rgb24.ref.png
new file mode 100644
index 000000000..0b190c22b
--- /dev/null
+++ b/test/reference/joins.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/joins.image16.ref.png b/test/reference/joins.image16.ref.png
new file mode 100644
index 000000000..57f9bb15f
--- /dev/null
+++ b/test/reference/joins.image16.ref.png
Binary files differ
diff --git a/test/reference/joins.mask.argb32.ref.png b/test/reference/joins.mask.argb32.ref.png
new file mode 100644
index 000000000..a1d069d3d
--- /dev/null
+++ b/test/reference/joins.mask.argb32.ref.png
Binary files differ
diff --git a/test/reference/joins.mask.rgb24.ref.png b/test/reference/joins.mask.rgb24.ref.png
new file mode 100644
index 000000000..a1d069d3d
--- /dev/null
+++ b/test/reference/joins.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/joins.ps.ref.png b/test/reference/joins.ps.ref.png
new file mode 100644
index 000000000..0d5adea01
--- /dev/null
+++ b/test/reference/joins.ps.ref.png
Binary files differ
diff --git a/test/reference/joins.quartz.ref.png b/test/reference/joins.quartz.ref.png
new file mode 100644
index 000000000..59b8fdb0b
--- /dev/null
+++ b/test/reference/joins.quartz.ref.png
Binary files differ
diff --git a/test/reference/joins.ref.png b/test/reference/joins.ref.png
new file mode 100644
index 000000000..d1e34fece
--- /dev/null
+++ b/test/reference/joins.ref.png
Binary files differ
diff --git a/test/reference/joins.traps.argb32.ref.png b/test/reference/joins.traps.argb32.ref.png
new file mode 100644
index 000000000..0b190c22b
--- /dev/null
+++ b/test/reference/joins.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/joins.traps.rgb24.ref.png b/test/reference/joins.traps.rgb24.ref.png
new file mode 100644
index 000000000..0b190c22b
--- /dev/null
+++ b/test/reference/joins.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/large-clip.base.argb32.ref.png b/test/reference/large-clip.base.argb32.ref.png
new file mode 100644
index 000000000..3c3464bed
--- /dev/null
+++ b/test/reference/large-clip.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/large-clip.base.rgb24.ref.png b/test/reference/large-clip.base.rgb24.ref.png
new file mode 100644
index 000000000..3c3464bed
--- /dev/null
+++ b/test/reference/large-clip.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/large-clip.ref.png b/test/reference/large-clip.ref.png
new file mode 100644
index 000000000..9e46d2d5f
--- /dev/null
+++ b/test/reference/large-clip.ref.png
Binary files differ
diff --git a/test/reference/large-font.base.argb32.ref.png b/test/reference/large-font.base.argb32.ref.png
new file mode 100644
index 000000000..503061a9e
--- /dev/null
+++ b/test/reference/large-font.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/large-font.base.rgb24.ref.png b/test/reference/large-font.base.rgb24.ref.png
new file mode 100644
index 000000000..503061a9e
--- /dev/null
+++ b/test/reference/large-font.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/large-font.image16.ref.png b/test/reference/large-font.image16.ref.png
new file mode 100644
index 000000000..d5d11a5b7
--- /dev/null
+++ b/test/reference/large-font.image16.ref.png
Binary files differ
diff --git a/test/reference/large-font.ref.png b/test/reference/large-font.ref.png
new file mode 100644
index 000000000..da5c43114
--- /dev/null
+++ b/test/reference/large-font.ref.png
Binary files differ
diff --git a/test/reference/large-source-roi.base.argb32.ref.png b/test/reference/large-source-roi.base.argb32.ref.png
new file mode 100644
index 000000000..216a065e1
--- /dev/null
+++ b/test/reference/large-source-roi.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/large-source-roi.base.rgb24.ref.png b/test/reference/large-source-roi.base.rgb24.ref.png
new file mode 100644
index 000000000..216a065e1
--- /dev/null
+++ b/test/reference/large-source-roi.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/large-source-roi.ref.png b/test/reference/large-source-roi.ref.png
new file mode 100644
index 000000000..b8dc8b1b6
--- /dev/null
+++ b/test/reference/large-source-roi.ref.png
Binary files differ
diff --git a/test/reference/large-source.base.argb32.ref.png b/test/reference/large-source.base.argb32.ref.png
new file mode 100644
index 000000000..a54455fbb
--- /dev/null
+++ b/test/reference/large-source.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/large-source.base.rgb24.ref.png b/test/reference/large-source.base.rgb24.ref.png
new file mode 100644
index 000000000..a54455fbb
--- /dev/null
+++ b/test/reference/large-source.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/large-source.ref.png b/test/reference/large-source.ref.png
new file mode 100644
index 000000000..5d96dd323
--- /dev/null
+++ b/test/reference/large-source.ref.png
Binary files differ
diff --git a/test/reference/large-twin-antialias-mixed.base.argb32.ref.png b/test/reference/large-twin-antialias-mixed.base.argb32.ref.png
new file mode 100644
index 000000000..a0b265f33
--- /dev/null
+++ b/test/reference/large-twin-antialias-mixed.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/large-twin-antialias-mixed.base.rgb24.ref.png b/test/reference/large-twin-antialias-mixed.base.rgb24.ref.png
new file mode 100644
index 000000000..a0b265f33
--- /dev/null
+++ b/test/reference/large-twin-antialias-mixed.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/large-twin-antialias-mixed.image16.ref.png b/test/reference/large-twin-antialias-mixed.image16.ref.png
new file mode 100644
index 000000000..93f071ee4
--- /dev/null
+++ b/test/reference/large-twin-antialias-mixed.image16.ref.png
Binary files differ
diff --git a/test/reference/large-twin-antialias-mixed.ref.png b/test/reference/large-twin-antialias-mixed.ref.png
new file mode 100644
index 000000000..73755ab52
--- /dev/null
+++ b/test/reference/large-twin-antialias-mixed.ref.png
Binary files differ
diff --git a/test/reference/large-twin-antialias-mixed.traps.argb32.ref.png b/test/reference/large-twin-antialias-mixed.traps.argb32.ref.png
new file mode 100644
index 000000000..a0b265f33
--- /dev/null
+++ b/test/reference/large-twin-antialias-mixed.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/large-twin-antialias-mixed.traps.rgb24.ref.png b/test/reference/large-twin-antialias-mixed.traps.rgb24.ref.png
new file mode 100644
index 000000000..a0b265f33
--- /dev/null
+++ b/test/reference/large-twin-antialias-mixed.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/leaky-dash.base.argb32.ref.png b/test/reference/leaky-dash.base.argb32.ref.png
new file mode 100644
index 000000000..0973ece7e
--- /dev/null
+++ b/test/reference/leaky-dash.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/leaky-dash.base.rgb24.ref.png b/test/reference/leaky-dash.base.rgb24.ref.png
new file mode 100644
index 000000000..0973ece7e
--- /dev/null
+++ b/test/reference/leaky-dash.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/leaky-dash.ps2.argb32.ref.png b/test/reference/leaky-dash.ps2.argb32.ref.png
new file mode 100644
index 000000000..93b8640a9
--- /dev/null
+++ b/test/reference/leaky-dash.ps2.argb32.ref.png
Binary files differ
diff --git a/test/reference/leaky-dash.ps2.rgb24.ref.png b/test/reference/leaky-dash.ps2.rgb24.ref.png
new file mode 100644
index 000000000..c11eb4807
--- /dev/null
+++ b/test/reference/leaky-dash.ps2.rgb24.ref.png
Binary files differ
diff --git a/test/reference/leaky-dash.ps3.argb32.ref.png b/test/reference/leaky-dash.ps3.argb32.ref.png
new file mode 100644
index 000000000..93b8640a9
--- /dev/null
+++ b/test/reference/leaky-dash.ps3.argb32.ref.png
Binary files differ
diff --git a/test/reference/leaky-dash.ps3.rgb24.ref.png b/test/reference/leaky-dash.ps3.rgb24.ref.png
new file mode 100644
index 000000000..c11eb4807
--- /dev/null
+++ b/test/reference/leaky-dash.ps3.rgb24.ref.png
Binary files differ
diff --git a/test/reference/leaky-dash.quartz.ref.png b/test/reference/leaky-dash.quartz.ref.png
new file mode 100644
index 000000000..96928195a
--- /dev/null
+++ b/test/reference/leaky-dash.quartz.ref.png
Binary files differ
diff --git a/test/reference/leaky-dash.ref.png b/test/reference/leaky-dash.ref.png
new file mode 100644
index 000000000..87facc551
--- /dev/null
+++ b/test/reference/leaky-dash.ref.png
Binary files differ
diff --git a/test/reference/leaky-dashed-rectangle.base.argb32.ref.png b/test/reference/leaky-dashed-rectangle.base.argb32.ref.png
new file mode 100644
index 000000000..de3542098
--- /dev/null
+++ b/test/reference/leaky-dashed-rectangle.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/leaky-dashed-rectangle.base.rgb24.ref.png b/test/reference/leaky-dashed-rectangle.base.rgb24.ref.png
new file mode 100644
index 000000000..de3542098
--- /dev/null
+++ b/test/reference/leaky-dashed-rectangle.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/leaky-dashed-rectangle.image16.ref.png b/test/reference/leaky-dashed-rectangle.image16.ref.png
new file mode 100644
index 000000000..f61db4c29
--- /dev/null
+++ b/test/reference/leaky-dashed-rectangle.image16.ref.png
Binary files differ
diff --git a/test/reference/leaky-dashed-rectangle.pdf.ref.png b/test/reference/leaky-dashed-rectangle.pdf.ref.png
new file mode 100644
index 000000000..72efd4954
--- /dev/null
+++ b/test/reference/leaky-dashed-rectangle.pdf.ref.png
Binary files differ
diff --git a/test/reference/leaky-dashed-rectangle.ps.ref.png b/test/reference/leaky-dashed-rectangle.ps.ref.png
new file mode 100644
index 000000000..1e0a1388c
--- /dev/null
+++ b/test/reference/leaky-dashed-rectangle.ps.ref.png
Binary files differ
diff --git a/test/reference/leaky-dashed-rectangle.quartz.ref.png b/test/reference/leaky-dashed-rectangle.quartz.ref.png
new file mode 100644
index 000000000..fad8588fe
--- /dev/null
+++ b/test/reference/leaky-dashed-rectangle.quartz.ref.png
Binary files differ
diff --git a/test/reference/leaky-dashed-rectangle.ref.png b/test/reference/leaky-dashed-rectangle.ref.png
new file mode 100644
index 000000000..05f45846a
--- /dev/null
+++ b/test/reference/leaky-dashed-rectangle.ref.png
Binary files differ
diff --git a/test/reference/leaky-dashed-rectangle.traps.argb32.ref.png b/test/reference/leaky-dashed-rectangle.traps.argb32.ref.png
new file mode 100644
index 000000000..de3542098
--- /dev/null
+++ b/test/reference/leaky-dashed-rectangle.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/leaky-dashed-rectangle.traps.rgb24.ref.png b/test/reference/leaky-dashed-rectangle.traps.rgb24.ref.png
new file mode 100644
index 000000000..de3542098
--- /dev/null
+++ b/test/reference/leaky-dashed-rectangle.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/leaky-dashed-stroke.base.argb32.ref.png b/test/reference/leaky-dashed-stroke.base.argb32.ref.png
new file mode 100644
index 000000000..da6807f77
--- /dev/null
+++ b/test/reference/leaky-dashed-stroke.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/leaky-dashed-stroke.base.rgb24.ref.png b/test/reference/leaky-dashed-stroke.base.rgb24.ref.png
new file mode 100644
index 000000000..da6807f77
--- /dev/null
+++ b/test/reference/leaky-dashed-stroke.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/leaky-dashed-stroke.image16.ref.png b/test/reference/leaky-dashed-stroke.image16.ref.png
new file mode 100644
index 000000000..f90bb2375
--- /dev/null
+++ b/test/reference/leaky-dashed-stroke.image16.ref.png
Binary files differ
diff --git a/test/reference/leaky-dashed-stroke.ps.ref.png b/test/reference/leaky-dashed-stroke.ps.ref.png
new file mode 100644
index 000000000..7d581e916
--- /dev/null
+++ b/test/reference/leaky-dashed-stroke.ps.ref.png
Binary files differ
diff --git a/test/reference/leaky-dashed-stroke.quartz.ref.png b/test/reference/leaky-dashed-stroke.quartz.ref.png
new file mode 100644
index 000000000..adbfd612a
--- /dev/null
+++ b/test/reference/leaky-dashed-stroke.quartz.ref.png
Binary files differ
diff --git a/test/reference/leaky-dashed-stroke.ref.png b/test/reference/leaky-dashed-stroke.ref.png
new file mode 100644
index 000000000..1b8569244
--- /dev/null
+++ b/test/reference/leaky-dashed-stroke.ref.png
Binary files differ
diff --git a/test/reference/leaky-dashed-stroke.traps.argb32.ref.png b/test/reference/leaky-dashed-stroke.traps.argb32.ref.png
new file mode 100644
index 000000000..da6807f77
--- /dev/null
+++ b/test/reference/leaky-dashed-stroke.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/leaky-dashed-stroke.traps.rgb24.ref.png b/test/reference/leaky-dashed-stroke.traps.rgb24.ref.png
new file mode 100644
index 000000000..da6807f77
--- /dev/null
+++ b/test/reference/leaky-dashed-stroke.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/leaky-polygon.base.argb32.ref.png b/test/reference/leaky-polygon.base.argb32.ref.png
new file mode 100644
index 000000000..1cb7a3cac
--- /dev/null
+++ b/test/reference/leaky-polygon.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/leaky-polygon.base.rgb24.ref.png b/test/reference/leaky-polygon.base.rgb24.ref.png
new file mode 100644
index 000000000..1cb7a3cac
--- /dev/null
+++ b/test/reference/leaky-polygon.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/leaky-polygon.image16.ref.png b/test/reference/leaky-polygon.image16.ref.png
new file mode 100644
index 000000000..e91d0fa34
--- /dev/null
+++ b/test/reference/leaky-polygon.image16.ref.png
Binary files differ
diff --git a/test/reference/leaky-polygon.ps.ref.png b/test/reference/leaky-polygon.ps.ref.png
new file mode 100644
index 000000000..dd8a10434
--- /dev/null
+++ b/test/reference/leaky-polygon.ps.ref.png
Binary files differ
diff --git a/test/reference/leaky-polygon.ref.png b/test/reference/leaky-polygon.ref.png
new file mode 100644
index 000000000..d2a06a3cc
--- /dev/null
+++ b/test/reference/leaky-polygon.ref.png
Binary files differ
diff --git a/test/reference/leaky-polygon.traps.argb32.ref.png b/test/reference/leaky-polygon.traps.argb32.ref.png
new file mode 100644
index 000000000..1cb7a3cac
--- /dev/null
+++ b/test/reference/leaky-polygon.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/leaky-polygon.traps.rgb24.ref.png b/test/reference/leaky-polygon.traps.rgb24.ref.png
new file mode 100644
index 000000000..1cb7a3cac
--- /dev/null
+++ b/test/reference/leaky-polygon.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/line-width-large-overlap-dashed.base.argb32.ref.png b/test/reference/line-width-large-overlap-dashed.base.argb32.ref.png
new file mode 100644
index 000000000..e6cdcc2f7
--- /dev/null
+++ b/test/reference/line-width-large-overlap-dashed.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/line-width-large-overlap-dashed.base.rgb24.ref.png b/test/reference/line-width-large-overlap-dashed.base.rgb24.ref.png
new file mode 100644
index 000000000..e6cdcc2f7
--- /dev/null
+++ b/test/reference/line-width-large-overlap-dashed.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/line-width-large-overlap-dashed.mask.argb32.ref.png b/test/reference/line-width-large-overlap-dashed.mask.argb32.ref.png
new file mode 100644
index 000000000..8cd4d31e1
--- /dev/null
+++ b/test/reference/line-width-large-overlap-dashed.mask.argb32.ref.png
Binary files differ
diff --git a/test/reference/line-width-large-overlap-dashed.mask.rgb24.ref.png b/test/reference/line-width-large-overlap-dashed.mask.rgb24.ref.png
new file mode 100644
index 000000000..8cd4d31e1
--- /dev/null
+++ b/test/reference/line-width-large-overlap-dashed.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/line-width-large-overlap-dashed.ref.png b/test/reference/line-width-large-overlap-dashed.ref.png
new file mode 100644
index 000000000..12379ac03
--- /dev/null
+++ b/test/reference/line-width-large-overlap-dashed.ref.png
Binary files differ
diff --git a/test/reference/line-width-large-overlap-dashed.traps.argb32.ref.png b/test/reference/line-width-large-overlap-dashed.traps.argb32.ref.png
new file mode 100644
index 000000000..12379ac03
--- /dev/null
+++ b/test/reference/line-width-large-overlap-dashed.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/line-width-large-overlap-dashed.traps.rgb24.ref.png b/test/reference/line-width-large-overlap-dashed.traps.rgb24.ref.png
new file mode 100644
index 000000000..12379ac03
--- /dev/null
+++ b/test/reference/line-width-large-overlap-dashed.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/line-width-large-overlap-flipped.base.argb32.ref.png b/test/reference/line-width-large-overlap-flipped.base.argb32.ref.png
new file mode 100644
index 000000000..3c3464bed
--- /dev/null
+++ b/test/reference/line-width-large-overlap-flipped.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/line-width-large-overlap-flipped.base.rgb24.ref.png b/test/reference/line-width-large-overlap-flipped.base.rgb24.ref.png
new file mode 100644
index 000000000..3c3464bed
--- /dev/null
+++ b/test/reference/line-width-large-overlap-flipped.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/line-width-large-overlap-flipped.ref.png b/test/reference/line-width-large-overlap-flipped.ref.png
new file mode 100644
index 000000000..3c3464bed
--- /dev/null
+++ b/test/reference/line-width-large-overlap-flipped.ref.png
Binary files differ
diff --git a/test/reference/line-width-large-overlap-flopped.base.argb32.ref.png b/test/reference/line-width-large-overlap-flopped.base.argb32.ref.png
new file mode 100644
index 000000000..3c3464bed
--- /dev/null
+++ b/test/reference/line-width-large-overlap-flopped.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/line-width-large-overlap-flopped.base.rgb24.ref.png b/test/reference/line-width-large-overlap-flopped.base.rgb24.ref.png
new file mode 100644
index 000000000..3c3464bed
--- /dev/null
+++ b/test/reference/line-width-large-overlap-flopped.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/line-width-large-overlap-flopped.ref.png b/test/reference/line-width-large-overlap-flopped.ref.png
new file mode 100644
index 000000000..3c3464bed
--- /dev/null
+++ b/test/reference/line-width-large-overlap-flopped.ref.png
Binary files differ
diff --git a/test/reference/line-width-large-overlap-offset.base.argb32.ref.png b/test/reference/line-width-large-overlap-offset.base.argb32.ref.png
new file mode 100644
index 000000000..3c3464bed
--- /dev/null
+++ b/test/reference/line-width-large-overlap-offset.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/line-width-large-overlap-offset.base.rgb24.ref.png b/test/reference/line-width-large-overlap-offset.base.rgb24.ref.png
new file mode 100644
index 000000000..3c3464bed
--- /dev/null
+++ b/test/reference/line-width-large-overlap-offset.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/line-width-large-overlap-offset.ref.png b/test/reference/line-width-large-overlap-offset.ref.png
new file mode 100644
index 000000000..3c3464bed
--- /dev/null
+++ b/test/reference/line-width-large-overlap-offset.ref.png
Binary files differ
diff --git a/test/reference/line-width-large-overlap-rotated.base.argb32.ref.png b/test/reference/line-width-large-overlap-rotated.base.argb32.ref.png
new file mode 100644
index 000000000..87fe7523b
--- /dev/null
+++ b/test/reference/line-width-large-overlap-rotated.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/line-width-large-overlap-rotated.base.rgb24.ref.png b/test/reference/line-width-large-overlap-rotated.base.rgb24.ref.png
new file mode 100644
index 000000000..87fe7523b
--- /dev/null
+++ b/test/reference/line-width-large-overlap-rotated.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/line-width-large-overlap-rotated.ref.png b/test/reference/line-width-large-overlap-rotated.ref.png
new file mode 100644
index 000000000..3eeebb254
--- /dev/null
+++ b/test/reference/line-width-large-overlap-rotated.ref.png
Binary files differ
diff --git a/test/reference/line-width-large-overlap-rotated.traps.ref.png b/test/reference/line-width-large-overlap-rotated.traps.ref.png
new file mode 100644
index 000000000..87fe7523b
--- /dev/null
+++ b/test/reference/line-width-large-overlap-rotated.traps.ref.png
Binary files differ
diff --git a/test/reference/line-width-large-overlap.base.argb32.ref.png b/test/reference/line-width-large-overlap.base.argb32.ref.png
new file mode 100644
index 000000000..3c3464bed
--- /dev/null
+++ b/test/reference/line-width-large-overlap.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/line-width-large-overlap.base.rgb24.ref.png b/test/reference/line-width-large-overlap.base.rgb24.ref.png
new file mode 100644
index 000000000..3c3464bed
--- /dev/null
+++ b/test/reference/line-width-large-overlap.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/line-width-large-overlap.ref.png b/test/reference/line-width-large-overlap.ref.png
new file mode 100644
index 000000000..3c3464bed
--- /dev/null
+++ b/test/reference/line-width-large-overlap.ref.png
Binary files differ
diff --git a/test/reference/line-width-overlap-dashed.base.argb32.ref.png b/test/reference/line-width-overlap-dashed.base.argb32.ref.png
new file mode 100644
index 000000000..066b182ae
--- /dev/null
+++ b/test/reference/line-width-overlap-dashed.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/line-width-overlap-dashed.base.rgb24.ref.png b/test/reference/line-width-overlap-dashed.base.rgb24.ref.png
new file mode 100644
index 000000000..066b182ae
--- /dev/null
+++ b/test/reference/line-width-overlap-dashed.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/line-width-overlap-dashed.mask.argb32.ref.png b/test/reference/line-width-overlap-dashed.mask.argb32.ref.png
new file mode 100644
index 000000000..0de187d40
--- /dev/null
+++ b/test/reference/line-width-overlap-dashed.mask.argb32.ref.png
Binary files differ
diff --git a/test/reference/line-width-overlap-dashed.mask.rgb24.ref.png b/test/reference/line-width-overlap-dashed.mask.rgb24.ref.png
new file mode 100644
index 000000000..0de187d40
--- /dev/null
+++ b/test/reference/line-width-overlap-dashed.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/line-width-overlap-dashed.ref.png b/test/reference/line-width-overlap-dashed.ref.png
new file mode 100644
index 000000000..065d69958
--- /dev/null
+++ b/test/reference/line-width-overlap-dashed.ref.png
Binary files differ
diff --git a/test/reference/line-width-overlap-dashed.traps.argb32.ref.png b/test/reference/line-width-overlap-dashed.traps.argb32.ref.png
new file mode 100644
index 000000000..065d69958
--- /dev/null
+++ b/test/reference/line-width-overlap-dashed.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/line-width-overlap-dashed.traps.rgb24.ref.png b/test/reference/line-width-overlap-dashed.traps.rgb24.ref.png
new file mode 100644
index 000000000..065d69958
--- /dev/null
+++ b/test/reference/line-width-overlap-dashed.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/line-width-overlap-flipped.base.argb32.ref.png b/test/reference/line-width-overlap-flipped.base.argb32.ref.png
new file mode 100644
index 000000000..13d70c8fe
--- /dev/null
+++ b/test/reference/line-width-overlap-flipped.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/line-width-overlap-flipped.base.rgb24.ref.png b/test/reference/line-width-overlap-flipped.base.rgb24.ref.png
new file mode 100644
index 000000000..13d70c8fe
--- /dev/null
+++ b/test/reference/line-width-overlap-flipped.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/line-width-overlap-flipped.ref.png b/test/reference/line-width-overlap-flipped.ref.png
new file mode 100644
index 000000000..09911bc51
--- /dev/null
+++ b/test/reference/line-width-overlap-flipped.ref.png
Binary files differ
diff --git a/test/reference/line-width-overlap-flopped.base.argb32.ref.png b/test/reference/line-width-overlap-flopped.base.argb32.ref.png
new file mode 100644
index 000000000..13d70c8fe
--- /dev/null
+++ b/test/reference/line-width-overlap-flopped.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/line-width-overlap-flopped.base.rgb24.ref.png b/test/reference/line-width-overlap-flopped.base.rgb24.ref.png
new file mode 100644
index 000000000..13d70c8fe
--- /dev/null
+++ b/test/reference/line-width-overlap-flopped.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/line-width-overlap-flopped.ref.png b/test/reference/line-width-overlap-flopped.ref.png
new file mode 100644
index 000000000..09911bc51
--- /dev/null
+++ b/test/reference/line-width-overlap-flopped.ref.png
Binary files differ
diff --git a/test/reference/line-width-overlap-offset.base.argb32.ref.png b/test/reference/line-width-overlap-offset.base.argb32.ref.png
new file mode 100644
index 000000000..13a138b9a
--- /dev/null
+++ b/test/reference/line-width-overlap-offset.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/line-width-overlap-offset.base.rgb24.ref.png b/test/reference/line-width-overlap-offset.base.rgb24.ref.png
new file mode 100644
index 000000000..13a138b9a
--- /dev/null
+++ b/test/reference/line-width-overlap-offset.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/line-width-overlap-offset.ref.png b/test/reference/line-width-overlap-offset.ref.png
new file mode 100644
index 000000000..eafa50b1f
--- /dev/null
+++ b/test/reference/line-width-overlap-offset.ref.png
Binary files differ
diff --git a/test/reference/line-width-overlap-offset.traps.ref.png b/test/reference/line-width-overlap-offset.traps.ref.png
new file mode 100644
index 000000000..13a138b9a
--- /dev/null
+++ b/test/reference/line-width-overlap-offset.traps.ref.png
Binary files differ
diff --git a/test/reference/line-width-overlap-rotated.base.argb32.ref.png b/test/reference/line-width-overlap-rotated.base.argb32.ref.png
new file mode 100644
index 000000000..fa7290d6c
--- /dev/null
+++ b/test/reference/line-width-overlap-rotated.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/line-width-overlap-rotated.base.rgb24.ref.png b/test/reference/line-width-overlap-rotated.base.rgb24.ref.png
new file mode 100644
index 000000000..fa7290d6c
--- /dev/null
+++ b/test/reference/line-width-overlap-rotated.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/line-width-overlap-rotated.ref.png b/test/reference/line-width-overlap-rotated.ref.png
new file mode 100644
index 000000000..cce46c70a
--- /dev/null
+++ b/test/reference/line-width-overlap-rotated.ref.png
Binary files differ
diff --git a/test/reference/line-width-overlap-rotated.traps.argb32.ref.png b/test/reference/line-width-overlap-rotated.traps.argb32.ref.png
new file mode 100644
index 000000000..fa7290d6c
--- /dev/null
+++ b/test/reference/line-width-overlap-rotated.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/line-width-overlap-rotated.traps.rgb24.ref.png b/test/reference/line-width-overlap-rotated.traps.rgb24.ref.png
new file mode 100644
index 000000000..fa7290d6c
--- /dev/null
+++ b/test/reference/line-width-overlap-rotated.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/line-width-overlap.base.argb32.ref.png b/test/reference/line-width-overlap.base.argb32.ref.png
new file mode 100644
index 000000000..13d70c8fe
--- /dev/null
+++ b/test/reference/line-width-overlap.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/line-width-overlap.base.rgb24.ref.png b/test/reference/line-width-overlap.base.rgb24.ref.png
new file mode 100644
index 000000000..13d70c8fe
--- /dev/null
+++ b/test/reference/line-width-overlap.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/line-width-overlap.ref.png b/test/reference/line-width-overlap.ref.png
new file mode 100644
index 000000000..13d70c8fe
--- /dev/null
+++ b/test/reference/line-width-overlap.ref.png
Binary files differ
diff --git a/test/reference/line-width-scale.base.argb32.ref.png b/test/reference/line-width-scale.base.argb32.ref.png
new file mode 100644
index 000000000..41d55b0eb
--- /dev/null
+++ b/test/reference/line-width-scale.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/line-width-scale.base.rgb24.ref.png b/test/reference/line-width-scale.base.rgb24.ref.png
new file mode 100644
index 000000000..41d55b0eb
--- /dev/null
+++ b/test/reference/line-width-scale.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/line-width-scale.image16.ref.png b/test/reference/line-width-scale.image16.ref.png
new file mode 100644
index 000000000..a784f6582
--- /dev/null
+++ b/test/reference/line-width-scale.image16.ref.png
Binary files differ
diff --git a/test/reference/line-width-scale.ps2.ref.png b/test/reference/line-width-scale.ps2.ref.png
new file mode 100644
index 000000000..57999b802
--- /dev/null
+++ b/test/reference/line-width-scale.ps2.ref.png
Binary files differ
diff --git a/test/reference/line-width-scale.ps3.ref.png b/test/reference/line-width-scale.ps3.ref.png
new file mode 100644
index 000000000..57999b802
--- /dev/null
+++ b/test/reference/line-width-scale.ps3.ref.png
Binary files differ
diff --git a/test/reference/line-width-scale.quartz.ref.png b/test/reference/line-width-scale.quartz.ref.png
new file mode 100644
index 000000000..afdc9da76
--- /dev/null
+++ b/test/reference/line-width-scale.quartz.ref.png
Binary files differ
diff --git a/test/reference/line-width-scale.ref.png b/test/reference/line-width-scale.ref.png
new file mode 100644
index 000000000..5767bc7d8
--- /dev/null
+++ b/test/reference/line-width-scale.ref.png
Binary files differ
diff --git a/test/reference/line-width-scale.traps.argb32.ref.png b/test/reference/line-width-scale.traps.argb32.ref.png
new file mode 100644
index 000000000..41d55b0eb
--- /dev/null
+++ b/test/reference/line-width-scale.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/line-width-scale.traps.rgb24.ref.png b/test/reference/line-width-scale.traps.rgb24.ref.png
new file mode 100644
index 000000000..41d55b0eb
--- /dev/null
+++ b/test/reference/line-width-scale.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/line-width-tolerance.base.argb32.ref.png b/test/reference/line-width-tolerance.base.argb32.ref.png
new file mode 100644
index 000000000..f890a52ed
--- /dev/null
+++ b/test/reference/line-width-tolerance.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/line-width-tolerance.base.rgb24.ref.png b/test/reference/line-width-tolerance.base.rgb24.ref.png
new file mode 100644
index 000000000..f890a52ed
--- /dev/null
+++ b/test/reference/line-width-tolerance.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/line-width-tolerance.ref.png b/test/reference/line-width-tolerance.ref.png
new file mode 100644
index 000000000..9c4d43987
--- /dev/null
+++ b/test/reference/line-width-tolerance.ref.png
Binary files differ
diff --git a/test/reference/line-width-tolerance.traps.argb32.ref.png b/test/reference/line-width-tolerance.traps.argb32.ref.png
new file mode 100644
index 000000000..f890a52ed
--- /dev/null
+++ b/test/reference/line-width-tolerance.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/line-width-tolerance.traps.rgb24.ref.png b/test/reference/line-width-tolerance.traps.rgb24.ref.png
new file mode 100644
index 000000000..f890a52ed
--- /dev/null
+++ b/test/reference/line-width-tolerance.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/line-width.base.argb32.ref.png b/test/reference/line-width.base.argb32.ref.png
new file mode 100644
index 000000000..208d17083
--- /dev/null
+++ b/test/reference/line-width.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/line-width.base.rgb24.ref.png b/test/reference/line-width.base.rgb24.ref.png
new file mode 100644
index 000000000..208d17083
--- /dev/null
+++ b/test/reference/line-width.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/line-width.ref.png b/test/reference/line-width.ref.png
new file mode 100644
index 000000000..2a788285f
--- /dev/null
+++ b/test/reference/line-width.ref.png
Binary files differ
diff --git a/test/reference/line-width.traps.argb32.ref.png b/test/reference/line-width.traps.argb32.ref.png
new file mode 100644
index 000000000..208d17083
--- /dev/null
+++ b/test/reference/line-width.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/line-width.traps.rgb24.ref.png b/test/reference/line-width.traps.rgb24.ref.png
new file mode 100644
index 000000000..208d17083
--- /dev/null
+++ b/test/reference/line-width.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/linear-gradient-extend.base.argb32.ref.png b/test/reference/linear-gradient-extend.base.argb32.ref.png
new file mode 100644
index 000000000..79ce747db
--- /dev/null
+++ b/test/reference/linear-gradient-extend.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/linear-gradient-extend.base.rgb24.ref.png b/test/reference/linear-gradient-extend.base.rgb24.ref.png
new file mode 100644
index 000000000..79ce747db
--- /dev/null
+++ b/test/reference/linear-gradient-extend.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/linear-gradient-extend.ref.png b/test/reference/linear-gradient-extend.ref.png
new file mode 100644
index 000000000..79ce747db
--- /dev/null
+++ b/test/reference/linear-gradient-extend.ref.png
Binary files differ
diff --git a/test/reference/linear-gradient-large.base.argb32.ref.png b/test/reference/linear-gradient-large.base.argb32.ref.png
new file mode 100644
index 000000000..f1f37ab47
--- /dev/null
+++ b/test/reference/linear-gradient-large.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/linear-gradient-large.base.rgb24.ref.png b/test/reference/linear-gradient-large.base.rgb24.ref.png
new file mode 100644
index 000000000..f1f37ab47
--- /dev/null
+++ b/test/reference/linear-gradient-large.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/linear-gradient-large.quartz.ref.png b/test/reference/linear-gradient-large.quartz.ref.png
new file mode 100644
index 000000000..68f08297b
--- /dev/null
+++ b/test/reference/linear-gradient-large.quartz.ref.png
Binary files differ
diff --git a/test/reference/linear-gradient-large.ref.png b/test/reference/linear-gradient-large.ref.png
new file mode 100644
index 000000000..f1f37ab47
--- /dev/null
+++ b/test/reference/linear-gradient-large.ref.png
Binary files differ
diff --git a/test/reference/linear-gradient-one-stop.base.argb32.ref.png b/test/reference/linear-gradient-one-stop.base.argb32.ref.png
new file mode 100644
index 000000000..da02fda49
--- /dev/null
+++ b/test/reference/linear-gradient-one-stop.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/linear-gradient-one-stop.base.rgb24.ref.png b/test/reference/linear-gradient-one-stop.base.rgb24.ref.png
new file mode 100644
index 000000000..efc12ee71
--- /dev/null
+++ b/test/reference/linear-gradient-one-stop.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/linear-gradient-one-stop.ref.png b/test/reference/linear-gradient-one-stop.ref.png
new file mode 100644
index 000000000..da02fda49
--- /dev/null
+++ b/test/reference/linear-gradient-one-stop.ref.png
Binary files differ
diff --git a/test/reference/linear-gradient-reflect.base.argb32.ref.png b/test/reference/linear-gradient-reflect.base.argb32.ref.png
new file mode 100644
index 000000000..b68dccb5e
--- /dev/null
+++ b/test/reference/linear-gradient-reflect.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/linear-gradient-reflect.base.rgb24.ref.png b/test/reference/linear-gradient-reflect.base.rgb24.ref.png
new file mode 100644
index 000000000..b68dccb5e
--- /dev/null
+++ b/test/reference/linear-gradient-reflect.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/linear-gradient-reflect.image16.ref.png b/test/reference/linear-gradient-reflect.image16.ref.png
new file mode 100644
index 000000000..de74afcb0
--- /dev/null
+++ b/test/reference/linear-gradient-reflect.image16.ref.png
Binary files differ
diff --git a/test/reference/linear-gradient-reflect.pdf.argb32.ref.png b/test/reference/linear-gradient-reflect.pdf.argb32.ref.png
new file mode 100644
index 000000000..46e1c0f0e
--- /dev/null
+++ b/test/reference/linear-gradient-reflect.pdf.argb32.ref.png
Binary files differ
diff --git a/test/reference/linear-gradient-reflect.pdf.rgb24.ref.png b/test/reference/linear-gradient-reflect.pdf.rgb24.ref.png
new file mode 100644
index 000000000..46e1c0f0e
--- /dev/null
+++ b/test/reference/linear-gradient-reflect.pdf.rgb24.ref.png
Binary files differ
diff --git a/test/reference/linear-gradient-reflect.ps3.ref.png b/test/reference/linear-gradient-reflect.ps3.ref.png
new file mode 100644
index 000000000..ea6d25c17
--- /dev/null
+++ b/test/reference/linear-gradient-reflect.ps3.ref.png
Binary files differ
diff --git a/test/reference/linear-gradient-reflect.quartz.ref.png b/test/reference/linear-gradient-reflect.quartz.ref.png
new file mode 100644
index 000000000..89bac91da
--- /dev/null
+++ b/test/reference/linear-gradient-reflect.quartz.ref.png
Binary files differ
diff --git a/test/reference/linear-gradient-reflect.ref.png b/test/reference/linear-gradient-reflect.ref.png
new file mode 100644
index 000000000..b68dccb5e
--- /dev/null
+++ b/test/reference/linear-gradient-reflect.ref.png
Binary files differ
diff --git a/test/reference/linear-gradient-subset.base.argb32.ref.png b/test/reference/linear-gradient-subset.base.argb32.ref.png
new file mode 100644
index 000000000..e03d3d60f
--- /dev/null
+++ b/test/reference/linear-gradient-subset.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/linear-gradient-subset.base.rgb24.ref.png b/test/reference/linear-gradient-subset.base.rgb24.ref.png
new file mode 100644
index 000000000..e03d3d60f
--- /dev/null
+++ b/test/reference/linear-gradient-subset.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/linear-gradient-subset.image16.ref.png b/test/reference/linear-gradient-subset.image16.ref.png
new file mode 100644
index 000000000..9d04057e2
--- /dev/null
+++ b/test/reference/linear-gradient-subset.image16.ref.png
Binary files differ
diff --git a/test/reference/linear-gradient-subset.ps3.ref.png b/test/reference/linear-gradient-subset.ps3.ref.png
new file mode 100644
index 000000000..db0a4c067
--- /dev/null
+++ b/test/reference/linear-gradient-subset.ps3.ref.png
Binary files differ
diff --git a/test/reference/linear-gradient-subset.quartz.ref.png b/test/reference/linear-gradient-subset.quartz.ref.png
new file mode 100644
index 000000000..85d80adbb
--- /dev/null
+++ b/test/reference/linear-gradient-subset.quartz.ref.png
Binary files differ
diff --git a/test/reference/linear-gradient-subset.ref.png b/test/reference/linear-gradient-subset.ref.png
new file mode 100644
index 000000000..8e95d10f6
--- /dev/null
+++ b/test/reference/linear-gradient-subset.ref.png
Binary files differ
diff --git a/test/reference/linear-gradient-subset.traps.argb32.ref.png b/test/reference/linear-gradient-subset.traps.argb32.ref.png
new file mode 100644
index 000000000..e03d3d60f
--- /dev/null
+++ b/test/reference/linear-gradient-subset.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/linear-gradient-subset.traps.rgb24.ref.png b/test/reference/linear-gradient-subset.traps.rgb24.ref.png
new file mode 100644
index 000000000..e03d3d60f
--- /dev/null
+++ b/test/reference/linear-gradient-subset.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/linear-gradient.base.argb32.ref.png b/test/reference/linear-gradient.base.argb32.ref.png
new file mode 100644
index 000000000..083a9b87b
--- /dev/null
+++ b/test/reference/linear-gradient.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/linear-gradient.base.rgb24.ref.png b/test/reference/linear-gradient.base.rgb24.ref.png
new file mode 100644
index 000000000..083a9b87b
--- /dev/null
+++ b/test/reference/linear-gradient.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/linear-gradient.image16.ref.png b/test/reference/linear-gradient.image16.ref.png
new file mode 100644
index 000000000..183d3d985
--- /dev/null
+++ b/test/reference/linear-gradient.image16.ref.png
Binary files differ
diff --git a/test/reference/linear-gradient.ps3.ref.png b/test/reference/linear-gradient.ps3.ref.png
new file mode 100644
index 000000000..c2fa71b11
--- /dev/null
+++ b/test/reference/linear-gradient.ps3.ref.png
Binary files differ
diff --git a/test/reference/linear-gradient.quartz.ref.png b/test/reference/linear-gradient.quartz.ref.png
new file mode 100644
index 000000000..1c3e7c228
--- /dev/null
+++ b/test/reference/linear-gradient.quartz.ref.png
Binary files differ
diff --git a/test/reference/linear-gradient.ref.png b/test/reference/linear-gradient.ref.png
new file mode 100644
index 000000000..32c99a4a3
--- /dev/null
+++ b/test/reference/linear-gradient.ref.png
Binary files differ
diff --git a/test/reference/linear-gradient.traps.argb32.ref.png b/test/reference/linear-gradient.traps.argb32.ref.png
new file mode 100644
index 000000000..083a9b87b
--- /dev/null
+++ b/test/reference/linear-gradient.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/linear-gradient.traps.rgb24.ref.png b/test/reference/linear-gradient.traps.rgb24.ref.png
new file mode 100644
index 000000000..083a9b87b
--- /dev/null
+++ b/test/reference/linear-gradient.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/linear-step-function.base.argb32.ref.png b/test/reference/linear-step-function.base.argb32.ref.png
new file mode 100644
index 000000000..0ed126e1d
--- /dev/null
+++ b/test/reference/linear-step-function.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/linear-step-function.base.rgb24.ref.png b/test/reference/linear-step-function.base.rgb24.ref.png
new file mode 100644
index 000000000..0ed126e1d
--- /dev/null
+++ b/test/reference/linear-step-function.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/linear-step-function.mask.argb32.ref.png b/test/reference/linear-step-function.mask.argb32.ref.png
new file mode 100644
index 000000000..0ed126e1d
--- /dev/null
+++ b/test/reference/linear-step-function.mask.argb32.ref.png
Binary files differ
diff --git a/test/reference/linear-step-function.mask.rgb24.ref.png b/test/reference/linear-step-function.mask.rgb24.ref.png
new file mode 100644
index 000000000..0ed126e1d
--- /dev/null
+++ b/test/reference/linear-step-function.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/linear-step-function.traps.argb32.ref.png b/test/reference/linear-step-function.traps.argb32.ref.png
new file mode 100644
index 000000000..0ed126e1d
--- /dev/null
+++ b/test/reference/linear-step-function.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/linear-step-function.traps.rgb24.ref.png b/test/reference/linear-step-function.traps.rgb24.ref.png
new file mode 100644
index 000000000..0ed126e1d
--- /dev/null
+++ b/test/reference/linear-step-function.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/linear-step-function.xfail.png b/test/reference/linear-step-function.xfail.png
new file mode 100644
index 000000000..b8afd218a
--- /dev/null
+++ b/test/reference/linear-step-function.xfail.png
Binary files differ
diff --git a/test/reference/linear-uniform.base.argb32.ref.png b/test/reference/linear-uniform.base.argb32.ref.png
new file mode 100644
index 000000000..94ca33615
--- /dev/null
+++ b/test/reference/linear-uniform.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/linear-uniform.base.rgb24.ref.png b/test/reference/linear-uniform.base.rgb24.ref.png
new file mode 100644
index 000000000..94ca33615
--- /dev/null
+++ b/test/reference/linear-uniform.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/linear-uniform.image16.ref.png b/test/reference/linear-uniform.image16.ref.png
new file mode 100644
index 000000000..7bf4bf561
--- /dev/null
+++ b/test/reference/linear-uniform.image16.ref.png
Binary files differ
diff --git a/test/reference/linear-uniform.ref.png b/test/reference/linear-uniform.ref.png
new file mode 100644
index 000000000..94ca33615
--- /dev/null
+++ b/test/reference/linear-uniform.ref.png
Binary files differ
diff --git a/test/reference/long-dashed-lines.base.argb32.ref.png b/test/reference/long-dashed-lines.base.argb32.ref.png
new file mode 100644
index 000000000..ccd3d5df1
--- /dev/null
+++ b/test/reference/long-dashed-lines.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/long-dashed-lines.base.rgb24.ref.png b/test/reference/long-dashed-lines.base.rgb24.ref.png
new file mode 100644
index 000000000..ccd3d5df1
--- /dev/null
+++ b/test/reference/long-dashed-lines.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/long-dashed-lines.image16.ref.png b/test/reference/long-dashed-lines.image16.ref.png
new file mode 100644
index 000000000..8abac9b4d
--- /dev/null
+++ b/test/reference/long-dashed-lines.image16.ref.png
Binary files differ
diff --git a/test/reference/long-dashed-lines.ps2.ref.png b/test/reference/long-dashed-lines.ps2.ref.png
new file mode 100644
index 000000000..7fce667e8
--- /dev/null
+++ b/test/reference/long-dashed-lines.ps2.ref.png
Binary files differ
diff --git a/test/reference/long-dashed-lines.ps3.ref.png b/test/reference/long-dashed-lines.ps3.ref.png
new file mode 100644
index 000000000..7fce667e8
--- /dev/null
+++ b/test/reference/long-dashed-lines.ps3.ref.png
Binary files differ
diff --git a/test/reference/long-dashed-lines.quartz.ref.png b/test/reference/long-dashed-lines.quartz.ref.png
new file mode 100644
index 000000000..3f68d216d
--- /dev/null
+++ b/test/reference/long-dashed-lines.quartz.ref.png
Binary files differ
diff --git a/test/reference/long-dashed-lines.ref.png b/test/reference/long-dashed-lines.ref.png
new file mode 100644
index 000000000..9c7208c18
--- /dev/null
+++ b/test/reference/long-dashed-lines.ref.png
Binary files differ
diff --git a/test/reference/long-dashed-lines.traps.argb32.ref.png b/test/reference/long-dashed-lines.traps.argb32.ref.png
new file mode 100644
index 000000000..ccd3d5df1
--- /dev/null
+++ b/test/reference/long-dashed-lines.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/long-dashed-lines.traps.rgb24.ref.png b/test/reference/long-dashed-lines.traps.rgb24.ref.png
new file mode 100644
index 000000000..ccd3d5df1
--- /dev/null
+++ b/test/reference/long-dashed-lines.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/long-lines.base.argb32.ref.png b/test/reference/long-lines.base.argb32.ref.png
new file mode 100644
index 000000000..fe9116312
--- /dev/null
+++ b/test/reference/long-lines.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/long-lines.base.rgb24.ref.png b/test/reference/long-lines.base.rgb24.ref.png
new file mode 100644
index 000000000..fe9116312
--- /dev/null
+++ b/test/reference/long-lines.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/long-lines.mask.argb32.ref.png b/test/reference/long-lines.mask.argb32.ref.png
new file mode 100644
index 000000000..fe9116312
--- /dev/null
+++ b/test/reference/long-lines.mask.argb32.ref.png
Binary files differ
diff --git a/test/reference/long-lines.mask.rgb24.ref.png b/test/reference/long-lines.mask.rgb24.ref.png
new file mode 100644
index 000000000..fe9116312
--- /dev/null
+++ b/test/reference/long-lines.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/long-lines.traps.argb32.ref.png b/test/reference/long-lines.traps.argb32.ref.png
new file mode 100644
index 000000000..fe9116312
--- /dev/null
+++ b/test/reference/long-lines.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/long-lines.traps.rgb24.ref.png b/test/reference/long-lines.traps.rgb24.ref.png
new file mode 100644
index 000000000..fe9116312
--- /dev/null
+++ b/test/reference/long-lines.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/map-all-to-image.base.argb32.ref.png b/test/reference/map-all-to-image.base.argb32.ref.png
new file mode 100644
index 000000000..c56d9698d
--- /dev/null
+++ b/test/reference/map-all-to-image.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/map-all-to-image.base.rgb24.ref.png b/test/reference/map-all-to-image.base.rgb24.ref.png
new file mode 100644
index 000000000..c56d9698d
--- /dev/null
+++ b/test/reference/map-all-to-image.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/map-all-to-image.ref.png b/test/reference/map-all-to-image.ref.png
new file mode 100644
index 000000000..c56d9698d
--- /dev/null
+++ b/test/reference/map-all-to-image.ref.png
Binary files differ
diff --git a/test/reference/map-all-to-xlib-fallback.rgb24.ref.png b/test/reference/map-all-to-xlib-fallback.rgb24.ref.png
new file mode 100644
index 000000000..c56d9698d
--- /dev/null
+++ b/test/reference/map-all-to-xlib-fallback.rgb24.ref.png
Binary files differ
diff --git a/test/reference/map-all-to-xlib-window.rgb24.ref.png b/test/reference/map-all-to-xlib-window.rgb24.ref.png
new file mode 100644
index 000000000..c56d9698d
--- /dev/null
+++ b/test/reference/map-all-to-xlib-window.rgb24.ref.png
Binary files differ
diff --git a/test/reference/map-all-to-xlib.ref.png b/test/reference/map-all-to-xlib.ref.png
new file mode 100644
index 000000000..c56d9698d
--- /dev/null
+++ b/test/reference/map-all-to-xlib.ref.png
Binary files differ
diff --git a/test/reference/map-bit-to-image.base.argb32.ref.png b/test/reference/map-bit-to-image.base.argb32.ref.png
new file mode 100644
index 000000000..b42dcb62a
--- /dev/null
+++ b/test/reference/map-bit-to-image.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/map-bit-to-image.base.rgb24.ref.png b/test/reference/map-bit-to-image.base.rgb24.ref.png
new file mode 100644
index 000000000..b42dcb62a
--- /dev/null
+++ b/test/reference/map-bit-to-image.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/map-bit-to-image.ref.png b/test/reference/map-bit-to-image.ref.png
new file mode 100644
index 000000000..b42dcb62a
--- /dev/null
+++ b/test/reference/map-bit-to-image.ref.png
Binary files differ
diff --git a/test/reference/map-bit-to-xlib-fallback.rgb24.ref.png b/test/reference/map-bit-to-xlib-fallback.rgb24.ref.png
new file mode 100644
index 000000000..b42dcb62a
--- /dev/null
+++ b/test/reference/map-bit-to-xlib-fallback.rgb24.ref.png
Binary files differ
diff --git a/test/reference/map-bit-to-xlib-window.rgb24.ref.png b/test/reference/map-bit-to-xlib-window.rgb24.ref.png
new file mode 100644
index 000000000..b42dcb62a
--- /dev/null
+++ b/test/reference/map-bit-to-xlib-window.rgb24.ref.png
Binary files differ
diff --git a/test/reference/map-bit-to-xlib.ref.png b/test/reference/map-bit-to-xlib.ref.png
new file mode 100644
index 000000000..b42dcb62a
--- /dev/null
+++ b/test/reference/map-bit-to-xlib.ref.png
Binary files differ
diff --git a/test/reference/map-to-image-fill.base.argb32.ref.png b/test/reference/map-to-image-fill.base.argb32.ref.png
new file mode 100644
index 000000000..c2893e0de
--- /dev/null
+++ b/test/reference/map-to-image-fill.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/map-to-image-fill.base.rgb24.ref.png b/test/reference/map-to-image-fill.base.rgb24.ref.png
new file mode 100644
index 000000000..c2893e0de
--- /dev/null
+++ b/test/reference/map-to-image-fill.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/map-to-image-fill.ref.png b/test/reference/map-to-image-fill.ref.png
new file mode 100644
index 000000000..c2893e0de
--- /dev/null
+++ b/test/reference/map-to-image-fill.ref.png
Binary files differ
diff --git a/test/reference/mask-alpha.argb32.ref.png b/test/reference/mask-alpha.argb32.ref.png
new file mode 100644
index 000000000..90717f0cc
--- /dev/null
+++ b/test/reference/mask-alpha.argb32.ref.png
Binary files differ
diff --git a/test/reference/mask-alpha.base.argb32.ref.png b/test/reference/mask-alpha.base.argb32.ref.png
new file mode 100644
index 000000000..a0b9017e0
--- /dev/null
+++ b/test/reference/mask-alpha.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/mask-alpha.base.rgb24.ref.png b/test/reference/mask-alpha.base.rgb24.ref.png
new file mode 100644
index 000000000..d8f4b8f81
--- /dev/null
+++ b/test/reference/mask-alpha.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/mask-alpha.image16.ref.png b/test/reference/mask-alpha.image16.ref.png
new file mode 100644
index 000000000..dbf121a4b
--- /dev/null
+++ b/test/reference/mask-alpha.image16.ref.png
Binary files differ
diff --git a/test/reference/mask-alpha.ps.ref.png b/test/reference/mask-alpha.ps.ref.png
new file mode 100644
index 000000000..b0058dd47
--- /dev/null
+++ b/test/reference/mask-alpha.ps.ref.png
Binary files differ
diff --git a/test/reference/mask-alpha.quartz.argb32.ref.png b/test/reference/mask-alpha.quartz.argb32.ref.png
new file mode 100644
index 000000000..1d530ee17
--- /dev/null
+++ b/test/reference/mask-alpha.quartz.argb32.ref.png
Binary files differ
diff --git a/test/reference/mask-alpha.rgb24.ref.png b/test/reference/mask-alpha.rgb24.ref.png
new file mode 100644
index 000000000..9999b8a4f
--- /dev/null
+++ b/test/reference/mask-alpha.rgb24.ref.png
Binary files differ
diff --git a/test/reference/mask-alpha.svg.rgb24.xfail.png b/test/reference/mask-alpha.svg.rgb24.xfail.png
new file mode 100644
index 000000000..15ebf7559
--- /dev/null
+++ b/test/reference/mask-alpha.svg.rgb24.xfail.png
Binary files differ
diff --git a/test/reference/mask-alpha.traps.argb32.ref.png b/test/reference/mask-alpha.traps.argb32.ref.png
new file mode 100644
index 000000000..a0b9017e0
--- /dev/null
+++ b/test/reference/mask-alpha.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/mask-alpha.traps.rgb24.ref.png b/test/reference/mask-alpha.traps.rgb24.ref.png
new file mode 100644
index 000000000..d8f4b8f81
--- /dev/null
+++ b/test/reference/mask-alpha.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/mask-ctm.base.argb32.ref.png b/test/reference/mask-ctm.base.argb32.ref.png
new file mode 100644
index 000000000..07d903d15
--- /dev/null
+++ b/test/reference/mask-ctm.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/mask-ctm.base.rgb24.ref.png b/test/reference/mask-ctm.base.rgb24.ref.png
new file mode 100644
index 000000000..de3fa097f
--- /dev/null
+++ b/test/reference/mask-ctm.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/mask-ctm.ref.png b/test/reference/mask-ctm.ref.png
new file mode 100644
index 000000000..88a0402ca
--- /dev/null
+++ b/test/reference/mask-ctm.ref.png
Binary files differ
diff --git a/test/reference/mask-glyphs.gl.ref.png b/test/reference/mask-glyphs.gl.ref.png
new file mode 100644
index 000000000..d3410976f
--- /dev/null
+++ b/test/reference/mask-glyphs.gl.ref.png
Binary files differ
diff --git a/test/reference/mask-glyphs.image16.ref.png b/test/reference/mask-glyphs.image16.ref.png
new file mode 100644
index 000000000..177e79560
--- /dev/null
+++ b/test/reference/mask-glyphs.image16.ref.png
Binary files differ
diff --git a/test/reference/mask-glyphs.pdf.ref.png b/test/reference/mask-glyphs.pdf.ref.png
new file mode 100644
index 000000000..673ef92d8
--- /dev/null
+++ b/test/reference/mask-glyphs.pdf.ref.png
Binary files differ
diff --git a/test/reference/mask-glyphs.ref.png b/test/reference/mask-glyphs.ref.png
new file mode 100644
index 000000000..5beda0dbe
--- /dev/null
+++ b/test/reference/mask-glyphs.ref.png
Binary files differ
diff --git a/test/reference/mask-glyphs.svg.ref.png b/test/reference/mask-glyphs.svg.ref.png
new file mode 100644
index 000000000..bbc44f207
--- /dev/null
+++ b/test/reference/mask-glyphs.svg.ref.png
Binary files differ
diff --git a/test/reference/mask-surface-ctm.base.argb32.ref.png b/test/reference/mask-surface-ctm.base.argb32.ref.png
new file mode 100644
index 000000000..07d903d15
--- /dev/null
+++ b/test/reference/mask-surface-ctm.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/mask-surface-ctm.base.rgb24.ref.png b/test/reference/mask-surface-ctm.base.rgb24.ref.png
new file mode 100644
index 000000000..de3fa097f
--- /dev/null
+++ b/test/reference/mask-surface-ctm.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/mask-surface-ctm.ref.png b/test/reference/mask-surface-ctm.ref.png
new file mode 100644
index 000000000..744b1dd37
--- /dev/null
+++ b/test/reference/mask-surface-ctm.ref.png
Binary files differ
diff --git a/test/reference/mask-transformed-image.base.argb32.ref.png b/test/reference/mask-transformed-image.base.argb32.ref.png
new file mode 100644
index 000000000..af84b39d3
--- /dev/null
+++ b/test/reference/mask-transformed-image.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/mask-transformed-image.base.rgb24.ref.png b/test/reference/mask-transformed-image.base.rgb24.ref.png
new file mode 100644
index 000000000..af84b39d3
--- /dev/null
+++ b/test/reference/mask-transformed-image.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/mask-transformed-image.image16.ref.png b/test/reference/mask-transformed-image.image16.ref.png
new file mode 100644
index 000000000..9e196eff1
--- /dev/null
+++ b/test/reference/mask-transformed-image.image16.ref.png
Binary files differ
diff --git a/test/reference/mask-transformed-image.pdf.ref.png b/test/reference/mask-transformed-image.pdf.ref.png
new file mode 100644
index 000000000..33ec27997
--- /dev/null
+++ b/test/reference/mask-transformed-image.pdf.ref.png
Binary files differ
diff --git a/test/reference/mask-transformed-image.quartz.ref.png b/test/reference/mask-transformed-image.quartz.ref.png
new file mode 100644
index 000000000..58ac57558
--- /dev/null
+++ b/test/reference/mask-transformed-image.quartz.ref.png
Binary files differ
diff --git a/test/reference/mask-transformed-image.ref.png b/test/reference/mask-transformed-image.ref.png
new file mode 100644
index 000000000..af84b39d3
--- /dev/null
+++ b/test/reference/mask-transformed-image.ref.png
Binary files differ
diff --git a/test/reference/mask-transformed-similar.base.argb32.ref.png b/test/reference/mask-transformed-similar.base.argb32.ref.png
new file mode 100644
index 000000000..af84b39d3
--- /dev/null
+++ b/test/reference/mask-transformed-similar.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/mask-transformed-similar.base.rgb24.ref.png b/test/reference/mask-transformed-similar.base.rgb24.ref.png
new file mode 100644
index 000000000..af84b39d3
--- /dev/null
+++ b/test/reference/mask-transformed-similar.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/mask-transformed-similar.image16.ref.png b/test/reference/mask-transformed-similar.image16.ref.png
new file mode 100644
index 000000000..9e196eff1
--- /dev/null
+++ b/test/reference/mask-transformed-similar.image16.ref.png
Binary files differ
diff --git a/test/reference/mask-transformed-similar.pdf.ref.png b/test/reference/mask-transformed-similar.pdf.ref.png
new file mode 100644
index 000000000..e8d387903
--- /dev/null
+++ b/test/reference/mask-transformed-similar.pdf.ref.png
Binary files differ
diff --git a/test/reference/mask-transformed-similar.quartz.ref.png b/test/reference/mask-transformed-similar.quartz.ref.png
new file mode 100644
index 000000000..58ac57558
--- /dev/null
+++ b/test/reference/mask-transformed-similar.quartz.ref.png
Binary files differ
diff --git a/test/reference/mask-transformed-similar.recording.ref.png b/test/reference/mask-transformed-similar.recording.ref.png
new file mode 100644
index 000000000..33ec27997
--- /dev/null
+++ b/test/reference/mask-transformed-similar.recording.ref.png
Binary files differ
diff --git a/test/reference/mask-transformed-similar.ref.png b/test/reference/mask-transformed-similar.ref.png
new file mode 100644
index 000000000..af84b39d3
--- /dev/null
+++ b/test/reference/mask-transformed-similar.ref.png
Binary files differ
diff --git a/test/reference/mask-transformed-similar.svg.ref.png b/test/reference/mask-transformed-similar.svg.ref.png
new file mode 100644
index 000000000..a5b9b00b9
--- /dev/null
+++ b/test/reference/mask-transformed-similar.svg.ref.png
Binary files differ
diff --git a/test/reference/mask-transformed-xlib-fallback.rgb24.ref.png b/test/reference/mask-transformed-xlib-fallback.rgb24.ref.png
new file mode 100644
index 000000000..09eb43ae7
--- /dev/null
+++ b/test/reference/mask-transformed-xlib-fallback.rgb24.ref.png
Binary files differ
diff --git a/test/reference/mask-transformed-xlib-window.rgb24.ref.png b/test/reference/mask-transformed-xlib-window.rgb24.ref.png
new file mode 100644
index 000000000..09eb43ae7
--- /dev/null
+++ b/test/reference/mask-transformed-xlib-window.rgb24.ref.png
Binary files differ
diff --git a/test/reference/mask-transformed-xlib.ref.png b/test/reference/mask-transformed-xlib.ref.png
new file mode 100644
index 000000000..09eb43ae7
--- /dev/null
+++ b/test/reference/mask-transformed-xlib.ref.png
Binary files differ
diff --git a/test/reference/mask.argb32.ref.png b/test/reference/mask.argb32.ref.png
new file mode 100644
index 000000000..a4c683ccc
--- /dev/null
+++ b/test/reference/mask.argb32.ref.png
Binary files differ
diff --git a/test/reference/mask.base.argb32.ref.png b/test/reference/mask.base.argb32.ref.png
new file mode 100644
index 000000000..7ee6b4536
--- /dev/null
+++ b/test/reference/mask.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/mask.base.rgb24.ref.png b/test/reference/mask.base.rgb24.ref.png
new file mode 100644
index 000000000..b0ceb3522
--- /dev/null
+++ b/test/reference/mask.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/mask.image16.ref.png b/test/reference/mask.image16.ref.png
new file mode 100644
index 000000000..4ab52de26
--- /dev/null
+++ b/test/reference/mask.image16.ref.png
Binary files differ
diff --git a/test/reference/mask.pdf.argb32.ref.png b/test/reference/mask.pdf.argb32.ref.png
new file mode 100644
index 000000000..33769ee16
--- /dev/null
+++ b/test/reference/mask.pdf.argb32.ref.png
Binary files differ
diff --git a/test/reference/mask.pdf.rgb24.ref.png b/test/reference/mask.pdf.rgb24.ref.png
new file mode 100644
index 000000000..dbd49a816
--- /dev/null
+++ b/test/reference/mask.pdf.rgb24.ref.png
Binary files differ
diff --git a/test/reference/mask.quartz.argb32.ref.png b/test/reference/mask.quartz.argb32.ref.png
new file mode 100644
index 000000000..c7ab76e82
--- /dev/null
+++ b/test/reference/mask.quartz.argb32.ref.png
Binary files differ
diff --git a/test/reference/mask.quartz.rgb24.ref.png b/test/reference/mask.quartz.rgb24.ref.png
new file mode 100644
index 000000000..f475ba933
--- /dev/null
+++ b/test/reference/mask.quartz.rgb24.ref.png
Binary files differ
diff --git a/test/reference/mask.rgb24.ref.png b/test/reference/mask.rgb24.ref.png
new file mode 100644
index 000000000..1bd18334f
--- /dev/null
+++ b/test/reference/mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/mask.svg.argb32.xfail.png b/test/reference/mask.svg.argb32.xfail.png
new file mode 100644
index 000000000..867248004
--- /dev/null
+++ b/test/reference/mask.svg.argb32.xfail.png
Binary files differ
diff --git a/test/reference/mask.svg.rgb24.xfail.png b/test/reference/mask.svg.rgb24.xfail.png
new file mode 100644
index 000000000..743a758e6
--- /dev/null
+++ b/test/reference/mask.svg.rgb24.xfail.png
Binary files differ
diff --git a/test/reference/mask.traps.argb32.ref.png b/test/reference/mask.traps.argb32.ref.png
new file mode 100644
index 000000000..3286ce6b7
--- /dev/null
+++ b/test/reference/mask.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/mask.traps.rgb24.ref.png b/test/reference/mask.traps.rgb24.ref.png
new file mode 100644
index 000000000..edcabaf91
--- /dev/null
+++ b/test/reference/mask.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/mesh-pattern-accuracy.base.argb32.ref.png b/test/reference/mesh-pattern-accuracy.base.argb32.ref.png
new file mode 100644
index 000000000..dfc19ff4f
--- /dev/null
+++ b/test/reference/mesh-pattern-accuracy.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/mesh-pattern-accuracy.base.rgb24.ref.png b/test/reference/mesh-pattern-accuracy.base.rgb24.ref.png
new file mode 100644
index 000000000..dfc19ff4f
--- /dev/null
+++ b/test/reference/mesh-pattern-accuracy.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/mesh-pattern-accuracy.image16.ref.png b/test/reference/mesh-pattern-accuracy.image16.ref.png
new file mode 100644
index 000000000..a82e4fbeb
--- /dev/null
+++ b/test/reference/mesh-pattern-accuracy.image16.ref.png
Binary files differ
diff --git a/test/reference/mesh-pattern-accuracy.ref.png b/test/reference/mesh-pattern-accuracy.ref.png
new file mode 100644
index 000000000..dfc19ff4f
--- /dev/null
+++ b/test/reference/mesh-pattern-accuracy.ref.png
Binary files differ
diff --git a/test/reference/mesh-pattern-conical.base.argb32.ref.png b/test/reference/mesh-pattern-conical.base.argb32.ref.png
new file mode 100644
index 000000000..f5dc21dc8
--- /dev/null
+++ b/test/reference/mesh-pattern-conical.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/mesh-pattern-conical.base.rgb24.ref.png b/test/reference/mesh-pattern-conical.base.rgb24.ref.png
new file mode 100644
index 000000000..f5dc21dc8
--- /dev/null
+++ b/test/reference/mesh-pattern-conical.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/mesh-pattern-conical.image16.ref.png b/test/reference/mesh-pattern-conical.image16.ref.png
new file mode 100644
index 000000000..b8f9416ea
--- /dev/null
+++ b/test/reference/mesh-pattern-conical.image16.ref.png
Binary files differ
diff --git a/test/reference/mesh-pattern-conical.ref.png b/test/reference/mesh-pattern-conical.ref.png
new file mode 100644
index 000000000..f5dc21dc8
--- /dev/null
+++ b/test/reference/mesh-pattern-conical.ref.png
Binary files differ
diff --git a/test/reference/mesh-pattern-control-points.base.argb32.ref.png b/test/reference/mesh-pattern-control-points.base.argb32.ref.png
new file mode 100644
index 000000000..841fc3ef9
--- /dev/null
+++ b/test/reference/mesh-pattern-control-points.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/mesh-pattern-control-points.base.rgb24.ref.png b/test/reference/mesh-pattern-control-points.base.rgb24.ref.png
new file mode 100644
index 000000000..841fc3ef9
--- /dev/null
+++ b/test/reference/mesh-pattern-control-points.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/mesh-pattern-control-points.image16.ref.png b/test/reference/mesh-pattern-control-points.image16.ref.png
new file mode 100644
index 000000000..b664ef90d
--- /dev/null
+++ b/test/reference/mesh-pattern-control-points.image16.ref.png
Binary files differ
diff --git a/test/reference/mesh-pattern-control-points.ref.png b/test/reference/mesh-pattern-control-points.ref.png
new file mode 100644
index 000000000..841fc3ef9
--- /dev/null
+++ b/test/reference/mesh-pattern-control-points.ref.png
Binary files differ
diff --git a/test/reference/mesh-pattern-fold.base.argb32.ref.png b/test/reference/mesh-pattern-fold.base.argb32.ref.png
new file mode 100644
index 000000000..6275b82d8
--- /dev/null
+++ b/test/reference/mesh-pattern-fold.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/mesh-pattern-fold.base.rgb24.ref.png b/test/reference/mesh-pattern-fold.base.rgb24.ref.png
new file mode 100644
index 000000000..6275b82d8
--- /dev/null
+++ b/test/reference/mesh-pattern-fold.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/mesh-pattern-fold.image16.ref.png b/test/reference/mesh-pattern-fold.image16.ref.png
new file mode 100644
index 000000000..4264ad2c7
--- /dev/null
+++ b/test/reference/mesh-pattern-fold.image16.ref.png
Binary files differ
diff --git a/test/reference/mesh-pattern-fold.ref.png b/test/reference/mesh-pattern-fold.ref.png
new file mode 100644
index 000000000..6275b82d8
--- /dev/null
+++ b/test/reference/mesh-pattern-fold.ref.png
Binary files differ
diff --git a/test/reference/mesh-pattern-overlap.base.argb32.ref.png b/test/reference/mesh-pattern-overlap.base.argb32.ref.png
new file mode 100644
index 000000000..1394c9ec5
--- /dev/null
+++ b/test/reference/mesh-pattern-overlap.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/mesh-pattern-overlap.base.rgb24.ref.png b/test/reference/mesh-pattern-overlap.base.rgb24.ref.png
new file mode 100644
index 000000000..1394c9ec5
--- /dev/null
+++ b/test/reference/mesh-pattern-overlap.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/mesh-pattern-overlap.image16.ref.png b/test/reference/mesh-pattern-overlap.image16.ref.png
new file mode 100644
index 000000000..a67f7ddec
--- /dev/null
+++ b/test/reference/mesh-pattern-overlap.image16.ref.png
Binary files differ
diff --git a/test/reference/mesh-pattern-overlap.ref.png b/test/reference/mesh-pattern-overlap.ref.png
new file mode 100644
index 000000000..1394c9ec5
--- /dev/null
+++ b/test/reference/mesh-pattern-overlap.ref.png
Binary files differ
diff --git a/test/reference/mesh-pattern-transformed.base.argb32.ref.png b/test/reference/mesh-pattern-transformed.base.argb32.ref.png
new file mode 100644
index 000000000..9aa482f52
--- /dev/null
+++ b/test/reference/mesh-pattern-transformed.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/mesh-pattern-transformed.base.rgb24.ref.png b/test/reference/mesh-pattern-transformed.base.rgb24.ref.png
new file mode 100644
index 000000000..9aa482f52
--- /dev/null
+++ b/test/reference/mesh-pattern-transformed.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/mesh-pattern-transformed.image16.ref.png b/test/reference/mesh-pattern-transformed.image16.ref.png
new file mode 100644
index 000000000..0645b861e
--- /dev/null
+++ b/test/reference/mesh-pattern-transformed.image16.ref.png
Binary files differ
diff --git a/test/reference/mesh-pattern-transformed.ref.png b/test/reference/mesh-pattern-transformed.ref.png
new file mode 100644
index 000000000..9aa482f52
--- /dev/null
+++ b/test/reference/mesh-pattern-transformed.ref.png
Binary files differ
diff --git a/test/reference/mesh-pattern.base.argb32.ref.png b/test/reference/mesh-pattern.base.argb32.ref.png
new file mode 100644
index 000000000..1f76639f0
--- /dev/null
+++ b/test/reference/mesh-pattern.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/mesh-pattern.base.rgb24.ref.png b/test/reference/mesh-pattern.base.rgb24.ref.png
new file mode 100644
index 000000000..1f76639f0
--- /dev/null
+++ b/test/reference/mesh-pattern.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/mesh-pattern.image16.ref.png b/test/reference/mesh-pattern.image16.ref.png
new file mode 100644
index 000000000..bd6353842
--- /dev/null
+++ b/test/reference/mesh-pattern.image16.ref.png
Binary files differ
diff --git a/test/reference/mesh-pattern.ref.png b/test/reference/mesh-pattern.ref.png
new file mode 100644
index 000000000..1f76639f0
--- /dev/null
+++ b/test/reference/mesh-pattern.ref.png
Binary files differ
diff --git a/test/reference/mime-data.base.argb32.ref.png b/test/reference/mime-data.base.argb32.ref.png
new file mode 100644
index 000000000..4bc007c8a
--- /dev/null
+++ b/test/reference/mime-data.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/mime-data.base.rgb24.ref.png b/test/reference/mime-data.base.rgb24.ref.png
new file mode 100644
index 000000000..4bc007c8a
--- /dev/null
+++ b/test/reference/mime-data.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/mime-data.pdf.ref.png b/test/reference/mime-data.pdf.ref.png
new file mode 100644
index 000000000..76c17f8de
--- /dev/null
+++ b/test/reference/mime-data.pdf.ref.png
Binary files differ
diff --git a/test/reference/mime-data.ps.ref.png b/test/reference/mime-data.ps.ref.png
new file mode 100644
index 000000000..7ec7d9b2c
--- /dev/null
+++ b/test/reference/mime-data.ps.ref.png
Binary files differ
diff --git a/test/reference/mime-data.ref.png b/test/reference/mime-data.ref.png
new file mode 100644
index 000000000..4bc007c8a
--- /dev/null
+++ b/test/reference/mime-data.ref.png
Binary files differ
diff --git a/test/reference/mime-data.script.ref.png b/test/reference/mime-data.script.ref.png
new file mode 100644
index 000000000..07691b101
--- /dev/null
+++ b/test/reference/mime-data.script.ref.png
Binary files differ
diff --git a/test/reference/mime-data.svg.ref.png b/test/reference/mime-data.svg.ref.png
new file mode 100644
index 000000000..a4bbb1b6c
--- /dev/null
+++ b/test/reference/mime-data.svg.ref.png
Binary files differ
diff --git a/test/reference/miter-precision.base.argb32.ref.png b/test/reference/miter-precision.base.argb32.ref.png
new file mode 100644
index 000000000..b881dd4ad
--- /dev/null
+++ b/test/reference/miter-precision.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/miter-precision.base.rgb24.ref.png b/test/reference/miter-precision.base.rgb24.ref.png
new file mode 100644
index 000000000..b881dd4ad
--- /dev/null
+++ b/test/reference/miter-precision.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/miter-precision.ps2.ref.png b/test/reference/miter-precision.ps2.ref.png
new file mode 100644
index 000000000..c2b69ad6a
--- /dev/null
+++ b/test/reference/miter-precision.ps2.ref.png
Binary files differ
diff --git a/test/reference/miter-precision.ps3.ref.png b/test/reference/miter-precision.ps3.ref.png
new file mode 100644
index 000000000..c2b69ad6a
--- /dev/null
+++ b/test/reference/miter-precision.ps3.ref.png
Binary files differ
diff --git a/test/reference/miter-precision.ref.png b/test/reference/miter-precision.ref.png
new file mode 100644
index 000000000..a2c333e41
--- /dev/null
+++ b/test/reference/miter-precision.ref.png
Binary files differ
diff --git a/test/reference/miter-precision.traps.argb32.ref.png b/test/reference/miter-precision.traps.argb32.ref.png
new file mode 100644
index 000000000..b881dd4ad
--- /dev/null
+++ b/test/reference/miter-precision.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/miter-precision.traps.rgb24.ref.png b/test/reference/miter-precision.traps.rgb24.ref.png
new file mode 100644
index 000000000..b881dd4ad
--- /dev/null
+++ b/test/reference/miter-precision.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/move-to-show-surface.base.argb32.ref.png b/test/reference/move-to-show-surface.base.argb32.ref.png
new file mode 100644
index 000000000..0a145d918
--- /dev/null
+++ b/test/reference/move-to-show-surface.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/move-to-show-surface.base.rgb24.ref.png b/test/reference/move-to-show-surface.base.rgb24.ref.png
new file mode 100644
index 000000000..0a145d918
--- /dev/null
+++ b/test/reference/move-to-show-surface.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/move-to-show-surface.ref.png b/test/reference/move-to-show-surface.ref.png
new file mode 100644
index 000000000..765adc4a4
--- /dev/null
+++ b/test/reference/move-to-show-surface.ref.png
Binary files differ
diff --git a/test/reference/negative-stride-image.base.argb32.ref.png b/test/reference/negative-stride-image.base.argb32.ref.png
new file mode 100644
index 000000000..44284566e
--- /dev/null
+++ b/test/reference/negative-stride-image.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/negative-stride-image.base.rgb24.ref.png b/test/reference/negative-stride-image.base.rgb24.ref.png
new file mode 100644
index 000000000..44284566e
--- /dev/null
+++ b/test/reference/negative-stride-image.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/negative-stride-image.image16.ref.png b/test/reference/negative-stride-image.image16.ref.png
new file mode 100644
index 000000000..4b15914f2
--- /dev/null
+++ b/test/reference/negative-stride-image.image16.ref.png
Binary files differ
diff --git a/test/reference/negative-stride-image.ps.ref.png b/test/reference/negative-stride-image.ps.ref.png
new file mode 100644
index 000000000..953c9a18e
--- /dev/null
+++ b/test/reference/negative-stride-image.ps.ref.png
Binary files differ
diff --git a/test/reference/negative-stride-image.ref.png b/test/reference/negative-stride-image.ref.png
new file mode 100644
index 000000000..44284566e
--- /dev/null
+++ b/test/reference/negative-stride-image.ref.png
Binary files differ
diff --git a/test/reference/new-sub-path.base.argb32.ref.png b/test/reference/new-sub-path.base.argb32.ref.png
new file mode 100644
index 000000000..13e067550
--- /dev/null
+++ b/test/reference/new-sub-path.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/new-sub-path.base.rgb24.ref.png b/test/reference/new-sub-path.base.rgb24.ref.png
new file mode 100644
index 000000000..b69e4abec
--- /dev/null
+++ b/test/reference/new-sub-path.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/new-sub-path.pdf.argb32.ref.png b/test/reference/new-sub-path.pdf.argb32.ref.png
new file mode 100644
index 000000000..41fe1314e
--- /dev/null
+++ b/test/reference/new-sub-path.pdf.argb32.ref.png
Binary files differ
diff --git a/test/reference/new-sub-path.ps2.argb32.ref.png b/test/reference/new-sub-path.ps2.argb32.ref.png
new file mode 100644
index 000000000..45253dbee
--- /dev/null
+++ b/test/reference/new-sub-path.ps2.argb32.ref.png
Binary files differ
diff --git a/test/reference/new-sub-path.ps2.rgb24.ref.png b/test/reference/new-sub-path.ps2.rgb24.ref.png
new file mode 100644
index 000000000..bceb5b75a
--- /dev/null
+++ b/test/reference/new-sub-path.ps2.rgb24.ref.png
Binary files differ
diff --git a/test/reference/new-sub-path.ps3.argb32.ref.png b/test/reference/new-sub-path.ps3.argb32.ref.png
new file mode 100644
index 000000000..45253dbee
--- /dev/null
+++ b/test/reference/new-sub-path.ps3.argb32.ref.png
Binary files differ
diff --git a/test/reference/new-sub-path.ps3.rgb24.ref.png b/test/reference/new-sub-path.ps3.rgb24.ref.png
new file mode 100644
index 000000000..bceb5b75a
--- /dev/null
+++ b/test/reference/new-sub-path.ps3.rgb24.ref.png
Binary files differ
diff --git a/test/reference/new-sub-path.quartz.ref.png b/test/reference/new-sub-path.quartz.ref.png
new file mode 100644
index 000000000..20d49ba33
--- /dev/null
+++ b/test/reference/new-sub-path.quartz.ref.png
Binary files differ
diff --git a/test/reference/new-sub-path.ref.png b/test/reference/new-sub-path.ref.png
new file mode 100644
index 000000000..87a6c91c5
--- /dev/null
+++ b/test/reference/new-sub-path.ref.png
Binary files differ
diff --git a/test/reference/new-sub-path.traps.argb32.ref.png b/test/reference/new-sub-path.traps.argb32.ref.png
new file mode 100644
index 000000000..13e067550
--- /dev/null
+++ b/test/reference/new-sub-path.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/new-sub-path.traps.rgb24.ref.png b/test/reference/new-sub-path.traps.rgb24.ref.png
new file mode 100644
index 000000000..b69e4abec
--- /dev/null
+++ b/test/reference/new-sub-path.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/nil-surface.base.argb32.ref.png b/test/reference/nil-surface.base.argb32.ref.png
new file mode 100644
index 000000000..50e35a246
--- /dev/null
+++ b/test/reference/nil-surface.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/nil-surface.base.rgb24.ref.png b/test/reference/nil-surface.base.rgb24.ref.png
new file mode 100644
index 000000000..7d5589c1d
--- /dev/null
+++ b/test/reference/nil-surface.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/nil-surface.ref.png b/test/reference/nil-surface.ref.png
new file mode 100644
index 000000000..79dd2bc1d
--- /dev/null
+++ b/test/reference/nil-surface.ref.png
Binary files differ
diff --git a/test/reference/operator-alpha-alpha.base.argb32.ref.png b/test/reference/operator-alpha-alpha.base.argb32.ref.png
new file mode 100644
index 000000000..fc173cb18
--- /dev/null
+++ b/test/reference/operator-alpha-alpha.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/operator-alpha-alpha.base.rgb24.ref.png b/test/reference/operator-alpha-alpha.base.rgb24.ref.png
new file mode 100644
index 000000000..fc173cb18
--- /dev/null
+++ b/test/reference/operator-alpha-alpha.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/operator-alpha-alpha.image16.ref.png b/test/reference/operator-alpha-alpha.image16.ref.png
new file mode 100644
index 000000000..31eba5f75
--- /dev/null
+++ b/test/reference/operator-alpha-alpha.image16.ref.png
Binary files differ
diff --git a/test/reference/operator-alpha-alpha.pdf.xfail.png b/test/reference/operator-alpha-alpha.pdf.xfail.png
new file mode 100644
index 000000000..0a06685e6
--- /dev/null
+++ b/test/reference/operator-alpha-alpha.pdf.xfail.png
Binary files differ
diff --git a/test/reference/operator-alpha-alpha.ps.xfail.png b/test/reference/operator-alpha-alpha.ps.xfail.png
new file mode 100644
index 000000000..e7c4fea2d
--- /dev/null
+++ b/test/reference/operator-alpha-alpha.ps.xfail.png
Binary files differ
diff --git a/test/reference/operator-alpha-alpha.ref.png b/test/reference/operator-alpha-alpha.ref.png
new file mode 100644
index 000000000..695d0d012
--- /dev/null
+++ b/test/reference/operator-alpha-alpha.ref.png
Binary files differ
diff --git a/test/reference/operator-alpha-alpha.svg.xfail.png b/test/reference/operator-alpha-alpha.svg.xfail.png
new file mode 100644
index 000000000..c7dc8cbd3
--- /dev/null
+++ b/test/reference/operator-alpha-alpha.svg.xfail.png
Binary files differ
diff --git a/test/reference/operator-alpha-alpha.traps.argb32.ref.png b/test/reference/operator-alpha-alpha.traps.argb32.ref.png
new file mode 100644
index 000000000..fc173cb18
--- /dev/null
+++ b/test/reference/operator-alpha-alpha.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/operator-alpha-alpha.traps.rgb24.ref.png b/test/reference/operator-alpha-alpha.traps.rgb24.ref.png
new file mode 100644
index 000000000..fc173cb18
--- /dev/null
+++ b/test/reference/operator-alpha-alpha.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/operator-alpha.argb32.ref.png b/test/reference/operator-alpha.argb32.ref.png
new file mode 100644
index 000000000..b4f3b71f0
--- /dev/null
+++ b/test/reference/operator-alpha.argb32.ref.png
Binary files differ
diff --git a/test/reference/operator-alpha.base.argb32.ref.png b/test/reference/operator-alpha.base.argb32.ref.png
new file mode 100644
index 000000000..b4f3b71f0
--- /dev/null
+++ b/test/reference/operator-alpha.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/operator-alpha.base.rgb24.ref.png b/test/reference/operator-alpha.base.rgb24.ref.png
new file mode 100644
index 000000000..bc7be3aeb
--- /dev/null
+++ b/test/reference/operator-alpha.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/operator-alpha.rgb24.ref.png b/test/reference/operator-alpha.rgb24.ref.png
new file mode 100644
index 000000000..bc7be3aeb
--- /dev/null
+++ b/test/reference/operator-alpha.rgb24.ref.png
Binary files differ
diff --git a/test/reference/operator-alpha.svg12.argb32.xfail.png b/test/reference/operator-alpha.svg12.argb32.xfail.png
new file mode 100644
index 000000000..e821d206f
--- /dev/null
+++ b/test/reference/operator-alpha.svg12.argb32.xfail.png
Binary files differ
diff --git a/test/reference/operator-alpha.svg12.rgb24.xfail.png b/test/reference/operator-alpha.svg12.rgb24.xfail.png
new file mode 100644
index 000000000..42d9ddee9
--- /dev/null
+++ b/test/reference/operator-alpha.svg12.rgb24.xfail.png
Binary files differ
diff --git a/test/reference/operator-clear.argb32.ref.png b/test/reference/operator-clear.argb32.ref.png
new file mode 100644
index 000000000..2ce556e7c
--- /dev/null
+++ b/test/reference/operator-clear.argb32.ref.png
Binary files differ
diff --git a/test/reference/operator-clear.base.argb32.ref.png b/test/reference/operator-clear.base.argb32.ref.png
new file mode 100644
index 000000000..c49b4a8d6
--- /dev/null
+++ b/test/reference/operator-clear.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/operator-clear.base.rgb24.ref.png b/test/reference/operator-clear.base.rgb24.ref.png
new file mode 100644
index 000000000..51d38d134
--- /dev/null
+++ b/test/reference/operator-clear.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/operator-clear.mask.rgb24.ref.png b/test/reference/operator-clear.mask.rgb24.ref.png
new file mode 100644
index 000000000..3d58ab341
--- /dev/null
+++ b/test/reference/operator-clear.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/operator-clear.ps2.argb32.ref.png b/test/reference/operator-clear.ps2.argb32.ref.png
new file mode 100644
index 000000000..92b41111f
--- /dev/null
+++ b/test/reference/operator-clear.ps2.argb32.ref.png
Binary files differ
diff --git a/test/reference/operator-clear.ps3.argb32.ref.png b/test/reference/operator-clear.ps3.argb32.ref.png
new file mode 100644
index 000000000..92b41111f
--- /dev/null
+++ b/test/reference/operator-clear.ps3.argb32.ref.png
Binary files differ
diff --git a/test/reference/operator-clear.quartz.argb32.ref.png b/test/reference/operator-clear.quartz.argb32.ref.png
new file mode 100644
index 000000000..caf265e75
--- /dev/null
+++ b/test/reference/operator-clear.quartz.argb32.ref.png
Binary files differ
diff --git a/test/reference/operator-clear.quartz.rgb24.ref.png b/test/reference/operator-clear.quartz.rgb24.ref.png
new file mode 100644
index 000000000..a07a6e0af
--- /dev/null
+++ b/test/reference/operator-clear.quartz.rgb24.ref.png
Binary files differ
diff --git a/test/reference/operator-clear.rgb24.ref.png b/test/reference/operator-clear.rgb24.ref.png
new file mode 100644
index 000000000..533b49aa0
--- /dev/null
+++ b/test/reference/operator-clear.rgb24.ref.png
Binary files differ
diff --git a/test/reference/operator-clear.svg12.argb32.xfail.png b/test/reference/operator-clear.svg12.argb32.xfail.png
new file mode 100644
index 000000000..7dfbd28fa
--- /dev/null
+++ b/test/reference/operator-clear.svg12.argb32.xfail.png
Binary files differ
diff --git a/test/reference/operator-clear.svg12.rgb24.xfail.png b/test/reference/operator-clear.svg12.rgb24.xfail.png
new file mode 100644
index 000000000..c561bc36c
--- /dev/null
+++ b/test/reference/operator-clear.svg12.rgb24.xfail.png
Binary files differ
diff --git a/test/reference/operator-clear.traps.argb32.ref.png b/test/reference/operator-clear.traps.argb32.ref.png
new file mode 100644
index 000000000..c49b4a8d6
--- /dev/null
+++ b/test/reference/operator-clear.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/operator-clear.traps.rgb24.ref.png b/test/reference/operator-clear.traps.rgb24.ref.png
new file mode 100644
index 000000000..51d38d134
--- /dev/null
+++ b/test/reference/operator-clear.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/operator-source.argb32.ref.png b/test/reference/operator-source.argb32.ref.png
new file mode 100644
index 000000000..5fd5c43b8
--- /dev/null
+++ b/test/reference/operator-source.argb32.ref.png
Binary files differ
diff --git a/test/reference/operator-source.base.argb32.ref.png b/test/reference/operator-source.base.argb32.ref.png
new file mode 100644
index 000000000..42e24f24c
--- /dev/null
+++ b/test/reference/operator-source.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/operator-source.base.rgb24.ref.png b/test/reference/operator-source.base.rgb24.ref.png
new file mode 100644
index 000000000..4736d5852
--- /dev/null
+++ b/test/reference/operator-source.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/operator-source.image16.ref.png b/test/reference/operator-source.image16.ref.png
new file mode 100644
index 000000000..45562603c
--- /dev/null
+++ b/test/reference/operator-source.image16.ref.png
Binary files differ
diff --git a/test/reference/operator-source.mask.argb32.ref.png b/test/reference/operator-source.mask.argb32.ref.png
new file mode 100644
index 000000000..74ad1dad6
--- /dev/null
+++ b/test/reference/operator-source.mask.argb32.ref.png
Binary files differ
diff --git a/test/reference/operator-source.mask.rgb24.ref.png b/test/reference/operator-source.mask.rgb24.ref.png
new file mode 100644
index 000000000..c0033562b
--- /dev/null
+++ b/test/reference/operator-source.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/operator-source.rgb24.ref.png b/test/reference/operator-source.rgb24.ref.png
new file mode 100644
index 000000000..c7846e5a7
--- /dev/null
+++ b/test/reference/operator-source.rgb24.ref.png
Binary files differ
diff --git a/test/reference/operator-source.traps.argb32.ref.png b/test/reference/operator-source.traps.argb32.ref.png
new file mode 100644
index 000000000..42e24f24c
--- /dev/null
+++ b/test/reference/operator-source.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/operator-source.traps.rgb24.ref.png b/test/reference/operator-source.traps.rgb24.ref.png
new file mode 100644
index 000000000..4736d5852
--- /dev/null
+++ b/test/reference/operator-source.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/operator-source.xlib-fallback.ref.png b/test/reference/operator-source.xlib-fallback.ref.png
new file mode 100644
index 000000000..4527ce715
--- /dev/null
+++ b/test/reference/operator-source.xlib-fallback.ref.png
Binary files differ
diff --git a/test/reference/operator.argb32.ref.png b/test/reference/operator.argb32.ref.png
new file mode 100644
index 000000000..34fce987b
--- /dev/null
+++ b/test/reference/operator.argb32.ref.png
Binary files differ
diff --git a/test/reference/operator.base.argb32.ref.png b/test/reference/operator.base.argb32.ref.png
new file mode 100644
index 000000000..34fce987b
--- /dev/null
+++ b/test/reference/operator.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/operator.base.rgb24.ref.png b/test/reference/operator.base.rgb24.ref.png
new file mode 100644
index 000000000..aa6103df8
--- /dev/null
+++ b/test/reference/operator.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/operator.rgb24.ref.png b/test/reference/operator.rgb24.ref.png
new file mode 100644
index 000000000..aa6103df8
--- /dev/null
+++ b/test/reference/operator.rgb24.ref.png
Binary files differ
diff --git a/test/reference/operator.svg12.argb32.xfail.png b/test/reference/operator.svg12.argb32.xfail.png
new file mode 100644
index 000000000..3996221e7
--- /dev/null
+++ b/test/reference/operator.svg12.argb32.xfail.png
Binary files differ
diff --git a/test/reference/operator.svg12.rgb24.xfail.png b/test/reference/operator.svg12.rgb24.xfail.png
new file mode 100644
index 000000000..198d4b1c9
--- /dev/null
+++ b/test/reference/operator.svg12.rgb24.xfail.png
Binary files differ
diff --git a/test/reference/outline-tolerance.ref.png b/test/reference/outline-tolerance.ref.png
new file mode 100644
index 000000000..2733836c9
--- /dev/null
+++ b/test/reference/outline-tolerance.ref.png
Binary files differ
diff --git a/test/reference/over-above-source.argb32.ref.png b/test/reference/over-above-source.argb32.ref.png
new file mode 100644
index 000000000..479437fa8
--- /dev/null
+++ b/test/reference/over-above-source.argb32.ref.png
Binary files differ
diff --git a/test/reference/over-above-source.base.argb32.ref.png b/test/reference/over-above-source.base.argb32.ref.png
new file mode 100644
index 000000000..8a0183a6e
--- /dev/null
+++ b/test/reference/over-above-source.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/over-above-source.base.rgb24.ref.png b/test/reference/over-above-source.base.rgb24.ref.png
new file mode 100644
index 000000000..85c19971d
--- /dev/null
+++ b/test/reference/over-above-source.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/over-above-source.ps2.argb32.ref.png b/test/reference/over-above-source.ps2.argb32.ref.png
new file mode 100644
index 000000000..7c90d0867
--- /dev/null
+++ b/test/reference/over-above-source.ps2.argb32.ref.png
Binary files differ
diff --git a/test/reference/over-above-source.ps3.argb32.ref.png b/test/reference/over-above-source.ps3.argb32.ref.png
new file mode 100644
index 000000000..7c90d0867
--- /dev/null
+++ b/test/reference/over-above-source.ps3.argb32.ref.png
Binary files differ
diff --git a/test/reference/over-above-source.quartz.argb32.ref.png b/test/reference/over-above-source.quartz.argb32.ref.png
new file mode 100644
index 000000000..eeb3622b6
--- /dev/null
+++ b/test/reference/over-above-source.quartz.argb32.ref.png
Binary files differ
diff --git a/test/reference/over-above-source.quartz.rgb24.ref.png b/test/reference/over-above-source.quartz.rgb24.ref.png
new file mode 100644
index 000000000..2ab347653
--- /dev/null
+++ b/test/reference/over-above-source.quartz.rgb24.ref.png
Binary files differ
diff --git a/test/reference/over-above-source.rgb24.ref.png b/test/reference/over-above-source.rgb24.ref.png
new file mode 100644
index 000000000..6fc2f5248
--- /dev/null
+++ b/test/reference/over-above-source.rgb24.ref.png
Binary files differ
diff --git a/test/reference/over-above-source.svg12.rgb24.xfail.png b/test/reference/over-above-source.svg12.rgb24.xfail.png
new file mode 100644
index 000000000..b2939c24b
--- /dev/null
+++ b/test/reference/over-above-source.svg12.rgb24.xfail.png
Binary files differ
diff --git a/test/reference/over-above-source.traps.argb32.ref.png b/test/reference/over-above-source.traps.argb32.ref.png
new file mode 100644
index 000000000..8a0183a6e
--- /dev/null
+++ b/test/reference/over-above-source.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/over-above-source.traps.rgb24.ref.png b/test/reference/over-above-source.traps.rgb24.ref.png
new file mode 100644
index 000000000..85c19971d
--- /dev/null
+++ b/test/reference/over-above-source.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/over-around-source.argb32.ref.png b/test/reference/over-around-source.argb32.ref.png
new file mode 100644
index 000000000..abc81c771
--- /dev/null
+++ b/test/reference/over-around-source.argb32.ref.png
Binary files differ
diff --git a/test/reference/over-around-source.base.argb32.ref.png b/test/reference/over-around-source.base.argb32.ref.png
new file mode 100644
index 000000000..fca75056d
--- /dev/null
+++ b/test/reference/over-around-source.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/over-around-source.base.rgb24.ref.png b/test/reference/over-around-source.base.rgb24.ref.png
new file mode 100644
index 000000000..e8dd91d6e
--- /dev/null
+++ b/test/reference/over-around-source.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/over-around-source.image16.ref.png b/test/reference/over-around-source.image16.ref.png
new file mode 100644
index 000000000..f571b7d1d
--- /dev/null
+++ b/test/reference/over-around-source.image16.ref.png
Binary files differ
diff --git a/test/reference/over-around-source.pdf.argb32.ref.png b/test/reference/over-around-source.pdf.argb32.ref.png
new file mode 100644
index 000000000..da700af73
--- /dev/null
+++ b/test/reference/over-around-source.pdf.argb32.ref.png
Binary files differ
diff --git a/test/reference/over-around-source.ps2.argb32.ref.png b/test/reference/over-around-source.ps2.argb32.ref.png
new file mode 100644
index 000000000..43917597d
--- /dev/null
+++ b/test/reference/over-around-source.ps2.argb32.ref.png
Binary files differ
diff --git a/test/reference/over-around-source.ps2.rgb24.ref.png b/test/reference/over-around-source.ps2.rgb24.ref.png
new file mode 100644
index 000000000..ee325eab3
--- /dev/null
+++ b/test/reference/over-around-source.ps2.rgb24.ref.png
Binary files differ
diff --git a/test/reference/over-around-source.ps3.argb32.ref.png b/test/reference/over-around-source.ps3.argb32.ref.png
new file mode 100644
index 000000000..43917597d
--- /dev/null
+++ b/test/reference/over-around-source.ps3.argb32.ref.png
Binary files differ
diff --git a/test/reference/over-around-source.ps3.rgb24.ref.png b/test/reference/over-around-source.ps3.rgb24.ref.png
new file mode 100644
index 000000000..ee325eab3
--- /dev/null
+++ b/test/reference/over-around-source.ps3.rgb24.ref.png
Binary files differ
diff --git a/test/reference/over-around-source.quartz.argb32.ref.png b/test/reference/over-around-source.quartz.argb32.ref.png
new file mode 100644
index 000000000..26ab8e5cd
--- /dev/null
+++ b/test/reference/over-around-source.quartz.argb32.ref.png
Binary files differ
diff --git a/test/reference/over-around-source.rgb24.ref.png b/test/reference/over-around-source.rgb24.ref.png
new file mode 100644
index 000000000..41ade9574
--- /dev/null
+++ b/test/reference/over-around-source.rgb24.ref.png
Binary files differ
diff --git a/test/reference/over-around-source.svg12.argb32.xfail.png b/test/reference/over-around-source.svg12.argb32.xfail.png
new file mode 100644
index 000000000..bb29538d1
--- /dev/null
+++ b/test/reference/over-around-source.svg12.argb32.xfail.png
Binary files differ
diff --git a/test/reference/over-around-source.svg12.rgb24.xfail.png b/test/reference/over-around-source.svg12.rgb24.xfail.png
new file mode 100644
index 000000000..bb29538d1
--- /dev/null
+++ b/test/reference/over-around-source.svg12.rgb24.xfail.png
Binary files differ
diff --git a/test/reference/over-around-source.traps.argb32.ref.png b/test/reference/over-around-source.traps.argb32.ref.png
new file mode 100644
index 000000000..fca75056d
--- /dev/null
+++ b/test/reference/over-around-source.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/over-around-source.traps.rgb24.ref.png b/test/reference/over-around-source.traps.rgb24.ref.png
new file mode 100644
index 000000000..e8dd91d6e
--- /dev/null
+++ b/test/reference/over-around-source.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/over-below-source.argb32.ref.png b/test/reference/over-below-source.argb32.ref.png
new file mode 100644
index 000000000..519160967
--- /dev/null
+++ b/test/reference/over-below-source.argb32.ref.png
Binary files differ
diff --git a/test/reference/over-below-source.base.argb32.ref.png b/test/reference/over-below-source.base.argb32.ref.png
new file mode 100644
index 000000000..c65936323
--- /dev/null
+++ b/test/reference/over-below-source.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/over-below-source.base.rgb24.ref.png b/test/reference/over-below-source.base.rgb24.ref.png
new file mode 100644
index 000000000..88a85acbb
--- /dev/null
+++ b/test/reference/over-below-source.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/over-below-source.pdf.argb32.ref.png b/test/reference/over-below-source.pdf.argb32.ref.png
new file mode 100644
index 000000000..b9c4fe283
--- /dev/null
+++ b/test/reference/over-below-source.pdf.argb32.ref.png
Binary files differ
diff --git a/test/reference/over-below-source.ps2.argb32.ref.png b/test/reference/over-below-source.ps2.argb32.ref.png
new file mode 100644
index 000000000..c05bda540
--- /dev/null
+++ b/test/reference/over-below-source.ps2.argb32.ref.png
Binary files differ
diff --git a/test/reference/over-below-source.ps2.rgb24.ref.png b/test/reference/over-below-source.ps2.rgb24.ref.png
new file mode 100644
index 000000000..07e10d464
--- /dev/null
+++ b/test/reference/over-below-source.ps2.rgb24.ref.png
Binary files differ
diff --git a/test/reference/over-below-source.ps3.argb32.ref.png b/test/reference/over-below-source.ps3.argb32.ref.png
new file mode 100644
index 000000000..c05bda540
--- /dev/null
+++ b/test/reference/over-below-source.ps3.argb32.ref.png
Binary files differ
diff --git a/test/reference/over-below-source.ps3.rgb24.ref.png b/test/reference/over-below-source.ps3.rgb24.ref.png
new file mode 100644
index 000000000..07e10d464
--- /dev/null
+++ b/test/reference/over-below-source.ps3.rgb24.ref.png
Binary files differ
diff --git a/test/reference/over-below-source.rgb24.ref.png b/test/reference/over-below-source.rgb24.ref.png
new file mode 100644
index 000000000..20ee671fa
--- /dev/null
+++ b/test/reference/over-below-source.rgb24.ref.png
Binary files differ
diff --git a/test/reference/over-below-source.svg12.argb32.xfail.png b/test/reference/over-below-source.svg12.argb32.xfail.png
new file mode 100644
index 000000000..c80705b7e
--- /dev/null
+++ b/test/reference/over-below-source.svg12.argb32.xfail.png
Binary files differ
diff --git a/test/reference/over-below-source.svg12.rgb24.xfail.png b/test/reference/over-below-source.svg12.rgb24.xfail.png
new file mode 100644
index 000000000..c80705b7e
--- /dev/null
+++ b/test/reference/over-below-source.svg12.rgb24.xfail.png
Binary files differ
diff --git a/test/reference/over-below-source.traps.argb32.ref.png b/test/reference/over-below-source.traps.argb32.ref.png
new file mode 100644
index 000000000..c65936323
--- /dev/null
+++ b/test/reference/over-below-source.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/over-below-source.traps.rgb24.ref.png b/test/reference/over-below-source.traps.rgb24.ref.png
new file mode 100644
index 000000000..88a85acbb
--- /dev/null
+++ b/test/reference/over-below-source.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/over-between-source.argb32.ref.png b/test/reference/over-between-source.argb32.ref.png
new file mode 100644
index 000000000..9ba86f0e4
--- /dev/null
+++ b/test/reference/over-between-source.argb32.ref.png
Binary files differ
diff --git a/test/reference/over-between-source.base.argb32.ref.png b/test/reference/over-between-source.base.argb32.ref.png
new file mode 100644
index 000000000..a8fe66a30
--- /dev/null
+++ b/test/reference/over-between-source.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/over-between-source.base.rgb24.ref.png b/test/reference/over-between-source.base.rgb24.ref.png
new file mode 100644
index 000000000..bb77a9b97
--- /dev/null
+++ b/test/reference/over-between-source.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/over-between-source.ps2.argb32.ref.png b/test/reference/over-between-source.ps2.argb32.ref.png
new file mode 100644
index 000000000..dd95940ae
--- /dev/null
+++ b/test/reference/over-between-source.ps2.argb32.ref.png
Binary files differ
diff --git a/test/reference/over-between-source.ps3.argb32.ref.png b/test/reference/over-between-source.ps3.argb32.ref.png
new file mode 100644
index 000000000..dd95940ae
--- /dev/null
+++ b/test/reference/over-between-source.ps3.argb32.ref.png
Binary files differ
diff --git a/test/reference/over-between-source.quartz.argb32.ref.png b/test/reference/over-between-source.quartz.argb32.ref.png
new file mode 100644
index 000000000..adb17aee4
--- /dev/null
+++ b/test/reference/over-between-source.quartz.argb32.ref.png
Binary files differ
diff --git a/test/reference/over-between-source.rgb24.ref.png b/test/reference/over-between-source.rgb24.ref.png
new file mode 100644
index 000000000..b0d31e6f7
--- /dev/null
+++ b/test/reference/over-between-source.rgb24.ref.png
Binary files differ
diff --git a/test/reference/over-between-source.svg12.argb32.xfail.png b/test/reference/over-between-source.svg12.argb32.xfail.png
new file mode 100644
index 000000000..c80705b7e
--- /dev/null
+++ b/test/reference/over-between-source.svg12.argb32.xfail.png
Binary files differ
diff --git a/test/reference/over-between-source.svg12.rgb24.xfail.png b/test/reference/over-between-source.svg12.rgb24.xfail.png
new file mode 100644
index 000000000..c80705b7e
--- /dev/null
+++ b/test/reference/over-between-source.svg12.rgb24.xfail.png
Binary files differ
diff --git a/test/reference/over-between-source.traps.argb32.ref.png b/test/reference/over-between-source.traps.argb32.ref.png
new file mode 100644
index 000000000..a8fe66a30
--- /dev/null
+++ b/test/reference/over-between-source.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/over-between-source.traps.rgb24.ref.png b/test/reference/over-between-source.traps.rgb24.ref.png
new file mode 100644
index 000000000..bb77a9b97
--- /dev/null
+++ b/test/reference/over-between-source.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/overlapping-boxes.base.argb32.ref.png b/test/reference/overlapping-boxes.base.argb32.ref.png
new file mode 100644
index 000000000..278e62a84
--- /dev/null
+++ b/test/reference/overlapping-boxes.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/overlapping-boxes.base.rgb24.ref.png b/test/reference/overlapping-boxes.base.rgb24.ref.png
new file mode 100644
index 000000000..f35d0e6b3
--- /dev/null
+++ b/test/reference/overlapping-boxes.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/overlapping-boxes.ref.png b/test/reference/overlapping-boxes.ref.png
new file mode 100644
index 000000000..1c684381f
--- /dev/null
+++ b/test/reference/overlapping-boxes.ref.png
Binary files differ
diff --git a/test/reference/overlapping-boxes.traps.argb32.ref.png b/test/reference/overlapping-boxes.traps.argb32.ref.png
new file mode 100644
index 000000000..278e62a84
--- /dev/null
+++ b/test/reference/overlapping-boxes.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/overlapping-boxes.traps.rgb24.ref.png b/test/reference/overlapping-boxes.traps.rgb24.ref.png
new file mode 100644
index 000000000..f35d0e6b3
--- /dev/null
+++ b/test/reference/overlapping-boxes.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/overlapping-dash-caps.base.argb32.ref.png b/test/reference/overlapping-dash-caps.base.argb32.ref.png
new file mode 100644
index 000000000..849a5163f
--- /dev/null
+++ b/test/reference/overlapping-dash-caps.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/overlapping-dash-caps.base.rgb24.ref.png b/test/reference/overlapping-dash-caps.base.rgb24.ref.png
new file mode 100644
index 000000000..849a5163f
--- /dev/null
+++ b/test/reference/overlapping-dash-caps.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/overlapping-dash-caps.mask.argb32.ref.png b/test/reference/overlapping-dash-caps.mask.argb32.ref.png
new file mode 100644
index 000000000..367d68357
--- /dev/null
+++ b/test/reference/overlapping-dash-caps.mask.argb32.ref.png
Binary files differ
diff --git a/test/reference/overlapping-dash-caps.mask.rgb24.ref.png b/test/reference/overlapping-dash-caps.mask.rgb24.ref.png
new file mode 100644
index 000000000..367d68357
--- /dev/null
+++ b/test/reference/overlapping-dash-caps.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/overlapping-dash-caps.ref.png b/test/reference/overlapping-dash-caps.ref.png
new file mode 100644
index 000000000..1a2abf738
--- /dev/null
+++ b/test/reference/overlapping-dash-caps.ref.png
Binary files differ
diff --git a/test/reference/overlapping-dash-caps.traps.argb32.ref.png b/test/reference/overlapping-dash-caps.traps.argb32.ref.png
new file mode 100644
index 000000000..849a5163f
--- /dev/null
+++ b/test/reference/overlapping-dash-caps.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/overlapping-dash-caps.traps.rgb24.ref.png b/test/reference/overlapping-dash-caps.traps.rgb24.ref.png
new file mode 100644
index 000000000..849a5163f
--- /dev/null
+++ b/test/reference/overlapping-dash-caps.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/overlapping-glyphs.base.argb32.ref.png b/test/reference/overlapping-glyphs.base.argb32.ref.png
new file mode 100644
index 000000000..11bf4e111
--- /dev/null
+++ b/test/reference/overlapping-glyphs.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/overlapping-glyphs.base.rgb24.ref.png b/test/reference/overlapping-glyphs.base.rgb24.ref.png
new file mode 100644
index 000000000..6b6551044
--- /dev/null
+++ b/test/reference/overlapping-glyphs.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/overlapping-glyphs.pdf.argb32.xfail.png b/test/reference/overlapping-glyphs.pdf.argb32.xfail.png
new file mode 100644
index 000000000..e3e433727
--- /dev/null
+++ b/test/reference/overlapping-glyphs.pdf.argb32.xfail.png
Binary files differ
diff --git a/test/reference/overlapping-glyphs.pdf.rgb24.xfail.png b/test/reference/overlapping-glyphs.pdf.rgb24.xfail.png
new file mode 100644
index 000000000..a3f1d7047
--- /dev/null
+++ b/test/reference/overlapping-glyphs.pdf.rgb24.xfail.png
Binary files differ
diff --git a/test/reference/overlapping-glyphs.quartz.argb32.ref.png b/test/reference/overlapping-glyphs.quartz.argb32.ref.png
new file mode 100644
index 000000000..eaa0cb9c6
--- /dev/null
+++ b/test/reference/overlapping-glyphs.quartz.argb32.ref.png
Binary files differ
diff --git a/test/reference/overlapping-glyphs.quartz.rgb24.ref.png b/test/reference/overlapping-glyphs.quartz.rgb24.ref.png
new file mode 100644
index 000000000..c2b5fc0ab
--- /dev/null
+++ b/test/reference/overlapping-glyphs.quartz.rgb24.ref.png
Binary files differ
diff --git a/test/reference/overlapping-glyphs.ref.png b/test/reference/overlapping-glyphs.ref.png
new file mode 100644
index 000000000..4ec4ee541
--- /dev/null
+++ b/test/reference/overlapping-glyphs.ref.png
Binary files differ
diff --git a/test/reference/overlapping-glyphs.svg.argb32.ref.png b/test/reference/overlapping-glyphs.svg.argb32.ref.png
new file mode 100644
index 000000000..ce3849967
--- /dev/null
+++ b/test/reference/overlapping-glyphs.svg.argb32.ref.png
Binary files differ
diff --git a/test/reference/overlapping-glyphs.svg.rgb24.ref.png b/test/reference/overlapping-glyphs.svg.rgb24.ref.png
new file mode 100644
index 000000000..ce3849967
--- /dev/null
+++ b/test/reference/overlapping-glyphs.svg.rgb24.ref.png
Binary files differ
diff --git a/test/reference/overlapping-glyphs.traps.argb32.ref.png b/test/reference/overlapping-glyphs.traps.argb32.ref.png
new file mode 100644
index 000000000..11bf4e111
--- /dev/null
+++ b/test/reference/overlapping-glyphs.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/overlapping-glyphs.traps.rgb24.ref.png b/test/reference/overlapping-glyphs.traps.rgb24.ref.png
new file mode 100644
index 000000000..6b6551044
--- /dev/null
+++ b/test/reference/overlapping-glyphs.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/paint-clip-fill-aa.base.argb32.ref.png b/test/reference/paint-clip-fill-aa.base.argb32.ref.png
new file mode 100644
index 000000000..768322a39
--- /dev/null
+++ b/test/reference/paint-clip-fill-aa.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/paint-clip-fill-aa.base.rgb24.ref.png b/test/reference/paint-clip-fill-aa.base.rgb24.ref.png
new file mode 100644
index 000000000..768322a39
--- /dev/null
+++ b/test/reference/paint-clip-fill-aa.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/paint-clip-fill-aa.ref.png b/test/reference/paint-clip-fill-aa.ref.png
new file mode 100644
index 000000000..a8cf417b3
--- /dev/null
+++ b/test/reference/paint-clip-fill-aa.ref.png
Binary files differ
diff --git a/test/reference/paint-clip-fill-mono.base.argb32.ref.png b/test/reference/paint-clip-fill-mono.base.argb32.ref.png
new file mode 100644
index 000000000..768322a39
--- /dev/null
+++ b/test/reference/paint-clip-fill-mono.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/paint-clip-fill-mono.base.rgb24.ref.png b/test/reference/paint-clip-fill-mono.base.rgb24.ref.png
new file mode 100644
index 000000000..768322a39
--- /dev/null
+++ b/test/reference/paint-clip-fill-mono.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/paint-clip-fill-mono.ref.png b/test/reference/paint-clip-fill-mono.ref.png
new file mode 100644
index 000000000..a8cf417b3
--- /dev/null
+++ b/test/reference/paint-clip-fill-mono.ref.png
Binary files differ
diff --git a/test/reference/paint-repeat.base.argb32.ref.png b/test/reference/paint-repeat.base.argb32.ref.png
new file mode 100644
index 000000000..8cdd9b4be
--- /dev/null
+++ b/test/reference/paint-repeat.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/paint-repeat.base.rgb24.ref.png b/test/reference/paint-repeat.base.rgb24.ref.png
new file mode 100644
index 000000000..8cdd9b4be
--- /dev/null
+++ b/test/reference/paint-repeat.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/paint-repeat.ref.png b/test/reference/paint-repeat.ref.png
new file mode 100644
index 000000000..2cc48f336
--- /dev/null
+++ b/test/reference/paint-repeat.ref.png
Binary files differ
diff --git a/test/reference/paint-source-alpha.base.argb32.ref.png b/test/reference/paint-source-alpha.base.argb32.ref.png
new file mode 100644
index 000000000..65d9c179b
--- /dev/null
+++ b/test/reference/paint-source-alpha.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/paint-source-alpha.base.rgb24.ref.png b/test/reference/paint-source-alpha.base.rgb24.ref.png
new file mode 100644
index 000000000..65d9c179b
--- /dev/null
+++ b/test/reference/paint-source-alpha.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/paint-source-alpha.image16.ref.png b/test/reference/paint-source-alpha.image16.ref.png
new file mode 100644
index 000000000..12bd89d55
--- /dev/null
+++ b/test/reference/paint-source-alpha.image16.ref.png
Binary files differ
diff --git a/test/reference/paint-source-alpha.ref.png b/test/reference/paint-source-alpha.ref.png
new file mode 100644
index 000000000..548bcd7f3
--- /dev/null
+++ b/test/reference/paint-source-alpha.ref.png
Binary files differ
diff --git a/test/reference/paint-source-alpha.svg.ref.png b/test/reference/paint-source-alpha.svg.ref.png
new file mode 100644
index 000000000..763bb592b
--- /dev/null
+++ b/test/reference/paint-source-alpha.svg.ref.png
Binary files differ
diff --git a/test/reference/paint-with-alpha-clip-mask.base.argb32.ref.png b/test/reference/paint-with-alpha-clip-mask.base.argb32.ref.png
new file mode 100644
index 000000000..95746ffcb
--- /dev/null
+++ b/test/reference/paint-with-alpha-clip-mask.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/paint-with-alpha-clip-mask.base.rgb24.ref.png b/test/reference/paint-with-alpha-clip-mask.base.rgb24.ref.png
new file mode 100644
index 000000000..95746ffcb
--- /dev/null
+++ b/test/reference/paint-with-alpha-clip-mask.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/paint-with-alpha-clip-mask.mask.argb32.ref.png b/test/reference/paint-with-alpha-clip-mask.mask.argb32.ref.png
new file mode 100644
index 000000000..95746ffcb
--- /dev/null
+++ b/test/reference/paint-with-alpha-clip-mask.mask.argb32.ref.png
Binary files differ
diff --git a/test/reference/paint-with-alpha-clip-mask.mask.rgb24.ref.png b/test/reference/paint-with-alpha-clip-mask.mask.rgb24.ref.png
new file mode 100644
index 000000000..95746ffcb
--- /dev/null
+++ b/test/reference/paint-with-alpha-clip-mask.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/paint-with-alpha-clip-mask.ref.png b/test/reference/paint-with-alpha-clip-mask.ref.png
new file mode 100644
index 000000000..4ee4c41ac
--- /dev/null
+++ b/test/reference/paint-with-alpha-clip-mask.ref.png
Binary files differ
diff --git a/test/reference/paint-with-alpha-clip-mask.traps.argb32.ref.png b/test/reference/paint-with-alpha-clip-mask.traps.argb32.ref.png
new file mode 100644
index 000000000..201bd0d55
--- /dev/null
+++ b/test/reference/paint-with-alpha-clip-mask.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/paint-with-alpha-clip-mask.traps.rgb24.ref.png b/test/reference/paint-with-alpha-clip-mask.traps.rgb24.ref.png
new file mode 100644
index 000000000..201bd0d55
--- /dev/null
+++ b/test/reference/paint-with-alpha-clip-mask.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/paint-with-alpha-clip.base.argb32.ref.png b/test/reference/paint-with-alpha-clip.base.argb32.ref.png
new file mode 100644
index 000000000..c1da67e01
--- /dev/null
+++ b/test/reference/paint-with-alpha-clip.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/paint-with-alpha-clip.base.rgb24.ref.png b/test/reference/paint-with-alpha-clip.base.rgb24.ref.png
new file mode 100644
index 000000000..c1da67e01
--- /dev/null
+++ b/test/reference/paint-with-alpha-clip.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/paint-with-alpha-clip.mask.argb32.ref.png b/test/reference/paint-with-alpha-clip.mask.argb32.ref.png
new file mode 100644
index 000000000..c1da67e01
--- /dev/null
+++ b/test/reference/paint-with-alpha-clip.mask.argb32.ref.png
Binary files differ
diff --git a/test/reference/paint-with-alpha-clip.mask.rgb24.ref.png b/test/reference/paint-with-alpha-clip.mask.rgb24.ref.png
new file mode 100644
index 000000000..c1da67e01
--- /dev/null
+++ b/test/reference/paint-with-alpha-clip.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/paint-with-alpha-clip.ref.png b/test/reference/paint-with-alpha-clip.ref.png
new file mode 100644
index 000000000..4bad4e8ca
--- /dev/null
+++ b/test/reference/paint-with-alpha-clip.ref.png
Binary files differ
diff --git a/test/reference/paint-with-alpha-clip.traps.argb32.ref.png b/test/reference/paint-with-alpha-clip.traps.argb32.ref.png
new file mode 100644
index 000000000..c1da67e01
--- /dev/null
+++ b/test/reference/paint-with-alpha-clip.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/paint-with-alpha-clip.traps.rgb24.ref.png b/test/reference/paint-with-alpha-clip.traps.rgb24.ref.png
new file mode 100644
index 000000000..c1da67e01
--- /dev/null
+++ b/test/reference/paint-with-alpha-clip.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/paint-with-alpha-group-clip.ref.png b/test/reference/paint-with-alpha-group-clip.ref.png
new file mode 100644
index 000000000..e2dfb063a
--- /dev/null
+++ b/test/reference/paint-with-alpha-group-clip.ref.png
Binary files differ
diff --git a/test/reference/paint-with-alpha-solid-clip.base.argb32.ref.png b/test/reference/paint-with-alpha-solid-clip.base.argb32.ref.png
new file mode 100644
index 000000000..59d226d1a
--- /dev/null
+++ b/test/reference/paint-with-alpha-solid-clip.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/paint-with-alpha-solid-clip.base.rgb24.ref.png b/test/reference/paint-with-alpha-solid-clip.base.rgb24.ref.png
new file mode 100644
index 000000000..59d226d1a
--- /dev/null
+++ b/test/reference/paint-with-alpha-solid-clip.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/paint-with-alpha-solid-clip.mask.argb32.ref.png b/test/reference/paint-with-alpha-solid-clip.mask.argb32.ref.png
new file mode 100644
index 000000000..2cd2df21c
--- /dev/null
+++ b/test/reference/paint-with-alpha-solid-clip.mask.argb32.ref.png
Binary files differ
diff --git a/test/reference/paint-with-alpha-solid-clip.mask.rgb24.ref.png b/test/reference/paint-with-alpha-solid-clip.mask.rgb24.ref.png
new file mode 100644
index 000000000..2cd2df21c
--- /dev/null
+++ b/test/reference/paint-with-alpha-solid-clip.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/paint-with-alpha-solid-clip.ref.png b/test/reference/paint-with-alpha-solid-clip.ref.png
new file mode 100644
index 000000000..59d226d1a
--- /dev/null
+++ b/test/reference/paint-with-alpha-solid-clip.ref.png
Binary files differ
diff --git a/test/reference/paint-with-alpha-solid-clip.traps.argb32.ref.png b/test/reference/paint-with-alpha-solid-clip.traps.argb32.ref.png
new file mode 100644
index 000000000..2cd2df21c
--- /dev/null
+++ b/test/reference/paint-with-alpha-solid-clip.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/paint-with-alpha-solid-clip.traps.rgb24.ref.png b/test/reference/paint-with-alpha-solid-clip.traps.rgb24.ref.png
new file mode 100644
index 000000000..2cd2df21c
--- /dev/null
+++ b/test/reference/paint-with-alpha-solid-clip.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/paint-with-alpha.base.argb32.ref.png b/test/reference/paint-with-alpha.base.argb32.ref.png
new file mode 100644
index 000000000..65d9c179b
--- /dev/null
+++ b/test/reference/paint-with-alpha.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/paint-with-alpha.base.rgb24.ref.png b/test/reference/paint-with-alpha.base.rgb24.ref.png
new file mode 100644
index 000000000..65d9c179b
--- /dev/null
+++ b/test/reference/paint-with-alpha.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/paint-with-alpha.image16.ref.png b/test/reference/paint-with-alpha.image16.ref.png
new file mode 100644
index 000000000..12bd89d55
--- /dev/null
+++ b/test/reference/paint-with-alpha.image16.ref.png
Binary files differ
diff --git a/test/reference/paint-with-alpha.ref.png b/test/reference/paint-with-alpha.ref.png
new file mode 100644
index 000000000..ab7ce3e04
--- /dev/null
+++ b/test/reference/paint-with-alpha.ref.png
Binary files differ
diff --git a/test/reference/paint-with-alpha.svg.ref.png b/test/reference/paint-with-alpha.svg.ref.png
new file mode 100644
index 000000000..c0df8eb72
--- /dev/null
+++ b/test/reference/paint-with-alpha.svg.ref.png
Binary files differ
diff --git a/test/reference/paint.base.argb32.ref.png b/test/reference/paint.base.argb32.ref.png
new file mode 100644
index 000000000..22cc7a1ae
--- /dev/null
+++ b/test/reference/paint.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/paint.base.rgb24.ref.png b/test/reference/paint.base.rgb24.ref.png
new file mode 100644
index 000000000..22cc7a1ae
--- /dev/null
+++ b/test/reference/paint.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/paint.ref.png b/test/reference/paint.ref.png
new file mode 100644
index 000000000..fff03b363
--- /dev/null
+++ b/test/reference/paint.ref.png
Binary files differ
diff --git a/test/reference/partial-clip-text-bottom.base.argb32.ref.png b/test/reference/partial-clip-text-bottom.base.argb32.ref.png
new file mode 100644
index 000000000..6a299d48c
--- /dev/null
+++ b/test/reference/partial-clip-text-bottom.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/partial-clip-text-bottom.base.rgb24.ref.png b/test/reference/partial-clip-text-bottom.base.rgb24.ref.png
new file mode 100644
index 000000000..6a299d48c
--- /dev/null
+++ b/test/reference/partial-clip-text-bottom.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/partial-clip-text-bottom.ref.png b/test/reference/partial-clip-text-bottom.ref.png
new file mode 100644
index 000000000..6a299d48c
--- /dev/null
+++ b/test/reference/partial-clip-text-bottom.ref.png
Binary files differ
diff --git a/test/reference/partial-clip-text-left.base.argb32.ref.png b/test/reference/partial-clip-text-left.base.argb32.ref.png
new file mode 100644
index 000000000..54a1a8586
--- /dev/null
+++ b/test/reference/partial-clip-text-left.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/partial-clip-text-left.base.rgb24.ref.png b/test/reference/partial-clip-text-left.base.rgb24.ref.png
new file mode 100644
index 000000000..54a1a8586
--- /dev/null
+++ b/test/reference/partial-clip-text-left.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/partial-clip-text-left.ref.png b/test/reference/partial-clip-text-left.ref.png
new file mode 100644
index 000000000..54a1a8586
--- /dev/null
+++ b/test/reference/partial-clip-text-left.ref.png
Binary files differ
diff --git a/test/reference/partial-clip-text-right.base.argb32.ref.png b/test/reference/partial-clip-text-right.base.argb32.ref.png
new file mode 100644
index 000000000..2fbdca038
--- /dev/null
+++ b/test/reference/partial-clip-text-right.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/partial-clip-text-right.base.rgb24.ref.png b/test/reference/partial-clip-text-right.base.rgb24.ref.png
new file mode 100644
index 000000000..2fbdca038
--- /dev/null
+++ b/test/reference/partial-clip-text-right.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/partial-clip-text-right.ref.png b/test/reference/partial-clip-text-right.ref.png
new file mode 100644
index 000000000..2fbdca038
--- /dev/null
+++ b/test/reference/partial-clip-text-right.ref.png
Binary files differ
diff --git a/test/reference/partial-clip-text-right.traps.ref.png b/test/reference/partial-clip-text-right.traps.ref.png
new file mode 100644
index 000000000..2fbdca038
--- /dev/null
+++ b/test/reference/partial-clip-text-right.traps.ref.png
Binary files differ
diff --git a/test/reference/partial-clip-text-top.base.argb32.ref.png b/test/reference/partial-clip-text-top.base.argb32.ref.png
new file mode 100644
index 000000000..d18475be3
--- /dev/null
+++ b/test/reference/partial-clip-text-top.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/partial-clip-text-top.base.rgb24.ref.png b/test/reference/partial-clip-text-top.base.rgb24.ref.png
new file mode 100644
index 000000000..d18475be3
--- /dev/null
+++ b/test/reference/partial-clip-text-top.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/partial-clip-text-top.ps.ref.png b/test/reference/partial-clip-text-top.ps.ref.png
new file mode 100644
index 000000000..049bba58f
--- /dev/null
+++ b/test/reference/partial-clip-text-top.ps.ref.png
Binary files differ
diff --git a/test/reference/partial-clip-text-top.quartz.ref.png b/test/reference/partial-clip-text-top.quartz.ref.png
new file mode 100644
index 000000000..33ac283af
--- /dev/null
+++ b/test/reference/partial-clip-text-top.quartz.ref.png
Binary files differ
diff --git a/test/reference/partial-clip-text-top.ref.png b/test/reference/partial-clip-text-top.ref.png
new file mode 100644
index 000000000..d18475be3
--- /dev/null
+++ b/test/reference/partial-clip-text-top.ref.png
Binary files differ
diff --git a/test/reference/partial-clip-text-top.svg.ref.png b/test/reference/partial-clip-text-top.svg.ref.png
new file mode 100644
index 000000000..dc3fc5869
--- /dev/null
+++ b/test/reference/partial-clip-text-top.svg.ref.png
Binary files differ
diff --git a/test/reference/partial-clip-text-top.traps.ref.png b/test/reference/partial-clip-text-top.traps.ref.png
new file mode 100644
index 000000000..d18475be3
--- /dev/null
+++ b/test/reference/partial-clip-text-top.traps.ref.png
Binary files differ
diff --git a/test/reference/partial-coverage-half-reference.base.argb32.ref.png b/test/reference/partial-coverage-half-reference.base.argb32.ref.png
new file mode 100644
index 000000000..17f4ff06b
--- /dev/null
+++ b/test/reference/partial-coverage-half-reference.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/partial-coverage-half-reference.base.rgb24.ref.png b/test/reference/partial-coverage-half-reference.base.rgb24.ref.png
new file mode 100644
index 000000000..17f4ff06b
--- /dev/null
+++ b/test/reference/partial-coverage-half-reference.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/partial-coverage-half-reference.ref.png b/test/reference/partial-coverage-half-reference.ref.png
new file mode 100644
index 000000000..17f4ff06b
--- /dev/null
+++ b/test/reference/partial-coverage-half-reference.ref.png
Binary files differ
diff --git a/test/reference/partial-coverage-half-triangles.ref.png b/test/reference/partial-coverage-half-triangles.ref.png
new file mode 100644
index 000000000..17f4ff06b
--- /dev/null
+++ b/test/reference/partial-coverage-half-triangles.ref.png
Binary files differ
diff --git a/test/reference/partial-coverage-intersecting-quads.ref.png b/test/reference/partial-coverage-intersecting-quads.ref.png
new file mode 100644
index 000000000..17f4ff06b
--- /dev/null
+++ b/test/reference/partial-coverage-intersecting-quads.ref.png
Binary files differ
diff --git a/test/reference/partial-coverage-intersecting-quads.xfail.png b/test/reference/partial-coverage-intersecting-quads.xfail.png
new file mode 100644
index 000000000..a6635b9e8
--- /dev/null
+++ b/test/reference/partial-coverage-intersecting-quads.xfail.png
Binary files differ
diff --git a/test/reference/partial-coverage-intersecting-triangles.ref.png b/test/reference/partial-coverage-intersecting-triangles.ref.png
new file mode 100644
index 000000000..9e4a6fe42
--- /dev/null
+++ b/test/reference/partial-coverage-intersecting-triangles.ref.png
Binary files differ
diff --git a/test/reference/partial-coverage-overlap-half-triangles-eo.ref.png b/test/reference/partial-coverage-overlap-half-triangles-eo.ref.png
new file mode 100644
index 000000000..17f4ff06b
--- /dev/null
+++ b/test/reference/partial-coverage-overlap-half-triangles-eo.ref.png
Binary files differ
diff --git a/test/reference/partial-coverage-overlap-half-triangles.ref.png b/test/reference/partial-coverage-overlap-half-triangles.ref.png
new file mode 100644
index 000000000..17f4ff06b
--- /dev/null
+++ b/test/reference/partial-coverage-overlap-half-triangles.ref.png
Binary files differ
diff --git a/test/reference/partial-coverage-overlap-three-quarter-triangles.ref.png b/test/reference/partial-coverage-overlap-three-quarter-triangles.ref.png
new file mode 100644
index 000000000..ea16dc4bb
--- /dev/null
+++ b/test/reference/partial-coverage-overlap-three-quarter-triangles.ref.png
Binary files differ
diff --git a/test/reference/partial-coverage-rectangles.ref.png b/test/reference/partial-coverage-rectangles.ref.png
new file mode 100644
index 000000000..9e4a6fe42
--- /dev/null
+++ b/test/reference/partial-coverage-rectangles.ref.png
Binary files differ
diff --git a/test/reference/partial-coverage-reference.base.argb32.ref.png b/test/reference/partial-coverage-reference.base.argb32.ref.png
new file mode 100644
index 000000000..9e4a6fe42
--- /dev/null
+++ b/test/reference/partial-coverage-reference.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/partial-coverage-reference.base.rgb24.ref.png b/test/reference/partial-coverage-reference.base.rgb24.ref.png
new file mode 100644
index 000000000..9e4a6fe42
--- /dev/null
+++ b/test/reference/partial-coverage-reference.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/partial-coverage-reference.ref.png b/test/reference/partial-coverage-reference.ref.png
new file mode 100644
index 000000000..9e4a6fe42
--- /dev/null
+++ b/test/reference/partial-coverage-reference.ref.png
Binary files differ
diff --git a/test/reference/partial-coverage-three-quarter-reference.base.argb32.ref.png b/test/reference/partial-coverage-three-quarter-reference.base.argb32.ref.png
new file mode 100644
index 000000000..ea16dc4bb
--- /dev/null
+++ b/test/reference/partial-coverage-three-quarter-reference.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/partial-coverage-three-quarter-reference.base.rgb24.ref.png b/test/reference/partial-coverage-three-quarter-reference.base.rgb24.ref.png
new file mode 100644
index 000000000..ea16dc4bb
--- /dev/null
+++ b/test/reference/partial-coverage-three-quarter-reference.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/partial-coverage-three-quarter-reference.ref.png b/test/reference/partial-coverage-three-quarter-reference.ref.png
new file mode 100644
index 000000000..ea16dc4bb
--- /dev/null
+++ b/test/reference/partial-coverage-three-quarter-reference.ref.png
Binary files differ
diff --git a/test/reference/partial-coverage-triangles.ref.png b/test/reference/partial-coverage-triangles.ref.png
new file mode 100644
index 000000000..9e4a6fe42
--- /dev/null
+++ b/test/reference/partial-coverage-triangles.ref.png
Binary files differ
diff --git a/test/reference/pass-through.base.argb32.ref.png b/test/reference/pass-through.base.argb32.ref.png
new file mode 100644
index 000000000..058a1920f
--- /dev/null
+++ b/test/reference/pass-through.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/pass-through.base.rgb24.ref.png b/test/reference/pass-through.base.rgb24.ref.png
new file mode 100644
index 000000000..1be631aad
--- /dev/null
+++ b/test/reference/pass-through.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/pass-through.ref.png b/test/reference/pass-through.ref.png
new file mode 100644
index 000000000..058a1920f
--- /dev/null
+++ b/test/reference/pass-through.ref.png
Binary files differ
diff --git a/test/reference/path-append.base.argb32.ref.png b/test/reference/path-append.base.argb32.ref.png
new file mode 100644
index 000000000..6fb6b2a33
--- /dev/null
+++ b/test/reference/path-append.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/path-append.base.rgb24.ref.png b/test/reference/path-append.base.rgb24.ref.png
new file mode 100644
index 000000000..6fb6b2a33
--- /dev/null
+++ b/test/reference/path-append.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/path-append.image16.ref.png b/test/reference/path-append.image16.ref.png
new file mode 100644
index 000000000..5d939bbc1
--- /dev/null
+++ b/test/reference/path-append.image16.ref.png
Binary files differ
diff --git a/test/reference/path-append.ps.ref.png b/test/reference/path-append.ps.ref.png
new file mode 100644
index 000000000..2c8df1698
--- /dev/null
+++ b/test/reference/path-append.ps.ref.png
Binary files differ
diff --git a/test/reference/path-append.quartz.ref.png b/test/reference/path-append.quartz.ref.png
new file mode 100644
index 000000000..665d3ccb9
--- /dev/null
+++ b/test/reference/path-append.quartz.ref.png
Binary files differ
diff --git a/test/reference/path-append.ref.png b/test/reference/path-append.ref.png
new file mode 100644
index 000000000..33af231bb
--- /dev/null
+++ b/test/reference/path-append.ref.png
Binary files differ
diff --git a/test/reference/path-append.test-fallback.ref.png b/test/reference/path-append.test-fallback.ref.png
new file mode 100644
index 000000000..fa72ac06f
--- /dev/null
+++ b/test/reference/path-append.test-fallback.ref.png
Binary files differ
diff --git a/test/reference/path-append.traps.argb32.ref.png b/test/reference/path-append.traps.argb32.ref.png
new file mode 100644
index 000000000..6fb6b2a33
--- /dev/null
+++ b/test/reference/path-append.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/path-append.traps.rgb24.ref.png b/test/reference/path-append.traps.rgb24.ref.png
new file mode 100644
index 000000000..6fb6b2a33
--- /dev/null
+++ b/test/reference/path-append.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/path-append.xlib-fallback.ref.png b/test/reference/path-append.xlib-fallback.ref.png
new file mode 100644
index 000000000..d34cce125
--- /dev/null
+++ b/test/reference/path-append.xlib-fallback.ref.png
Binary files differ
diff --git a/test/reference/path-stroke-twice.base.argb32.ref.png b/test/reference/path-stroke-twice.base.argb32.ref.png
new file mode 100644
index 000000000..48dd2c7c6
--- /dev/null
+++ b/test/reference/path-stroke-twice.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/path-stroke-twice.base.rgb24.ref.png b/test/reference/path-stroke-twice.base.rgb24.ref.png
new file mode 100644
index 000000000..48dd2c7c6
--- /dev/null
+++ b/test/reference/path-stroke-twice.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/path-stroke-twice.image16.ref.png b/test/reference/path-stroke-twice.image16.ref.png
new file mode 100644
index 000000000..9f162adf3
--- /dev/null
+++ b/test/reference/path-stroke-twice.image16.ref.png
Binary files differ
diff --git a/test/reference/path-stroke-twice.ps.ref.png b/test/reference/path-stroke-twice.ps.ref.png
new file mode 100644
index 000000000..23e814743
--- /dev/null
+++ b/test/reference/path-stroke-twice.ps.ref.png
Binary files differ
diff --git a/test/reference/path-stroke-twice.ref.png b/test/reference/path-stroke-twice.ref.png
new file mode 100644
index 000000000..743c6ce52
--- /dev/null
+++ b/test/reference/path-stroke-twice.ref.png
Binary files differ
diff --git a/test/reference/path-stroke-twice.traps.argb32.ref.png b/test/reference/path-stroke-twice.traps.argb32.ref.png
new file mode 100644
index 000000000..48dd2c7c6
--- /dev/null
+++ b/test/reference/path-stroke-twice.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/path-stroke-twice.traps.rgb24.ref.png b/test/reference/path-stroke-twice.traps.rgb24.ref.png
new file mode 100644
index 000000000..48dd2c7c6
--- /dev/null
+++ b/test/reference/path-stroke-twice.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/pattern-getters.base.argb32.ref.png b/test/reference/pattern-getters.base.argb32.ref.png
new file mode 100644
index 000000000..3cc39a8be
--- /dev/null
+++ b/test/reference/pattern-getters.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/pattern-getters.base.rgb24.ref.png b/test/reference/pattern-getters.base.rgb24.ref.png
new file mode 100644
index 000000000..3cc39a8be
--- /dev/null
+++ b/test/reference/pattern-getters.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/pattern-getters.ref.png b/test/reference/pattern-getters.ref.png
new file mode 100644
index 000000000..80304b0ec
--- /dev/null
+++ b/test/reference/pattern-getters.ref.png
Binary files differ
diff --git a/test/reference/pdf-isolated-group.base.argb32.ref.png b/test/reference/pdf-isolated-group.base.argb32.ref.png
new file mode 100644
index 000000000..6c8522ccc
--- /dev/null
+++ b/test/reference/pdf-isolated-group.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/pdf-isolated-group.base.rgb24.ref.png b/test/reference/pdf-isolated-group.base.rgb24.ref.png
new file mode 100644
index 000000000..6c8522ccc
--- /dev/null
+++ b/test/reference/pdf-isolated-group.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/pdf-isolated-group.ref.png b/test/reference/pdf-isolated-group.ref.png
new file mode 100644
index 000000000..6c8522ccc
--- /dev/null
+++ b/test/reference/pdf-isolated-group.ref.png
Binary files differ
diff --git a/test/reference/pdf-surface-source.base.argb32.ref.png b/test/reference/pdf-surface-source.base.argb32.ref.png
new file mode 100644
index 000000000..018297208
--- /dev/null
+++ b/test/reference/pdf-surface-source.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/pdf-surface-source.base.rgb24.ref.png b/test/reference/pdf-surface-source.base.rgb24.ref.png
new file mode 100644
index 000000000..0d68a82cc
--- /dev/null
+++ b/test/reference/pdf-surface-source.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/pdf-surface-source.image16.ref.png b/test/reference/pdf-surface-source.image16.ref.png
new file mode 100644
index 000000000..2a7460e28
--- /dev/null
+++ b/test/reference/pdf-surface-source.image16.ref.png
Binary files differ
diff --git a/test/reference/pdf-surface-source.ref.png b/test/reference/pdf-surface-source.ref.png
new file mode 100644
index 000000000..018297208
--- /dev/null
+++ b/test/reference/pdf-surface-source.ref.png
Binary files differ
diff --git a/test/reference/pdf-surface-source.svg12.argb32.xfail.png b/test/reference/pdf-surface-source.svg12.argb32.xfail.png
new file mode 100644
index 000000000..6ebcaf9a1
--- /dev/null
+++ b/test/reference/pdf-surface-source.svg12.argb32.xfail.png
Binary files differ
diff --git a/test/reference/pdf-surface-source.svg12.rgb24.xfail.png b/test/reference/pdf-surface-source.svg12.rgb24.xfail.png
new file mode 100644
index 000000000..6ebcaf9a1
--- /dev/null
+++ b/test/reference/pdf-surface-source.svg12.rgb24.xfail.png
Binary files differ
diff --git a/test/reference/pixman-downscale-best-24.ref.png b/test/reference/pixman-downscale-best-24.ref.png
new file mode 100644
index 000000000..df0f9c0d8
--- /dev/null
+++ b/test/reference/pixman-downscale-best-24.ref.png
Binary files differ
diff --git a/test/reference/pixman-downscale-best-95.image.rgb24.ref.png b/test/reference/pixman-downscale-best-95.image.rgb24.ref.png
new file mode 100644
index 000000000..5885c4bcc
--- /dev/null
+++ b/test/reference/pixman-downscale-best-95.image.rgb24.ref.png
Binary files differ
diff --git a/test/reference/pixman-downscale-best-95.image16.rgb24.ref.png b/test/reference/pixman-downscale-best-95.image16.rgb24.ref.png
new file mode 100644
index 000000000..37783991d
--- /dev/null
+++ b/test/reference/pixman-downscale-best-95.image16.rgb24.ref.png
Binary files differ
diff --git a/test/reference/pixman-downscale-best-95.pdf.ref.png b/test/reference/pixman-downscale-best-95.pdf.ref.png
new file mode 100644
index 000000000..71b518e1e
--- /dev/null
+++ b/test/reference/pixman-downscale-best-95.pdf.ref.png
Binary files differ
diff --git a/test/reference/pixman-downscale-best-95.ps2.ref.png b/test/reference/pixman-downscale-best-95.ps2.ref.png
new file mode 100644
index 000000000..08983dca6
--- /dev/null
+++ b/test/reference/pixman-downscale-best-95.ps2.ref.png
Binary files differ
diff --git a/test/reference/pixman-downscale-best-95.ps3.ref.png b/test/reference/pixman-downscale-best-95.ps3.ref.png
new file mode 100644
index 000000000..08983dca6
--- /dev/null
+++ b/test/reference/pixman-downscale-best-95.ps3.ref.png
Binary files differ
diff --git a/test/reference/pixman-downscale-best-95.recording.rgb24.ref.png b/test/reference/pixman-downscale-best-95.recording.rgb24.ref.png
new file mode 100644
index 000000000..5885c4bcc
--- /dev/null
+++ b/test/reference/pixman-downscale-best-95.recording.rgb24.ref.png
Binary files differ
diff --git a/test/reference/pixman-downscale-best-95.ref.png b/test/reference/pixman-downscale-best-95.ref.png
new file mode 100644
index 000000000..1b98e8f63
--- /dev/null
+++ b/test/reference/pixman-downscale-best-95.ref.png
Binary files differ
diff --git a/test/reference/pixman-downscale-best-95.script.ref.png b/test/reference/pixman-downscale-best-95.script.ref.png
new file mode 100644
index 000000000..f3bd7ff81
--- /dev/null
+++ b/test/reference/pixman-downscale-best-95.script.ref.png
Binary files differ
diff --git a/test/reference/pixman-downscale-best-95.svg11.ref.png b/test/reference/pixman-downscale-best-95.svg11.ref.png
new file mode 100644
index 000000000..777f448e3
--- /dev/null
+++ b/test/reference/pixman-downscale-best-95.svg11.ref.png
Binary files differ
diff --git a/test/reference/pixman-downscale-best-95.svg12.ref.png b/test/reference/pixman-downscale-best-95.svg12.ref.png
new file mode 100644
index 000000000..777f448e3
--- /dev/null
+++ b/test/reference/pixman-downscale-best-95.svg12.ref.png
Binary files differ
diff --git a/test/reference/pixman-downscale-best-95.test-base.rgb24.ref.png b/test/reference/pixman-downscale-best-95.test-base.rgb24.ref.png
new file mode 100644
index 000000000..5885c4bcc
--- /dev/null
+++ b/test/reference/pixman-downscale-best-95.test-base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/pixman-downscale-best-95.test-fallback.rgb24.ref.png b/test/reference/pixman-downscale-best-95.test-fallback.rgb24.ref.png
new file mode 100644
index 000000000..5885c4bcc
--- /dev/null
+++ b/test/reference/pixman-downscale-best-95.test-fallback.rgb24.ref.png
Binary files differ
diff --git a/test/reference/pixman-downscale-best-95.test-mask.rgb24.ref.png b/test/reference/pixman-downscale-best-95.test-mask.rgb24.ref.png
new file mode 100644
index 000000000..5885c4bcc
--- /dev/null
+++ b/test/reference/pixman-downscale-best-95.test-mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/pixman-downscale-best-95.test-paginated.rgb24.ref.png b/test/reference/pixman-downscale-best-95.test-paginated.rgb24.ref.png
new file mode 100644
index 000000000..5885c4bcc
--- /dev/null
+++ b/test/reference/pixman-downscale-best-95.test-paginated.rgb24.ref.png
Binary files differ
diff --git a/test/reference/pixman-downscale-best-95.test-spans.rgb24.ref.png b/test/reference/pixman-downscale-best-95.test-spans.rgb24.ref.png
new file mode 100644
index 000000000..5885c4bcc
--- /dev/null
+++ b/test/reference/pixman-downscale-best-95.test-spans.rgb24.ref.png
Binary files differ
diff --git a/test/reference/pixman-downscale-best-95.test-traps.rgb24.ref.png b/test/reference/pixman-downscale-best-95.test-traps.rgb24.ref.png
new file mode 100644
index 000000000..5885c4bcc
--- /dev/null
+++ b/test/reference/pixman-downscale-best-95.test-traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/pixman-downscale-best-95.xcb-fallback.rgb24.ref.png b/test/reference/pixman-downscale-best-95.xcb-fallback.rgb24.ref.png
new file mode 100644
index 000000000..5885c4bcc
--- /dev/null
+++ b/test/reference/pixman-downscale-best-95.xcb-fallback.rgb24.ref.png
Binary files differ
diff --git a/test/reference/pixman-downscale-best-95.xcb-render-0_0.rgb24.ref.png b/test/reference/pixman-downscale-best-95.xcb-render-0_0.rgb24.ref.png
new file mode 100644
index 000000000..5885c4bcc
--- /dev/null
+++ b/test/reference/pixman-downscale-best-95.xcb-render-0_0.rgb24.ref.png
Binary files differ
diff --git a/test/reference/pixman-downscale-best-95.xcb-window&.rgb24.ref.png b/test/reference/pixman-downscale-best-95.xcb-window&.rgb24.ref.png
new file mode 100644
index 000000000..777f448e3
--- /dev/null
+++ b/test/reference/pixman-downscale-best-95.xcb-window&.rgb24.ref.png
Binary files differ
diff --git a/test/reference/pixman-downscale-best-95.xcb-window.rgb24.ref.png b/test/reference/pixman-downscale-best-95.xcb-window.rgb24.ref.png
new file mode 100644
index 000000000..777f448e3
--- /dev/null
+++ b/test/reference/pixman-downscale-best-95.xcb-window.rgb24.ref.png
Binary files differ
diff --git a/test/reference/pixman-downscale-best-95.xcb.ref.png b/test/reference/pixman-downscale-best-95.xcb.ref.png
new file mode 100644
index 000000000..777f448e3
--- /dev/null
+++ b/test/reference/pixman-downscale-best-95.xcb.ref.png
Binary files differ
diff --git a/test/reference/pixman-downscale-best-95.xlib-fallback.rgb24.ref.png b/test/reference/pixman-downscale-best-95.xlib-fallback.rgb24.ref.png
new file mode 100644
index 000000000..5885c4bcc
--- /dev/null
+++ b/test/reference/pixman-downscale-best-95.xlib-fallback.rgb24.ref.png
Binary files differ
diff --git a/test/reference/pixman-downscale-best-95.xlib-render-0_0.rgb24.ref.png b/test/reference/pixman-downscale-best-95.xlib-render-0_0.rgb24.ref.png
new file mode 100644
index 000000000..5885c4bcc
--- /dev/null
+++ b/test/reference/pixman-downscale-best-95.xlib-render-0_0.rgb24.ref.png
Binary files differ
diff --git a/test/reference/pixman-downscale-best-95.xlib-window.rgb24.ref.png b/test/reference/pixman-downscale-best-95.xlib-window.rgb24.ref.png
new file mode 100644
index 000000000..777f448e3
--- /dev/null
+++ b/test/reference/pixman-downscale-best-95.xlib-window.rgb24.ref.png
Binary files differ
diff --git a/test/reference/pixman-downscale-best-95.xlib.ref.png b/test/reference/pixman-downscale-best-95.xlib.ref.png
new file mode 100644
index 000000000..777f448e3
--- /dev/null
+++ b/test/reference/pixman-downscale-best-95.xlib.ref.png
Binary files differ
diff --git a/test/reference/pixman-downscale-best-96.ref.png b/test/reference/pixman-downscale-best-96.ref.png
new file mode 100644
index 000000000..0d68a82cc
--- /dev/null
+++ b/test/reference/pixman-downscale-best-96.ref.png
Binary files differ
diff --git a/test/reference/pixman-downscale-bilinear-24.ref.png b/test/reference/pixman-downscale-bilinear-24.ref.png
new file mode 100644
index 000000000..df0f9c0d8
--- /dev/null
+++ b/test/reference/pixman-downscale-bilinear-24.ref.png
Binary files differ
diff --git a/test/reference/pixman-downscale-bilinear-95.image16.rgb24.ref.png b/test/reference/pixman-downscale-bilinear-95.image16.rgb24.ref.png
new file mode 100644
index 000000000..9d67251e2
--- /dev/null
+++ b/test/reference/pixman-downscale-bilinear-95.image16.rgb24.ref.png
Binary files differ
diff --git a/test/reference/pixman-downscale-bilinear-95.pdf.ref.png b/test/reference/pixman-downscale-bilinear-95.pdf.ref.png
new file mode 100644
index 000000000..71b518e1e
--- /dev/null
+++ b/test/reference/pixman-downscale-bilinear-95.pdf.ref.png
Binary files differ
diff --git a/test/reference/pixman-downscale-bilinear-95.ps2.ref.png b/test/reference/pixman-downscale-bilinear-95.ps2.ref.png
new file mode 100644
index 000000000..08983dca6
--- /dev/null
+++ b/test/reference/pixman-downscale-bilinear-95.ps2.ref.png
Binary files differ
diff --git a/test/reference/pixman-downscale-bilinear-95.ps3.ref.png b/test/reference/pixman-downscale-bilinear-95.ps3.ref.png
new file mode 100644
index 000000000..08983dca6
--- /dev/null
+++ b/test/reference/pixman-downscale-bilinear-95.ps3.ref.png
Binary files differ
diff --git a/test/reference/pixman-downscale-bilinear-95.ref.png b/test/reference/pixman-downscale-bilinear-95.ref.png
new file mode 100644
index 000000000..777f448e3
--- /dev/null
+++ b/test/reference/pixman-downscale-bilinear-95.ref.png
Binary files differ
diff --git a/test/reference/pixman-downscale-bilinear-95.script.ref.png b/test/reference/pixman-downscale-bilinear-95.script.ref.png
new file mode 100644
index 000000000..fa4c04c02
--- /dev/null
+++ b/test/reference/pixman-downscale-bilinear-95.script.ref.png
Binary files differ
diff --git a/test/reference/pixman-downscale-bilinear-96.ref.png b/test/reference/pixman-downscale-bilinear-96.ref.png
new file mode 100644
index 000000000..0d68a82cc
--- /dev/null
+++ b/test/reference/pixman-downscale-bilinear-96.ref.png
Binary files differ
diff --git a/test/reference/pixman-downscale-fast-24.ref.png b/test/reference/pixman-downscale-fast-24.ref.png
new file mode 100644
index 000000000..df0f9c0d8
--- /dev/null
+++ b/test/reference/pixman-downscale-fast-24.ref.png
Binary files differ
diff --git a/test/reference/pixman-downscale-fast-95.image16.rgb24.ref.png b/test/reference/pixman-downscale-fast-95.image16.rgb24.ref.png
new file mode 100644
index 000000000..a2b67156f
--- /dev/null
+++ b/test/reference/pixman-downscale-fast-95.image16.rgb24.ref.png
Binary files differ
diff --git a/test/reference/pixman-downscale-fast-95.pdf.ref.png b/test/reference/pixman-downscale-fast-95.pdf.ref.png
new file mode 100644
index 000000000..71b518e1e
--- /dev/null
+++ b/test/reference/pixman-downscale-fast-95.pdf.ref.png
Binary files differ
diff --git a/test/reference/pixman-downscale-fast-95.ps2.ref.png b/test/reference/pixman-downscale-fast-95.ps2.ref.png
new file mode 100644
index 000000000..af93ae72d
--- /dev/null
+++ b/test/reference/pixman-downscale-fast-95.ps2.ref.png
Binary files differ
diff --git a/test/reference/pixman-downscale-fast-95.ps3.ref.png b/test/reference/pixman-downscale-fast-95.ps3.ref.png
new file mode 100644
index 000000000..af93ae72d
--- /dev/null
+++ b/test/reference/pixman-downscale-fast-95.ps3.ref.png
Binary files differ
diff --git a/test/reference/pixman-downscale-fast-95.ref.png b/test/reference/pixman-downscale-fast-95.ref.png
new file mode 100644
index 000000000..3340423fc
--- /dev/null
+++ b/test/reference/pixman-downscale-fast-95.ref.png
Binary files differ
diff --git a/test/reference/pixman-downscale-fast-95.svg11.ref.png b/test/reference/pixman-downscale-fast-95.svg11.ref.png
new file mode 100644
index 000000000..777f448e3
--- /dev/null
+++ b/test/reference/pixman-downscale-fast-95.svg11.ref.png
Binary files differ
diff --git a/test/reference/pixman-downscale-fast-95.svg12.ref.png b/test/reference/pixman-downscale-fast-95.svg12.ref.png
new file mode 100644
index 000000000..777f448e3
--- /dev/null
+++ b/test/reference/pixman-downscale-fast-95.svg12.ref.png
Binary files differ
diff --git a/test/reference/pixman-downscale-fast-96.ref.png b/test/reference/pixman-downscale-fast-96.ref.png
new file mode 100644
index 000000000..0d68a82cc
--- /dev/null
+++ b/test/reference/pixman-downscale-fast-96.ref.png
Binary files differ
diff --git a/test/reference/pixman-downscale-good-24.ref.png b/test/reference/pixman-downscale-good-24.ref.png
new file mode 100644
index 000000000..df0f9c0d8
--- /dev/null
+++ b/test/reference/pixman-downscale-good-24.ref.png
Binary files differ
diff --git a/test/reference/pixman-downscale-good-95.image16.rgb24.ref.png b/test/reference/pixman-downscale-good-95.image16.rgb24.ref.png
new file mode 100644
index 000000000..9d67251e2
--- /dev/null
+++ b/test/reference/pixman-downscale-good-95.image16.rgb24.ref.png
Binary files differ
diff --git a/test/reference/pixman-downscale-good-95.pdf.ref.png b/test/reference/pixman-downscale-good-95.pdf.ref.png
new file mode 100644
index 000000000..71b518e1e
--- /dev/null
+++ b/test/reference/pixman-downscale-good-95.pdf.ref.png
Binary files differ
diff --git a/test/reference/pixman-downscale-good-95.ps2.ref.png b/test/reference/pixman-downscale-good-95.ps2.ref.png
new file mode 100644
index 000000000..08983dca6
--- /dev/null
+++ b/test/reference/pixman-downscale-good-95.ps2.ref.png
Binary files differ
diff --git a/test/reference/pixman-downscale-good-95.ps3.ref.png b/test/reference/pixman-downscale-good-95.ps3.ref.png
new file mode 100644
index 000000000..08983dca6
--- /dev/null
+++ b/test/reference/pixman-downscale-good-95.ps3.ref.png
Binary files differ
diff --git a/test/reference/pixman-downscale-good-95.ref.png b/test/reference/pixman-downscale-good-95.ref.png
new file mode 100644
index 000000000..777f448e3
--- /dev/null
+++ b/test/reference/pixman-downscale-good-95.ref.png
Binary files differ
diff --git a/test/reference/pixman-downscale-good-95.script.ref.png b/test/reference/pixman-downscale-good-95.script.ref.png
new file mode 100644
index 000000000..fa4c04c02
--- /dev/null
+++ b/test/reference/pixman-downscale-good-95.script.ref.png
Binary files differ
diff --git a/test/reference/pixman-downscale-good-96.ref.png b/test/reference/pixman-downscale-good-96.ref.png
new file mode 100644
index 000000000..0d68a82cc
--- /dev/null
+++ b/test/reference/pixman-downscale-good-96.ref.png
Binary files differ
diff --git a/test/reference/pixman-downscale-nearest-24.ref.png b/test/reference/pixman-downscale-nearest-24.ref.png
new file mode 100644
index 000000000..df0f9c0d8
--- /dev/null
+++ b/test/reference/pixman-downscale-nearest-24.ref.png
Binary files differ
diff --git a/test/reference/pixman-downscale-nearest-95.image16.rgb24.ref.png b/test/reference/pixman-downscale-nearest-95.image16.rgb24.ref.png
new file mode 100644
index 000000000..a2b67156f
--- /dev/null
+++ b/test/reference/pixman-downscale-nearest-95.image16.rgb24.ref.png
Binary files differ
diff --git a/test/reference/pixman-downscale-nearest-95.pdf.ref.png b/test/reference/pixman-downscale-nearest-95.pdf.ref.png
new file mode 100644
index 000000000..71b518e1e
--- /dev/null
+++ b/test/reference/pixman-downscale-nearest-95.pdf.ref.png
Binary files differ
diff --git a/test/reference/pixman-downscale-nearest-95.ps2.ref.png b/test/reference/pixman-downscale-nearest-95.ps2.ref.png
new file mode 100644
index 000000000..af93ae72d
--- /dev/null
+++ b/test/reference/pixman-downscale-nearest-95.ps2.ref.png
Binary files differ
diff --git a/test/reference/pixman-downscale-nearest-95.ps3.ref.png b/test/reference/pixman-downscale-nearest-95.ps3.ref.png
new file mode 100644
index 000000000..af93ae72d
--- /dev/null
+++ b/test/reference/pixman-downscale-nearest-95.ps3.ref.png
Binary files differ
diff --git a/test/reference/pixman-downscale-nearest-95.ref.png b/test/reference/pixman-downscale-nearest-95.ref.png
new file mode 100644
index 000000000..3340423fc
--- /dev/null
+++ b/test/reference/pixman-downscale-nearest-95.ref.png
Binary files differ
diff --git a/test/reference/pixman-downscale-nearest-95.svg11.ref.png b/test/reference/pixman-downscale-nearest-95.svg11.ref.png
new file mode 100644
index 000000000..777f448e3
--- /dev/null
+++ b/test/reference/pixman-downscale-nearest-95.svg11.ref.png
Binary files differ
diff --git a/test/reference/pixman-downscale-nearest-95.svg12.ref.png b/test/reference/pixman-downscale-nearest-95.svg12.ref.png
new file mode 100644
index 000000000..777f448e3
--- /dev/null
+++ b/test/reference/pixman-downscale-nearest-95.svg12.ref.png
Binary files differ
diff --git a/test/reference/pixman-downscale-nearest-96.ref.png b/test/reference/pixman-downscale-nearest-96.ref.png
new file mode 100644
index 000000000..0d68a82cc
--- /dev/null
+++ b/test/reference/pixman-downscale-nearest-96.ref.png
Binary files differ
diff --git a/test/reference/pixman-rotate.base.argb32.ref.png b/test/reference/pixman-rotate.base.argb32.ref.png
new file mode 100644
index 000000000..7e47a4d8f
--- /dev/null
+++ b/test/reference/pixman-rotate.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/pixman-rotate.base.rgb24.ref.png b/test/reference/pixman-rotate.base.rgb24.ref.png
new file mode 100644
index 000000000..397acbe7e
--- /dev/null
+++ b/test/reference/pixman-rotate.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/pixman-rotate.ps.argb32.ref.png b/test/reference/pixman-rotate.ps.argb32.ref.png
new file mode 100644
index 000000000..0e916883d
--- /dev/null
+++ b/test/reference/pixman-rotate.ps.argb32.ref.png
Binary files differ
diff --git a/test/reference/pixman-rotate.ref.png b/test/reference/pixman-rotate.ref.png
new file mode 100644
index 000000000..7e47a4d8f
--- /dev/null
+++ b/test/reference/pixman-rotate.ref.png
Binary files differ
diff --git a/test/reference/ps-eps.ref.png b/test/reference/ps-eps.ref.png
new file mode 100644
index 000000000..9aadb0887
--- /dev/null
+++ b/test/reference/ps-eps.ref.png
Binary files differ
diff --git a/test/reference/ps-surface-source.base.argb32.ref.png b/test/reference/ps-surface-source.base.argb32.ref.png
new file mode 100644
index 000000000..018297208
--- /dev/null
+++ b/test/reference/ps-surface-source.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/ps-surface-source.base.rgb24.ref.png b/test/reference/ps-surface-source.base.rgb24.ref.png
new file mode 100644
index 000000000..0d68a82cc
--- /dev/null
+++ b/test/reference/ps-surface-source.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/ps-surface-source.image16.ref.png b/test/reference/ps-surface-source.image16.ref.png
new file mode 100644
index 000000000..2a7460e28
--- /dev/null
+++ b/test/reference/ps-surface-source.image16.ref.png
Binary files differ
diff --git a/test/reference/ps-surface-source.ref.png b/test/reference/ps-surface-source.ref.png
new file mode 100644
index 000000000..018297208
--- /dev/null
+++ b/test/reference/ps-surface-source.ref.png
Binary files differ
diff --git a/test/reference/ps-surface-source.svg12.argb32.xfail.png b/test/reference/ps-surface-source.svg12.argb32.xfail.png
new file mode 100644
index 000000000..6ebcaf9a1
--- /dev/null
+++ b/test/reference/ps-surface-source.svg12.argb32.xfail.png
Binary files differ
diff --git a/test/reference/ps-surface-source.svg12.rgb24.xfail.png b/test/reference/ps-surface-source.svg12.rgb24.xfail.png
new file mode 100644
index 000000000..6ebcaf9a1
--- /dev/null
+++ b/test/reference/ps-surface-source.svg12.rgb24.xfail.png
Binary files differ
diff --git a/test/reference/pthread-same-source.image16.ref.png b/test/reference/pthread-same-source.image16.ref.png
new file mode 100644
index 000000000..67eb22f9d
--- /dev/null
+++ b/test/reference/pthread-same-source.image16.ref.png
Binary files differ
diff --git a/test/reference/pthread-same-source.quartz.xfail.png b/test/reference/pthread-same-source.quartz.xfail.png
new file mode 100644
index 000000000..ffed61998
--- /dev/null
+++ b/test/reference/pthread-same-source.quartz.xfail.png
Binary files differ
diff --git a/test/reference/pthread-same-source.ref.png b/test/reference/pthread-same-source.ref.png
new file mode 100644
index 000000000..c1c186b9b
--- /dev/null
+++ b/test/reference/pthread-same-source.ref.png
Binary files differ
diff --git a/test/reference/pthread-show-text.base.argb32.ref.png b/test/reference/pthread-show-text.base.argb32.ref.png
new file mode 100644
index 000000000..90d0af349
--- /dev/null
+++ b/test/reference/pthread-show-text.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/pthread-show-text.base.rgb24.ref.png b/test/reference/pthread-show-text.base.rgb24.ref.png
new file mode 100644
index 000000000..90d0af349
--- /dev/null
+++ b/test/reference/pthread-show-text.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/pthread-show-text.image16.ref.png b/test/reference/pthread-show-text.image16.ref.png
new file mode 100644
index 000000000..a1d1af57c
--- /dev/null
+++ b/test/reference/pthread-show-text.image16.ref.png
Binary files differ
diff --git a/test/reference/pthread-show-text.pdf.ref.png b/test/reference/pthread-show-text.pdf.ref.png
new file mode 100644
index 000000000..bb72fc27b
--- /dev/null
+++ b/test/reference/pthread-show-text.pdf.ref.png
Binary files differ
diff --git a/test/reference/pthread-show-text.ps.ref.png b/test/reference/pthread-show-text.ps.ref.png
new file mode 100644
index 000000000..807b73ff3
--- /dev/null
+++ b/test/reference/pthread-show-text.ps.ref.png
Binary files differ
diff --git a/test/reference/pthread-show-text.quartz.ref.png b/test/reference/pthread-show-text.quartz.ref.png
new file mode 100644
index 000000000..cc9bb25dc
--- /dev/null
+++ b/test/reference/pthread-show-text.quartz.ref.png
Binary files differ
diff --git a/test/reference/pthread-show-text.ref.png b/test/reference/pthread-show-text.ref.png
new file mode 100644
index 000000000..90d0af349
--- /dev/null
+++ b/test/reference/pthread-show-text.ref.png
Binary files differ
diff --git a/test/reference/pthread-show-text.traps.ref.png b/test/reference/pthread-show-text.traps.ref.png
new file mode 100644
index 000000000..90d0af349
--- /dev/null
+++ b/test/reference/pthread-show-text.traps.ref.png
Binary files differ
diff --git a/test/reference/pthread-show-text.xlib-fallback.ref.png b/test/reference/pthread-show-text.xlib-fallback.ref.png
new file mode 100644
index 000000000..d96abed47
--- /dev/null
+++ b/test/reference/pthread-show-text.xlib-fallback.ref.png
Binary files differ
diff --git a/test/reference/pthread-similar.base.argb32.ref.png b/test/reference/pthread-similar.base.argb32.ref.png
new file mode 100644
index 000000000..a22210db8
--- /dev/null
+++ b/test/reference/pthread-similar.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/pthread-similar.base.rgb24.ref.png b/test/reference/pthread-similar.base.rgb24.ref.png
new file mode 100644
index 000000000..a22210db8
--- /dev/null
+++ b/test/reference/pthread-similar.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/pthread-similar.ref.png b/test/reference/pthread-similar.ref.png
new file mode 100644
index 000000000..c8763ba0e
--- /dev/null
+++ b/test/reference/pthread-similar.ref.png
Binary files differ
diff --git a/test/reference/push-group-color.base.argb32.ref.png b/test/reference/push-group-color.base.argb32.ref.png
new file mode 100644
index 000000000..11b1014e0
--- /dev/null
+++ b/test/reference/push-group-color.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/push-group-color.base.rgb24.ref.png b/test/reference/push-group-color.base.rgb24.ref.png
new file mode 100644
index 000000000..11b1014e0
--- /dev/null
+++ b/test/reference/push-group-color.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/push-group-color.image16.ref.png b/test/reference/push-group-color.image16.ref.png
new file mode 100644
index 000000000..6378b75ad
--- /dev/null
+++ b/test/reference/push-group-color.image16.ref.png
Binary files differ
diff --git a/test/reference/push-group-color.ps2.ref.png b/test/reference/push-group-color.ps2.ref.png
new file mode 100644
index 000000000..daf827ee3
--- /dev/null
+++ b/test/reference/push-group-color.ps2.ref.png
Binary files differ
diff --git a/test/reference/push-group-color.ps3.ref.png b/test/reference/push-group-color.ps3.ref.png
new file mode 100644
index 000000000..291fcec8d
--- /dev/null
+++ b/test/reference/push-group-color.ps3.ref.png
Binary files differ
diff --git a/test/reference/push-group-color.quartz.ref.png b/test/reference/push-group-color.quartz.ref.png
new file mode 100644
index 000000000..bca7c5693
--- /dev/null
+++ b/test/reference/push-group-color.quartz.ref.png
Binary files differ
diff --git a/test/reference/push-group-color.ref.png b/test/reference/push-group-color.ref.png
new file mode 100644
index 000000000..a2842b092
--- /dev/null
+++ b/test/reference/push-group-color.ref.png
Binary files differ
diff --git a/test/reference/push-group-color.traps.argb32.ref.png b/test/reference/push-group-color.traps.argb32.ref.png
new file mode 100644
index 000000000..11b1014e0
--- /dev/null
+++ b/test/reference/push-group-color.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/push-group-color.traps.rgb24.ref.png b/test/reference/push-group-color.traps.rgb24.ref.png
new file mode 100644
index 000000000..11b1014e0
--- /dev/null
+++ b/test/reference/push-group-color.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/push-group-path-offset.base.argb32.ref.png b/test/reference/push-group-path-offset.base.argb32.ref.png
new file mode 100644
index 000000000..b836a9197
--- /dev/null
+++ b/test/reference/push-group-path-offset.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/push-group-path-offset.base.rgb24.ref.png b/test/reference/push-group-path-offset.base.rgb24.ref.png
new file mode 100644
index 000000000..b836a9197
--- /dev/null
+++ b/test/reference/push-group-path-offset.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/push-group-path-offset.ref.png b/test/reference/push-group-path-offset.ref.png
new file mode 100644
index 000000000..b836a9197
--- /dev/null
+++ b/test/reference/push-group-path-offset.ref.png
Binary files differ
diff --git a/test/reference/push-group.argb32.ref.png b/test/reference/push-group.argb32.ref.png
new file mode 100644
index 000000000..28dcf0c27
--- /dev/null
+++ b/test/reference/push-group.argb32.ref.png
Binary files differ
diff --git a/test/reference/push-group.base.argb32.ref.png b/test/reference/push-group.base.argb32.ref.png
new file mode 100644
index 000000000..9d27f4508
--- /dev/null
+++ b/test/reference/push-group.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/push-group.base.rgb24.ref.png b/test/reference/push-group.base.rgb24.ref.png
new file mode 100644
index 000000000..e19694f02
--- /dev/null
+++ b/test/reference/push-group.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/push-group.image16.ref.png b/test/reference/push-group.image16.ref.png
new file mode 100644
index 000000000..999040583
--- /dev/null
+++ b/test/reference/push-group.image16.ref.png
Binary files differ
diff --git a/test/reference/push-group.quartz.argb32.ref.png b/test/reference/push-group.quartz.argb32.ref.png
new file mode 100644
index 000000000..b3867b98a
--- /dev/null
+++ b/test/reference/push-group.quartz.argb32.ref.png
Binary files differ
diff --git a/test/reference/push-group.quartz.rgb24.ref.png b/test/reference/push-group.quartz.rgb24.ref.png
new file mode 100644
index 000000000..1fd6ef321
--- /dev/null
+++ b/test/reference/push-group.quartz.rgb24.ref.png
Binary files differ
diff --git a/test/reference/push-group.rgb24.ref.png b/test/reference/push-group.rgb24.ref.png
new file mode 100644
index 000000000..ca6706821
--- /dev/null
+++ b/test/reference/push-group.rgb24.ref.png
Binary files differ
diff --git a/test/reference/push-group.traps.argb32.ref.png b/test/reference/push-group.traps.argb32.ref.png
new file mode 100644
index 000000000..9d27f4508
--- /dev/null
+++ b/test/reference/push-group.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/push-group.traps.rgb24.ref.png b/test/reference/push-group.traps.rgb24.ref.png
new file mode 100644
index 000000000..e19694f02
--- /dev/null
+++ b/test/reference/push-group.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/quartz-surface-source.ps2.ref.png b/test/reference/quartz-surface-source.ps2.ref.png
new file mode 100644
index 000000000..10231581b
--- /dev/null
+++ b/test/reference/quartz-surface-source.ps2.ref.png
Binary files differ
diff --git a/test/reference/quartz-surface-source.ps3.ref.png b/test/reference/quartz-surface-source.ps3.ref.png
new file mode 100644
index 000000000..10231581b
--- /dev/null
+++ b/test/reference/quartz-surface-source.ps3.ref.png
Binary files differ
diff --git a/test/reference/quartz-surface-source.ref.png b/test/reference/quartz-surface-source.ref.png
new file mode 100644
index 000000000..018297208
--- /dev/null
+++ b/test/reference/quartz-surface-source.ref.png
Binary files differ
diff --git a/test/reference/radial-gradient-extend.base.argb32.ref.png b/test/reference/radial-gradient-extend.base.argb32.ref.png
new file mode 100644
index 000000000..3d7de5e56
--- /dev/null
+++ b/test/reference/radial-gradient-extend.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/radial-gradient-extend.base.rgb24.ref.png b/test/reference/radial-gradient-extend.base.rgb24.ref.png
new file mode 100644
index 000000000..3d7de5e56
--- /dev/null
+++ b/test/reference/radial-gradient-extend.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/radial-gradient-extend.mask.argb32.ref.png b/test/reference/radial-gradient-extend.mask.argb32.ref.png
new file mode 100644
index 000000000..3d7de5e56
--- /dev/null
+++ b/test/reference/radial-gradient-extend.mask.argb32.ref.png
Binary files differ
diff --git a/test/reference/radial-gradient-extend.mask.rgb24.ref.png b/test/reference/radial-gradient-extend.mask.rgb24.ref.png
new file mode 100644
index 000000000..3d7de5e56
--- /dev/null
+++ b/test/reference/radial-gradient-extend.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/radial-gradient-extend.ps3.ref.png b/test/reference/radial-gradient-extend.ps3.ref.png
new file mode 100644
index 000000000..e84041eae
--- /dev/null
+++ b/test/reference/radial-gradient-extend.ps3.ref.png
Binary files differ
diff --git a/test/reference/radial-gradient-extend.ref.png b/test/reference/radial-gradient-extend.ref.png
new file mode 100644
index 000000000..3d7de5e56
--- /dev/null
+++ b/test/reference/radial-gradient-extend.ref.png
Binary files differ
diff --git a/test/reference/radial-gradient-extend.traps.argb32.ref.png b/test/reference/radial-gradient-extend.traps.argb32.ref.png
new file mode 100644
index 000000000..3d7de5e56
--- /dev/null
+++ b/test/reference/radial-gradient-extend.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/radial-gradient-extend.traps.rgb24.ref.png b/test/reference/radial-gradient-extend.traps.rgb24.ref.png
new file mode 100644
index 000000000..3d7de5e56
--- /dev/null
+++ b/test/reference/radial-gradient-extend.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/radial-gradient-mask-source.argb32.ref.png b/test/reference/radial-gradient-mask-source.argb32.ref.png
new file mode 100644
index 000000000..2bf65b3d6
--- /dev/null
+++ b/test/reference/radial-gradient-mask-source.argb32.ref.png
Binary files differ
diff --git a/test/reference/radial-gradient-mask-source.base.argb32.ref.png b/test/reference/radial-gradient-mask-source.base.argb32.ref.png
new file mode 100644
index 000000000..2bf65b3d6
--- /dev/null
+++ b/test/reference/radial-gradient-mask-source.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/radial-gradient-mask-source.base.rgb24.ref.png b/test/reference/radial-gradient-mask-source.base.rgb24.ref.png
new file mode 100644
index 000000000..55335196a
--- /dev/null
+++ b/test/reference/radial-gradient-mask-source.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/radial-gradient-mask-source.image16.ref.png b/test/reference/radial-gradient-mask-source.image16.ref.png
new file mode 100644
index 000000000..edb93a986
--- /dev/null
+++ b/test/reference/radial-gradient-mask-source.image16.ref.png
Binary files differ
diff --git a/test/reference/radial-gradient-mask-source.mask.rgb24.ref.png b/test/reference/radial-gradient-mask-source.mask.rgb24.ref.png
new file mode 100644
index 000000000..55335196a
--- /dev/null
+++ b/test/reference/radial-gradient-mask-source.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/radial-gradient-mask-source.quartz.argb32.ref.png b/test/reference/radial-gradient-mask-source.quartz.argb32.ref.png
new file mode 100644
index 000000000..5f734f612
--- /dev/null
+++ b/test/reference/radial-gradient-mask-source.quartz.argb32.ref.png
Binary files differ
diff --git a/test/reference/radial-gradient-mask-source.quartz.rgb24.ref.png b/test/reference/radial-gradient-mask-source.quartz.rgb24.ref.png
new file mode 100644
index 000000000..4ae71f753
--- /dev/null
+++ b/test/reference/radial-gradient-mask-source.quartz.rgb24.ref.png
Binary files differ
diff --git a/test/reference/radial-gradient-mask-source.traps.rgb24.ref.png b/test/reference/radial-gradient-mask-source.traps.rgb24.ref.png
new file mode 100644
index 000000000..55335196a
--- /dev/null
+++ b/test/reference/radial-gradient-mask-source.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/radial-gradient-mask.base.argb32.ref.png b/test/reference/radial-gradient-mask.base.argb32.ref.png
new file mode 100644
index 000000000..4db39aa3f
--- /dev/null
+++ b/test/reference/radial-gradient-mask.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/radial-gradient-mask.base.rgb24.ref.png b/test/reference/radial-gradient-mask.base.rgb24.ref.png
new file mode 100644
index 000000000..4db39aa3f
--- /dev/null
+++ b/test/reference/radial-gradient-mask.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/radial-gradient-mask.image16.ref.png b/test/reference/radial-gradient-mask.image16.ref.png
new file mode 100644
index 000000000..78712ca52
--- /dev/null
+++ b/test/reference/radial-gradient-mask.image16.ref.png
Binary files differ
diff --git a/test/reference/radial-gradient-mask.quartz.ref.png b/test/reference/radial-gradient-mask.quartz.ref.png
new file mode 100644
index 000000000..c1bd50686
--- /dev/null
+++ b/test/reference/radial-gradient-mask.quartz.ref.png
Binary files differ
diff --git a/test/reference/radial-gradient-mask.ref.png b/test/reference/radial-gradient-mask.ref.png
new file mode 100644
index 000000000..4db39aa3f
--- /dev/null
+++ b/test/reference/radial-gradient-mask.ref.png
Binary files differ
diff --git a/test/reference/radial-gradient-one-stop.base.argb32.ref.png b/test/reference/radial-gradient-one-stop.base.argb32.ref.png
new file mode 100644
index 000000000..fb35be61d
--- /dev/null
+++ b/test/reference/radial-gradient-one-stop.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/radial-gradient-one-stop.base.rgb24.ref.png b/test/reference/radial-gradient-one-stop.base.rgb24.ref.png
new file mode 100644
index 000000000..fb35be61d
--- /dev/null
+++ b/test/reference/radial-gradient-one-stop.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/radial-gradient-one-stop.quartz.ref.png b/test/reference/radial-gradient-one-stop.quartz.ref.png
new file mode 100644
index 000000000..da991b1bd
--- /dev/null
+++ b/test/reference/radial-gradient-one-stop.quartz.ref.png
Binary files differ
diff --git a/test/reference/radial-gradient-one-stop.ref.png b/test/reference/radial-gradient-one-stop.ref.png
new file mode 100644
index 000000000..fb35be61d
--- /dev/null
+++ b/test/reference/radial-gradient-one-stop.ref.png
Binary files differ
diff --git a/test/reference/radial-gradient-source.base.argb32.ref.png b/test/reference/radial-gradient-source.base.argb32.ref.png
new file mode 100644
index 000000000..4ab4796fa
--- /dev/null
+++ b/test/reference/radial-gradient-source.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/radial-gradient-source.base.rgb24.ref.png b/test/reference/radial-gradient-source.base.rgb24.ref.png
new file mode 100644
index 000000000..afaa24118
--- /dev/null
+++ b/test/reference/radial-gradient-source.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/radial-gradient-source.image16.ref.png b/test/reference/radial-gradient-source.image16.ref.png
new file mode 100644
index 000000000..f992b6f39
--- /dev/null
+++ b/test/reference/radial-gradient-source.image16.ref.png
Binary files differ
diff --git a/test/reference/radial-gradient-source.quartz.argb32.ref.png b/test/reference/radial-gradient-source.quartz.argb32.ref.png
new file mode 100644
index 000000000..421c0b988
--- /dev/null
+++ b/test/reference/radial-gradient-source.quartz.argb32.ref.png
Binary files differ
diff --git a/test/reference/radial-gradient-source.quartz.rgb24.ref.png b/test/reference/radial-gradient-source.quartz.rgb24.ref.png
new file mode 100644
index 000000000..22f2b9077
--- /dev/null
+++ b/test/reference/radial-gradient-source.quartz.rgb24.ref.png
Binary files differ
diff --git a/test/reference/radial-gradient-source.ref.png b/test/reference/radial-gradient-source.ref.png
new file mode 100644
index 000000000..4ab4796fa
--- /dev/null
+++ b/test/reference/radial-gradient-source.ref.png
Binary files differ
diff --git a/test/reference/radial-gradient.base.argb32.ref.png b/test/reference/radial-gradient.base.argb32.ref.png
new file mode 100644
index 000000000..a2cbbc82e
--- /dev/null
+++ b/test/reference/radial-gradient.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/radial-gradient.base.rgb24.ref.png b/test/reference/radial-gradient.base.rgb24.ref.png
new file mode 100644
index 000000000..a2cbbc82e
--- /dev/null
+++ b/test/reference/radial-gradient.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/radial-gradient.image16.ref.png b/test/reference/radial-gradient.image16.ref.png
new file mode 100644
index 000000000..91202d3c4
--- /dev/null
+++ b/test/reference/radial-gradient.image16.ref.png
Binary files differ
diff --git a/test/reference/radial-gradient.quartz.ref.png b/test/reference/radial-gradient.quartz.ref.png
new file mode 100644
index 000000000..f01c6eb89
--- /dev/null
+++ b/test/reference/radial-gradient.quartz.ref.png
Binary files differ
diff --git a/test/reference/radial-gradient.ref.png b/test/reference/radial-gradient.ref.png
new file mode 100644
index 000000000..a2cbbc82e
--- /dev/null
+++ b/test/reference/radial-gradient.ref.png
Binary files differ
diff --git a/test/reference/radial-outer-focus.base.argb32.ref.png b/test/reference/radial-outer-focus.base.argb32.ref.png
new file mode 100644
index 000000000..21f0bf6fb
--- /dev/null
+++ b/test/reference/radial-outer-focus.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/radial-outer-focus.base.rgb24.ref.png b/test/reference/radial-outer-focus.base.rgb24.ref.png
new file mode 100644
index 000000000..21f0bf6fb
--- /dev/null
+++ b/test/reference/radial-outer-focus.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/radial-outer-focus.mask.argb32.ref.png b/test/reference/radial-outer-focus.mask.argb32.ref.png
new file mode 100644
index 000000000..21f0bf6fb
--- /dev/null
+++ b/test/reference/radial-outer-focus.mask.argb32.ref.png
Binary files differ
diff --git a/test/reference/radial-outer-focus.mask.rgb24.ref.png b/test/reference/radial-outer-focus.mask.rgb24.ref.png
new file mode 100644
index 000000000..21f0bf6fb
--- /dev/null
+++ b/test/reference/radial-outer-focus.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/radial-outer-focus.traps.argb32.ref.png b/test/reference/radial-outer-focus.traps.argb32.ref.png
new file mode 100644
index 000000000..21f0bf6fb
--- /dev/null
+++ b/test/reference/radial-outer-focus.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/radial-outer-focus.traps.rgb24.ref.png b/test/reference/radial-outer-focus.traps.rgb24.ref.png
new file mode 100644
index 000000000..21f0bf6fb
--- /dev/null
+++ b/test/reference/radial-outer-focus.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/radial-outer-focus.xfail.png b/test/reference/radial-outer-focus.xfail.png
new file mode 100644
index 000000000..53e9f8238
--- /dev/null
+++ b/test/reference/radial-outer-focus.xfail.png
Binary files differ
diff --git a/test/reference/random-clip.base.argb32.ref.png b/test/reference/random-clip.base.argb32.ref.png
new file mode 100644
index 000000000..2750fb159
--- /dev/null
+++ b/test/reference/random-clip.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/random-clip.base.argb32.xfail.png b/test/reference/random-clip.base.argb32.xfail.png
new file mode 100644
index 000000000..15f91588e
--- /dev/null
+++ b/test/reference/random-clip.base.argb32.xfail.png
Binary files differ
diff --git a/test/reference/random-clip.base.rgb24.ref.png b/test/reference/random-clip.base.rgb24.ref.png
new file mode 100644
index 000000000..2750fb159
--- /dev/null
+++ b/test/reference/random-clip.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/random-clip.base.rgb24.xfail.png b/test/reference/random-clip.base.rgb24.xfail.png
new file mode 100644
index 000000000..15f91588e
--- /dev/null
+++ b/test/reference/random-clip.base.rgb24.xfail.png
Binary files differ
diff --git a/test/reference/random-clip.mask.argb32.ref.png b/test/reference/random-clip.mask.argb32.ref.png
new file mode 100644
index 000000000..41643cbad
--- /dev/null
+++ b/test/reference/random-clip.mask.argb32.ref.png
Binary files differ
diff --git a/test/reference/random-clip.mask.rgb24.ref.png b/test/reference/random-clip.mask.rgb24.ref.png
new file mode 100644
index 000000000..41643cbad
--- /dev/null
+++ b/test/reference/random-clip.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/random-clip.ref.png b/test/reference/random-clip.ref.png
new file mode 100644
index 000000000..de7a6052c
--- /dev/null
+++ b/test/reference/random-clip.ref.png
Binary files differ
diff --git a/test/reference/random-clip.traps.argb32.ref.png b/test/reference/random-clip.traps.argb32.ref.png
new file mode 100644
index 000000000..01cc60a4f
--- /dev/null
+++ b/test/reference/random-clip.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/random-clip.traps.rgb24.ref.png b/test/reference/random-clip.traps.rgb24.ref.png
new file mode 100644
index 000000000..01cc60a4f
--- /dev/null
+++ b/test/reference/random-clip.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/random-intersections-curves-eo.base.argb32.ref.png b/test/reference/random-intersections-curves-eo.base.argb32.ref.png
new file mode 100644
index 000000000..ee10cb409
--- /dev/null
+++ b/test/reference/random-intersections-curves-eo.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/random-intersections-curves-eo.base.rgb24.ref.png b/test/reference/random-intersections-curves-eo.base.rgb24.ref.png
new file mode 100644
index 000000000..ee10cb409
--- /dev/null
+++ b/test/reference/random-intersections-curves-eo.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/random-intersections-curves-eo.image16.ref.png b/test/reference/random-intersections-curves-eo.image16.ref.png
new file mode 100644
index 000000000..0663270f9
--- /dev/null
+++ b/test/reference/random-intersections-curves-eo.image16.ref.png
Binary files differ
diff --git a/test/reference/random-intersections-curves-eo.pdf.ref.png b/test/reference/random-intersections-curves-eo.pdf.ref.png
new file mode 100644
index 000000000..befa3c859
--- /dev/null
+++ b/test/reference/random-intersections-curves-eo.pdf.ref.png
Binary files differ
diff --git a/test/reference/random-intersections-curves-eo.ps.ref.png b/test/reference/random-intersections-curves-eo.ps.ref.png
new file mode 100644
index 000000000..374ace90a
--- /dev/null
+++ b/test/reference/random-intersections-curves-eo.ps.ref.png
Binary files differ
diff --git a/test/reference/random-intersections-curves-eo.quartz.ref.png b/test/reference/random-intersections-curves-eo.quartz.ref.png
new file mode 100644
index 000000000..2a44a5a5d
--- /dev/null
+++ b/test/reference/random-intersections-curves-eo.quartz.ref.png
Binary files differ
diff --git a/test/reference/random-intersections-curves-eo.ref.png b/test/reference/random-intersections-curves-eo.ref.png
new file mode 100644
index 000000000..1c12f22d2
--- /dev/null
+++ b/test/reference/random-intersections-curves-eo.ref.png
Binary files differ
diff --git a/test/reference/random-intersections-curves-eo.traps.argb32.ref.png b/test/reference/random-intersections-curves-eo.traps.argb32.ref.png
new file mode 100644
index 000000000..ee10cb409
--- /dev/null
+++ b/test/reference/random-intersections-curves-eo.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/random-intersections-curves-eo.traps.rgb24.ref.png b/test/reference/random-intersections-curves-eo.traps.rgb24.ref.png
new file mode 100644
index 000000000..ee10cb409
--- /dev/null
+++ b/test/reference/random-intersections-curves-eo.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/random-intersections-curves-eo.xlib-fallback.ref.png b/test/reference/random-intersections-curves-eo.xlib-fallback.ref.png
new file mode 100644
index 000000000..d91af0bf2
--- /dev/null
+++ b/test/reference/random-intersections-curves-eo.xlib-fallback.ref.png
Binary files differ
diff --git a/test/reference/random-intersections-curves-nz.base.argb32.ref.png b/test/reference/random-intersections-curves-nz.base.argb32.ref.png
new file mode 100644
index 000000000..77f812987
--- /dev/null
+++ b/test/reference/random-intersections-curves-nz.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/random-intersections-curves-nz.base.rgb24.ref.png b/test/reference/random-intersections-curves-nz.base.rgb24.ref.png
new file mode 100644
index 000000000..77f812987
--- /dev/null
+++ b/test/reference/random-intersections-curves-nz.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/random-intersections-curves-nz.image16.ref.png b/test/reference/random-intersections-curves-nz.image16.ref.png
new file mode 100644
index 000000000..5fbc7113b
--- /dev/null
+++ b/test/reference/random-intersections-curves-nz.image16.ref.png
Binary files differ
diff --git a/test/reference/random-intersections-curves-nz.pdf.ref.png b/test/reference/random-intersections-curves-nz.pdf.ref.png
new file mode 100644
index 000000000..a374934bc
--- /dev/null
+++ b/test/reference/random-intersections-curves-nz.pdf.ref.png
Binary files differ
diff --git a/test/reference/random-intersections-curves-nz.ps.ref.png b/test/reference/random-intersections-curves-nz.ps.ref.png
new file mode 100644
index 000000000..6cc5814fc
--- /dev/null
+++ b/test/reference/random-intersections-curves-nz.ps.ref.png
Binary files differ
diff --git a/test/reference/random-intersections-curves-nz.quartz.ref.png b/test/reference/random-intersections-curves-nz.quartz.ref.png
new file mode 100644
index 000000000..cf799bba9
--- /dev/null
+++ b/test/reference/random-intersections-curves-nz.quartz.ref.png
Binary files differ
diff --git a/test/reference/random-intersections-curves-nz.ref.png b/test/reference/random-intersections-curves-nz.ref.png
new file mode 100644
index 000000000..f251d2705
--- /dev/null
+++ b/test/reference/random-intersections-curves-nz.ref.png
Binary files differ
diff --git a/test/reference/random-intersections-curves-nz.traps.argb32.ref.png b/test/reference/random-intersections-curves-nz.traps.argb32.ref.png
new file mode 100644
index 000000000..77f812987
--- /dev/null
+++ b/test/reference/random-intersections-curves-nz.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/random-intersections-curves-nz.traps.rgb24.ref.png b/test/reference/random-intersections-curves-nz.traps.rgb24.ref.png
new file mode 100644
index 000000000..77f812987
--- /dev/null
+++ b/test/reference/random-intersections-curves-nz.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/random-intersections-curves-nz.xlib-fallback.ref.png b/test/reference/random-intersections-curves-nz.xlib-fallback.ref.png
new file mode 100644
index 000000000..f72f8f175
--- /dev/null
+++ b/test/reference/random-intersections-curves-nz.xlib-fallback.ref.png
Binary files differ
diff --git a/test/reference/random-intersections-eo.base.argb32.ref.png b/test/reference/random-intersections-eo.base.argb32.ref.png
new file mode 100644
index 000000000..037f926e4
--- /dev/null
+++ b/test/reference/random-intersections-eo.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/random-intersections-eo.base.rgb24.ref.png b/test/reference/random-intersections-eo.base.rgb24.ref.png
new file mode 100644
index 000000000..037f926e4
--- /dev/null
+++ b/test/reference/random-intersections-eo.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/random-intersections-eo.image16.ref.png b/test/reference/random-intersections-eo.image16.ref.png
new file mode 100644
index 000000000..cf214d41a
--- /dev/null
+++ b/test/reference/random-intersections-eo.image16.ref.png
Binary files differ
diff --git a/test/reference/random-intersections-eo.ps.ref.png b/test/reference/random-intersections-eo.ps.ref.png
new file mode 100644
index 000000000..49b359af0
--- /dev/null
+++ b/test/reference/random-intersections-eo.ps.ref.png
Binary files differ
diff --git a/test/reference/random-intersections-eo.quartz.ref.png b/test/reference/random-intersections-eo.quartz.ref.png
new file mode 100644
index 000000000..859abb050
--- /dev/null
+++ b/test/reference/random-intersections-eo.quartz.ref.png
Binary files differ
diff --git a/test/reference/random-intersections-eo.ref.png b/test/reference/random-intersections-eo.ref.png
new file mode 100644
index 000000000..ccd3f80d1
--- /dev/null
+++ b/test/reference/random-intersections-eo.ref.png
Binary files differ
diff --git a/test/reference/random-intersections-eo.traps.argb32.ref.png b/test/reference/random-intersections-eo.traps.argb32.ref.png
new file mode 100644
index 000000000..037f926e4
--- /dev/null
+++ b/test/reference/random-intersections-eo.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/random-intersections-eo.traps.rgb24.ref.png b/test/reference/random-intersections-eo.traps.rgb24.ref.png
new file mode 100644
index 000000000..037f926e4
--- /dev/null
+++ b/test/reference/random-intersections-eo.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/random-intersections-nonzero.base.argb32.ref.png b/test/reference/random-intersections-nonzero.base.argb32.ref.png
new file mode 100644
index 000000000..7eb9a0a3a
--- /dev/null
+++ b/test/reference/random-intersections-nonzero.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/random-intersections-nonzero.base.rgb24.ref.png b/test/reference/random-intersections-nonzero.base.rgb24.ref.png
new file mode 100644
index 000000000..7eb9a0a3a
--- /dev/null
+++ b/test/reference/random-intersections-nonzero.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/random-intersections-nonzero.image16.ref.png b/test/reference/random-intersections-nonzero.image16.ref.png
new file mode 100644
index 000000000..370abd9d5
--- /dev/null
+++ b/test/reference/random-intersections-nonzero.image16.ref.png
Binary files differ
diff --git a/test/reference/random-intersections-nonzero.ps.ref.png b/test/reference/random-intersections-nonzero.ps.ref.png
new file mode 100644
index 000000000..53a151f6f
--- /dev/null
+++ b/test/reference/random-intersections-nonzero.ps.ref.png
Binary files differ
diff --git a/test/reference/random-intersections-nonzero.quartz.ref.png b/test/reference/random-intersections-nonzero.quartz.ref.png
new file mode 100644
index 000000000..f4310ea27
--- /dev/null
+++ b/test/reference/random-intersections-nonzero.quartz.ref.png
Binary files differ
diff --git a/test/reference/random-intersections-nonzero.ref.png b/test/reference/random-intersections-nonzero.ref.png
new file mode 100644
index 000000000..6f02ea0d8
--- /dev/null
+++ b/test/reference/random-intersections-nonzero.ref.png
Binary files differ
diff --git a/test/reference/random-intersections-nonzero.traps.argb32.ref.png b/test/reference/random-intersections-nonzero.traps.argb32.ref.png
new file mode 100644
index 000000000..7eb9a0a3a
--- /dev/null
+++ b/test/reference/random-intersections-nonzero.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/random-intersections-nonzero.traps.rgb24.ref.png b/test/reference/random-intersections-nonzero.traps.rgb24.ref.png
new file mode 100644
index 000000000..7eb9a0a3a
--- /dev/null
+++ b/test/reference/random-intersections-nonzero.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/raster-source.base.argb32.ref.png b/test/reference/raster-source.base.argb32.ref.png
new file mode 100644
index 000000000..ac5e56063
--- /dev/null
+++ b/test/reference/raster-source.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/raster-source.base.rgb24.ref.png b/test/reference/raster-source.base.rgb24.ref.png
new file mode 100644
index 000000000..ac5e56063
--- /dev/null
+++ b/test/reference/raster-source.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/raster-source.ps.ref.png b/test/reference/raster-source.ps.ref.png
new file mode 100644
index 000000000..2ffc11412
--- /dev/null
+++ b/test/reference/raster-source.ps.ref.png
Binary files differ
diff --git a/test/reference/raster-source.ref.png b/test/reference/raster-source.ref.png
new file mode 100644
index 000000000..ac5e56063
--- /dev/null
+++ b/test/reference/raster-source.ref.png
Binary files differ
diff --git a/test/reference/record-extend-none-similar.base.argb32.ref.png b/test/reference/record-extend-none-similar.base.argb32.ref.png
new file mode 100644
index 000000000..7d5c49fa2
--- /dev/null
+++ b/test/reference/record-extend-none-similar.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/record-extend-none-similar.base.rgb24.ref.png b/test/reference/record-extend-none-similar.base.rgb24.ref.png
new file mode 100644
index 000000000..7d5c49fa2
--- /dev/null
+++ b/test/reference/record-extend-none-similar.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/record-extend-none-similar.ref.png b/test/reference/record-extend-none-similar.ref.png
new file mode 100644
index 000000000..d63c31c1f
--- /dev/null
+++ b/test/reference/record-extend-none-similar.ref.png
Binary files differ
diff --git a/test/reference/record-extend-none-similar.traps.argb32.ref.png b/test/reference/record-extend-none-similar.traps.argb32.ref.png
new file mode 100644
index 000000000..7d5c49fa2
--- /dev/null
+++ b/test/reference/record-extend-none-similar.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/record-extend-none-similar.traps.rgb24.ref.png b/test/reference/record-extend-none-similar.traps.rgb24.ref.png
new file mode 100644
index 000000000..7d5c49fa2
--- /dev/null
+++ b/test/reference/record-extend-none-similar.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/record-extend-none.base.argb32.ref.png b/test/reference/record-extend-none.base.argb32.ref.png
new file mode 100644
index 000000000..d63c31c1f
--- /dev/null
+++ b/test/reference/record-extend-none.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/record-extend-none.base.rgb24.ref.png b/test/reference/record-extend-none.base.rgb24.ref.png
new file mode 100644
index 000000000..d63c31c1f
--- /dev/null
+++ b/test/reference/record-extend-none.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/record-extend-none.ref.png b/test/reference/record-extend-none.ref.png
new file mode 100644
index 000000000..d63c31c1f
--- /dev/null
+++ b/test/reference/record-extend-none.ref.png
Binary files differ
diff --git a/test/reference/record-extend-pad-similar.base.argb32.ref.png b/test/reference/record-extend-pad-similar.base.argb32.ref.png
new file mode 100644
index 000000000..da3de96d3
--- /dev/null
+++ b/test/reference/record-extend-pad-similar.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/record-extend-pad-similar.base.rgb24.ref.png b/test/reference/record-extend-pad-similar.base.rgb24.ref.png
new file mode 100644
index 000000000..da3de96d3
--- /dev/null
+++ b/test/reference/record-extend-pad-similar.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/record-extend-pad-similar.ref.png b/test/reference/record-extend-pad-similar.ref.png
new file mode 100644
index 000000000..12915255c
--- /dev/null
+++ b/test/reference/record-extend-pad-similar.ref.png
Binary files differ
diff --git a/test/reference/record-extend-pad-similar.traps.argb32.ref.png b/test/reference/record-extend-pad-similar.traps.argb32.ref.png
new file mode 100644
index 000000000..da3de96d3
--- /dev/null
+++ b/test/reference/record-extend-pad-similar.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/record-extend-pad-similar.traps.rgb24.ref.png b/test/reference/record-extend-pad-similar.traps.rgb24.ref.png
new file mode 100644
index 000000000..da3de96d3
--- /dev/null
+++ b/test/reference/record-extend-pad-similar.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/record-extend-pad.base.argb32.ref.png b/test/reference/record-extend-pad.base.argb32.ref.png
new file mode 100644
index 000000000..12915255c
--- /dev/null
+++ b/test/reference/record-extend-pad.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/record-extend-pad.base.rgb24.ref.png b/test/reference/record-extend-pad.base.rgb24.ref.png
new file mode 100644
index 000000000..12915255c
--- /dev/null
+++ b/test/reference/record-extend-pad.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/record-extend-pad.ref.png b/test/reference/record-extend-pad.ref.png
new file mode 100644
index 000000000..12915255c
--- /dev/null
+++ b/test/reference/record-extend-pad.ref.png
Binary files differ
diff --git a/test/reference/record-extend-reflect-similar.base.argb32.ref.png b/test/reference/record-extend-reflect-similar.base.argb32.ref.png
new file mode 100644
index 000000000..da3de96d3
--- /dev/null
+++ b/test/reference/record-extend-reflect-similar.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/record-extend-reflect-similar.base.rgb24.ref.png b/test/reference/record-extend-reflect-similar.base.rgb24.ref.png
new file mode 100644
index 000000000..da3de96d3
--- /dev/null
+++ b/test/reference/record-extend-reflect-similar.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/record-extend-reflect-similar.ref.png b/test/reference/record-extend-reflect-similar.ref.png
new file mode 100644
index 000000000..aec5c9454
--- /dev/null
+++ b/test/reference/record-extend-reflect-similar.ref.png
Binary files differ
diff --git a/test/reference/record-extend-reflect-similar.traps.argb32.ref.png b/test/reference/record-extend-reflect-similar.traps.argb32.ref.png
new file mode 100644
index 000000000..da3de96d3
--- /dev/null
+++ b/test/reference/record-extend-reflect-similar.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/record-extend-reflect-similar.traps.rgb24.ref.png b/test/reference/record-extend-reflect-similar.traps.rgb24.ref.png
new file mode 100644
index 000000000..da3de96d3
--- /dev/null
+++ b/test/reference/record-extend-reflect-similar.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/record-extend-reflect.base.argb32.ref.png b/test/reference/record-extend-reflect.base.argb32.ref.png
new file mode 100644
index 000000000..aec5c9454
--- /dev/null
+++ b/test/reference/record-extend-reflect.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/record-extend-reflect.base.rgb24.ref.png b/test/reference/record-extend-reflect.base.rgb24.ref.png
new file mode 100644
index 000000000..aec5c9454
--- /dev/null
+++ b/test/reference/record-extend-reflect.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/record-extend-reflect.ref.png b/test/reference/record-extend-reflect.ref.png
new file mode 100644
index 000000000..aec5c9454
--- /dev/null
+++ b/test/reference/record-extend-reflect.ref.png
Binary files differ
diff --git a/test/reference/record-extend-repeat-similar.base.argb32.ref.png b/test/reference/record-extend-repeat-similar.base.argb32.ref.png
new file mode 100644
index 000000000..da3de96d3
--- /dev/null
+++ b/test/reference/record-extend-repeat-similar.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/record-extend-repeat-similar.base.rgb24.ref.png b/test/reference/record-extend-repeat-similar.base.rgb24.ref.png
new file mode 100644
index 000000000..da3de96d3
--- /dev/null
+++ b/test/reference/record-extend-repeat-similar.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/record-extend-repeat-similar.ref.png b/test/reference/record-extend-repeat-similar.ref.png
new file mode 100644
index 000000000..d4db9bf58
--- /dev/null
+++ b/test/reference/record-extend-repeat-similar.ref.png
Binary files differ
diff --git a/test/reference/record-extend-repeat-similar.traps.argb32.ref.png b/test/reference/record-extend-repeat-similar.traps.argb32.ref.png
new file mode 100644
index 000000000..da3de96d3
--- /dev/null
+++ b/test/reference/record-extend-repeat-similar.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/record-extend-repeat-similar.traps.rgb24.ref.png b/test/reference/record-extend-repeat-similar.traps.rgb24.ref.png
new file mode 100644
index 000000000..da3de96d3
--- /dev/null
+++ b/test/reference/record-extend-repeat-similar.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/record-extend-repeat.base.argb32.ref.png b/test/reference/record-extend-repeat.base.argb32.ref.png
new file mode 100644
index 000000000..d4db9bf58
--- /dev/null
+++ b/test/reference/record-extend-repeat.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/record-extend-repeat.base.rgb24.ref.png b/test/reference/record-extend-repeat.base.rgb24.ref.png
new file mode 100644
index 000000000..d4db9bf58
--- /dev/null
+++ b/test/reference/record-extend-repeat.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/record-extend-repeat.ref.png b/test/reference/record-extend-repeat.ref.png
new file mode 100644
index 000000000..d4db9bf58
--- /dev/null
+++ b/test/reference/record-extend-repeat.ref.png
Binary files differ
diff --git a/test/reference/record-fill-alpha.base.argb32.ref.png b/test/reference/record-fill-alpha.base.argb32.ref.png
new file mode 100644
index 000000000..5a2ebad01
--- /dev/null
+++ b/test/reference/record-fill-alpha.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/record-fill-alpha.base.rgb24.ref.png b/test/reference/record-fill-alpha.base.rgb24.ref.png
new file mode 100644
index 000000000..5a2ebad01
--- /dev/null
+++ b/test/reference/record-fill-alpha.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/record-fill-alpha.base.xfail.png b/test/reference/record-fill-alpha.base.xfail.png
new file mode 100644
index 000000000..5a2ebad01
--- /dev/null
+++ b/test/reference/record-fill-alpha.base.xfail.png
Binary files differ
diff --git a/test/reference/record-fill-alpha.image16.rgb24.ref.png b/test/reference/record-fill-alpha.image16.rgb24.ref.png
new file mode 100644
index 000000000..8ba164e28
--- /dev/null
+++ b/test/reference/record-fill-alpha.image16.rgb24.ref.png
Binary files differ
diff --git a/test/reference/record-fill-alpha.ref.png b/test/reference/record-fill-alpha.ref.png
new file mode 100644
index 000000000..25c1ac68f
--- /dev/null
+++ b/test/reference/record-fill-alpha.ref.png
Binary files differ
diff --git a/test/reference/record-fill-alpha.traps.argb32.ref.png b/test/reference/record-fill-alpha.traps.argb32.ref.png
new file mode 100644
index 000000000..85df9198c
--- /dev/null
+++ b/test/reference/record-fill-alpha.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/record-fill-alpha.traps.rgb24.ref.png b/test/reference/record-fill-alpha.traps.rgb24.ref.png
new file mode 100644
index 000000000..85df9198c
--- /dev/null
+++ b/test/reference/record-fill-alpha.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/record-fill-alpha.xfail.png b/test/reference/record-fill-alpha.xfail.png
new file mode 100644
index 000000000..630c02466
--- /dev/null
+++ b/test/reference/record-fill-alpha.xfail.png
Binary files differ
diff --git a/test/reference/record-mesh.base.argb32.ref.png b/test/reference/record-mesh.base.argb32.ref.png
new file mode 100644
index 000000000..4921ba386
--- /dev/null
+++ b/test/reference/record-mesh.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/record-mesh.base.rgb24.ref.png b/test/reference/record-mesh.base.rgb24.ref.png
new file mode 100644
index 000000000..4921ba386
--- /dev/null
+++ b/test/reference/record-mesh.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/record-mesh.image16.rgb24.ref.png b/test/reference/record-mesh.image16.rgb24.ref.png
new file mode 100644
index 000000000..df7bd0396
--- /dev/null
+++ b/test/reference/record-mesh.image16.rgb24.ref.png
Binary files differ
diff --git a/test/reference/record-mesh.ref.png b/test/reference/record-mesh.ref.png
new file mode 100644
index 000000000..4921ba386
--- /dev/null
+++ b/test/reference/record-mesh.ref.png
Binary files differ
diff --git a/test/reference/record-paint-alpha-clip-mask.base.argb32.ref.png b/test/reference/record-paint-alpha-clip-mask.base.argb32.ref.png
new file mode 100644
index 000000000..f7bb8ffee
--- /dev/null
+++ b/test/reference/record-paint-alpha-clip-mask.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/record-paint-alpha-clip-mask.base.rgb24.ref.png b/test/reference/record-paint-alpha-clip-mask.base.rgb24.ref.png
new file mode 100644
index 000000000..f7bb8ffee
--- /dev/null
+++ b/test/reference/record-paint-alpha-clip-mask.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/record-paint-alpha-clip-mask.base.xfail.png b/test/reference/record-paint-alpha-clip-mask.base.xfail.png
new file mode 100644
index 000000000..f7bb8ffee
--- /dev/null
+++ b/test/reference/record-paint-alpha-clip-mask.base.xfail.png
Binary files differ
diff --git a/test/reference/record-paint-alpha-clip-mask.image16.rgb24.ref.png b/test/reference/record-paint-alpha-clip-mask.image16.rgb24.ref.png
new file mode 100644
index 000000000..f069c13b8
--- /dev/null
+++ b/test/reference/record-paint-alpha-clip-mask.image16.rgb24.ref.png
Binary files differ
diff --git a/test/reference/record-paint-alpha-clip-mask.ref.png b/test/reference/record-paint-alpha-clip-mask.ref.png
new file mode 100644
index 000000000..4ee4c41ac
--- /dev/null
+++ b/test/reference/record-paint-alpha-clip-mask.ref.png
Binary files differ
diff --git a/test/reference/record-paint-alpha-clip-mask.traps.argb32.ref.png b/test/reference/record-paint-alpha-clip-mask.traps.argb32.ref.png
new file mode 100644
index 000000000..201bd0d55
--- /dev/null
+++ b/test/reference/record-paint-alpha-clip-mask.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/record-paint-alpha-clip-mask.traps.rgb24.ref.png b/test/reference/record-paint-alpha-clip-mask.traps.rgb24.ref.png
new file mode 100644
index 000000000..201bd0d55
--- /dev/null
+++ b/test/reference/record-paint-alpha-clip-mask.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/record-paint-alpha-clip-mask.xfail.png b/test/reference/record-paint-alpha-clip-mask.xfail.png
new file mode 100644
index 000000000..3bc8cd5d5
--- /dev/null
+++ b/test/reference/record-paint-alpha-clip-mask.xfail.png
Binary files differ
diff --git a/test/reference/record-paint-alpha-clip.base.argb32.ref.png b/test/reference/record-paint-alpha-clip.base.argb32.ref.png
new file mode 100644
index 000000000..9f6841eb1
--- /dev/null
+++ b/test/reference/record-paint-alpha-clip.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/record-paint-alpha-clip.base.rgb24.ref.png b/test/reference/record-paint-alpha-clip.base.rgb24.ref.png
new file mode 100644
index 000000000..9f6841eb1
--- /dev/null
+++ b/test/reference/record-paint-alpha-clip.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/record-paint-alpha-clip.image16.rgb24.ref.png b/test/reference/record-paint-alpha-clip.image16.rgb24.ref.png
new file mode 100644
index 000000000..6eb92c305
--- /dev/null
+++ b/test/reference/record-paint-alpha-clip.image16.rgb24.ref.png
Binary files differ
diff --git a/test/reference/record-paint-alpha-clip.ref.png b/test/reference/record-paint-alpha-clip.ref.png
new file mode 100644
index 000000000..4bad4e8ca
--- /dev/null
+++ b/test/reference/record-paint-alpha-clip.ref.png
Binary files differ
diff --git a/test/reference/record-paint-alpha-clip.traps.argb32.ref.png b/test/reference/record-paint-alpha-clip.traps.argb32.ref.png
new file mode 100644
index 000000000..c1da67e01
--- /dev/null
+++ b/test/reference/record-paint-alpha-clip.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/record-paint-alpha-clip.traps.rgb24.ref.png b/test/reference/record-paint-alpha-clip.traps.rgb24.ref.png
new file mode 100644
index 000000000..c1da67e01
--- /dev/null
+++ b/test/reference/record-paint-alpha-clip.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/record-paint-alpha-solid-clip.base.argb32.ref.png b/test/reference/record-paint-alpha-solid-clip.base.argb32.ref.png
new file mode 100644
index 000000000..59d226d1a
--- /dev/null
+++ b/test/reference/record-paint-alpha-solid-clip.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/record-paint-alpha-solid-clip.base.rgb24.ref.png b/test/reference/record-paint-alpha-solid-clip.base.rgb24.ref.png
new file mode 100644
index 000000000..59d226d1a
--- /dev/null
+++ b/test/reference/record-paint-alpha-solid-clip.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/record-paint-alpha-solid-clip.image16.rgb24.ref.png b/test/reference/record-paint-alpha-solid-clip.image16.rgb24.ref.png
new file mode 100644
index 000000000..111293d7c
--- /dev/null
+++ b/test/reference/record-paint-alpha-solid-clip.image16.rgb24.ref.png
Binary files differ
diff --git a/test/reference/record-paint-alpha-solid-clip.ref.png b/test/reference/record-paint-alpha-solid-clip.ref.png
new file mode 100644
index 000000000..59d226d1a
--- /dev/null
+++ b/test/reference/record-paint-alpha-solid-clip.ref.png
Binary files differ
diff --git a/test/reference/record-paint-alpha-solid-clip.traps.argb32.ref.png b/test/reference/record-paint-alpha-solid-clip.traps.argb32.ref.png
new file mode 100644
index 000000000..2cd2df21c
--- /dev/null
+++ b/test/reference/record-paint-alpha-solid-clip.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/record-paint-alpha-solid-clip.traps.rgb24.ref.png b/test/reference/record-paint-alpha-solid-clip.traps.rgb24.ref.png
new file mode 100644
index 000000000..2cd2df21c
--- /dev/null
+++ b/test/reference/record-paint-alpha-solid-clip.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/record-paint-alpha.base.argb32.ref.png b/test/reference/record-paint-alpha.base.argb32.ref.png
new file mode 100644
index 000000000..65d9c179b
--- /dev/null
+++ b/test/reference/record-paint-alpha.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/record-paint-alpha.base.rgb24.ref.png b/test/reference/record-paint-alpha.base.rgb24.ref.png
new file mode 100644
index 000000000..65d9c179b
--- /dev/null
+++ b/test/reference/record-paint-alpha.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/record-paint-alpha.image16.rgb24.ref.png b/test/reference/record-paint-alpha.image16.rgb24.ref.png
new file mode 100644
index 000000000..12bd89d55
--- /dev/null
+++ b/test/reference/record-paint-alpha.image16.rgb24.ref.png
Binary files differ
diff --git a/test/reference/record-paint-alpha.ref.png b/test/reference/record-paint-alpha.ref.png
new file mode 100644
index 000000000..487b8b622
--- /dev/null
+++ b/test/reference/record-paint-alpha.ref.png
Binary files differ
diff --git a/test/reference/record-paint.base.argb32.ref.png b/test/reference/record-paint.base.argb32.ref.png
new file mode 100644
index 000000000..22cc7a1ae
--- /dev/null
+++ b/test/reference/record-paint.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/record-paint.base.rgb24.ref.png b/test/reference/record-paint.base.rgb24.ref.png
new file mode 100644
index 000000000..22cc7a1ae
--- /dev/null
+++ b/test/reference/record-paint.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/record-paint.ref.png b/test/reference/record-paint.ref.png
new file mode 100644
index 000000000..fff03b363
--- /dev/null
+++ b/test/reference/record-paint.ref.png
Binary files differ
diff --git a/test/reference/record-select-font-face.base.argb32.ref.png b/test/reference/record-select-font-face.base.argb32.ref.png
new file mode 100644
index 000000000..63c7cca8a
--- /dev/null
+++ b/test/reference/record-select-font-face.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/record-select-font-face.base.rgb24.ref.png b/test/reference/record-select-font-face.base.rgb24.ref.png
new file mode 100644
index 000000000..63c7cca8a
--- /dev/null
+++ b/test/reference/record-select-font-face.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/record-select-font-face.image16.rgb24.ref.png b/test/reference/record-select-font-face.image16.rgb24.ref.png
new file mode 100644
index 000000000..88388e5e8
--- /dev/null
+++ b/test/reference/record-select-font-face.image16.rgb24.ref.png
Binary files differ
diff --git a/test/reference/record-select-font-face.ref.png b/test/reference/record-select-font-face.ref.png
new file mode 100644
index 000000000..1334a9a01
--- /dev/null
+++ b/test/reference/record-select-font-face.ref.png
Binary files differ
diff --git a/test/reference/record-select-font-face.xfail.png b/test/reference/record-select-font-face.xfail.png
new file mode 100644
index 000000000..1f57d692f
--- /dev/null
+++ b/test/reference/record-select-font-face.xfail.png
Binary files differ
diff --git a/test/reference/record-self-intersecting.base.argb32.ref.png b/test/reference/record-self-intersecting.base.argb32.ref.png
new file mode 100644
index 000000000..d554d83ee
--- /dev/null
+++ b/test/reference/record-self-intersecting.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/record-self-intersecting.base.rgb24.ref.png b/test/reference/record-self-intersecting.base.rgb24.ref.png
new file mode 100644
index 000000000..d554d83ee
--- /dev/null
+++ b/test/reference/record-self-intersecting.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/record-self-intersecting.image16.rgb24.ref.png b/test/reference/record-self-intersecting.image16.rgb24.ref.png
new file mode 100644
index 000000000..cab3507c9
--- /dev/null
+++ b/test/reference/record-self-intersecting.image16.rgb24.ref.png
Binary files differ
diff --git a/test/reference/record-self-intersecting.ref.png b/test/reference/record-self-intersecting.ref.png
new file mode 100644
index 000000000..d554d83ee
--- /dev/null
+++ b/test/reference/record-self-intersecting.ref.png
Binary files differ
diff --git a/test/reference/record-text-transform.base.argb32.ref.png b/test/reference/record-text-transform.base.argb32.ref.png
new file mode 100644
index 000000000..8e74785f5
--- /dev/null
+++ b/test/reference/record-text-transform.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/record-text-transform.base.rgb24.ref.png b/test/reference/record-text-transform.base.rgb24.ref.png
new file mode 100644
index 000000000..8e74785f5
--- /dev/null
+++ b/test/reference/record-text-transform.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/record-text-transform.image16.rgb24.ref.png b/test/reference/record-text-transform.image16.rgb24.ref.png
new file mode 100644
index 000000000..460389928
--- /dev/null
+++ b/test/reference/record-text-transform.image16.rgb24.ref.png
Binary files differ
diff --git a/test/reference/record-text-transform.ref.png b/test/reference/record-text-transform.ref.png
new file mode 100644
index 000000000..4603bc528
--- /dev/null
+++ b/test/reference/record-text-transform.ref.png
Binary files differ
diff --git a/test/reference/record1414x-fill-alpha.base.argb32.ref.png b/test/reference/record1414x-fill-alpha.base.argb32.ref.png
new file mode 100644
index 000000000..69673434f
--- /dev/null
+++ b/test/reference/record1414x-fill-alpha.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/record1414x-fill-alpha.base.rgb24.ref.png b/test/reference/record1414x-fill-alpha.base.rgb24.ref.png
new file mode 100644
index 000000000..69673434f
--- /dev/null
+++ b/test/reference/record1414x-fill-alpha.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/record1414x-fill-alpha.base.xfail.png b/test/reference/record1414x-fill-alpha.base.xfail.png
new file mode 100644
index 000000000..69673434f
--- /dev/null
+++ b/test/reference/record1414x-fill-alpha.base.xfail.png
Binary files differ
diff --git a/test/reference/record1414x-fill-alpha.ref.png b/test/reference/record1414x-fill-alpha.ref.png
new file mode 100644
index 000000000..8e9f3226a
--- /dev/null
+++ b/test/reference/record1414x-fill-alpha.ref.png
Binary files differ
diff --git a/test/reference/record1414x-fill-alpha.xfail.png b/test/reference/record1414x-fill-alpha.xfail.png
new file mode 100644
index 000000000..9393186f6
--- /dev/null
+++ b/test/reference/record1414x-fill-alpha.xfail.png
Binary files differ
diff --git a/test/reference/record1414x-paint-alpha-clip-mask.base.argb32.ref.png b/test/reference/record1414x-paint-alpha-clip-mask.base.argb32.ref.png
new file mode 100644
index 000000000..0ae9861d5
--- /dev/null
+++ b/test/reference/record1414x-paint-alpha-clip-mask.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/record1414x-paint-alpha-clip-mask.base.rgb24.ref.png b/test/reference/record1414x-paint-alpha-clip-mask.base.rgb24.ref.png
new file mode 100644
index 000000000..0ae9861d5
--- /dev/null
+++ b/test/reference/record1414x-paint-alpha-clip-mask.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/record1414x-paint-alpha-clip-mask.ref.png b/test/reference/record1414x-paint-alpha-clip-mask.ref.png
new file mode 100644
index 000000000..e381b73aa
--- /dev/null
+++ b/test/reference/record1414x-paint-alpha-clip-mask.ref.png
Binary files differ
diff --git a/test/reference/record1414x-paint-alpha-clip.base.argb32.ref.png b/test/reference/record1414x-paint-alpha-clip.base.argb32.ref.png
new file mode 100644
index 000000000..d1b57ae3c
--- /dev/null
+++ b/test/reference/record1414x-paint-alpha-clip.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/record1414x-paint-alpha-clip.base.rgb24.ref.png b/test/reference/record1414x-paint-alpha-clip.base.rgb24.ref.png
new file mode 100644
index 000000000..d1b57ae3c
--- /dev/null
+++ b/test/reference/record1414x-paint-alpha-clip.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/record1414x-paint-alpha-clip.ref.png b/test/reference/record1414x-paint-alpha-clip.ref.png
new file mode 100644
index 000000000..6c11f1d96
--- /dev/null
+++ b/test/reference/record1414x-paint-alpha-clip.ref.png
Binary files differ
diff --git a/test/reference/record1414x-paint-alpha-solid-clip.base.argb32.ref.png b/test/reference/record1414x-paint-alpha-solid-clip.base.argb32.ref.png
new file mode 100644
index 000000000..86d3f51b2
--- /dev/null
+++ b/test/reference/record1414x-paint-alpha-solid-clip.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/record1414x-paint-alpha-solid-clip.base.rgb24.ref.png b/test/reference/record1414x-paint-alpha-solid-clip.base.rgb24.ref.png
new file mode 100644
index 000000000..86d3f51b2
--- /dev/null
+++ b/test/reference/record1414x-paint-alpha-solid-clip.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/record1414x-paint-alpha-solid-clip.ref.png b/test/reference/record1414x-paint-alpha-solid-clip.ref.png
new file mode 100644
index 000000000..7a8e59462
--- /dev/null
+++ b/test/reference/record1414x-paint-alpha-solid-clip.ref.png
Binary files differ
diff --git a/test/reference/record1414x-paint-alpha.base.argb32.ref.png b/test/reference/record1414x-paint-alpha.base.argb32.ref.png
new file mode 100644
index 000000000..eee74ced0
--- /dev/null
+++ b/test/reference/record1414x-paint-alpha.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/record1414x-paint-alpha.base.rgb24.ref.png b/test/reference/record1414x-paint-alpha.base.rgb24.ref.png
new file mode 100644
index 000000000..eee74ced0
--- /dev/null
+++ b/test/reference/record1414x-paint-alpha.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/record1414x-paint-alpha.ref.png b/test/reference/record1414x-paint-alpha.ref.png
new file mode 100644
index 000000000..eee74ced0
--- /dev/null
+++ b/test/reference/record1414x-paint-alpha.ref.png
Binary files differ
diff --git a/test/reference/record1414x-paint.base.argb32.ref.png b/test/reference/record1414x-paint.base.argb32.ref.png
new file mode 100644
index 000000000..e0a1341c9
--- /dev/null
+++ b/test/reference/record1414x-paint.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/record1414x-paint.base.rgb24.ref.png b/test/reference/record1414x-paint.base.rgb24.ref.png
new file mode 100644
index 000000000..e0a1341c9
--- /dev/null
+++ b/test/reference/record1414x-paint.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/record1414x-paint.ref.png b/test/reference/record1414x-paint.ref.png
new file mode 100644
index 000000000..e0a1341c9
--- /dev/null
+++ b/test/reference/record1414x-paint.ref.png
Binary files differ
diff --git a/test/reference/record1414x-select-font-face.base.argb32.ref.png b/test/reference/record1414x-select-font-face.base.argb32.ref.png
new file mode 100644
index 000000000..ac30b23a3
--- /dev/null
+++ b/test/reference/record1414x-select-font-face.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/record1414x-select-font-face.base.rgb24.ref.png b/test/reference/record1414x-select-font-face.base.rgb24.ref.png
new file mode 100644
index 000000000..ac30b23a3
--- /dev/null
+++ b/test/reference/record1414x-select-font-face.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/record1414x-select-font-face.ref.png b/test/reference/record1414x-select-font-face.ref.png
new file mode 100644
index 000000000..6c52067b1
--- /dev/null
+++ b/test/reference/record1414x-select-font-face.ref.png
Binary files differ
diff --git a/test/reference/record1414x-self-intersecting.base.argb32.ref.png b/test/reference/record1414x-self-intersecting.base.argb32.ref.png
new file mode 100644
index 000000000..62f91c9e7
--- /dev/null
+++ b/test/reference/record1414x-self-intersecting.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/record1414x-self-intersecting.base.rgb24.ref.png b/test/reference/record1414x-self-intersecting.base.rgb24.ref.png
new file mode 100644
index 000000000..62f91c9e7
--- /dev/null
+++ b/test/reference/record1414x-self-intersecting.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/record1414x-self-intersecting.ref.png b/test/reference/record1414x-self-intersecting.ref.png
new file mode 100644
index 000000000..62f91c9e7
--- /dev/null
+++ b/test/reference/record1414x-self-intersecting.ref.png
Binary files differ
diff --git a/test/reference/record1414x-text-transform.base.argb32.ref.png b/test/reference/record1414x-text-transform.base.argb32.ref.png
new file mode 100644
index 000000000..624e3683a
--- /dev/null
+++ b/test/reference/record1414x-text-transform.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/record1414x-text-transform.base.rgb24.ref.png b/test/reference/record1414x-text-transform.base.rgb24.ref.png
new file mode 100644
index 000000000..624e3683a
--- /dev/null
+++ b/test/reference/record1414x-text-transform.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/record1414x-text-transform.ref.png b/test/reference/record1414x-text-transform.ref.png
new file mode 100644
index 000000000..3bb8b1212
--- /dev/null
+++ b/test/reference/record1414x-text-transform.ref.png
Binary files differ
diff --git a/test/reference/record2x-fill-alpha.base.argb32.ref.png b/test/reference/record2x-fill-alpha.base.argb32.ref.png
new file mode 100644
index 000000000..b96ff8d00
--- /dev/null
+++ b/test/reference/record2x-fill-alpha.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/record2x-fill-alpha.base.rgb24.ref.png b/test/reference/record2x-fill-alpha.base.rgb24.ref.png
new file mode 100644
index 000000000..b96ff8d00
--- /dev/null
+++ b/test/reference/record2x-fill-alpha.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/record2x-fill-alpha.base.xfail.png b/test/reference/record2x-fill-alpha.base.xfail.png
new file mode 100644
index 000000000..b96ff8d00
--- /dev/null
+++ b/test/reference/record2x-fill-alpha.base.xfail.png
Binary files differ
diff --git a/test/reference/record2x-fill-alpha.ref.png b/test/reference/record2x-fill-alpha.ref.png
new file mode 100644
index 000000000..91787bd9b
--- /dev/null
+++ b/test/reference/record2x-fill-alpha.ref.png
Binary files differ
diff --git a/test/reference/record2x-fill-alpha.xfail.png b/test/reference/record2x-fill-alpha.xfail.png
new file mode 100644
index 000000000..3b70c0194
--- /dev/null
+++ b/test/reference/record2x-fill-alpha.xfail.png
Binary files differ
diff --git a/test/reference/record2x-paint-alpha-clip-mask.base.argb32.ref.png b/test/reference/record2x-paint-alpha-clip-mask.base.argb32.ref.png
new file mode 100644
index 000000000..ebfa1db5d
--- /dev/null
+++ b/test/reference/record2x-paint-alpha-clip-mask.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/record2x-paint-alpha-clip-mask.base.rgb24.ref.png b/test/reference/record2x-paint-alpha-clip-mask.base.rgb24.ref.png
new file mode 100644
index 000000000..ebfa1db5d
--- /dev/null
+++ b/test/reference/record2x-paint-alpha-clip-mask.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/record2x-paint-alpha-clip-mask.ref.png b/test/reference/record2x-paint-alpha-clip-mask.ref.png
new file mode 100644
index 000000000..dd1ca05f9
--- /dev/null
+++ b/test/reference/record2x-paint-alpha-clip-mask.ref.png
Binary files differ
diff --git a/test/reference/record2x-paint-alpha-clip.base.argb32.ref.png b/test/reference/record2x-paint-alpha-clip.base.argb32.ref.png
new file mode 100644
index 000000000..b3829d56e
--- /dev/null
+++ b/test/reference/record2x-paint-alpha-clip.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/record2x-paint-alpha-clip.base.rgb24.ref.png b/test/reference/record2x-paint-alpha-clip.base.rgb24.ref.png
new file mode 100644
index 000000000..b3829d56e
--- /dev/null
+++ b/test/reference/record2x-paint-alpha-clip.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/record2x-paint-alpha-clip.ref.png b/test/reference/record2x-paint-alpha-clip.ref.png
new file mode 100644
index 000000000..b3829d56e
--- /dev/null
+++ b/test/reference/record2x-paint-alpha-clip.ref.png
Binary files differ
diff --git a/test/reference/record2x-paint-alpha-solid-clip.base.argb32.ref.png b/test/reference/record2x-paint-alpha-solid-clip.base.argb32.ref.png
new file mode 100644
index 000000000..06e350f35
--- /dev/null
+++ b/test/reference/record2x-paint-alpha-solid-clip.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/record2x-paint-alpha-solid-clip.base.rgb24.ref.png b/test/reference/record2x-paint-alpha-solid-clip.base.rgb24.ref.png
new file mode 100644
index 000000000..06e350f35
--- /dev/null
+++ b/test/reference/record2x-paint-alpha-solid-clip.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/record2x-paint-alpha-solid-clip.ref.png b/test/reference/record2x-paint-alpha-solid-clip.ref.png
new file mode 100644
index 000000000..06e350f35
--- /dev/null
+++ b/test/reference/record2x-paint-alpha-solid-clip.ref.png
Binary files differ
diff --git a/test/reference/record2x-paint-alpha.base.argb32.ref.png b/test/reference/record2x-paint-alpha.base.argb32.ref.png
new file mode 100644
index 000000000..3a02b675c
--- /dev/null
+++ b/test/reference/record2x-paint-alpha.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/record2x-paint-alpha.base.rgb24.ref.png b/test/reference/record2x-paint-alpha.base.rgb24.ref.png
new file mode 100644
index 000000000..3a02b675c
--- /dev/null
+++ b/test/reference/record2x-paint-alpha.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/record2x-paint-alpha.ref.png b/test/reference/record2x-paint-alpha.ref.png
new file mode 100644
index 000000000..3a02b675c
--- /dev/null
+++ b/test/reference/record2x-paint-alpha.ref.png
Binary files differ
diff --git a/test/reference/record2x-paint.base.argb32.ref.png b/test/reference/record2x-paint.base.argb32.ref.png
new file mode 100644
index 000000000..792a1d033
--- /dev/null
+++ b/test/reference/record2x-paint.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/record2x-paint.base.rgb24.ref.png b/test/reference/record2x-paint.base.rgb24.ref.png
new file mode 100644
index 000000000..792a1d033
--- /dev/null
+++ b/test/reference/record2x-paint.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/record2x-paint.ref.png b/test/reference/record2x-paint.ref.png
new file mode 100644
index 000000000..792a1d033
--- /dev/null
+++ b/test/reference/record2x-paint.ref.png
Binary files differ
diff --git a/test/reference/record2x-select-font-face.base.argb32.ref.png b/test/reference/record2x-select-font-face.base.argb32.ref.png
new file mode 100644
index 000000000..f0b268f5a
--- /dev/null
+++ b/test/reference/record2x-select-font-face.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/record2x-select-font-face.base.rgb24.ref.png b/test/reference/record2x-select-font-face.base.rgb24.ref.png
new file mode 100644
index 000000000..f0b268f5a
--- /dev/null
+++ b/test/reference/record2x-select-font-face.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/record2x-select-font-face.ref.png b/test/reference/record2x-select-font-face.ref.png
new file mode 100644
index 000000000..7a99795e4
--- /dev/null
+++ b/test/reference/record2x-select-font-face.ref.png
Binary files differ
diff --git a/test/reference/record2x-self-intersecting.base.argb32.ref.png b/test/reference/record2x-self-intersecting.base.argb32.ref.png
new file mode 100644
index 000000000..2836dae03
--- /dev/null
+++ b/test/reference/record2x-self-intersecting.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/record2x-self-intersecting.base.rgb24.ref.png b/test/reference/record2x-self-intersecting.base.rgb24.ref.png
new file mode 100644
index 000000000..2836dae03
--- /dev/null
+++ b/test/reference/record2x-self-intersecting.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/record2x-self-intersecting.ref.png b/test/reference/record2x-self-intersecting.ref.png
new file mode 100644
index 000000000..2836dae03
--- /dev/null
+++ b/test/reference/record2x-self-intersecting.ref.png
Binary files differ
diff --git a/test/reference/record2x-text-transform.base.argb32.ref.png b/test/reference/record2x-text-transform.base.argb32.ref.png
new file mode 100644
index 000000000..9811c1b5f
--- /dev/null
+++ b/test/reference/record2x-text-transform.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/record2x-text-transform.base.rgb24.ref.png b/test/reference/record2x-text-transform.base.rgb24.ref.png
new file mode 100644
index 000000000..9811c1b5f
--- /dev/null
+++ b/test/reference/record2x-text-transform.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/record2x-text-transform.ref.png b/test/reference/record2x-text-transform.ref.png
new file mode 100644
index 000000000..6c21785ef
--- /dev/null
+++ b/test/reference/record2x-text-transform.ref.png
Binary files differ
diff --git a/test/reference/record90-fill-alpha.base.argb32.ref.png b/test/reference/record90-fill-alpha.base.argb32.ref.png
new file mode 100644
index 000000000..4c743f5fc
--- /dev/null
+++ b/test/reference/record90-fill-alpha.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/record90-fill-alpha.base.rgb24.ref.png b/test/reference/record90-fill-alpha.base.rgb24.ref.png
new file mode 100644
index 000000000..4c743f5fc
--- /dev/null
+++ b/test/reference/record90-fill-alpha.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/record90-fill-alpha.ref.png b/test/reference/record90-fill-alpha.ref.png
new file mode 100644
index 000000000..bf3b260a2
--- /dev/null
+++ b/test/reference/record90-fill-alpha.ref.png
Binary files differ
diff --git a/test/reference/record90-fill-alpha.xfail.png b/test/reference/record90-fill-alpha.xfail.png
new file mode 100644
index 000000000..ad1e65c4c
--- /dev/null
+++ b/test/reference/record90-fill-alpha.xfail.png
Binary files differ
diff --git a/test/reference/record90-paint-alpha-clip-mask.base.argb32.ref.png b/test/reference/record90-paint-alpha-clip-mask.base.argb32.ref.png
new file mode 100644
index 000000000..976192c1a
--- /dev/null
+++ b/test/reference/record90-paint-alpha-clip-mask.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/record90-paint-alpha-clip-mask.base.rgb24.ref.png b/test/reference/record90-paint-alpha-clip-mask.base.rgb24.ref.png
new file mode 100644
index 000000000..976192c1a
--- /dev/null
+++ b/test/reference/record90-paint-alpha-clip-mask.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/record90-paint-alpha-clip-mask.ref.png b/test/reference/record90-paint-alpha-clip-mask.ref.png
new file mode 100644
index 000000000..5c2106ba7
--- /dev/null
+++ b/test/reference/record90-paint-alpha-clip-mask.ref.png
Binary files differ
diff --git a/test/reference/record90-paint-alpha-clip-mask.xfail.png b/test/reference/record90-paint-alpha-clip-mask.xfail.png
new file mode 100644
index 000000000..bad037fee
--- /dev/null
+++ b/test/reference/record90-paint-alpha-clip-mask.xfail.png
Binary files differ
diff --git a/test/reference/record90-paint-alpha-clip.base.argb32.ref.png b/test/reference/record90-paint-alpha-clip.base.argb32.ref.png
new file mode 100644
index 000000000..d687e3b4d
--- /dev/null
+++ b/test/reference/record90-paint-alpha-clip.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/record90-paint-alpha-clip.base.rgb24.ref.png b/test/reference/record90-paint-alpha-clip.base.rgb24.ref.png
new file mode 100644
index 000000000..d687e3b4d
--- /dev/null
+++ b/test/reference/record90-paint-alpha-clip.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/record90-paint-alpha-clip.ref.png b/test/reference/record90-paint-alpha-clip.ref.png
new file mode 100644
index 000000000..3fae802ac
--- /dev/null
+++ b/test/reference/record90-paint-alpha-clip.ref.png
Binary files differ
diff --git a/test/reference/record90-paint-alpha-clip.xfail.png b/test/reference/record90-paint-alpha-clip.xfail.png
new file mode 100644
index 000000000..d687e3b4d
--- /dev/null
+++ b/test/reference/record90-paint-alpha-clip.xfail.png
Binary files differ
diff --git a/test/reference/record90-paint-alpha-solid-clip.base.argb32.ref.png b/test/reference/record90-paint-alpha-solid-clip.base.argb32.ref.png
new file mode 100644
index 000000000..48a01eaaa
--- /dev/null
+++ b/test/reference/record90-paint-alpha-solid-clip.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/record90-paint-alpha-solid-clip.base.rgb24.ref.png b/test/reference/record90-paint-alpha-solid-clip.base.rgb24.ref.png
new file mode 100644
index 000000000..48a01eaaa
--- /dev/null
+++ b/test/reference/record90-paint-alpha-solid-clip.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/record90-paint-alpha-solid-clip.ref.png b/test/reference/record90-paint-alpha-solid-clip.ref.png
new file mode 100644
index 000000000..17bff57c5
--- /dev/null
+++ b/test/reference/record90-paint-alpha-solid-clip.ref.png
Binary files differ
diff --git a/test/reference/record90-paint-alpha.base.argb32.ref.png b/test/reference/record90-paint-alpha.base.argb32.ref.png
new file mode 100644
index 000000000..57aa95d37
--- /dev/null
+++ b/test/reference/record90-paint-alpha.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/record90-paint-alpha.base.rgb24.ref.png b/test/reference/record90-paint-alpha.base.rgb24.ref.png
new file mode 100644
index 000000000..57aa95d37
--- /dev/null
+++ b/test/reference/record90-paint-alpha.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/record90-paint-alpha.ref.png b/test/reference/record90-paint-alpha.ref.png
new file mode 100644
index 000000000..5e9cb58d9
--- /dev/null
+++ b/test/reference/record90-paint-alpha.ref.png
Binary files differ
diff --git a/test/reference/record90-paint.base.argb32.ref.png b/test/reference/record90-paint.base.argb32.ref.png
new file mode 100644
index 000000000..22cc7a1ae
--- /dev/null
+++ b/test/reference/record90-paint.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/record90-paint.base.rgb24.ref.png b/test/reference/record90-paint.base.rgb24.ref.png
new file mode 100644
index 000000000..22cc7a1ae
--- /dev/null
+++ b/test/reference/record90-paint.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/record90-paint.ref.png b/test/reference/record90-paint.ref.png
new file mode 100644
index 000000000..22cc7a1ae
--- /dev/null
+++ b/test/reference/record90-paint.ref.png
Binary files differ
diff --git a/test/reference/record90-select-font-face.base.argb32.ref.png b/test/reference/record90-select-font-face.base.argb32.ref.png
new file mode 100644
index 000000000..13ed998f2
--- /dev/null
+++ b/test/reference/record90-select-font-face.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/record90-select-font-face.base.rgb24.ref.png b/test/reference/record90-select-font-face.base.rgb24.ref.png
new file mode 100644
index 000000000..13ed998f2
--- /dev/null
+++ b/test/reference/record90-select-font-face.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/record90-select-font-face.ref.png b/test/reference/record90-select-font-face.ref.png
new file mode 100644
index 000000000..189a3154d
--- /dev/null
+++ b/test/reference/record90-select-font-face.ref.png
Binary files differ
diff --git a/test/reference/record90-self-intersecting.base.argb32.ref.png b/test/reference/record90-self-intersecting.base.argb32.ref.png
new file mode 100644
index 000000000..7df179e94
--- /dev/null
+++ b/test/reference/record90-self-intersecting.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/record90-self-intersecting.base.rgb24.ref.png b/test/reference/record90-self-intersecting.base.rgb24.ref.png
new file mode 100644
index 000000000..7df179e94
--- /dev/null
+++ b/test/reference/record90-self-intersecting.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/record90-self-intersecting.ref.png b/test/reference/record90-self-intersecting.ref.png
new file mode 100644
index 000000000..15ce4c005
--- /dev/null
+++ b/test/reference/record90-self-intersecting.ref.png
Binary files differ
diff --git a/test/reference/record90-text-transform.base.argb32.ref.png b/test/reference/record90-text-transform.base.argb32.ref.png
new file mode 100644
index 000000000..e8fa7225f
--- /dev/null
+++ b/test/reference/record90-text-transform.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/record90-text-transform.base.rgb24.ref.png b/test/reference/record90-text-transform.base.rgb24.ref.png
new file mode 100644
index 000000000..e8fa7225f
--- /dev/null
+++ b/test/reference/record90-text-transform.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/record90-text-transform.ref.png b/test/reference/record90-text-transform.ref.png
new file mode 100644
index 000000000..22f6c1f0c
--- /dev/null
+++ b/test/reference/record90-text-transform.ref.png
Binary files differ
diff --git a/test/reference/recordflip-fill-alpha.ref.png b/test/reference/recordflip-fill-alpha.ref.png
new file mode 100644
index 000000000..289a91505
--- /dev/null
+++ b/test/reference/recordflip-fill-alpha.ref.png
Binary files differ
diff --git a/test/reference/recordflip-paint-alpha-clip-mask.ref.png b/test/reference/recordflip-paint-alpha-clip-mask.ref.png
new file mode 100644
index 000000000..842fa35ae
--- /dev/null
+++ b/test/reference/recordflip-paint-alpha-clip-mask.ref.png
Binary files differ
diff --git a/test/reference/recordflip-paint-alpha-clip.ref.png b/test/reference/recordflip-paint-alpha-clip.ref.png
new file mode 100644
index 000000000..d619b6d60
--- /dev/null
+++ b/test/reference/recordflip-paint-alpha-clip.ref.png
Binary files differ
diff --git a/test/reference/recordflip-paint-alpha-solid-clip.ref.png b/test/reference/recordflip-paint-alpha-solid-clip.ref.png
new file mode 100644
index 000000000..10dde68c5
--- /dev/null
+++ b/test/reference/recordflip-paint-alpha-solid-clip.ref.png
Binary files differ
diff --git a/test/reference/recordflip-paint-alpha.ref.png b/test/reference/recordflip-paint-alpha.ref.png
new file mode 100644
index 000000000..599acfba2
--- /dev/null
+++ b/test/reference/recordflip-paint-alpha.ref.png
Binary files differ
diff --git a/test/reference/recordflip-paint.ref.png b/test/reference/recordflip-paint.ref.png
new file mode 100644
index 000000000..22cc7a1ae
--- /dev/null
+++ b/test/reference/recordflip-paint.ref.png
Binary files differ
diff --git a/test/reference/recordflip-select-font-face.ref.png b/test/reference/recordflip-select-font-face.ref.png
new file mode 100644
index 000000000..eb710858c
--- /dev/null
+++ b/test/reference/recordflip-select-font-face.ref.png
Binary files differ
diff --git a/test/reference/recordflip-self-intersecting.ref.png b/test/reference/recordflip-self-intersecting.ref.png
new file mode 100644
index 000000000..d554d83ee
--- /dev/null
+++ b/test/reference/recordflip-self-intersecting.ref.png
Binary files differ
diff --git a/test/reference/recordflip-text-transform.ref.png b/test/reference/recordflip-text-transform.ref.png
new file mode 100644
index 000000000..31784d735
--- /dev/null
+++ b/test/reference/recordflip-text-transform.ref.png
Binary files differ
diff --git a/test/reference/recordflip-whole-fill-alpha.ref.png b/test/reference/recordflip-whole-fill-alpha.ref.png
new file mode 100644
index 000000000..289a91505
--- /dev/null
+++ b/test/reference/recordflip-whole-fill-alpha.ref.png
Binary files differ
diff --git a/test/reference/recordflip-whole-paint-alpha-clip-mask.ref.png b/test/reference/recordflip-whole-paint-alpha-clip-mask.ref.png
new file mode 100644
index 000000000..842fa35ae
--- /dev/null
+++ b/test/reference/recordflip-whole-paint-alpha-clip-mask.ref.png
Binary files differ
diff --git a/test/reference/recordflip-whole-paint-alpha-clip.ref.png b/test/reference/recordflip-whole-paint-alpha-clip.ref.png
new file mode 100644
index 000000000..d619b6d60
--- /dev/null
+++ b/test/reference/recordflip-whole-paint-alpha-clip.ref.png
Binary files differ
diff --git a/test/reference/recordflip-whole-paint-alpha-solid-clip.ref.png b/test/reference/recordflip-whole-paint-alpha-solid-clip.ref.png
new file mode 100644
index 000000000..10dde68c5
--- /dev/null
+++ b/test/reference/recordflip-whole-paint-alpha-solid-clip.ref.png
Binary files differ
diff --git a/test/reference/recordflip-whole-paint-alpha.ref.png b/test/reference/recordflip-whole-paint-alpha.ref.png
new file mode 100644
index 000000000..599acfba2
--- /dev/null
+++ b/test/reference/recordflip-whole-paint-alpha.ref.png
Binary files differ
diff --git a/test/reference/recordflip-whole-paint.ref.png b/test/reference/recordflip-whole-paint.ref.png
new file mode 100644
index 000000000..22cc7a1ae
--- /dev/null
+++ b/test/reference/recordflip-whole-paint.ref.png
Binary files differ
diff --git a/test/reference/recordflip-whole-select-font-face.ref.png b/test/reference/recordflip-whole-select-font-face.ref.png
new file mode 100644
index 000000000..eb710858c
--- /dev/null
+++ b/test/reference/recordflip-whole-select-font-face.ref.png
Binary files differ
diff --git a/test/reference/recordflip-whole-self-intersecting.ref.png b/test/reference/recordflip-whole-self-intersecting.ref.png
new file mode 100644
index 000000000..d554d83ee
--- /dev/null
+++ b/test/reference/recordflip-whole-self-intersecting.ref.png
Binary files differ
diff --git a/test/reference/recordflip-whole-text-transform.ref.png b/test/reference/recordflip-whole-text-transform.ref.png
new file mode 100644
index 000000000..31784d735
--- /dev/null
+++ b/test/reference/recordflip-whole-text-transform.ref.png
Binary files differ
diff --git a/test/reference/recording-surface-extend-none.argb32.ref.png b/test/reference/recording-surface-extend-none.argb32.ref.png
new file mode 100644
index 000000000..13898879d
--- /dev/null
+++ b/test/reference/recording-surface-extend-none.argb32.ref.png
Binary files differ
diff --git a/test/reference/recording-surface-extend-none.base.argb32.ref.png b/test/reference/recording-surface-extend-none.base.argb32.ref.png
new file mode 100644
index 000000000..d612250af
--- /dev/null
+++ b/test/reference/recording-surface-extend-none.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/recording-surface-extend-none.base.rgb24.ref.png b/test/reference/recording-surface-extend-none.base.rgb24.ref.png
new file mode 100644
index 000000000..0a57b44e7
--- /dev/null
+++ b/test/reference/recording-surface-extend-none.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/recording-surface-extend-none.rgb24.ref.png b/test/reference/recording-surface-extend-none.rgb24.ref.png
new file mode 100644
index 000000000..6a8b81e68
--- /dev/null
+++ b/test/reference/recording-surface-extend-none.rgb24.ref.png
Binary files differ
diff --git a/test/reference/recording-surface-extend-none.traps.argb32.ref.png b/test/reference/recording-surface-extend-none.traps.argb32.ref.png
new file mode 100644
index 000000000..d612250af
--- /dev/null
+++ b/test/reference/recording-surface-extend-none.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/recording-surface-extend-none.traps.rgb24.ref.png b/test/reference/recording-surface-extend-none.traps.rgb24.ref.png
new file mode 100644
index 000000000..0a57b44e7
--- /dev/null
+++ b/test/reference/recording-surface-extend-none.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/recording-surface-extend-pad.argb32.ref.png b/test/reference/recording-surface-extend-pad.argb32.ref.png
new file mode 100644
index 000000000..9efed65be
--- /dev/null
+++ b/test/reference/recording-surface-extend-pad.argb32.ref.png
Binary files differ
diff --git a/test/reference/recording-surface-extend-pad.base.argb32.ref.png b/test/reference/recording-surface-extend-pad.base.argb32.ref.png
new file mode 100644
index 000000000..7ec94c5bc
--- /dev/null
+++ b/test/reference/recording-surface-extend-pad.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/recording-surface-extend-pad.base.rgb24.ref.png b/test/reference/recording-surface-extend-pad.base.rgb24.ref.png
new file mode 100644
index 000000000..8a064cd46
--- /dev/null
+++ b/test/reference/recording-surface-extend-pad.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/recording-surface-extend-pad.rgb24.ref.png b/test/reference/recording-surface-extend-pad.rgb24.ref.png
new file mode 100644
index 000000000..7336890c4
--- /dev/null
+++ b/test/reference/recording-surface-extend-pad.rgb24.ref.png
Binary files differ
diff --git a/test/reference/recording-surface-extend-pad.traps.argb32.ref.png b/test/reference/recording-surface-extend-pad.traps.argb32.ref.png
new file mode 100644
index 000000000..7ec94c5bc
--- /dev/null
+++ b/test/reference/recording-surface-extend-pad.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/recording-surface-extend-pad.traps.rgb24.ref.png b/test/reference/recording-surface-extend-pad.traps.rgb24.ref.png
new file mode 100644
index 000000000..8a064cd46
--- /dev/null
+++ b/test/reference/recording-surface-extend-pad.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/recording-surface-extend-reflect.argb32.ref.png b/test/reference/recording-surface-extend-reflect.argb32.ref.png
new file mode 100644
index 000000000..f63ccee85
--- /dev/null
+++ b/test/reference/recording-surface-extend-reflect.argb32.ref.png
Binary files differ
diff --git a/test/reference/recording-surface-extend-reflect.base.argb32.ref.png b/test/reference/recording-surface-extend-reflect.base.argb32.ref.png
new file mode 100644
index 000000000..4699d42f4
--- /dev/null
+++ b/test/reference/recording-surface-extend-reflect.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/recording-surface-extend-reflect.base.rgb24.ref.png b/test/reference/recording-surface-extend-reflect.base.rgb24.ref.png
new file mode 100644
index 000000000..4975d7559
--- /dev/null
+++ b/test/reference/recording-surface-extend-reflect.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/recording-surface-extend-reflect.rgb24.ref.png b/test/reference/recording-surface-extend-reflect.rgb24.ref.png
new file mode 100644
index 000000000..26d4ae916
--- /dev/null
+++ b/test/reference/recording-surface-extend-reflect.rgb24.ref.png
Binary files differ
diff --git a/test/reference/recording-surface-extend-reflect.traps.argb32.ref.png b/test/reference/recording-surface-extend-reflect.traps.argb32.ref.png
new file mode 100644
index 000000000..4699d42f4
--- /dev/null
+++ b/test/reference/recording-surface-extend-reflect.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/recording-surface-extend-reflect.traps.rgb24.ref.png b/test/reference/recording-surface-extend-reflect.traps.rgb24.ref.png
new file mode 100644
index 000000000..4975d7559
--- /dev/null
+++ b/test/reference/recording-surface-extend-reflect.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/recording-surface-extend-repeat.argb32.ref.png b/test/reference/recording-surface-extend-repeat.argb32.ref.png
new file mode 100644
index 000000000..99d880c8e
--- /dev/null
+++ b/test/reference/recording-surface-extend-repeat.argb32.ref.png
Binary files differ
diff --git a/test/reference/recording-surface-extend-repeat.base.argb32.ref.png b/test/reference/recording-surface-extend-repeat.base.argb32.ref.png
new file mode 100644
index 000000000..305c022a0
--- /dev/null
+++ b/test/reference/recording-surface-extend-repeat.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/recording-surface-extend-repeat.base.rgb24.ref.png b/test/reference/recording-surface-extend-repeat.base.rgb24.ref.png
new file mode 100644
index 000000000..c3e296cbe
--- /dev/null
+++ b/test/reference/recording-surface-extend-repeat.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/recording-surface-extend-repeat.rgb24.ref.png b/test/reference/recording-surface-extend-repeat.rgb24.ref.png
new file mode 100644
index 000000000..474e6e9e8
--- /dev/null
+++ b/test/reference/recording-surface-extend-repeat.rgb24.ref.png
Binary files differ
diff --git a/test/reference/recording-surface-extend-repeat.traps.argb32.ref.png b/test/reference/recording-surface-extend-repeat.traps.argb32.ref.png
new file mode 100644
index 000000000..305c022a0
--- /dev/null
+++ b/test/reference/recording-surface-extend-repeat.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/recording-surface-extend-repeat.traps.rgb24.ref.png b/test/reference/recording-surface-extend-repeat.traps.rgb24.ref.png
new file mode 100644
index 000000000..c3e296cbe
--- /dev/null
+++ b/test/reference/recording-surface-extend-repeat.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/recording-surface-over.argb32.ref.png b/test/reference/recording-surface-over.argb32.ref.png
new file mode 100644
index 000000000..13898879d
--- /dev/null
+++ b/test/reference/recording-surface-over.argb32.ref.png
Binary files differ
diff --git a/test/reference/recording-surface-over.base.argb32.ref.png b/test/reference/recording-surface-over.base.argb32.ref.png
new file mode 100644
index 000000000..d612250af
--- /dev/null
+++ b/test/reference/recording-surface-over.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/recording-surface-over.base.rgb24.ref.png b/test/reference/recording-surface-over.base.rgb24.ref.png
new file mode 100644
index 000000000..0a57b44e7
--- /dev/null
+++ b/test/reference/recording-surface-over.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/recording-surface-over.gl.argb32.ref.png b/test/reference/recording-surface-over.gl.argb32.ref.png
new file mode 100644
index 000000000..50e6f5ab0
--- /dev/null
+++ b/test/reference/recording-surface-over.gl.argb32.ref.png
Binary files differ
diff --git a/test/reference/recording-surface-over.image16.ref.png b/test/reference/recording-surface-over.image16.ref.png
new file mode 100644
index 000000000..020289389
--- /dev/null
+++ b/test/reference/recording-surface-over.image16.ref.png
Binary files differ
diff --git a/test/reference/recording-surface-over.pdf.argb32.ref.png b/test/reference/recording-surface-over.pdf.argb32.ref.png
new file mode 100644
index 000000000..a06386b12
--- /dev/null
+++ b/test/reference/recording-surface-over.pdf.argb32.ref.png
Binary files differ
diff --git a/test/reference/recording-surface-over.pdf.rgb24.ref.png b/test/reference/recording-surface-over.pdf.rgb24.ref.png
new file mode 100644
index 000000000..bf69f9ea3
--- /dev/null
+++ b/test/reference/recording-surface-over.pdf.rgb24.ref.png
Binary files differ
diff --git a/test/reference/recording-surface-over.ps.argb32.ref.png b/test/reference/recording-surface-over.ps.argb32.ref.png
new file mode 100644
index 000000000..ac6632316
--- /dev/null
+++ b/test/reference/recording-surface-over.ps.argb32.ref.png
Binary files differ
diff --git a/test/reference/recording-surface-over.ps.rgb24.ref.png b/test/reference/recording-surface-over.ps.rgb24.ref.png
new file mode 100644
index 000000000..fab338235
--- /dev/null
+++ b/test/reference/recording-surface-over.ps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/recording-surface-over.quartz.argb32.ref.png b/test/reference/recording-surface-over.quartz.argb32.ref.png
new file mode 100644
index 000000000..09d955967
--- /dev/null
+++ b/test/reference/recording-surface-over.quartz.argb32.ref.png
Binary files differ
diff --git a/test/reference/recording-surface-over.quartz.rgb24.ref.png b/test/reference/recording-surface-over.quartz.rgb24.ref.png
new file mode 100644
index 000000000..96aff408b
--- /dev/null
+++ b/test/reference/recording-surface-over.quartz.rgb24.ref.png
Binary files differ
diff --git a/test/reference/recording-surface-over.rgb24.ref.png b/test/reference/recording-surface-over.rgb24.ref.png
new file mode 100644
index 000000000..6a8b81e68
--- /dev/null
+++ b/test/reference/recording-surface-over.rgb24.ref.png
Binary files differ
diff --git a/test/reference/recording-surface-over.svg.argb32.ref.png b/test/reference/recording-surface-over.svg.argb32.ref.png
new file mode 100644
index 000000000..ff4154d61
--- /dev/null
+++ b/test/reference/recording-surface-over.svg.argb32.ref.png
Binary files differ
diff --git a/test/reference/recording-surface-over.svg.rgb24.ref.png b/test/reference/recording-surface-over.svg.rgb24.ref.png
new file mode 100644
index 000000000..d2d537241
--- /dev/null
+++ b/test/reference/recording-surface-over.svg.rgb24.ref.png
Binary files differ
diff --git a/test/reference/recording-surface-over.traps.argb32.ref.png b/test/reference/recording-surface-over.traps.argb32.ref.png
new file mode 100644
index 000000000..d612250af
--- /dev/null
+++ b/test/reference/recording-surface-over.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/recording-surface-over.traps.rgb24.ref.png b/test/reference/recording-surface-over.traps.rgb24.ref.png
new file mode 100644
index 000000000..0a57b44e7
--- /dev/null
+++ b/test/reference/recording-surface-over.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/recording-surface-source.argb32.ref.png b/test/reference/recording-surface-source.argb32.ref.png
new file mode 100644
index 000000000..afe658772
--- /dev/null
+++ b/test/reference/recording-surface-source.argb32.ref.png
Binary files differ
diff --git a/test/reference/recording-surface-source.base.argb32.ref.png b/test/reference/recording-surface-source.base.argb32.ref.png
new file mode 100644
index 000000000..3fe1057fb
--- /dev/null
+++ b/test/reference/recording-surface-source.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/recording-surface-source.base.rgb24.ref.png b/test/reference/recording-surface-source.base.rgb24.ref.png
new file mode 100644
index 000000000..d2605bd35
--- /dev/null
+++ b/test/reference/recording-surface-source.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/recording-surface-source.rgb24.ref.png b/test/reference/recording-surface-source.rgb24.ref.png
new file mode 100644
index 000000000..76ec38964
--- /dev/null
+++ b/test/reference/recording-surface-source.rgb24.ref.png
Binary files differ
diff --git a/test/reference/recording-surface-source.traps.argb32.ref.png b/test/reference/recording-surface-source.traps.argb32.ref.png
new file mode 100644
index 000000000..3fe1057fb
--- /dev/null
+++ b/test/reference/recording-surface-source.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/recording-surface-source.traps.rgb24.ref.png b/test/reference/recording-surface-source.traps.rgb24.ref.png
new file mode 100644
index 000000000..d2605bd35
--- /dev/null
+++ b/test/reference/recording-surface-source.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/rectangle-rounding-error.base.argb32.ref.png b/test/reference/rectangle-rounding-error.base.argb32.ref.png
new file mode 100644
index 000000000..6cc1b21a2
--- /dev/null
+++ b/test/reference/rectangle-rounding-error.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/rectangle-rounding-error.base.rgb24.ref.png b/test/reference/rectangle-rounding-error.base.rgb24.ref.png
new file mode 100644
index 000000000..6cc1b21a2
--- /dev/null
+++ b/test/reference/rectangle-rounding-error.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/rectangle-rounding-error.ref.png b/test/reference/rectangle-rounding-error.ref.png
new file mode 100644
index 000000000..413345d7c
--- /dev/null
+++ b/test/reference/rectangle-rounding-error.ref.png
Binary files differ
diff --git a/test/reference/rectilinear-dash-scale-unaligned.ref.png b/test/reference/rectilinear-dash-scale-unaligned.ref.png
new file mode 100644
index 000000000..19dbe7f15
--- /dev/null
+++ b/test/reference/rectilinear-dash-scale-unaligned.ref.png
Binary files differ
diff --git a/test/reference/rectilinear-dash-scale-unaligned.traps.ref.png b/test/reference/rectilinear-dash-scale-unaligned.traps.ref.png
new file mode 100644
index 000000000..02abfaad2
--- /dev/null
+++ b/test/reference/rectilinear-dash-scale-unaligned.traps.ref.png
Binary files differ
diff --git a/test/reference/rectilinear-dash-scale.ref.png b/test/reference/rectilinear-dash-scale.ref.png
new file mode 100644
index 000000000..1ab868c34
--- /dev/null
+++ b/test/reference/rectilinear-dash-scale.ref.png
Binary files differ
diff --git a/test/reference/rectilinear-dash.base.argb32.ref.png b/test/reference/rectilinear-dash.base.argb32.ref.png
new file mode 100644
index 000000000..33e7851e7
--- /dev/null
+++ b/test/reference/rectilinear-dash.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/rectilinear-dash.base.rgb24.ref.png b/test/reference/rectilinear-dash.base.rgb24.ref.png
new file mode 100644
index 000000000..33e7851e7
--- /dev/null
+++ b/test/reference/rectilinear-dash.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/rectilinear-dash.mask.argb32.ref.png b/test/reference/rectilinear-dash.mask.argb32.ref.png
new file mode 100644
index 000000000..33e7851e7
--- /dev/null
+++ b/test/reference/rectilinear-dash.mask.argb32.ref.png
Binary files differ
diff --git a/test/reference/rectilinear-dash.mask.rgb24.ref.png b/test/reference/rectilinear-dash.mask.rgb24.ref.png
new file mode 100644
index 000000000..33e7851e7
--- /dev/null
+++ b/test/reference/rectilinear-dash.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/rectilinear-dash.quartz.xfail.png b/test/reference/rectilinear-dash.quartz.xfail.png
new file mode 100644
index 000000000..510184551
--- /dev/null
+++ b/test/reference/rectilinear-dash.quartz.xfail.png
Binary files differ
diff --git a/test/reference/rectilinear-dash.ref.png b/test/reference/rectilinear-dash.ref.png
new file mode 100644
index 000000000..33e7851e7
--- /dev/null
+++ b/test/reference/rectilinear-dash.ref.png
Binary files differ
diff --git a/test/reference/rectilinear-dash.traps.argb32.ref.png b/test/reference/rectilinear-dash.traps.argb32.ref.png
new file mode 100644
index 000000000..33e7851e7
--- /dev/null
+++ b/test/reference/rectilinear-dash.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/rectilinear-dash.traps.rgb24.ref.png b/test/reference/rectilinear-dash.traps.rgb24.ref.png
new file mode 100644
index 000000000..33e7851e7
--- /dev/null
+++ b/test/reference/rectilinear-dash.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/rectilinear-fill.base.argb32.ref.png b/test/reference/rectilinear-fill.base.argb32.ref.png
new file mode 100644
index 000000000..dbaf38368
--- /dev/null
+++ b/test/reference/rectilinear-fill.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/rectilinear-fill.base.rgb24.ref.png b/test/reference/rectilinear-fill.base.rgb24.ref.png
new file mode 100644
index 000000000..dbaf38368
--- /dev/null
+++ b/test/reference/rectilinear-fill.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/rectilinear-fill.ref.png b/test/reference/rectilinear-fill.ref.png
new file mode 100644
index 000000000..84b5967e2
--- /dev/null
+++ b/test/reference/rectilinear-fill.ref.png
Binary files differ
diff --git a/test/reference/rectilinear-grid.base.argb32.ref.png b/test/reference/rectilinear-grid.base.argb32.ref.png
new file mode 100644
index 000000000..7176cb4dd
--- /dev/null
+++ b/test/reference/rectilinear-grid.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/rectilinear-grid.base.rgb24.ref.png b/test/reference/rectilinear-grid.base.rgb24.ref.png
new file mode 100644
index 000000000..7176cb4dd
--- /dev/null
+++ b/test/reference/rectilinear-grid.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/rectilinear-grid.image16.ref.png b/test/reference/rectilinear-grid.image16.ref.png
new file mode 100644
index 000000000..4d4c4da73
--- /dev/null
+++ b/test/reference/rectilinear-grid.image16.ref.png
Binary files differ
diff --git a/test/reference/rectilinear-grid.ref.png b/test/reference/rectilinear-grid.ref.png
new file mode 100644
index 000000000..8d47ef567
--- /dev/null
+++ b/test/reference/rectilinear-grid.ref.png
Binary files differ
diff --git a/test/reference/rectilinear-grid.traps.argb32.ref.png b/test/reference/rectilinear-grid.traps.argb32.ref.png
new file mode 100644
index 000000000..7176cb4dd
--- /dev/null
+++ b/test/reference/rectilinear-grid.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/rectilinear-grid.traps.rgb24.ref.png b/test/reference/rectilinear-grid.traps.rgb24.ref.png
new file mode 100644
index 000000000..7176cb4dd
--- /dev/null
+++ b/test/reference/rectilinear-grid.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/rectilinear-miter-limit.base.argb32.ref.png b/test/reference/rectilinear-miter-limit.base.argb32.ref.png
new file mode 100644
index 000000000..ddf7570d6
--- /dev/null
+++ b/test/reference/rectilinear-miter-limit.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/rectilinear-miter-limit.base.rgb24.ref.png b/test/reference/rectilinear-miter-limit.base.rgb24.ref.png
new file mode 100644
index 000000000..ddf7570d6
--- /dev/null
+++ b/test/reference/rectilinear-miter-limit.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/rectilinear-miter-limit.ps2.ref.png b/test/reference/rectilinear-miter-limit.ps2.ref.png
new file mode 100644
index 000000000..821306067
--- /dev/null
+++ b/test/reference/rectilinear-miter-limit.ps2.ref.png
Binary files differ
diff --git a/test/reference/rectilinear-miter-limit.ps3.ref.png b/test/reference/rectilinear-miter-limit.ps3.ref.png
new file mode 100644
index 000000000..821306067
--- /dev/null
+++ b/test/reference/rectilinear-miter-limit.ps3.ref.png
Binary files differ
diff --git a/test/reference/rectilinear-miter-limit.ref.png b/test/reference/rectilinear-miter-limit.ref.png
new file mode 100644
index 000000000..d64d581e4
--- /dev/null
+++ b/test/reference/rectilinear-miter-limit.ref.png
Binary files differ
diff --git a/test/reference/rectilinear-miter-limit.traps.argb32.ref.png b/test/reference/rectilinear-miter-limit.traps.argb32.ref.png
new file mode 100644
index 000000000..ddf7570d6
--- /dev/null
+++ b/test/reference/rectilinear-miter-limit.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/rectilinear-miter-limit.traps.rgb24.ref.png b/test/reference/rectilinear-miter-limit.traps.rgb24.ref.png
new file mode 100644
index 000000000..ddf7570d6
--- /dev/null
+++ b/test/reference/rectilinear-miter-limit.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/rectilinear-stroke.base.argb32.ref.png b/test/reference/rectilinear-stroke.base.argb32.ref.png
new file mode 100644
index 000000000..260909b6f
--- /dev/null
+++ b/test/reference/rectilinear-stroke.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/rectilinear-stroke.base.rgb24.ref.png b/test/reference/rectilinear-stroke.base.rgb24.ref.png
new file mode 100644
index 000000000..260909b6f
--- /dev/null
+++ b/test/reference/rectilinear-stroke.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/rectilinear-stroke.quartz.xfail.png b/test/reference/rectilinear-stroke.quartz.xfail.png
new file mode 100644
index 000000000..e2a508e41
--- /dev/null
+++ b/test/reference/rectilinear-stroke.quartz.xfail.png
Binary files differ
diff --git a/test/reference/rectilinear-stroke.ref.png b/test/reference/rectilinear-stroke.ref.png
new file mode 100644
index 000000000..0a40b0dec
--- /dev/null
+++ b/test/reference/rectilinear-stroke.ref.png
Binary files differ
diff --git a/test/reference/reflected-stroke.base.argb32.ref.png b/test/reference/reflected-stroke.base.argb32.ref.png
new file mode 100644
index 000000000..3b99f1cf2
--- /dev/null
+++ b/test/reference/reflected-stroke.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/reflected-stroke.base.rgb24.ref.png b/test/reference/reflected-stroke.base.rgb24.ref.png
new file mode 100644
index 000000000..3b99f1cf2
--- /dev/null
+++ b/test/reference/reflected-stroke.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/reflected-stroke.image16.ref.png b/test/reference/reflected-stroke.image16.ref.png
new file mode 100644
index 000000000..ab1273719
--- /dev/null
+++ b/test/reference/reflected-stroke.image16.ref.png
Binary files differ
diff --git a/test/reference/reflected-stroke.mask.argb32.ref.png b/test/reference/reflected-stroke.mask.argb32.ref.png
new file mode 100644
index 000000000..9a7d6bc41
--- /dev/null
+++ b/test/reference/reflected-stroke.mask.argb32.ref.png
Binary files differ
diff --git a/test/reference/reflected-stroke.mask.rgb24.ref.png b/test/reference/reflected-stroke.mask.rgb24.ref.png
new file mode 100644
index 000000000..9a7d6bc41
--- /dev/null
+++ b/test/reference/reflected-stroke.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/reflected-stroke.ps.ref.png b/test/reference/reflected-stroke.ps.ref.png
new file mode 100644
index 000000000..5a28eefec
--- /dev/null
+++ b/test/reference/reflected-stroke.ps.ref.png
Binary files differ
diff --git a/test/reference/reflected-stroke.ref.png b/test/reference/reflected-stroke.ref.png
new file mode 100644
index 000000000..c05eb96f6
--- /dev/null
+++ b/test/reference/reflected-stroke.ref.png
Binary files differ
diff --git a/test/reference/reflected-stroke.traps.argb32.ref.png b/test/reference/reflected-stroke.traps.argb32.ref.png
new file mode 100644
index 000000000..3b99f1cf2
--- /dev/null
+++ b/test/reference/reflected-stroke.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/reflected-stroke.traps.rgb24.ref.png b/test/reference/reflected-stroke.traps.rgb24.ref.png
new file mode 100644
index 000000000..3b99f1cf2
--- /dev/null
+++ b/test/reference/reflected-stroke.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/rel-path.base.argb32.ref.png b/test/reference/rel-path.base.argb32.ref.png
new file mode 100644
index 000000000..5c9cf210a
--- /dev/null
+++ b/test/reference/rel-path.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/rel-path.base.rgb24.ref.png b/test/reference/rel-path.base.rgb24.ref.png
new file mode 100644
index 000000000..72e975ac1
--- /dev/null
+++ b/test/reference/rel-path.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/rel-path.mask.rgb24.ref.png b/test/reference/rel-path.mask.rgb24.ref.png
new file mode 100644
index 000000000..78d8a0884
--- /dev/null
+++ b/test/reference/rel-path.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/rel-path.ps2.rgb24.ref.png b/test/reference/rel-path.ps2.rgb24.ref.png
new file mode 100644
index 000000000..ccdcebbc6
--- /dev/null
+++ b/test/reference/rel-path.ps2.rgb24.ref.png
Binary files differ
diff --git a/test/reference/rel-path.ps3.rgb24.ref.png b/test/reference/rel-path.ps3.rgb24.ref.png
new file mode 100644
index 000000000..ccdcebbc6
--- /dev/null
+++ b/test/reference/rel-path.ps3.rgb24.ref.png
Binary files differ
diff --git a/test/reference/rel-path.ref.png b/test/reference/rel-path.ref.png
new file mode 100644
index 000000000..67fe178a7
--- /dev/null
+++ b/test/reference/rel-path.ref.png
Binary files differ
diff --git a/test/reference/rel-path.traps.argb32.ref.png b/test/reference/rel-path.traps.argb32.ref.png
new file mode 100644
index 000000000..5c9cf210a
--- /dev/null
+++ b/test/reference/rel-path.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/rel-path.traps.rgb24.ref.png b/test/reference/rel-path.traps.rgb24.ref.png
new file mode 100644
index 000000000..72e975ac1
--- /dev/null
+++ b/test/reference/rel-path.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/rgb24-ignore-alpha.base.argb32.ref.png b/test/reference/rgb24-ignore-alpha.base.argb32.ref.png
new file mode 100644
index 000000000..922eddda5
--- /dev/null
+++ b/test/reference/rgb24-ignore-alpha.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/rgb24-ignore-alpha.base.rgb24.ref.png b/test/reference/rgb24-ignore-alpha.base.rgb24.ref.png
new file mode 100644
index 000000000..922eddda5
--- /dev/null
+++ b/test/reference/rgb24-ignore-alpha.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/rgb24-ignore-alpha.ref.png b/test/reference/rgb24-ignore-alpha.ref.png
new file mode 100644
index 000000000..ab1d8fac7
--- /dev/null
+++ b/test/reference/rgb24-ignore-alpha.ref.png
Binary files differ
diff --git a/test/reference/rotate-clip-image-surface-paint.base.argb32.ref.png b/test/reference/rotate-clip-image-surface-paint.base.argb32.ref.png
new file mode 100644
index 000000000..7f74b2b3c
--- /dev/null
+++ b/test/reference/rotate-clip-image-surface-paint.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/rotate-clip-image-surface-paint.base.rgb24.ref.png b/test/reference/rotate-clip-image-surface-paint.base.rgb24.ref.png
new file mode 100644
index 000000000..7f74b2b3c
--- /dev/null
+++ b/test/reference/rotate-clip-image-surface-paint.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/rotate-clip-image-surface-paint.ref.png b/test/reference/rotate-clip-image-surface-paint.ref.png
new file mode 100644
index 000000000..90746fd2e
--- /dev/null
+++ b/test/reference/rotate-clip-image-surface-paint.ref.png
Binary files differ
diff --git a/test/reference/rotate-clip-image-surface-paint.traps.argb32.ref.png b/test/reference/rotate-clip-image-surface-paint.traps.argb32.ref.png
new file mode 100644
index 000000000..9d991d971
--- /dev/null
+++ b/test/reference/rotate-clip-image-surface-paint.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/rotate-clip-image-surface-paint.traps.rgb24.ref.png b/test/reference/rotate-clip-image-surface-paint.traps.rgb24.ref.png
new file mode 100644
index 000000000..9d991d971
--- /dev/null
+++ b/test/reference/rotate-clip-image-surface-paint.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/rotate-clip-image-surface-paint.xlib-fallback.rgb24.ref.png b/test/reference/rotate-clip-image-surface-paint.xlib-fallback.rgb24.ref.png
new file mode 100644
index 000000000..9d991d971
--- /dev/null
+++ b/test/reference/rotate-clip-image-surface-paint.xlib-fallback.rgb24.ref.png
Binary files differ
diff --git a/test/reference/rotate-clip-image-surface-paint.xlib-window.rgb24.ref.png b/test/reference/rotate-clip-image-surface-paint.xlib-window.rgb24.ref.png
new file mode 100644
index 000000000..9d991d971
--- /dev/null
+++ b/test/reference/rotate-clip-image-surface-paint.xlib-window.rgb24.ref.png
Binary files differ
diff --git a/test/reference/rotate-clip.surface-paint.image.argb32.ref.png b/test/reference/rotate-clip.surface-paint.image.argb32.ref.png
new file mode 100644
index 000000000..63e6f9625
--- /dev/null
+++ b/test/reference/rotate-clip.surface-paint.image.argb32.ref.png
Binary files differ
diff --git a/test/reference/rotate-clip.surface-paint.image.rgb24.ref.png b/test/reference/rotate-clip.surface-paint.image.rgb24.ref.png
new file mode 100644
index 000000000..63e6f9625
--- /dev/null
+++ b/test/reference/rotate-clip.surface-paint.image.rgb24.ref.png
Binary files differ
diff --git a/test/reference/rotate-image-surface-paint.base.argb32.ref.png b/test/reference/rotate-image-surface-paint.base.argb32.ref.png
new file mode 100644
index 000000000..06a482005
--- /dev/null
+++ b/test/reference/rotate-image-surface-paint.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/rotate-image-surface-paint.base.rgb24.ref.png b/test/reference/rotate-image-surface-paint.base.rgb24.ref.png
new file mode 100644
index 000000000..06a482005
--- /dev/null
+++ b/test/reference/rotate-image-surface-paint.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/rotate-image-surface-paint.pdf.xfail.png b/test/reference/rotate-image-surface-paint.pdf.xfail.png
new file mode 100644
index 000000000..e1892e57b
--- /dev/null
+++ b/test/reference/rotate-image-surface-paint.pdf.xfail.png
Binary files differ
diff --git a/test/reference/rotate-image-surface-paint.ps.ref.png b/test/reference/rotate-image-surface-paint.ps.ref.png
new file mode 100644
index 000000000..4e46364e9
--- /dev/null
+++ b/test/reference/rotate-image-surface-paint.ps.ref.png
Binary files differ
diff --git a/test/reference/rotate-image-surface-paint.quartz.ref.png b/test/reference/rotate-image-surface-paint.quartz.ref.png
new file mode 100644
index 000000000..a716b630a
--- /dev/null
+++ b/test/reference/rotate-image-surface-paint.quartz.ref.png
Binary files differ
diff --git a/test/reference/rotate-image-surface-paint.ref.png b/test/reference/rotate-image-surface-paint.ref.png
new file mode 100644
index 000000000..06a482005
--- /dev/null
+++ b/test/reference/rotate-image-surface-paint.ref.png
Binary files differ
diff --git a/test/reference/rotate-image-surface-paint.svg.ref.png b/test/reference/rotate-image-surface-paint.svg.ref.png
new file mode 100644
index 000000000..e0db2452e
--- /dev/null
+++ b/test/reference/rotate-image-surface-paint.svg.ref.png
Binary files differ
diff --git a/test/reference/rotate-image-surface-paint.svg.xfail.png b/test/reference/rotate-image-surface-paint.svg.xfail.png
new file mode 100644
index 000000000..4040784b9
--- /dev/null
+++ b/test/reference/rotate-image-surface-paint.svg.xfail.png
Binary files differ
diff --git a/test/reference/rotate-stroke-box.ref.png b/test/reference/rotate-stroke-box.ref.png
new file mode 100644
index 000000000..ef155f032
--- /dev/null
+++ b/test/reference/rotate-stroke-box.ref.png
Binary files differ
diff --git a/test/reference/rotated-clip.base.argb32.ref.png b/test/reference/rotated-clip.base.argb32.ref.png
new file mode 100644
index 000000000..e553a138c
--- /dev/null
+++ b/test/reference/rotated-clip.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/rotated-clip.base.rgb24.ref.png b/test/reference/rotated-clip.base.rgb24.ref.png
new file mode 100644
index 000000000..e553a138c
--- /dev/null
+++ b/test/reference/rotated-clip.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/rotated-clip.image16.ref.png b/test/reference/rotated-clip.image16.ref.png
new file mode 100644
index 000000000..26d9a1aa0
--- /dev/null
+++ b/test/reference/rotated-clip.image16.ref.png
Binary files differ
diff --git a/test/reference/rotated-clip.mask.argb32.ref.png b/test/reference/rotated-clip.mask.argb32.ref.png
new file mode 100644
index 000000000..8168f9d99
--- /dev/null
+++ b/test/reference/rotated-clip.mask.argb32.ref.png
Binary files differ
diff --git a/test/reference/rotated-clip.mask.rgb24.ref.png b/test/reference/rotated-clip.mask.rgb24.ref.png
new file mode 100644
index 000000000..8168f9d99
--- /dev/null
+++ b/test/reference/rotated-clip.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/rotated-clip.ps.ref.png b/test/reference/rotated-clip.ps.ref.png
new file mode 100644
index 000000000..a2a0aceda
--- /dev/null
+++ b/test/reference/rotated-clip.ps.ref.png
Binary files differ
diff --git a/test/reference/rotated-clip.quartz.ref.png b/test/reference/rotated-clip.quartz.ref.png
new file mode 100644
index 000000000..6282846e2
--- /dev/null
+++ b/test/reference/rotated-clip.quartz.ref.png
Binary files differ
diff --git a/test/reference/rotated-clip.ref.png b/test/reference/rotated-clip.ref.png
new file mode 100644
index 000000000..f5468c7de
--- /dev/null
+++ b/test/reference/rotated-clip.ref.png
Binary files differ
diff --git a/test/reference/rotated-clip.traps.argb32.ref.png b/test/reference/rotated-clip.traps.argb32.ref.png
new file mode 100644
index 000000000..ca0f0af71
--- /dev/null
+++ b/test/reference/rotated-clip.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/rotated-clip.traps.rgb24.ref.png b/test/reference/rotated-clip.traps.rgb24.ref.png
new file mode 100644
index 000000000..ca0f0af71
--- /dev/null
+++ b/test/reference/rotated-clip.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/rounded-rectangle-fill.base.argb32.ref.png b/test/reference/rounded-rectangle-fill.base.argb32.ref.png
new file mode 100644
index 000000000..52a355dbc
--- /dev/null
+++ b/test/reference/rounded-rectangle-fill.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/rounded-rectangle-fill.base.rgb24.ref.png b/test/reference/rounded-rectangle-fill.base.rgb24.ref.png
new file mode 100644
index 000000000..52a355dbc
--- /dev/null
+++ b/test/reference/rounded-rectangle-fill.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/rounded-rectangle-fill.image16.ref.png b/test/reference/rounded-rectangle-fill.image16.ref.png
new file mode 100644
index 000000000..0739e5dae
--- /dev/null
+++ b/test/reference/rounded-rectangle-fill.image16.ref.png
Binary files differ
diff --git a/test/reference/rounded-rectangle-fill.ps.ref.png b/test/reference/rounded-rectangle-fill.ps.ref.png
new file mode 100644
index 000000000..215ad3a15
--- /dev/null
+++ b/test/reference/rounded-rectangle-fill.ps.ref.png
Binary files differ
diff --git a/test/reference/rounded-rectangle-fill.quartz.ref.png b/test/reference/rounded-rectangle-fill.quartz.ref.png
new file mode 100644
index 000000000..ee685ca06
--- /dev/null
+++ b/test/reference/rounded-rectangle-fill.quartz.ref.png
Binary files differ
diff --git a/test/reference/rounded-rectangle-fill.ref.png b/test/reference/rounded-rectangle-fill.ref.png
new file mode 100644
index 000000000..e9bab0f95
--- /dev/null
+++ b/test/reference/rounded-rectangle-fill.ref.png
Binary files differ
diff --git a/test/reference/rounded-rectangle-fill.traps.argb32.ref.png b/test/reference/rounded-rectangle-fill.traps.argb32.ref.png
new file mode 100644
index 000000000..52a355dbc
--- /dev/null
+++ b/test/reference/rounded-rectangle-fill.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/rounded-rectangle-fill.traps.rgb24.ref.png b/test/reference/rounded-rectangle-fill.traps.rgb24.ref.png
new file mode 100644
index 000000000..52a355dbc
--- /dev/null
+++ b/test/reference/rounded-rectangle-fill.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/rounded-rectangle-stroke.base.argb32.ref.png b/test/reference/rounded-rectangle-stroke.base.argb32.ref.png
new file mode 100644
index 000000000..490821e06
--- /dev/null
+++ b/test/reference/rounded-rectangle-stroke.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/rounded-rectangle-stroke.base.rgb24.ref.png b/test/reference/rounded-rectangle-stroke.base.rgb24.ref.png
new file mode 100644
index 000000000..490821e06
--- /dev/null
+++ b/test/reference/rounded-rectangle-stroke.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/rounded-rectangle-stroke.image16.ref.png b/test/reference/rounded-rectangle-stroke.image16.ref.png
new file mode 100644
index 000000000..f32a2e069
--- /dev/null
+++ b/test/reference/rounded-rectangle-stroke.image16.ref.png
Binary files differ
diff --git a/test/reference/rounded-rectangle-stroke.mask.argb32.ref.png b/test/reference/rounded-rectangle-stroke.mask.argb32.ref.png
new file mode 100644
index 000000000..3f2a1fb2c
--- /dev/null
+++ b/test/reference/rounded-rectangle-stroke.mask.argb32.ref.png
Binary files differ
diff --git a/test/reference/rounded-rectangle-stroke.mask.rgb24.ref.png b/test/reference/rounded-rectangle-stroke.mask.rgb24.ref.png
new file mode 100644
index 000000000..3f2a1fb2c
--- /dev/null
+++ b/test/reference/rounded-rectangle-stroke.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/rounded-rectangle-stroke.ps.ref.png b/test/reference/rounded-rectangle-stroke.ps.ref.png
new file mode 100644
index 000000000..dd5fc97f8
--- /dev/null
+++ b/test/reference/rounded-rectangle-stroke.ps.ref.png
Binary files differ
diff --git a/test/reference/rounded-rectangle-stroke.ref.png b/test/reference/rounded-rectangle-stroke.ref.png
new file mode 100644
index 000000000..a98596006
--- /dev/null
+++ b/test/reference/rounded-rectangle-stroke.ref.png
Binary files differ
diff --git a/test/reference/rounded-rectangle-stroke.traps.argb32.ref.png b/test/reference/rounded-rectangle-stroke.traps.argb32.ref.png
new file mode 100644
index 000000000..490821e06
--- /dev/null
+++ b/test/reference/rounded-rectangle-stroke.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/rounded-rectangle-stroke.traps.rgb24.ref.png b/test/reference/rounded-rectangle-stroke.traps.rgb24.ref.png
new file mode 100644
index 000000000..490821e06
--- /dev/null
+++ b/test/reference/rounded-rectangle-stroke.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/sample-diagonal.ref.png b/test/reference/sample-diagonal.ref.png
new file mode 100644
index 000000000..f866c2e87
--- /dev/null
+++ b/test/reference/sample-diagonal.ref.png
Binary files differ
diff --git a/test/reference/sample-horizontal.ref.png b/test/reference/sample-horizontal.ref.png
new file mode 100644
index 000000000..75f866b74
--- /dev/null
+++ b/test/reference/sample-horizontal.ref.png
Binary files differ
diff --git a/test/reference/sample-vertical.ref.png b/test/reference/sample-vertical.ref.png
new file mode 100644
index 000000000..75f866b74
--- /dev/null
+++ b/test/reference/sample-vertical.ref.png
Binary files differ
diff --git a/test/reference/scale-down-source-surface-paint.base.argb32.ref.png b/test/reference/scale-down-source-surface-paint.base.argb32.ref.png
new file mode 100644
index 000000000..74770948d
--- /dev/null
+++ b/test/reference/scale-down-source-surface-paint.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/scale-down-source-surface-paint.base.rgb24.ref.png b/test/reference/scale-down-source-surface-paint.base.rgb24.ref.png
new file mode 100644
index 000000000..74770948d
--- /dev/null
+++ b/test/reference/scale-down-source-surface-paint.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/scale-down-source-surface-paint.ref.png b/test/reference/scale-down-source-surface-paint.ref.png
new file mode 100644
index 000000000..5c969d2c5
--- /dev/null
+++ b/test/reference/scale-down-source-surface-paint.ref.png
Binary files differ
diff --git a/test/reference/scale-offset-image.base.argb32.ref.png b/test/reference/scale-offset-image.base.argb32.ref.png
new file mode 100644
index 000000000..19cd614d4
--- /dev/null
+++ b/test/reference/scale-offset-image.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/scale-offset-image.base.rgb24.ref.png b/test/reference/scale-offset-image.base.rgb24.ref.png
new file mode 100644
index 000000000..19cd614d4
--- /dev/null
+++ b/test/reference/scale-offset-image.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/scale-offset-image.gl.ref.png b/test/reference/scale-offset-image.gl.ref.png
new file mode 100644
index 000000000..d2a845c5a
--- /dev/null
+++ b/test/reference/scale-offset-image.gl.ref.png
Binary files differ
diff --git a/test/reference/scale-offset-image.image16.ref.png b/test/reference/scale-offset-image.image16.ref.png
new file mode 100644
index 000000000..e67949d01
--- /dev/null
+++ b/test/reference/scale-offset-image.image16.ref.png
Binary files differ
diff --git a/test/reference/scale-offset-image.pdf.argb32.ref.png b/test/reference/scale-offset-image.pdf.argb32.ref.png
new file mode 100644
index 000000000..74abfaecb
--- /dev/null
+++ b/test/reference/scale-offset-image.pdf.argb32.ref.png
Binary files differ
diff --git a/test/reference/scale-offset-image.pdf.rgb24.ref.png b/test/reference/scale-offset-image.pdf.rgb24.ref.png
new file mode 100644
index 000000000..74abfaecb
--- /dev/null
+++ b/test/reference/scale-offset-image.pdf.rgb24.ref.png
Binary files differ
diff --git a/test/reference/scale-offset-image.ps.ref.png b/test/reference/scale-offset-image.ps.ref.png
new file mode 100644
index 000000000..19941f00e
--- /dev/null
+++ b/test/reference/scale-offset-image.ps.ref.png
Binary files differ
diff --git a/test/reference/scale-offset-image.quartz.ref.png b/test/reference/scale-offset-image.quartz.ref.png
new file mode 100644
index 000000000..f7a5e7228
--- /dev/null
+++ b/test/reference/scale-offset-image.quartz.ref.png
Binary files differ
diff --git a/test/reference/scale-offset-image.ref.png b/test/reference/scale-offset-image.ref.png
new file mode 100644
index 000000000..ab1ced830
--- /dev/null
+++ b/test/reference/scale-offset-image.ref.png
Binary files differ
diff --git a/test/reference/scale-offset-image.script.xfail.png b/test/reference/scale-offset-image.script.xfail.png
new file mode 100644
index 000000000..b89bb66b0
--- /dev/null
+++ b/test/reference/scale-offset-image.script.xfail.png
Binary files differ
diff --git a/test/reference/scale-offset-image.traps.argb32.ref.png b/test/reference/scale-offset-image.traps.argb32.ref.png
new file mode 100644
index 000000000..19cd614d4
--- /dev/null
+++ b/test/reference/scale-offset-image.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/scale-offset-image.traps.rgb24.ref.png b/test/reference/scale-offset-image.traps.rgb24.ref.png
new file mode 100644
index 000000000..19cd614d4
--- /dev/null
+++ b/test/reference/scale-offset-image.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/scale-offset-image.xfail.png b/test/reference/scale-offset-image.xfail.png
new file mode 100644
index 000000000..f0db601fc
--- /dev/null
+++ b/test/reference/scale-offset-image.xfail.png
Binary files differ
diff --git a/test/reference/scale-offset-image.xlib-fallback.xfail.png b/test/reference/scale-offset-image.xlib-fallback.xfail.png
new file mode 100644
index 000000000..3e09d6f88
--- /dev/null
+++ b/test/reference/scale-offset-image.xlib-fallback.xfail.png
Binary files differ
diff --git a/test/reference/scale-offset-similar.base.argb32.ref.png b/test/reference/scale-offset-similar.base.argb32.ref.png
new file mode 100644
index 000000000..19cd614d4
--- /dev/null
+++ b/test/reference/scale-offset-similar.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/scale-offset-similar.base.rgb24.ref.png b/test/reference/scale-offset-similar.base.rgb24.ref.png
new file mode 100644
index 000000000..19cd614d4
--- /dev/null
+++ b/test/reference/scale-offset-similar.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/scale-offset-similar.gl.ref.png b/test/reference/scale-offset-similar.gl.ref.png
new file mode 100644
index 000000000..d2a845c5a
--- /dev/null
+++ b/test/reference/scale-offset-similar.gl.ref.png
Binary files differ
diff --git a/test/reference/scale-offset-similar.image16.ref.png b/test/reference/scale-offset-similar.image16.ref.png
new file mode 100644
index 000000000..e67949d01
--- /dev/null
+++ b/test/reference/scale-offset-similar.image16.ref.png
Binary files differ
diff --git a/test/reference/scale-offset-similar.pdf.argb32.ref.png b/test/reference/scale-offset-similar.pdf.argb32.ref.png
new file mode 100644
index 000000000..c1e27653f
--- /dev/null
+++ b/test/reference/scale-offset-similar.pdf.argb32.ref.png
Binary files differ
diff --git a/test/reference/scale-offset-similar.pdf.rgb24.ref.png b/test/reference/scale-offset-similar.pdf.rgb24.ref.png
new file mode 100644
index 000000000..c1e27653f
--- /dev/null
+++ b/test/reference/scale-offset-similar.pdf.rgb24.ref.png
Binary files differ
diff --git a/test/reference/scale-offset-similar.ps.ref.png b/test/reference/scale-offset-similar.ps.ref.png
new file mode 100644
index 000000000..8c10d30e4
--- /dev/null
+++ b/test/reference/scale-offset-similar.ps.ref.png
Binary files differ
diff --git a/test/reference/scale-offset-similar.quartz.ref.png b/test/reference/scale-offset-similar.quartz.ref.png
new file mode 100644
index 000000000..f7a5e7228
--- /dev/null
+++ b/test/reference/scale-offset-similar.quartz.ref.png
Binary files differ
diff --git a/test/reference/scale-offset-similar.recording.xfail.png b/test/reference/scale-offset-similar.recording.xfail.png
new file mode 100644
index 000000000..0f2553e49
--- /dev/null
+++ b/test/reference/scale-offset-similar.recording.xfail.png
Binary files differ
diff --git a/test/reference/scale-offset-similar.ref.png b/test/reference/scale-offset-similar.ref.png
new file mode 100644
index 000000000..8b3649a33
--- /dev/null
+++ b/test/reference/scale-offset-similar.ref.png
Binary files differ
diff --git a/test/reference/scale-offset-similar.script.xfail.png b/test/reference/scale-offset-similar.script.xfail.png
new file mode 100644
index 000000000..b89bb66b0
--- /dev/null
+++ b/test/reference/scale-offset-similar.script.xfail.png
Binary files differ
diff --git a/test/reference/scale-offset-similar.traps.argb32.ref.png b/test/reference/scale-offset-similar.traps.argb32.ref.png
new file mode 100644
index 000000000..19cd614d4
--- /dev/null
+++ b/test/reference/scale-offset-similar.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/scale-offset-similar.traps.rgb24.ref.png b/test/reference/scale-offset-similar.traps.rgb24.ref.png
new file mode 100644
index 000000000..19cd614d4
--- /dev/null
+++ b/test/reference/scale-offset-similar.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/scale-offset-similar.xfail.png b/test/reference/scale-offset-similar.xfail.png
new file mode 100644
index 000000000..f0db601fc
--- /dev/null
+++ b/test/reference/scale-offset-similar.xfail.png
Binary files differ
diff --git a/test/reference/scale-offset-similar.xlib-fallback.xfail.png b/test/reference/scale-offset-similar.xlib-fallback.xfail.png
new file mode 100644
index 000000000..3e09d6f88
--- /dev/null
+++ b/test/reference/scale-offset-similar.xlib-fallback.xfail.png
Binary files differ
diff --git a/test/reference/scale-offset-similar.xlib.xfail.png b/test/reference/scale-offset-similar.xlib.xfail.png
new file mode 100644
index 000000000..eb4851628
--- /dev/null
+++ b/test/reference/scale-offset-similar.xlib.xfail.png
Binary files differ
diff --git a/test/reference/scale-offset-xlib-fallback.rgb24.ref.png b/test/reference/scale-offset-xlib-fallback.rgb24.ref.png
new file mode 100644
index 000000000..dbb1225ed
--- /dev/null
+++ b/test/reference/scale-offset-xlib-fallback.rgb24.ref.png
Binary files differ
diff --git a/test/reference/scale-offset-xlib-window.rgb24.ref.png b/test/reference/scale-offset-xlib-window.rgb24.ref.png
new file mode 100644
index 000000000..dbb1225ed
--- /dev/null
+++ b/test/reference/scale-offset-xlib-window.rgb24.ref.png
Binary files differ
diff --git a/test/reference/scale-offset-xlib.ref.png b/test/reference/scale-offset-xlib.ref.png
new file mode 100644
index 000000000..dbb1225ed
--- /dev/null
+++ b/test/reference/scale-offset-xlib.ref.png
Binary files differ
diff --git a/test/reference/scale-offset.image.argb32.ref.png b/test/reference/scale-offset.image.argb32.ref.png
new file mode 100644
index 000000000..12470634b
--- /dev/null
+++ b/test/reference/scale-offset.image.argb32.ref.png
Binary files differ
diff --git a/test/reference/scale-offset.image.rgb24.ref.png b/test/reference/scale-offset.image.rgb24.ref.png
new file mode 100644
index 000000000..12470634b
--- /dev/null
+++ b/test/reference/scale-offset.image.rgb24.ref.png
Binary files differ
diff --git a/test/reference/scale-source-surface-paint.base.argb32.ref.png b/test/reference/scale-source-surface-paint.base.argb32.ref.png
new file mode 100644
index 000000000..e159d15e3
--- /dev/null
+++ b/test/reference/scale-source-surface-paint.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/scale-source-surface-paint.base.rgb24.ref.png b/test/reference/scale-source-surface-paint.base.rgb24.ref.png
new file mode 100644
index 000000000..3491a7c05
--- /dev/null
+++ b/test/reference/scale-source-surface-paint.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/scale-source-surface-paint.pdf.argb32.xfail.png b/test/reference/scale-source-surface-paint.pdf.argb32.xfail.png
new file mode 100644
index 000000000..7ecac1776
--- /dev/null
+++ b/test/reference/scale-source-surface-paint.pdf.argb32.xfail.png
Binary files differ
diff --git a/test/reference/scale-source-surface-paint.pdf.rgb24.xfail.png b/test/reference/scale-source-surface-paint.pdf.rgb24.xfail.png
new file mode 100644
index 000000000..fa1291f96
--- /dev/null
+++ b/test/reference/scale-source-surface-paint.pdf.rgb24.xfail.png
Binary files differ
diff --git a/test/reference/scale-source-surface-paint.ref.png b/test/reference/scale-source-surface-paint.ref.png
new file mode 100644
index 000000000..ec3c059fd
--- /dev/null
+++ b/test/reference/scale-source-surface-paint.ref.png
Binary files differ
diff --git a/test/reference/scale-source-surface-paint.svg.argb32.xfail.png b/test/reference/scale-source-surface-paint.svg.argb32.xfail.png
new file mode 100644
index 000000000..ed946d4d4
--- /dev/null
+++ b/test/reference/scale-source-surface-paint.svg.argb32.xfail.png
Binary files differ
diff --git a/test/reference/scale-source-surface-paint.svg.rgb24.xfail.png b/test/reference/scale-source-surface-paint.svg.rgb24.xfail.png
new file mode 100644
index 000000000..7d065d405
--- /dev/null
+++ b/test/reference/scale-source-surface-paint.svg.rgb24.xfail.png
Binary files differ
diff --git a/test/reference/select-font-face.base.argb32.ref.png b/test/reference/select-font-face.base.argb32.ref.png
new file mode 100644
index 000000000..1334a9a01
--- /dev/null
+++ b/test/reference/select-font-face.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/select-font-face.base.rgb24.ref.png b/test/reference/select-font-face.base.rgb24.ref.png
new file mode 100644
index 000000000..1334a9a01
--- /dev/null
+++ b/test/reference/select-font-face.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/select-font-face.image16.ref.png b/test/reference/select-font-face.image16.ref.png
new file mode 100644
index 000000000..2c3191cb9
--- /dev/null
+++ b/test/reference/select-font-face.image16.ref.png
Binary files differ
diff --git a/test/reference/select-font-face.ps2.ref.png b/test/reference/select-font-face.ps2.ref.png
new file mode 100644
index 000000000..6c2f36115
--- /dev/null
+++ b/test/reference/select-font-face.ps2.ref.png
Binary files differ
diff --git a/test/reference/select-font-face.ps3.ref.png b/test/reference/select-font-face.ps3.ref.png
new file mode 100644
index 000000000..6c2f36115
--- /dev/null
+++ b/test/reference/select-font-face.ps3.ref.png
Binary files differ
diff --git a/test/reference/select-font-face.quartz.ref.png b/test/reference/select-font-face.quartz.ref.png
new file mode 100644
index 000000000..69fd2e239
--- /dev/null
+++ b/test/reference/select-font-face.quartz.ref.png
Binary files differ
diff --git a/test/reference/select-font-face.ref.png b/test/reference/select-font-face.ref.png
new file mode 100644
index 000000000..1334a9a01
--- /dev/null
+++ b/test/reference/select-font-face.ref.png
Binary files differ
diff --git a/test/reference/select-font-face.traps.ref.png b/test/reference/select-font-face.traps.ref.png
new file mode 100644
index 000000000..1334a9a01
--- /dev/null
+++ b/test/reference/select-font-face.traps.ref.png
Binary files differ
diff --git a/test/reference/self-copy-overlap.base.argb32.ref.png b/test/reference/self-copy-overlap.base.argb32.ref.png
new file mode 100644
index 000000000..a70e819ed
--- /dev/null
+++ b/test/reference/self-copy-overlap.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/self-copy-overlap.base.rgb24.ref.png b/test/reference/self-copy-overlap.base.rgb24.ref.png
new file mode 100644
index 000000000..e9cd7b567
--- /dev/null
+++ b/test/reference/self-copy-overlap.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/self-copy-overlap.mask.argb32.ref.png b/test/reference/self-copy-overlap.mask.argb32.ref.png
new file mode 100644
index 000000000..a70e819ed
--- /dev/null
+++ b/test/reference/self-copy-overlap.mask.argb32.ref.png
Binary files differ
diff --git a/test/reference/self-copy-overlap.mask.rgb24.ref.png b/test/reference/self-copy-overlap.mask.rgb24.ref.png
new file mode 100644
index 000000000..e9cd7b567
--- /dev/null
+++ b/test/reference/self-copy-overlap.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/self-copy-overlap.traps.argb32.ref.png b/test/reference/self-copy-overlap.traps.argb32.ref.png
new file mode 100644
index 000000000..a70e819ed
--- /dev/null
+++ b/test/reference/self-copy-overlap.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/self-copy-overlap.traps.rgb24.ref.png b/test/reference/self-copy-overlap.traps.rgb24.ref.png
new file mode 100644
index 000000000..e9cd7b567
--- /dev/null
+++ b/test/reference/self-copy-overlap.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/self-copy.base.argb32.ref.png b/test/reference/self-copy.base.argb32.ref.png
new file mode 100644
index 000000000..daa4dcb30
--- /dev/null
+++ b/test/reference/self-copy.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/self-copy.base.rgb24.ref.png b/test/reference/self-copy.base.rgb24.ref.png
new file mode 100644
index 000000000..daa4dcb30
--- /dev/null
+++ b/test/reference/self-copy.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/self-copy.ps2.ref.png b/test/reference/self-copy.ps2.ref.png
new file mode 100644
index 000000000..5c9dd5771
--- /dev/null
+++ b/test/reference/self-copy.ps2.ref.png
Binary files differ
diff --git a/test/reference/self-copy.ps3.ref.png b/test/reference/self-copy.ps3.ref.png
new file mode 100644
index 000000000..5c9dd5771
--- /dev/null
+++ b/test/reference/self-copy.ps3.ref.png
Binary files differ
diff --git a/test/reference/self-copy.ref.png b/test/reference/self-copy.ref.png
new file mode 100644
index 000000000..d8221d8a7
--- /dev/null
+++ b/test/reference/self-copy.ref.png
Binary files differ
diff --git a/test/reference/self-copy.traps.argb32.ref.png b/test/reference/self-copy.traps.argb32.ref.png
new file mode 100644
index 000000000..daa4dcb30
--- /dev/null
+++ b/test/reference/self-copy.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/self-copy.traps.rgb24.ref.png b/test/reference/self-copy.traps.rgb24.ref.png
new file mode 100644
index 000000000..daa4dcb30
--- /dev/null
+++ b/test/reference/self-copy.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/self-intersecting.base.argb32.ref.png b/test/reference/self-intersecting.base.argb32.ref.png
new file mode 100644
index 000000000..f0068e618
--- /dev/null
+++ b/test/reference/self-intersecting.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/self-intersecting.base.rgb24.ref.png b/test/reference/self-intersecting.base.rgb24.ref.png
new file mode 100644
index 000000000..f0068e618
--- /dev/null
+++ b/test/reference/self-intersecting.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/self-intersecting.ps.ref.png b/test/reference/self-intersecting.ps.ref.png
new file mode 100644
index 000000000..84fde0171
--- /dev/null
+++ b/test/reference/self-intersecting.ps.ref.png
Binary files differ
diff --git a/test/reference/self-intersecting.quartz.xfail.png b/test/reference/self-intersecting.quartz.xfail.png
new file mode 100644
index 000000000..4d087137f
--- /dev/null
+++ b/test/reference/self-intersecting.quartz.xfail.png
Binary files differ
diff --git a/test/reference/self-intersecting.ref.png b/test/reference/self-intersecting.ref.png
new file mode 100644
index 000000000..d554d83ee
--- /dev/null
+++ b/test/reference/self-intersecting.ref.png
Binary files differ
diff --git a/test/reference/self-intersecting.traps.argb32.ref.png b/test/reference/self-intersecting.traps.argb32.ref.png
new file mode 100644
index 000000000..f0068e618
--- /dev/null
+++ b/test/reference/self-intersecting.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/self-intersecting.traps.rgb24.ref.png b/test/reference/self-intersecting.traps.rgb24.ref.png
new file mode 100644
index 000000000..f0068e618
--- /dev/null
+++ b/test/reference/self-intersecting.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/set-source.base.argb32.ref.png b/test/reference/set-source.base.argb32.ref.png
new file mode 100644
index 000000000..222b3723e
--- /dev/null
+++ b/test/reference/set-source.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/set-source.base.rgb24.ref.png b/test/reference/set-source.base.rgb24.ref.png
new file mode 100644
index 000000000..5e13c82e7
--- /dev/null
+++ b/test/reference/set-source.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/set-source.ref.png b/test/reference/set-source.ref.png
new file mode 100644
index 000000000..19793e026
--- /dev/null
+++ b/test/reference/set-source.ref.png
Binary files differ
diff --git a/test/reference/shape-general-convex.base.argb32.ref.png b/test/reference/shape-general-convex.base.argb32.ref.png
new file mode 100644
index 000000000..fc2d3f0d3
--- /dev/null
+++ b/test/reference/shape-general-convex.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/shape-general-convex.base.rgb24.ref.png b/test/reference/shape-general-convex.base.rgb24.ref.png
new file mode 100644
index 000000000..fc2d3f0d3
--- /dev/null
+++ b/test/reference/shape-general-convex.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/shape-general-convex.ps.ref.png b/test/reference/shape-general-convex.ps.ref.png
new file mode 100644
index 000000000..6cdd615d6
--- /dev/null
+++ b/test/reference/shape-general-convex.ps.ref.png
Binary files differ
diff --git a/test/reference/shape-general-convex.ref.png b/test/reference/shape-general-convex.ref.png
new file mode 100644
index 000000000..2f648d524
--- /dev/null
+++ b/test/reference/shape-general-convex.ref.png
Binary files differ
diff --git a/test/reference/shape-general-convex.traps.argb32.ref.png b/test/reference/shape-general-convex.traps.argb32.ref.png
new file mode 100644
index 000000000..fc2d3f0d3
--- /dev/null
+++ b/test/reference/shape-general-convex.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/shape-general-convex.traps.rgb24.ref.png b/test/reference/shape-general-convex.traps.rgb24.ref.png
new file mode 100644
index 000000000..fc2d3f0d3
--- /dev/null
+++ b/test/reference/shape-general-convex.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/shape-sierpinski.base.argb32.ref.png b/test/reference/shape-sierpinski.base.argb32.ref.png
new file mode 100644
index 000000000..69755d27a
--- /dev/null
+++ b/test/reference/shape-sierpinski.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/shape-sierpinski.base.rgb24.ref.png b/test/reference/shape-sierpinski.base.rgb24.ref.png
new file mode 100644
index 000000000..69755d27a
--- /dev/null
+++ b/test/reference/shape-sierpinski.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/shape-sierpinski.pdf.argb32.ref.png b/test/reference/shape-sierpinski.pdf.argb32.ref.png
new file mode 100644
index 000000000..4e70fbd60
--- /dev/null
+++ b/test/reference/shape-sierpinski.pdf.argb32.ref.png
Binary files differ
diff --git a/test/reference/shape-sierpinski.pdf.rgb24.ref.png b/test/reference/shape-sierpinski.pdf.rgb24.ref.png
new file mode 100644
index 000000000..4e70fbd60
--- /dev/null
+++ b/test/reference/shape-sierpinski.pdf.rgb24.ref.png
Binary files differ
diff --git a/test/reference/shape-sierpinski.ps.ref.png b/test/reference/shape-sierpinski.ps.ref.png
new file mode 100644
index 000000000..700c9f148
--- /dev/null
+++ b/test/reference/shape-sierpinski.ps.ref.png
Binary files differ
diff --git a/test/reference/shape-sierpinski.ps3.argb32.ref.png b/test/reference/shape-sierpinski.ps3.argb32.ref.png
new file mode 100644
index 000000000..700c9f148
--- /dev/null
+++ b/test/reference/shape-sierpinski.ps3.argb32.ref.png
Binary files differ
diff --git a/test/reference/shape-sierpinski.ps3.rgb24.ref.png b/test/reference/shape-sierpinski.ps3.rgb24.ref.png
new file mode 100644
index 000000000..700c9f148
--- /dev/null
+++ b/test/reference/shape-sierpinski.ps3.rgb24.ref.png
Binary files differ
diff --git a/test/reference/shape-sierpinski.ref.png b/test/reference/shape-sierpinski.ref.png
new file mode 100644
index 000000000..5d983671f
--- /dev/null
+++ b/test/reference/shape-sierpinski.ref.png
Binary files differ
diff --git a/test/reference/shape-sierpinski.traps.argb32.ref.png b/test/reference/shape-sierpinski.traps.argb32.ref.png
new file mode 100644
index 000000000..69755d27a
--- /dev/null
+++ b/test/reference/shape-sierpinski.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/shape-sierpinski.traps.rgb24.ref.png b/test/reference/shape-sierpinski.traps.rgb24.ref.png
new file mode 100644
index 000000000..69755d27a
--- /dev/null
+++ b/test/reference/shape-sierpinski.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/show-glyphs-advance.base.argb32.ref.png b/test/reference/show-glyphs-advance.base.argb32.ref.png
new file mode 100644
index 000000000..e65ad05d5
--- /dev/null
+++ b/test/reference/show-glyphs-advance.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/show-glyphs-advance.base.rgb24.ref.png b/test/reference/show-glyphs-advance.base.rgb24.ref.png
new file mode 100644
index 000000000..e65ad05d5
--- /dev/null
+++ b/test/reference/show-glyphs-advance.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/show-glyphs-advance.image16.ref.png b/test/reference/show-glyphs-advance.image16.ref.png
new file mode 100644
index 000000000..dd2f18d08
--- /dev/null
+++ b/test/reference/show-glyphs-advance.image16.ref.png
Binary files differ
diff --git a/test/reference/show-glyphs-advance.ps.ref.png b/test/reference/show-glyphs-advance.ps.ref.png
new file mode 100644
index 000000000..96a80f9bc
--- /dev/null
+++ b/test/reference/show-glyphs-advance.ps.ref.png
Binary files differ
diff --git a/test/reference/show-glyphs-advance.quartz.ref.png b/test/reference/show-glyphs-advance.quartz.ref.png
new file mode 100644
index 000000000..4750308fa
--- /dev/null
+++ b/test/reference/show-glyphs-advance.quartz.ref.png
Binary files differ
diff --git a/test/reference/show-glyphs-advance.ref.png b/test/reference/show-glyphs-advance.ref.png
new file mode 100644
index 000000000..e65ad05d5
--- /dev/null
+++ b/test/reference/show-glyphs-advance.ref.png
Binary files differ
diff --git a/test/reference/show-glyphs-advance.svg.ref.png b/test/reference/show-glyphs-advance.svg.ref.png
new file mode 100644
index 000000000..914d4d69f
--- /dev/null
+++ b/test/reference/show-glyphs-advance.svg.ref.png
Binary files differ
diff --git a/test/reference/show-glyphs-advance.traps.ref.png b/test/reference/show-glyphs-advance.traps.ref.png
new file mode 100644
index 000000000..e65ad05d5
--- /dev/null
+++ b/test/reference/show-glyphs-advance.traps.ref.png
Binary files differ
diff --git a/test/reference/show-glyphs-many.base.argb32.ref.png b/test/reference/show-glyphs-many.base.argb32.ref.png
new file mode 100644
index 000000000..b638015d3
--- /dev/null
+++ b/test/reference/show-glyphs-many.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/show-glyphs-many.base.rgb24.ref.png b/test/reference/show-glyphs-many.base.rgb24.ref.png
new file mode 100644
index 000000000..b638015d3
--- /dev/null
+++ b/test/reference/show-glyphs-many.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/show-glyphs-many.ref.png b/test/reference/show-glyphs-many.ref.png
new file mode 100644
index 000000000..b61c5f7b6
--- /dev/null
+++ b/test/reference/show-glyphs-many.ref.png
Binary files differ
diff --git a/test/reference/show-text-current-point.base.argb32.ref.png b/test/reference/show-text-current-point.base.argb32.ref.png
new file mode 100644
index 000000000..d60d4ac01
--- /dev/null
+++ b/test/reference/show-text-current-point.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/show-text-current-point.base.rgb24.ref.png b/test/reference/show-text-current-point.base.rgb24.ref.png
new file mode 100644
index 000000000..d60d4ac01
--- /dev/null
+++ b/test/reference/show-text-current-point.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/show-text-current-point.image16.ref.png b/test/reference/show-text-current-point.image16.ref.png
new file mode 100644
index 000000000..b2b933fba
--- /dev/null
+++ b/test/reference/show-text-current-point.image16.ref.png
Binary files differ
diff --git a/test/reference/show-text-current-point.ps2.ref.png b/test/reference/show-text-current-point.ps2.ref.png
new file mode 100644
index 000000000..b42c48e7f
--- /dev/null
+++ b/test/reference/show-text-current-point.ps2.ref.png
Binary files differ
diff --git a/test/reference/show-text-current-point.ps3.ref.png b/test/reference/show-text-current-point.ps3.ref.png
new file mode 100644
index 000000000..b42c48e7f
--- /dev/null
+++ b/test/reference/show-text-current-point.ps3.ref.png
Binary files differ
diff --git a/test/reference/show-text-current-point.quartz.ref.png b/test/reference/show-text-current-point.quartz.ref.png
new file mode 100644
index 000000000..a5313814a
--- /dev/null
+++ b/test/reference/show-text-current-point.quartz.ref.png
Binary files differ
diff --git a/test/reference/show-text-current-point.ref.png b/test/reference/show-text-current-point.ref.png
new file mode 100644
index 000000000..d60d4ac01
--- /dev/null
+++ b/test/reference/show-text-current-point.ref.png
Binary files differ
diff --git a/test/reference/show-text-current-point.traps.ref.png b/test/reference/show-text-current-point.traps.ref.png
new file mode 100644
index 000000000..d60d4ac01
--- /dev/null
+++ b/test/reference/show-text-current-point.traps.ref.png
Binary files differ
diff --git a/test/reference/simple-edge.ref.png b/test/reference/simple-edge.ref.png
new file mode 100644
index 000000000..4757b0a54
--- /dev/null
+++ b/test/reference/simple-edge.ref.png
Binary files differ
diff --git a/test/reference/simple-edge.xfail.png b/test/reference/simple-edge.xfail.png
new file mode 100644
index 000000000..2daad9783
--- /dev/null
+++ b/test/reference/simple-edge.xfail.png
Binary files differ
diff --git a/test/reference/skew-extreme.base.argb32.ref.png b/test/reference/skew-extreme.base.argb32.ref.png
new file mode 100644
index 000000000..5e00606d1
--- /dev/null
+++ b/test/reference/skew-extreme.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/skew-extreme.base.rgb24.ref.png b/test/reference/skew-extreme.base.rgb24.ref.png
new file mode 100644
index 000000000..5e00606d1
--- /dev/null
+++ b/test/reference/skew-extreme.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/skew-extreme.ps2.ref.png b/test/reference/skew-extreme.ps2.ref.png
new file mode 100644
index 000000000..69f1d374f
--- /dev/null
+++ b/test/reference/skew-extreme.ps2.ref.png
Binary files differ
diff --git a/test/reference/skew-extreme.ps3.ref.png b/test/reference/skew-extreme.ps3.ref.png
new file mode 100644
index 000000000..69f1d374f
--- /dev/null
+++ b/test/reference/skew-extreme.ps3.ref.png
Binary files differ
diff --git a/test/reference/skew-extreme.ref.png b/test/reference/skew-extreme.ref.png
new file mode 100644
index 000000000..69e026d7e
--- /dev/null
+++ b/test/reference/skew-extreme.ref.png
Binary files differ
diff --git a/test/reference/skew-extreme.traps.argb32.ref.png b/test/reference/skew-extreme.traps.argb32.ref.png
new file mode 100644
index 000000000..5e00606d1
--- /dev/null
+++ b/test/reference/skew-extreme.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/skew-extreme.traps.rgb24.ref.png b/test/reference/skew-extreme.traps.rgb24.ref.png
new file mode 100644
index 000000000..5e00606d1
--- /dev/null
+++ b/test/reference/skew-extreme.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/smask-fill.base.argb32.ref.png b/test/reference/smask-fill.base.argb32.ref.png
new file mode 100644
index 000000000..30bc98e14
--- /dev/null
+++ b/test/reference/smask-fill.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/smask-fill.base.rgb24.ref.png b/test/reference/smask-fill.base.rgb24.ref.png
new file mode 100644
index 000000000..30bc98e14
--- /dev/null
+++ b/test/reference/smask-fill.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/smask-fill.image16.ref.png b/test/reference/smask-fill.image16.ref.png
new file mode 100644
index 000000000..25a6d5b2a
--- /dev/null
+++ b/test/reference/smask-fill.image16.ref.png
Binary files differ
diff --git a/test/reference/smask-fill.pdf.ref.png b/test/reference/smask-fill.pdf.ref.png
new file mode 100644
index 000000000..cfd40b07c
--- /dev/null
+++ b/test/reference/smask-fill.pdf.ref.png
Binary files differ
diff --git a/test/reference/smask-fill.quartz.ref.png b/test/reference/smask-fill.quartz.ref.png
new file mode 100644
index 000000000..ae0547652
--- /dev/null
+++ b/test/reference/smask-fill.quartz.ref.png
Binary files differ
diff --git a/test/reference/smask-fill.ref.png b/test/reference/smask-fill.ref.png
new file mode 100644
index 000000000..c7aff5a1b
--- /dev/null
+++ b/test/reference/smask-fill.ref.png
Binary files differ
diff --git a/test/reference/smask-fill.svg.ref.png b/test/reference/smask-fill.svg.ref.png
new file mode 100644
index 000000000..824e8cff1
--- /dev/null
+++ b/test/reference/smask-fill.svg.ref.png
Binary files differ
diff --git a/test/reference/smask-fill.traps.argb32.ref.png b/test/reference/smask-fill.traps.argb32.ref.png
new file mode 100644
index 000000000..30bc98e14
--- /dev/null
+++ b/test/reference/smask-fill.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/smask-fill.traps.rgb24.ref.png b/test/reference/smask-fill.traps.rgb24.ref.png
new file mode 100644
index 000000000..30bc98e14
--- /dev/null
+++ b/test/reference/smask-fill.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/smask-image-mask.base.argb32.ref.png b/test/reference/smask-image-mask.base.argb32.ref.png
new file mode 100644
index 000000000..12063bda2
--- /dev/null
+++ b/test/reference/smask-image-mask.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/smask-image-mask.base.rgb24.ref.png b/test/reference/smask-image-mask.base.rgb24.ref.png
new file mode 100644
index 000000000..12063bda2
--- /dev/null
+++ b/test/reference/smask-image-mask.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/smask-image-mask.pdf.ref.png b/test/reference/smask-image-mask.pdf.ref.png
new file mode 100644
index 000000000..7ac43e483
--- /dev/null
+++ b/test/reference/smask-image-mask.pdf.ref.png
Binary files differ
diff --git a/test/reference/smask-image-mask.ref.png b/test/reference/smask-image-mask.ref.png
new file mode 100644
index 000000000..12063bda2
--- /dev/null
+++ b/test/reference/smask-image-mask.ref.png
Binary files differ
diff --git a/test/reference/smask-mask.base.argb32.ref.png b/test/reference/smask-mask.base.argb32.ref.png
new file mode 100644
index 000000000..80329c263
--- /dev/null
+++ b/test/reference/smask-mask.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/smask-mask.base.rgb24.ref.png b/test/reference/smask-mask.base.rgb24.ref.png
new file mode 100644
index 000000000..80329c263
--- /dev/null
+++ b/test/reference/smask-mask.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/smask-mask.image16.ref.png b/test/reference/smask-mask.image16.ref.png
new file mode 100644
index 000000000..502452157
--- /dev/null
+++ b/test/reference/smask-mask.image16.ref.png
Binary files differ
diff --git a/test/reference/smask-mask.pdf.ref.png b/test/reference/smask-mask.pdf.ref.png
new file mode 100644
index 000000000..59c97407e
--- /dev/null
+++ b/test/reference/smask-mask.pdf.ref.png
Binary files differ
diff --git a/test/reference/smask-mask.quartz.ref.png b/test/reference/smask-mask.quartz.ref.png
new file mode 100644
index 000000000..98ba2996b
--- /dev/null
+++ b/test/reference/smask-mask.quartz.ref.png
Binary files differ
diff --git a/test/reference/smask-mask.ref.png b/test/reference/smask-mask.ref.png
new file mode 100644
index 000000000..80329c263
--- /dev/null
+++ b/test/reference/smask-mask.ref.png
Binary files differ
diff --git a/test/reference/smask-mask.svg.ref.png b/test/reference/smask-mask.svg.ref.png
new file mode 100644
index 000000000..ae46036f4
--- /dev/null
+++ b/test/reference/smask-mask.svg.ref.png
Binary files differ
diff --git a/test/reference/smask-paint.base.argb32.ref.png b/test/reference/smask-paint.base.argb32.ref.png
new file mode 100644
index 000000000..95af29af4
--- /dev/null
+++ b/test/reference/smask-paint.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/smask-paint.base.rgb24.ref.png b/test/reference/smask-paint.base.rgb24.ref.png
new file mode 100644
index 000000000..95af29af4
--- /dev/null
+++ b/test/reference/smask-paint.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/smask-paint.image16.ref.png b/test/reference/smask-paint.image16.ref.png
new file mode 100644
index 000000000..dc371dfc3
--- /dev/null
+++ b/test/reference/smask-paint.image16.ref.png
Binary files differ
diff --git a/test/reference/smask-paint.pdf.ref.png b/test/reference/smask-paint.pdf.ref.png
new file mode 100644
index 000000000..623a92dae
--- /dev/null
+++ b/test/reference/smask-paint.pdf.ref.png
Binary files differ
diff --git a/test/reference/smask-paint.quartz.ref.png b/test/reference/smask-paint.quartz.ref.png
new file mode 100644
index 000000000..4ee25fd0f
--- /dev/null
+++ b/test/reference/smask-paint.quartz.ref.png
Binary files differ
diff --git a/test/reference/smask-paint.ref.png b/test/reference/smask-paint.ref.png
new file mode 100644
index 000000000..95af29af4
--- /dev/null
+++ b/test/reference/smask-paint.ref.png
Binary files differ
diff --git a/test/reference/smask-paint.svg.ref.png b/test/reference/smask-paint.svg.ref.png
new file mode 100644
index 000000000..93a423fe5
--- /dev/null
+++ b/test/reference/smask-paint.svg.ref.png
Binary files differ
diff --git a/test/reference/smask-stroke.base.argb32.ref.png b/test/reference/smask-stroke.base.argb32.ref.png
new file mode 100644
index 000000000..c6a557d8b
--- /dev/null
+++ b/test/reference/smask-stroke.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/smask-stroke.base.rgb24.ref.png b/test/reference/smask-stroke.base.rgb24.ref.png
new file mode 100644
index 000000000..c6a557d8b
--- /dev/null
+++ b/test/reference/smask-stroke.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/smask-stroke.image16.ref.png b/test/reference/smask-stroke.image16.ref.png
new file mode 100644
index 000000000..ea2138ab3
--- /dev/null
+++ b/test/reference/smask-stroke.image16.ref.png
Binary files differ
diff --git a/test/reference/smask-stroke.pdf.xfail.png b/test/reference/smask-stroke.pdf.xfail.png
new file mode 100644
index 000000000..9a1a7713e
--- /dev/null
+++ b/test/reference/smask-stroke.pdf.xfail.png
Binary files differ
diff --git a/test/reference/smask-stroke.quartz.ref.png b/test/reference/smask-stroke.quartz.ref.png
new file mode 100644
index 000000000..f6f0d1bcc
--- /dev/null
+++ b/test/reference/smask-stroke.quartz.ref.png
Binary files differ
diff --git a/test/reference/smask-stroke.ref.png b/test/reference/smask-stroke.ref.png
new file mode 100644
index 000000000..5d8c79960
--- /dev/null
+++ b/test/reference/smask-stroke.ref.png
Binary files differ
diff --git a/test/reference/smask-stroke.traps.argb32.ref.png b/test/reference/smask-stroke.traps.argb32.ref.png
new file mode 100644
index 000000000..c6a557d8b
--- /dev/null
+++ b/test/reference/smask-stroke.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/smask-stroke.traps.rgb24.ref.png b/test/reference/smask-stroke.traps.rgb24.ref.png
new file mode 100644
index 000000000..c6a557d8b
--- /dev/null
+++ b/test/reference/smask-stroke.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/smask-text.base.argb32.ref.png b/test/reference/smask-text.base.argb32.ref.png
new file mode 100644
index 000000000..344ac2089
--- /dev/null
+++ b/test/reference/smask-text.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/smask-text.base.rgb24.ref.png b/test/reference/smask-text.base.rgb24.ref.png
new file mode 100644
index 000000000..344ac2089
--- /dev/null
+++ b/test/reference/smask-text.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/smask-text.image16.ref.png b/test/reference/smask-text.image16.ref.png
new file mode 100644
index 000000000..098043d67
--- /dev/null
+++ b/test/reference/smask-text.image16.ref.png
Binary files differ
diff --git a/test/reference/smask-text.mask.argb32.ref.png b/test/reference/smask-text.mask.argb32.ref.png
new file mode 100644
index 000000000..344ac2089
--- /dev/null
+++ b/test/reference/smask-text.mask.argb32.ref.png
Binary files differ
diff --git a/test/reference/smask-text.mask.rgb24.ref.png b/test/reference/smask-text.mask.rgb24.ref.png
new file mode 100644
index 000000000..344ac2089
--- /dev/null
+++ b/test/reference/smask-text.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/smask-text.pdf.ref.png b/test/reference/smask-text.pdf.ref.png
new file mode 100644
index 000000000..fa4905627
--- /dev/null
+++ b/test/reference/smask-text.pdf.ref.png
Binary files differ
diff --git a/test/reference/smask-text.ps2.ref.png b/test/reference/smask-text.ps2.ref.png
new file mode 100644
index 000000000..ae61325cb
--- /dev/null
+++ b/test/reference/smask-text.ps2.ref.png
Binary files differ
diff --git a/test/reference/smask-text.ps3.ref.png b/test/reference/smask-text.ps3.ref.png
new file mode 100644
index 000000000..ae61325cb
--- /dev/null
+++ b/test/reference/smask-text.ps3.ref.png
Binary files differ
diff --git a/test/reference/smask-text.quartz.ref.png b/test/reference/smask-text.quartz.ref.png
new file mode 100644
index 000000000..096dc9853
--- /dev/null
+++ b/test/reference/smask-text.quartz.ref.png
Binary files differ
diff --git a/test/reference/smask-text.ref.png b/test/reference/smask-text.ref.png
new file mode 100644
index 000000000..66ef289ca
--- /dev/null
+++ b/test/reference/smask-text.ref.png
Binary files differ
diff --git a/test/reference/smask-text.script.ref.png b/test/reference/smask-text.script.ref.png
new file mode 100644
index 000000000..62b2de5af
--- /dev/null
+++ b/test/reference/smask-text.script.ref.png
Binary files differ
diff --git a/test/reference/smask-text.svg.ref.png b/test/reference/smask-text.svg.ref.png
new file mode 100644
index 000000000..65f225ea8
--- /dev/null
+++ b/test/reference/smask-text.svg.ref.png
Binary files differ
diff --git a/test/reference/smask-text.traps.ref.png b/test/reference/smask-text.traps.ref.png
new file mode 100644
index 000000000..66ef289ca
--- /dev/null
+++ b/test/reference/smask-text.traps.ref.png
Binary files differ
diff --git a/test/reference/smask-text.xlib-fallback.ref.png b/test/reference/smask-text.xlib-fallback.ref.png
new file mode 100644
index 000000000..bb393b520
--- /dev/null
+++ b/test/reference/smask-text.xlib-fallback.ref.png
Binary files differ
diff --git a/test/reference/smask.base.argb32.ref.png b/test/reference/smask.base.argb32.ref.png
new file mode 100644
index 000000000..357e8e7fb
--- /dev/null
+++ b/test/reference/smask.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/smask.base.rgb24.ref.png b/test/reference/smask.base.rgb24.ref.png
new file mode 100644
index 000000000..357e8e7fb
--- /dev/null
+++ b/test/reference/smask.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/smask.image16.ref.png b/test/reference/smask.image16.ref.png
new file mode 100644
index 000000000..d817c8014
--- /dev/null
+++ b/test/reference/smask.image16.ref.png
Binary files differ
diff --git a/test/reference/smask.mask.argb32.ref.png b/test/reference/smask.mask.argb32.ref.png
new file mode 100644
index 000000000..dab308d8e
--- /dev/null
+++ b/test/reference/smask.mask.argb32.ref.png
Binary files differ
diff --git a/test/reference/smask.mask.rgb24.ref.png b/test/reference/smask.mask.rgb24.ref.png
new file mode 100644
index 000000000..dab308d8e
--- /dev/null
+++ b/test/reference/smask.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/smask.pdf.xfail.png b/test/reference/smask.pdf.xfail.png
new file mode 100644
index 000000000..f8b559cb4
--- /dev/null
+++ b/test/reference/smask.pdf.xfail.png
Binary files differ
diff --git a/test/reference/smask.ps.ref.png b/test/reference/smask.ps.ref.png
new file mode 100644
index 000000000..31ccc17b7
--- /dev/null
+++ b/test/reference/smask.ps.ref.png
Binary files differ
diff --git a/test/reference/smask.quartz.ref.png b/test/reference/smask.quartz.ref.png
new file mode 100644
index 000000000..f9ab00f85
--- /dev/null
+++ b/test/reference/smask.quartz.ref.png
Binary files differ
diff --git a/test/reference/smask.ref.png b/test/reference/smask.ref.png
new file mode 100644
index 000000000..d49e8f5a1
--- /dev/null
+++ b/test/reference/smask.ref.png
Binary files differ
diff --git a/test/reference/smask.script.ref.png b/test/reference/smask.script.ref.png
new file mode 100644
index 000000000..3b672d6e9
--- /dev/null
+++ b/test/reference/smask.script.ref.png
Binary files differ
diff --git a/test/reference/smask.svg.ref.png b/test/reference/smask.svg.ref.png
new file mode 100644
index 000000000..b9c0308d2
--- /dev/null
+++ b/test/reference/smask.svg.ref.png
Binary files differ
diff --git a/test/reference/smask.traps.ref.png b/test/reference/smask.traps.ref.png
new file mode 100644
index 000000000..357e8e7fb
--- /dev/null
+++ b/test/reference/smask.traps.ref.png
Binary files differ
diff --git a/test/reference/smask.xlib-fallback.ref.png b/test/reference/smask.xlib-fallback.ref.png
new file mode 100644
index 000000000..b5919de37
--- /dev/null
+++ b/test/reference/smask.xlib-fallback.ref.png
Binary files differ
diff --git a/test/reference/solid-pattern-cache-stress.base.argb32.ref.png b/test/reference/solid-pattern-cache-stress.base.argb32.ref.png
new file mode 100644
index 000000000..08a2ce152
--- /dev/null
+++ b/test/reference/solid-pattern-cache-stress.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/solid-pattern-cache-stress.base.rgb24.ref.png b/test/reference/solid-pattern-cache-stress.base.rgb24.ref.png
new file mode 100644
index 000000000..08a2ce152
--- /dev/null
+++ b/test/reference/solid-pattern-cache-stress.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/solid-pattern-cache-stress.ref.png b/test/reference/solid-pattern-cache-stress.ref.png
new file mode 100644
index 000000000..e0e8498c3
--- /dev/null
+++ b/test/reference/solid-pattern-cache-stress.ref.png
Binary files differ
diff --git a/test/reference/source-clip-scale.base.argb32.ref.png b/test/reference/source-clip-scale.base.argb32.ref.png
new file mode 100644
index 000000000..4b63ad9bf
--- /dev/null
+++ b/test/reference/source-clip-scale.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/source-clip-scale.base.rgb24.ref.png b/test/reference/source-clip-scale.base.rgb24.ref.png
new file mode 100644
index 000000000..4b63ad9bf
--- /dev/null
+++ b/test/reference/source-clip-scale.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/source-clip-scale.gl.ref.png b/test/reference/source-clip-scale.gl.ref.png
new file mode 100644
index 000000000..fcffbef1f
--- /dev/null
+++ b/test/reference/source-clip-scale.gl.ref.png
Binary files differ
diff --git a/test/reference/source-clip-scale.pdf.ref.png b/test/reference/source-clip-scale.pdf.ref.png
new file mode 100644
index 000000000..78c77106c
--- /dev/null
+++ b/test/reference/source-clip-scale.pdf.ref.png
Binary files differ
diff --git a/test/reference/source-clip-scale.ps2.argb32.ref.png b/test/reference/source-clip-scale.ps2.argb32.ref.png
new file mode 100644
index 000000000..be57d7721
--- /dev/null
+++ b/test/reference/source-clip-scale.ps2.argb32.ref.png
Binary files differ
diff --git a/test/reference/source-clip-scale.ps2.rgb24.ref.png b/test/reference/source-clip-scale.ps2.rgb24.ref.png
new file mode 100644
index 000000000..be57d7721
--- /dev/null
+++ b/test/reference/source-clip-scale.ps2.rgb24.ref.png
Binary files differ
diff --git a/test/reference/source-clip-scale.ps3.argb32.ref.png b/test/reference/source-clip-scale.ps3.argb32.ref.png
new file mode 100644
index 000000000..be57d7721
--- /dev/null
+++ b/test/reference/source-clip-scale.ps3.argb32.ref.png
Binary files differ
diff --git a/test/reference/source-clip-scale.ps3.rgb24.ref.png b/test/reference/source-clip-scale.ps3.rgb24.ref.png
new file mode 100644
index 000000000..be57d7721
--- /dev/null
+++ b/test/reference/source-clip-scale.ps3.rgb24.ref.png
Binary files differ
diff --git a/test/reference/source-clip-scale.quartz.ref.png b/test/reference/source-clip-scale.quartz.ref.png
new file mode 100644
index 000000000..366500905
--- /dev/null
+++ b/test/reference/source-clip-scale.quartz.ref.png
Binary files differ
diff --git a/test/reference/source-clip-scale.recording.ref.png b/test/reference/source-clip-scale.recording.ref.png
new file mode 100644
index 000000000..bbf7c9be5
--- /dev/null
+++ b/test/reference/source-clip-scale.recording.ref.png
Binary files differ
diff --git a/test/reference/source-clip-scale.ref.png b/test/reference/source-clip-scale.ref.png
new file mode 100644
index 000000000..1519ff895
--- /dev/null
+++ b/test/reference/source-clip-scale.ref.png
Binary files differ
diff --git a/test/reference/source-clip-scale.svg.ref.png b/test/reference/source-clip-scale.svg.ref.png
new file mode 100644
index 000000000..bbf7c9be5
--- /dev/null
+++ b/test/reference/source-clip-scale.svg.ref.png
Binary files differ
diff --git a/test/reference/source-clip.base.argb32.ref.png b/test/reference/source-clip.base.argb32.ref.png
new file mode 100644
index 000000000..821bc6cab
--- /dev/null
+++ b/test/reference/source-clip.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/source-clip.base.rgb24.ref.png b/test/reference/source-clip.base.rgb24.ref.png
new file mode 100644
index 000000000..821bc6cab
--- /dev/null
+++ b/test/reference/source-clip.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/source-clip.ref.png b/test/reference/source-clip.ref.png
new file mode 100644
index 000000000..22454bed9
--- /dev/null
+++ b/test/reference/source-clip.ref.png
Binary files differ
diff --git a/test/reference/source-surface-scale-paint.base.argb32.ref.png b/test/reference/source-surface-scale-paint.base.argb32.ref.png
new file mode 100644
index 000000000..087ef7521
--- /dev/null
+++ b/test/reference/source-surface-scale-paint.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/source-surface-scale-paint.base.rgb24.ref.png b/test/reference/source-surface-scale-paint.base.rgb24.ref.png
new file mode 100644
index 000000000..322af211d
--- /dev/null
+++ b/test/reference/source-surface-scale-paint.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/source-surface-scale-paint.ref.png b/test/reference/source-surface-scale-paint.ref.png
new file mode 100644
index 000000000..a81f93d94
--- /dev/null
+++ b/test/reference/source-surface-scale-paint.ref.png
Binary files differ
diff --git a/test/reference/spline-decomposition.base.argb32.ref.png b/test/reference/spline-decomposition.base.argb32.ref.png
new file mode 100644
index 000000000..babde7d72
--- /dev/null
+++ b/test/reference/spline-decomposition.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/spline-decomposition.base.rgb24.ref.png b/test/reference/spline-decomposition.base.rgb24.ref.png
new file mode 100644
index 000000000..babde7d72
--- /dev/null
+++ b/test/reference/spline-decomposition.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/spline-decomposition.image16.ref.png b/test/reference/spline-decomposition.image16.ref.png
new file mode 100644
index 000000000..4084b00f9
--- /dev/null
+++ b/test/reference/spline-decomposition.image16.ref.png
Binary files differ
diff --git a/test/reference/spline-decomposition.pdf.ref.png b/test/reference/spline-decomposition.pdf.ref.png
new file mode 100644
index 000000000..5afa09498
--- /dev/null
+++ b/test/reference/spline-decomposition.pdf.ref.png
Binary files differ
diff --git a/test/reference/spline-decomposition.ps.ref.png b/test/reference/spline-decomposition.ps.ref.png
new file mode 100644
index 000000000..51e2938ac
--- /dev/null
+++ b/test/reference/spline-decomposition.ps.ref.png
Binary files differ
diff --git a/test/reference/spline-decomposition.quartz.xfail.png b/test/reference/spline-decomposition.quartz.xfail.png
new file mode 100644
index 000000000..18d67fbb5
--- /dev/null
+++ b/test/reference/spline-decomposition.quartz.xfail.png
Binary files differ
diff --git a/test/reference/spline-decomposition.ref.png b/test/reference/spline-decomposition.ref.png
new file mode 100644
index 000000000..356a3a56e
--- /dev/null
+++ b/test/reference/spline-decomposition.ref.png
Binary files differ
diff --git a/test/reference/spline-decomposition.svg.ref.png b/test/reference/spline-decomposition.svg.ref.png
new file mode 100644
index 000000000..5afa09498
--- /dev/null
+++ b/test/reference/spline-decomposition.svg.ref.png
Binary files differ
diff --git a/test/reference/spline-decomposition.traps.argb32.ref.png b/test/reference/spline-decomposition.traps.argb32.ref.png
new file mode 100644
index 000000000..babde7d72
--- /dev/null
+++ b/test/reference/spline-decomposition.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/spline-decomposition.traps.rgb24.ref.png b/test/reference/spline-decomposition.traps.rgb24.ref.png
new file mode 100644
index 000000000..babde7d72
--- /dev/null
+++ b/test/reference/spline-decomposition.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/stride-12-image.base.argb32.ref.png b/test/reference/stride-12-image.base.argb32.ref.png
new file mode 100644
index 000000000..44284566e
--- /dev/null
+++ b/test/reference/stride-12-image.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/stride-12-image.base.rgb24.ref.png b/test/reference/stride-12-image.base.rgb24.ref.png
new file mode 100644
index 000000000..44284566e
--- /dev/null
+++ b/test/reference/stride-12-image.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/stride-12-image.image16.ref.png b/test/reference/stride-12-image.image16.ref.png
new file mode 100644
index 000000000..4b15914f2
--- /dev/null
+++ b/test/reference/stride-12-image.image16.ref.png
Binary files differ
diff --git a/test/reference/stride-12-image.ps.ref.png b/test/reference/stride-12-image.ps.ref.png
new file mode 100644
index 000000000..953c9a18e
--- /dev/null
+++ b/test/reference/stride-12-image.ps.ref.png
Binary files differ
diff --git a/test/reference/stride-12-image.ref.png b/test/reference/stride-12-image.ref.png
new file mode 100644
index 000000000..44284566e
--- /dev/null
+++ b/test/reference/stride-12-image.ref.png
Binary files differ
diff --git a/test/reference/stride-12-xlib-fallback.rgb24.ref.png b/test/reference/stride-12-xlib-fallback.rgb24.ref.png
new file mode 100644
index 000000000..44284566e
--- /dev/null
+++ b/test/reference/stride-12-xlib-fallback.rgb24.ref.png
Binary files differ
diff --git a/test/reference/stride-12-xlib-window.rgb24.ref.png b/test/reference/stride-12-xlib-window.rgb24.ref.png
new file mode 100644
index 000000000..44284566e
--- /dev/null
+++ b/test/reference/stride-12-xlib-window.rgb24.ref.png
Binary files differ
diff --git a/test/reference/stride-12-xlib.ref.png b/test/reference/stride-12-xlib.ref.png
new file mode 100644
index 000000000..44284566e
--- /dev/null
+++ b/test/reference/stride-12-xlib.ref.png
Binary files differ
diff --git a/test/reference/stroke-clipped.ref.png b/test/reference/stroke-clipped.ref.png
new file mode 100644
index 000000000..fbe5788d5
--- /dev/null
+++ b/test/reference/stroke-clipped.ref.png
Binary files differ
diff --git a/test/reference/stroke-ctm-caps.base.argb32.ref.png b/test/reference/stroke-ctm-caps.base.argb32.ref.png
new file mode 100644
index 000000000..efe2faab3
--- /dev/null
+++ b/test/reference/stroke-ctm-caps.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/stroke-ctm-caps.base.rgb24.ref.png b/test/reference/stroke-ctm-caps.base.rgb24.ref.png
new file mode 100644
index 000000000..efe2faab3
--- /dev/null
+++ b/test/reference/stroke-ctm-caps.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/stroke-ctm-caps.image16.ref.png b/test/reference/stroke-ctm-caps.image16.ref.png
new file mode 100644
index 000000000..f5f551e23
--- /dev/null
+++ b/test/reference/stroke-ctm-caps.image16.ref.png
Binary files differ
diff --git a/test/reference/stroke-ctm-caps.mask.argb32.ref.png b/test/reference/stroke-ctm-caps.mask.argb32.ref.png
new file mode 100644
index 000000000..3a77d3ea6
--- /dev/null
+++ b/test/reference/stroke-ctm-caps.mask.argb32.ref.png
Binary files differ
diff --git a/test/reference/stroke-ctm-caps.mask.rgb24.ref.png b/test/reference/stroke-ctm-caps.mask.rgb24.ref.png
new file mode 100644
index 000000000..3a77d3ea6
--- /dev/null
+++ b/test/reference/stroke-ctm-caps.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/stroke-ctm-caps.ps2.ref.png b/test/reference/stroke-ctm-caps.ps2.ref.png
new file mode 100644
index 000000000..63c10645b
--- /dev/null
+++ b/test/reference/stroke-ctm-caps.ps2.ref.png
Binary files differ
diff --git a/test/reference/stroke-ctm-caps.ps3.ref.png b/test/reference/stroke-ctm-caps.ps3.ref.png
new file mode 100644
index 000000000..63c10645b
--- /dev/null
+++ b/test/reference/stroke-ctm-caps.ps3.ref.png
Binary files differ
diff --git a/test/reference/stroke-ctm-caps.quartz.ref.png b/test/reference/stroke-ctm-caps.quartz.ref.png
new file mode 100644
index 000000000..c9da2c9d3
--- /dev/null
+++ b/test/reference/stroke-ctm-caps.quartz.ref.png
Binary files differ
diff --git a/test/reference/stroke-ctm-caps.ref.png b/test/reference/stroke-ctm-caps.ref.png
new file mode 100644
index 000000000..33ff0fad7
--- /dev/null
+++ b/test/reference/stroke-ctm-caps.ref.png
Binary files differ
diff --git a/test/reference/stroke-ctm-caps.traps.argb32.ref.png b/test/reference/stroke-ctm-caps.traps.argb32.ref.png
new file mode 100644
index 000000000..efe2faab3
--- /dev/null
+++ b/test/reference/stroke-ctm-caps.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/stroke-ctm-caps.traps.rgb24.ref.png b/test/reference/stroke-ctm-caps.traps.rgb24.ref.png
new file mode 100644
index 000000000..efe2faab3
--- /dev/null
+++ b/test/reference/stroke-ctm-caps.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/stroke-image.base.argb32.ref.png b/test/reference/stroke-image.base.argb32.ref.png
new file mode 100644
index 000000000..75737d57c
--- /dev/null
+++ b/test/reference/stroke-image.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/stroke-image.base.rgb24.ref.png b/test/reference/stroke-image.base.rgb24.ref.png
new file mode 100644
index 000000000..75737d57c
--- /dev/null
+++ b/test/reference/stroke-image.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/stroke-image.image16.ref.png b/test/reference/stroke-image.image16.ref.png
new file mode 100644
index 000000000..cef40bda9
--- /dev/null
+++ b/test/reference/stroke-image.image16.ref.png
Binary files differ
diff --git a/test/reference/stroke-image.pdf.ref.png b/test/reference/stroke-image.pdf.ref.png
new file mode 100644
index 000000000..790369cb4
--- /dev/null
+++ b/test/reference/stroke-image.pdf.ref.png
Binary files differ
diff --git a/test/reference/stroke-image.ps.ref.png b/test/reference/stroke-image.ps.ref.png
new file mode 100644
index 000000000..71889acfd
--- /dev/null
+++ b/test/reference/stroke-image.ps.ref.png
Binary files differ
diff --git a/test/reference/stroke-image.quartz.ref.png b/test/reference/stroke-image.quartz.ref.png
new file mode 100644
index 000000000..f9a60f2a6
--- /dev/null
+++ b/test/reference/stroke-image.quartz.ref.png
Binary files differ
diff --git a/test/reference/stroke-image.ref.png b/test/reference/stroke-image.ref.png
new file mode 100644
index 000000000..f126afe2c
--- /dev/null
+++ b/test/reference/stroke-image.ref.png
Binary files differ
diff --git a/test/reference/stroke-image.traps.argb32.ref.png b/test/reference/stroke-image.traps.argb32.ref.png
new file mode 100644
index 000000000..75737d57c
--- /dev/null
+++ b/test/reference/stroke-image.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/stroke-image.traps.rgb24.ref.png b/test/reference/stroke-image.traps.rgb24.ref.png
new file mode 100644
index 000000000..75737d57c
--- /dev/null
+++ b/test/reference/stroke-image.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/stroke-open-box.base.argb32.ref.png b/test/reference/stroke-open-box.base.argb32.ref.png
new file mode 100644
index 000000000..b5f5bd581
--- /dev/null
+++ b/test/reference/stroke-open-box.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/stroke-open-box.base.rgb24.ref.png b/test/reference/stroke-open-box.base.rgb24.ref.png
new file mode 100644
index 000000000..b5f5bd581
--- /dev/null
+++ b/test/reference/stroke-open-box.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/stroke-open-box.ref.png b/test/reference/stroke-open-box.ref.png
new file mode 100644
index 000000000..b5f5bd581
--- /dev/null
+++ b/test/reference/stroke-open-box.ref.png
Binary files differ
diff --git a/test/reference/stroke-pattern.base.argb32.ref.png b/test/reference/stroke-pattern.base.argb32.ref.png
new file mode 100644
index 000000000..67bb03143
--- /dev/null
+++ b/test/reference/stroke-pattern.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/stroke-pattern.base.rgb24.ref.png b/test/reference/stroke-pattern.base.rgb24.ref.png
new file mode 100644
index 000000000..67bb03143
--- /dev/null
+++ b/test/reference/stroke-pattern.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/stroke-pattern.ref.png b/test/reference/stroke-pattern.ref.png
new file mode 100644
index 000000000..e299c5869
--- /dev/null
+++ b/test/reference/stroke-pattern.ref.png
Binary files differ
diff --git a/test/reference/stroke-pattern.traps.ref.png b/test/reference/stroke-pattern.traps.ref.png
new file mode 100644
index 000000000..67bb03143
--- /dev/null
+++ b/test/reference/stroke-pattern.traps.ref.png
Binary files differ
diff --git a/test/reference/stroke-xlib-fallback.rgb24.ref.png b/test/reference/stroke-xlib-fallback.rgb24.ref.png
new file mode 100644
index 000000000..75737d57c
--- /dev/null
+++ b/test/reference/stroke-xlib-fallback.rgb24.ref.png
Binary files differ
diff --git a/test/reference/stroke-xlib-window.rgb24.ref.png b/test/reference/stroke-xlib-window.rgb24.ref.png
new file mode 100644
index 000000000..75737d57c
--- /dev/null
+++ b/test/reference/stroke-xlib-window.rgb24.ref.png
Binary files differ
diff --git a/test/reference/stroke-xlib.ref.png b/test/reference/stroke-xlib.ref.png
new file mode 100644
index 000000000..75737d57c
--- /dev/null
+++ b/test/reference/stroke-xlib.ref.png
Binary files differ
diff --git a/test/reference/stroke.image.argb32.ref.png b/test/reference/stroke.image.argb32.ref.png
new file mode 100644
index 000000000..0dc701f2e
--- /dev/null
+++ b/test/reference/stroke.image.argb32.ref.png
Binary files differ
diff --git a/test/reference/stroke.image.rgb24.ref.png b/test/reference/stroke.image.rgb24.ref.png
new file mode 100644
index 000000000..0dc701f2e
--- /dev/null
+++ b/test/reference/stroke.image.rgb24.ref.png
Binary files differ
diff --git a/test/reference/subsurface-image-repeat.base.argb32.ref.png b/test/reference/subsurface-image-repeat.base.argb32.ref.png
new file mode 100644
index 000000000..3dd6306a0
--- /dev/null
+++ b/test/reference/subsurface-image-repeat.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/subsurface-image-repeat.base.rgb24.ref.png b/test/reference/subsurface-image-repeat.base.rgb24.ref.png
new file mode 100644
index 000000000..3dd6306a0
--- /dev/null
+++ b/test/reference/subsurface-image-repeat.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/subsurface-image-repeat.image16.ref.png b/test/reference/subsurface-image-repeat.image16.ref.png
new file mode 100644
index 000000000..a62f21078
--- /dev/null
+++ b/test/reference/subsurface-image-repeat.image16.ref.png
Binary files differ
diff --git a/test/reference/subsurface-image-repeat.ref.png b/test/reference/subsurface-image-repeat.ref.png
new file mode 100644
index 000000000..3dd6306a0
--- /dev/null
+++ b/test/reference/subsurface-image-repeat.ref.png
Binary files differ
diff --git a/test/reference/subsurface-modify-child.base.argb32.ref.png b/test/reference/subsurface-modify-child.base.argb32.ref.png
new file mode 100644
index 000000000..c37e22e36
--- /dev/null
+++ b/test/reference/subsurface-modify-child.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/subsurface-modify-child.base.rgb24.ref.png b/test/reference/subsurface-modify-child.base.rgb24.ref.png
new file mode 100644
index 000000000..c37e22e36
--- /dev/null
+++ b/test/reference/subsurface-modify-child.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/subsurface-modify-child.ref.png b/test/reference/subsurface-modify-child.ref.png
new file mode 100644
index 000000000..c37e22e36
--- /dev/null
+++ b/test/reference/subsurface-modify-child.ref.png
Binary files differ
diff --git a/test/reference/subsurface-modify-parent.base.argb32.ref.png b/test/reference/subsurface-modify-parent.base.argb32.ref.png
new file mode 100644
index 000000000..c37e22e36
--- /dev/null
+++ b/test/reference/subsurface-modify-parent.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/subsurface-modify-parent.base.rgb24.ref.png b/test/reference/subsurface-modify-parent.base.rgb24.ref.png
new file mode 100644
index 000000000..c37e22e36
--- /dev/null
+++ b/test/reference/subsurface-modify-parent.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/subsurface-modify-parent.ref.png b/test/reference/subsurface-modify-parent.ref.png
new file mode 100644
index 000000000..c37e22e36
--- /dev/null
+++ b/test/reference/subsurface-modify-parent.ref.png
Binary files differ
diff --git a/test/reference/subsurface-outside-target.base.argb32.ref.png b/test/reference/subsurface-outside-target.base.argb32.ref.png
new file mode 100644
index 000000000..337cdd803
--- /dev/null
+++ b/test/reference/subsurface-outside-target.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/subsurface-outside-target.base.rgb24.ref.png b/test/reference/subsurface-outside-target.base.rgb24.ref.png
new file mode 100644
index 000000000..368936e5c
--- /dev/null
+++ b/test/reference/subsurface-outside-target.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/subsurface-outside-target.ref.png b/test/reference/subsurface-outside-target.ref.png
new file mode 100644
index 000000000..337cdd803
--- /dev/null
+++ b/test/reference/subsurface-outside-target.ref.png
Binary files differ
diff --git a/test/reference/subsurface-pad.base.argb32.ref.png b/test/reference/subsurface-pad.base.argb32.ref.png
new file mode 100644
index 000000000..eeb9f8f59
--- /dev/null
+++ b/test/reference/subsurface-pad.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/subsurface-pad.base.rgb24.ref.png b/test/reference/subsurface-pad.base.rgb24.ref.png
new file mode 100644
index 000000000..eeb9f8f59
--- /dev/null
+++ b/test/reference/subsurface-pad.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/subsurface-pad.quartz.xfail.png b/test/reference/subsurface-pad.quartz.xfail.png
new file mode 100644
index 000000000..c37e22e36
--- /dev/null
+++ b/test/reference/subsurface-pad.quartz.xfail.png
Binary files differ
diff --git a/test/reference/subsurface-pad.ref.png b/test/reference/subsurface-pad.ref.png
new file mode 100644
index 000000000..eeb9f8f59
--- /dev/null
+++ b/test/reference/subsurface-pad.ref.png
Binary files differ
diff --git a/test/reference/subsurface-reflect.base.argb32.ref.png b/test/reference/subsurface-reflect.base.argb32.ref.png
new file mode 100644
index 000000000..55643f448
--- /dev/null
+++ b/test/reference/subsurface-reflect.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/subsurface-reflect.base.rgb24.ref.png b/test/reference/subsurface-reflect.base.rgb24.ref.png
new file mode 100644
index 000000000..55643f448
--- /dev/null
+++ b/test/reference/subsurface-reflect.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/subsurface-reflect.ref.png b/test/reference/subsurface-reflect.ref.png
new file mode 100644
index 000000000..55643f448
--- /dev/null
+++ b/test/reference/subsurface-reflect.ref.png
Binary files differ
diff --git a/test/reference/subsurface-repeat.base.argb32.ref.png b/test/reference/subsurface-repeat.base.argb32.ref.png
new file mode 100644
index 000000000..c37e22e36
--- /dev/null
+++ b/test/reference/subsurface-repeat.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/subsurface-repeat.base.rgb24.ref.png b/test/reference/subsurface-repeat.base.rgb24.ref.png
new file mode 100644
index 000000000..c37e22e36
--- /dev/null
+++ b/test/reference/subsurface-repeat.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/subsurface-repeat.ref.png b/test/reference/subsurface-repeat.ref.png
new file mode 100644
index 000000000..c37e22e36
--- /dev/null
+++ b/test/reference/subsurface-repeat.ref.png
Binary files differ
diff --git a/test/reference/subsurface-scale.base.argb32.ref.png b/test/reference/subsurface-scale.base.argb32.ref.png
new file mode 100644
index 000000000..3b70c2fb4
--- /dev/null
+++ b/test/reference/subsurface-scale.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/subsurface-scale.base.rgb24.ref.png b/test/reference/subsurface-scale.base.rgb24.ref.png
new file mode 100644
index 000000000..3b70c2fb4
--- /dev/null
+++ b/test/reference/subsurface-scale.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/subsurface-scale.ref.png b/test/reference/subsurface-scale.ref.png
new file mode 100644
index 000000000..69bb0fb9a
--- /dev/null
+++ b/test/reference/subsurface-scale.ref.png
Binary files differ
diff --git a/test/reference/subsurface-scale.traps.argb32.ref.png b/test/reference/subsurface-scale.traps.argb32.ref.png
new file mode 100644
index 000000000..3b70c2fb4
--- /dev/null
+++ b/test/reference/subsurface-scale.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/subsurface-scale.traps.rgb24.ref.png b/test/reference/subsurface-scale.traps.rgb24.ref.png
new file mode 100644
index 000000000..3b70c2fb4
--- /dev/null
+++ b/test/reference/subsurface-scale.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/subsurface-similar-repeat.base.argb32.ref.png b/test/reference/subsurface-similar-repeat.base.argb32.ref.png
new file mode 100644
index 000000000..c37e22e36
--- /dev/null
+++ b/test/reference/subsurface-similar-repeat.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/subsurface-similar-repeat.base.rgb24.ref.png b/test/reference/subsurface-similar-repeat.base.rgb24.ref.png
new file mode 100644
index 000000000..c37e22e36
--- /dev/null
+++ b/test/reference/subsurface-similar-repeat.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/subsurface-similar-repeat.ref.png b/test/reference/subsurface-similar-repeat.ref.png
new file mode 100644
index 000000000..c37e22e36
--- /dev/null
+++ b/test/reference/subsurface-similar-repeat.ref.png
Binary files differ
diff --git a/test/reference/subsurface.base.argb32.ref.png b/test/reference/subsurface.base.argb32.ref.png
new file mode 100644
index 000000000..d2035592e
--- /dev/null
+++ b/test/reference/subsurface.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/subsurface.base.rgb24.ref.png b/test/reference/subsurface.base.rgb24.ref.png
new file mode 100644
index 000000000..d2035592e
--- /dev/null
+++ b/test/reference/subsurface.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/subsurface.image16.ref.png b/test/reference/subsurface.image16.ref.png
new file mode 100644
index 000000000..ba9b7ed07
--- /dev/null
+++ b/test/reference/subsurface.image16.ref.png
Binary files differ
diff --git a/test/reference/subsurface.ps.ref.png b/test/reference/subsurface.ps.ref.png
new file mode 100644
index 000000000..51e19fcf7
--- /dev/null
+++ b/test/reference/subsurface.ps.ref.png
Binary files differ
diff --git a/test/reference/subsurface.ref.png b/test/reference/subsurface.ref.png
new file mode 100644
index 000000000..feeb5dc8a
--- /dev/null
+++ b/test/reference/subsurface.ref.png
Binary files differ
diff --git a/test/reference/subsurface.traps.argb32.ref.png b/test/reference/subsurface.traps.argb32.ref.png
new file mode 100644
index 000000000..d2035592e
--- /dev/null
+++ b/test/reference/subsurface.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/subsurface.traps.rgb24.ref.png b/test/reference/subsurface.traps.rgb24.ref.png
new file mode 100644
index 000000000..d2035592e
--- /dev/null
+++ b/test/reference/subsurface.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/surface-pattern-big-scale-down.base.argb32.ref.png b/test/reference/surface-pattern-big-scale-down.base.argb32.ref.png
new file mode 100644
index 000000000..c05099077
--- /dev/null
+++ b/test/reference/surface-pattern-big-scale-down.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/surface-pattern-big-scale-down.base.rgb24.ref.png b/test/reference/surface-pattern-big-scale-down.base.rgb24.ref.png
new file mode 100644
index 000000000..c05099077
--- /dev/null
+++ b/test/reference/surface-pattern-big-scale-down.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/surface-pattern-big-scale-down.ps.ref.png b/test/reference/surface-pattern-big-scale-down.ps.ref.png
new file mode 100644
index 000000000..13fb09362
--- /dev/null
+++ b/test/reference/surface-pattern-big-scale-down.ps.ref.png
Binary files differ
diff --git a/test/reference/surface-pattern-big-scale-down.quartz.ref.png b/test/reference/surface-pattern-big-scale-down.quartz.ref.png
new file mode 100644
index 000000000..32deb2d9b
--- /dev/null
+++ b/test/reference/surface-pattern-big-scale-down.quartz.ref.png
Binary files differ
diff --git a/test/reference/surface-pattern-big-scale-down.ref.png b/test/reference/surface-pattern-big-scale-down.ref.png
new file mode 100644
index 000000000..c05099077
--- /dev/null
+++ b/test/reference/surface-pattern-big-scale-down.ref.png
Binary files differ
diff --git a/test/reference/surface-pattern-operator.argb32.ref.png b/test/reference/surface-pattern-operator.argb32.ref.png
new file mode 100644
index 000000000..67573715c
--- /dev/null
+++ b/test/reference/surface-pattern-operator.argb32.ref.png
Binary files differ
diff --git a/test/reference/surface-pattern-operator.base.argb32.ref.png b/test/reference/surface-pattern-operator.base.argb32.ref.png
new file mode 100644
index 000000000..c274fcf71
--- /dev/null
+++ b/test/reference/surface-pattern-operator.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/surface-pattern-operator.base.rgb24.ref.png b/test/reference/surface-pattern-operator.base.rgb24.ref.png
new file mode 100644
index 000000000..23e540df5
--- /dev/null
+++ b/test/reference/surface-pattern-operator.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/surface-pattern-operator.image16.ref.png b/test/reference/surface-pattern-operator.image16.ref.png
new file mode 100644
index 000000000..507e49c83
--- /dev/null
+++ b/test/reference/surface-pattern-operator.image16.ref.png
Binary files differ
diff --git a/test/reference/surface-pattern-operator.pdf.argb32.xfail.png b/test/reference/surface-pattern-operator.pdf.argb32.xfail.png
new file mode 100644
index 000000000..371d08474
--- /dev/null
+++ b/test/reference/surface-pattern-operator.pdf.argb32.xfail.png
Binary files differ
diff --git a/test/reference/surface-pattern-operator.pdf.rgb24.xfail.png b/test/reference/surface-pattern-operator.pdf.rgb24.xfail.png
new file mode 100644
index 000000000..a2da18d22
--- /dev/null
+++ b/test/reference/surface-pattern-operator.pdf.rgb24.xfail.png
Binary files differ
diff --git a/test/reference/surface-pattern-operator.quartz.argb32.ref.png b/test/reference/surface-pattern-operator.quartz.argb32.ref.png
new file mode 100644
index 000000000..5e934b211
--- /dev/null
+++ b/test/reference/surface-pattern-operator.quartz.argb32.ref.png
Binary files differ
diff --git a/test/reference/surface-pattern-operator.quartz.rgb24.ref.png b/test/reference/surface-pattern-operator.quartz.rgb24.ref.png
new file mode 100644
index 000000000..30408c1f4
--- /dev/null
+++ b/test/reference/surface-pattern-operator.quartz.rgb24.ref.png
Binary files differ
diff --git a/test/reference/surface-pattern-operator.rgb24.ref.png b/test/reference/surface-pattern-operator.rgb24.ref.png
new file mode 100644
index 000000000..aee0959c2
--- /dev/null
+++ b/test/reference/surface-pattern-operator.rgb24.ref.png
Binary files differ
diff --git a/test/reference/surface-pattern-operator.traps.argb32.ref.png b/test/reference/surface-pattern-operator.traps.argb32.ref.png
new file mode 100644
index 000000000..c274fcf71
--- /dev/null
+++ b/test/reference/surface-pattern-operator.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/surface-pattern-operator.traps.rgb24.ref.png b/test/reference/surface-pattern-operator.traps.rgb24.ref.png
new file mode 100644
index 000000000..23e540df5
--- /dev/null
+++ b/test/reference/surface-pattern-operator.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/surface-pattern-scale-down-extend-none.base.argb32.ref.png b/test/reference/surface-pattern-scale-down-extend-none.base.argb32.ref.png
new file mode 100644
index 000000000..9df14cc5c
--- /dev/null
+++ b/test/reference/surface-pattern-scale-down-extend-none.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/surface-pattern-scale-down-extend-none.base.rgb24.ref.png b/test/reference/surface-pattern-scale-down-extend-none.base.rgb24.ref.png
new file mode 100644
index 000000000..9df14cc5c
--- /dev/null
+++ b/test/reference/surface-pattern-scale-down-extend-none.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/surface-pattern-scale-down-extend-none.quartz.ref.png b/test/reference/surface-pattern-scale-down-extend-none.quartz.ref.png
new file mode 100644
index 000000000..e126cbb31
--- /dev/null
+++ b/test/reference/surface-pattern-scale-down-extend-none.quartz.ref.png
Binary files differ
diff --git a/test/reference/surface-pattern-scale-down-extend-none.ref.png b/test/reference/surface-pattern-scale-down-extend-none.ref.png
new file mode 100644
index 000000000..9df14cc5c
--- /dev/null
+++ b/test/reference/surface-pattern-scale-down-extend-none.ref.png
Binary files differ
diff --git a/test/reference/surface-pattern-scale-down-extend-pad.base.argb32.ref.png b/test/reference/surface-pattern-scale-down-extend-pad.base.argb32.ref.png
new file mode 100644
index 000000000..2ee941907
--- /dev/null
+++ b/test/reference/surface-pattern-scale-down-extend-pad.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/surface-pattern-scale-down-extend-pad.base.rgb24.ref.png b/test/reference/surface-pattern-scale-down-extend-pad.base.rgb24.ref.png
new file mode 100644
index 000000000..2ee941907
--- /dev/null
+++ b/test/reference/surface-pattern-scale-down-extend-pad.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/surface-pattern-scale-down-extend-pad.quartz.xfail.png b/test/reference/surface-pattern-scale-down-extend-pad.quartz.xfail.png
new file mode 100644
index 000000000..6b8f7540e
--- /dev/null
+++ b/test/reference/surface-pattern-scale-down-extend-pad.quartz.xfail.png
Binary files differ
diff --git a/test/reference/surface-pattern-scale-down-extend-pad.ref.png b/test/reference/surface-pattern-scale-down-extend-pad.ref.png
new file mode 100644
index 000000000..2ee941907
--- /dev/null
+++ b/test/reference/surface-pattern-scale-down-extend-pad.ref.png
Binary files differ
diff --git a/test/reference/surface-pattern-scale-down-extend-reflect.base.argb32.ref.png b/test/reference/surface-pattern-scale-down-extend-reflect.base.argb32.ref.png
new file mode 100644
index 000000000..f2e93a7dd
--- /dev/null
+++ b/test/reference/surface-pattern-scale-down-extend-reflect.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/surface-pattern-scale-down-extend-reflect.base.rgb24.ref.png b/test/reference/surface-pattern-scale-down-extend-reflect.base.rgb24.ref.png
new file mode 100644
index 000000000..f2e93a7dd
--- /dev/null
+++ b/test/reference/surface-pattern-scale-down-extend-reflect.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/surface-pattern-scale-down-extend-reflect.quartz.ref.png b/test/reference/surface-pattern-scale-down-extend-reflect.quartz.ref.png
new file mode 100644
index 000000000..ef5e62e11
--- /dev/null
+++ b/test/reference/surface-pattern-scale-down-extend-reflect.quartz.ref.png
Binary files differ
diff --git a/test/reference/surface-pattern-scale-down-extend-reflect.ref.png b/test/reference/surface-pattern-scale-down-extend-reflect.ref.png
new file mode 100644
index 000000000..f2e93a7dd
--- /dev/null
+++ b/test/reference/surface-pattern-scale-down-extend-reflect.ref.png
Binary files differ
diff --git a/test/reference/surface-pattern-scale-down-extend-repeat.base.argb32.ref.png b/test/reference/surface-pattern-scale-down-extend-repeat.base.argb32.ref.png
new file mode 100644
index 000000000..c5cff0fe3
--- /dev/null
+++ b/test/reference/surface-pattern-scale-down-extend-repeat.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/surface-pattern-scale-down-extend-repeat.base.rgb24.ref.png b/test/reference/surface-pattern-scale-down-extend-repeat.base.rgb24.ref.png
new file mode 100644
index 000000000..c5cff0fe3
--- /dev/null
+++ b/test/reference/surface-pattern-scale-down-extend-repeat.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/surface-pattern-scale-down-extend-repeat.quartz.ref.png b/test/reference/surface-pattern-scale-down-extend-repeat.quartz.ref.png
new file mode 100644
index 000000000..6b8f7540e
--- /dev/null
+++ b/test/reference/surface-pattern-scale-down-extend-repeat.quartz.ref.png
Binary files differ
diff --git a/test/reference/surface-pattern-scale-down-extend-repeat.ref.png b/test/reference/surface-pattern-scale-down-extend-repeat.ref.png
new file mode 100644
index 000000000..c5cff0fe3
--- /dev/null
+++ b/test/reference/surface-pattern-scale-down-extend-repeat.ref.png
Binary files differ
diff --git a/test/reference/surface-pattern-scale-down.base.argb32.ref.png b/test/reference/surface-pattern-scale-down.base.argb32.ref.png
new file mode 100644
index 000000000..8bb58a2a1
--- /dev/null
+++ b/test/reference/surface-pattern-scale-down.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/surface-pattern-scale-down.base.rgb24.ref.png b/test/reference/surface-pattern-scale-down.base.rgb24.ref.png
new file mode 100644
index 000000000..8bb58a2a1
--- /dev/null
+++ b/test/reference/surface-pattern-scale-down.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/surface-pattern-scale-down.image16.ref.png b/test/reference/surface-pattern-scale-down.image16.ref.png
new file mode 100644
index 000000000..8be8fb0e4
--- /dev/null
+++ b/test/reference/surface-pattern-scale-down.image16.ref.png
Binary files differ
diff --git a/test/reference/surface-pattern-scale-down.pdf.ref.png b/test/reference/surface-pattern-scale-down.pdf.ref.png
new file mode 100644
index 000000000..1e32a44bb
--- /dev/null
+++ b/test/reference/surface-pattern-scale-down.pdf.ref.png
Binary files differ
diff --git a/test/reference/surface-pattern-scale-down.ps2.ref.png b/test/reference/surface-pattern-scale-down.ps2.ref.png
new file mode 100644
index 000000000..5fb6395ce
--- /dev/null
+++ b/test/reference/surface-pattern-scale-down.ps2.ref.png
Binary files differ
diff --git a/test/reference/surface-pattern-scale-down.ps3.ref.png b/test/reference/surface-pattern-scale-down.ps3.ref.png
new file mode 100644
index 000000000..5fb6395ce
--- /dev/null
+++ b/test/reference/surface-pattern-scale-down.ps3.ref.png
Binary files differ
diff --git a/test/reference/surface-pattern-scale-down.quartz.ref.png b/test/reference/surface-pattern-scale-down.quartz.ref.png
new file mode 100644
index 000000000..5b3ace4ae
--- /dev/null
+++ b/test/reference/surface-pattern-scale-down.quartz.ref.png
Binary files differ
diff --git a/test/reference/surface-pattern-scale-down.ref.png b/test/reference/surface-pattern-scale-down.ref.png
new file mode 100644
index 000000000..8bb58a2a1
--- /dev/null
+++ b/test/reference/surface-pattern-scale-down.ref.png
Binary files differ
diff --git a/test/reference/surface-pattern-scale-up.base.argb32.ref.png b/test/reference/surface-pattern-scale-up.base.argb32.ref.png
new file mode 100644
index 000000000..e8d84e2b4
--- /dev/null
+++ b/test/reference/surface-pattern-scale-up.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/surface-pattern-scale-up.base.rgb24.ref.png b/test/reference/surface-pattern-scale-up.base.rgb24.ref.png
new file mode 100644
index 000000000..e8d84e2b4
--- /dev/null
+++ b/test/reference/surface-pattern-scale-up.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/surface-pattern-scale-up.image16.ref.png b/test/reference/surface-pattern-scale-up.image16.ref.png
new file mode 100644
index 000000000..5207bd3bc
--- /dev/null
+++ b/test/reference/surface-pattern-scale-up.image16.ref.png
Binary files differ
diff --git a/test/reference/surface-pattern-scale-up.pdf.ref.png b/test/reference/surface-pattern-scale-up.pdf.ref.png
new file mode 100644
index 000000000..593d058aa
--- /dev/null
+++ b/test/reference/surface-pattern-scale-up.pdf.ref.png
Binary files differ
diff --git a/test/reference/surface-pattern-scale-up.ps2.ref.png b/test/reference/surface-pattern-scale-up.ps2.ref.png
new file mode 100644
index 000000000..f2eac7a78
--- /dev/null
+++ b/test/reference/surface-pattern-scale-up.ps2.ref.png
Binary files differ
diff --git a/test/reference/surface-pattern-scale-up.ps3.ref.png b/test/reference/surface-pattern-scale-up.ps3.ref.png
new file mode 100644
index 000000000..f2eac7a78
--- /dev/null
+++ b/test/reference/surface-pattern-scale-up.ps3.ref.png
Binary files differ
diff --git a/test/reference/surface-pattern-scale-up.quartz.xfail.png b/test/reference/surface-pattern-scale-up.quartz.xfail.png
new file mode 100644
index 000000000..ed52ee80a
--- /dev/null
+++ b/test/reference/surface-pattern-scale-up.quartz.xfail.png
Binary files differ
diff --git a/test/reference/surface-pattern-scale-up.ref.png b/test/reference/surface-pattern-scale-up.ref.png
new file mode 100644
index 000000000..e8d84e2b4
--- /dev/null
+++ b/test/reference/surface-pattern-scale-up.ref.png
Binary files differ
diff --git a/test/reference/surface-pattern.base.argb32.ref.png b/test/reference/surface-pattern.base.argb32.ref.png
new file mode 100644
index 000000000..079ebfba1
--- /dev/null
+++ b/test/reference/surface-pattern.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/surface-pattern.base.rgb24.ref.png b/test/reference/surface-pattern.base.rgb24.ref.png
new file mode 100644
index 000000000..079ebfba1
--- /dev/null
+++ b/test/reference/surface-pattern.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/surface-pattern.image16.ref.png b/test/reference/surface-pattern.image16.ref.png
new file mode 100644
index 000000000..909009702
--- /dev/null
+++ b/test/reference/surface-pattern.image16.ref.png
Binary files differ
diff --git a/test/reference/surface-pattern.pdf.xfail.png b/test/reference/surface-pattern.pdf.xfail.png
new file mode 100644
index 000000000..fadc2c240
--- /dev/null
+++ b/test/reference/surface-pattern.pdf.xfail.png
Binary files differ
diff --git a/test/reference/surface-pattern.ps.xfail.png b/test/reference/surface-pattern.ps.xfail.png
new file mode 100644
index 000000000..02fbde847
--- /dev/null
+++ b/test/reference/surface-pattern.ps.xfail.png
Binary files differ
diff --git a/test/reference/surface-pattern.quartz.xfail.png b/test/reference/surface-pattern.quartz.xfail.png
new file mode 100644
index 000000000..4ac47de5e
--- /dev/null
+++ b/test/reference/surface-pattern.quartz.xfail.png
Binary files differ
diff --git a/test/reference/surface-pattern.ref.png b/test/reference/surface-pattern.ref.png
new file mode 100644
index 000000000..079ebfba1
--- /dev/null
+++ b/test/reference/surface-pattern.ref.png
Binary files differ
diff --git a/test/reference/surface-pattern.svg.xfail.png b/test/reference/surface-pattern.svg.xfail.png
new file mode 100644
index 000000000..cdbcf476b
--- /dev/null
+++ b/test/reference/surface-pattern.svg.xfail.png
Binary files differ
diff --git a/test/reference/svg-surface-source.base.argb32.ref.png b/test/reference/svg-surface-source.base.argb32.ref.png
new file mode 100644
index 000000000..018297208
--- /dev/null
+++ b/test/reference/svg-surface-source.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/svg-surface-source.base.rgb24.ref.png b/test/reference/svg-surface-source.base.rgb24.ref.png
new file mode 100644
index 000000000..0d68a82cc
--- /dev/null
+++ b/test/reference/svg-surface-source.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/svg-surface-source.image16.ref.png b/test/reference/svg-surface-source.image16.ref.png
new file mode 100644
index 000000000..2a7460e28
--- /dev/null
+++ b/test/reference/svg-surface-source.image16.ref.png
Binary files differ
diff --git a/test/reference/svg-surface-source.ref.png b/test/reference/svg-surface-source.ref.png
new file mode 100644
index 000000000..018297208
--- /dev/null
+++ b/test/reference/svg-surface-source.ref.png
Binary files differ
diff --git a/test/reference/svg-surface-source.svg12.argb32.xfail.png b/test/reference/svg-surface-source.svg12.argb32.xfail.png
new file mode 100644
index 000000000..6ebcaf9a1
--- /dev/null
+++ b/test/reference/svg-surface-source.svg12.argb32.xfail.png
Binary files differ
diff --git a/test/reference/svg-surface-source.svg12.rgb24.xfail.png b/test/reference/svg-surface-source.svg12.rgb24.xfail.png
new file mode 100644
index 000000000..6ebcaf9a1
--- /dev/null
+++ b/test/reference/svg-surface-source.svg12.rgb24.xfail.png
Binary files differ
diff --git a/test/reference/text-antialias-gray.base.argb32.ref.png b/test/reference/text-antialias-gray.base.argb32.ref.png
new file mode 100644
index 000000000..06b805eaa
--- /dev/null
+++ b/test/reference/text-antialias-gray.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/text-antialias-gray.base.rgb24.ref.png b/test/reference/text-antialias-gray.base.rgb24.ref.png
new file mode 100644
index 000000000..06b805eaa
--- /dev/null
+++ b/test/reference/text-antialias-gray.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/text-antialias-gray.image16.ref.png b/test/reference/text-antialias-gray.image16.ref.png
new file mode 100644
index 000000000..c86dbae5d
--- /dev/null
+++ b/test/reference/text-antialias-gray.image16.ref.png
Binary files differ
diff --git a/test/reference/text-antialias-gray.quartz.ref.png b/test/reference/text-antialias-gray.quartz.ref.png
new file mode 100644
index 000000000..63926a8eb
--- /dev/null
+++ b/test/reference/text-antialias-gray.quartz.ref.png
Binary files differ
diff --git a/test/reference/text-antialias-gray.ref.png b/test/reference/text-antialias-gray.ref.png
new file mode 100644
index 000000000..06b805eaa
--- /dev/null
+++ b/test/reference/text-antialias-gray.ref.png
Binary files differ
diff --git a/test/reference/text-antialias-gray.traps.ref.png b/test/reference/text-antialias-gray.traps.ref.png
new file mode 100644
index 000000000..06b805eaa
--- /dev/null
+++ b/test/reference/text-antialias-gray.traps.ref.png
Binary files differ
diff --git a/test/reference/text-antialias-none.base.argb32.ref.png b/test/reference/text-antialias-none.base.argb32.ref.png
new file mode 100644
index 000000000..86c09cd36
--- /dev/null
+++ b/test/reference/text-antialias-none.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/text-antialias-none.base.rgb24.ref.png b/test/reference/text-antialias-none.base.rgb24.ref.png
new file mode 100644
index 000000000..86c09cd36
--- /dev/null
+++ b/test/reference/text-antialias-none.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/text-antialias-none.quartz.ref.png b/test/reference/text-antialias-none.quartz.ref.png
new file mode 100644
index 000000000..872b21d64
--- /dev/null
+++ b/test/reference/text-antialias-none.quartz.ref.png
Binary files differ
diff --git a/test/reference/text-antialias-none.ref.png b/test/reference/text-antialias-none.ref.png
new file mode 100644
index 000000000..bdd77bd56
--- /dev/null
+++ b/test/reference/text-antialias-none.ref.png
Binary files differ
diff --git a/test/reference/text-antialias-subpixel-bgr.base.argb32.ref.png b/test/reference/text-antialias-subpixel-bgr.base.argb32.ref.png
new file mode 100644
index 000000000..f8d5130af
--- /dev/null
+++ b/test/reference/text-antialias-subpixel-bgr.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/text-antialias-subpixel-bgr.base.rgb24.ref.png b/test/reference/text-antialias-subpixel-bgr.base.rgb24.ref.png
new file mode 100644
index 000000000..f8d5130af
--- /dev/null
+++ b/test/reference/text-antialias-subpixel-bgr.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/text-antialias-subpixel-bgr.image16.ref.png b/test/reference/text-antialias-subpixel-bgr.image16.ref.png
new file mode 100644
index 000000000..5a4e193b7
--- /dev/null
+++ b/test/reference/text-antialias-subpixel-bgr.image16.ref.png
Binary files differ
diff --git a/test/reference/text-antialias-subpixel-bgr.mask.argb32.ref.png b/test/reference/text-antialias-subpixel-bgr.mask.argb32.ref.png
new file mode 100644
index 000000000..f8d5130af
--- /dev/null
+++ b/test/reference/text-antialias-subpixel-bgr.mask.argb32.ref.png
Binary files differ
diff --git a/test/reference/text-antialias-subpixel-bgr.mask.rgb24.ref.png b/test/reference/text-antialias-subpixel-bgr.mask.rgb24.ref.png
new file mode 100644
index 000000000..f8d5130af
--- /dev/null
+++ b/test/reference/text-antialias-subpixel-bgr.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/text-antialias-subpixel-bgr.ref.png b/test/reference/text-antialias-subpixel-bgr.ref.png
new file mode 100644
index 000000000..c36218295
--- /dev/null
+++ b/test/reference/text-antialias-subpixel-bgr.ref.png
Binary files differ
diff --git a/test/reference/text-antialias-subpixel-bgr.traps.ref.png b/test/reference/text-antialias-subpixel-bgr.traps.ref.png
new file mode 100644
index 000000000..a221472df
--- /dev/null
+++ b/test/reference/text-antialias-subpixel-bgr.traps.ref.png
Binary files differ
diff --git a/test/reference/text-antialias-subpixel-rgb.base.argb32.ref.png b/test/reference/text-antialias-subpixel-rgb.base.argb32.ref.png
new file mode 100644
index 000000000..f8d5130af
--- /dev/null
+++ b/test/reference/text-antialias-subpixel-rgb.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/text-antialias-subpixel-rgb.base.rgb24.ref.png b/test/reference/text-antialias-subpixel-rgb.base.rgb24.ref.png
new file mode 100644
index 000000000..f8d5130af
--- /dev/null
+++ b/test/reference/text-antialias-subpixel-rgb.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/text-antialias-subpixel-rgb.image16.ref.png b/test/reference/text-antialias-subpixel-rgb.image16.ref.png
new file mode 100644
index 000000000..cf049b961
--- /dev/null
+++ b/test/reference/text-antialias-subpixel-rgb.image16.ref.png
Binary files differ
diff --git a/test/reference/text-antialias-subpixel-rgb.mask.argb32.ref.png b/test/reference/text-antialias-subpixel-rgb.mask.argb32.ref.png
new file mode 100644
index 000000000..f8d5130af
--- /dev/null
+++ b/test/reference/text-antialias-subpixel-rgb.mask.argb32.ref.png
Binary files differ
diff --git a/test/reference/text-antialias-subpixel-rgb.mask.rgb24.ref.png b/test/reference/text-antialias-subpixel-rgb.mask.rgb24.ref.png
new file mode 100644
index 000000000..f8d5130af
--- /dev/null
+++ b/test/reference/text-antialias-subpixel-rgb.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/text-antialias-subpixel-rgb.ref.png b/test/reference/text-antialias-subpixel-rgb.ref.png
new file mode 100644
index 000000000..0cbf3f1f2
--- /dev/null
+++ b/test/reference/text-antialias-subpixel-rgb.ref.png
Binary files differ
diff --git a/test/reference/text-antialias-subpixel-rgb.traps.ref.png b/test/reference/text-antialias-subpixel-rgb.traps.ref.png
new file mode 100644
index 000000000..af5e0aef5
--- /dev/null
+++ b/test/reference/text-antialias-subpixel-rgb.traps.ref.png
Binary files differ
diff --git a/test/reference/text-antialias-subpixel-vbgr.base.argb32.ref.png b/test/reference/text-antialias-subpixel-vbgr.base.argb32.ref.png
new file mode 100644
index 000000000..9fd35ea2c
--- /dev/null
+++ b/test/reference/text-antialias-subpixel-vbgr.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/text-antialias-subpixel-vbgr.base.rgb24.ref.png b/test/reference/text-antialias-subpixel-vbgr.base.rgb24.ref.png
new file mode 100644
index 000000000..9fd35ea2c
--- /dev/null
+++ b/test/reference/text-antialias-subpixel-vbgr.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/text-antialias-subpixel-vbgr.image16.ref.png b/test/reference/text-antialias-subpixel-vbgr.image16.ref.png
new file mode 100644
index 000000000..6ef721a7d
--- /dev/null
+++ b/test/reference/text-antialias-subpixel-vbgr.image16.ref.png
Binary files differ
diff --git a/test/reference/text-antialias-subpixel-vbgr.mask.argb32.ref.png b/test/reference/text-antialias-subpixel-vbgr.mask.argb32.ref.png
new file mode 100644
index 000000000..9fd35ea2c
--- /dev/null
+++ b/test/reference/text-antialias-subpixel-vbgr.mask.argb32.ref.png
Binary files differ
diff --git a/test/reference/text-antialias-subpixel-vbgr.mask.rgb24.ref.png b/test/reference/text-antialias-subpixel-vbgr.mask.rgb24.ref.png
new file mode 100644
index 000000000..9fd35ea2c
--- /dev/null
+++ b/test/reference/text-antialias-subpixel-vbgr.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/text-antialias-subpixel-vbgr.ref.png b/test/reference/text-antialias-subpixel-vbgr.ref.png
new file mode 100644
index 000000000..7c89df9ea
--- /dev/null
+++ b/test/reference/text-antialias-subpixel-vbgr.ref.png
Binary files differ
diff --git a/test/reference/text-antialias-subpixel-vbgr.traps.ref.png b/test/reference/text-antialias-subpixel-vbgr.traps.ref.png
new file mode 100644
index 000000000..905579b66
--- /dev/null
+++ b/test/reference/text-antialias-subpixel-vbgr.traps.ref.png
Binary files differ
diff --git a/test/reference/text-antialias-subpixel-vrgb.base.argb32.ref.png b/test/reference/text-antialias-subpixel-vrgb.base.argb32.ref.png
new file mode 100644
index 000000000..9fd35ea2c
--- /dev/null
+++ b/test/reference/text-antialias-subpixel-vrgb.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/text-antialias-subpixel-vrgb.base.rgb24.ref.png b/test/reference/text-antialias-subpixel-vrgb.base.rgb24.ref.png
new file mode 100644
index 000000000..9fd35ea2c
--- /dev/null
+++ b/test/reference/text-antialias-subpixel-vrgb.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/text-antialias-subpixel-vrgb.image16.ref.png b/test/reference/text-antialias-subpixel-vrgb.image16.ref.png
new file mode 100644
index 000000000..cb3586b95
--- /dev/null
+++ b/test/reference/text-antialias-subpixel-vrgb.image16.ref.png
Binary files differ
diff --git a/test/reference/text-antialias-subpixel-vrgb.mask.argb32.ref.png b/test/reference/text-antialias-subpixel-vrgb.mask.argb32.ref.png
new file mode 100644
index 000000000..9fd35ea2c
--- /dev/null
+++ b/test/reference/text-antialias-subpixel-vrgb.mask.argb32.ref.png
Binary files differ
diff --git a/test/reference/text-antialias-subpixel-vrgb.mask.rgb24.ref.png b/test/reference/text-antialias-subpixel-vrgb.mask.rgb24.ref.png
new file mode 100644
index 000000000..9fd35ea2c
--- /dev/null
+++ b/test/reference/text-antialias-subpixel-vrgb.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/text-antialias-subpixel-vrgb.ref.png b/test/reference/text-antialias-subpixel-vrgb.ref.png
new file mode 100644
index 000000000..103c7e416
--- /dev/null
+++ b/test/reference/text-antialias-subpixel-vrgb.ref.png
Binary files differ
diff --git a/test/reference/text-antialias-subpixel-vrgb.traps.ref.png b/test/reference/text-antialias-subpixel-vrgb.traps.ref.png
new file mode 100644
index 000000000..f7c5befa9
--- /dev/null
+++ b/test/reference/text-antialias-subpixel-vrgb.traps.ref.png
Binary files differ
diff --git a/test/reference/text-antialias-subpixel.base.argb32.ref.png b/test/reference/text-antialias-subpixel.base.argb32.ref.png
new file mode 100644
index 000000000..f8d5130af
--- /dev/null
+++ b/test/reference/text-antialias-subpixel.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/text-antialias-subpixel.base.argb32.xfail.png b/test/reference/text-antialias-subpixel.base.argb32.xfail.png
new file mode 100644
index 000000000..4a6bde49a
--- /dev/null
+++ b/test/reference/text-antialias-subpixel.base.argb32.xfail.png
Binary files differ
diff --git a/test/reference/text-antialias-subpixel.base.rgb24.ref.png b/test/reference/text-antialias-subpixel.base.rgb24.ref.png
new file mode 100644
index 000000000..f8d5130af
--- /dev/null
+++ b/test/reference/text-antialias-subpixel.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/text-antialias-subpixel.base.rgb24.xfail.png b/test/reference/text-antialias-subpixel.base.rgb24.xfail.png
new file mode 100644
index 000000000..4a6bde49a
--- /dev/null
+++ b/test/reference/text-antialias-subpixel.base.rgb24.xfail.png
Binary files differ
diff --git a/test/reference/text-antialias-subpixel.image16.ref.png b/test/reference/text-antialias-subpixel.image16.ref.png
new file mode 100644
index 000000000..81fad89d0
--- /dev/null
+++ b/test/reference/text-antialias-subpixel.image16.ref.png
Binary files differ
diff --git a/test/reference/text-antialias-subpixel.mask.argb32.ref.png b/test/reference/text-antialias-subpixel.mask.argb32.ref.png
new file mode 100644
index 000000000..f8d5130af
--- /dev/null
+++ b/test/reference/text-antialias-subpixel.mask.argb32.ref.png
Binary files differ
diff --git a/test/reference/text-antialias-subpixel.mask.rgb24.ref.png b/test/reference/text-antialias-subpixel.mask.rgb24.ref.png
new file mode 100644
index 000000000..f8d5130af
--- /dev/null
+++ b/test/reference/text-antialias-subpixel.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/text-antialias-subpixel.quartz.ref.png b/test/reference/text-antialias-subpixel.quartz.ref.png
new file mode 100644
index 000000000..f5b1aa8f0
--- /dev/null
+++ b/test/reference/text-antialias-subpixel.quartz.ref.png
Binary files differ
diff --git a/test/reference/text-antialias-subpixel.ref.png b/test/reference/text-antialias-subpixel.ref.png
new file mode 100644
index 000000000..0cbf3f1f2
--- /dev/null
+++ b/test/reference/text-antialias-subpixel.ref.png
Binary files differ
diff --git a/test/reference/text-antialias-subpixel.traps.ref.png b/test/reference/text-antialias-subpixel.traps.ref.png
new file mode 100644
index 000000000..af5e0aef5
--- /dev/null
+++ b/test/reference/text-antialias-subpixel.traps.ref.png
Binary files differ
diff --git a/test/reference/text-glyph-range.base.argb32.ref.png b/test/reference/text-glyph-range.base.argb32.ref.png
new file mode 100644
index 000000000..326869923
--- /dev/null
+++ b/test/reference/text-glyph-range.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/text-glyph-range.base.rgb24.ref.png b/test/reference/text-glyph-range.base.rgb24.ref.png
new file mode 100644
index 000000000..326869923
--- /dev/null
+++ b/test/reference/text-glyph-range.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/text-glyph-range.image16.ref.png b/test/reference/text-glyph-range.image16.ref.png
new file mode 100644
index 000000000..51daa1688
--- /dev/null
+++ b/test/reference/text-glyph-range.image16.ref.png
Binary files differ
diff --git a/test/reference/text-glyph-range.ps.ref.png b/test/reference/text-glyph-range.ps.ref.png
new file mode 100644
index 000000000..96bc85a34
--- /dev/null
+++ b/test/reference/text-glyph-range.ps.ref.png
Binary files differ
diff --git a/test/reference/text-glyph-range.quartz.ref.png b/test/reference/text-glyph-range.quartz.ref.png
new file mode 100644
index 000000000..e4a14b2aa
--- /dev/null
+++ b/test/reference/text-glyph-range.quartz.ref.png
Binary files differ
diff --git a/test/reference/text-glyph-range.ref.png b/test/reference/text-glyph-range.ref.png
new file mode 100644
index 000000000..648fef5b7
--- /dev/null
+++ b/test/reference/text-glyph-range.ref.png
Binary files differ
diff --git a/test/reference/text-glyph-range.traps.ref.png b/test/reference/text-glyph-range.traps.ref.png
new file mode 100644
index 000000000..326869923
--- /dev/null
+++ b/test/reference/text-glyph-range.traps.ref.png
Binary files differ
diff --git a/test/reference/text-pattern.base.argb32.ref.png b/test/reference/text-pattern.base.argb32.ref.png
new file mode 100644
index 000000000..79f18e4e1
--- /dev/null
+++ b/test/reference/text-pattern.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/text-pattern.base.rgb24.ref.png b/test/reference/text-pattern.base.rgb24.ref.png
new file mode 100644
index 000000000..b073b9831
--- /dev/null
+++ b/test/reference/text-pattern.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/text-pattern.pdf.argb32.ref.png b/test/reference/text-pattern.pdf.argb32.ref.png
new file mode 100644
index 000000000..5eef739dc
--- /dev/null
+++ b/test/reference/text-pattern.pdf.argb32.ref.png
Binary files differ
diff --git a/test/reference/text-pattern.pdf.rgb24.ref.png b/test/reference/text-pattern.pdf.rgb24.ref.png
new file mode 100644
index 000000000..27a1195e8
--- /dev/null
+++ b/test/reference/text-pattern.pdf.rgb24.ref.png
Binary files differ
diff --git a/test/reference/text-pattern.ps2.argb32.ref.png b/test/reference/text-pattern.ps2.argb32.ref.png
new file mode 100644
index 000000000..bdea146f2
--- /dev/null
+++ b/test/reference/text-pattern.ps2.argb32.ref.png
Binary files differ
diff --git a/test/reference/text-pattern.ps2.rgb24.ref.png b/test/reference/text-pattern.ps2.rgb24.ref.png
new file mode 100644
index 000000000..bdea146f2
--- /dev/null
+++ b/test/reference/text-pattern.ps2.rgb24.ref.png
Binary files differ
diff --git a/test/reference/text-pattern.ps3.argb32.ref.png b/test/reference/text-pattern.ps3.argb32.ref.png
new file mode 100644
index 000000000..411a531b2
--- /dev/null
+++ b/test/reference/text-pattern.ps3.argb32.ref.png
Binary files differ
diff --git a/test/reference/text-pattern.ps3.rgb24.ref.png b/test/reference/text-pattern.ps3.rgb24.ref.png
new file mode 100644
index 000000000..f696a9926
--- /dev/null
+++ b/test/reference/text-pattern.ps3.rgb24.ref.png
Binary files differ
diff --git a/test/reference/text-pattern.quartz.argb32.ref.png b/test/reference/text-pattern.quartz.argb32.ref.png
new file mode 100644
index 000000000..1a15964e5
--- /dev/null
+++ b/test/reference/text-pattern.quartz.argb32.ref.png
Binary files differ
diff --git a/test/reference/text-pattern.quartz.rgb24.ref.png b/test/reference/text-pattern.quartz.rgb24.ref.png
new file mode 100644
index 000000000..f19dd767d
--- /dev/null
+++ b/test/reference/text-pattern.quartz.rgb24.ref.png
Binary files differ
diff --git a/test/reference/text-pattern.ref.png b/test/reference/text-pattern.ref.png
new file mode 100644
index 000000000..95410fa2b
--- /dev/null
+++ b/test/reference/text-pattern.ref.png
Binary files differ
diff --git a/test/reference/text-pattern.svg.argb32.ref.png b/test/reference/text-pattern.svg.argb32.ref.png
new file mode 100644
index 000000000..f472858f9
--- /dev/null
+++ b/test/reference/text-pattern.svg.argb32.ref.png
Binary files differ
diff --git a/test/reference/text-pattern.svg.rgb24.ref.png b/test/reference/text-pattern.svg.rgb24.ref.png
new file mode 100644
index 000000000..2b2064ece
--- /dev/null
+++ b/test/reference/text-pattern.svg.rgb24.ref.png
Binary files differ
diff --git a/test/reference/text-pattern.traps.argb32.ref.png b/test/reference/text-pattern.traps.argb32.ref.png
new file mode 100644
index 000000000..79f18e4e1
--- /dev/null
+++ b/test/reference/text-pattern.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/text-pattern.traps.rgb24.ref.png b/test/reference/text-pattern.traps.rgb24.ref.png
new file mode 100644
index 000000000..b073b9831
--- /dev/null
+++ b/test/reference/text-pattern.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/text-rotate.base.argb32.ref.png b/test/reference/text-rotate.base.argb32.ref.png
new file mode 100644
index 000000000..ff3fe847c
--- /dev/null
+++ b/test/reference/text-rotate.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/text-rotate.base.rgb24.ref.png b/test/reference/text-rotate.base.rgb24.ref.png
new file mode 100644
index 000000000..ff3fe847c
--- /dev/null
+++ b/test/reference/text-rotate.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/text-rotate.image16.ref.png b/test/reference/text-rotate.image16.ref.png
new file mode 100644
index 000000000..fddd002c9
--- /dev/null
+++ b/test/reference/text-rotate.image16.ref.png
Binary files differ
diff --git a/test/reference/text-rotate.mask.argb32.ref.png b/test/reference/text-rotate.mask.argb32.ref.png
new file mode 100644
index 000000000..b455aab63
--- /dev/null
+++ b/test/reference/text-rotate.mask.argb32.ref.png
Binary files differ
diff --git a/test/reference/text-rotate.mask.rgb24.ref.png b/test/reference/text-rotate.mask.rgb24.ref.png
new file mode 100644
index 000000000..b455aab63
--- /dev/null
+++ b/test/reference/text-rotate.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/text-rotate.pdf.ref.png b/test/reference/text-rotate.pdf.ref.png
new file mode 100644
index 000000000..b533075c4
--- /dev/null
+++ b/test/reference/text-rotate.pdf.ref.png
Binary files differ
diff --git a/test/reference/text-rotate.ps.ref.png b/test/reference/text-rotate.ps.ref.png
new file mode 100644
index 000000000..c68d02dae
--- /dev/null
+++ b/test/reference/text-rotate.ps.ref.png
Binary files differ
diff --git a/test/reference/text-rotate.quartz.ref.png b/test/reference/text-rotate.quartz.ref.png
new file mode 100644
index 000000000..113e727af
--- /dev/null
+++ b/test/reference/text-rotate.quartz.ref.png
Binary files differ
diff --git a/test/reference/text-rotate.ref.png b/test/reference/text-rotate.ref.png
new file mode 100644
index 000000000..432de3123
--- /dev/null
+++ b/test/reference/text-rotate.ref.png
Binary files differ
diff --git a/test/reference/text-rotate.svg.ref.png b/test/reference/text-rotate.svg.ref.png
new file mode 100644
index 000000000..9d887a02f
--- /dev/null
+++ b/test/reference/text-rotate.svg.ref.png
Binary files differ
diff --git a/test/reference/text-rotate.traps.ref.png b/test/reference/text-rotate.traps.ref.png
new file mode 100644
index 000000000..ff3fe847c
--- /dev/null
+++ b/test/reference/text-rotate.traps.ref.png
Binary files differ
diff --git a/test/reference/text-rotate.xlib-fallback.ref.png b/test/reference/text-rotate.xlib-fallback.ref.png
new file mode 100644
index 000000000..ce063303a
--- /dev/null
+++ b/test/reference/text-rotate.xlib-fallback.ref.png
Binary files differ
diff --git a/test/reference/text-transform.base.argb32.ref.png b/test/reference/text-transform.base.argb32.ref.png
new file mode 100644
index 000000000..4603bc528
--- /dev/null
+++ b/test/reference/text-transform.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/text-transform.base.rgb24.ref.png b/test/reference/text-transform.base.rgb24.ref.png
new file mode 100644
index 000000000..4603bc528
--- /dev/null
+++ b/test/reference/text-transform.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/text-transform.image16.ref.png b/test/reference/text-transform.image16.ref.png
new file mode 100644
index 000000000..59caca800
--- /dev/null
+++ b/test/reference/text-transform.image16.ref.png
Binary files differ
diff --git a/test/reference/text-transform.pdf.argb32.ref.png b/test/reference/text-transform.pdf.argb32.ref.png
new file mode 100644
index 000000000..7a2f3a72a
--- /dev/null
+++ b/test/reference/text-transform.pdf.argb32.ref.png
Binary files differ
diff --git a/test/reference/text-transform.pdf.rgb24.ref.png b/test/reference/text-transform.pdf.rgb24.ref.png
new file mode 100644
index 000000000..7a2f3a72a
--- /dev/null
+++ b/test/reference/text-transform.pdf.rgb24.ref.png
Binary files differ
diff --git a/test/reference/text-transform.ps2.ref.png b/test/reference/text-transform.ps2.ref.png
new file mode 100644
index 000000000..07896b302
--- /dev/null
+++ b/test/reference/text-transform.ps2.ref.png
Binary files differ
diff --git a/test/reference/text-transform.ps3.ref.png b/test/reference/text-transform.ps3.ref.png
new file mode 100644
index 000000000..07896b302
--- /dev/null
+++ b/test/reference/text-transform.ps3.ref.png
Binary files differ
diff --git a/test/reference/text-transform.ref.png b/test/reference/text-transform.ref.png
new file mode 100644
index 000000000..6f36b9d41
--- /dev/null
+++ b/test/reference/text-transform.ref.png
Binary files differ
diff --git a/test/reference/text-transform.svg.ref.png b/test/reference/text-transform.svg.ref.png
new file mode 100644
index 000000000..1473a643a
--- /dev/null
+++ b/test/reference/text-transform.svg.ref.png
Binary files differ
diff --git a/test/reference/tiger.base.argb32.ref.png b/test/reference/tiger.base.argb32.ref.png
new file mode 100644
index 000000000..bc7f668e4
--- /dev/null
+++ b/test/reference/tiger.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/tiger.base.rgb24.ref.png b/test/reference/tiger.base.rgb24.ref.png
new file mode 100644
index 000000000..bc7f668e4
--- /dev/null
+++ b/test/reference/tiger.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/tiger.ref.png b/test/reference/tiger.ref.png
new file mode 100644
index 000000000..b8b21758b
--- /dev/null
+++ b/test/reference/tiger.ref.png
Binary files differ
diff --git a/test/reference/tiger.traps.argb32.ref.png b/test/reference/tiger.traps.argb32.ref.png
new file mode 100644
index 000000000..bc7f668e4
--- /dev/null
+++ b/test/reference/tiger.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/tiger.traps.rgb24.ref.png b/test/reference/tiger.traps.rgb24.ref.png
new file mode 100644
index 000000000..bc7f668e4
--- /dev/null
+++ b/test/reference/tiger.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/tighten-bounds.argb32.ref.png b/test/reference/tighten-bounds.argb32.ref.png
new file mode 100644
index 000000000..042038c6f
--- /dev/null
+++ b/test/reference/tighten-bounds.argb32.ref.png
Binary files differ
diff --git a/test/reference/tighten-bounds.base.argb32.ref.png b/test/reference/tighten-bounds.base.argb32.ref.png
new file mode 100644
index 000000000..dad3a7fc9
--- /dev/null
+++ b/test/reference/tighten-bounds.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/tighten-bounds.base.rgb24.ref.png b/test/reference/tighten-bounds.base.rgb24.ref.png
new file mode 100644
index 000000000..9d3a25262
--- /dev/null
+++ b/test/reference/tighten-bounds.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/tighten-bounds.rgb24.ref.png b/test/reference/tighten-bounds.rgb24.ref.png
new file mode 100644
index 000000000..28158816b
--- /dev/null
+++ b/test/reference/tighten-bounds.rgb24.ref.png
Binary files differ
diff --git a/test/reference/tighten-bounds.traps.argb32.ref.png b/test/reference/tighten-bounds.traps.argb32.ref.png
new file mode 100644
index 000000000..291a84114
--- /dev/null
+++ b/test/reference/tighten-bounds.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/tighten-bounds.traps.rgb24.ref.png b/test/reference/tighten-bounds.traps.rgb24.ref.png
new file mode 100644
index 000000000..f31c17c3d
--- /dev/null
+++ b/test/reference/tighten-bounds.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/transforms.base.argb32.ref.png b/test/reference/transforms.base.argb32.ref.png
new file mode 100644
index 000000000..3ce917649
--- /dev/null
+++ b/test/reference/transforms.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/transforms.base.rgb24.ref.png b/test/reference/transforms.base.rgb24.ref.png
new file mode 100644
index 000000000..3ce917649
--- /dev/null
+++ b/test/reference/transforms.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/transforms.image16.ref.png b/test/reference/transforms.image16.ref.png
new file mode 100644
index 000000000..e9a1813a0
--- /dev/null
+++ b/test/reference/transforms.image16.ref.png
Binary files differ
diff --git a/test/reference/transforms.ps2.ref.png b/test/reference/transforms.ps2.ref.png
new file mode 100644
index 000000000..6d195aaf3
--- /dev/null
+++ b/test/reference/transforms.ps2.ref.png
Binary files differ
diff --git a/test/reference/transforms.ps3.ref.png b/test/reference/transforms.ps3.ref.png
new file mode 100644
index 000000000..6d195aaf3
--- /dev/null
+++ b/test/reference/transforms.ps3.ref.png
Binary files differ
diff --git a/test/reference/transforms.ref.png b/test/reference/transforms.ref.png
new file mode 100644
index 000000000..390bad482
--- /dev/null
+++ b/test/reference/transforms.ref.png
Binary files differ
diff --git a/test/reference/transforms.traps.argb32.ref.png b/test/reference/transforms.traps.argb32.ref.png
new file mode 100644
index 000000000..3ce917649
--- /dev/null
+++ b/test/reference/transforms.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/transforms.traps.rgb24.ref.png b/test/reference/transforms.traps.rgb24.ref.png
new file mode 100644
index 000000000..3ce917649
--- /dev/null
+++ b/test/reference/transforms.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/translate-show-surface.base.argb32.ref.png b/test/reference/translate-show-surface.base.argb32.ref.png
new file mode 100644
index 000000000..0a145d918
--- /dev/null
+++ b/test/reference/translate-show-surface.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/translate-show-surface.base.rgb24.ref.png b/test/reference/translate-show-surface.base.rgb24.ref.png
new file mode 100644
index 000000000..0a145d918
--- /dev/null
+++ b/test/reference/translate-show-surface.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/translate-show-surface.ref.png b/test/reference/translate-show-surface.ref.png
new file mode 100644
index 000000000..765adc4a4
--- /dev/null
+++ b/test/reference/translate-show-surface.ref.png
Binary files differ
diff --git a/test/reference/trap-clip.argb32.ref.png b/test/reference/trap-clip.argb32.ref.png
new file mode 100644
index 000000000..08e6c68a5
--- /dev/null
+++ b/test/reference/trap-clip.argb32.ref.png
Binary files differ
diff --git a/test/reference/trap-clip.base.argb32.ref.png b/test/reference/trap-clip.base.argb32.ref.png
new file mode 100644
index 000000000..285934bc3
--- /dev/null
+++ b/test/reference/trap-clip.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/trap-clip.base.rgb24.ref.png b/test/reference/trap-clip.base.rgb24.ref.png
new file mode 100644
index 000000000..ed89be754
--- /dev/null
+++ b/test/reference/trap-clip.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/trap-clip.image16.ref.png b/test/reference/trap-clip.image16.ref.png
new file mode 100644
index 000000000..e9ef2cf90
--- /dev/null
+++ b/test/reference/trap-clip.image16.ref.png
Binary files differ
diff --git a/test/reference/trap-clip.mask.argb32.ref.png b/test/reference/trap-clip.mask.argb32.ref.png
new file mode 100644
index 000000000..98cd0a244
--- /dev/null
+++ b/test/reference/trap-clip.mask.argb32.ref.png
Binary files differ
diff --git a/test/reference/trap-clip.mask.rgb24.ref.png b/test/reference/trap-clip.mask.rgb24.ref.png
new file mode 100644
index 000000000..c01315331
--- /dev/null
+++ b/test/reference/trap-clip.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/trap-clip.ps2.argb32.ref.png b/test/reference/trap-clip.ps2.argb32.ref.png
new file mode 100644
index 000000000..4db9f8e70
--- /dev/null
+++ b/test/reference/trap-clip.ps2.argb32.ref.png
Binary files differ
diff --git a/test/reference/trap-clip.ps2.rgb24.ref.png b/test/reference/trap-clip.ps2.rgb24.ref.png
new file mode 100644
index 000000000..de309b975
--- /dev/null
+++ b/test/reference/trap-clip.ps2.rgb24.ref.png
Binary files differ
diff --git a/test/reference/trap-clip.ps3.argb32.ref.png b/test/reference/trap-clip.ps3.argb32.ref.png
new file mode 100644
index 000000000..17d74beb3
--- /dev/null
+++ b/test/reference/trap-clip.ps3.argb32.ref.png
Binary files differ
diff --git a/test/reference/trap-clip.ps3.rgb24.ref.png b/test/reference/trap-clip.ps3.rgb24.ref.png
new file mode 100644
index 000000000..236b75c5b
--- /dev/null
+++ b/test/reference/trap-clip.ps3.rgb24.ref.png
Binary files differ
diff --git a/test/reference/trap-clip.quartz.argb32.ref.png b/test/reference/trap-clip.quartz.argb32.ref.png
new file mode 100644
index 000000000..e045ea4ed
--- /dev/null
+++ b/test/reference/trap-clip.quartz.argb32.ref.png
Binary files differ
diff --git a/test/reference/trap-clip.quartz.rgb24.ref.png b/test/reference/trap-clip.quartz.rgb24.ref.png
new file mode 100644
index 000000000..1044d8699
--- /dev/null
+++ b/test/reference/trap-clip.quartz.rgb24.ref.png
Binary files differ
diff --git a/test/reference/trap-clip.rgb24.ref.png b/test/reference/trap-clip.rgb24.ref.png
new file mode 100644
index 000000000..9c51d62eb
--- /dev/null
+++ b/test/reference/trap-clip.rgb24.ref.png
Binary files differ
diff --git a/test/reference/trap-clip.test-paginated.argb32.ref.png b/test/reference/trap-clip.test-paginated.argb32.ref.png
new file mode 100644
index 000000000..7259edc49
--- /dev/null
+++ b/test/reference/trap-clip.test-paginated.argb32.ref.png
Binary files differ
diff --git a/test/reference/trap-clip.traps.argb32.ref.png b/test/reference/trap-clip.traps.argb32.ref.png
new file mode 100644
index 000000000..170d3781f
--- /dev/null
+++ b/test/reference/trap-clip.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/trap-clip.traps.rgb24.ref.png b/test/reference/trap-clip.traps.rgb24.ref.png
new file mode 100644
index 000000000..b1129b033
--- /dev/null
+++ b/test/reference/trap-clip.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/twin-antialias-gray.base.argb32.ref.png b/test/reference/twin-antialias-gray.base.argb32.ref.png
new file mode 100644
index 000000000..0692dea28
--- /dev/null
+++ b/test/reference/twin-antialias-gray.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/twin-antialias-gray.base.rgb24.ref.png b/test/reference/twin-antialias-gray.base.rgb24.ref.png
new file mode 100644
index 000000000..0692dea28
--- /dev/null
+++ b/test/reference/twin-antialias-gray.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/twin-antialias-gray.image16.ref.png b/test/reference/twin-antialias-gray.image16.ref.png
new file mode 100644
index 000000000..1fadcb125
--- /dev/null
+++ b/test/reference/twin-antialias-gray.image16.ref.png
Binary files differ
diff --git a/test/reference/twin-antialias-gray.mask.argb32.ref.png b/test/reference/twin-antialias-gray.mask.argb32.ref.png
new file mode 100644
index 000000000..6b091afd8
--- /dev/null
+++ b/test/reference/twin-antialias-gray.mask.argb32.ref.png
Binary files differ
diff --git a/test/reference/twin-antialias-gray.mask.rgb24.ref.png b/test/reference/twin-antialias-gray.mask.rgb24.ref.png
new file mode 100644
index 000000000..6b091afd8
--- /dev/null
+++ b/test/reference/twin-antialias-gray.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/twin-antialias-gray.ref.png b/test/reference/twin-antialias-gray.ref.png
new file mode 100644
index 000000000..602e00524
--- /dev/null
+++ b/test/reference/twin-antialias-gray.ref.png
Binary files differ
diff --git a/test/reference/twin-antialias-gray.traps.argb32.ref.png b/test/reference/twin-antialias-gray.traps.argb32.ref.png
new file mode 100644
index 000000000..0692dea28
--- /dev/null
+++ b/test/reference/twin-antialias-gray.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/twin-antialias-gray.traps.rgb24.ref.png b/test/reference/twin-antialias-gray.traps.rgb24.ref.png
new file mode 100644
index 000000000..0692dea28
--- /dev/null
+++ b/test/reference/twin-antialias-gray.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/twin-antialias-mixed.base.argb32.ref.png b/test/reference/twin-antialias-mixed.base.argb32.ref.png
new file mode 100644
index 000000000..ba8180e11
--- /dev/null
+++ b/test/reference/twin-antialias-mixed.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/twin-antialias-mixed.base.rgb24.ref.png b/test/reference/twin-antialias-mixed.base.rgb24.ref.png
new file mode 100644
index 000000000..ba8180e11
--- /dev/null
+++ b/test/reference/twin-antialias-mixed.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/twin-antialias-mixed.image16.ref.png b/test/reference/twin-antialias-mixed.image16.ref.png
new file mode 100644
index 000000000..10c4980fc
--- /dev/null
+++ b/test/reference/twin-antialias-mixed.image16.ref.png
Binary files differ
diff --git a/test/reference/twin-antialias-mixed.ref.png b/test/reference/twin-antialias-mixed.ref.png
new file mode 100644
index 000000000..28e85a3e6
--- /dev/null
+++ b/test/reference/twin-antialias-mixed.ref.png
Binary files differ
diff --git a/test/reference/twin-antialias-mixed.traps.argb32.ref.png b/test/reference/twin-antialias-mixed.traps.argb32.ref.png
new file mode 100644
index 000000000..ba8180e11
--- /dev/null
+++ b/test/reference/twin-antialias-mixed.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/twin-antialias-mixed.traps.rgb24.ref.png b/test/reference/twin-antialias-mixed.traps.rgb24.ref.png
new file mode 100644
index 000000000..ba8180e11
--- /dev/null
+++ b/test/reference/twin-antialias-mixed.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/twin-antialias-none.base.argb32.ref.png b/test/reference/twin-antialias-none.base.argb32.ref.png
new file mode 100644
index 000000000..02cf333d7
--- /dev/null
+++ b/test/reference/twin-antialias-none.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/twin-antialias-none.base.rgb24.ref.png b/test/reference/twin-antialias-none.base.rgb24.ref.png
new file mode 100644
index 000000000..02cf333d7
--- /dev/null
+++ b/test/reference/twin-antialias-none.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/twin-antialias-none.ref.png b/test/reference/twin-antialias-none.ref.png
new file mode 100644
index 000000000..28ad3036d
--- /dev/null
+++ b/test/reference/twin-antialias-none.ref.png
Binary files differ
diff --git a/test/reference/twin-antialias-none.traps.argb32.ref.png b/test/reference/twin-antialias-none.traps.argb32.ref.png
new file mode 100644
index 000000000..02cf333d7
--- /dev/null
+++ b/test/reference/twin-antialias-none.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/twin-antialias-none.traps.rgb24.ref.png b/test/reference/twin-antialias-none.traps.rgb24.ref.png
new file mode 100644
index 000000000..02cf333d7
--- /dev/null
+++ b/test/reference/twin-antialias-none.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/twin-antialias-subpixel.base.argb32.ref.png b/test/reference/twin-antialias-subpixel.base.argb32.ref.png
new file mode 100644
index 000000000..0692dea28
--- /dev/null
+++ b/test/reference/twin-antialias-subpixel.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/twin-antialias-subpixel.base.rgb24.ref.png b/test/reference/twin-antialias-subpixel.base.rgb24.ref.png
new file mode 100644
index 000000000..0692dea28
--- /dev/null
+++ b/test/reference/twin-antialias-subpixel.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/twin-antialias-subpixel.image16.ref.png b/test/reference/twin-antialias-subpixel.image16.ref.png
new file mode 100644
index 000000000..1fadcb125
--- /dev/null
+++ b/test/reference/twin-antialias-subpixel.image16.ref.png
Binary files differ
diff --git a/test/reference/twin-antialias-subpixel.mask.argb32.ref.png b/test/reference/twin-antialias-subpixel.mask.argb32.ref.png
new file mode 100644
index 000000000..6b091afd8
--- /dev/null
+++ b/test/reference/twin-antialias-subpixel.mask.argb32.ref.png
Binary files differ
diff --git a/test/reference/twin-antialias-subpixel.mask.rgb24.ref.png b/test/reference/twin-antialias-subpixel.mask.rgb24.ref.png
new file mode 100644
index 000000000..6b091afd8
--- /dev/null
+++ b/test/reference/twin-antialias-subpixel.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/twin-antialias-subpixel.ref.png b/test/reference/twin-antialias-subpixel.ref.png
new file mode 100644
index 000000000..602e00524
--- /dev/null
+++ b/test/reference/twin-antialias-subpixel.ref.png
Binary files differ
diff --git a/test/reference/twin-antialias-subpixel.traps.argb32.ref.png b/test/reference/twin-antialias-subpixel.traps.argb32.ref.png
new file mode 100644
index 000000000..0692dea28
--- /dev/null
+++ b/test/reference/twin-antialias-subpixel.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/twin-antialias-subpixel.traps.rgb24.ref.png b/test/reference/twin-antialias-subpixel.traps.rgb24.ref.png
new file mode 100644
index 000000000..0692dea28
--- /dev/null
+++ b/test/reference/twin-antialias-subpixel.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/twin.base.argb32.ref.png b/test/reference/twin.base.argb32.ref.png
new file mode 100644
index 000000000..0692dea28
--- /dev/null
+++ b/test/reference/twin.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/twin.base.rgb24.ref.png b/test/reference/twin.base.rgb24.ref.png
new file mode 100644
index 000000000..0692dea28
--- /dev/null
+++ b/test/reference/twin.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/twin.image16.ref.png b/test/reference/twin.image16.ref.png
new file mode 100644
index 000000000..1fadcb125
--- /dev/null
+++ b/test/reference/twin.image16.ref.png
Binary files differ
diff --git a/test/reference/twin.mask.argb32.ref.png b/test/reference/twin.mask.argb32.ref.png
new file mode 100644
index 000000000..6b091afd8
--- /dev/null
+++ b/test/reference/twin.mask.argb32.ref.png
Binary files differ
diff --git a/test/reference/twin.mask.rgb24.ref.png b/test/reference/twin.mask.rgb24.ref.png
new file mode 100644
index 000000000..6b091afd8
--- /dev/null
+++ b/test/reference/twin.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/twin.ps.ref.png b/test/reference/twin.ps.ref.png
new file mode 100644
index 000000000..25c71b440
--- /dev/null
+++ b/test/reference/twin.ps.ref.png
Binary files differ
diff --git a/test/reference/twin.ref.png b/test/reference/twin.ref.png
new file mode 100644
index 000000000..602e00524
--- /dev/null
+++ b/test/reference/twin.ref.png
Binary files differ
diff --git a/test/reference/twin.svg.ref.png b/test/reference/twin.svg.ref.png
new file mode 100644
index 000000000..628a83c76
--- /dev/null
+++ b/test/reference/twin.svg.ref.png
Binary files differ
diff --git a/test/reference/twin.traps.argb32.ref.png b/test/reference/twin.traps.argb32.ref.png
new file mode 100644
index 000000000..0692dea28
--- /dev/null
+++ b/test/reference/twin.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/twin.traps.rgb24.ref.png b/test/reference/twin.traps.rgb24.ref.png
new file mode 100644
index 000000000..0692dea28
--- /dev/null
+++ b/test/reference/twin.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/unaligned-box.base.argb32.ref.png b/test/reference/unaligned-box.base.argb32.ref.png
new file mode 100644
index 000000000..48e23b8f8
--- /dev/null
+++ b/test/reference/unaligned-box.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/unaligned-box.base.rgb24.ref.png b/test/reference/unaligned-box.base.rgb24.ref.png
new file mode 100644
index 000000000..48e23b8f8
--- /dev/null
+++ b/test/reference/unaligned-box.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/unaligned-box.ref.png b/test/reference/unaligned-box.ref.png
new file mode 100644
index 000000000..ec7c48996
--- /dev/null
+++ b/test/reference/unaligned-box.ref.png
Binary files differ
diff --git a/test/reference/unaligned-box.traps.argb32.ref.png b/test/reference/unaligned-box.traps.argb32.ref.png
new file mode 100644
index 000000000..48e23b8f8
--- /dev/null
+++ b/test/reference/unaligned-box.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/unaligned-box.traps.rgb24.ref.png b/test/reference/unaligned-box.traps.rgb24.ref.png
new file mode 100644
index 000000000..48e23b8f8
--- /dev/null
+++ b/test/reference/unaligned-box.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/unantialiased-shapes.base.argb32.ref.png b/test/reference/unantialiased-shapes.base.argb32.ref.png
new file mode 100644
index 000000000..a55ba889b
--- /dev/null
+++ b/test/reference/unantialiased-shapes.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/unantialiased-shapes.base.rgb24.ref.png b/test/reference/unantialiased-shapes.base.rgb24.ref.png
new file mode 100644
index 000000000..a55ba889b
--- /dev/null
+++ b/test/reference/unantialiased-shapes.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/unantialiased-shapes.quartz.ref.png b/test/reference/unantialiased-shapes.quartz.ref.png
new file mode 100644
index 000000000..349ece778
--- /dev/null
+++ b/test/reference/unantialiased-shapes.quartz.ref.png
Binary files differ
diff --git a/test/reference/unantialiased-shapes.ref.png b/test/reference/unantialiased-shapes.ref.png
new file mode 100644
index 000000000..d9f466e52
--- /dev/null
+++ b/test/reference/unantialiased-shapes.ref.png
Binary files differ
diff --git a/test/reference/unantialiased-shapes.traps.argb32.ref.png b/test/reference/unantialiased-shapes.traps.argb32.ref.png
new file mode 100644
index 000000000..cb2ce3d95
--- /dev/null
+++ b/test/reference/unantialiased-shapes.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/unantialiased-shapes.traps.rgb24.ref.png b/test/reference/unantialiased-shapes.traps.rgb24.ref.png
new file mode 100644
index 000000000..cb2ce3d95
--- /dev/null
+++ b/test/reference/unantialiased-shapes.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/unbounded-operator.argb32.ref.png b/test/reference/unbounded-operator.argb32.ref.png
new file mode 100644
index 000000000..0b4338865
--- /dev/null
+++ b/test/reference/unbounded-operator.argb32.ref.png
Binary files differ
diff --git a/test/reference/unbounded-operator.base.argb32.ref.png b/test/reference/unbounded-operator.base.argb32.ref.png
new file mode 100644
index 000000000..fe86a948e
--- /dev/null
+++ b/test/reference/unbounded-operator.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/unbounded-operator.base.rgb24.ref.png b/test/reference/unbounded-operator.base.rgb24.ref.png
new file mode 100644
index 000000000..c8555af14
--- /dev/null
+++ b/test/reference/unbounded-operator.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/unbounded-operator.gl.argb32.xfail.png b/test/reference/unbounded-operator.gl.argb32.xfail.png
new file mode 100644
index 000000000..34e32eba1
--- /dev/null
+++ b/test/reference/unbounded-operator.gl.argb32.xfail.png
Binary files differ
diff --git a/test/reference/unbounded-operator.gl.rgb24.xfail.png b/test/reference/unbounded-operator.gl.rgb24.xfail.png
new file mode 100644
index 000000000..b91da8f08
--- /dev/null
+++ b/test/reference/unbounded-operator.gl.rgb24.xfail.png
Binary files differ
diff --git a/test/reference/unbounded-operator.image16.ref.png b/test/reference/unbounded-operator.image16.ref.png
new file mode 100644
index 000000000..17dfb46df
--- /dev/null
+++ b/test/reference/unbounded-operator.image16.ref.png
Binary files differ
diff --git a/test/reference/unbounded-operator.mask.argb32.ref.png b/test/reference/unbounded-operator.mask.argb32.ref.png
new file mode 100644
index 000000000..08f43561b
--- /dev/null
+++ b/test/reference/unbounded-operator.mask.argb32.ref.png
Binary files differ
diff --git a/test/reference/unbounded-operator.mask.rgb24.ref.png b/test/reference/unbounded-operator.mask.rgb24.ref.png
new file mode 100644
index 000000000..80d20dc57
--- /dev/null
+++ b/test/reference/unbounded-operator.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/unbounded-operator.pdf.argb32.ref.png b/test/reference/unbounded-operator.pdf.argb32.ref.png
new file mode 100644
index 000000000..4aa476de4
--- /dev/null
+++ b/test/reference/unbounded-operator.pdf.argb32.ref.png
Binary files differ
diff --git a/test/reference/unbounded-operator.ps2.argb32.ref.png b/test/reference/unbounded-operator.ps2.argb32.ref.png
new file mode 100644
index 000000000..4aa476de4
--- /dev/null
+++ b/test/reference/unbounded-operator.ps2.argb32.ref.png
Binary files differ
diff --git a/test/reference/unbounded-operator.ps3.argb32.ref.png b/test/reference/unbounded-operator.ps3.argb32.ref.png
new file mode 100644
index 000000000..4aa476de4
--- /dev/null
+++ b/test/reference/unbounded-operator.ps3.argb32.ref.png
Binary files differ
diff --git a/test/reference/unbounded-operator.quartz.argb32.ref.png b/test/reference/unbounded-operator.quartz.argb32.ref.png
new file mode 100644
index 000000000..b2e99165e
--- /dev/null
+++ b/test/reference/unbounded-operator.quartz.argb32.ref.png
Binary files differ
diff --git a/test/reference/unbounded-operator.quartz.rgb24.ref.png b/test/reference/unbounded-operator.quartz.rgb24.ref.png
new file mode 100644
index 000000000..ea41dc892
--- /dev/null
+++ b/test/reference/unbounded-operator.quartz.rgb24.ref.png
Binary files differ
diff --git a/test/reference/unbounded-operator.rgb24.ref.png b/test/reference/unbounded-operator.rgb24.ref.png
new file mode 100644
index 000000000..c9b5b3456
--- /dev/null
+++ b/test/reference/unbounded-operator.rgb24.ref.png
Binary files differ
diff --git a/test/reference/unbounded-operator.svg12.argb32.ref.png b/test/reference/unbounded-operator.svg12.argb32.ref.png
new file mode 100644
index 000000000..45b173fae
--- /dev/null
+++ b/test/reference/unbounded-operator.svg12.argb32.ref.png
Binary files differ
diff --git a/test/reference/unbounded-operator.svg12.rgb24.xfail.png b/test/reference/unbounded-operator.svg12.rgb24.xfail.png
new file mode 100644
index 000000000..828a9db97
--- /dev/null
+++ b/test/reference/unbounded-operator.svg12.rgb24.xfail.png
Binary files differ
diff --git a/test/reference/unbounded-operator.traps.argb32.ref.png b/test/reference/unbounded-operator.traps.argb32.ref.png
new file mode 100644
index 000000000..fe86a948e
--- /dev/null
+++ b/test/reference/unbounded-operator.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/unbounded-operator.traps.rgb24.ref.png b/test/reference/unbounded-operator.traps.rgb24.ref.png
new file mode 100644
index 000000000..c8555af14
--- /dev/null
+++ b/test/reference/unbounded-operator.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/unclosed-strokes.base.argb32.ref.png b/test/reference/unclosed-strokes.base.argb32.ref.png
new file mode 100644
index 000000000..34cedbd8b
--- /dev/null
+++ b/test/reference/unclosed-strokes.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/unclosed-strokes.base.rgb24.ref.png b/test/reference/unclosed-strokes.base.rgb24.ref.png
new file mode 100644
index 000000000..34cedbd8b
--- /dev/null
+++ b/test/reference/unclosed-strokes.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/unclosed-strokes.ref.png b/test/reference/unclosed-strokes.ref.png
new file mode 100644
index 000000000..7649c0338
--- /dev/null
+++ b/test/reference/unclosed-strokes.ref.png
Binary files differ
diff --git a/test/reference/unclosed-strokes.traps.argb32.ref.png b/test/reference/unclosed-strokes.traps.argb32.ref.png
new file mode 100644
index 000000000..34cedbd8b
--- /dev/null
+++ b/test/reference/unclosed-strokes.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/unclosed-strokes.traps.rgb24.ref.png b/test/reference/unclosed-strokes.traps.rgb24.ref.png
new file mode 100644
index 000000000..34cedbd8b
--- /dev/null
+++ b/test/reference/unclosed-strokes.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/user-font-mask.base.argb32.ref.png b/test/reference/user-font-mask.base.argb32.ref.png
new file mode 100644
index 000000000..02a9a5eca
--- /dev/null
+++ b/test/reference/user-font-mask.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/user-font-mask.base.rgb24.ref.png b/test/reference/user-font-mask.base.rgb24.ref.png
new file mode 100644
index 000000000..02a9a5eca
--- /dev/null
+++ b/test/reference/user-font-mask.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/user-font-mask.image16.ref.png b/test/reference/user-font-mask.image16.ref.png
new file mode 100644
index 000000000..0a63ddedc
--- /dev/null
+++ b/test/reference/user-font-mask.image16.ref.png
Binary files differ
diff --git a/test/reference/user-font-mask.pdf.ref.png b/test/reference/user-font-mask.pdf.ref.png
new file mode 100644
index 000000000..ebf148587
--- /dev/null
+++ b/test/reference/user-font-mask.pdf.ref.png
Binary files differ
diff --git a/test/reference/user-font-mask.ps2.ref.png b/test/reference/user-font-mask.ps2.ref.png
new file mode 100644
index 000000000..ebf148587
--- /dev/null
+++ b/test/reference/user-font-mask.ps2.ref.png
Binary files differ
diff --git a/test/reference/user-font-mask.ps3.ref.png b/test/reference/user-font-mask.ps3.ref.png
new file mode 100644
index 000000000..ebf148587
--- /dev/null
+++ b/test/reference/user-font-mask.ps3.ref.png
Binary files differ
diff --git a/test/reference/user-font-mask.ref.png b/test/reference/user-font-mask.ref.png
new file mode 100644
index 000000000..02a9a5eca
--- /dev/null
+++ b/test/reference/user-font-mask.ref.png
Binary files differ
diff --git a/test/reference/user-font-mask.svg.ref.png b/test/reference/user-font-mask.svg.ref.png
new file mode 100644
index 000000000..1a8f2c8cc
--- /dev/null
+++ b/test/reference/user-font-mask.svg.ref.png
Binary files differ
diff --git a/test/reference/user-font-proxy.base.argb32.ref.png b/test/reference/user-font-proxy.base.argb32.ref.png
new file mode 100644
index 000000000..094938c6e
--- /dev/null
+++ b/test/reference/user-font-proxy.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/user-font-proxy.base.rgb24.ref.png b/test/reference/user-font-proxy.base.rgb24.ref.png
new file mode 100644
index 000000000..094938c6e
--- /dev/null
+++ b/test/reference/user-font-proxy.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/user-font-proxy.image16.ref.png b/test/reference/user-font-proxy.image16.ref.png
new file mode 100644
index 000000000..5b44351bd
--- /dev/null
+++ b/test/reference/user-font-proxy.image16.ref.png
Binary files differ
diff --git a/test/reference/user-font-proxy.pdf.argb32.ref.png b/test/reference/user-font-proxy.pdf.argb32.ref.png
new file mode 100644
index 000000000..cffa9edb7
--- /dev/null
+++ b/test/reference/user-font-proxy.pdf.argb32.ref.png
Binary files differ
diff --git a/test/reference/user-font-proxy.pdf.ref.png b/test/reference/user-font-proxy.pdf.ref.png
new file mode 100644
index 000000000..afe7cb0dc
--- /dev/null
+++ b/test/reference/user-font-proxy.pdf.ref.png
Binary files differ
diff --git a/test/reference/user-font-proxy.pdf.rgb24.ref.png b/test/reference/user-font-proxy.pdf.rgb24.ref.png
new file mode 100644
index 000000000..cffa9edb7
--- /dev/null
+++ b/test/reference/user-font-proxy.pdf.rgb24.ref.png
Binary files differ
diff --git a/test/reference/user-font-proxy.ps.ref.png b/test/reference/user-font-proxy.ps.ref.png
new file mode 100644
index 000000000..a7b348b6a
--- /dev/null
+++ b/test/reference/user-font-proxy.ps.ref.png
Binary files differ
diff --git a/test/reference/user-font-proxy.quartz.ref.png b/test/reference/user-font-proxy.quartz.ref.png
new file mode 100644
index 000000000..3bead3d1f
--- /dev/null
+++ b/test/reference/user-font-proxy.quartz.ref.png
Binary files differ
diff --git a/test/reference/user-font-proxy.ref.png b/test/reference/user-font-proxy.ref.png
new file mode 100644
index 000000000..aa4f2556a
--- /dev/null
+++ b/test/reference/user-font-proxy.ref.png
Binary files differ
diff --git a/test/reference/user-font-proxy.svg.ref.png b/test/reference/user-font-proxy.svg.ref.png
new file mode 100644
index 000000000..6c458485d
--- /dev/null
+++ b/test/reference/user-font-proxy.svg.ref.png
Binary files differ
diff --git a/test/reference/user-font-proxy.traps.ref.png b/test/reference/user-font-proxy.traps.ref.png
new file mode 100644
index 000000000..094938c6e
--- /dev/null
+++ b/test/reference/user-font-proxy.traps.ref.png
Binary files differ
diff --git a/test/reference/user-font-rescale.base.argb32.ref.png b/test/reference/user-font-rescale.base.argb32.ref.png
new file mode 100644
index 000000000..093906014
--- /dev/null
+++ b/test/reference/user-font-rescale.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/user-font-rescale.base.rgb24.ref.png b/test/reference/user-font-rescale.base.rgb24.ref.png
new file mode 100644
index 000000000..093906014
--- /dev/null
+++ b/test/reference/user-font-rescale.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/user-font-rescale.image16.ref.png b/test/reference/user-font-rescale.image16.ref.png
new file mode 100644
index 000000000..a6be0d3d3
--- /dev/null
+++ b/test/reference/user-font-rescale.image16.ref.png
Binary files differ
diff --git a/test/reference/user-font-rescale.ps.ref.png b/test/reference/user-font-rescale.ps.ref.png
new file mode 100644
index 000000000..1ee4b1303
--- /dev/null
+++ b/test/reference/user-font-rescale.ps.ref.png
Binary files differ
diff --git a/test/reference/user-font-rescale.quartz.ref.png b/test/reference/user-font-rescale.quartz.ref.png
new file mode 100644
index 000000000..5fa2984ca
--- /dev/null
+++ b/test/reference/user-font-rescale.quartz.ref.png
Binary files differ
diff --git a/test/reference/user-font-rescale.ref.png b/test/reference/user-font-rescale.ref.png
new file mode 100644
index 000000000..093906014
--- /dev/null
+++ b/test/reference/user-font-rescale.ref.png
Binary files differ
diff --git a/test/reference/user-font-rescale.svg.ref.png b/test/reference/user-font-rescale.svg.ref.png
new file mode 100644
index 000000000..6ed2a1924
--- /dev/null
+++ b/test/reference/user-font-rescale.svg.ref.png
Binary files differ
diff --git a/test/reference/user-font-rescale.traps.ref.png b/test/reference/user-font-rescale.traps.ref.png
new file mode 100644
index 000000000..093906014
--- /dev/null
+++ b/test/reference/user-font-rescale.traps.ref.png
Binary files differ
diff --git a/test/reference/user-font.base.argb32.ref.png b/test/reference/user-font.base.argb32.ref.png
new file mode 100644
index 000000000..896dbab25
--- /dev/null
+++ b/test/reference/user-font.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/user-font.base.rgb24.ref.png b/test/reference/user-font.base.rgb24.ref.png
new file mode 100644
index 000000000..896dbab25
--- /dev/null
+++ b/test/reference/user-font.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/user-font.image16.ref.png b/test/reference/user-font.image16.ref.png
new file mode 100644
index 000000000..fcdfb5793
--- /dev/null
+++ b/test/reference/user-font.image16.ref.png
Binary files differ
diff --git a/test/reference/user-font.mask.argb32.ref.png b/test/reference/user-font.mask.argb32.ref.png
new file mode 100644
index 000000000..b234a8801
--- /dev/null
+++ b/test/reference/user-font.mask.argb32.ref.png
Binary files differ
diff --git a/test/reference/user-font.mask.rgb24.ref.png b/test/reference/user-font.mask.rgb24.ref.png
new file mode 100644
index 000000000..b234a8801
--- /dev/null
+++ b/test/reference/user-font.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/user-font.pdf.ref.png b/test/reference/user-font.pdf.ref.png
new file mode 100644
index 000000000..de864074a
--- /dev/null
+++ b/test/reference/user-font.pdf.ref.png
Binary files differ
diff --git a/test/reference/user-font.ps.ref.png b/test/reference/user-font.ps.ref.png
new file mode 100644
index 000000000..63f289698
--- /dev/null
+++ b/test/reference/user-font.ps.ref.png
Binary files differ
diff --git a/test/reference/user-font.quartz.ref.png b/test/reference/user-font.quartz.ref.png
new file mode 100644
index 000000000..8c0ec94e6
--- /dev/null
+++ b/test/reference/user-font.quartz.ref.png
Binary files differ
diff --git a/test/reference/user-font.ref.png b/test/reference/user-font.ref.png
new file mode 100644
index 000000000..4cff7e996
--- /dev/null
+++ b/test/reference/user-font.ref.png
Binary files differ
diff --git a/test/reference/user-font.svg.ref.png b/test/reference/user-font.svg.ref.png
new file mode 100644
index 000000000..1ff6ea0fe
--- /dev/null
+++ b/test/reference/user-font.svg.ref.png
Binary files differ
diff --git a/test/reference/user-font.traps.argb32.ref.png b/test/reference/user-font.traps.argb32.ref.png
new file mode 100644
index 000000000..896dbab25
--- /dev/null
+++ b/test/reference/user-font.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/user-font.traps.rgb24.ref.png b/test/reference/user-font.traps.rgb24.ref.png
new file mode 100644
index 000000000..896dbab25
--- /dev/null
+++ b/test/reference/user-font.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/white-in-noop.base.argb32.ref.png b/test/reference/white-in-noop.base.argb32.ref.png
new file mode 100644
index 000000000..f42bb8d5f
--- /dev/null
+++ b/test/reference/white-in-noop.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/white-in-noop.base.rgb24.ref.png b/test/reference/white-in-noop.base.rgb24.ref.png
new file mode 100644
index 000000000..f42bb8d5f
--- /dev/null
+++ b/test/reference/white-in-noop.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/white-in-noop.ref.png b/test/reference/white-in-noop.ref.png
new file mode 100644
index 000000000..f42bb8d5f
--- /dev/null
+++ b/test/reference/white-in-noop.ref.png
Binary files differ
diff --git a/test/reference/world-map-fill.base.argb32.ref.png b/test/reference/world-map-fill.base.argb32.ref.png
new file mode 100644
index 000000000..926c1a8ee
--- /dev/null
+++ b/test/reference/world-map-fill.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/world-map-fill.base.rgb24.ref.png b/test/reference/world-map-fill.base.rgb24.ref.png
new file mode 100644
index 000000000..926c1a8ee
--- /dev/null
+++ b/test/reference/world-map-fill.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/world-map-fill.image16.ref.png b/test/reference/world-map-fill.image16.ref.png
new file mode 100644
index 000000000..c97cb5766
--- /dev/null
+++ b/test/reference/world-map-fill.image16.ref.png
Binary files differ
diff --git a/test/reference/world-map-fill.ref.png b/test/reference/world-map-fill.ref.png
new file mode 100644
index 000000000..23cec5046
--- /dev/null
+++ b/test/reference/world-map-fill.ref.png
Binary files differ
diff --git a/test/reference/world-map-fill.traps.argb32.ref.png b/test/reference/world-map-fill.traps.argb32.ref.png
new file mode 100644
index 000000000..926c1a8ee
--- /dev/null
+++ b/test/reference/world-map-fill.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/world-map-fill.traps.rgb24.ref.png b/test/reference/world-map-fill.traps.rgb24.ref.png
new file mode 100644
index 000000000..926c1a8ee
--- /dev/null
+++ b/test/reference/world-map-fill.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/world-map-stroke.base.argb32.ref.png b/test/reference/world-map-stroke.base.argb32.ref.png
new file mode 100644
index 000000000..d00c9450e
--- /dev/null
+++ b/test/reference/world-map-stroke.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/world-map-stroke.base.rgb24.ref.png b/test/reference/world-map-stroke.base.rgb24.ref.png
new file mode 100644
index 000000000..d00c9450e
--- /dev/null
+++ b/test/reference/world-map-stroke.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/world-map-stroke.image16.ref.png b/test/reference/world-map-stroke.image16.ref.png
new file mode 100644
index 000000000..771ff0b19
--- /dev/null
+++ b/test/reference/world-map-stroke.image16.ref.png
Binary files differ
diff --git a/test/reference/world-map-stroke.mask.argb32.ref.png b/test/reference/world-map-stroke.mask.argb32.ref.png
new file mode 100644
index 000000000..ec0d5021b
--- /dev/null
+++ b/test/reference/world-map-stroke.mask.argb32.ref.png
Binary files differ
diff --git a/test/reference/world-map-stroke.mask.rgb24.ref.png b/test/reference/world-map-stroke.mask.rgb24.ref.png
new file mode 100644
index 000000000..ec0d5021b
--- /dev/null
+++ b/test/reference/world-map-stroke.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/world-map-stroke.ref.png b/test/reference/world-map-stroke.ref.png
new file mode 100644
index 000000000..5c6e7d52b
--- /dev/null
+++ b/test/reference/world-map-stroke.ref.png
Binary files differ
diff --git a/test/reference/world-map-stroke.traps.argb32.ref.png b/test/reference/world-map-stroke.traps.argb32.ref.png
new file mode 100644
index 000000000..d00c9450e
--- /dev/null
+++ b/test/reference/world-map-stroke.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/world-map-stroke.traps.rgb24.ref.png b/test/reference/world-map-stroke.traps.rgb24.ref.png
new file mode 100644
index 000000000..d00c9450e
--- /dev/null
+++ b/test/reference/world-map-stroke.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/world-map.base.argb32.ref.png b/test/reference/world-map.base.argb32.ref.png
new file mode 100644
index 000000000..6bae50d2b
--- /dev/null
+++ b/test/reference/world-map.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/world-map.base.rgb24.ref.png b/test/reference/world-map.base.rgb24.ref.png
new file mode 100644
index 000000000..6bae50d2b
--- /dev/null
+++ b/test/reference/world-map.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/world-map.image16.ref.png b/test/reference/world-map.image16.ref.png
new file mode 100644
index 000000000..ea7ae8a9a
--- /dev/null
+++ b/test/reference/world-map.image16.ref.png
Binary files differ
diff --git a/test/reference/world-map.mask.argb32.ref.png b/test/reference/world-map.mask.argb32.ref.png
new file mode 100644
index 000000000..218a303ac
--- /dev/null
+++ b/test/reference/world-map.mask.argb32.ref.png
Binary files differ
diff --git a/test/reference/world-map.mask.rgb24.ref.png b/test/reference/world-map.mask.rgb24.ref.png
new file mode 100644
index 000000000..218a303ac
--- /dev/null
+++ b/test/reference/world-map.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/world-map.ref.png b/test/reference/world-map.ref.png
new file mode 100644
index 000000000..12743675c
--- /dev/null
+++ b/test/reference/world-map.ref.png
Binary files differ
diff --git a/test/reference/world-map.traps.argb32.ref.png b/test/reference/world-map.traps.argb32.ref.png
new file mode 100644
index 000000000..6bae50d2b
--- /dev/null
+++ b/test/reference/world-map.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/world-map.traps.rgb24.ref.png b/test/reference/world-map.traps.rgb24.ref.png
new file mode 100644
index 000000000..6bae50d2b
--- /dev/null
+++ b/test/reference/world-map.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/xcb-huge-image-shm.base.argb32.ref.png b/test/reference/xcb-huge-image-shm.base.argb32.ref.png
new file mode 100644
index 000000000..a0b24c8aa
--- /dev/null
+++ b/test/reference/xcb-huge-image-shm.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/xcb-huge-image-shm.base.rgb24.ref.png b/test/reference/xcb-huge-image-shm.base.rgb24.ref.png
new file mode 100644
index 000000000..a0b24c8aa
--- /dev/null
+++ b/test/reference/xcb-huge-image-shm.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/xcb-huge-image-shm.ref.png b/test/reference/xcb-huge-image-shm.ref.png
new file mode 100644
index 000000000..5c274f824
--- /dev/null
+++ b/test/reference/xcb-huge-image-shm.ref.png
Binary files differ
diff --git a/test/reference/xcb-huge-subimage.ref.png b/test/reference/xcb-huge-subimage.ref.png
new file mode 100644
index 000000000..5c274f824
--- /dev/null
+++ b/test/reference/xcb-huge-subimage.ref.png
Binary files differ
diff --git a/test/reference/xcb-snapshot-assert.base.argb32.ref.png b/test/reference/xcb-snapshot-assert.base.argb32.ref.png
new file mode 100644
index 000000000..850ce59be
--- /dev/null
+++ b/test/reference/xcb-snapshot-assert.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/xcb-snapshot-assert.base.rgb24.ref.png b/test/reference/xcb-snapshot-assert.base.rgb24.ref.png
new file mode 100644
index 000000000..850ce59be
--- /dev/null
+++ b/test/reference/xcb-snapshot-assert.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/xcb-snapshot-assert.ref.png b/test/reference/xcb-snapshot-assert.ref.png
new file mode 100644
index 000000000..850ce59be
--- /dev/null
+++ b/test/reference/xcb-snapshot-assert.ref.png
Binary files differ
diff --git a/test/reference/xcb-stress-cache.base.argb32.ref.png b/test/reference/xcb-stress-cache.base.argb32.ref.png
new file mode 100644
index 000000000..850ce59be
--- /dev/null
+++ b/test/reference/xcb-stress-cache.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/xcb-stress-cache.base.rgb24.ref.png b/test/reference/xcb-stress-cache.base.rgb24.ref.png
new file mode 100644
index 000000000..850ce59be
--- /dev/null
+++ b/test/reference/xcb-stress-cache.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/xcb-stress-cache.ref.png b/test/reference/xcb-stress-cache.ref.png
new file mode 100644
index 000000000..850ce59be
--- /dev/null
+++ b/test/reference/xcb-stress-cache.ref.png
Binary files differ
diff --git a/test/reference/xcb-surface-source.base.argb32.ref.png b/test/reference/xcb-surface-source.base.argb32.ref.png
new file mode 100644
index 000000000..018297208
--- /dev/null
+++ b/test/reference/xcb-surface-source.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/xcb-surface-source.base.rgb24.ref.png b/test/reference/xcb-surface-source.base.rgb24.ref.png
new file mode 100644
index 000000000..0d68a82cc
--- /dev/null
+++ b/test/reference/xcb-surface-source.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/xcb-surface-source.image16.ref.png b/test/reference/xcb-surface-source.image16.ref.png
new file mode 100644
index 000000000..2a7460e28
--- /dev/null
+++ b/test/reference/xcb-surface-source.image16.ref.png
Binary files differ
diff --git a/test/reference/xcb-surface-source.ps.argb32.ref.png b/test/reference/xcb-surface-source.ps.argb32.ref.png
new file mode 100644
index 000000000..910f895db
--- /dev/null
+++ b/test/reference/xcb-surface-source.ps.argb32.ref.png
Binary files differ
diff --git a/test/reference/xcb-surface-source.ps.rgb24.ref.png b/test/reference/xcb-surface-source.ps.rgb24.ref.png
new file mode 100644
index 000000000..636b0f58b
--- /dev/null
+++ b/test/reference/xcb-surface-source.ps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/xcb-surface-source.ref.png b/test/reference/xcb-surface-source.ref.png
new file mode 100644
index 000000000..018297208
--- /dev/null
+++ b/test/reference/xcb-surface-source.ref.png
Binary files differ
diff --git a/test/reference/xcomposite-projection.base.argb32.ref.png b/test/reference/xcomposite-projection.base.argb32.ref.png
new file mode 100644
index 000000000..ea4dddf71
--- /dev/null
+++ b/test/reference/xcomposite-projection.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/xcomposite-projection.base.rgb24.ref.png b/test/reference/xcomposite-projection.base.rgb24.ref.png
new file mode 100644
index 000000000..ea4dddf71
--- /dev/null
+++ b/test/reference/xcomposite-projection.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/xcomposite-projection.image16.ref.png b/test/reference/xcomposite-projection.image16.ref.png
new file mode 100644
index 000000000..f9bc3b621
--- /dev/null
+++ b/test/reference/xcomposite-projection.image16.ref.png
Binary files differ
diff --git a/test/reference/xcomposite-projection.mask.argb32.ref.png b/test/reference/xcomposite-projection.mask.argb32.ref.png
new file mode 100644
index 000000000..9ccabda9f
--- /dev/null
+++ b/test/reference/xcomposite-projection.mask.argb32.ref.png
Binary files differ
diff --git a/test/reference/xcomposite-projection.mask.rgb24.ref.png b/test/reference/xcomposite-projection.mask.rgb24.ref.png
new file mode 100644
index 000000000..9ccabda9f
--- /dev/null
+++ b/test/reference/xcomposite-projection.mask.rgb24.ref.png
Binary files differ
diff --git a/test/reference/xcomposite-projection.quartz.ref.png b/test/reference/xcomposite-projection.quartz.ref.png
new file mode 100644
index 000000000..02216071b
--- /dev/null
+++ b/test/reference/xcomposite-projection.quartz.ref.png
Binary files differ
diff --git a/test/reference/xcomposite-projection.ref.png b/test/reference/xcomposite-projection.ref.png
new file mode 100644
index 000000000..abbea0866
--- /dev/null
+++ b/test/reference/xcomposite-projection.ref.png
Binary files differ
diff --git a/test/reference/xcomposite-projection.traps.argb32.ref.png b/test/reference/xcomposite-projection.traps.argb32.ref.png
new file mode 100644
index 000000000..ea4dddf71
--- /dev/null
+++ b/test/reference/xcomposite-projection.traps.argb32.ref.png
Binary files differ
diff --git a/test/reference/xcomposite-projection.traps.rgb24.ref.png b/test/reference/xcomposite-projection.traps.rgb24.ref.png
new file mode 100644
index 000000000..ea4dddf71
--- /dev/null
+++ b/test/reference/xcomposite-projection.traps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/xlib-expose-event.base.argb32.ref.png b/test/reference/xlib-expose-event.base.argb32.ref.png
new file mode 100644
index 000000000..fd71f5a32
--- /dev/null
+++ b/test/reference/xlib-expose-event.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/xlib-expose-event.base.rgb24.ref.png b/test/reference/xlib-expose-event.base.rgb24.ref.png
new file mode 100644
index 000000000..fd71f5a32
--- /dev/null
+++ b/test/reference/xlib-expose-event.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/xlib-expose-event.image16.ref.png b/test/reference/xlib-expose-event.image16.ref.png
new file mode 100644
index 000000000..54d5f2673
--- /dev/null
+++ b/test/reference/xlib-expose-event.image16.ref.png
Binary files differ
diff --git a/test/reference/xlib-expose-event.ps.ref.png b/test/reference/xlib-expose-event.ps.ref.png
new file mode 100644
index 000000000..88f49c134
--- /dev/null
+++ b/test/reference/xlib-expose-event.ps.ref.png
Binary files differ
diff --git a/test/reference/xlib-expose-event.ref.png b/test/reference/xlib-expose-event.ref.png
new file mode 100644
index 000000000..1cca0e749
--- /dev/null
+++ b/test/reference/xlib-expose-event.ref.png
Binary files differ
diff --git a/test/reference/xlib-surface-source.base.argb32.ref.png b/test/reference/xlib-surface-source.base.argb32.ref.png
new file mode 100644
index 000000000..018297208
--- /dev/null
+++ b/test/reference/xlib-surface-source.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/xlib-surface-source.base.rgb24.ref.png b/test/reference/xlib-surface-source.base.rgb24.ref.png
new file mode 100644
index 000000000..0d68a82cc
--- /dev/null
+++ b/test/reference/xlib-surface-source.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/xlib-surface-source.image16.ref.png b/test/reference/xlib-surface-source.image16.ref.png
new file mode 100644
index 000000000..2a7460e28
--- /dev/null
+++ b/test/reference/xlib-surface-source.image16.ref.png
Binary files differ
diff --git a/test/reference/xlib-surface-source.ps.argb32.ref.png b/test/reference/xlib-surface-source.ps.argb32.ref.png
new file mode 100644
index 000000000..910f895db
--- /dev/null
+++ b/test/reference/xlib-surface-source.ps.argb32.ref.png
Binary files differ
diff --git a/test/reference/xlib-surface-source.ps.rgb24.ref.png b/test/reference/xlib-surface-source.ps.rgb24.ref.png
new file mode 100644
index 000000000..636b0f58b
--- /dev/null
+++ b/test/reference/xlib-surface-source.ps.rgb24.ref.png
Binary files differ
diff --git a/test/reference/xlib-surface-source.ref.png b/test/reference/xlib-surface-source.ref.png
new file mode 100644
index 000000000..018297208
--- /dev/null
+++ b/test/reference/xlib-surface-source.ref.png
Binary files differ
diff --git a/test/reference/xlib-surface-source.svg12.argb32.xfail.png b/test/reference/xlib-surface-source.svg12.argb32.xfail.png
new file mode 100644
index 000000000..6ebcaf9a1
--- /dev/null
+++ b/test/reference/xlib-surface-source.svg12.argb32.xfail.png
Binary files differ
diff --git a/test/reference/xlib-surface-source.svg12.rgb24.xfail.png b/test/reference/xlib-surface-source.svg12.rgb24.xfail.png
new file mode 100644
index 000000000..6ebcaf9a1
--- /dev/null
+++ b/test/reference/xlib-surface-source.svg12.rgb24.xfail.png
Binary files differ
diff --git a/test/reference/zero-alpha.base.argb32.ref.png b/test/reference/zero-alpha.base.argb32.ref.png
new file mode 100644
index 000000000..595c0aee4
--- /dev/null
+++ b/test/reference/zero-alpha.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/zero-alpha.base.rgb24.ref.png b/test/reference/zero-alpha.base.rgb24.ref.png
new file mode 100644
index 000000000..595c0aee4
--- /dev/null
+++ b/test/reference/zero-alpha.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/zero-alpha.ref.png b/test/reference/zero-alpha.ref.png
new file mode 100644
index 000000000..d03727dda
--- /dev/null
+++ b/test/reference/zero-alpha.ref.png
Binary files differ
diff --git a/test/reference/zero-mask.base.argb32.ref.png b/test/reference/zero-mask.base.argb32.ref.png
new file mode 100644
index 000000000..ffae8d995
--- /dev/null
+++ b/test/reference/zero-mask.base.argb32.ref.png
Binary files differ
diff --git a/test/reference/zero-mask.base.rgb24.ref.png b/test/reference/zero-mask.base.rgb24.ref.png
new file mode 100644
index 000000000..263c3d1e8
--- /dev/null
+++ b/test/reference/zero-mask.base.rgb24.ref.png
Binary files differ
diff --git a/test/reference/zero-mask.ref.png b/test/reference/zero-mask.ref.png
new file mode 100644
index 000000000..ffae8d995
--- /dev/null
+++ b/test/reference/zero-mask.ref.png
Binary files differ
diff --git a/test/reflected-stroke.c b/test/reflected-stroke.c
new file mode 100644
index 000000000..895396a6a
--- /dev/null
+++ b/test/reflected-stroke.c
@@ -0,0 +1,91 @@
+/*
+ * Copyright © 2008 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * the author not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. The author makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THE AUTHOR. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+static void
+draw_symbol (cairo_t *cr)
+{
+ double dash[] = {6, 3};
+
+ cairo_rectangle (cr, -25, -25, 50, 50);
+ cairo_stroke (cr);
+
+ cairo_move_to (cr, 0, -25);
+ cairo_curve_to (cr, 12.5, -12.5, 12.5, -12.5, 0, 0);
+ cairo_curve_to (cr, -12.5, 12.5, -12.5, 12.5, 0, 25);
+ cairo_curve_to (cr, 12.5, 12.5, 12.5, 12.5, 0, 0);
+ cairo_stroke (cr);
+
+ cairo_save (cr);
+ cairo_set_dash (cr, dash, ARRAY_LENGTH (dash), 0.);
+ cairo_move_to (cr, 0, 0);
+ cairo_arc (cr, 0, 0, 12.5, 0, 3 * M_PI / 2);
+ cairo_close_path (cr);
+ cairo_stroke (cr);
+ cairo_restore (cr);
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+ cairo_set_source_rgb (cr, 0, 0, 0);
+
+ cairo_save (cr);
+ cairo_translate (cr, 50, 50);
+ cairo_scale (cr, 1, 1);
+ draw_symbol (cr);
+ cairo_restore (cr);
+
+ cairo_save (cr);
+ cairo_translate (cr, 150, 50);
+ cairo_scale (cr, -1, 1);
+ draw_symbol (cr);
+ cairo_restore (cr);
+
+ cairo_save (cr);
+ cairo_translate (cr, 150, 150);
+ cairo_scale (cr, -1, -1);
+ draw_symbol (cr);
+ cairo_restore (cr);
+
+ cairo_save (cr);
+ cairo_translate (cr, 50, 150);
+ cairo_scale (cr, 1, -1);
+ draw_symbol (cr);
+ cairo_restore (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (reflected_stroke,
+ "Exercises the stroker with a reflected ctm",
+ "stroke, transform", /* keywords */
+ NULL, /* requirements */
+ 200, 200,
+ NULL, draw)
diff --git a/test/rel-path.c b/test/rel-path.c
new file mode 100644
index 000000000..d1ef25920
--- /dev/null
+++ b/test/rel-path.c
@@ -0,0 +1,129 @@
+/*
+ * Copyright © 2005 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "cairo-test.h"
+
+#define SIZE 10
+
+static cairo_status_t
+invalid_rel_move_to (cairo_surface_t *target)
+{
+ cairo_t *cr;
+ cairo_status_t status;
+
+ cr = cairo_create (target);
+ cairo_rel_move_to (cr, SIZE, SIZE/2);
+ status = cairo_status (cr);
+ cairo_destroy (cr);
+
+ return status;
+}
+
+static cairo_status_t
+invalid_rel_line_to (cairo_surface_t *target)
+{
+ cairo_t *cr;
+ cairo_status_t status;
+
+ cr = cairo_create (target);
+ cairo_rel_line_to (cr, -SIZE, SIZE/2);
+ status = cairo_status (cr);
+ cairo_destroy (cr);
+
+ return status;
+}
+
+static cairo_status_t
+invalid_rel_curve_to (cairo_surface_t *target)
+{
+ cairo_t *cr;
+ cairo_status_t status;
+
+ cr = cairo_create (target);
+ cairo_rel_curve_to (cr,
+ SIZE/2, -SIZE/2,
+ SIZE*2/3, -SIZE/3,
+ SIZE/2, -SIZE);
+ status = cairo_status (cr);
+ cairo_destroy (cr);
+
+ return status;
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ const cairo_test_context_t *ctx = cairo_test_get_context (cr);
+ cairo_status_t status;
+ cairo_test_status_t result;
+
+ /* first test that a relative move without a current point fails... */
+ status = invalid_rel_move_to (cairo_get_target (cr));
+ if (status != CAIRO_STATUS_NO_CURRENT_POINT) {
+ result = cairo_test_status_from_status (ctx, status);
+ if (result == CAIRO_TEST_NO_MEMORY)
+ return result;
+
+ cairo_test_log (ctx, "Error: invalid cairo_rel_move_to() did not raise NO_CURRENT_POINT\n");
+ return result;
+ }
+
+ status = invalid_rel_line_to (cairo_get_target (cr));
+ if (status != CAIRO_STATUS_NO_CURRENT_POINT) {
+ result = cairo_test_status_from_status (ctx, status);
+ if (result == CAIRO_TEST_NO_MEMORY)
+ return result;
+
+ cairo_test_log (ctx, "Error: invalid cairo_rel_line_to() did not raise NO_CURRENT_POINT\n");
+ return result;
+ }
+
+ status = invalid_rel_curve_to (cairo_get_target (cr));
+ if (status != CAIRO_STATUS_NO_CURRENT_POINT) {
+ result = cairo_test_status_from_status (ctx, status);
+ if (result == CAIRO_TEST_NO_MEMORY)
+ return result;
+
+ cairo_test_log (ctx, "Error: invalid cairo_rel_curve_to() did not raise NO_CURRENT_POINT\n");
+ return result;
+ }
+
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_move_to (cr, 0, 0);
+ cairo_rel_move_to (cr, SIZE, SIZE/2);
+ cairo_rel_line_to (cr, -SIZE, SIZE/2);
+ cairo_rel_curve_to (cr,
+ SIZE/2, -SIZE/2,
+ SIZE*2/3, -SIZE/3,
+ SIZE/2, -SIZE);
+
+ cairo_stroke (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (rel_path,
+ "Tests calls to various relative path functions",
+ "path", /* keywords */
+ NULL, /* requirements */
+ SIZE, SIZE,
+ NULL, draw)
diff --git a/test/rgb24-ignore-alpha.c b/test/rgb24-ignore-alpha.c
new file mode 100644
index 000000000..1c9d57e9e
--- /dev/null
+++ b/test/rgb24-ignore-alpha.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright © 2007 Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+#include "cairo-test.h"
+
+#define WIDTH 2
+#define HEIGHT 2
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_surface_t *surface;
+ /* Four green pixels with different "alpha" values, (but which
+ * should be entirely ignored). */
+ uint32_t colors[4] = {
+ 0xff00ff00, 0x8800ff00,
+ 0x4400ff00, 0x0000ff00
+ };
+
+ surface = cairo_image_surface_create_for_data ((unsigned char *) colors,
+ CAIRO_FORMAT_RGB24, 2, 2, 8);
+
+ cairo_set_source_surface (cr, surface, 0, 0);
+ cairo_paint (cr);
+
+ cairo_surface_finish (surface); /* colors will go out of scope */
+ cairo_surface_destroy (surface);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (rgb24_ignore_alpha,
+ "Test that when using an RGB24 image as a source, there is no alpha channel",
+ "image, alpha", /* keywords */
+ NULL, /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw)
diff --git a/test/romedalen.jpg b/test/romedalen.jpg
new file mode 100644
index 000000000..d655e3d89
--- /dev/null
+++ b/test/romedalen.jpg
Binary files differ
diff --git a/test/romedalen.png b/test/romedalen.png
new file mode 100644
index 000000000..0c41eb0cf
--- /dev/null
+++ b/test/romedalen.png
Binary files differ
diff --git a/test/rotate-image-surface-paint.c b/test/rotate-image-surface-paint.c
new file mode 100644
index 000000000..42fda6ec2
--- /dev/null
+++ b/test/rotate-image-surface-paint.c
@@ -0,0 +1,172 @@
+/*
+ * Copyright © 2005, 2007 Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+#include "cairo-test.h"
+
+#define SIZE 20
+#define PAD 2
+
+static cairo_pattern_t *
+create_image_source (int size)
+{
+ cairo_surface_t *surface;
+ cairo_pattern_t *pattern;
+ cairo_t *cr;
+
+ /* Create an image surface with my favorite four colors in each
+ * quadrant. */
+ surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, size, size);
+ cr = cairo_create (surface);
+ cairo_surface_destroy (surface);
+
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_rectangle (cr, 0, 0, size / 2, size / 2);
+ cairo_fill (cr);
+
+ cairo_set_source_rgb (cr, 1, 0, 0);
+ cairo_rectangle (cr, size / 2, 0, size - size / 2, size / 2);
+ cairo_fill (cr);
+
+ cairo_set_source_rgb (cr, 0, 1, 0);
+ cairo_rectangle (cr, 0, size / 2, size / 2, size - size / 2);
+ cairo_fill (cr);
+
+ cairo_set_source_rgb (cr, 0, 0, 1);
+ cairo_rectangle (cr, size / 2, size / 2, size - size / 2, size - size / 2);
+ cairo_fill (cr);
+
+ pattern = cairo_pattern_create_for_surface (cairo_get_target (cr));
+ cairo_destroy (cr);
+
+ return pattern;
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_pattern_t *source;
+ int surface_size = sqrt ((SIZE - 2*PAD)*(SIZE - 2*PAD)/2);
+
+ /* Use a gray (neutral) background, so we can spot if the backend pads
+ * with any other colour.
+ */
+ cairo_set_source_rgb (cr, .5, .5, .5);
+ cairo_paint (cr);
+
+ cairo_translate(cr, SIZE/2, SIZE/2);
+ cairo_rotate (cr, M_PI / 4.0);
+ cairo_translate (cr, -surface_size/2, -surface_size/2);
+
+ source = create_image_source (surface_size);
+ cairo_pattern_set_filter (source, CAIRO_FILTER_NEAREST);
+ cairo_set_source(cr, source);
+ cairo_pattern_destroy (source);
+
+ cairo_paint (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+clip_draw (cairo_t *cr, int width, int height)
+{
+ cairo_pattern_t *source;
+ int surface_size = sqrt ((SIZE - 2*PAD)*(SIZE - 2*PAD)/2);
+
+ /* Use a gray (neutral) background, so we can spot if the backend pads
+ * with any other colour.
+ */
+ cairo_set_source_rgb (cr, .5, .5, .5);
+ cairo_paint (cr);
+
+ cairo_rectangle (cr, 2*PAD, 2*PAD, SIZE-4*PAD, SIZE-4*PAD);
+ cairo_clip (cr);
+
+ cairo_translate(cr, SIZE/2, SIZE/2);
+ cairo_rotate (cr, M_PI / 4.0);
+ cairo_translate (cr, -surface_size/2, -surface_size/2);
+
+ source = create_image_source (surface_size);
+ cairo_pattern_set_filter (source, CAIRO_FILTER_NEAREST);
+ cairo_set_source(cr, source);
+ cairo_pattern_destroy (source);
+
+ cairo_paint (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+draw_clip (cairo_t *cr, int width, int height)
+{
+ cairo_pattern_t *source;
+ int surface_size = sqrt ((SIZE - 2*PAD)*(SIZE - 2*PAD)/2);
+
+ /* Use a gray (neutral) background, so we can spot if the backend pads
+ * with any other colour.
+ */
+ cairo_set_source_rgb (cr, .5, .5, .5);
+ cairo_paint (cr);
+
+ cairo_translate(cr, SIZE/2, SIZE/2);
+ cairo_rotate (cr, M_PI / 4.0);
+ cairo_translate (cr, -surface_size/2, -surface_size/2);
+
+ cairo_rectangle (cr, PAD, PAD, surface_size-2*PAD, surface_size-2*PAD);
+ cairo_clip (cr);
+
+ source = create_image_source (surface_size);
+ cairo_pattern_set_filter (source, CAIRO_FILTER_NEAREST);
+ cairo_set_source(cr, source);
+ cairo_pattern_destroy (source);
+
+ cairo_paint (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (rotate_image_surface_paint,
+ "Test call sequence: image_surface_create; rotate; set_source_surface; paint"
+ "\nThis test is known to fail on the ps backend currently",
+ "image, transform, paint", /* keywords */
+ NULL, /* requirements */
+ SIZE, SIZE,
+ NULL, draw)
+
+CAIRO_TEST (clip_rotate_image_surface_paint,
+ "Test call sequence: image_surface_create; rotate; set_source_surface; paint"
+ "\nThis test is known to fail on the ps backend currently",
+ "image, transform, paint", /* keywords */
+ NULL, /* requirements */
+ SIZE, SIZE,
+ NULL, clip_draw)
+CAIRO_TEST (rotate_clip_image_surface_paint,
+ "Test call sequence: image_surface_create; rotate; set_source_surface; paint"
+ "\nThis test is known to fail on the ps backend currently",
+ "image, transform, paint", /* keywords */
+ NULL, /* requirements */
+ SIZE, SIZE,
+ NULL, draw_clip)
diff --git a/test/rotate-stroke-box.c b/test/rotate-stroke-box.c
new file mode 100644
index 000000000..862abc933
--- /dev/null
+++ b/test/rotate-stroke-box.c
@@ -0,0 +1,49 @@
+/*
+ * Copyright © 2013 Adrian Johnson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Adrian Johnson <ajohnson@redneon.com>
+ */
+
+#include "cairo-test.h"
+#include <math.h>
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_save (cr);
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+ cairo_restore (cr);
+
+ cairo_rectangle (cr, 5, 5, 20, 20);
+ cairo_rotate (cr, M_PI/4);
+ cairo_stroke (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (rotate_stroke_box,
+ "Ensure rectangle path optimization works when the stroking transform is non rectilinear",
+ "path", /* keywords */
+ NULL, /* requirements */
+ 30, 30,
+ NULL, draw)
diff --git a/test/rotated-clip.c b/test/rotated-clip.c
new file mode 100644
index 000000000..4ca4566d5
--- /dev/null
+++ b/test/rotated-clip.c
@@ -0,0 +1,110 @@
+/*
+ * Copyright © 2007 Adrian Johnson
+ * Copyright © 2009 Chris Wilson
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Adrian Johnson <ajohnson@redneon.com>
+ * Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+#define PAT_WIDTH 120
+#define PAT_HEIGHT 120
+#define SIZE (PAT_WIDTH*2)
+#define PAD 2
+#define WIDTH (PAD + SIZE + PAD)
+#define HEIGHT WIDTH
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_matrix_t m;
+
+ /* make the output opaque */
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ cairo_paint (cr);
+
+ cairo_translate (cr, PAD, PAD);
+
+ cairo_matrix_init_scale (&m, 2, 1.5);
+ cairo_matrix_rotate (&m, 1);
+ cairo_matrix_translate (&m, -PAT_WIDTH/4.0, -PAT_WIDTH/2.0);
+ cairo_matrix_invert (&m);
+ cairo_set_matrix (cr, &m);
+
+ cairo_rectangle (cr, 0, 0, PAT_WIDTH, PAT_HEIGHT);
+ cairo_clip (cr);
+
+ cairo_set_source_rgba (cr, 1, 0, 1, 0.5);
+ cairo_rectangle (cr, PAT_WIDTH/6.0, PAT_HEIGHT/6.0, PAT_WIDTH/4.0, PAT_HEIGHT/4.0);
+ cairo_fill (cr);
+
+ cairo_set_source_rgba (cr, 0, 1, 1, 0.5);
+ cairo_rectangle (cr, PAT_WIDTH/2.0, PAT_HEIGHT/2.0, PAT_WIDTH/4.0, PAT_HEIGHT/4.0);
+ cairo_fill (cr);
+
+ cairo_set_line_width (cr, 1);
+ cairo_move_to (cr, PAT_WIDTH/6.0, 0);
+ cairo_line_to (cr, 0, 0);
+ cairo_line_to (cr, 0, PAT_HEIGHT/6.0);
+ cairo_set_source_rgb (cr, 1, 0, 0);
+ cairo_stroke (cr);
+
+ cairo_move_to (cr, PAT_WIDTH/6.0, PAT_HEIGHT);
+ cairo_line_to (cr, 0, PAT_HEIGHT);
+ cairo_line_to (cr, 0, 5*PAT_HEIGHT/6.0);
+ cairo_set_source_rgb (cr, 0, 1, 0);
+ cairo_stroke (cr);
+
+ cairo_move_to (cr, 5*PAT_WIDTH/6.0, 0);
+ cairo_line_to (cr, PAT_WIDTH, 0);
+ cairo_line_to (cr, PAT_WIDTH, PAT_HEIGHT/6.0);
+ cairo_set_source_rgb (cr, 0, 0, 1);
+ cairo_stroke (cr);
+
+ cairo_move_to (cr, 5*PAT_WIDTH/6.0, PAT_HEIGHT);
+ cairo_line_to (cr, PAT_WIDTH, PAT_HEIGHT);
+ cairo_line_to (cr, PAT_WIDTH, 5*PAT_HEIGHT/6.0);
+ cairo_set_source_rgb (cr, 1, 1, 0);
+ cairo_stroke (cr);
+
+ cairo_set_source_rgb (cr, 0.5, 0.5, 0.5);
+ cairo_set_line_width (cr, PAT_WIDTH/10.0);
+
+ cairo_move_to (cr, 0, PAT_HEIGHT/4.0);
+ cairo_line_to (cr, PAT_WIDTH, PAT_HEIGHT/4.0);
+ cairo_stroke (cr);
+
+ cairo_move_to (cr, PAT_WIDTH/4.0, 0);
+ cairo_line_to (cr, PAT_WIDTH/4.0, PAT_WIDTH);
+ cairo_stroke (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (rotated_clip,
+ "Test clipping with non identity pattern matrix",
+ "clip", /* keywords */
+ NULL, /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw)
diff --git a/test/rounded-rectangle-fill.c b/test/rounded-rectangle-fill.c
new file mode 100644
index 000000000..d211cf626
--- /dev/null
+++ b/test/rounded-rectangle-fill.c
@@ -0,0 +1,65 @@
+/*
+ * Copyright © 2009 Chris Wilson
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+#define SIZE 80
+
+/* A very simple test to exercise the scan rasterisers with constant regions. */
+
+static void
+rounded_rectangle (cairo_t *cr, int x, int y, int w, int h, int r)
+{
+ cairo_new_sub_path (cr);
+ cairo_arc (cr, x + r, y + r, r, M_PI, 3 * M_PI / 2);
+ cairo_arc (cr, x + w - r, y + r, r, 3 *M_PI / 2, 2 * M_PI);
+ cairo_arc (cr, x + w - r, y + h - r, r, 0, M_PI / 2);
+ cairo_arc (cr, x + r, y + h - r, r, M_PI / 2, M_PI);
+ cairo_close_path (cr);
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ /* Paint background white, then draw in black. */
+ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */
+ cairo_paint (cr);
+ cairo_set_source_rgb (cr, 0.0, 0.0, 0.0); /* black */
+
+ cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
+ rounded_rectangle (cr, 5, 5, width-10, height-10, 15);
+ rounded_rectangle (cr, 15, 15, width-30, height-30, 5);
+ cairo_fill (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (rounded_rectangle_fill,
+ "Tests handling of rounded rectangles, the UI designers favourite",
+ "fill, rounded-rectangle", /* keywords */
+ NULL, /* requirements */
+ SIZE, SIZE,
+ NULL, draw)
diff --git a/test/rounded-rectangle-stroke.c b/test/rounded-rectangle-stroke.c
new file mode 100644
index 000000000..22bc51557
--- /dev/null
+++ b/test/rounded-rectangle-stroke.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright © 2009 Chris Wilson
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+#define SIZE 80
+
+/* A very simple test to exercise the scan rasterisers with constant regions. */
+
+static void
+rounded_rectangle (cairo_t *cr, int x, int y, int w, int h, int r)
+{
+ cairo_new_sub_path (cr);
+ cairo_arc (cr, x + r, y + r, r, M_PI, 3 * M_PI / 2);
+ cairo_arc (cr, x + w - r, y + r, r, 3 *M_PI / 2, 2 * M_PI);
+ cairo_arc (cr, x + w - r, y + h - r, r, 0, M_PI / 2);
+ cairo_arc (cr, x + r, y + h - r, r, M_PI / 2, M_PI);
+ cairo_close_path (cr);
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ /* Paint background white, then draw in black. */
+ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */
+ cairo_paint (cr);
+ cairo_set_source_rgb (cr, 0.0, 0.0, 0.0); /* black */
+
+ cairo_set_line_width (cr, 10);
+ rounded_rectangle (cr, 10, 10, width-20, height-20, 10);
+ cairo_stroke (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (rounded_rectangle_stroke,
+ "Tests handling of rounded rectangles, the UI designers favourite",
+ "stroke, rounded-rectangle", /* keywords */
+ NULL, /* requirements */
+ SIZE, SIZE,
+ NULL, draw)
diff --git a/test/run-cairo-test-suite.sh b/test/run-cairo-test-suite.sh
new file mode 100755
index 000000000..567d2b14b
--- /dev/null
+++ b/test/run-cairo-test-suite.sh
@@ -0,0 +1,18 @@
+#!/bin/bash
+
+set -m
+
+if `which gnome-screensaver-command`; then
+ gnome-screensaver-command -i -n "cairo-test-suite" -r "Cairo needs to read back from the screen in order to test rendering to xlib" &
+ pid=$!
+
+ restore_screensaver() { kill $pid; }
+else
+ restore_screensaver() { :; }
+fi
+
+trap cleanup SIGINT SIGTERM
+
+./cairo-test-suite "$*"
+
+restore_screensaver
diff --git a/test/sample.c b/test/sample.c
new file mode 100644
index 000000000..caf68777e
--- /dev/null
+++ b/test/sample.c
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2012 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+/* Test the fidelity of the rasterisation, because Cairo is my favourite
+ * driver test suite.
+ */
+
+#define GENERATE_REFERENCE 0
+
+#define WIDTH 256
+#define HEIGHT 40
+
+#include "../src/cairo-fixed-type-private.h"
+#define PRECISION (1 << CAIRO_FIXED_FRAC_BITS)
+
+static cairo_test_status_t
+vertical (cairo_t *cr, int width, int height)
+{
+ int x;
+
+ cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
+ cairo_paint (cr);
+
+ cairo_set_source_rgba (cr, 1, 1, 1, 1);
+ for (x = -HEIGHT*PRECISION-2; x <= (WIDTH+HEIGHT)*PRECISION+2; x += 4) {
+ cairo_move_to (cr, x / (double)PRECISION - 2, -2);
+ cairo_rel_line_to (cr, 0, HEIGHT + 4);
+ }
+ cairo_set_line_width (cr, 2 / (double)PRECISION);
+ cairo_stroke (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+horizontal (cairo_t *cr, int width, int height)
+{
+ int x;
+
+ cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
+ cairo_paint (cr);
+
+ cairo_set_source_rgba (cr, 1, 1, 1, 1);
+ for (x = -HEIGHT*PRECISION-2; x <= (WIDTH+HEIGHT)*PRECISION+2; x += 4) {
+ cairo_move_to (cr, -2, x / (double)PRECISION - 2);
+ cairo_rel_line_to (cr, HEIGHT + 4, 0);
+ }
+ cairo_set_line_width (cr, 2 / (double)PRECISION);
+ cairo_stroke (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+diagonal (cairo_t *cr, int width, int height)
+{
+ int x;
+
+ cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
+ cairo_paint (cr);
+
+ cairo_set_source_rgba (cr, 1, 1, 1, 1);
+ for (x = -HEIGHT*PRECISION-2; x <= (WIDTH+HEIGHT)*PRECISION+2; x += 6) {
+ cairo_move_to (cr, x / (double)PRECISION - 2, -2);
+ cairo_rel_line_to (cr, HEIGHT + 4, HEIGHT + 4);
+ }
+ cairo_set_line_width (cr, 2 / (double)PRECISION);
+ cairo_stroke (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (sample_vertical,
+ "Check the fidelity of the rasterisation.",
+ NULL, /* keywords */
+ "target=raster slow", /* requirements */
+ WIDTH, HEIGHT,
+ NULL, vertical)
+
+CAIRO_TEST (sample_horizontal,
+ "Check the fidelity of the rasterisation.",
+ NULL, /* keywords */
+ "target=raster slow", /* requirements */
+ WIDTH, HEIGHT,
+ NULL, horizontal)
+
+CAIRO_TEST (sample_diagonal,
+ "Check the fidelity of the rasterisation.",
+ NULL, /* keywords */
+ "target=raster slow", /* requirements */
+ WIDTH, HEIGHT,
+ NULL, diagonal)
diff --git a/test/scale-down-source-surface-paint.c b/test/scale-down-source-surface-paint.c
new file mode 100644
index 000000000..8cf0e06f2
--- /dev/null
+++ b/test/scale-down-source-surface-paint.c
@@ -0,0 +1,65 @@
+/*
+ * Copyright © 2005,2007 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+#include "cairo-test.h"
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_surface_t *surface;
+ uint32_t data[16] = {
+ 0xffffffff, 0xffffffff, 0xffff0000, 0xffff0000,
+ 0xffffffff, 0xffffffff, 0xffff0000, 0xffff0000,
+
+ 0xff00ff00, 0xff00ff00, 0xff0000ff, 0xff0000ff,
+ 0xff00ff00, 0xff00ff00, 0xff0000ff, 0xff0000ff
+ };
+
+ /* First paint opaque background (black) so we don't need separate
+ * ARGB32 and RGB24 reference images. */
+ cairo_set_source_rgb (cr, 0, 0, 0); /* black */
+ cairo_paint (cr);
+
+ surface = cairo_image_surface_create_for_data ((unsigned char *) data,
+ CAIRO_FORMAT_RGB24, 4, 4, 16);
+
+ cairo_scale (cr, 0.5, 0.5);
+
+ cairo_set_source_surface (cr, surface, 4, 4);
+ cairo_pattern_set_filter (cairo_get_source (cr), CAIRO_FILTER_NEAREST);
+ cairo_paint (cr);
+
+ cairo_surface_finish (surface); /* data will go out of scope */
+ cairo_surface_destroy (surface);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (scale_down_source_surface_paint,
+ "Test call sequence: cairo_scale; cairo_set_source_surface; cairo_paint, with a scale < 1.0",
+ "paint, transform", /* keywords */
+ NULL, /* requirements */
+ 6, 6,
+ NULL, draw)
diff --git a/test/scale-offset-image.c b/test/scale-offset-image.c
new file mode 100644
index 000000000..7243a0669
--- /dev/null
+++ b/test/scale-offset-image.c
@@ -0,0 +1,143 @@
+/*
+ * Copyright 2008 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Chris Wilson not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Chris Wilson makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+/*
+ * Test case derived from the bug report by Michel Iwaniec:
+ * http://lists.cairographics.org/archives/cairo/2008-November/015660.html
+ */
+
+#include "cairo-test.h"
+
+static cairo_surface_t *
+create_source (cairo_surface_t *target, int width, int height)
+{
+ cairo_surface_t *similar;
+ cairo_t *cr;
+
+ similar = cairo_image_surface_create (CAIRO_FORMAT_RGB24,
+ width, height);
+ cr = cairo_create (similar);
+ cairo_surface_destroy (similar);
+
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_rectangle (cr,
+ width - 4, height - 4,
+ 2, 2);
+ cairo_fill (cr);
+ cairo_set_source_rgb (cr, 1, 0, 0);
+ cairo_rectangle (cr,
+ width - 2, height - 4,
+ 2, 2);
+ cairo_fill (cr);
+ cairo_set_source_rgb (cr, 0, 1, 0);
+ cairo_rectangle (cr,
+ width - 4, height - 2,
+ 2, 2);
+ cairo_fill (cr);
+ cairo_set_source_rgb (cr, 0, 0, 1);
+ cairo_rectangle (cr,
+ width - 2, height - 2,
+ 2, 2);
+ cairo_fill (cr);
+
+ similar = cairo_surface_reference (cairo_get_target (cr));
+ cairo_destroy (cr);
+
+ return similar;
+}
+
+static void
+draw_grid (cairo_t *cr, cairo_pattern_t *pattern, int dst_x, int dst_y)
+{
+ cairo_matrix_t m;
+
+ cairo_save (cr);
+ cairo_translate (cr, dst_x, dst_y);
+ cairo_scale (cr, 16, 16);
+ cairo_rotate (cr, 1);
+
+ cairo_matrix_init_translate (&m, 2560-4, 1280-4);
+ cairo_pattern_set_matrix (pattern, &m);
+ cairo_set_source (cr, pattern);
+ cairo_rectangle (cr, 0, 0, 4, 4);
+ cairo_fill (cr);
+
+ cairo_set_source_rgb (cr, .7, .7, .7);
+ cairo_set_line_width (cr, 1./16);
+ cairo_move_to (cr, 0, 0);
+ cairo_line_to (cr, 4, 0);
+ cairo_move_to (cr, 0, 2);
+ cairo_line_to (cr, 4, 2);
+ cairo_move_to (cr, 0, 4);
+ cairo_line_to (cr, 4, 4);
+ cairo_move_to (cr, 0, 0);
+ cairo_line_to (cr, 0, 4);
+ cairo_move_to (cr, 2, 0);
+ cairo_line_to (cr, 2, 4);
+ cairo_move_to (cr, 4, 0);
+ cairo_line_to (cr, 4, 4);
+ cairo_stroke (cr);
+
+ cairo_restore (cr);
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_surface_t *source;
+ cairo_pattern_t *pattern;
+
+ cairo_paint (cr);
+
+ source = create_source (cairo_get_target (cr), 2560, 1280);
+ pattern = cairo_pattern_create_for_surface (source);
+ cairo_surface_destroy (source);
+
+ cairo_pattern_set_filter (pattern, CAIRO_FILTER_NEAREST);
+ cairo_pattern_set_extend (pattern, CAIRO_EXTEND_NONE);
+
+ draw_grid (cr, pattern, 50, 0);
+ draw_grid (cr, pattern, 130, 0);
+ draw_grid (cr, pattern, 210, 0);
+ draw_grid (cr, pattern, 290, 0);
+
+ draw_grid (cr, pattern, 50, 230);
+ draw_grid (cr, pattern, 130, 230);
+ draw_grid (cr, pattern, 210, 230);
+ draw_grid (cr, pattern, 290, 230);
+
+ cairo_pattern_destroy (pattern);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+/* XFAIL: loss of precision converting a cairo matrix to */
+CAIRO_TEST (scale_offset_image,
+ "Tests drawing surfaces under various scales and transforms",
+ "surface, scale-offset", /* keywords */
+ NULL, /* requirements */
+ 320, 320,
+ NULL, draw)
+
diff --git a/test/scale-offset-similar.c b/test/scale-offset-similar.c
new file mode 100644
index 000000000..e9e6a2bbe
--- /dev/null
+++ b/test/scale-offset-similar.c
@@ -0,0 +1,143 @@
+/*
+ * Copyright 2008 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Chris Wilson not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Chris Wilson makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+/*
+ * Test case derived from the bug report by Michel Iwaniec:
+ * http://lists.cairographics.org/archives/cairo/2008-November/015660.html
+ */
+
+#include "cairo-test.h"
+
+static cairo_surface_t *
+create_source (cairo_surface_t *target, int width, int height)
+{
+ cairo_surface_t *similar;
+ cairo_t *cr;
+
+ similar = cairo_surface_create_similar (target,
+ CAIRO_CONTENT_COLOR,
+ width, height);
+ cr = cairo_create (similar);
+ cairo_surface_destroy (similar);
+
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_rectangle (cr,
+ width - 4, height - 4,
+ 2, 2);
+ cairo_fill (cr);
+ cairo_set_source_rgb (cr, 1, 0, 0);
+ cairo_rectangle (cr,
+ width - 2, height - 4,
+ 2, 2);
+ cairo_fill (cr);
+ cairo_set_source_rgb (cr, 0, 1, 0);
+ cairo_rectangle (cr,
+ width - 4, height - 2,
+ 2, 2);
+ cairo_fill (cr);
+ cairo_set_source_rgb (cr, 0, 0, 1);
+ cairo_rectangle (cr,
+ width - 2, height - 2,
+ 2, 2);
+ cairo_fill (cr);
+
+ similar = cairo_surface_reference (cairo_get_target (cr));
+ cairo_destroy (cr);
+
+ return similar;
+}
+
+static void
+draw_grid (cairo_t *cr, cairo_pattern_t *pattern, int dst_x, int dst_y)
+{
+ cairo_matrix_t m;
+
+ cairo_save (cr);
+ cairo_translate (cr, dst_x, dst_y);
+ cairo_scale (cr, 16, 16);
+ cairo_rotate (cr, 1);
+
+ cairo_matrix_init_translate (&m, 2560-4, 1280-4);
+ cairo_pattern_set_matrix (pattern, &m);
+ cairo_set_source (cr, pattern);
+ cairo_rectangle (cr, 0, 0, 4, 4);
+ cairo_fill (cr);
+
+ cairo_set_source_rgb (cr, .7, .7, .7);
+ cairo_set_line_width (cr, 1./16);
+ cairo_move_to (cr, 0, 0);
+ cairo_line_to (cr, 4, 0);
+ cairo_move_to (cr, 0, 2);
+ cairo_line_to (cr, 4, 2);
+ cairo_move_to (cr, 0, 4);
+ cairo_line_to (cr, 4, 4);
+ cairo_move_to (cr, 0, 0);
+ cairo_line_to (cr, 0, 4);
+ cairo_move_to (cr, 2, 0);
+ cairo_line_to (cr, 2, 4);
+ cairo_move_to (cr, 4, 0);
+ cairo_line_to (cr, 4, 4);
+ cairo_stroke (cr);
+
+ cairo_restore (cr);
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_surface_t *source;
+ cairo_pattern_t *pattern;
+
+ cairo_paint (cr);
+
+ source = create_source (cairo_get_target (cr), 2560, 1280);
+ pattern = cairo_pattern_create_for_surface (source);
+ cairo_surface_destroy (source);
+
+ cairo_pattern_set_filter (pattern, CAIRO_FILTER_NEAREST);
+ cairo_pattern_set_extend (pattern, CAIRO_EXTEND_NONE);
+
+ draw_grid (cr, pattern, 50, 0);
+ draw_grid (cr, pattern, 130, 0);
+ draw_grid (cr, pattern, 210, 0);
+ draw_grid (cr, pattern, 290, 0);
+
+ draw_grid (cr, pattern, 50, 230);
+ draw_grid (cr, pattern, 130, 230);
+ draw_grid (cr, pattern, 210, 230);
+ draw_grid (cr, pattern, 290, 230);
+
+ cairo_pattern_destroy (pattern);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (scale_offset_similar,
+ "Tests drawing surfaces under various scales and transforms",
+ "surface, scale-offset", /* keywords */
+ NULL, /* requirements */
+ 320, 320,
+ NULL, draw)
+
diff --git a/test/scale-source-surface-paint.c b/test/scale-source-surface-paint.c
new file mode 100644
index 000000000..0c0a3acd8
--- /dev/null
+++ b/test/scale-source-surface-paint.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright © 2005 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+#include "cairo-test.h"
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_surface_t *surface;
+ uint32_t data[16] = {
+ 0xffffffff, 0xffffffff, 0xffff0000, 0xffff0000,
+ 0xffffffff, 0xffffffff, 0xffff0000, 0xffff0000,
+
+ 0xff00ff00, 0xff00ff00, 0xff0000ff, 0xff0000ff,
+ 0xff00ff00, 0xff00ff00, 0xff0000ff, 0xff0000ff
+ };
+
+ surface = cairo_image_surface_create_for_data ((unsigned char *) data,
+ CAIRO_FORMAT_RGB24, 4, 4, 16);
+
+ cairo_scale (cr, 2, 2);
+
+ cairo_set_source_surface (cr, surface, 1 , 1);
+ cairo_pattern_set_filter (cairo_get_source (cr), CAIRO_FILTER_NEAREST);
+ cairo_paint (cr);
+
+ cairo_surface_finish (surface); /* data will go out of scope */
+ cairo_surface_destroy (surface);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (scale_source_surface_paint,
+ "Test call sequence: cairo_scale; cairo_set_source_surface; cairo_paint",
+ "paint, transform", /* keywords */
+ NULL, /* requirements */
+ 12, 12,
+ NULL, draw)
diff --git a/test/scaled-font-zero-matrix.c b/test/scaled-font-zero-matrix.c
new file mode 100644
index 000000000..d4f79a669
--- /dev/null
+++ b/test/scaled-font-zero-matrix.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright © 2008 Mozilla Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Mozilla Corporation not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Mozilla Corporation makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * MOZILLA CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL MOZILLA CORPORATION BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Jeff Muizelaar
+ */
+
+#include "cairo-test.h"
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_font_face_t *font_face;
+ cairo_font_options_t *font_options;
+ cairo_scaled_font_t *scaled_font;
+ cairo_matrix_t identity;
+ cairo_matrix_t zero;
+
+ cairo_matrix_init_identity(&identity);
+
+ zero = identity;
+ cairo_matrix_scale(&zero, 0, 0);
+
+ font_face = cairo_get_font_face (cr);
+ font_options = cairo_font_options_create ();
+ cairo_get_font_options (cr, font_options);
+ scaled_font = cairo_scaled_font_create (font_face,
+ &identity,
+ &zero,
+ font_options);
+ cairo_set_scaled_font (cr, scaled_font);
+ cairo_show_text (cr, "Hello");
+ cairo_scaled_font_destroy (scaled_font);
+ cairo_font_options_destroy (font_options);
+
+ return cairo_test_status_from_status (cairo_test_get_context (cr),
+ cairo_status(cr));
+}
+
+CAIRO_TEST (scaled_font_zero_matrix,
+ "Test that scaled fonts with a degenerate matrix work",
+ "zero, matrix, degenerate, scaled-font", /* keywords */
+ NULL, /* requirements */
+ 0, 0,
+ NULL, draw)
diff --git a/test/scarab.jpg b/test/scarab.jpg
new file mode 100644
index 000000000..6a66ff789
--- /dev/null
+++ b/test/scarab.jpg
Binary files differ
diff --git a/test/select-font-face.c b/test/select-font-face.c
new file mode 100644
index 000000000..ec4b27cf3
--- /dev/null
+++ b/test/select-font-face.c
@@ -0,0 +1,65 @@
+/*
+ * Copyright © 2006 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+#include "cairo-test.h"
+
+#define TEXT_SIZE 12
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ /* We draw in the default black, so paint white first. */
+ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */
+ cairo_paint (cr);
+
+ cairo_set_source_rgb (cr, 0, 0, 0); /* black */
+
+ cairo_set_font_size (cr, TEXT_SIZE);
+ cairo_move_to (cr, 0, TEXT_SIZE);
+
+ cairo_select_font_face (cr, CAIRO_TEST_FONT_FAMILY " Serif",
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_NORMAL);
+ cairo_show_text (cr, "i-am-serif");
+
+ cairo_select_font_face (cr, CAIRO_TEST_FONT_FAMILY " Sans",
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_NORMAL);
+ cairo_show_text (cr, " i-am-sans");
+
+ cairo_select_font_face (cr, CAIRO_TEST_FONT_FAMILY " Sans Mono",
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_NORMAL);
+ cairo_show_text (cr, " i-am-mono");
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (select_font_face,
+ "Tests using cairo_select_font_face to draw text in different faces",
+ "font", /* keywords */
+ NULL, /* requirements */
+ 192, TEXT_SIZE + 4,
+ NULL, draw)
diff --git a/test/select-font-no-show-text.c b/test/select-font-no-show-text.c
new file mode 100644
index 000000000..b2b47966f
--- /dev/null
+++ b/test/select-font-no-show-text.c
@@ -0,0 +1,59 @@
+/*
+ * Copyright © 2005 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl Worth <cworth@redhat.com>
+ */
+
+/* Bug history
+ *
+ * 2005-04-12 Carl Worth <cworth@cworth.org>
+ *
+ * I noticed that if we call cairo_select_font_face, but then do a
+ * cairo_destroy before ever drawing any text, then we get:
+ *
+ * *** glibc detected *** double free or corruption (fasttop): 0x083274d0 ***
+ * Aborted
+ *
+ * 2005-04-14 Owen Taylor <otaylor@redhat.com>
+ *
+ * Fixed... just a stray free().
+ */
+
+#include "cairo-test.h"
+#include <math.h>
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_select_font_face (cr, CAIRO_TEST_FONT_FAMILY " Sans",
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_BOLD);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (select_font_no_show_text,
+ "Test calling cairo_select_font_face but never drawing text.",
+ "font", /* keywords */
+ NULL, /* requirements */
+ 0, 0,
+ NULL, draw)
diff --git a/test/self-copy-overlap.c b/test/self-copy-overlap.c
new file mode 100644
index 000000000..6e3b39c91
--- /dev/null
+++ b/test/self-copy-overlap.c
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2008 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Chris Wilson not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Chris Wilson makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+/* Question: are patterns mutable? The answer depends on who you ask... */
+
+#include "cairo-test.h"
+
+/* This test is only interesting if the target has alpha */
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_set_source_rgba (cr, 0, 0, 0, .01);
+ cairo_paint (cr);
+
+ cairo_set_source_surface (cr, cairo_get_target (cr), 1, 1);
+ cairo_paint (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+/*
+ * XFAIL: vector surfaces take snapshot of patterns in contrast to the raster
+ * backends which don't. One solution would be to clone overlapping areas of
+ * dst/source, so patterns were effectively snapshotted across all backends.
+ */
+CAIRO_TEST (self_copy_overlap,
+ "Tests painting to itself using itself as the source"
+ "\nBackends treat this case inconsistently---vector backends are creating snapshots.",
+ "self-copy", /* keywords */
+ NULL, /* requirements */
+ 200, 200,
+ NULL, draw)
diff --git a/test/self-copy.c b/test/self-copy.c
new file mode 100644
index 000000000..bef02e98b
--- /dev/null
+++ b/test/self-copy.c
@@ -0,0 +1,84 @@
+/*
+ * Copyright © 2005 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Owen Taylor <otaylor@redhat.com>
+ */
+
+#include "cairo-test.h"
+#include <math.h>
+#include <stdio.h>
+
+#define SIZE 40
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_pattern_t *pattern;
+ cairo_matrix_t matrix;
+
+ /* Paint a diagonal division as a test image */
+ cairo_set_source_rgb (cr, 1, 1, 1); /* White */
+ cairo_paint (cr);
+
+ cairo_move_to (cr, SIZE, 0);
+ cairo_line_to (cr, SIZE, SIZE);
+ cairo_line_to (cr, 0, SIZE);
+
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ cairo_fill (cr);
+
+ /* Create a pattern with the target surface as the source,
+ * offset by SIZE/2
+ */
+ pattern = cairo_pattern_create_for_surface (cairo_get_group_target (cr));
+
+ cairo_matrix_init_translate (&matrix, - SIZE / 2, - SIZE / 2);
+ cairo_pattern_set_matrix (pattern, &matrix);
+
+ cairo_set_source (cr, pattern);
+ cairo_pattern_destroy (pattern);
+
+ /* Copy two rectangles from the upper-left quarter of the image to
+ * the lower right. It will work if we use cairo_fill(), but the
+ * cairo_clip() cairo_paint() combination fails because the clip
+ * on the surface as a destination affects it as the source as
+ * well.
+ */
+ cairo_rectangle (cr,
+ 2 * SIZE / 4, 2 * SIZE / 4,
+ SIZE / 4, SIZE / 4);
+ cairo_rectangle (cr,
+ 3 * SIZE / 4, 3 * SIZE / 4,
+ SIZE / 4, SIZE / 4);
+ cairo_clip (cr);
+ cairo_paint (cr);
+
+ return CAIRO_TEST_SUCCESS;
+
+}
+
+CAIRO_TEST (self_copy,
+ "Test copying from a surface to itself with a clip",
+ "paint", /* keywords */
+ NULL, /* requirements */
+ SIZE, SIZE,
+ NULL, draw)
diff --git a/test/self-intersecting.c b/test/self-intersecting.c
new file mode 100644
index 000000000..8053235ac
--- /dev/null
+++ b/test/self-intersecting.c
@@ -0,0 +1,87 @@
+/*
+ * Copyright © 2005 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+/* Bug history
+ *
+ * 2005-06-01 Carl Worth <cworth@cworth.org>
+ *
+ * There's a long-standing bug in that self-intersecting paths give
+ * an incorrect result when stroked. The problem is that the
+ * trapezoids are generated incrementally along the stroke and as
+ * such, are not disjoint. The errant intersections of these
+ * trapezoids then leads to overfilled pixels.
+ *
+ * The test belows first creates and fills a path. Then it creates a
+ * second path which has a stroked boundary identical to the first
+ * filled path. But the results of the two operations are
+ * different. The most obvious difference is in the central region
+ * where the entire path intersects itself. But notice that every
+ * time the path turns there are also errors on the inside of the
+ * turn, (since the subsequent trapezoids along the path intersect).
+ */
+
+#include "cairo-test.h"
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+ cairo_translate (cr, 1.0, 1.0);
+
+ cairo_set_source_rgb (cr, 1, 0, 0); /* red */
+
+ /* First draw the desired shape with a fill */
+ cairo_rectangle (cr, 0.5, 0.5, 4.0, 4.0);
+ cairo_rectangle (cr, 3.5, 3.5, 4.0, 4.0);
+ cairo_rectangle (cr, 3.5, 1.5, -2.0, 2.0);
+ cairo_rectangle (cr, 6.5, 4.5, -2.0, 2.0);
+
+ cairo_fill (cr);
+
+ /* Then try the same thing with a stroke */
+ cairo_translate (cr, 0, 10);
+ cairo_move_to (cr, 1.0, 1.0);
+ cairo_rel_line_to (cr, 3.0, 0.0);
+ cairo_rel_line_to (cr, 0.0, 6.0);
+ cairo_rel_line_to (cr, 3.0, 0.0);
+ cairo_rel_line_to (cr, 0.0, -3.0);
+ cairo_rel_line_to (cr, -6.0, 0.0);
+ cairo_close_path (cr);
+
+ cairo_set_line_width (cr, 1.0);
+ cairo_stroke (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (self_intersecting,
+ "Test strokes of self-intersecting paths"
+ "\nSelf-intersecting strokes are wrong due to incremental trapezoidization.",
+ "stroke, trap", /* keywords */
+ NULL, /* requirements */
+ 10, 20,
+ NULL, draw)
diff --git a/test/set-source.c b/test/set-source.c
new file mode 100644
index 000000000..7e54626a8
--- /dev/null
+++ b/test/set-source.c
@@ -0,0 +1,81 @@
+/*
+ * Copyright © 2005 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+#include "cairo-test.h"
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ int i;
+ uint32_t color = 0x8019334c;
+ cairo_surface_t *surface;
+ cairo_pattern_t *pattern;
+
+ surface = cairo_image_surface_create_for_data ((unsigned char *) &color,
+ CAIRO_FORMAT_ARGB32, 1, 1, 4);
+ pattern = cairo_pattern_create_for_surface (surface);
+ cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT);
+
+ /* Several different means of making mostly the same color (though
+ * we can't get anything but alpha==1.0 out of
+ * cairo_set_source_rgb. */
+ for (i=0; i < width; i++) {
+ switch (i) {
+ case 0:
+ cairo_set_source_rgb (cr, .6, .7, .8);
+ break;
+ case 1:
+ cairo_set_source_rgba (cr, .2, .4, .6, 0.5);
+ break;
+ case 2:
+#if WE_HAD_SUPPORT_FOR_PREMULTIPLIED
+ cairo_set_source_rgba_premultiplied (cr, .1, .2, .3, 0.5);
+#else
+ cairo_set_source_rgba (cr, .2, .4, .6, 0.5);
+#endif
+ break;
+ case 3:
+ default:
+ cairo_set_source (cr, pattern);
+ break;
+ }
+
+ cairo_rectangle (cr, i, 0, 1, height);
+ cairo_fill (cr);
+ }
+
+ cairo_pattern_destroy (pattern);
+ cairo_surface_finish (surface); /* data will go out of scope */
+ cairo_surface_destroy (surface);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (set_source,
+ "Tests calls to various set_source functions",
+ "api", /* keywords */
+ NULL, /* requirements */
+ 5, 5,
+ NULL, draw)
diff --git a/test/shape-general-convex.c b/test/shape-general-convex.c
new file mode 100644
index 000000000..b9241bb9f
--- /dev/null
+++ b/test/shape-general-convex.c
@@ -0,0 +1,88 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+/* A general convex shape with a twist. */
+
+#include "cairo-test.h"
+
+#define SIZE (100)
+#define PAD 4
+
+static void
+limacon (cairo_t *cr, double a, double b, double radius)
+{
+ int i;
+
+ cairo_save (cr);
+ cairo_translate (cr, PAD, 0);
+ for (i = 0; i < 360; i++) {
+ double theta = i * M_PI / 180;
+ double r = b + a * cos (theta);
+ double x = radius * r * cos (theta);
+ double y = radius * r * sin (theta);
+ cairo_line_to (cr, x, y);
+ }
+ cairo_close_path (cr);
+ cairo_restore (cr);
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+ cairo_save (cr);
+ cairo_translate (cr, 2*PAD, PAD);
+
+ cairo_translate (cr, SIZE/2, SIZE/2);
+ limacon (cr, 1, .5, SIZE/3); /* trivia, this is a trisectrix */
+
+ cairo_set_source_rgb (cr, 1, 0, 0);
+ cairo_fill_preserve (cr);
+
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ cairo_stroke (cr);
+
+ cairo_scale (cr, -1, 1);
+
+ limacon (cr, 1, .5, SIZE/3); /* trivia, this is a trisectrix */
+
+ cairo_set_source_rgb (cr, 0, 0, 1);
+ cairo_fill_preserve (cr);
+
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ cairo_stroke (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (shape_general_convex,
+ "A general shape that is not as convex as it first appears",
+ "fill,stroke", /* keywords */
+ NULL, /* requirements */
+ SIZE+4*PAD, SIZE+4*PAD,
+ NULL, draw)
diff --git a/test/shape-sierpinski.c b/test/shape-sierpinski.c
new file mode 100644
index 000000000..9d2017067
--- /dev/null
+++ b/test/shape-sierpinski.c
@@ -0,0 +1,85 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+/* I thought I spied a bug... */
+
+#include "cairo-test.h"
+
+#define WIDTH (1024)
+#define HEIGHT (600)
+
+static const double m_1_sqrt_3 = 0.577359269;
+
+static void
+T (cairo_t *cr, int size)
+{
+ cairo_move_to (cr, 0, 0);
+ cairo_line_to (cr, size, 0);
+ cairo_line_to (cr, size/2, size*m_1_sqrt_3);
+
+ size /= 2;
+ if (size >= 4) {
+ T (cr, size);
+ cairo_save (cr); {
+ cairo_translate (cr, size, 0);
+ T (cr, size);
+ } cairo_restore (cr);
+ cairo_save (cr); {
+ cairo_translate (cr, size/2, size*m_1_sqrt_3);
+ T (cr, size);
+ } cairo_restore (cr);
+ }
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+ cairo_translate (cr, 0, 8);
+
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ cairo_set_line_width (cr, 1.);
+
+ T (cr, WIDTH);
+
+ cairo_translate (cr, 0, 2*HEIGHT-16);
+ cairo_scale (cr, 1, -1);
+
+ T (cr, WIDTH);
+
+ cairo_stroke (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (shape_sierpinski,
+ "A fractal triangle",
+ "stroke", /* keywords */
+ NULL, /* requirements */
+ WIDTH, 2*HEIGHT,
+ NULL, draw)
diff --git a/test/show-glyphs-advance.c b/test/show-glyphs-advance.c
new file mode 100644
index 000000000..5fe9ec839
--- /dev/null
+++ b/test/show-glyphs-advance.c
@@ -0,0 +1,107 @@
+/*
+ * Copyright © 2006 Red Hat, Inc.
+ * Copyright © 2011 Andrea Canciani
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ * Andrea Canciani <ranma42@gmail.com>
+ */
+
+#include "cairo-test.h"
+
+static cairo_test_status_t
+get_glyph (const cairo_test_context_t *ctx,
+ cairo_scaled_font_t *scaled_font,
+ const char *utf8,
+ cairo_glyph_t *glyph)
+{
+ cairo_glyph_t *text_to_glyphs;
+ cairo_status_t status;
+ int i;
+
+ text_to_glyphs = glyph;
+ i = 1;
+ status = cairo_scaled_font_text_to_glyphs (scaled_font,
+ 0, 0,
+ utf8, -1,
+ &text_to_glyphs, &i,
+ NULL, NULL,
+ 0);
+ if (status != CAIRO_STATUS_SUCCESS)
+ return cairo_test_status_from_status (ctx, status);
+
+ if (text_to_glyphs != glyph) {
+ *glyph = text_to_glyphs[0];
+ cairo_glyph_free (text_to_glyphs);
+ }
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static const char *characters[] = { "A", "B", "C", "D" };
+
+#define NUM_CHARS ARRAY_LENGTH (characters)
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ const cairo_test_context_t *ctx = cairo_test_get_context (cr);
+ cairo_scaled_font_t *scaled_font;
+ cairo_glyph_t *glyphs = xmalloc (NUM_CHARS * sizeof (cairo_glyph_t));
+ int i;
+ cairo_status_t status;
+
+ /* Paint white background. */
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+ scaled_font = cairo_get_scaled_font (cr);
+
+ for (i = 0; i < NUM_CHARS; i++) {
+ status = get_glyph (ctx, scaled_font, characters[i], &glyphs[i]);
+ if (status)
+ goto BAIL;
+
+ glyphs[i].x = 10.0 + 10.0 * (i % 2);
+ glyphs[i].y = 20.0 + 10.0 * (i / 2);
+ }
+
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ cairo_show_glyphs (cr, glyphs, 4);
+
+ cairo_translate (cr, 40., 20.);
+ cairo_rotate (cr, M_PI / 4.);
+
+ cairo_show_glyphs (cr, glyphs, NUM_CHARS);
+
+ BAIL:
+ free(glyphs);
+
+ return status;
+}
+
+CAIRO_TEST (show_glyphs_advance,
+ "Test that glyph advances work as expected along both axes",
+ "text, matrix", /* keywords */
+ NULL, /* requirements */
+ 64, 64,
+ NULL, draw)
diff --git a/test/show-glyphs-many.c b/test/show-glyphs-many.c
new file mode 100644
index 000000000..f689fe080
--- /dev/null
+++ b/test/show-glyphs-many.c
@@ -0,0 +1,176 @@
+/*
+ * Copyright © 2006 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+#include "cairo-test.h"
+
+#include <string.h>
+
+/* Bug history
+ *
+ * 2006-01-07 Jon Hellan <hellan@acm.org>
+ *
+ * Jon opened the following bug report:
+ *
+ * _XError from XRenderCompositeText8
+ * https://bugs.freedesktop.org/show_bug.cgi?id=5528
+ *
+ * 2006-03-02 Carl Worth <cworth@cworth.org>
+ *
+ * I wrote this test case to demonstrate the bug.
+ *
+ * Approach:
+ *
+ * Draw 65535 glyphs white-on-white all on top of each other.
+ *
+ * Rationale:
+ *
+ * The number 65535 comes from the original bug report.
+ *
+ * I would use cairo_show_text with a long string of 'x's say,
+ * but then the surface would need to be enormous to contain
+ * them. A smaller surface could be used, but I fear that at some
+ * point the off-surface glyph drawing would be optimized away
+ * and not exercise the bug.
+ *
+ * So, to keep the surface size under control, I use
+ * cairo_show_glyphs which allows me to place the glyphs all on
+ * top of each other. But, since cairo doesn't provide any
+ * character-to-glyphs mapping, I can't get a reliable glyph
+ * index (for character 'x' for example). So I just "guess" a
+ * glyph index and use white-on-white drawing to ignore the
+ * result. (I don't care what's drawn---I just want to ensure
+ * that things don't crash.)
+ *
+ * Status: I replicated bug. The largest value of NUM_GLYPHS for
+ * which I saw success is 21842.
+ *
+ * 2008-30-08 Chris Wilson <chris@chris-wilson.co.uk>
+ * This is also a valid test case for:
+ *
+ * Bug 5913 crash on overlong string
+ * https://bugs.freedesktop.org/show_bug.cgi?id=5913
+ *
+ * which is still causing a crash in the Xlib backend - presumably, just
+ * a miscalculation of the length of the available request.
+ */
+
+#define TEXT_SIZE 12
+#define NUM_GLYPHS 65535
+
+static cairo_test_status_t
+get_glyph (const cairo_test_context_t *ctx,
+ cairo_scaled_font_t *scaled_font,
+ const char *utf8,
+ cairo_glyph_t *glyph)
+{
+ cairo_glyph_t *text_to_glyphs;
+ cairo_status_t status;
+ int i;
+
+ text_to_glyphs = glyph;
+ i = 1;
+ status = cairo_scaled_font_text_to_glyphs (scaled_font,
+ 0, 0,
+ utf8, -1,
+ &text_to_glyphs, &i,
+ NULL, NULL,
+ 0);
+ if (status != CAIRO_STATUS_SUCCESS)
+ return cairo_test_status_from_status (ctx, status);
+
+ if (text_to_glyphs != glyph) {
+ *glyph = text_to_glyphs[0];
+ cairo_glyph_free (text_to_glyphs);
+ }
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ const cairo_test_context_t *ctx = cairo_test_get_context (cr);
+ cairo_glyph_t *glyphs = xmalloc (NUM_GLYPHS * sizeof (cairo_glyph_t));
+ cairo_scaled_font_t *scaled_font;
+ const char *characters[] = { /* try to exercise different widths of index */
+ "m", /* Latin letter m, index=0x50 */
+ "μ", /* Greek letter mu, index=0x349 */
+ NULL,
+ }, **utf8;
+ int i, j;
+ cairo_status_t status;
+
+ /* Paint white background. */
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+ cairo_select_font_face (cr, "Sans",
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_NORMAL);
+ cairo_set_font_size (cr, TEXT_SIZE);
+ scaled_font = cairo_get_scaled_font (cr);
+
+ for (utf8 = characters; *utf8 != NULL; utf8++) {
+ status = get_glyph (ctx, scaled_font, *utf8, &glyphs[0]);
+ if (status)
+ goto BAIL;
+
+ if (glyphs[0].index) {
+ glyphs[0].x = 1.0;
+ glyphs[0].y = height - 1;
+ for (i=1; i < NUM_GLYPHS; i++)
+ glyphs[i] = glyphs[0];
+
+ cairo_show_glyphs (cr, glyphs, NUM_GLYPHS);
+ }
+ }
+
+ /* we can pack ~21k 1-byte glyphs into a single XRenderCompositeGlyphs8 */
+ status = get_glyph (ctx, scaled_font, "m", &glyphs[0]);
+ if (status)
+ goto BAIL;
+ for (i=1; i < 21500; i++)
+ glyphs[i] = glyphs[0];
+ /* so check expanding the current 1-byte request for 2-byte glyphs */
+ status = get_glyph (ctx, scaled_font, "μ", &glyphs[i]);
+ if (status)
+ goto BAIL;
+ for (j=i+1; j < NUM_GLYPHS; j++)
+ glyphs[j] = glyphs[i];
+
+ cairo_show_glyphs (cr, glyphs, NUM_GLYPHS);
+
+ BAIL:
+ free(glyphs);
+
+ return status;
+}
+
+CAIRO_TEST (show_glyphs_many,
+ "Test that cairo_show_glyphs works when handed 'many' glyphs",
+ "text, stress", /* keywords */
+ NULL, /* requirements */
+ 9, 11,
+ NULL, draw)
diff --git a/test/show-text-current-point.c b/test/show-text-current-point.c
new file mode 100644
index 000000000..2fe32a82d
--- /dev/null
+++ b/test/show-text-current-point.c
@@ -0,0 +1,59 @@
+/*
+ * Copyright © 2005 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+#include "cairo-test.h"
+
+#define TEXT_SIZE 12
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ /* We draw in the default black, so paint white first. */
+ cairo_save (cr);
+ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */
+ cairo_paint (cr);
+ cairo_restore (cr);
+
+ cairo_select_font_face (cr, CAIRO_TEST_FONT_FAMILY " Sans",
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_NORMAL);
+ cairo_set_font_size (cr, TEXT_SIZE);
+
+ cairo_set_source_rgb (cr, 0, 0, 0); /* black */
+
+ cairo_move_to (cr, 0, TEXT_SIZE);
+ cairo_show_text (cr, "Hello from the ");
+ cairo_show_text (cr, "show-text-current-point");
+ cairo_show_text (cr, " test.");
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (show_text_current_point,
+ "Test that cairo_show_text adjusts the current point properly",
+ "text, api", /* keywords */
+ NULL, /* requirements */
+ 263, TEXT_SIZE + 4,
+ NULL, draw)
diff --git a/test/simple.c b/test/simple.c
new file mode 100644
index 000000000..7ec8a9ac5
--- /dev/null
+++ b/test/simple.c
@@ -0,0 +1,347 @@
+/*
+ * Copyright 2014 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+/* Test the fidelity of the rasterisation, because Cairo is my favourite
+ * driver test suite.
+ */
+
+#define GENERATE_REFERENCE 0
+
+#include "../src/cairo-fixed-type-private.h"
+
+#if GENERATE_REFERENCE
+#include <assert.h>
+struct coverage {
+ int width, height;
+ struct {
+ int uncovered_area;
+ int covered_height;
+ } cells[0];
+};
+
+static int pfloor (int v)
+{
+ return v >> CAIRO_FIXED_FRAC_BITS;
+}
+
+static int pfrac (int v)
+{
+ return v & ((1 << CAIRO_FIXED_FRAC_BITS) - 1);
+}
+
+static void add_edge (struct coverage *coverage,
+ int x1, int y1, int x2, int y2,
+ int sign)
+{
+ int dx, dy;
+ int dxdy_quo, dxdy_rem;
+ int xq, xr;
+ int y, t;
+
+ if (y2 < y1) {
+ t = y1;
+ y1 = y2;
+ y2 = t;
+
+ t = x1;
+ x1 = x2;
+ x2 = t;
+
+ sign = -sign;
+ }
+
+ dx = x2 - x1;
+ dy = y2 - y1;
+ if (dy == 0)
+ return;
+
+ dy *= 2;
+
+ dxdy_quo = 2*dx / dy;
+ dxdy_rem = 2*dx % dy;
+
+ xq = x1 + dxdy_quo / 2;
+ xr = dxdy_rem / 2;
+ if (xr < 0) {
+ xq--;
+ xr += dy;
+ }
+
+ for (y = MAX(0, y1); y < MIN(y2, 256*coverage->height); y++) {
+ int x = xq + (xr >= dy/2);
+
+ if (x < 256*coverage->width) {
+ int i = pfloor (y) * coverage->width;
+ if (x > 0) {
+ i += pfloor (x);
+ coverage->cells[i].uncovered_area += sign * pfrac(x);
+ }
+ coverage->cells[i].covered_height += sign;
+ }
+
+ xq += dxdy_quo;
+ xr += dxdy_rem;
+ if (xr < 0) {
+ xq--;
+ xr += dy;
+ } else if (xr >= dy) {
+ xq++;
+ xr -= dy;
+ }
+ }
+}
+
+static struct coverage *
+coverage_create (int width, int height)
+{
+ int size;
+ struct coverage *c;
+
+ size = sizeof (struct coverage);
+ size += width * height * sizeof (int) * 2;
+
+ c = malloc (size);
+ if (c == NULL)
+ return c;
+
+ memset(c, 0, size);
+ c->width = width;
+ c->height = height;
+
+ return c;
+}
+
+static cairo_surface_t *
+coverage_to_alpha (struct coverage *c)
+{
+ cairo_surface_t *image;
+ uint8_t *data;
+ int x, y, stride;
+
+ image = cairo_image_surface_create (CAIRO_FORMAT_A8, c->width, c->height);
+
+ data = cairo_image_surface_get_data (image);
+ stride = cairo_image_surface_get_stride (image);
+
+ cairo_surface_flush (image);
+ for (y = 0; y < c->height; y++) {
+ uint8_t *row = data + y *stride;
+ int cover = 0;
+ for (x = 0; x < c->width; x++) {
+ int v = y*c->width + x;
+
+ cover += c->cells[v].covered_height * 256;
+ v = cover - c->cells[v].uncovered_area;
+
+ v /= 256;
+ if (v < 0)
+ v = -v;
+ row[x] = v - (v >> 8);
+ }
+ }
+ cairo_surface_mark_dirty (image);
+
+ free (c);
+ return image;
+}
+#endif
+
+static cairo_test_status_t
+edge (cairo_t *cr, int width, int height)
+{
+ cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
+ cairo_paint (cr);
+
+ cairo_set_operator (cr, CAIRO_OPERATOR_ADD);
+
+#if GENERATE_REFERENCE
+ {
+ struct coverage *c;
+ cairo_surface_t *mask;
+
+ cairo_set_source_rgb (cr, 1, 0, 0);
+
+ c = coverage_create (width, height);
+ add_edge (c, 128*256, 129*256, 129*256, 1*256, 1);
+ add_edge (c, 128*256, 129*256, 128*256, 131*256, -1);
+ add_edge (c, 128*256, 131*256, 129*256, 259*256, -1);
+ add_edge (c, 130*256, 129*256, 129*256, 1*256, -1);
+ add_edge (c, 130*256, 129*256, 130*256, 131*256, 1);
+ add_edge (c, 130*256, 131*256, 129*256, 259*256, 1);
+ mask = coverage_to_alpha (c);
+ cairo_mask_surface (cr, mask, 0, 0);
+ cairo_surface_destroy (mask);
+
+ c = coverage_create (width, height);
+ add_edge (c, 128*256/2, 129*256/2, 129*256/2, 1*256/2, 1);
+ add_edge (c, 128*256/2, 129*256/2, 128*256/2, 131*256/2, -1);
+ add_edge (c, 128*256/2, 131*256/2, 129*256/2, 259*256/2, -1);
+ add_edge (c, 130*256/2, 129*256/2, 129*256/2, 1*256/2, -1);
+ add_edge (c, 130*256/2, 129*256/2, 130*256/2, 131*256/2, 1);
+ add_edge (c, 130*256/2, 131*256/2, 129*256/2, 259*256/2, 1);
+ mask = coverage_to_alpha (c);
+ cairo_mask_surface (cr, mask, 0, 0);
+ cairo_surface_destroy (mask);
+
+ c = coverage_create (width, height);
+ add_edge (c, (192-2)*256, 129*256, 192*256, 1*256, 1);
+ add_edge (c, (192-2)*256, 129*256, (192-2)*256, 131*256, -1);
+ add_edge (c, (192-2)*256, 131*256, 192*256, 259*256, -1);
+ add_edge (c, (192+2)*256, 129*256, 192*256, 1*256, -1);
+ add_edge (c, (192+2)*256, 129*256, (192+2)*256, 131*256, 1);
+ add_edge (c, (192+2)*256, 131*256, 192*256, 259*256, 1);
+ mask = coverage_to_alpha (c);
+ cairo_mask_surface (cr, mask, 0, 0);
+ cairo_surface_destroy (mask);
+
+ c = coverage_create (width, height);
+ add_edge (c, (256-4)*256, 129*256, 256*256, 1*256, 1);
+ add_edge (c, (256-4)*256, 129*256, (256-4)*256, 131*256, -1);
+ add_edge (c, (256-4)*256, 131*256, 256*256, 259*256, -1);
+ add_edge (c, (256+4)*256, 129*256, 256*256, 1*256, -1);
+ add_edge (c, (256+4)*256, 129*256, (256+4)*256, 131*256, 1);
+ add_edge (c, (256+4)*256, 131*256, 256*256, 259*256, 1);
+ mask = coverage_to_alpha (c);
+ cairo_mask_surface (cr, mask, 0, 0);
+ cairo_surface_destroy (mask);
+
+ cairo_set_source_rgb (cr, 0, 1, 0);
+
+ c = coverage_create (width, height);
+ add_edge (c, 1*256, 129*256, 129*256, 128*256, 1);
+ add_edge (c, 131*256, 128*256, 259*256, 129*256, 1);
+ add_edge (c, 1*256, 129*256, 129*256, 130*256, -1);
+ add_edge (c, 131*256, 130*256, 259*256, 129*256, -1);
+ mask = coverage_to_alpha (c);
+ cairo_mask_surface (cr, mask, 0, 0);
+ cairo_surface_destroy (mask);
+
+ c = coverage_create (width, height);
+ add_edge (c, 1*256/2, 129*256/2, 129*256/2, 128*256/2, 1);
+ add_edge (c, 131*256/2, 128*256/2, 259*256/2, 129*256/2, 1);
+ add_edge (c, 1*256/2, 129*256/2, 129*256/2, 130*256/2, -1);
+ add_edge (c, 131*256/2, 130*256/2, 259*256/2, 129*256/2, -1);
+ mask = coverage_to_alpha (c);
+ cairo_mask_surface (cr, mask, 0, 0);
+ cairo_surface_destroy (mask);
+
+ c = coverage_create (width, height);
+ add_edge (c, 1*256, (192-0)*256, 129*256, (192-2)*256, 1);
+ add_edge (c, 131*256, (192-2)*256, 259*256, (192-0)*256, 1);
+ add_edge (c, 1*256, (192+0)*256, 129*256, (192+2)*256, -1);
+ add_edge (c, 131*256, (192+2)*256, 259*256, (192+0)*256, -1);
+ mask = coverage_to_alpha (c);
+ cairo_mask_surface (cr, mask, 0, 0);
+ cairo_surface_destroy (mask);
+
+ c = coverage_create (width, height);
+ add_edge (c, 1*256, (256-0)*256, 129*256, (256-4)*256, 1);
+ add_edge (c, 131*256, (256-4)*256, 259*256, (256-0)*256, 1);
+ add_edge (c, 1*256, (256+0)*256, 129*256, (256+4)*256, -1);
+ add_edge (c, 131*256, (256+4)*256, 259*256, (256+0)*256, -1);
+ mask = coverage_to_alpha (c);
+ cairo_mask_surface (cr, mask, 0, 0);
+ cairo_surface_destroy (mask);
+ }
+#else
+ cairo_set_source_rgb (cr, 1, 0, 0);
+ cairo_move_to (cr, 129, 1);
+ cairo_line_to (cr, 128, 129);
+ cairo_line_to (cr, 128, 131);
+ cairo_line_to (cr, 129, 259);
+ cairo_line_to (cr, 130, 131);
+ cairo_line_to (cr, 130, 129);
+ cairo_fill (cr);
+
+ cairo_move_to (cr, 129/2., 1/2.);
+ cairo_line_to (cr, 128/2., 129/2.);
+ cairo_line_to (cr, 128/2., 131/2.);
+ cairo_line_to (cr, 129/2., 259/2.);
+ cairo_line_to (cr, 130/2., 131/2.);
+ cairo_line_to (cr, 130/2., 129/2.);
+ cairo_fill (cr);
+
+ cairo_move_to (cr, 192, 1);
+ cairo_line_to (cr, 192-2, 129);
+ cairo_line_to (cr, 192-2, 131);
+ cairo_line_to (cr, 192, 259);
+ cairo_line_to (cr, 192+2, 131);
+ cairo_line_to (cr, 192+2, 129);
+ cairo_fill (cr);
+
+ cairo_move_to (cr, 256, 1);
+ cairo_line_to (cr, 256-4, 129);
+ cairo_line_to (cr, 256-4, 131);
+ cairo_line_to (cr, 256, 259);
+ cairo_line_to (cr, 256+4, 131);
+ cairo_line_to (cr, 256+4, 129);
+ cairo_fill (cr);
+
+ cairo_set_source_rgb (cr, 0, 1, 0);
+ cairo_move_to (cr, 1, 129);
+ cairo_line_to (cr, 129, 128);
+ cairo_line_to (cr, 131, 128);
+ cairo_line_to (cr, 259, 129);
+ cairo_line_to (cr, 131, 130);
+ cairo_line_to (cr, 129, 130);
+ cairo_fill (cr);
+
+ cairo_move_to (cr, 1/2., 129/2.);
+ cairo_line_to (cr, 129/2., 128/2.);
+ cairo_line_to (cr, 131/2., 128/2.);
+ cairo_line_to (cr, 259/2., 129/2.);
+ cairo_line_to (cr, 131/2., 130/2.);
+ cairo_line_to (cr, 129/2., 130/2.);
+ cairo_fill (cr);
+
+ cairo_move_to (cr, 1, 192);
+ cairo_line_to (cr, 129, 192-2);
+ cairo_line_to (cr, 131, 192-2);
+ cairo_line_to (cr, 259, 192);
+ cairo_line_to (cr, 131, 192+2);
+ cairo_line_to (cr, 129, 192+2);
+ cairo_fill (cr);
+
+ cairo_move_to (cr, 1, 256);
+ cairo_line_to (cr, 129, 256-4);
+ cairo_line_to (cr, 131, 256-4);
+ cairo_line_to (cr, 259, 256);
+ cairo_line_to (cr, 131, 256+4);
+ cairo_line_to (cr, 129, 256+4);
+ cairo_fill (cr);
+#endif
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (simple_edge,
+ "Check the fidelity of the rasterisation.",
+ NULL, /* keywords */
+ "target=raster", /* requirements */
+ 260, 260,
+ NULL, edge)
diff --git a/test/skew-extreme.c b/test/skew-extreme.c
new file mode 100644
index 000000000..69299a86c
--- /dev/null
+++ b/test/skew-extreme.c
@@ -0,0 +1,118 @@
+/*
+ * Copyright © 2007 Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Carl Worth <cworth@cworth.org>
+ */
+
+#include "cairo-test.h"
+
+/* This test case is designed to exercise the following bug:
+ *
+ * Skew transforms were broken by the cairo update in December
+ * https://bugzilla.mozilla.org/show_bug.cgi?id=373632
+ *
+ * What's happening is that the rectangle is being skewed into the
+ * following shape:
+ *
+ * a__b
+ * \ \
+ * \ \
+ * \ \
+ * \ \
+ * \ \
+ * d\_\c
+ *
+ * and the bug is that _cairo_traps_tessellate_convex_quad is
+ * comparing b.x as less then d.x and therfore determining that the bc
+ * edge is left of the ad edge. The fix is simply to compare c.x to
+ * d.x instead of b.x to d.x .
+ */
+
+#define PAD 2
+#define LINE_WIDTH 10
+#define LINE_LENGTH (2 * LINE_WIDTH)
+#define SKEW_FACTOR 5.0
+#define WIDTH (PAD + (LINE_LENGTH * SKEW_FACTOR) + LINE_WIDTH + PAD)
+#define HEIGHT (PAD + LINE_WIDTH + (LINE_LENGTH * SKEW_FACTOR) + LINE_WIDTH + PAD)
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ /* We draw in the default black, so paint white first. */
+ cairo_save (cr);
+ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */
+ cairo_paint (cr);
+ cairo_restore (cr);
+
+ cairo_translate (cr, PAD, PAD);
+
+ cairo_set_line_width (cr, LINE_WIDTH);
+ cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT);
+
+ cairo_save (cr);
+ {
+ cairo_matrix_t skew_x = {
+ 1.0, 0.0,
+ SKEW_FACTOR, 1.0,
+ 0.0, 0.0
+ };
+
+ cairo_translate (cr, LINE_WIDTH / 2.0, 0.0);
+
+ cairo_transform (cr, &skew_x);
+
+ cairo_move_to (cr, 0.0, 0.0);
+ cairo_line_to (cr, 0.0, LINE_LENGTH);
+ cairo_stroke (cr);
+ }
+ cairo_restore (cr);
+
+ cairo_translate (cr, 0.0, LINE_WIDTH);
+
+ cairo_save (cr);
+ {
+ cairo_matrix_t skew_y = {
+ 1.0, SKEW_FACTOR,
+ 0.0, 1.0,
+ 0.0, 0.0
+ };
+
+ cairo_translate (cr, 0.0, LINE_WIDTH / 2.0);
+
+ cairo_transform (cr, &skew_y);
+
+ cairo_move_to (cr, 0.0, 0.0);
+ cairo_line_to (cr, LINE_LENGTH, 0.0);
+ cairo_stroke (cr);
+ }
+ cairo_restore (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (skew_extreme,
+ "Test cases of extreme skew.",
+ "transform, stroke", /* keywords */
+ NULL, /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw)
diff --git a/test/smask-fill.c b/test/smask-fill.c
new file mode 100644
index 000000000..cb3861036
--- /dev/null
+++ b/test/smask-fill.c
@@ -0,0 +1,73 @@
+/*
+ * Copyright © 2008 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Chris Wilson not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Chris Wilson makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_surface_t *mask;
+ cairo_pattern_t *pattern;
+ cairo_t *cr2;
+
+ cairo_set_source_rgb (cr, 0, 0, 1.0);
+ cairo_paint (cr);
+
+ mask = cairo_surface_create_similar (cairo_get_group_target (cr),
+ CAIRO_CONTENT_ALPHA,
+ width, height);
+ cr2 = cairo_create (mask);
+ cairo_surface_destroy (mask);
+
+ cairo_save (cr2); {
+ cairo_set_operator (cr2, CAIRO_OPERATOR_CLEAR);
+ cairo_paint (cr2);
+ } cairo_restore (cr2);
+
+ pattern = cairo_pattern_create_linear (0, 0, width, height);
+ cairo_pattern_add_color_stop_rgba (pattern, 0.00, 0., 0., 0., 0.);
+ cairo_pattern_add_color_stop_rgba (pattern, 0.25, 1., 1., 1., 1.);
+ cairo_pattern_add_color_stop_rgba (pattern, 0.50, 1., 1., 1., .5);
+ cairo_pattern_add_color_stop_rgba (pattern, 0.75, 1., 1., 1., 1.);
+ cairo_pattern_add_color_stop_rgba (pattern, 1.00, 0., 0., 0., 0.);
+ cairo_set_source (cr2, pattern);
+ cairo_pattern_destroy (pattern);
+
+ cairo_arc (cr2, 0.5 * width, 0.5 * height, 0.45 * height, 0, 2 * M_PI);
+ cairo_fill (cr2);
+
+ cairo_set_source_rgb (cr, 1.0, 0, 0);
+ cairo_mask_surface (cr, cairo_get_target (cr2), 0, 0);
+ cairo_destroy (cr2);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (smask_fill,
+ "Test the support of \"soft\" masks with fills",
+ "smask, fill", /* keywords */
+ NULL, /* requirements */
+ 60, 60,
+ NULL, draw)
diff --git a/test/smask-image-mask.c b/test/smask-image-mask.c
new file mode 100644
index 000000000..3d8b5d5a8
--- /dev/null
+++ b/test/smask-image-mask.c
@@ -0,0 +1,85 @@
+/*
+ * Copyright © 2008 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Chris Wilson not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Chris Wilson makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ uint32_t data[] = {
+ 0xaa000000, 0x55000000,
+ 0x55000000, 0xaa000000,
+ };
+
+ cairo_surface_t *mask, *mask2;
+ cairo_pattern_t *pattern;
+ cairo_t *cr2;
+
+ cairo_set_source_rgb (cr, 0, 0, 1.0);
+ cairo_paint (cr);
+
+ mask = cairo_surface_create_similar (cairo_get_group_target (cr),
+ CAIRO_CONTENT_ALPHA,
+ width, height);
+ cr2 = cairo_create (mask);
+ cairo_surface_destroy (mask);
+
+ cairo_save (cr2); {
+ cairo_set_operator (cr2, CAIRO_OPERATOR_CLEAR);
+ cairo_paint (cr2);
+ } cairo_restore (cr2);
+
+ pattern = cairo_pattern_create_linear (0, 0, width, height);
+ cairo_pattern_add_color_stop_rgba (pattern, 0.00, 0., 0., 0., 0.);
+ cairo_pattern_add_color_stop_rgba (pattern, 0.25, 1., 1., 1., 1.);
+ cairo_pattern_add_color_stop_rgba (pattern, 0.50, 1., 1., 1., .5);
+ cairo_pattern_add_color_stop_rgba (pattern, 0.75, 1., 1., 1., 1.);
+ cairo_pattern_add_color_stop_rgba (pattern, 1.00, 0., 0., 0., 0.);
+ cairo_set_source (cr2, pattern);
+ cairo_pattern_destroy (pattern);
+
+ mask2 = cairo_image_surface_create_for_data ((unsigned char *) data,
+ CAIRO_FORMAT_ARGB32, 2, 2, 8);
+ pattern = cairo_pattern_create_for_surface (mask2);
+ cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT);
+ cairo_mask (cr2, pattern);
+ cairo_pattern_destroy (pattern);
+
+ cairo_set_source_rgb (cr, 1.0, 0, 0);
+ cairo_mask_surface (cr, cairo_get_target (cr2), 0, 0);
+ cairo_destroy (cr2);
+
+ cairo_surface_finish (mask2); /* data will go out of scope */
+ cairo_surface_destroy (mask2);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (smask_image_mask,
+ "Test the support of \"soft\" masks with a secondary image mask",
+ "smask, image", /* keywords */
+ NULL, /* requirements */
+ 60, 60,
+ NULL, draw)
diff --git a/test/smask-mask.c b/test/smask-mask.c
new file mode 100644
index 000000000..11cff82ff
--- /dev/null
+++ b/test/smask-mask.c
@@ -0,0 +1,96 @@
+/*
+ * Copyright © 2008 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Chris Wilson not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Chris Wilson makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_surface_t *mask;
+ cairo_pattern_t *pattern;
+ cairo_t *cr2, *cr3;
+
+ cairo_set_source_rgb (cr, 0, 0, 1.0);
+ cairo_paint (cr);
+
+ mask = cairo_surface_create_similar (cairo_get_group_target (cr),
+ CAIRO_CONTENT_ALPHA,
+ width, height);
+ cr2 = cairo_create (mask);
+ cairo_surface_destroy (mask);
+
+ mask = cairo_surface_create_similar (cairo_get_group_target (cr2),
+ CAIRO_CONTENT_ALPHA,
+ width, height);
+ cr3 = cairo_create (mask);
+ cairo_surface_destroy (mask);
+
+ cairo_save (cr3); {
+ cairo_set_operator (cr3, CAIRO_OPERATOR_CLEAR);
+ cairo_paint (cr3);
+ } cairo_restore (cr3);
+
+ pattern = cairo_pattern_create_linear (0, 0, width, height);
+ cairo_pattern_add_color_stop_rgba (pattern, 0.00, 0., 0., 0., 0.);
+ cairo_pattern_add_color_stop_rgba (pattern, 0.25, 1., 1., 1., 1.);
+ cairo_pattern_add_color_stop_rgba (pattern, 0.50, 1., 1., 1., .5);
+ cairo_pattern_add_color_stop_rgba (pattern, 0.75, 1., 1., 1., 1.);
+ cairo_pattern_add_color_stop_rgba (pattern, 1.00, 0., 0., 0., 0.);
+ cairo_set_source (cr3, pattern);
+ cairo_pattern_destroy (pattern);
+ cairo_paint (cr3);
+
+
+ cairo_save (cr2); {
+ cairo_set_operator (cr2, CAIRO_OPERATOR_CLEAR);
+ cairo_paint (cr2);
+ } cairo_restore (cr2);
+
+ pattern = cairo_pattern_create_radial (
+ 0.5 * width, 0.5 * height, 0,
+ 0.5 * width, 0.5 * height, 0.5 *height);
+ cairo_pattern_add_color_stop_rgba (pattern, 0.00, 0., 0., 0., 0.);
+ cairo_pattern_add_color_stop_rgba (pattern, 0.25, 1., 1., 1., 1.);
+ cairo_pattern_add_color_stop_rgba (pattern, 0.50, 1., 1., 1., .5);
+ cairo_pattern_add_color_stop_rgba (pattern, 1.00, 1., 1., 1., 1.);
+ cairo_set_source (cr2, pattern);
+ cairo_pattern_destroy (pattern);
+
+ cairo_mask_surface (cr2, cairo_get_target (cr3), 0, 0);
+ cairo_destroy (cr3);
+
+ cairo_set_source_rgb (cr, 1.0, 0, 0);
+ cairo_mask_surface (cr, cairo_get_target (cr2), 0, 0);
+ cairo_destroy (cr2);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (smask_mask,
+ "Test the support of \"soft\" masks with a secondary mask",
+ "smask, mask", /* keywords */
+ NULL, /* requirements */
+ 60, 60,
+ NULL, draw)
diff --git a/test/smask-paint.c b/test/smask-paint.c
new file mode 100644
index 000000000..ee781caae
--- /dev/null
+++ b/test/smask-paint.c
@@ -0,0 +1,81 @@
+/*
+ * Copyright © 2008 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Chris Wilson not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Chris Wilson makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_surface_t *mask;
+ cairo_pattern_t *pattern;
+ cairo_t *cr2;
+
+ mask = cairo_surface_create_similar (cairo_get_group_target (cr),
+ CAIRO_CONTENT_ALPHA,
+ width, height);
+ cr2 = cairo_create (mask);
+ cairo_surface_destroy (mask);
+
+ cairo_save (cr2); {
+ cairo_set_operator (cr2, CAIRO_OPERATOR_CLEAR);
+ cairo_paint (cr2);
+ } cairo_restore (cr2);
+
+ pattern = cairo_pattern_create_linear (0, 0, width, height);
+ cairo_pattern_add_color_stop_rgba (pattern, 0.00, 0., 0., 0., 0.);
+ cairo_pattern_add_color_stop_rgba (pattern, 0.25, 1., 1., 1., 1.);
+ cairo_pattern_add_color_stop_rgba (pattern, 0.50, 1., 1., 1., .5);
+ cairo_pattern_add_color_stop_rgba (pattern, 0.75, 1., 1., 1., 1.);
+ cairo_pattern_add_color_stop_rgba (pattern, 1.00, 0., 0., 0., 0.);
+ cairo_set_source (cr2, pattern);
+ cairo_pattern_destroy (pattern);
+
+ cairo_paint (cr2);
+
+ cairo_set_source_rgb (cr, 0, 0, 1.0);
+ cairo_paint (cr);
+
+ pattern = cairo_pattern_create_radial (
+ 0.5 * width, 0.5 * height, 0,
+ 0.5 * width, 0.5 * height, 0.5 *height);
+ cairo_pattern_add_color_stop_rgba (pattern, 0.00, 0., 0., 0., 0.);
+ cairo_pattern_add_color_stop_rgba (pattern, 0.25, 1., 0., 0., 1.);
+ cairo_pattern_add_color_stop_rgba (pattern, 0.50, 1., 0., 0., .5);
+ cairo_pattern_add_color_stop_rgba (pattern, 1.00, 1., 0., 0., 1.);
+ cairo_set_source (cr, pattern);
+ cairo_pattern_destroy (pattern);
+
+ cairo_mask_surface (cr, cairo_get_target (cr2), 0, 0);
+ cairo_destroy (cr2);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (smask_paint,
+ "Test the support of \"soft\" masks with paints",
+ "smask, paint", /* keywords */
+ NULL, /* requirements */
+ 60, 60,
+ NULL, draw)
diff --git a/test/smask-stroke.c b/test/smask-stroke.c
new file mode 100644
index 000000000..2a8e7e890
--- /dev/null
+++ b/test/smask-stroke.c
@@ -0,0 +1,73 @@
+/*
+ * Copyright © 2008 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Chris Wilson not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Chris Wilson makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_surface_t *mask;
+ cairo_pattern_t *pattern;
+ cairo_t *cr2;
+
+ cairo_set_source_rgb (cr, 0, 0, 1.0);
+ cairo_paint (cr);
+
+ mask = cairo_surface_create_similar (cairo_get_group_target (cr),
+ CAIRO_CONTENT_ALPHA,
+ width, height);
+ cr2 = cairo_create (mask);
+ cairo_surface_destroy (mask);
+
+ cairo_save (cr2); {
+ cairo_set_operator (cr2, CAIRO_OPERATOR_CLEAR);
+ cairo_paint (cr2);
+ } cairo_restore (cr2);
+
+ pattern = cairo_pattern_create_linear (0, 0, width, height);
+ cairo_pattern_add_color_stop_rgba (pattern, 0.00, 0., 0., 0., 0.);
+ cairo_pattern_add_color_stop_rgba (pattern, 0.25, 1., 1., 1., 1.);
+ cairo_pattern_add_color_stop_rgba (pattern, 0.50, 1., 1., 1., .5);
+ cairo_pattern_add_color_stop_rgba (pattern, 0.75, 1., 1., 1., 1.);
+ cairo_pattern_add_color_stop_rgba (pattern, 1.00, 0., 0., 0., 0.);
+ cairo_set_source (cr2, pattern);
+ cairo_pattern_destroy (pattern);
+
+ cairo_arc (cr2, 0.5 * width, 0.5 * height, 0.4 * height, 0, 2 * M_PI);
+ cairo_stroke (cr2);
+
+ cairo_set_source_rgb (cr, 1.0, 0, 0);
+ cairo_mask_surface (cr, cairo_get_target (cr2), 0, 0);
+ cairo_destroy (cr2);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (smask_stroke,
+ "Test the support of \"soft\" masks with strokes",
+ "smask, stroke", /* keywords */
+ NULL, /* requirements */
+ 60, 60,
+ NULL, draw)
diff --git a/test/smask-text.c b/test/smask-text.c
new file mode 100644
index 000000000..f36ae2674
--- /dev/null
+++ b/test/smask-text.c
@@ -0,0 +1,83 @@
+/*
+ * Copyright © 2008 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Chris Wilson not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Chris Wilson makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_surface_t *mask;
+ cairo_pattern_t *pattern;
+ cairo_t *cr2;
+ cairo_text_extents_t extents;
+
+ cairo_set_source_rgb (cr, 0, 0, 1.0);
+ cairo_paint (cr);
+
+ mask = cairo_surface_create_similar (cairo_get_group_target (cr),
+ CAIRO_CONTENT_ALPHA,
+ width, height);
+ cr2 = cairo_create (mask);
+ cairo_surface_destroy (mask);
+
+ cairo_save (cr2); {
+ cairo_set_operator (cr2, CAIRO_OPERATOR_CLEAR);
+ cairo_paint (cr2);
+ } cairo_restore (cr2);
+
+ pattern = cairo_pattern_create_linear (0, 0, width, height);
+ cairo_pattern_add_color_stop_rgba (pattern, 0.00, 0., 0., 0., 0.);
+ cairo_pattern_add_color_stop_rgba (pattern, 0.25, 1., 1., 1., 1.);
+ cairo_pattern_add_color_stop_rgba (pattern, 0.50, 1., 1., 1., .5);
+ cairo_pattern_add_color_stop_rgba (pattern, 0.75, 1., 1., 1., 1.);
+ cairo_pattern_add_color_stop_rgba (pattern, 1.00, 0., 0., 0., 0.);
+ cairo_set_source (cr2, pattern);
+ cairo_pattern_destroy (pattern);
+
+ cairo_select_font_face (cr2,
+ CAIRO_TEST_FONT_FAMILY " Sans",
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_NORMAL);
+ cairo_set_font_size (cr2, 0.5 * height);
+
+ cairo_text_extents (cr2, "cairo", &extents);
+ cairo_move_to (cr2,
+ floor ((width - extents.width) / 2 + 0.5) - extents.x_bearing,
+ floor ((height - extents.height) / 2 - 0.5) - extents.y_bearing);
+ cairo_show_text (cr2, "cairo");
+
+ cairo_set_source_rgb (cr, 1.0, 0, 0);
+ cairo_mask_surface (cr, cairo_get_target (cr2), 0, 0);
+ cairo_destroy (cr2);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (smask_text,
+ "Test the support of \"soft\" masks with text",
+ "smask, text", /* keywords */
+ NULL, /* keywords */
+ 120, 60,
+ NULL, draw)
diff --git a/test/smask.c b/test/smask.c
new file mode 100644
index 000000000..4cf3adb2a
--- /dev/null
+++ b/test/smask.c
@@ -0,0 +1,123 @@
+/*
+ * Copyright © 2008 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Chris Wilson not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Chris Wilson makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ uint32_t data[] = {
+ 0x80000000, 0x80000000,
+ 0x80000000, 0x80000000,
+ };
+
+ cairo_surface_t *mask, *mask2;
+ cairo_pattern_t *pattern;
+ cairo_t *cr2;
+ cairo_text_extents_t extents;
+
+ mask = cairo_surface_create_similar (cairo_get_group_target (cr),
+ CAIRO_CONTENT_ALPHA,
+ width, height);
+ cr2 = cairo_create (mask);
+ cairo_surface_destroy (mask);
+
+ cairo_save (cr2); {
+ cairo_set_operator (cr2, CAIRO_OPERATOR_CLEAR);
+ cairo_paint (cr2);
+ } cairo_restore (cr2);
+
+ pattern = cairo_pattern_create_linear (0, 0, 0, height);
+ cairo_pattern_add_color_stop_rgba (pattern, 0.00, 0., 0., 0., 0.0);
+ cairo_pattern_add_color_stop_rgba (pattern, 0.80, 0., 0., 0., 0.0);
+ cairo_pattern_add_color_stop_rgba (pattern, 0.90, 1., 1., 1., 0.25);
+ cairo_pattern_add_color_stop_rgba (pattern, 1.00, 1., 1., 1., 1.0);
+ cairo_set_source (cr2, pattern);
+ cairo_pattern_destroy (pattern);
+
+ cairo_paint (cr2);
+
+ pattern = cairo_pattern_create_linear (0, 0, width, height);
+ cairo_pattern_add_color_stop_rgba (pattern, 0.00, 0., 0., 0., 0.);
+ cairo_pattern_add_color_stop_rgba (pattern, 0.25, 1., 1., 1., 1.);
+ cairo_pattern_add_color_stop_rgba (pattern, 0.50, 1., 1., 1., .5);
+ cairo_pattern_add_color_stop_rgba (pattern, 0.75, 1., 1., 1., 1.);
+ cairo_pattern_add_color_stop_rgba (pattern, 1.00, 0., 0., 0., 0.);
+ cairo_set_source (cr2, pattern);
+ cairo_pattern_destroy (pattern);
+
+ mask2 = cairo_image_surface_create_for_data ((unsigned char *) data,
+ CAIRO_FORMAT_ARGB32, 2, 2, 8);
+ pattern = cairo_pattern_create_for_surface (mask2);
+ cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT);
+ cairo_mask (cr2, pattern);
+ cairo_pattern_destroy (pattern);
+
+ cairo_arc (cr2, 0.5 * width, 0.5 * height - 10, 0.2 * height, 0, 2 * M_PI);
+ cairo_fill (cr2);
+
+ cairo_arc (cr2, 0.5 * width, 0.5 * height - 10, 0.25 * height, 0, 2 * M_PI);
+ cairo_stroke (cr2);
+
+ cairo_select_font_face (cr2,
+ CAIRO_TEST_FONT_FAMILY " Sans",
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_NORMAL);
+ cairo_set_font_size (cr2, 0.3 * height);
+
+ cairo_text_extents (cr2, "FG", &extents);
+ cairo_move_to (cr2,
+ floor ((width - extents.width) / 2 + 0.5) - extents.x_bearing,
+ floor (height - extents.height - 0.5) - extents.y_bearing - 5);
+ cairo_show_text (cr2, "FG");
+
+ cairo_set_source_rgb (cr, 0, 0, 1.0);
+ cairo_paint (cr);
+
+ pattern = cairo_pattern_create_radial (
+ 0.5 * width, 0.5 * height, 0,
+ 0.5 * width, 0.5 * height, 0.5 *height);
+ cairo_pattern_add_color_stop_rgba (pattern, 0.00, 0., 0., 0., 0.);
+ cairo_pattern_add_color_stop_rgba (pattern, 0.25, 1., 0., 0., 1.);
+ cairo_pattern_add_color_stop_rgba (pattern, 0.50, 1., 0., 0., .5);
+ cairo_pattern_add_color_stop_rgba (pattern, 1.00, 1., 0., 0., 1.);
+ cairo_set_source (cr, pattern);
+ cairo_pattern_destroy (pattern);
+
+ cairo_mask_surface (cr, cairo_get_target (cr2), 0, 0);
+ cairo_destroy (cr2);
+
+ cairo_surface_finish (mask2); /* data will go out of scope */
+ cairo_surface_destroy (mask2);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (smask,
+ "Test the support of \"soft\" masks",
+ "smask", /* keywords */
+ NULL, /* requirements */
+ 60, 60,
+ NULL, draw)
diff --git a/test/solid-pattern-cache-stress.c b/test/solid-pattern-cache-stress.c
new file mode 100644
index 000000000..c2a1c1526
--- /dev/null
+++ b/test/solid-pattern-cache-stress.c
@@ -0,0 +1,212 @@
+/*
+ * Copyright © 2007 Chris Wilson.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Chris Wilson. Not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Chris Wilson makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris at chris-wilson.co.uk>
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "cairo-test.h"
+#include <stdlib.h> /* drand48() */
+
+#define LOOPS 10
+#define NRAND 100
+
+#ifndef HAVE_DRAND48
+#define drand48() (rand () / (double) RAND_MAX)
+#endif
+
+static cairo_scaled_font_t *scaled_font;
+
+static cairo_t *
+_cairo_create_similar (cairo_t *cr, int width, int height)
+{
+ cairo_surface_t *similar;
+
+ similar = cairo_surface_create_similar (cairo_get_target (cr),
+ cairo_surface_get_content (cairo_get_target (cr)),
+ width, height);
+ cr = cairo_create (similar);
+ cairo_surface_destroy (similar);
+
+ return cr;
+}
+
+static cairo_t *
+_cairo_create_image (cairo_t *cr, cairo_format_t format, int width, int height)
+{
+ cairo_surface_t *image;
+
+ image = cairo_image_surface_create (format, width, height);
+ cr = cairo_create (image);
+ cairo_surface_destroy (image);
+
+ return cr;
+}
+
+static void
+_propagate_status (cairo_t *dst, cairo_t *src)
+{
+ cairo_path_t path;
+
+ path.status = cairo_status (src);
+ if (path.status) {
+ path.num_data = 0;
+ path.data = NULL;
+ cairo_append_path (dst, &path);
+ }
+}
+
+static void
+_draw (cairo_t *cr,
+ double red,
+ double green,
+ double blue)
+{
+ cairo_text_extents_t extents;
+
+ cairo_set_source_rgb (cr, red, green, blue);
+ cairo_paint (cr);
+
+ cairo_move_to (cr, 0, 0);
+ cairo_line_to (cr, 1, 1);
+ cairo_stroke (cr);
+
+ cairo_mask (cr, cairo_get_source (cr));
+
+ cairo_set_scaled_font (cr, scaled_font);
+ cairo_text_extents (cr, "cairo", &extents);
+ cairo_move_to (cr,
+ -extents.x_bearing - .5 * extents.width,
+ -extents.y_bearing - .5 * extents.height);
+ cairo_show_text (cr, "cairo");
+}
+
+static void
+use_similar (cairo_t *cr,
+ double red,
+ double green,
+ double blue)
+{
+ cairo_t *cr2;
+
+ if (cairo_status (cr))
+ return;
+
+ cr2 = _cairo_create_similar (cr, 1, 1);
+
+ _draw (cr2, red, green, blue);
+
+ _propagate_status (cr, cr2);
+ cairo_destroy (cr2);
+}
+
+static void
+use_image (cairo_t *cr,
+ cairo_format_t format,
+ double red,
+ double green,
+ double blue)
+{
+ cairo_t *cr2;
+
+ if (cairo_status (cr))
+ return;
+
+ cr2 = _cairo_create_image (cr, format, 1, 1);
+
+ _draw (cr2, red, green, blue);
+
+ _propagate_status (cr, cr2);
+ cairo_destroy (cr2);
+}
+
+static void
+use_solid (cairo_t *cr,
+ double red,
+ double green,
+ double blue)
+{
+ /* mix in dissimilar solids */
+ use_image (cr, CAIRO_FORMAT_A1, red, green, blue);
+ use_image (cr, CAIRO_FORMAT_A8, red, green, blue);
+ use_image (cr, CAIRO_FORMAT_RGB24, red, green, blue);
+ use_image (cr, CAIRO_FORMAT_ARGB32, red, green, blue);
+
+ use_similar (cr, red, green, blue);
+
+ _draw (cr, red, green, blue);
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ const cairo_test_context_t *ctx = cairo_test_get_context (cr);
+ cairo_status_t status;
+ const double colors[8][3] = {
+ { 1.0, 0.0, 0.0 }, /* red */
+ { 0.0, 1.0, 0.0 }, /* green */
+ { 1.0, 1.0, 0.0 }, /* yellow */
+ { 0.0, 0.0, 1.0 }, /* blue */
+ { 1.0, 0.0, 1.0 }, /* magenta */
+ { 0.0, 1.0, 1.0 }, /* cyan */
+ { 1.0, 1.0, 1.0 }, /* white */
+ { 0.0, 0.0, 0.0 }, /* black */
+ };
+ int i, j, loop;
+
+ /* cache a resolved scaled-font */
+ scaled_font = cairo_get_scaled_font (cr);
+
+ for (loop = 0; loop < LOOPS; loop++) {
+ for (i = 0; i < LOOPS; i++) {
+ for (j = 0; j < 8; j++) {
+ use_solid (cr, colors[j][0], colors[j][1], colors[j][2]);
+ status = cairo_status (cr);
+ if (status)
+ return cairo_test_status_from_status (ctx, status);
+ }
+ }
+
+ for (i = 0; i < NRAND; i++) {
+ use_solid (cr, drand48 (), drand48 (), drand48 ());
+ status = cairo_status (cr);
+ if (status)
+ return cairo_test_status_from_status (ctx, status);
+ }
+ }
+
+ /* stress test only, so clear the surface before comparing */
+ cairo_set_source_rgb (cr, 0, 0, 1);
+ cairo_paint (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (solid_pattern_cache_stress,
+ "Stress the solid pattern cache and ensure it behaves",
+ "stress", /* keywords */
+ NULL, /* requirements */
+ 1, 1,
+ NULL, draw)
diff --git a/test/source-clip-scale.c b/test/source-clip-scale.c
new file mode 100644
index 000000000..4eca2061c
--- /dev/null
+++ b/test/source-clip-scale.c
@@ -0,0 +1,82 @@
+/*
+ * Copyright © 2005 Mozilla Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Mozilla Corporation not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Mozilla Corporation makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * MOZILLA CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL MOZILLA CORPORATION BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Vladimir Vukicevic <vladimir@pobox.com>
+ */
+
+#include "cairo-test.h"
+#include <math.h>
+#include <stdio.h>
+
+#define SIZE 12
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_surface_t *source;
+ cairo_t *cr2;
+
+ source = cairo_surface_create_similar (cairo_get_group_target (cr),
+ CAIRO_CONTENT_COLOR_ALPHA,
+ SIZE, SIZE);
+ cr2 = cairo_create (source);
+ cairo_surface_destroy (source);
+
+ /* Fill the source surface with green */
+ cairo_set_source_rgb (cr2, 0, 1, 0);
+ cairo_paint (cr2);
+
+ /* Draw a blue square in the middle of the source with clipping.
+ * Note that we are only clipping within a save/restore block but
+ * the buggy behavior demonstrates that the clip remains present
+ * on the surface. */
+ cairo_save (cr2);
+ cairo_rectangle (cr2,
+ SIZE / 4, SIZE / 4,
+ SIZE / 2, SIZE / 2);
+ cairo_clip (cr2);
+ cairo_set_source_rgb (cr2, 0, 0, 1);
+ cairo_paint (cr2);
+ cairo_restore (cr2);
+
+ /* Fill the destination surface with solid red (should not appear
+ * in final result) */
+ cairo_set_source_rgb (cr, 1, 0, 0);
+ cairo_paint (cr);
+
+ /* Now draw the source surface onto the destination with scaling. */
+ cairo_scale (cr, 2.0, 1.0);
+
+ cairo_set_source_surface (cr, cairo_get_target (cr2), 0, 0);
+ cairo_destroy (cr2);
+
+ cairo_paint (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (source_clip_scale,
+ "Test that a source surface is not affected by a clip when scaling",
+ "clip", /* keywords */
+ NULL, /* requirements */
+ SIZE * 2, SIZE,
+ NULL, draw)
diff --git a/test/source-clip.c b/test/source-clip.c
new file mode 100644
index 000000000..0c00070b1
--- /dev/null
+++ b/test/source-clip.c
@@ -0,0 +1,77 @@
+/*
+ * Copyright © 2005 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Owen Taylor <otaylor@redhat.com>
+ */
+
+#include "cairo-test.h"
+#include <math.h>
+#include <stdio.h>
+
+#define SIZE 12
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_surface_t *source;
+ cairo_t *cr2;
+
+ source = cairo_surface_create_similar (cairo_get_group_target (cr),
+ CAIRO_CONTENT_COLOR_ALPHA,
+ SIZE, SIZE);
+
+ cr2 = cairo_create (source);
+ cairo_surface_destroy (source);
+
+ /* Fill the source surface with green */
+ cairo_set_source_rgb (cr2, 0, 1, 0);
+ cairo_paint (cr2);
+
+ /* Draw a blue square in the middle of the source with clipping,
+ * and leave the clip there. */
+ cairo_rectangle (cr2,
+ SIZE / 4, SIZE / 4,
+ SIZE / 2, SIZE / 2);
+ cairo_clip (cr2);
+ cairo_set_source_rgb (cr2, 0, 0, 1);
+ cairo_paint (cr2);
+
+ /* Fill the destination surface with solid red (should not appear
+ * in final result) */
+ cairo_set_source_rgb (cr, 1, 0, 0);
+ cairo_paint (cr);
+
+ /* Now draw the source surface onto the destination surface */
+ cairo_set_source_surface (cr, cairo_get_target (cr2), 0, 0);
+ cairo_paint (cr);
+
+ cairo_destroy (cr2);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (source_clip,
+ "Test that a source surface is not affected by a clip",
+ "clip", /* keywords */
+ NULL, /* requirements */
+ SIZE, SIZE,
+ NULL, draw)
diff --git a/test/source-surface-scale-paint.c b/test/source-surface-scale-paint.c
new file mode 100644
index 000000000..4ac62490a
--- /dev/null
+++ b/test/source-surface-scale-paint.c
@@ -0,0 +1,59 @@
+/*
+ * Copyright © 2005 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+#include "cairo-test.h"
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_surface_t *surface;
+ uint32_t data[16] = {
+ 0xffffffff, 0xffffffff, 0xffff0000, 0xffff0000,
+ 0xffffffff, 0xffffffff, 0xffff0000, 0xffff0000,
+
+ 0xff00ff00, 0xff00ff00, 0xff0000ff, 0xff0000ff,
+ 0xff00ff00, 0xff00ff00, 0xff0000ff, 0xff0000ff
+ };
+
+ surface = cairo_image_surface_create_for_data ((unsigned char *) data,
+ CAIRO_FORMAT_RGB24, 4, 4, 16);
+
+ cairo_set_source_surface (cr, surface, 2, 2);
+ cairo_pattern_set_filter (cairo_get_source (cr), CAIRO_FILTER_NEAREST);
+ cairo_scale (cr, 2, 2);
+ cairo_paint (cr);
+
+ cairo_surface_finish (surface); /* data will go out of scope */
+ cairo_surface_destroy (surface);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (source_surface_scale_paint,
+ "Test call sequence: cairo_set_source_surface; cairo_scale; cairo_paint",
+ "transform, paint", /* keywords */
+ NULL, /* requirements */
+ 8, 8,
+ NULL, draw)
diff --git a/test/spline-decomposition.c b/test/spline-decomposition.c
new file mode 100644
index 000000000..ea8f26f23
--- /dev/null
+++ b/test/spline-decomposition.c
@@ -0,0 +1,471 @@
+/*
+ * Copyright 2008 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Chris Wilson not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Chris Wilson makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+typedef struct _point {
+ double x,y;
+} point_t;
+
+typedef struct _knots {
+ point_t a,b,c,d;
+} knots_t;
+
+static knots_t knots[5] = {
+ { {0, 0}, {0, 100}, {100, 100}, {100, 0} },
+ { {0, 0}, {75, 100}, {25, 100}, {100, 0} },
+ { {0, 0}, {100, 100}, {0, 100}, {100, 0} },
+ { {0, 0}, {150, 100}, {-50, 100}, {100, 0} },
+ { {0, 0}, {100, 200}, {0, -100}, {100, 100} },
+};
+
+#ifdef REFERENCE
+static void
+_lerp_half (const point_t *a, const point_t *b, point_t *result)
+{
+ result->x = .5 * (a->x + b->x);
+ result->y = .5 * (a->y + b->y);
+}
+
+static void
+_de_casteljau (knots_t *k1, knots_t *k2)
+{
+ point_t ab, bc, cd;
+ point_t abbc, bccd;
+ point_t final;
+
+ _lerp_half (&k1->a, &k1->b, &ab);
+ _lerp_half (&k1->b, &k1->c, &bc);
+ _lerp_half (&k1->c, &k1->d, &cd);
+ _lerp_half (&ab, &bc, &abbc);
+ _lerp_half (&bc, &cd, &bccd);
+ _lerp_half (&abbc, &bccd, &final);
+
+ k2->a = final;
+ k2->b = bccd;
+ k2->c = cd;
+ k2->d = k1->d;
+
+ k1->b = ab;
+ k1->c = abbc;
+ k1->d = final;
+}
+
+static double
+_spline_error_squared (const knots_t *knots)
+{
+ double bdx, bdy, berr;
+ double cdx, cdy, cerr;
+ double dx, dy, v;
+
+ /* Intersection point (px):
+ * px = p1 + u(p2 - p1)
+ * (p - px) ∙ (p2 - p1) = 0
+ * Thus:
+ * u = ((p - p1) ∙ (p2 - p1)) / ∥p2 - p1∥²;
+ */
+ bdx = knots->b.x - knots->a.x;
+ bdy = knots->b.y - knots->a.y;
+
+ cdx = knots->c.x - knots->a.x;
+ cdy = knots->c.y - knots->a.y;
+
+ dx = knots->d.x - knots->a.x;
+ dy = knots->d.y - knots->a.y;
+ v = dx * dx + dy * dy;
+ if (v != 0.) {
+ double u;
+
+ u = bdx * dx + bdy * dy;
+ if (u <= 0) {
+ /* bdx -= 0;
+ * bdy -= 0;
+ */
+ } else if (u >= v) {
+ bdx -= dx;
+ bdy -= dy;
+ } else {
+ bdx -= u/v * dx;
+ bdy -= u/v * dy;
+ }
+
+ u = cdx * dx + cdy * dy;
+ if (u <= 0) {
+ /* cdx -= 0;
+ * cdy -= 0;
+ */
+ } else if (u >= v) {
+ cdx -= dx;
+ cdy -= dy;
+ } else {
+ cdx -= u/v * dx;
+ cdy -= u/v * dy;
+ }
+ }
+
+ berr = bdx * bdx + bdy * bdy;
+ cerr = cdx * cdx + cdy * cdy;
+ if (berr > cerr)
+ return berr * v;
+ else
+ return cerr * v;
+}
+
+static void
+_offset_line_to (cairo_t *cr,
+ const point_t *p0,
+ const point_t *p1,
+ const point_t *p2,
+ const point_t *p3,
+ double offset)
+{
+ double dx, dy, v;
+
+ dx = p1->x - p0->x;
+ dy = p1->y - p0->y;
+ v = hypot (dx, dy);
+ if (v == 0) {
+ dx = p2->x - p0->x;
+ dy = p2->y - p0->y;
+ v = hypot (dx, dy);
+ if (v == 0) {
+ dx = p3->x - p0->x;
+ dy = p3->y - p0->y;
+ v = hypot (dx, dy);
+ }
+ }
+
+ if (v == 0) {
+ cairo_line_to (cr, p0->x, p0->y);
+ } else
+ cairo_line_to (cr, p0->x - offset * dy / v, p0->y + offset * dx / v);
+}
+
+static void
+_spline_decompose_into (knots_t *k1,
+ double tolerance_squared,
+ double offset,
+ cairo_t *cr)
+{
+ knots_t k2;
+
+ if (_spline_error_squared (k1) < tolerance_squared) {
+ _offset_line_to (cr, &k1->a, &k1->b, &k1->c, &k1->d, offset);
+ return;
+ }
+
+ _de_casteljau (k1, &k2);
+
+ _spline_decompose_into (k1, tolerance_squared, offset, cr);
+ _spline_decompose_into (&k2, tolerance_squared, offset, cr);
+}
+
+static void
+_spline_decompose (const knots_t *knots,
+ double tolerance, double offset,
+ cairo_t *cr)
+{
+ knots_t k;
+
+ k = *knots;
+ _spline_decompose_into (&k, tolerance * tolerance, offset, cr);
+
+ _offset_line_to (cr, &knots->d, &knots->c, &knots->b, &knots->a, -offset);
+}
+
+static void
+_knots_reverse (knots_t *knots)
+{
+ point_t tmp;
+
+ tmp = knots->a;
+ knots->a = knots->d;
+ knots->d = tmp;
+
+ tmp = knots->b;
+ knots->b = knots->c;
+ knots->c = tmp;
+}
+
+static void
+thick_splines (cairo_t *cr, double offset)
+{
+ knots_t k;
+
+ cairo_save (cr);
+ cairo_translate (cr, 15, 15);
+
+ k = knots[0];
+
+ cairo_new_path (cr);
+ _spline_decompose (&k, .1, offset, cr);
+ _knots_reverse (&k);
+ _spline_decompose (&k, .1, offset, cr);
+ cairo_close_path (cr);
+ cairo_fill (cr);
+
+ cairo_translate (cr, 130, 0);
+
+ k = knots[1];
+
+ cairo_new_path (cr);
+ _spline_decompose (&k, .1, offset, cr);
+ _knots_reverse (&k);
+ _spline_decompose (&k, .1, offset, cr);
+ cairo_close_path (cr);
+ cairo_fill (cr);
+
+ cairo_translate (cr, 130, 0);
+
+ k = knots[2];
+
+ cairo_new_path (cr);
+ _spline_decompose (&k, .1, offset, cr);
+ _knots_reverse (&k);
+ _spline_decompose (&k, .1, offset, cr);
+ cairo_close_path (cr);
+ cairo_fill (cr);
+
+ cairo_translate (cr, -130 - 65, 130);
+
+ k = knots[3];
+
+ cairo_new_path (cr);
+ _spline_decompose (&k, .1, offset, cr);
+ _knots_reverse (&k);
+ _spline_decompose (&k, .1, offset, cr);
+ cairo_close_path (cr);
+ cairo_fill (cr);
+
+ cairo_translate (cr, 130, 0);
+
+ k = knots[4];
+
+ cairo_new_path (cr);
+ _spline_decompose (&k, .1, offset, cr);
+ _knots_reverse (&k);
+ _spline_decompose (&k, .1, offset, cr);
+ cairo_close_path (cr);
+ cairo_fill (cr);
+ cairo_restore (cr);
+}
+
+static void
+thin_splines (cairo_t *cr)
+{
+ cairo_save (cr);
+ cairo_translate (cr, 15, 15);
+
+ cairo_new_path (cr);
+ _spline_decompose (&knots[0], .1, 0, cr);
+ cairo_stroke (cr);
+
+ cairo_translate (cr, 130, 0);
+
+ cairo_new_path (cr);
+ _spline_decompose (&knots[1], .1, 0, cr);
+ cairo_stroke (cr);
+
+ cairo_translate (cr, 130, 0);
+
+ cairo_new_path (cr);
+ _spline_decompose (&knots[2], .1, 0, cr);
+ cairo_stroke (cr);
+
+ cairo_translate (cr, -130 - 65, 130);
+
+ cairo_new_path (cr);
+ _spline_decompose (&knots[3], .1, 0, cr);
+ cairo_stroke (cr);
+
+ cairo_translate (cr, 130, 0);
+
+ cairo_new_path (cr);
+ _spline_decompose (&knots[4], .1, 0, cr);
+ cairo_stroke (cr);
+ cairo_restore (cr);
+}
+#endif
+
+static void
+draw_bbox (cairo_t *cr, double x0, double y0, double x1, double y1)
+{
+ cairo_rectangle (cr,
+ floor (x0) + .5, floor (y0) + .5,
+ ceil (x1) - floor (x0), ceil (y1) - floor (y0));
+ cairo_stroke (cr);
+}
+
+static void
+stroke_splines (cairo_t *cr)
+{
+ double stroke_x0, stroke_x1, stroke_y0, stroke_y1;
+ double path_x0, path_x1, path_y0, path_y1;
+
+ cairo_save (cr);
+ cairo_translate (cr, 15, 15);
+
+ cairo_new_path (cr);
+ cairo_move_to (cr,
+ knots[0].a.x, knots[0].a.y);
+ cairo_curve_to (cr,
+ knots[0].b.x, knots[0].b.y,
+ knots[0].c.x, knots[0].c.y,
+ knots[0].d.x, knots[0].d.y);
+ cairo_stroke_extents (cr, &stroke_x0, &stroke_y0, &stroke_x1, &stroke_y1);
+ cairo_path_extents (cr, &path_x0, &path_y0, &path_x1, &path_y1);
+ cairo_stroke (cr);
+
+ cairo_save (cr); {
+ cairo_set_line_width (cr, 1);
+ cairo_set_source_rgb (cr, 1, 0, 0);
+ draw_bbox (cr, stroke_x0, stroke_y0, stroke_x1, stroke_y1);
+ cairo_set_source_rgb (cr, 0, 0, 1);
+ draw_bbox (cr, path_x0, path_y0, path_x1, path_y1);
+ } cairo_restore (cr);
+
+ cairo_translate (cr, 130, 0);
+
+ cairo_new_path (cr);
+ cairo_move_to (cr,
+ knots[1].a.x, knots[1].a.y);
+ cairo_curve_to (cr,
+ knots[1].b.x, knots[1].b.y,
+ knots[1].c.x, knots[1].c.y,
+ knots[1].d.x, knots[1].d.y);
+ cairo_stroke_extents (cr, &stroke_x0, &stroke_y0, &stroke_x1, &stroke_y1);
+ cairo_path_extents (cr, &path_x0, &path_y0, &path_x1, &path_y1);
+ cairo_stroke (cr);
+
+ cairo_save (cr); {
+ cairo_set_line_width (cr, 1);
+ cairo_set_source_rgb (cr, 1, 0, 0);
+ draw_bbox (cr, stroke_x0, stroke_y0, stroke_x1, stroke_y1);
+ cairo_set_source_rgb (cr, 0, 0, 1);
+ draw_bbox (cr, path_x0, path_y0, path_x1, path_y1);
+ } cairo_restore (cr);
+
+ cairo_translate (cr, 130, 0);
+
+ cairo_new_path (cr);
+ cairo_move_to (cr,
+ knots[2].a.x, knots[2].a.y);
+ cairo_curve_to (cr,
+ knots[2].b.x, knots[2].b.y,
+ knots[2].c.x, knots[2].c.y,
+ knots[2].d.x, knots[2].d.y);
+ cairo_stroke_extents (cr, &stroke_x0, &stroke_y0, &stroke_x1, &stroke_y1);
+ cairo_path_extents (cr, &path_x0, &path_y0, &path_x1, &path_y1);
+ cairo_stroke (cr);
+
+ cairo_save (cr); {
+ cairo_set_line_width (cr, 1);
+ cairo_set_source_rgb (cr, 1, 0, 0);
+ draw_bbox (cr, stroke_x0, stroke_y0, stroke_x1, stroke_y1);
+ cairo_set_source_rgb (cr, 0, 0, 1);
+ draw_bbox (cr, path_x0, path_y0, path_x1, path_y1);
+ } cairo_restore (cr);
+
+ cairo_translate (cr, -130 - 65, 130);
+
+ cairo_new_path (cr);
+ cairo_move_to (cr,
+ knots[3].a.x, knots[3].a.y);
+ cairo_curve_to (cr,
+ knots[3].b.x, knots[3].b.y,
+ knots[3].c.x, knots[3].c.y,
+ knots[3].d.x, knots[3].d.y);
+ cairo_stroke_extents (cr, &stroke_x0, &stroke_y0, &stroke_x1, &stroke_y1);
+ cairo_path_extents (cr, &path_x0, &path_y0, &path_x1, &path_y1);
+ cairo_stroke (cr);
+
+ cairo_save (cr); {
+ cairo_set_line_width (cr, 1);
+ cairo_set_source_rgb (cr, 1, 0, 0);
+ draw_bbox (cr, stroke_x0, stroke_y0, stroke_x1, stroke_y1);
+ cairo_set_source_rgb (cr, 0, 0, 1);
+ draw_bbox (cr, path_x0, path_y0, path_x1, path_y1);
+ } cairo_restore (cr);
+
+ cairo_translate (cr, 130, 0);
+
+ cairo_new_path (cr);
+ cairo_move_to (cr,
+ knots[4].a.x, knots[4].a.y);
+ cairo_curve_to (cr,
+ knots[4].b.x, knots[4].b.y,
+ knots[4].c.x, knots[4].c.y,
+ knots[4].d.x, knots[4].d.y);
+ cairo_stroke_extents (cr, &stroke_x0, &stroke_y0, &stroke_x1, &stroke_y1);
+ cairo_path_extents (cr, &path_x0, &path_y0, &path_x1, &path_y1);
+ cairo_stroke (cr);
+
+ cairo_save (cr); {
+ cairo_set_line_width (cr, 1);
+ cairo_set_source_rgb (cr, 1, 0, 0);
+ draw_bbox (cr, stroke_x0, stroke_y0, stroke_x1, stroke_y1);
+ cairo_set_source_rgb (cr, 0, 0, 1);
+ draw_bbox (cr, path_x0, path_y0, path_x1, path_y1);
+ } cairo_restore (cr);
+
+ cairo_restore (cr);
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+#ifdef REFERENCE
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ thick_splines (cr, 5);
+
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ thin_splines (cr);
+#endif
+
+ /*
+ * Use a high tolerance to reduce dependence upon algorithm used for
+ * spline decomposition.
+ */
+ cairo_set_tolerance (cr, 0.001);
+
+ cairo_set_line_width (cr, 10);
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ stroke_splines (cr);
+ cairo_set_line_width (cr, 2);
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ stroke_splines (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (spline_decomposition,
+ "Tests splines with various inflection points",
+ "stroke, spline", /* keywords */
+ NULL, /* requirements */
+ 390, 260,
+ NULL, draw)
diff --git a/test/stride-12-image.c b/test/stride-12-image.c
new file mode 100644
index 000000000..5650e9830
--- /dev/null
+++ b/test/stride-12-image.c
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2012 Andrea Canciani
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Andrea Canciani <ranma42@gmail.com>
+ */
+
+#include "cairo-test.h"
+
+static const char *png_filename = "romedalen.png";
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ const cairo_test_context_t *ctx = cairo_test_get_context (cr);
+ cairo_format_t format = CAIRO_FORMAT_ARGB32;
+ cairo_t *cr_src;
+ cairo_surface_t *png, *src;
+ uint8_t *data;
+ int stride;
+
+ png = cairo_test_create_surface_from_png (ctx, png_filename);
+
+ stride = cairo_format_stride_for_width (format, width) + 12;
+ data = xcalloc (stride, height);
+ src = cairo_image_surface_create_for_data (data, format,
+ width, height, stride);
+
+ cr_src = cairo_create (src);
+ cairo_set_source_surface (cr_src, png, 0, 0);
+ cairo_paint (cr_src);
+ cairo_destroy (cr_src);
+
+ cairo_set_source_surface (cr, src, 0, 0);
+ cairo_paint (cr);
+
+ cairo_surface_destroy (png);
+
+ cairo_surface_finish (src);
+ cairo_surface_destroy (src);
+
+ free (data);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (stride_12_image,
+ "Test that images with a non-default stride are handled correctly.",
+ "stride, image", /* keywords */
+ NULL, /* requirements */
+ 256, 192,
+ NULL, draw)
diff --git a/test/stroke-clipped.c b/test/stroke-clipped.c
new file mode 100644
index 000000000..4b8079480
--- /dev/null
+++ b/test/stroke-clipped.c
@@ -0,0 +1,54 @@
+/*
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include "cairo-test.h"
+
+#define SIZE 200
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ int row;
+
+ cairo_set_source_rgb(cr, 1, 1, 1);
+ cairo_paint(cr);
+
+ cairo_set_source_rgb(cr, 1, 0, 0);
+ for(row = 0; row < SIZE; row++) {
+ cairo_rectangle(cr, 0, row, SIZE, 1);
+ cairo_clip(cr);
+
+ cairo_arc(cr, SIZE/2, SIZE/2, SIZE/2-8, 0, 2*M_PI);
+ cairo_stroke(cr);
+
+ cairo_reset_clip(cr);
+ }
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (stroke_clipped,
+ "Check that the stroke is accurately drawn through smaller clips",
+ "stroke", /* keywords */
+ NULL, /* requirements */
+ SIZE, SIZE,
+ NULL, draw)
diff --git a/test/stroke-ctm-caps.c b/test/stroke-ctm-caps.c
new file mode 100644
index 000000000..1bbee83c6
--- /dev/null
+++ b/test/stroke-ctm-caps.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright © 2008 Adrian Johnson
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Adrian Johnson <ajohnson@redneon.com>
+ */
+
+#include "cairo-test.h"
+
+#define SIZE 100
+#define PAD 2
+#define WIDTH (PAD + SIZE + PAD)
+#define HEIGHT WIDTH
+
+/* This test is designed to test that PDF viewers use the correct
+ * alpha values in an Alpha SMasks. Some viewers use the color values
+ * instead of the alpha. The test draws a triangle and rectangle in a
+ * group then draws the group using cairo_mask(). The mask consists of
+ * a circle with the rgba (0.4, 0.4, 0.4, 0.8) and the background rgba
+ * (0.8, 0.8, 0.8, 0.4).
+ */
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+ /* flip the CTM, which most clearly shows the problem */
+ cairo_translate (cr, 0, HEIGHT);
+ cairo_scale (cr, 1, -1);
+
+ cairo_set_source_rgb (cr, 0, 0, 0);
+
+ cairo_set_line_width (cr, 10);
+ cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
+ cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND);
+
+ cairo_move_to (cr, 20, 20);
+ cairo_line_to (cr, 20, 70);
+ cairo_stroke (cr);
+
+ cairo_move_to (cr, 40, 20);
+ cairo_line_to (cr, 70, 70);
+ cairo_stroke (cr);
+
+ cairo_move_to (cr, 60, 20);
+ cairo_line_to (cr, 90, 20);
+ cairo_stroke (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (stroke_ctm_caps,
+ "Test that the stroker correctly passes the device-space vector to the stroker for endcaps",
+ "stroke, transform", /* keywords */
+ NULL, /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw)
diff --git a/test/stroke-image.c b/test/stroke-image.c
new file mode 100644
index 000000000..17e6653ff
--- /dev/null
+++ b/test/stroke-image.c
@@ -0,0 +1,73 @@
+/*
+ * Copyright © 2006 Mozilla Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Mozilla Corporation not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Mozilla Corporation makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * MOZILLA CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL MOZILLA CORPORATION BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Vladimir Vukicevic <vladimir@pobox.com>
+ */
+
+#include "cairo-test.h"
+
+#define PAD 10
+#define SIZE 100
+#define IMAGE_SIZE (SIZE-PAD*2)
+#define LINE_WIDTH 10
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_surface_t *image;
+ cairo_t *cr_image;
+
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ cairo_paint (cr);
+
+ image = cairo_image_surface_create (CAIRO_FORMAT_RGB24, IMAGE_SIZE, IMAGE_SIZE);
+ cr_image = cairo_create (image);
+ cairo_surface_destroy (image);
+
+ /* Create the image */
+ cairo_set_source_rgb (cr_image, 0, 0, 0);
+ cairo_paint (cr_image);
+ cairo_set_source_rgb (cr_image, 0, 1, 0);
+ cairo_set_line_width (cr_image, LINE_WIDTH);
+ cairo_arc (cr_image, IMAGE_SIZE/2, IMAGE_SIZE/2, IMAGE_SIZE/2 - LINE_WIDTH/2, 0, M_PI * 2.0);
+ cairo_stroke (cr_image);
+
+ /* Now stroke with it */
+ cairo_translate (cr, PAD, PAD);
+
+ cairo_set_source_surface (cr, cairo_get_target (cr_image), 0, 0);
+ cairo_destroy (cr_image);
+
+ cairo_new_path (cr);
+ cairo_set_line_width (cr, LINE_WIDTH);
+ cairo_arc (cr, IMAGE_SIZE/2, IMAGE_SIZE/2, IMAGE_SIZE/2 - LINE_WIDTH/2, 0, M_PI * 2.0);
+ cairo_stroke (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (stroke_image,
+ "Test stroking with an image source, with a non-identity CTM",
+ "stroke, image, transform", /* keywords */
+ NULL, /* requirements */
+ SIZE, SIZE,
+ NULL, draw)
diff --git a/test/stroke-open-box.c b/test/stroke-open-box.c
new file mode 100644
index 000000000..b1dae5090
--- /dev/null
+++ b/test/stroke-open-box.c
@@ -0,0 +1,51 @@
+/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */
+/*
+ * Copyright 2011 Simon Kellner
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Simon Kellner <kellner@kit.edu>
+ */
+
+#include "cairo-test.h"
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ cairo_move_to (cr, 5, 7);
+ cairo_rel_line_to (cr, 20, 0);
+ cairo_rel_line_to (cr, 0, 15);
+ cairo_rel_line_to (cr, -20, 0);
+ cairo_stroke (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (stroke_open_box,
+ "Tests stroking of a 3-sided box",
+ "stroke,box", /* keywords */
+ NULL, /* requirements */
+ 30, 32,
+ NULL, draw)
diff --git a/test/stroke-pattern.c b/test/stroke-pattern.c
new file mode 100644
index 000000000..01e10195d
--- /dev/null
+++ b/test/stroke-pattern.c
@@ -0,0 +1,68 @@
+/*
+ * Copyright © 2011 Adrian Johnson
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Adrian Johnson <ajohnson@redneon.com>
+ */
+
+#include "cairo-test.h"
+
+#define IMAGE_WIDTH 80
+#define IMAGE_HEIGHT 80
+
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_pattern_t *pattern;
+
+ cairo_test_paint_checkered (cr);
+
+ cairo_scale (cr, 0.3, 0.3);
+ cairo_translate (cr, 50, 50);
+
+ pattern = cairo_pattern_create_linear (70, 100, 130, 100);
+ cairo_pattern_add_color_stop_rgba (pattern, 0, 1, 0, 0, 1.0);
+ cairo_pattern_add_color_stop_rgba (pattern, 1, 0, 1, 0, 0.5);
+
+ cairo_pattern_set_extend (pattern, CAIRO_EXTEND_PAD);
+ cairo_set_source (cr, pattern);
+
+ cairo_move_to(cr, 20, 20);
+ cairo_curve_to(cr,
+ 130, 0,
+ 70, 200,
+ 180, 180);
+ cairo_set_line_width (cr, 20);
+ cairo_stroke (cr);
+
+ cairo_pattern_destroy (pattern);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (stroke_pattern,
+ "Patterned stroke",
+ "stroke, pattern", /* keywords */
+ NULL, /* requirements */
+ IMAGE_WIDTH, IMAGE_HEIGHT,
+ NULL, draw)
diff --git a/test/subsurface-image-repeat.c b/test/subsurface-image-repeat.c
new file mode 100644
index 000000000..c741944fb
--- /dev/null
+++ b/test/subsurface-image-repeat.c
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2009 Intel Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Intel not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Intel makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * INTEL CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+static const char *png_filename = "romedalen.png";
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ const cairo_test_context_t *ctx = cairo_test_get_context (cr);
+ cairo_surface_t *image, *region;
+ cairo_t *cr_region;
+
+ cairo_set_source_rgb (cr, .5, .5, .5);
+ cairo_paint (cr);
+
+ /* fill the centre */
+ region = cairo_surface_create_for_rectangle (cairo_get_target (cr),
+ 20, 20, 20, 20);
+ cr_region = cairo_create (region);
+ cairo_surface_destroy (region);
+
+ image = cairo_test_create_surface_from_png (ctx, png_filename);
+ cairo_set_source_surface (cr_region, image,
+ 10 - cairo_image_surface_get_width (image)/2,
+ 10 - cairo_image_surface_get_height (image)/2);
+ cairo_paint (cr_region);
+ cairo_surface_destroy (image);
+
+ cairo_set_source_surface (cr, cairo_get_target (cr_region), 20, 20);
+ cairo_destroy (cr_region);
+
+ /* repeat the pattern around the outside, but do not overwrite...*/
+ cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_REPEAT);
+ cairo_rectangle (cr, 0, 0, width, height);
+ cairo_rectangle (cr, 20, 40, 20, -20);
+ cairo_fill (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (subsurface_image_repeat,
+ "Tests source (image) clipping with repeat",
+ "subsurface, image, repeat", /* keywords */
+ "target=raster", /* FIXME! recursion bug in subsurface/snapshot (with pdf backend) */ /* requirements */
+ 60, 60,
+ NULL, draw)
diff --git a/test/subsurface-modify-child.c b/test/subsurface-modify-child.c
new file mode 100644
index 000000000..ed9435616
--- /dev/null
+++ b/test/subsurface-modify-child.c
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2010 Intel Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Intel not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Intel makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * INTEL CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_surface_t *region, *similar;
+ cairo_t *cr_region, *cr_similar;
+
+ cairo_set_source_rgb (cr, .5, .5, .5);
+ cairo_paint (cr);
+
+ similar = cairo_surface_create_similar (cairo_get_target (cr),
+ CAIRO_CONTENT_COLOR_ALPHA,
+ 20, 20);
+
+ /* copy the centre */
+ cr_similar = cairo_create (similar);
+ cairo_surface_destroy (similar);
+ cairo_set_source_surface (cr_similar, cairo_get_target (cr), -20, -20);
+ cairo_paint (cr_similar);
+ similar = cairo_surface_reference (cairo_get_target (cr_similar));
+ cairo_destroy (cr_similar);
+
+ /* fill the centre */
+ region = cairo_surface_create_for_rectangle (cairo_get_target (cr),
+ 20, 20, 20, 20);
+ cr_region = cairo_create (region);
+ cairo_surface_destroy (region);
+
+ cairo_set_source_rgb (cr_region, 1, 1, 1);
+ cairo_rectangle (cr_region, 0, 0, 10, 10);
+ cairo_fill (cr_region);
+
+ cairo_set_source_rgb (cr_region, 1, 0, 0);
+ cairo_rectangle (cr_region, 10, 0, 10, 10);
+ cairo_fill (cr_region);
+
+ cairo_set_source_rgb (cr_region, 0, 1, 0);
+ cairo_rectangle (cr_region, 0, 10, 10, 10);
+ cairo_fill (cr_region);
+
+ cairo_set_source_rgb (cr_region, 0, 0, 1);
+ cairo_rectangle (cr_region, 10, 10, 10, 10);
+ cairo_fill (cr_region);
+
+ cairo_destroy (cr_region);
+
+ /* copy the centre, again */
+ cr_similar = cairo_create (similar);
+ cairo_surface_destroy (similar);
+ cairo_set_source_surface (cr_similar, cairo_get_target (cr), -20, -20);
+ cairo_paint (cr_similar);
+ similar = cairo_surface_reference (cairo_get_target (cr_similar));
+ cairo_destroy (cr_similar);
+
+ /* repeat the pattern around the outside, but do not overwrite...*/
+ cairo_set_source_surface (cr, similar, 20, 20);
+ cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_REPEAT);
+ cairo_rectangle (cr, 0, 0, width, height);
+ cairo_rectangle (cr, 20, 40, 20, -20);
+ cairo_fill (cr);
+
+ cairo_surface_destroy (similar);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (subsurface_modify_child,
+ "Tests source clipping with later modifications",
+ "subsurface", /* keywords */
+ "target=raster", /* FIXME! recursion bug in subsurface/snapshot (with pdf backend) */ /* requirements */
+ 60, 60,
+ NULL, draw)
diff --git a/test/subsurface-modify-parent.c b/test/subsurface-modify-parent.c
new file mode 100644
index 000000000..de16e7530
--- /dev/null
+++ b/test/subsurface-modify-parent.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2010 Intel Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Intel not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Intel makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * INTEL CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_surface_t *region;
+
+ cairo_set_source_rgb (cr, .5, .5, .5);
+ cairo_paint (cr);
+
+ /* fill the centre, but through the *original* surface */
+ region = cairo_surface_create_for_rectangle (cairo_get_target (cr),
+ 20, 20, 20, 20);
+
+ /* first trigger a snapshot of the region... */
+ cairo_set_source_surface (cr, region, 20, 20);
+ cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_REPEAT);
+ cairo_paint (cr);
+
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_rectangle (cr, 20, 20, 10, 10);
+ cairo_fill (cr);
+
+ cairo_set_source_rgb (cr, 1, 0, 0);
+ cairo_rectangle (cr, 30, 20, 10, 10);
+ cairo_fill (cr);
+
+ cairo_set_source_rgb (cr, 0, 1, 0);
+ cairo_rectangle (cr, 20, 30, 10, 10);
+ cairo_fill (cr);
+
+ cairo_set_source_rgb (cr, 0, 0, 1);
+ cairo_rectangle (cr, 30, 30, 10, 10);
+ cairo_fill (cr);
+
+ cairo_set_source_surface (cr, region, 20, 20);
+ cairo_surface_destroy (region);
+
+ /* repeat the pattern around the outside, but do not overwrite...*/
+ cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_REPEAT);
+ cairo_rectangle (cr, 0, 0, width, height);
+ cairo_rectangle (cr, 20, 40, 20, -20);
+ cairo_fill (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (subsurface_modify_parent,
+ "Tests source clipping with later modifications",
+ "subsurface", /* keywords */
+ "target=raster", /* FIXME! recursion bug in subsurface/snapshot (with pdf backend) */ /* requirements */
+ 60, 60,
+ NULL, draw)
diff --git a/test/subsurface-outside-target.c b/test/subsurface-outside-target.c
new file mode 100644
index 000000000..ef91a2e1c
--- /dev/null
+++ b/test/subsurface-outside-target.c
@@ -0,0 +1,177 @@
+/*
+ * Copyright 2010 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Benjamin Otte <otte@gnome.org>
+ */
+
+#include "cairo-test.h"
+
+#define TARGET_SIZE 10
+
+#define SUB_SIZE 15
+#define SUB_OFFSET -5
+
+#define PAINT_OFFSET SUB_SIZE
+#define PAINT_SIZE (3 * SUB_SIZE)
+
+static cairo_content_t contents[] = { CAIRO_CONTENT_ALPHA,
+ CAIRO_CONTENT_COLOR,
+ CAIRO_CONTENT_COLOR_ALPHA };
+
+#define N_CONTENTS ARRAY_LENGTH (contents)
+#define N_PADS (CAIRO_EXTEND_PAD + 1)
+
+
+static cairo_surface_t *
+create_target (cairo_surface_t *similar_to,
+ cairo_content_t content)
+{
+ cairo_surface_t *surface;
+ cairo_t *cr;
+
+ surface = cairo_surface_create_similar (similar_to,
+ content,
+ TARGET_SIZE, TARGET_SIZE);
+
+ cr = cairo_create (surface);
+ cairo_test_paint_checkered (cr);
+ cairo_destroy (cr);
+
+ return surface;
+}
+
+static cairo_test_status_t
+check_surface_extents (const cairo_test_context_t *ctx,
+ cairo_surface_t * surface,
+ double x,
+ double y,
+ double width,
+ double height)
+{
+ double x1, y1, x2, y2;
+ cairo_t *cr;
+
+ cr = cairo_create (surface);
+ cairo_clip_extents (cr, &x1, &y1, &x2, &y2);
+ cairo_destroy (cr);
+
+ if (x != x1 ||
+ y != y1 ||
+ width != x2 - x1 ||
+ height != y2 - y1) {
+ cairo_test_log (ctx,
+ "surface extents should be (%g, %g, %g, %g), but are (%g, %g, %g, %g)\n",
+ x, y, width, height,
+ x1, y1, x2 - x1, y2 - y1);
+ return CAIRO_TEST_FAILURE;
+ }
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+draw_for_size (cairo_t *cr,
+ double x,
+ double y)
+{
+ cairo_surface_t *target, *subsurface;
+ cairo_extend_t extend;
+ cairo_test_status_t check, result = CAIRO_TEST_SUCCESS;
+ unsigned int content;
+
+ for (content = 0; content < N_CONTENTS; content++) {
+ cairo_save (cr);
+
+ /* create a target surface for our subsurface */
+ target = create_target (cairo_get_target (cr),
+ contents[content]);
+
+ /* create a subsurface that extends the target surface */
+ subsurface = cairo_surface_create_for_rectangle (target,
+ x, y,
+ SUB_SIZE, SUB_SIZE);
+
+ /* ensure the extents are ok */
+ check = check_surface_extents (cairo_test_get_context (cr),
+ subsurface,
+ 0, 0,
+ SUB_SIZE, SUB_SIZE);
+ if (result == CAIRO_TEST_SUCCESS)
+ result = check;
+
+ /* paint this surface with all extend modes. */
+ for (extend = 0; extend < N_PADS; extend++) {
+ cairo_save (cr);
+
+ cairo_rectangle (cr, 0, 0, PAINT_SIZE, PAINT_SIZE);
+ cairo_clip (cr);
+
+ cairo_set_source_surface (cr, subsurface, PAINT_OFFSET, PAINT_OFFSET);
+ cairo_pattern_set_extend (cairo_get_source (cr), extend);
+ cairo_paint (cr);
+
+ cairo_restore (cr);
+
+ cairo_translate (cr, PAINT_SIZE + TARGET_SIZE, 0);
+ }
+
+ cairo_surface_destroy (subsurface);
+ cairo_surface_destroy (target);
+
+ cairo_restore (cr);
+
+ cairo_translate (cr, 0, PAINT_SIZE + TARGET_SIZE);
+ }
+
+ return result;
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_test_status_t check, result = CAIRO_TEST_SUCCESS;
+
+ /* paint background in nice gray */
+ cairo_set_source_rgb (cr, 0.51613, 0.55555, 0.51613);
+ cairo_paint (cr);
+
+ /* Use CAIRO_OPERATOR_SOURCE in the tests so we get the actual
+ * contents of the subsurface */
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+
+ result = draw_for_size (cr, SUB_OFFSET, SUB_OFFSET);
+
+ check = draw_for_size (cr, 0, 0);
+ if (result == CAIRO_TEST_SUCCESS)
+ result = check;
+
+ return result;
+}
+
+CAIRO_TEST (subsurface_outside_target,
+ "Tests contents of subsurfaces outside target area",
+ "subsurface, pad", /* keywords */
+ "target=raster", /* FIXME! recursion bug in subsurface/snapshot (with pdf backend) */ /* requirements */
+ (PAINT_SIZE + TARGET_SIZE) * N_PADS - TARGET_SIZE,
+ (PAINT_SIZE + TARGET_SIZE) * N_CONTENTS * 2 - TARGET_SIZE,
+ NULL, draw)
diff --git a/test/subsurface-pad.c b/test/subsurface-pad.c
new file mode 100644
index 000000000..1ac7a0e39
--- /dev/null
+++ b/test/subsurface-pad.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2009 Intel Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Intel not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Intel makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * INTEL CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_surface_t *region;
+ cairo_t *cr_region;
+
+ cairo_set_source_rgb (cr, .5, .5, .5);
+ cairo_paint (cr);
+
+ /* fill the centre */
+ region = cairo_surface_create_for_rectangle (cairo_get_target (cr),
+ 20, 20, 20, 20);
+ cr_region = cairo_create (region);
+ cairo_surface_destroy (region);
+
+ cairo_set_source_rgb (cr_region, 1, 1, 1);
+ cairo_rectangle (cr_region, 0, 0, 10, 10);
+ cairo_fill (cr_region);
+
+ cairo_set_source_rgb (cr_region, 1, 0, 0);
+ cairo_rectangle (cr_region, 10, 0, 10, 10);
+ cairo_fill (cr_region);
+
+ cairo_set_source_rgb (cr_region, 0, 1, 0);
+ cairo_rectangle (cr_region, 0, 10, 10, 10);
+ cairo_fill (cr_region);
+
+ cairo_set_source_rgb (cr_region, 0, 0, 1);
+ cairo_rectangle (cr_region, 10, 10, 10, 10);
+ cairo_fill (cr_region);
+
+ cairo_set_source_surface (cr, cairo_get_target (cr_region), 20, 20);
+ cairo_destroy (cr_region);
+
+ /* reflect the pattern around the outside, but do not overwrite...*/
+ cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_PAD);
+ cairo_rectangle (cr, 0, 0, width, height);
+ cairo_rectangle (cr, 20, 40, 20, -20);
+ cairo_fill (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (subsurface_pad,
+ "Tests source clipping with pad",
+ "subsurface, pad", /* keywords */
+ "target=raster", /* FIXME! recursion bug in subsurface/snapshot (with pdf backend) */ /* requirements */
+ 60, 60,
+ NULL, draw)
diff --git a/test/subsurface-reflect.c b/test/subsurface-reflect.c
new file mode 100644
index 000000000..517106df1
--- /dev/null
+++ b/test/subsurface-reflect.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2009 Intel Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Intel not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Intel makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * INTEL CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_surface_t *region;
+ cairo_t *cr_region;
+
+ cairo_set_source_rgb (cr, .5, .5, .5);
+ cairo_paint (cr);
+
+ /* fill the centre */
+ region = cairo_surface_create_for_rectangle (cairo_get_target (cr),
+ 20, 20, 20, 20);
+ cr_region = cairo_create (region);
+ cairo_surface_destroy (region);
+
+ cairo_set_source_rgb (cr_region, 1, 1, 1);
+ cairo_rectangle (cr_region, 0, 0, 10, 10);
+ cairo_fill (cr_region);
+
+ cairo_set_source_rgb (cr_region, 1, 0, 0);
+ cairo_rectangle (cr_region, 10, 0, 10, 10);
+ cairo_fill (cr_region);
+
+ cairo_set_source_rgb (cr_region, 0, 1, 0);
+ cairo_rectangle (cr_region, 0, 10, 10, 10);
+ cairo_fill (cr_region);
+
+ cairo_set_source_rgb (cr_region, 0, 0, 1);
+ cairo_rectangle (cr_region, 10, 10, 10, 10);
+ cairo_fill (cr_region);
+
+ cairo_set_source_surface (cr, cairo_get_target (cr_region), 20, 20);
+ cairo_destroy (cr_region);
+
+ /* reflect the pattern around the outside, but do not overwrite...*/
+ cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_REFLECT);
+ cairo_rectangle (cr, 0, 0, width, height);
+ cairo_rectangle (cr, 20, 40, 20, -20);
+ cairo_fill (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (subsurface_reflect,
+ "Tests source clipping with reflect",
+ "subsurface, reflect", /* keywords */
+ "target=raster", /* FIXME! recursion bug in subsurface/snapshot (with pdf backend) */ /* requirements */
+ 60, 60,
+ NULL, draw)
diff --git a/test/subsurface-repeat.c b/test/subsurface-repeat.c
new file mode 100644
index 000000000..596b97338
--- /dev/null
+++ b/test/subsurface-repeat.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2009 Intel Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Intel not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Intel makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * INTEL CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_surface_t *region;
+ cairo_t *cr_region;
+
+ cairo_set_source_rgb (cr, .5, .5, .5);
+ cairo_paint (cr);
+
+ /* fill the centre */
+ region = cairo_surface_create_for_rectangle (cairo_get_target (cr),
+ 20, 20, 20, 20);
+ cr_region = cairo_create (region);
+ cairo_surface_destroy (region);
+
+ cairo_set_source_rgb (cr_region, 1, 1, 1);
+ cairo_rectangle (cr_region, 0, 0, 10, 10);
+ cairo_fill (cr_region);
+
+ cairo_set_source_rgb (cr_region, 1, 0, 0);
+ cairo_rectangle (cr_region, 10, 0, 10, 10);
+ cairo_fill (cr_region);
+
+ cairo_set_source_rgb (cr_region, 0, 1, 0);
+ cairo_rectangle (cr_region, 0, 10, 10, 10);
+ cairo_fill (cr_region);
+
+ cairo_set_source_rgb (cr_region, 0, 0, 1);
+ cairo_rectangle (cr_region, 10, 10, 10, 10);
+ cairo_fill (cr_region);
+
+ cairo_set_source_surface (cr, cairo_get_target (cr_region), 20, 20);
+ cairo_destroy (cr_region);
+
+ /* repeat the pattern around the outside, but do not overwrite...*/
+ cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_REPEAT);
+ cairo_rectangle (cr, 0, 0, width, height);
+ cairo_rectangle (cr, 20, 40, 20, -20);
+ cairo_fill (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (subsurface_repeat,
+ "Tests source clipping with repeat",
+ "subsurface, repeat", /* keywords */
+ "target=raster", /* FIXME! recursion bug in subsurface/snapshot (with pdf backend) */ /* requirements */
+ 60, 60,
+ NULL, draw)
diff --git a/test/subsurface-scale.c b/test/subsurface-scale.c
new file mode 100644
index 000000000..9ffd2c422
--- /dev/null
+++ b/test/subsurface-scale.c
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2009 Intel Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Intel not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Intel makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * INTEL CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_surface_t *region[5];
+ const char *text = "Cairo";
+ int i;
+
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+ cairo_rectangle (cr, 0, 20, 200, 60);
+ cairo_set_source_rgb (cr, 1, 0, 0);
+ cairo_fill (cr);
+
+ cairo_set_source_rgb (cr, 0, 0, 0);
+
+ for (i = 0; i < 5; i++) {
+ cairo_t *cr_region;
+ cairo_text_extents_t extents;
+ char buf[2] = { text[i], '\0' };
+
+ region[i] = cairo_surface_create_for_rectangle (cairo_get_target (cr),
+ 20 * i, 0, 20, 20);
+
+ cr_region = cairo_create (region[i]);
+ cairo_surface_destroy (region[i]);
+
+ cairo_select_font_face (cr_region, "@cairo:",
+ CAIRO_FONT_WEIGHT_NORMAL,
+ CAIRO_FONT_SLANT_NORMAL);
+ cairo_set_font_size (cr_region, 20);
+ cairo_text_extents (cr_region, buf, &extents);
+ cairo_move_to (cr_region,
+ 10 - (extents.width/2 + extents.x_bearing),
+ 10 - (extents.height/2 + extents.y_bearing));
+ cairo_show_text (cr_region, buf);
+
+ region[i] = cairo_surface_reference (cairo_get_target (cr_region));
+ cairo_destroy (cr_region);
+ }
+
+ cairo_scale (cr, 2, 2);
+ for (i = 0; i < 5; i++) {
+ cairo_set_source_surface (cr, region[5-i-1], 20 * i, 20);
+ cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_PAD);
+ cairo_rectangle (cr, 20*i, 20, 20, 20);
+ cairo_fill (cr);
+ }
+
+ for (i = 0; i < 5; i++) {
+ cairo_set_source_surface (cr, region[5-i-1], 20 * i, 40);
+ cairo_paint_with_alpha (cr, .5);
+ }
+
+ for (i = 0; i < 5; i++)
+ cairo_surface_destroy (region[i]);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (subsurface_scale,
+ "Tests clipping of both source and destination using subsurfaces",
+ "subsurface", /* keywords */
+ "target=raster", /* FIXME! recursion bug in subsurface/snapshot (with pdf backend) */ /* requirements */
+ 200, 120,
+ NULL, draw)
diff --git a/test/subsurface-similar-repeat.c b/test/subsurface-similar-repeat.c
new file mode 100644
index 000000000..011f876e6
--- /dev/null
+++ b/test/subsurface-similar-repeat.c
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2009 Intel Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Intel not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Intel makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * INTEL CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_surface_t *similar;
+ cairo_surface_t *region;
+ cairo_t *cr_region;
+
+ cairo_set_source_rgb (cr, .5, .5, .5);
+ cairo_paint (cr);
+
+ similar = cairo_surface_create_similar (cairo_get_target (cr),
+ CAIRO_CONTENT_COLOR,
+ 60, 60);
+ cr_region = cairo_create (similar);
+ cairo_surface_destroy (similar);
+
+ cairo_set_source_rgb (cr_region, .5, .5, .0);
+ cairo_paint (cr_region);
+ similar = cairo_surface_reference (cairo_get_target (cr_region));
+ cairo_destroy (cr_region);
+
+ /* fill the centre */
+ region = cairo_surface_create_for_rectangle (similar, 20, 20, 20, 20);
+ cairo_surface_destroy (similar);
+
+ cr_region = cairo_create (region);
+ cairo_surface_destroy (region);
+
+ cairo_set_source_rgb (cr_region, 1, 1, 1);
+ cairo_rectangle (cr_region, 0, 0, 10, 10);
+ cairo_fill (cr_region);
+
+ cairo_set_source_rgb (cr_region, 1, 0, 0);
+ cairo_rectangle (cr_region, 10, 0, 10, 10);
+ cairo_fill (cr_region);
+
+ cairo_set_source_rgb (cr_region, 0, 1, 0);
+ cairo_rectangle (cr_region, 0, 10, 10, 10);
+ cairo_fill (cr_region);
+
+ cairo_set_source_rgb (cr_region, 0, 0, 1);
+ cairo_rectangle (cr_region, 10, 10, 10, 10);
+ cairo_fill (cr_region);
+
+ cairo_set_source_surface (cr, cairo_get_target (cr_region), 20, 20);
+ cairo_destroy (cr_region);
+
+ cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_REPEAT);
+ cairo_paint (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (subsurface_similar_repeat,
+ "Tests source clipping through an intermediate with repeat",
+ "subsurface, repeat", /* keywords */
+ "target=raster", /* FIXME! recursion bug in subsurface/snapshot (with pdf backend) */ /* requirements */
+ 60, 60,
+ NULL, draw)
diff --git a/test/subsurface.c b/test/subsurface.c
new file mode 100644
index 000000000..812776c0a
--- /dev/null
+++ b/test/subsurface.c
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2009 Intel Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Intel not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Intel makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * INTEL CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_surface_t *region[5];
+ const char *text = "Cairo";
+ int i;
+
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+ cairo_set_source_rgb (cr, 0, 0, 0);
+
+ for (i = 0; i < 5; i++) {
+ cairo_t *cr_region;
+ cairo_text_extents_t extents;
+ char buf[2] = { text[i], '\0' };
+
+ region[i] = cairo_surface_create_for_rectangle (cairo_get_target (cr),
+ 20 * i, 0, 20, 20);
+
+ cr_region = cairo_create (region[i]);
+ cairo_surface_destroy (region[i]);
+
+ cairo_select_font_face (cr_region, "@cairo:",
+ CAIRO_FONT_WEIGHT_NORMAL,
+ CAIRO_FONT_SLANT_NORMAL);
+ cairo_set_font_size (cr_region, 20);
+ cairo_text_extents (cr_region, buf, &extents);
+ cairo_move_to (cr_region,
+ 10 - (extents.width/2 + extents.x_bearing),
+ 10 - (extents.height/2 + extents.y_bearing));
+ cairo_show_text (cr_region, buf);
+
+ region[i] = cairo_surface_reference (cairo_get_target (cr_region));
+ cairo_destroy (cr_region);
+ }
+
+ for (i = 0; i < 5; i++) {
+ cairo_set_source_surface (cr, region[5-i-1], 20 * i, 20);
+ cairo_paint (cr);
+ }
+
+ for (i = 0; i < 5; i++) {
+ cairo_set_source_surface (cr, region[5-i-1], 20 * i, 40);
+ cairo_paint_with_alpha (cr, .5);
+ }
+
+ for (i = 0; i < 5; i++)
+ cairo_surface_destroy (region[i]);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (subsurface,
+ "Tests clipping of both source and destination using subsurfaces",
+ "subsurface", /* keywords */
+ "target=raster", /* FIXME! recursion bug in subsurface/snapshot (with pdf backend) */ /* requirements */
+ 100, 60,
+ NULL, draw)
diff --git a/test/surface-finish-twice.c b/test/surface-finish-twice.c
new file mode 100644
index 000000000..f63b50175
--- /dev/null
+++ b/test/surface-finish-twice.c
@@ -0,0 +1,79 @@
+/*
+ * Copyright © 2005 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl Worth <cworth@cworth.org>
+ */
+
+/* Bug history
+ *
+ * 2005-04-10 stevech1097@yahoo.com.au
+ *
+ * Subject: [Bug 2950] New: *** glibc detected *** double free or corruption
+ * URL: https://bugs.freedesktop.org/show_bug.cgi?id=2950
+ *
+ * The following short program gives the error message:
+ *
+ * *** glibc detected *** double free or corruption: 0x082a7268 ***
+ * Aborted
+ *
+ * 2005-04-13 Carl Worth <cworth@cworth.org>
+ *
+ * Looks like surface->finished was never being set. Now fixed.
+ */
+
+#include "cairo-test.h"
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ const cairo_test_context_t *ctx = cairo_test_get_context (cr);
+ cairo_surface_t *surface;
+ cairo_status_t status;
+
+ surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 1, 1);
+
+ cairo_surface_finish (surface);
+ status = cairo_surface_status (surface);
+ if (status != CAIRO_STATUS_SUCCESS)
+ return cairo_test_status_from_status (ctx, status);
+
+ cairo_surface_finish (surface);
+ status = cairo_surface_status (surface);
+ if (status != CAIRO_STATUS_SUCCESS)
+ return cairo_test_status_from_status (ctx, status);
+
+ cairo_surface_finish (surface);
+ status = cairo_surface_status (surface);
+ if (status != CAIRO_STATUS_SUCCESS)
+ return cairo_test_status_from_status (ctx, status);
+
+ cairo_surface_destroy (surface);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (surface_finish_twice,
+ "Test to exercise a crash when calling cairo_surface_finish twice on the same surface.",
+ "api", /* keywords */
+ NULL, /* requirements */
+ 0, 0,
+ NULL, draw)
diff --git a/test/surface-pattern-big-scale-down.c b/test/surface-pattern-big-scale-down.c
new file mode 100644
index 000000000..698accb6f
--- /dev/null
+++ b/test/surface-pattern-big-scale-down.c
@@ -0,0 +1,125 @@
+/*
+ * Copyright © 2006 Mozilla Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Mozilla Corporation not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Mozilla Corporation makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * MOZILLA CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL MOZILLA CORPORATION BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Vladimir Vukicevic <vladimir@pobox.com>
+ */
+
+#include "cairo-test.h"
+
+#define SRC_WIDTH 2048
+#define SRC_HEIGHT 32
+
+static cairo_surface_t *
+create_source_surface (int w, int h)
+{
+ cairo_surface_t *surface;
+ cairo_t *cr;
+
+ surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, SRC_WIDTH, SRC_HEIGHT);
+ cr = cairo_create (surface);
+ cairo_surface_destroy (surface);
+
+ cairo_set_source_rgb (cr, 1.0, 0.0, 0.0);
+ cairo_rectangle (cr, 0, 0, w/2, h/2);
+ cairo_fill (cr);
+
+ cairo_set_source_rgb (cr, 0.0, 1.0, 0.0);
+ cairo_rectangle (cr, w/2, 0, w/2, h/2);
+ cairo_fill (cr);
+
+ cairo_set_source_rgb (cr, 0.0, 0.0, 1.0);
+ cairo_rectangle (cr, 0, h/2, w/2, h/2);
+ cairo_fill (cr);
+
+ cairo_set_source_rgb (cr, 1.0, 1.0, 0.0);
+ cairo_rectangle (cr, w/2, h/2, w/2, h/2);
+ cairo_fill (cr);
+
+ surface = cairo_surface_reference (cairo_get_target (cr));
+ cairo_destroy (cr);
+
+ return surface;
+}
+
+static void
+draw_n (cairo_t *cr, cairo_pattern_t *pat, double dest_size, int n)
+{
+ cairo_matrix_t mat;
+
+ cairo_matrix_init_scale (&mat, SRC_WIDTH / dest_size, SRC_HEIGHT / dest_size);
+ cairo_matrix_translate (&mat, n * -dest_size, 0.0);
+ cairo_pattern_set_matrix (pat, &mat);
+
+ cairo_set_source (cr, pat);
+ cairo_new_path (cr);
+ cairo_rectangle (cr, n * dest_size, 0.0, dest_size, dest_size);
+ cairo_fill (cr);
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_surface_t *surface;
+ cairo_pattern_t *pat;
+
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ cairo_paint (cr);
+
+ surface = create_source_surface (SRC_WIDTH, SRC_HEIGHT);
+
+ pat = cairo_pattern_create_for_surface (surface);
+ cairo_surface_destroy (surface);
+
+ /* We want to draw at a position such that n * SRC_WIDTH * (SRC_WIDTH/16.0) > 32768.
+ * x = n * 16.
+ *
+ * To show the bug, we want to draw on either side of the boundary;
+ * in our case here, n = 16 results in 32768, and n = 17 results in > 32768.
+ *
+ * Drawing at 16 and 17 is sufficient to show the problem.
+ */
+
+#if 1
+ /* n = 16 */
+ draw_n (cr, pat, 16.0, 16);
+
+ /* n = 17 */
+ draw_n (cr, pat, 16.0, 17);
+#else
+ {
+ int n;
+ for (n = 0; n < 32; n++)
+ draw_n (cr, pat, 16.0, n);
+ }
+#endif
+
+ cairo_pattern_destroy (pat);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (surface_pattern_big_scale_down,
+ "Test scaled-down transformed not-repeated surface patterns with large images and offsets",
+ "transform", /* keywords */
+ NULL, /* requirements */
+ 512, 16,
+ NULL, draw)
diff --git a/test/surface-pattern-operator.c b/test/surface-pattern-operator.c
new file mode 100644
index 000000000..994baf92e
--- /dev/null
+++ b/test/surface-pattern-operator.c
@@ -0,0 +1,119 @@
+/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */
+/*
+ * Copyright 2009 Andrea Canciani
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Andrea Canciani <ranma42@gmail.com>
+ */
+
+#include "cairo-test.h"
+
+#define N_OPERATORS (CAIRO_OPERATOR_SATURATE + 1)
+#define HEIGHT 16
+#define WIDTH 16
+#define PAD 3
+
+static cairo_pattern_t*
+_create_pattern (cairo_surface_t *target, cairo_content_t content, int width, int height)
+{
+ cairo_pattern_t *pattern;
+ cairo_surface_t *surface;
+ cairo_t *cr;
+
+ surface = cairo_surface_create_similar (target, content, width, height);
+ cr = cairo_create (surface);
+ cairo_surface_destroy (surface);
+
+ cairo_set_source_rgb (cr, 1, 0, 0);
+ cairo_arc (cr, 0.5 * width, 0.5 * height, 0.45 * height, -M_PI / 4, 3 * M_PI / 4);
+ cairo_fill (cr);
+
+ pattern = cairo_pattern_create_for_surface (cairo_get_target (cr));
+ cairo_destroy (cr);
+
+ return pattern;
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_pattern_t *alpha_pattern, *color_alpha_pattern, *pattern;
+ unsigned int n, i;
+
+ alpha_pattern = _create_pattern (cairo_get_target (cr),
+ CAIRO_CONTENT_ALPHA,
+ 0.9 * WIDTH, 0.9 * HEIGHT);
+ color_alpha_pattern = _create_pattern (cairo_get_target (cr),
+ CAIRO_CONTENT_COLOR_ALPHA,
+ 0.9 * WIDTH, 0.9 * HEIGHT);
+
+ pattern = cairo_pattern_create_linear (WIDTH, 0, 0, HEIGHT);
+ cairo_pattern_add_color_stop_rgba (pattern, 0.2, 0, 0, 1, 1);
+ cairo_pattern_add_color_stop_rgba (pattern, 0.8, 0, 0, 1, 0);
+
+ cairo_translate (cr, PAD, PAD);
+
+ for (n = 0; n < N_OPERATORS; n++) {
+ cairo_save (cr);
+ for (i = 0; i < 4; i++) {
+ cairo_reset_clip (cr);
+ cairo_rectangle (cr, 0, 0, WIDTH, HEIGHT);
+ cairo_clip (cr);
+
+ cairo_set_source (cr, pattern);
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+ if (i & 2) {
+ cairo_paint (cr);
+ } else {
+ cairo_rectangle (cr, WIDTH/2, HEIGHT/2, WIDTH, HEIGHT);
+ cairo_fill (cr);
+ }
+
+ cairo_set_source (cr, i & 1 ? alpha_pattern : color_alpha_pattern);
+ cairo_set_operator (cr, n);
+ if (i & 2) {
+ cairo_paint (cr);
+ } else {
+ cairo_rectangle (cr, WIDTH/2, HEIGHT/2, WIDTH, HEIGHT);
+ cairo_fill (cr);
+ }
+
+ cairo_translate (cr, 0, HEIGHT+PAD);
+ }
+ cairo_restore (cr);
+
+ cairo_translate (cr, WIDTH+PAD, 0);
+ }
+
+ cairo_pattern_destroy (pattern);
+ cairo_pattern_destroy (alpha_pattern);
+ cairo_pattern_destroy (color_alpha_pattern);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (surface_pattern_operator,
+ "Tests alpha-only and alpha-color sources with all operators",
+ "surface, pattern, operator", /* keywords */
+ NULL, /* requirements */
+ (WIDTH+PAD) * N_OPERATORS + PAD, 4*HEIGHT + 5*PAD,
+ NULL, draw)
diff --git a/test/surface-pattern-scale-down-extend.c b/test/surface-pattern-scale-down-extend.c
new file mode 100644
index 000000000..191ab927f
--- /dev/null
+++ b/test/surface-pattern-scale-down-extend.c
@@ -0,0 +1,120 @@
+/*
+ * Copyright © 2010 M Joonas Pihlaja
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: M Joonas Pihlaja <jpihlaja@cc.helsinki.fi>
+ */
+#include "cairo-test.h"
+
+/* Test that we can simultaneously downscale and extend a surface
+ * pattern. Reported by Franz Schmid to the cairo mailing list as a
+ * regression in 1.9.6:
+ *
+ * http://lists.cairographics.org/archives/cairo/2010-February/019492.html
+ */
+
+static cairo_test_status_t
+draw_with_extend (cairo_t *cr, int w, int h, cairo_extend_t extend)
+{
+ cairo_pattern_t *pattern;
+ cairo_set_source_rgb (cr, 1,1,1);
+ cairo_paint (cr);
+
+ cairo_save (cr);
+
+ /* When the destination surface is created by cairo-test-suite to
+ * test device-offset, it is bigger than w x h. This test expects
+ * the group to have a size which is exactly w x h, so it must
+ * clip to the this rectangle to guarantee that the group will
+ * have the correct size.
+ */
+ cairo_rectangle (cr, 0, 0, w, h);
+ cairo_clip (cr);
+
+ cairo_push_group_with_content (cr, CAIRO_CONTENT_COLOR); {
+ /* A two by two checkerboard with black, red and yellow
+ * cells. */
+ cairo_set_source_rgb (cr, 1,0,0);
+ cairo_rectangle (cr, w/2, 0, w-w/2, h/2);
+ cairo_fill (cr);
+ cairo_set_source_rgb (cr, 1,1,0);
+ cairo_rectangle (cr, 0, h/2, w/2, h-h/2);
+ cairo_fill (cr);
+ }
+ pattern = cairo_pop_group (cr);
+ cairo_pattern_set_extend(pattern, extend);
+
+ cairo_restore (cr);
+
+ cairo_scale (cr, 0.5, 0.5);
+ cairo_set_source (cr, pattern);
+ cairo_paint (cr);
+
+ cairo_pattern_destroy (pattern);
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+draw_repeat (cairo_t *cr, int w, int h)
+{
+ return draw_with_extend (cr, w, h, CAIRO_EXTEND_REPEAT);
+}
+static cairo_test_status_t
+draw_none (cairo_t *cr, int w, int h)
+{
+ return draw_with_extend (cr, w, h, CAIRO_EXTEND_NONE);
+}
+static cairo_test_status_t
+draw_reflect (cairo_t *cr, int w, int h)
+{
+ return draw_with_extend (cr, w, h, CAIRO_EXTEND_REFLECT);
+}
+static cairo_test_status_t
+draw_pad (cairo_t *cr, int w, int h)
+{
+ return draw_with_extend (cr, w, h, CAIRO_EXTEND_PAD);
+}
+
+CAIRO_TEST (surface_pattern_scale_down_extend_repeat,
+ "Test interaction of downscaling a surface pattern and extend-repeat",
+ "pattern, transform, extend", /* keywords */
+ NULL, /* requirements */
+ 100, 100,
+ NULL, draw_repeat)
+CAIRO_TEST (surface_pattern_scale_down_extend_none,
+ "Test interaction of downscaling a surface pattern and extend-none",
+ "pattern, transform, extend", /* keywords */
+ NULL, /* requirements */
+ 100, 100,
+ NULL, draw_none)
+CAIRO_TEST (surface_pattern_scale_down_extend_reflect,
+ "Test interaction of downscaling a surface pattern and extend-reflect",
+ "pattern, transform, extend", /* keywords */
+ NULL, /* requirements */
+ 100, 100,
+ NULL, draw_reflect)
+CAIRO_TEST (surface_pattern_scale_down_extend_pad,
+ "Test interaction of downscaling a surface pattern and extend-pad",
+ "pattern, transform, extend", /* keywords */
+ NULL, /* requirements */
+ 100, 100,
+ NULL, draw_pad)
diff --git a/test/surface-pattern-scale-down.c b/test/surface-pattern-scale-down.c
new file mode 100644
index 000000000..95782efb1
--- /dev/null
+++ b/test/surface-pattern-scale-down.c
@@ -0,0 +1,88 @@
+/*
+ * Copyright © 2007 Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Behdad Esfahbod <behdad@behdad.org>
+ */
+
+#include "cairo-test.h"
+#include <math.h>
+#include <stdio.h>
+
+#define SIZE 200
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_surface_t *surface;
+ cairo_t * cr_surface;
+ int surface_size = 300;
+
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ cairo_paint (cr);
+
+ /* Create an image surface with my favorite four colors in each
+ * quadrant. */
+ surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24,
+ surface_size, surface_size);
+ cr_surface = cairo_create (surface);
+ cairo_surface_destroy (surface);
+
+ cairo_set_source_rgb (cr_surface, 1, 1, 1);
+ cairo_rectangle (cr_surface,
+ 0, 0,
+ surface_size / 2, surface_size / 2);
+ cairo_fill (cr_surface);
+ cairo_set_source_rgb (cr_surface, 1, 0, 0);
+ cairo_rectangle (cr_surface,
+ surface_size / 2, 0,
+ surface_size / 2, surface_size / 2);
+ cairo_fill (cr_surface);
+ cairo_set_source_rgb (cr_surface, 0, 1, 0);
+ cairo_rectangle (cr_surface,
+ 0, surface_size / 2,
+ surface_size / 2, surface_size / 2);
+ cairo_fill (cr_surface);
+ cairo_set_source_rgb (cr_surface, 0, 0, 1);
+ cairo_rectangle (cr_surface,
+ surface_size / 2, surface_size / 2,
+ surface_size / 2, surface_size / 2);
+ cairo_fill (cr_surface);
+
+ cairo_scale (cr, 0.2, 0.2);
+ cairo_rotate (cr, 1.);
+ cairo_set_source_surface (cr, cairo_get_target (cr_surface), 225, -225);
+ cairo_destroy (cr_surface);
+
+ cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_NONE);
+ cairo_paint (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (surface_pattern_scale_down,
+ "Test scaled-down transformed not-repeated surface patterns"
+ "\nFails xlib backend (with argb32) with inexplicable alpha in result",
+ "transform", /* keywords */
+ NULL, /* requirements */
+ SIZE, SIZE,
+ NULL, draw)
diff --git a/test/surface-pattern-scale-up.c b/test/surface-pattern-scale-up.c
new file mode 100644
index 000000000..0d71ba150
--- /dev/null
+++ b/test/surface-pattern-scale-up.c
@@ -0,0 +1,93 @@
+/*
+ * Copyright © 2007 Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Behdad Esfahbod <behdad@behdad.org>
+ */
+
+/* Exhibits nasty behaviour with GS due as their /Interpolate implementation
+ * does not function for rotated images. */
+
+#include "cairo-test.h"
+#include <math.h>
+#include <stdio.h>
+
+#define SIZE 100
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_surface_t *surface;
+ cairo_t * cr_surface;
+ int surface_size = 6;
+
+ /* Fill the background with grey, so that it's easily visible when
+ * things get overdrawn */
+ cairo_set_source_rgb (cr, 0.5, 0.5, 0.5);
+ cairo_paint (cr);
+
+ /* Create an image surface with my favorite four colors in each
+ * quadrant. */
+ surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24,
+ surface_size, surface_size);
+ cr_surface = cairo_create (surface);
+ cairo_surface_destroy (surface);
+
+ cairo_set_source_rgb (cr_surface, 1, 1, 1);
+ cairo_rectangle (cr_surface,
+ 0, 0,
+ surface_size / 2, surface_size / 2);
+ cairo_fill (cr_surface);
+ cairo_set_source_rgb (cr_surface, 1, 0, 0);
+ cairo_rectangle (cr_surface,
+ surface_size / 2, 0,
+ surface_size / 2, surface_size / 2);
+ cairo_fill (cr_surface);
+ cairo_set_source_rgb (cr_surface, 0, 1, 0);
+ cairo_rectangle (cr_surface,
+ 0, surface_size / 2,
+ surface_size / 2, surface_size / 2);
+ cairo_fill (cr_surface);
+ cairo_set_source_rgb (cr_surface, 0, 0, 1);
+ cairo_rectangle (cr_surface,
+ surface_size / 2, surface_size / 2,
+ surface_size / 2, surface_size / 2);
+ cairo_fill (cr_surface);
+
+ cairo_scale (cr, 10, 10);
+ cairo_rotate (cr, 1.);
+ cairo_set_source_surface (cr, cairo_get_target (cr_surface), 4, -4.5);
+ cairo_destroy (cr_surface);
+
+ cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_NONE);
+ cairo_paint (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (surface_pattern_scale_up,
+ "Test scaled-up transformed not-repeated surface patterns"
+ "\nFails xlib backend (with argb32) with inexplicable alpha in result",
+ "transform", /* keywords */
+ NULL, /* requirements */
+ SIZE, SIZE,
+ NULL, draw)
diff --git a/test/surface-pattern.c b/test/surface-pattern.c
new file mode 100644
index 000000000..725f68d00
--- /dev/null
+++ b/test/surface-pattern.c
@@ -0,0 +1,90 @@
+/*
+ * Copyright © 2007 Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Behdad Esfahbod <behdad@behdad.org>
+ */
+
+#include "cairo-test.h"
+#include <math.h>
+#include <stdio.h>
+
+#define SIZE 140
+/* Note GhostScript does not support /Interpolate on rotated images, so the PS
+ * output looks terrible, but is a known issue. */
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_surface_t *surface;
+ cairo_t * cr_surface;
+ int surface_size = 6;
+
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ cairo_paint (cr);
+
+ /* Create an image surface with my favorite four colors in each
+ * quadrant. */
+ surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24,
+ surface_size, surface_size);
+ cr_surface = cairo_create (surface);
+ cairo_surface_destroy (surface);
+
+ cairo_set_source_rgb (cr_surface, 1, 1, 1);
+ cairo_rectangle (cr_surface,
+ 0, 0,
+ surface_size / 2, surface_size / 2);
+ cairo_fill (cr_surface);
+ cairo_set_source_rgb (cr_surface, 1, 0, 0);
+ cairo_rectangle (cr_surface,
+ surface_size / 2, 0,
+ surface_size / 2, surface_size / 2);
+ cairo_fill (cr_surface);
+ cairo_set_source_rgb (cr_surface, 0, 1, 0);
+ cairo_rectangle (cr_surface,
+ 0, surface_size / 2,
+ surface_size / 2, surface_size / 2);
+ cairo_fill (cr_surface);
+ cairo_set_source_rgb (cr_surface, 0, 0, 1);
+ cairo_rectangle (cr_surface,
+ surface_size / 2, surface_size / 2,
+ surface_size / 2, surface_size / 2);
+ cairo_fill (cr_surface);
+
+ cairo_scale (cr, 10, 10);
+ cairo_rotate (cr, 1.);
+ cairo_set_source_surface (cr, cairo_get_target (cr_surface), 1.5, 1.5);
+ cairo_destroy (cr_surface);
+
+ cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_REPEAT);
+ cairo_paint (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (surface_pattern,
+ "Test transformed repeated surface patterns"
+ "\nExhibiting a strange (very minor) failure in ps backend with device-offset",
+ "transform", /* keywords */
+ NULL, /* requirements */
+ SIZE, SIZE,
+ NULL, draw)
diff --git a/test/surface-source.c b/test/surface-source.c
new file mode 100644
index 000000000..657a0c88e
--- /dev/null
+++ b/test/surface-source.c
@@ -0,0 +1,170 @@
+/*
+ * Copyright © 2008 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Chris Wilson not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Chris Wilson makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+static cairo_surface_t *create_source_surface (int size);
+
+/* We use a relatively large source to exercise bug:
+ * Bug 7360 painting huge surfaces fails
+ * [https://bugs.freedesktop.org/show_bug.cgi?id=7360]
+ * but still keep the resultant image small for reasonably quick checking.
+ */
+#define SOURCE_SIZE 2000
+#define INTER_SIZE 512
+#define SIZE 96
+
+static void
+draw_pattern (cairo_surface_t **surface_inout, int surface_size)
+{
+ cairo_t *cr;
+ int mid = surface_size/2;
+
+ cr = cairo_create (*surface_inout);
+ cairo_surface_destroy (*surface_inout);
+
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_set_source_rgba (cr, 0, 0, 0, 0);
+ cairo_paint (cr);
+
+ cairo_rectangle (cr, 0, 0, surface_size, surface_size);
+ cairo_rectangle (cr, mid - SIZE/4, mid + SIZE/4, SIZE/2, -SIZE/2);
+ cairo_clip (cr);
+
+ /* outside squares -> opaque */
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_rectangle (cr,
+ 0, 0,
+ surface_size / 2, surface_size / 2);
+ cairo_fill (cr);
+ cairo_set_source_rgb (cr, 1, 0, 0);
+ cairo_rectangle (cr,
+ surface_size / 2, 0,
+ surface_size / 2, surface_size / 2);
+ cairo_fill (cr);
+ cairo_set_source_rgb (cr, 0, 1, 0);
+ cairo_rectangle (cr,
+ 0, surface_size / 2,
+ surface_size / 2, surface_size / 2);
+ cairo_fill (cr);
+ cairo_set_source_rgb (cr, 0, 0, 1);
+ cairo_rectangle (cr,
+ surface_size / 2, surface_size / 2,
+ surface_size / 2, surface_size / 2);
+ cairo_fill (cr);
+
+ cairo_reset_clip (cr);
+ cairo_rectangle (cr, mid - SIZE/4, mid - SIZE/4, SIZE/2, SIZE/2);
+ cairo_clip (cr);
+
+ /* inside squares -> translucent */
+ cairo_set_source_rgba (cr, 0, 0, 1, .5);
+ cairo_rectangle (cr,
+ 0, 0,
+ surface_size / 2, surface_size / 2);
+ cairo_fill (cr);
+ cairo_set_source_rgba (cr, 0, 1, 0, .5);
+ cairo_rectangle (cr,
+ surface_size / 2, 0,
+ surface_size / 2, surface_size / 2);
+ cairo_fill (cr);
+ cairo_set_source_rgba (cr, 1, 0, 0, .5);
+ cairo_rectangle (cr,
+ 0, surface_size / 2,
+ surface_size / 2, surface_size / 2);
+ cairo_fill (cr);
+ cairo_set_source_rgba (cr, 1, 1, 1, .5);
+ cairo_rectangle (cr,
+ surface_size / 2, surface_size / 2,
+ surface_size / 2, surface_size / 2);
+ cairo_fill (cr);
+
+
+ *surface_inout = cairo_surface_reference (cairo_get_target (cr));
+ cairo_destroy (cr);
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_surface_t *surface;
+ cairo_surface_t *similar;
+ cairo_status_t status;
+ cairo_t *cr2;
+
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ cairo_paint (cr);
+
+ surface = create_source_surface (SOURCE_SIZE);
+ if (surface == NULL) /* can't create the source so skip the test */
+ return CAIRO_TEST_UNTESTED;
+
+ draw_pattern (&surface, SOURCE_SIZE);
+
+ /* copy a subregion to a smaller intermediate surface */
+ similar = cairo_surface_create_similar (surface,
+ CAIRO_CONTENT_COLOR_ALPHA,
+ INTER_SIZE, INTER_SIZE);
+ cr2 = cairo_create (similar);
+ cairo_surface_destroy (similar);
+ cairo_set_source_surface (cr2, surface,
+ (INTER_SIZE - SOURCE_SIZE)/2,
+ (INTER_SIZE - SOURCE_SIZE)/2);
+ cairo_paint (cr2);
+
+ /* and then paint onto a small surface for checking */
+ cairo_set_source_surface (cr, cairo_get_target (cr2),
+ (width - INTER_SIZE)/2,
+ (height - INTER_SIZE)/2);
+ cairo_destroy (cr2);
+ cairo_rectangle (cr, 16, 16, 64, 64);
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_fill (cr);
+
+ /* destroy the surface last, as this triggers XCloseDisplay */
+ cairo_surface_finish (surface);
+ status = cairo_surface_status (surface);
+ cairo_surface_destroy (surface);
+
+ return cairo_test_status_from_status (cairo_test_get_context (cr),
+ status);
+}
+
+static cairo_test_status_t
+preamble (cairo_test_context_t *ctx)
+{
+ cairo_surface_t *surface;
+ cairo_status_t status;
+
+ surface = create_source_surface (SOURCE_SIZE);
+ if (surface == NULL) /* can't create the source so skip the test */
+ return CAIRO_TEST_UNTESTED;
+
+ cairo_surface_finish (surface);
+ status = cairo_surface_status (surface);
+ cairo_surface_destroy (surface);
+
+ return cairo_test_status_from_status (ctx, status);
+}
diff --git a/test/svg-clip.c b/test/svg-clip.c
new file mode 100644
index 000000000..dff65f7cc
--- /dev/null
+++ b/test/svg-clip.c
@@ -0,0 +1,152 @@
+/*
+ * Copyright © 2005 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Kristian Høgsberg <krh@redhat.com>
+ */
+
+#include "cairo-test.h"
+
+#include <stdio.h>
+
+#include <cairo-svg.h>
+
+/* Test SVG clipping */
+
+#define WIDTH_IN_POINTS 600
+#define HEIGHT_IN_POINTS 600
+#define BASENAME "svg-clip.out"
+
+static void
+test_clip (cairo_t *cr, double width, double height)
+{
+ cairo_t *cr2;
+
+ /* Basic test; set a square clip and draw a circle to be clipped
+ * against it.*/
+
+ cairo_rectangle (cr, 100, 100, 400, 400);
+ cairo_clip (cr);
+ cairo_arc (cr, 300, 300, 210, 0, 2 * M_PI);
+ cairo_set_source_rgb (cr, 1, 0, 0);
+ cairo_fill (cr);
+
+ /* Add a plus shaped clip path to the square clip and draw a big
+ * green square to test the new clip path. */
+
+ cairo_save (cr);
+
+ cairo_rectangle (cr, 250, 100, 100, 400);
+ cairo_rectangle (cr, 100, 250, 400, 100);
+ cairo_clip (cr);
+
+ cairo_rectangle (cr, 0, 0, 600, 600);
+ cairo_set_source_rgb (cr, 0, 1, 0);
+ cairo_fill (cr);
+
+ cairo_restore (cr);
+
+ /* Set a bezier shape in addition to the rectangle clip set before
+ * the cairo_save() to verify that we successfully removed the
+ * plus shaped clip path and can set a new clip.*/
+
+ cairo_move_to (cr, 600, 0);
+ cairo_curve_to (cr, 300, 600, 0, 300, 600, 0);
+ cairo_clip (cr);
+
+ cairo_rectangle (cr, 0, 0, 600, 600);
+ cairo_set_source_rgb (cr, 0, 0, 1);
+ cairo_fill (cr);
+
+ /* Create a new context for this surface to test overlapped
+ * drawing from two contexts */
+ cr2 = cairo_create (cairo_get_group_target (cr));
+
+ /* Using the new context, draw a black vertical line, which should
+ * appear unclipped on top of everything drawn so far. */
+ cairo_move_to (cr2, 110, 0);
+ cairo_line_to (cr2, 110, 600);
+ cairo_stroke (cr2);
+
+ /* Using the first context, draw another black vertical line.
+ * This line should be clipped agaist the bezier clipping path set
+ * earlier. */
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ cairo_move_to (cr, 400, 0);
+ cairo_line_to (cr, 400, 600);
+ cairo_stroke (cr);
+
+ cairo_destroy (cr2);
+
+ /* Test reset clip. Draw a transparent black circle over
+ * everything. Specifically, make sure the circle extends outside
+ * the square clip set at the top of this function. */
+ cairo_reset_clip (cr);
+ cairo_arc (cr, 300, 300, 220, 0, 2 * M_PI);
+ cairo_set_source_rgba (cr, 0, 0, 0, 0.2);
+ cairo_fill (cr);
+}
+
+static cairo_test_status_t
+preamble (cairo_test_context_t *ctx)
+{
+ cairo_t *cr;
+ cairo_surface_t *surface;
+ char *filename;
+ const char *path = cairo_test_mkdir (CAIRO_TEST_OUTPUT_DIR) ? CAIRO_TEST_OUTPUT_DIR : ".";
+
+ if (! cairo_test_is_target_enabled (ctx, "svg11") &&
+ ! cairo_test_is_target_enabled (ctx, "svg12"))
+ {
+ return CAIRO_TEST_UNTESTED;
+ }
+
+ xasprintf (&filename, "%s/%s.svg", path, BASENAME);
+ surface = cairo_svg_surface_create (filename,
+ WIDTH_IN_POINTS, HEIGHT_IN_POINTS);
+ if (cairo_surface_status (surface)) {
+ cairo_test_log (ctx,
+ "Failed to create svg surface for file %s: %s\n",
+ filename, cairo_status_to_string (cairo_surface_status (surface)));
+ free (filename);
+ return CAIRO_TEST_FAILURE;
+ }
+
+ cr = cairo_create (surface);
+
+ test_clip (cr, WIDTH_IN_POINTS, HEIGHT_IN_POINTS);
+ cairo_show_page (cr);
+
+ cairo_destroy (cr);
+ cairo_surface_destroy (surface);
+
+ printf ("svg-clip: Please check %s to make sure it looks happy.\n",
+ filename);
+ free (filename);
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (svg_clip,
+ "Test SVG clipping",
+ "svg, clip", /* keywords */
+ NULL, /* requirements */
+ 0, 0,
+ preamble, NULL)
diff --git a/test/svg-surface-source.c b/test/svg-surface-source.c
new file mode 100644
index 000000000..3c7730f7f
--- /dev/null
+++ b/test/svg-surface-source.c
@@ -0,0 +1,54 @@
+/*
+ * Copyright © 2008 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Chris Wilson not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Chris Wilson makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+#include <cairo-svg.h>
+
+#include "surface-source.c"
+
+#define BASENAME "svg-surface-source.out"
+
+static cairo_surface_t *
+create_source_surface (int size)
+{
+ cairo_surface_t *surface;
+ char *filename;
+ const char *path = cairo_test_mkdir (CAIRO_TEST_OUTPUT_DIR) ? CAIRO_TEST_OUTPUT_DIR : ".";
+
+ xasprintf (&filename, "%s/%s.svg", path, BASENAME);
+ surface = cairo_svg_surface_create (filename,
+ size, size);
+ cairo_surface_set_fallback_resolution (surface, 72., 72.);
+ free (filename);
+
+ return surface;
+}
+
+CAIRO_TEST (svg_surface_source,
+ "Test using a SVG surface as the source",
+ "source", /* keywords */
+ NULL, /* requirements */
+ SIZE, SIZE,
+ preamble, draw)
diff --git a/test/svg-surface.c b/test/svg-surface.c
new file mode 100644
index 000000000..13b006d39
--- /dev/null
+++ b/test/svg-surface.c
@@ -0,0 +1,136 @@
+/*
+ * Copyright © 2005 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+#include "cairo-test.h"
+
+#include <stdio.h>
+
+#include <cairo-svg.h>
+
+/* Pretty boring test just to make sure things aren't crashing ---
+ * no verification that we're getting good results yet.
+ * But you can manually view the image to make sure it looks happy.
+ */
+
+#define WIDTH_IN_INCHES 3
+#define HEIGHT_IN_INCHES 3
+#define WIDTH_IN_POINTS (WIDTH_IN_INCHES * 72)
+#define HEIGHT_IN_POINTS (HEIGHT_IN_INCHES * 72)
+#define BASENAME "svg-surface.out"
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+#define STROKE_WIDTH .04
+
+ double size;
+
+ if (width > height)
+ size = height;
+ else
+ size = width;
+
+ cairo_translate (cr, (width - size) / 2.0, (height - size) / 2.0);
+ cairo_scale (cr, size, size);
+
+ /* Fill face */
+ cairo_arc (cr, 0.5, 0.5, 0.5 - STROKE_WIDTH, 0, 2 * M_PI);
+ cairo_set_source_rgb (cr, 1, 1, 0);
+ cairo_save (cr);
+ {
+ cairo_fill (cr);
+ }
+ cairo_restore (cr);
+
+ cairo_set_source_rgb (cr, 0, 0, 0);
+
+ /* Stroke face */
+ cairo_set_line_width (cr, STROKE_WIDTH / 2.0);
+ cairo_stroke (cr);
+
+ /* Eyes */
+ cairo_set_line_width (cr, STROKE_WIDTH);
+ cairo_arc (cr, 0.3, 0.4, STROKE_WIDTH, 0, 2 * M_PI);
+ cairo_fill (cr);
+ cairo_arc (cr, 0.7, 0.4, STROKE_WIDTH, 0, 2 * M_PI);
+ cairo_fill (cr);
+
+ /* Mouth */
+ cairo_move_to (cr, 0.3, 0.7);
+ cairo_curve_to (cr,
+ 0.4, 0.8,
+ 0.6, 0.8,
+ 0.7, 0.7);
+ cairo_stroke (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+preamble (cairo_test_context_t *ctx)
+{
+ cairo_t *cr;
+ cairo_surface_t *surface;
+ char *filename;
+ const char *path = cairo_test_mkdir (CAIRO_TEST_OUTPUT_DIR) ? CAIRO_TEST_OUTPUT_DIR : ".";
+
+ if (! cairo_test_is_target_enabled (ctx, "svg11") &&
+ ! cairo_test_is_target_enabled (ctx, "svg12"))
+ {
+ return CAIRO_TEST_UNTESTED;
+ }
+
+ xasprintf (&filename, "%s/%s.svg", path, BASENAME);
+ surface = cairo_svg_surface_create (filename,
+ WIDTH_IN_POINTS, HEIGHT_IN_POINTS);
+ if (cairo_surface_status (surface)) {
+ cairo_test_log (ctx,
+ "Failed to create svg surface for file %s: %s\n",
+ filename,
+ cairo_status_to_string (cairo_surface_status (surface)));
+ free (filename);
+ return CAIRO_TEST_FAILURE;
+ }
+
+ cr = cairo_create (surface);
+
+ draw (cr, WIDTH_IN_POINTS, HEIGHT_IN_POINTS);
+
+ cairo_show_page (cr);
+
+ cairo_destroy (cr);
+ cairo_surface_destroy (surface);
+
+ printf ("svg-surface: Please check %s to make sure it looks happy.\n", filename);
+ free (filename);
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (svg_surface,
+ "Check creation of a SVG surface",
+ "svg", /* keywords */
+ NULL, /* requirements */
+ 0, 0,
+ preamble, NULL)
diff --git a/test/svg2png.c b/test/svg2png.c
new file mode 100644
index 000000000..bdfbc8b1e
--- /dev/null
+++ b/test/svg2png.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright © 2005 Red Hat, Inc.
+ * Copyright © 2005 Emmanuel Pacaud <emmanuel.pacaud@free.fr>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Kristian Høgsberg <krh@redhat.com>
+ * Emmanuel Pacaud <emmanuel.pacaud@free.fr>
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <gdk/gdk.h>
+#include <gdk/gdkpixbuf.h>
+#include <librsvg/rsvg.h>
+
+#define FAIL(msg) \
+ do { fprintf (stderr, "FAIL: %s\n", msg); exit (-1); } while (0)
+
+int main (int argc, char *argv[])
+{
+ GError *error = NULL;
+ GdkPixbuf *pixbuf;
+ const char *filename = argv[1];
+ const char *output_filename = argv[2];
+
+ if (argc != 3)
+ FAIL ("usage: svg2png input_file.svg output_file.png");
+
+ g_type_init ();
+
+ error = NULL;
+
+ rsvg_set_default_dpi (72.0);
+ pixbuf = rsvg_pixbuf_from_file (filename, &error);
+ if (error != NULL)
+ FAIL (error->message);
+
+ gdk_pixbuf_save (pixbuf, output_filename, "png", &error, NULL);
+ if (error != NULL)
+ FAIL (error->message);
+
+ g_object_unref (pixbuf);
+ return 0;
+}
diff --git a/test/testsvg b/test/testsvg
new file mode 100755
index 000000000..9b18df586
--- /dev/null
+++ b/test/testsvg
@@ -0,0 +1,51 @@
+#!/bin/sh
+
+IMAGEDIFF=./imagediff
+
+OUTDIR=testsvg-output
+REFDIR=testsvg-reference
+DIFFDIR=testsvg-diff
+IMAGELIST=testsvg-imagelist
+
+if [ $# -lt 1 ]; then
+ argv0=`basename $0`
+ echo "Usage: $argv0 file.svg [...]" >&2
+ exit 1;
+fi
+
+mkdir -p $OUTDIR
+mkdir -p $DIFFDIR
+rm -f $IMAGELIST
+
+err=0
+for svg in $@; do
+ svgbase=`basename $svg`
+ png=${svgbase/\.svg/.png}
+ outpng=$OUTDIR/$png
+ refpng=$REFDIR/$png
+ diffpng=$DIFFDIR/$png
+# if xsvg $svg -p $outpng ; then
+ if svg2png $svg $outpng ; then
+ if [ -e $refpng ]; then
+ if $IMAGEDIFF $refpng $outpng > $diffpng; then
+ echo "Rendering of $svg matches." >&2
+ rm -f $diffpng
+ else
+ echo "ERROR: Rendering of $svg differs from reference image." >&2
+ echo $refpng $outpng $diffpng >> $IMAGELIST
+ err=$(($err+1))
+ fi
+ else
+ echo "WARNING: No reference file found for $svg (looked in $refpng)" >&2
+ fi
+ else
+ echo "ERROR: Failed to render $svg" >&2
+ err=$(($err+1))
+ fi
+done
+
+if [ $err -gt 0 ] ; then
+ echo "Differences found in $err renderings."
+else
+ echo "All renderings matched reference images."
+fi
diff --git a/test/testtable.js b/test/testtable.js
new file mode 100644
index 000000000..4fc664ff2
--- /dev/null
+++ b/test/testtable.js
@@ -0,0 +1,428 @@
+/* configuration */
+/* TODO: UNTESTED count can't be shown because it's not tracked explicitly */
+headerResults = [ "PASS", "NEW", "FAIL", "XFAIL", "CRASHED" ];
+logResults = [ "PASS", "NEW", "FAIL", "XFAIL", "CRASH!" ];
+resultToImgs = {
+ "PASS" : [],
+ "NEW" : [ "output" ],
+ "FAIL" : [ "output", "difference", "reference" ],
+ "XFAIL" : [],
+ "UNTESTED" : [],
+ "CRASHED" : []
+};
+
+resultToString = {
+ "PASS" : "",
+ "NEW" : "",
+ "FAIL" : "",
+ "XFAIL" : "",
+ "UNTESTED" : "",
+ "CRASHED" : "CRASHED!"
+};
+
+resultField = "result";
+rowFields = [ "test", "offset", "scale", "similar" ];
+colFields = [ "target", "format" ];
+allFields = [ resultField ].concat (rowFields, colFields);
+
+
+/* globals: */
+function resetGlobals () {
+ dragElement = undefined;
+ table = document.getElementById ("testTable");
+ while (table.rows.length)
+ table.deleteRow (0);
+ colsArray = [ "HrowHeader" ];
+ colsMap = undefined;
+ headerId = "HcolHeader";
+
+ fTrue = function (x) { return true; };
+
+ empty = new Row ();
+ header = new Row ();
+ header[colsArray[0]].toString = function () { return ""; };
+
+ untested = new Test ();
+ untested[resultField] = "UNTESTED";
+}
+
+
+/* utility functions */
+function isKey (key) { return key[key.length-1] == ':'; }
+function normalizeKey (key) { return key.toLowerCase ().replace (/[^a-z0-9]/, ""); }
+function isVisible (x) { return x.style.display != "none"; }
+
+function link (html, url) { return "<a href='" + url + "'>" + html + "</a>"; }
+function image (url) { return "<img src='" + url + "'>"; }
+function span (html, id, cls) { return "<span id='" + id + "' class='" + cls + "' onmousedown='startDrag (event)' onmouseup='mouseUp (event)'>" + html + "</span>"; }
+
+function fieldsToHTML (bColumns, values) {
+ var fields = bColumns ? colFields : rowFields;
+ var prefix = bColumns ? "c" : "r";
+ var tmpRE = arrayApply (function (x) { return "[^/]*"; }, fields);
+ var r = Array ();
+ for (var i = 0; i < fields.length; i++)
+ if (fields[i] == "test") {
+ r.push (link (values[fields[i]], "output/" + values[fields[i]] + ".log"));
+ } else {
+ tmpRE[i] = values[fields[i]];
+ r.push (span (values[fields[i]], prefix + "/" + tmpRE.join ("/") + "/", fields[i]));
+ tmpRE[i] = "[^/]*";
+ }
+ return r.join ("/");
+}
+
+function inArray (value, array) {
+ for (var i = 0; i < array.length; i++)
+ if (value == array[i])
+ return true;
+ return false;
+}
+
+function arrayApply (fun, array) {
+ var r = new Array ();
+ for (var i = 0; i < array.length; i++)
+ r.push (fun(array[i]));
+ return r;
+}
+
+function arrayPred (pred, array) {
+ var r = new Array ();
+ for (var i = 0; i < array.length; i++)
+ if (pred (array[i]))
+ r.push (array[i]);
+ return r;
+}
+
+function arrayMap (map, array) { return arrayApply (function (x) { return map[x]; }, array); }
+
+function binSearch (rows, newId){
+ var min = 0;
+ var max = rows.length;
+
+ while (max - min > 1) {
+ var mid = (max + min) >> 1;
+ if (rows[mid].id > newId)
+ max = mid;
+ else
+ min = mid;
+ }
+
+ if (max == min)
+ return max;
+ else
+ return rows[min].id > newId ? min : max;
+}
+
+/* dynamic table utils */
+function updateCurrent () {
+ for (var i = 0; i < table.rows.length; i++) {
+ var row = table.rows[i];
+ if (isVisible (row)) {
+ /* j starts from 1 because we want to ignore _rowHeader */
+ for (var j = 1; j < row.cells.length; j++)
+ if (row.id[0] == "H")
+ for (var k = 0; k < headerResults.length; k++)
+ header[row.cells[j].id].current[headerResults[k]] = 0;
+ else if (isVisible (row.cells[j]))
+ header[row.cells[j].id].current[row.cells[j].className]++;
+ }
+ }
+
+ updateHeader ();
+}
+
+function setVisible (array, subsetPred, visibilityPred, visibleFlag) {
+ var modified = false, somethingVisible = false;
+ for (var i = 0; i < array.length; i++)
+ if (array[i].id[0] != "H") {
+ if (subsetPred (array[i])) {
+ var wanted = visibilityPred (array[i]);
+ if (isVisible (array[i]) != wanted) {
+ modified = true;
+ array[i].style.display = wanted ? visibleFlag : "none";
+ }
+ }
+ somethingVisible = somethingVisible || isVisible (array[i]);
+ }
+ return modified && somethingVisible;
+}
+
+function setVisibleOnly (array, pred, visibleFlag) {
+ return setVisible (array, fTrue, pred, visibleFlag);
+}
+
+function flipVisible (array, subsetPred, visibleFlag) {
+ return setVisible (array, subsetPred, function (x) { return !isVisible (x); }, visibleFlag);
+}
+
+
+/* event handling */
+function ignoreEvent (event) {
+ if (event.preventDefault)
+ event.preventDefault();
+ else
+ event.returnValue= false;
+ return false;
+}
+
+function mouseUp (event) {
+ var visFun;
+ if (event.button == 0)
+ visFun = setVisibleOnly;
+ else if (event.button == 2)
+ visFun = flipVisible;
+ else
+ return false;
+
+ var structureFun;
+ if (event.target.id[0] == "r") /* rows */
+ structureFun = function (f, p) { return f (table.rows, p, "table-row"); };
+ else if (event.target.id[0] == "c") /* cols */
+ structureFun = function (f, p) { return inArray (true, arrayApply (function (row) { return f (row.cells, p, "table-cell") }, table.rows)) };
+ else
+ return false;
+
+ var pred;
+ if (event.target.id[1] == "/") { /* regexp */
+ var re = new RegExp (event.target.id);
+ pred = function (x) { return re.test (x.id); };
+ } else if (event.target.id[1] == "#") { /* counters */
+ var s = event.target.id.substr (2).split ("/");
+ pred = function (row) { return row.cells[s[0]].className == s[1]; }
+ } else
+ return false;
+
+ if (!structureFun (visFun, pred))
+ if (!structureFun (flipVisible, fTrue))
+ structureFun (flipVisible, fTrue);
+
+ updateCurrent ();
+
+ return false;
+}
+
+function noDrag (event) {
+ dragElement = undefined;
+ return false;
+}
+
+function startDrag (event) {
+ if (event.button == 0)
+ dragElement = event.target;
+ else
+ dragElement = undefined;
+ return false;
+}
+
+function endDrag (event) {
+ if (!dragElement)
+ return false;
+
+ if (event.currentTarget.id == colsArray[0] &&
+ inArray (dragElement.className, colFields)) {
+ rowFields.push (dragElement.className);
+ colFields = arrayPred (function (x) { return x != dragElement.className; }, colFields);
+ } else if (event.currentTarget.id == headerId &&
+ inArray (dragElement.className, rowFields)) {
+ colFields.push (dragElement.className);
+ rowFields = arrayPred (function (x) { return x != dragElement.className; }, rowFields);
+ } else
+ return true;
+
+ reloadAll ();
+ return false;
+}
+
+
+/* table content */
+function Row (id, t) {
+ this[colsArray[0]] = new RowHeader (id, t);
+
+ this.get = function (c) { return this[c] != undefined ? this[c] : untested; }
+ this.getHTML = function (c) { return this.get(c).toString (); };
+ this.setStyle = function (c, element) { return this.get(c).setStyle (element); };
+}
+
+function ColumnHeader (id, values) {
+ this.id = id;
+ this.values = values;
+ this.total = new Object ();
+ this.current = new Object ();
+
+ for (var i = 0; i < headerResults.length; i++) {
+ this.total[headerResults[i]] = 0;
+ this.current[headerResults[i]] = 0;
+ }
+
+ this.toString = function () {
+ var counts = new Array ();
+ for (var i = 0; i < headerResults.length; i++) {
+ var hr = headerResults[i];
+ var s = span (this.current[hr], "r#" + colsMap[this.id] + "/" + hr, hr);
+ if (this.current[hr] != this.total[hr])
+ s += span ("[" + this.total[hr] + "]", "r#" + colsMap[this.id] + "/" + hr, hr);
+ counts.push (s);
+ }
+
+ return fieldsToHTML (true, this.values) + "<br>" + counts.join ("/");
+ }
+
+ this.setStyle = function (element) { };
+}
+
+function RowHeader (id, values) {
+ this.id = id;
+ this.values = values;
+ this.toString = function () { return fieldsToHTML (false, this.values); }
+ this.setStyle = function (element) { element.onmouseup = endDrag; };
+}
+
+function Test () {
+ this.rowId = function () { return "r/" + arrayMap (this, rowFields).join("/") + "/"; };
+ this.colId = function () { return "c/" + arrayMap (this, colFields).join("/") + "/"; };
+ this.isComplete = function () { return !inArray (undefined, arrayMap (this, allFields)); }
+ this.toString = function () {
+ var images = arrayMap (this, resultToImgs[this[resultField]]);
+ images = arrayPred (function (x) { return x != undefined; }, images);
+ images = arrayApply (function (x) { return link (image (x), x); }, images);
+ images.push (resultToString[this[resultField]]);
+ return images.join (" ");
+ };
+
+ this.setStyle = function (element) { element.className = this[resultField]; };
+
+ this.addData = function (array) {
+ for (var i = 0; i < array.length - 1; i += 2)
+ if (isKey (array[i]))
+ this[normalizeKey (array[i])] = array[i+1];
+ };
+}
+
+
+/* table creation */
+function insertCell (domRow, nid, tests) {
+ var domCell = domRow.insertCell (nid);
+ domCell.id = colsArray[nid];
+ domCell.innerHTML = tests.getHTML (colsArray[nid]);
+ tests.setStyle (colsArray[nid], domCell);
+}
+
+function updateRow (row, tests) {
+ var domRow = document.getElementById (row);
+ if (!domRow) {
+ domRow = table.insertRow (binSearch (table.rows, row));
+ domRow.id = row;
+ }
+
+ for (var i = 0; i < colsArray.length; i++)
+ if (i >= domRow.cells.length || domRow.cells[i].id != colsArray[i])
+ insertCell (domRow, i, tests);
+}
+
+function updateHeader () {
+ var visibility;
+ var domRow = document.getElementById (headerId);
+ if (domRow) {
+ visibility = new Object ();
+ for (var i = 0; i < domRow.cells.length; i++)
+ visibility[domRow.cells[i].id] = domRow.cells[i].style.display;
+ table.deleteRow (domRow.rowIndex);
+ }
+
+ updateRow (headerId, header);
+ table.rows[0].onmouseup = endDrag;
+
+ if (visibility)
+ for (var i = 0; i < colsArray.length; i++)
+ if (visibility[colsArray[i]])
+ table.rows[0].cells[colsMap[colsArray[i]]].style.display = visibility[colsArray[i]];
+}
+
+function updateTable () {
+ colsArray.sort ();
+
+ colsMap = new Object ();
+ for (var i = 0; i < colsArray.length; i++)
+ colsMap[colsArray[i]] = i;
+
+ updateHeader ();
+ for (var i = 0; i < table.rows.length; i++)
+ updateRow (table.rows[i].id, empty);
+}
+
+
+/* log file parsing */
+function parseTest (testData) {
+ var colsChanged = false;
+ var rows = new Array ();
+ var data = new Object ();
+ var t = new Test ();
+ var lines = testData.replace (/\r/g, "").split ("\n");
+ for (var i = 0; i < lines.length; i++) {
+ t.addData (lines[i].split (" "));
+ if (t.isComplete ()) {
+ var c = t.colId ();
+ if (header[c] == undefined) {
+ colsArray.push (c);
+ header[c] = new ColumnHeader (c, t);
+ colsChanged = true;
+ }
+
+ var r = t.rowId ();
+ if (!data[r]) {
+ rows.push (r);
+ data[r] = new Row (r, t);
+ }
+
+ data[r][c] = t;
+ header[c].total[t[resultField]]++;
+ header[c].current[t[resultField]]++;
+ t = new Test ();
+ }
+ }
+
+ if (colsChanged)
+ updateTable ();
+ else
+ updateHeader ();
+
+ for (var i = 0; i < rows.length; i++)
+ updateRow (rows[i], data[rows[i]]);
+}
+
+function parseFile (fileName, parser) {
+ var req = new XMLHttpRequest ();
+ req.onreadystatechange = function () {
+ if (req.readyState == 4)
+ parser (req.responseText);
+ }
+
+ try {
+ req.open ("GET", fileName);
+ req.send (null);
+ } catch (e) {}
+}
+
+function parseTestList (listData) {
+ var summaryRE = /\d+ Passed, \d+ Failed \x5b\d+ crashed, \d+ expected\x5d, \d+ Skipped/;
+ var lines = listData.replace (/\r/g, "").split ("\n");
+ for (var i = 0; i < lines.length; i++) {
+ if (summaryRE.test (lines[i]))
+ return;
+
+ var words = lines[i].split (" ");
+ if (words.length >= 2 &&
+ words[0][words[0].length-1] == ":" &&
+ inArray (words[1], logResults))
+ parseFile ("output/" + words[0].substr (0, words[0].length-1) + ".log", parseTest);
+ }
+}
+
+function reloadAll() {
+ resetGlobals ();
+
+ parseFile ("cairo-test-suite.log", parseTestList);
+}
+
+window.onload = reloadAll;
diff --git a/test/text-antialias-subpixel.c b/test/text-antialias-subpixel.c
new file mode 100644
index 000000000..6a65059eb
--- /dev/null
+++ b/test/text-antialias-subpixel.c
@@ -0,0 +1,123 @@
+/*
+ * Copyright © 2005 Red Hat, Inc.
+ * Copyright © 2011 Uli Schlachter
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Uli Schlachter <psychon@znc.in>
+ *
+ * Based on test/text-antialias.c
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+#include "cairo-test.h"
+
+#define WIDTH 31
+#define HEIGHT 22
+#define TEXT_SIZE 12
+
+static cairo_test_status_t
+draw (cairo_t *cr, cairo_subpixel_order_t order)
+{
+ cairo_text_extents_t extents;
+ cairo_font_options_t *font_options;
+ const char black[] = "black", blue[] = "blue";
+
+ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */
+ cairo_paint (cr);
+
+ cairo_select_font_face (cr, CAIRO_TEST_FONT_FAMILY " Sans",
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_NORMAL);
+ cairo_set_font_size (cr, TEXT_SIZE);
+
+ font_options = cairo_font_options_create ();
+ cairo_get_font_options (cr, font_options);
+ cairo_font_options_set_antialias (font_options, CAIRO_ANTIALIAS_SUBPIXEL);
+ cairo_font_options_set_subpixel_order (font_options, order);
+ cairo_set_font_options (cr, font_options);
+
+ cairo_font_options_destroy (font_options);
+
+ cairo_set_source_rgb (cr, 0, 0, 0); /* black */
+ cairo_text_extents (cr, black, &extents);
+ cairo_move_to (cr, -extents.x_bearing, -extents.y_bearing);
+ cairo_show_text (cr, black);
+ cairo_translate (cr, 0, -extents.y_bearing + 1);
+
+ cairo_set_source_rgb (cr, 0, 0, 1); /* blue */
+ cairo_text_extents (cr, blue, &extents);
+ cairo_move_to (cr, -extents.x_bearing, -extents.y_bearing);
+ cairo_show_text (cr, blue);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+draw_rgb (cairo_t *cr, int width, int height)
+{
+ return draw (cr, CAIRO_SUBPIXEL_ORDER_RGB);
+}
+
+static cairo_test_status_t
+draw_bgr (cairo_t *cr, int width, int height)
+{
+ return draw (cr, CAIRO_SUBPIXEL_ORDER_BGR);
+}
+
+static cairo_test_status_t
+draw_vrgb (cairo_t *cr, int width, int height)
+{
+ return draw (cr, CAIRO_SUBPIXEL_ORDER_VRGB);
+}
+
+static cairo_test_status_t
+draw_vbgr (cairo_t *cr, int width, int height)
+{
+ return draw (cr, CAIRO_SUBPIXEL_ORDER_VBGR);
+}
+
+CAIRO_TEST (text_antialias_subpixel_rgb,
+ "Tests text rendering with rgb subpixel antialiasing",
+ "text", /* keywords */
+ "target=raster", /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw_rgb)
+
+CAIRO_TEST (text_antialias_subpixel_bgr,
+ "Tests text rendering with bgr subpixel antialiasing",
+ "text", /* keywords */
+ "target=raster", /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw_bgr)
+
+CAIRO_TEST (text_antialias_subpixel_vrgb,
+ "Tests text rendering with vertical rgb subpixel antialiasing",
+ "text", /* keywords */
+ "target=raster", /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw_vrgb)
+
+CAIRO_TEST (text_antialias_subpixel_vbgr,
+ "Tests text rendering with vertical bgr subpixel antialiasing",
+ "text", /* keywords */
+ "target=raster", /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw_vbgr)
diff --git a/test/text-antialias.c b/test/text-antialias.c
new file mode 100644
index 000000000..7d338925e
--- /dev/null
+++ b/test/text-antialias.c
@@ -0,0 +1,106 @@
+/*
+ * Copyright © 2005 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+#include "cairo-test.h"
+
+#define WIDTH 31
+#define HEIGHT 22
+#define TEXT_SIZE 12
+
+static cairo_test_status_t
+draw (cairo_t *cr, cairo_antialias_t antialias)
+{
+ cairo_text_extents_t extents;
+ cairo_font_options_t *font_options;
+ const char black[] = "black", blue[] = "blue";
+
+ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */
+ cairo_paint (cr);
+
+ cairo_select_font_face (cr, CAIRO_TEST_FONT_FAMILY " Sans",
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_NORMAL);
+ cairo_set_font_size (cr, TEXT_SIZE);
+
+ font_options = cairo_font_options_create ();
+ cairo_get_font_options (cr, font_options);
+ cairo_font_options_set_antialias (font_options, antialias);
+ cairo_font_options_set_subpixel_order (font_options, CAIRO_SUBPIXEL_ORDER_RGB);
+ cairo_set_font_options (cr, font_options);
+
+ cairo_font_options_destroy (font_options);
+
+ cairo_set_source_rgb (cr, 0, 0, 0); /* black */
+ cairo_text_extents (cr, black, &extents);
+ cairo_move_to (cr, -extents.x_bearing, -extents.y_bearing);
+ cairo_show_text (cr, black);
+ cairo_translate (cr, 0, -extents.y_bearing + 1);
+
+ cairo_set_source_rgb (cr, 0, 0, 1); /* blue */
+ cairo_text_extents (cr, blue, &extents);
+ cairo_move_to (cr, -extents.x_bearing, -extents.y_bearing);
+ cairo_show_text (cr, blue);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+draw_gray (cairo_t *cr, int width, int height)
+{
+ return draw (cr, CAIRO_ANTIALIAS_GRAY);
+}
+
+static cairo_test_status_t
+draw_none (cairo_t *cr, int width, int height)
+{
+ return draw (cr, CAIRO_ANTIALIAS_NONE);
+}
+
+static cairo_test_status_t
+draw_subpixel (cairo_t *cr, int width, int height)
+{
+ return draw (cr, CAIRO_ANTIALIAS_SUBPIXEL);
+}
+
+CAIRO_TEST (text_antialias_gray,
+ "Tests text rendering with grayscale antialiasing",
+ "text", /* keywords */
+ "target=raster", /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw_gray)
+
+CAIRO_TEST (text_antialias_none,
+ "Tests text rendering with no antialiasing",
+ "text", /* keywords */
+ "target=raster", /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw_none)
+
+CAIRO_TEST (text_antialias_subpixel,
+ "Tests text rendering with subpixel antialiasing",
+ "text", /* keywords */
+ "target=raster", /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw_subpixel)
diff --git a/test/text-cache-crash.c b/test/text-cache-crash.c
new file mode 100644
index 000000000..4786af4d5
--- /dev/null
+++ b/test/text-cache-crash.c
@@ -0,0 +1,93 @@
+/*
+ * Copyright © 2004 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+/* Bug history
+ *
+ * 2004-11-04 Ned Konz <ned@squeakland.org>
+ *
+ * Reported bug on mailing list:
+ *
+ * From: Ned Konz <ned@squeakland.org>
+ * To: cairo@cairographics.org
+ * Date: Thu, 4 Nov 2004 09:49:38 -0800
+ * Subject: [cairo] getting assertions [cairo_cache.c:143: _entry_destroy:
+ * Assertion `cache->used_memory > entry->memory' failed]
+ *
+ * The attached program dies on me with the assert
+ *
+ * $ ./testCairo
+ * testCairo: cairo_cache.c:143: _entry_destroy: Assertion `cache->used_memory > entry->memory' failed.
+ *
+ * 2004-11-04 Carl Worth <cworth@cworth.org>
+ *
+ * I trimmed down Ned's example to the folllowing test while still
+ * maintaining the assertion.
+ *
+ * Oh, actually, it looks like I may have triggered something
+ * slightly different:
+ *
+ * text_cache_crash: cairo_cache.c:422: _cairo_cache_lookup: Assertion `cache->max_memory >= (cache->used_memory + new_entry->memory)' failed.
+ *
+ * I'll have to go back and try the original test after I fix this.
+ *
+ * 2004-11-13 Carl Worth <cworth@cworth.org>
+ *
+ * Found the bug. cairo_gstate_select_font was noticing when the
+ * same font was selected twice in a row and was erroneously failing
+ * to free the old reference. Committed a fix and verified it also
+ * fixed the original test case.
+ */
+
+#include "cairo-test.h"
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ /* Once there was a bug that choked when selecting the same font twice. */
+ cairo_select_font_face (cr, "sans",
+ CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
+ cairo_set_font_size (cr, 40.0);
+
+ cairo_select_font_face (cr, "sans",
+ CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
+ cairo_set_font_size (cr, 40.0);
+ cairo_move_to (cr, 10, 50);
+ cairo_show_text (cr, "hello");
+
+ /* Then there was a bug that choked when selecting a font too big
+ * for the cache. */
+
+ cairo_set_font_size (cr, 500);
+ cairo_show_text (cr, "hello");
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (text_cache_crash,
+ "Test case for bug causing an assertion failure in _cairo_cache_lookup",
+ "text, stress", /* keywords */
+ NULL, /* requirements */
+ 0, 0,
+ NULL, draw)
diff --git a/test/text-glyph-range.c b/test/text-glyph-range.c
new file mode 100644
index 000000000..75b87d63a
--- /dev/null
+++ b/test/text-glyph-range.c
@@ -0,0 +1,125 @@
+/* -*- Mode: c; c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t; -*- */
+/* cairo - a vector graphics library with display and print output
+ *
+ * Copyright © 2006 Brian Ewins.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Brian Ewins not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Brian Ewins makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * BRIAN EWINS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL BRIAN EWINS BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Brian Ewins <Brian.Ewins@gmail.com>
+ */
+
+/* Related to bug 9530
+ *
+ * cairo_glyph_t can contain any unsigned long in its 'index', the intention
+ * being that it is large enough to hold a pointer. However, this means that
+ * it can specify many glyph indexes which don't exist in the font, and may
+ * exceed the range of legal glyph indexes for the font backend. It may
+ * also contain special values that are not usable as indexes - e.g. 0xffff is
+ * kATSDeletedGlyphcode in ATSUI, a glyph that should not be drawn.
+ * The font backends should handle all legal and out-of-range values
+ * consistently.
+ *
+ * This test expects that operations on out-of-range and missing glyphs should
+ * act as if they were zero-width.
+ */
+
+#include "cairo-test.h"
+
+#define WIDTH 100
+#define HEIGHT 75
+#define NUM_TEXT 20
+#define TEXT_SIZE 12
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_text_extents_t extents;
+ int i;
+ /* Glyphs with no paths followed by 'cairo', the additional
+ * text is to make the space obvious.
+ */
+ long int index[] = {
+ 0, /* 'no matching glyph' */
+ 0xffff, /* kATSDeletedGlyphCode */
+ 0x1ffff, /* out of range */
+ -1L, /* out of range */
+ 70, 68, 76, 85, 82 /* 'cairo' */
+ };
+
+ /* We draw in the default black, so paint white first. */
+ cairo_save (cr);
+ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */
+ cairo_paint (cr);
+ cairo_restore (cr);
+
+ cairo_select_font_face (cr, CAIRO_TEST_FONT_FAMILY " Sans",
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_NORMAL);
+ cairo_set_font_size (cr, 16);
+
+ for (i = 0; i < 9; i++) {
+ /* since we're just drawing glyphs directly we need to position them. */
+ cairo_glyph_t glyph = {
+ index[i], 10 * i, 25
+ };
+
+ /* test cairo_glyph_extents. Every glyph index should
+ * have extents, invalid glyphs should be zero-width.
+ */
+ cairo_move_to (cr, glyph.x, glyph.y);
+ cairo_set_line_width (cr, 1.0);
+ cairo_glyph_extents (cr, &glyph, 1, &extents);
+ cairo_rectangle (cr,
+ glyph.x + extents.x_bearing - 0.5,
+ glyph.y + extents.y_bearing - 0.5,
+ extents.width + 1,
+ extents.height + 1);
+ cairo_set_source_rgb (cr, 1, 0, 0); /* red */
+ cairo_stroke (cr);
+
+ /* test cairo_show_glyphs. Every glyph index should be
+ * drawable, invalid glyph indexes should draw nothing.
+ */
+ cairo_set_source_rgb (cr, 0, 0, 0); /* black */
+ cairo_show_glyphs (cr, &glyph, 1);
+ cairo_move_to (cr, glyph.x, glyph.y);
+
+ /* test cairo_glyph_path. Every glyph index should produce
+ * a path, invalid glyph indexes should have empty paths.
+ */
+ /* Change the glyph position
+ * so that the paths are visible.
+ */
+ glyph.y = 55;
+ cairo_move_to (cr, glyph.x, glyph.y);
+ cairo_glyph_path (cr, &glyph, 1);
+ cairo_fill (cr);
+ }
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (text_glyph_range,
+ "Tests show_glyphs, glyph_path, glyph_extents with out of range glyph ids."
+ "\nft and atsui font backends fail, misreporting errors from FT_Load_Glyph and ATSUGlyphGetCubicPaths",
+ "text, stress", /* keywords */
+ NULL, /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw)
diff --git a/test/text-pattern.c b/test/text-pattern.c
new file mode 100644
index 000000000..60267d658
--- /dev/null
+++ b/test/text-pattern.c
@@ -0,0 +1,73 @@
+/*
+ * Copyright © 2005 Tim Rowley
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Tim Rowley
+ */
+
+#include "cairo-test.h"
+
+#define IMAGE_WIDTH 128
+#define IMAGE_HEIGHT 64
+
+
+static void
+draw_text_pattern (cairo_t *cr, double alpha)
+{
+ cairo_pattern_t *pat;
+
+ cairo_select_font_face (cr, CAIRO_TEST_FONT_FAMILY " Sans",
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_NORMAL);
+
+ pat = cairo_pattern_create_linear (0.0, 0.0, 1, 1);
+ cairo_pattern_add_color_stop_rgba (pat, 1, 1, 0, 0, alpha);
+ cairo_pattern_add_color_stop_rgba (pat, 0, 0, 0, 1, alpha);
+ cairo_set_source (cr, pat);
+
+ /* test rectangle - make sure the gradient is set correctly */
+ cairo_rectangle (cr, 0, 0, 0.1, 1);
+ cairo_fill (cr);
+
+ cairo_set_font_size (cr, 0.4);
+ cairo_move_to (cr, 0.1, 0.6);
+ cairo_show_text (cr, "cairo");
+
+ cairo_pattern_destroy (pat);
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_scale (cr, width/2, height);
+ draw_text_pattern (cr, 1.0);
+ cairo_translate (cr, 1, 0);
+ draw_text_pattern (cr, 0.5);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (text_pattern,
+ "Patterned Text",
+ "text, pattern", /* keywords */
+ NULL, /* requirements */
+ IMAGE_WIDTH, IMAGE_HEIGHT,
+ NULL, draw)
diff --git a/test/text-rotate.c b/test/text-rotate.c
new file mode 100644
index 000000000..0a805ac67
--- /dev/null
+++ b/test/text-rotate.c
@@ -0,0 +1,189 @@
+/*
+ * Copyright © 2004 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+/* Bug history
+ *
+ * 2004-11-03 Steve Chaplin <stevech1097@yahoo.com.au>
+ *
+ * Reported bug on mailing list:
+ *
+ * From: Steve Chaplin <stevech1097@yahoo.com.au>
+ * To: cairo@cairographics.org
+ * Date: Thu, 04 Nov 2004 00:00:17 +0800
+ * Subject: [cairo] Rotated text bug on drawable target
+ *
+ * The attached file draws text rotated 90 degrees first to a PNG file and
+ * then to a drawable. The PNG file looks fine, the text on the drawable is
+ * unreadable.
+ *
+ * Steve
+ *
+ * 2004-11-03 Carl Worth <cworth@cworth.org>
+ *
+ * Looks like the major problems with this bug appeared in the great
+ * font rework between 0.1.23 and 0.2.0. And it looks like we need
+ * to fix the regression test suite to test the xlib target (since
+ * the bug does not show up in the png backend).
+ *
+ * Hmm... Actually, things don't look perfect even in the PNG
+ * output. Look at how that 'o' moves around. It's particularly off
+ * in the case where it's rotated by PI.
+ *
+ * And I'm still not sure about what to do for test cases with
+ * text--a new version of freetype will change everything. We may
+ * need to add a simple backend for stroked fonts and add a simple
+ * builtin font to cairo for pixel-perfect tests with text.
+ *
+ * 2005-08-23
+ *
+ * It appears that the worst placement and glyph selection problems
+ * have now been resolved. In the past some letters were noticeably
+ * of a different size at some rotations, and there was a lot of
+ * drift away from the baseline. These problems do not appear
+ * anymore.
+ *
+ * Another thing that helps is that we now have font options which
+ * we can use to disable hinting in order to get more repeatable
+ * results. I'm doing that in this test now.
+ *
+ * There are still some subtle positioning problems which I'm
+ * assuming are due to the lack of finer-than-whole-pixel glyph
+ * positioning. I'm generating a reference image now by replacing
+ * cairo_show_text with cairo_text_path; cairo_fill. This will let
+ * us look more closely at the remaining positioning problems. (In
+ * particular, I want to make sure we're rounding as well as
+ * possible).
+ *
+ * 2007-02-21
+ *
+ * Seems like all the "bugs" have been fixed and all remaining is
+ * missing support for subpixel glyph positioning. Removing from
+ * XFAIL now.
+ */
+
+#include "cairo-test.h"
+
+#define WIDTH 150
+#define HEIGHT 150
+#define NUM_TEXT 20
+#define TEXT_SIZE 12
+
+/* Draw the word cairo at NUM_TEXT different angles.
+ * We separate the circle into quadrants to reduce
+ * numerical errors i.e. so each quarter is pixel-aligned.
+ */
+static void
+draw_quadrant (cairo_t *cr,
+ const char *text,
+ const cairo_text_extents_t *extents,
+ const cairo_matrix_t *transform,
+ int x_off, int y_off)
+{
+ int i;
+
+ for (i = 0; i < NUM_TEXT/4; i++) {
+ cairo_save (cr);
+ cairo_rotate (cr, 2*M_PI*i/NUM_TEXT);
+ cairo_transform (cr, transform);
+ cairo_set_line_width (cr, 1.0);
+ cairo_rectangle (cr, x_off - 0.5, y_off - 0.5, extents->width + 1, extents->height + 1);
+ cairo_set_source_rgb (cr, 1, 0, 0);
+ cairo_stroke (cr);
+ cairo_move_to (cr, x_off - extents->x_bearing, y_off - extents->y_bearing);
+ cairo_set_source_rgb (cr, 0, 0, 0);
+#if CAIRO_TEST_GENERATE_REFERENCE_IMAGE
+ cairo_text_path (cr, text);
+ cairo_fill (cr);
+#else
+ cairo_show_text (cr, text);
+#endif
+ cairo_restore (cr);
+ }
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_text_extents_t extents;
+ cairo_font_options_t *font_options;
+ const char text[] = "cairo";
+ int x_off, y_off;
+ cairo_matrix_t m;
+
+ /* paint white so we don't need separate ref images for
+ * RGB24 and ARGB32 */
+ cairo_set_source_rgb (cr, 1., 1., 1.);
+ cairo_paint (cr);
+
+ cairo_select_font_face (cr, CAIRO_TEST_FONT_FAMILY " Sans",
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_NORMAL);
+ cairo_set_font_size (cr, TEXT_SIZE);
+
+ font_options = cairo_font_options_create ();
+
+ cairo_get_font_options (cr, font_options);
+ cairo_font_options_set_hint_metrics (font_options, CAIRO_HINT_METRICS_OFF);
+
+ cairo_set_font_options (cr, font_options);
+ cairo_font_options_destroy (font_options);
+
+ cairo_set_source_rgb (cr, 0, 0, 0);
+
+ cairo_translate (cr, WIDTH/2.0, HEIGHT/2.0);
+
+ cairo_text_extents (cr, text, &extents);
+
+ if (NUM_TEXT == 1) {
+ x_off = y_off = 0;
+ } else {
+ y_off = - floor (0.5 + extents.height / 2.0);
+ x_off = floor (0.5 + (extents.height+1) / (2 * tan (M_PI/NUM_TEXT)));
+ }
+
+ cairo_save (cr);
+ cairo_matrix_init_identity (&m);
+ draw_quadrant (cr, text, &extents, &m, x_off, y_off);
+ cairo_matrix_init (&m, 0, 1, -1, 0, 0, 0);
+ draw_quadrant (cr, text, &extents, &m, x_off, y_off);
+ cairo_restore (cr);
+
+ cairo_save (cr);
+ cairo_scale (cr, -1, -1);
+ cairo_matrix_init_identity (&m);
+ draw_quadrant (cr, text, &extents, &m, x_off, y_off);
+ cairo_matrix_init (&m, 0, 1, -1, 0, 0, 0);
+ draw_quadrant (cr, text, &extents, &m, x_off, y_off);
+ cairo_restore (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (text_rotate,
+ "Tests show_text under various rotations",
+ "text, transform", /* keywords */
+ NULL, /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw)
diff --git a/test/text-transform.c b/test/text-transform.c
new file mode 100644
index 000000000..2cd7f100b
--- /dev/null
+++ b/test/text-transform.c
@@ -0,0 +1,104 @@
+/*
+ * Copyright © 2006 Mozilla Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Mozilla Corporation not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Mozilla Corporation makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * MOZILLA CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL MOZILLA CORPORATION BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Vladimir Vukicevic <vladimir@pobox.com>
+ */
+
+#include "cairo-test.h"
+
+#define SIZE 100
+#define PAD 5
+
+#define FONT_SIZE 32.0
+
+static const char *png_filename = "romedalen.png";
+
+static void
+draw_text (cairo_t *cr)
+{
+ cairo_matrix_t tm;
+
+ /* skew */
+ cairo_matrix_init (&tm, 1, 0,
+ -0.25, 1,
+ 0, 0);
+ cairo_matrix_scale (&tm, FONT_SIZE, FONT_SIZE);
+ cairo_set_font_matrix (cr, &tm);
+
+ cairo_new_path (cr);
+ cairo_move_to (cr, 50, SIZE-PAD);
+ cairo_show_text (cr, "A");
+
+ /* rotate and scale */
+ cairo_matrix_init_rotate (&tm, M_PI / 2);
+ cairo_matrix_scale (&tm, FONT_SIZE, FONT_SIZE * 2.0);
+ cairo_set_font_matrix (cr, &tm);
+
+ cairo_new_path (cr);
+ cairo_move_to (cr, PAD, PAD + 25);
+ cairo_show_text (cr, "A");
+
+ cairo_matrix_init_rotate (&tm, M_PI / 2);
+ cairo_matrix_scale (&tm, FONT_SIZE * 2.0, FONT_SIZE);
+ cairo_set_font_matrix (cr, &tm);
+
+ cairo_new_path (cr);
+ cairo_move_to (cr, PAD, PAD + 50);
+ cairo_show_text (cr, "A");
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ const cairo_test_context_t *ctx = cairo_test_get_context (cr);
+ cairo_pattern_t *pattern;
+
+ cairo_set_source_rgb (cr, 1., 1., 1.);
+ cairo_paint (cr);
+
+ cairo_set_source_rgb (cr, 0., 0., 0.);
+
+ cairo_select_font_face (cr, CAIRO_TEST_FONT_FAMILY " Sans",
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_NORMAL);
+
+ draw_text (cr);
+
+ cairo_translate (cr, SIZE, SIZE);
+ cairo_rotate (cr, M_PI);
+
+ pattern = cairo_test_create_pattern_from_png (ctx, png_filename);
+ cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT);
+ cairo_set_source (cr, pattern);
+ cairo_pattern_destroy (pattern);
+
+ draw_text (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (text_transform,
+ "Test various applications of the font matrix",
+ "text, transform", /* keywords */
+ NULL, /* requirements */
+ SIZE, SIZE,
+ NULL, draw)
diff --git a/test/text-zero-len.c b/test/text-zero-len.c
new file mode 100644
index 000000000..5e89816c8
--- /dev/null
+++ b/test/text-zero-len.c
@@ -0,0 +1,203 @@
+/*
+ * Copyright © 2006 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Behdad Esfahbod <behdad@behdad.org>
+ */
+
+/* Related bug 5177
+ *
+ * In short:
+ *
+ * _cairo_atsui_font_text_to_glyph with a zero-sized string crashes.
+ *
+ * Moreover, the fallback path in cairo_scaled_font_text_to_glyphs()
+ * when handling a zero-sized string, allocates a zero-sized glyph array
+ * and when NULL is returned by malloc, recognizes that as an out-of-memory
+ * error. The glibc implementation of malloc() does not return NULL from
+ * malloc(0), but I don't think it's a safe assumption.
+ *
+ * By just bailing out on zero-sized text, we fix both issues.
+ */
+
+#include "cairo-test.h"
+
+#define NUM_TEXT 20
+#define TEXT_SIZE 12
+
+static cairo_bool_t
+text_extents_equal (const cairo_text_extents_t *A,
+ const cairo_text_extents_t *B)
+{
+ return A->x_bearing == B->x_bearing &&
+ A->y_bearing == B->y_bearing &&
+ A->width == B->width &&
+ A->height == B->height &&
+ A->x_advance == B->x_advance &&
+ A->y_advance == B->y_advance;
+}
+
+static cairo_bool_t
+font_extents_equal (const cairo_font_extents_t *A,
+ const cairo_font_extents_t *B)
+{
+ return A->ascent == B->ascent &&
+ A->descent == B->descent &&
+ A->height == B->height &&
+ A->max_x_advance == B->max_x_advance &&
+ A->max_y_advance == B->max_y_advance;
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ const cairo_test_context_t *ctx = cairo_test_get_context (cr);
+ cairo_text_extents_t extents, nil_extents;
+ cairo_font_extents_t font_extents, nil_font_extents;
+ cairo_scaled_font_t *scaled_font;
+
+ cairo_select_font_face (cr, CAIRO_TEST_FONT_FAMILY " Sans",
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_NORMAL);
+ cairo_set_font_size (cr, 16);
+
+ cairo_move_to (cr, 10, 25);
+ cairo_show_text (cr, NULL);
+ cairo_show_text (cr, "");
+ cairo_show_glyphs (cr, NULL, 0);
+ cairo_show_glyphs (cr, (void*)8, 0);
+
+ cairo_move_to (cr, 10, 55);
+ cairo_text_path (cr, NULL);
+ cairo_text_path (cr, "");
+ cairo_glyph_path (cr, (void*)8, 0);
+ cairo_fill (cr);
+
+ memset (&nil_extents, 0, sizeof (cairo_text_extents_t));
+
+ memset (&extents, 0xff, sizeof (cairo_text_extents_t));
+ cairo_text_extents (cr, "", &extents);
+ if (! text_extents_equal (&extents, &nil_extents)) {
+ cairo_test_log (ctx, "Error: cairo_text_extents(\"\"); extents (%g, %g, %g, %g, %g, %g)\n",
+ extents.x_bearing, extents.y_bearing,
+ extents.width, extents.height,
+ extents.x_advance, extents.y_advance);
+ return CAIRO_TEST_FAILURE;
+ }
+
+ memset (&extents, 0xff, sizeof (cairo_text_extents_t));
+ cairo_text_extents (cr, NULL, &extents);
+ if (! text_extents_equal (&extents, &nil_extents)) {
+ cairo_test_log (ctx, "Error: cairo_text_extents(NULL); extents (%g, %g, %g, %g, %g, %g)\n",
+ extents.x_bearing, extents.y_bearing,
+ extents.width, extents.height,
+ extents.x_advance, extents.y_advance);
+ return CAIRO_TEST_FAILURE;
+ }
+
+ memset (&extents, 0xff, sizeof (cairo_text_extents_t));
+ cairo_glyph_extents (cr, (void*)8, 0, &extents);
+ if (! text_extents_equal (&extents, &nil_extents)) {
+ cairo_test_log (ctx, "Error: cairo_glyph_extents(); extents (%g, %g, %g, %g, %g, %g)\n",
+ extents.x_bearing, extents.y_bearing,
+ extents.width, extents.height,
+ extents.x_advance, extents.y_advance);
+ return CAIRO_TEST_FAILURE;
+ }
+
+ scaled_font = cairo_get_scaled_font (cr);
+
+ memset (&extents, 0xff, sizeof (cairo_text_extents_t));
+ cairo_scaled_font_text_extents (scaled_font, "", &extents);
+ if (! text_extents_equal (&extents, &nil_extents)) {
+ cairo_test_log (ctx, "Error: cairo_scaled_font_text_extents(\"\"); extents (%g, %g, %g, %g, %g, %g)\n",
+ extents.x_bearing, extents.y_bearing,
+ extents.width, extents.height,
+ extents.x_advance, extents.y_advance);
+ return CAIRO_TEST_FAILURE;
+ }
+
+ memset (&extents, 0xff, sizeof (cairo_text_extents_t));
+ cairo_scaled_font_text_extents (scaled_font, NULL, &extents);
+ if (! text_extents_equal (&extents, &nil_extents)) {
+ cairo_test_log (ctx, "Error: cairo_scaled_font_text_extents(NULL); extents (%g, %g, %g, %g, %g, %g)\n",
+ extents.x_bearing, extents.y_bearing,
+ extents.width, extents.height,
+ extents.x_advance, extents.y_advance);
+ return CAIRO_TEST_FAILURE;
+ }
+
+ memset (&extents, 0xff, sizeof (cairo_text_extents_t));
+ cairo_scaled_font_glyph_extents (scaled_font, (void*)8, 0, &extents);
+ if (! text_extents_equal (&extents, &nil_extents)) {
+ cairo_test_log (ctx, "Error: cairo_scaled_font_glyph_extents(NULL); extents (%g, %g, %g, %g, %g, %g)\n",
+ extents.x_bearing, extents.y_bearing,
+ extents.width, extents.height,
+ extents.x_advance, extents.y_advance);
+ return CAIRO_TEST_FAILURE;
+ }
+
+ /* Lets also try font size 0 while here */
+ cairo_set_font_size (cr, 0);
+
+ memset (&extents, 0xff, sizeof (cairo_text_extents_t));
+ cairo_text_extents (cr, "test", &extents);
+ if (! text_extents_equal (&extents, &nil_extents)) {
+ cairo_test_log (ctx, "Error: cairo_set_font_size(0); cairo_text_extents(\"test\"); extents (%g, %g, %g, %g, %g, %g)\n",
+ extents.x_bearing, extents.y_bearing,
+ extents.width, extents.height,
+ extents.x_advance, extents.y_advance);
+ return CAIRO_TEST_FAILURE;
+ }
+
+ memset (&nil_font_extents, 0, sizeof (cairo_font_extents_t));
+
+ memset (&font_extents, 0xff, sizeof (cairo_font_extents_t));
+ cairo_font_extents (cr, &font_extents);
+ if (! font_extents_equal (&font_extents, &nil_font_extents)) {
+ cairo_test_log (ctx, "Error: cairo_set_font_size(0); cairo_font_extents(); extents (%g, %g, %g, %g, %g)\n",
+ font_extents.ascent, font_extents.descent,
+ font_extents.height,
+ font_extents.max_x_advance, font_extents.max_y_advance);
+ return CAIRO_TEST_FAILURE;
+ }
+
+ scaled_font = cairo_get_scaled_font (cr);
+
+ memset (&font_extents, 0xff, sizeof (cairo_font_extents_t));
+ cairo_scaled_font_extents (scaled_font, &font_extents);
+ if (! font_extents_equal (&font_extents, &nil_font_extents)) {
+ cairo_test_log (ctx, "Error: cairo_set_font_size(0); cairo_scaled_font_extents(); extents (%g, %g, %g, %g, %g)\n",
+ font_extents.ascent, font_extents.descent,
+ font_extents.height,
+ font_extents.max_x_advance, font_extents.max_y_advance);
+ return CAIRO_TEST_FAILURE;
+ }
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (text_zero_len,
+ "Tests show_text and text_path with a zero-sized string",
+ "text, stress, extents", /* keywords */
+ NULL, /* requirements */
+ 0, 0,
+ NULL, draw)
diff --git a/test/tiger.c b/test/tiger.c
new file mode 100644
index 000000000..059bb849f
--- /dev/null
+++ b/test/tiger.c
@@ -0,0 +1,85 @@
+/*
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include "cairo-test.h"
+
+#include "tiger.inc"
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ unsigned int i;
+
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_set_source_rgba (cr, 0.1, 0.2, 0.3, 1.0);
+ cairo_paint (cr);
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+
+ cairo_translate (cr, width/2, height/2);
+ cairo_scale (cr, .85, .85);
+
+ for (i = 0; i < ARRAY_LENGTH(tiger_commands); i++) {
+ const struct command *cmd = &tiger_commands[i];
+ switch (cmd->type) {
+ case 'm':
+ cairo_move_to (cr, cmd->x0, cmd->y0);
+ break;
+ case 'l':
+ cairo_line_to (cr, cmd->x0, cmd->y0);
+ break;
+ case 'c':
+ cairo_curve_to (cr,
+ cmd->x0, cmd->y0,
+ cmd->x1, cmd->y1,
+ cmd->x2, cmd->y2);
+ break;
+ case 'f':
+ cairo_set_source_rgba (cr,
+ cmd->x0, cmd->y0, cmd->x1, cmd->y1);
+ cairo_fill (cr);
+ break;
+ }
+ }
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+a1_draw (cairo_t *cr, int width, int height)
+{
+ cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE);
+ return draw (cr, width, height);
+}
+
+CAIRO_TEST (tiger,
+ "Check the fidelity of the rasterisation.",
+ "raster", /* keywords */
+ NULL, /* requirements */
+ 500, 500,
+ NULL, draw)
+
+CAIRO_TEST (a1_tiger,
+ "Check the fidelity of the rasterisation.",
+ "fill", /* keywords */
+ "target=raster", /* requirements */
+ 500, 500,
+ NULL, a1_draw)
diff --git a/test/tiger.inc b/test/tiger.inc
new file mode 100644
index 000000000..419b97989
--- /dev/null
+++ b/test/tiger.inc
@@ -0,0 +1,2316 @@
+static const struct command {
+ char type;
+ float x0, y0;
+ float x1, y1;
+ float x2, y2;
+} tiger_commands[] = {
+{'m', -122.30, 84.28, 0, 0, 0, 0},
+{'c', -122.30, 84.28, -122.20 ,86.18, -123.03, 86.16},
+{'c', -123.85, 86.14, -140.31 ,38.07, -160.83, 40.31},
+{'f', 1.000000,1.000000,1.000000,1.000000,0,0 },
+{'m', -118.77, 81.26, 0, 0, 0, 0},
+{'c', -118.77, 81.26, -119.32 ,83.08, -120.09, 82.78},
+{'c', -120.86, 82.48, -119.98 ,31.68, -140.04, 26.80},
+{'f', 1.000000,1.000000,1.000000,1.000000,0,0 },
+{'m', -91.28, 123.59, 0, 0, 0, 0},
+{'c', -91.28, 123.59, -89.65 ,124.55, -90.12, 125.23},
+{'c', -90.59, 125.90, -139.76 ,113.10, -149.22, 131.46},
+{'f', 1.000000,1.000000,1.000000,1.000000,0,0 },
+{'m', -94.09, 133.80, 0, 0, 0, 0},
+{'c', -94.09, 133.80, -92.24 ,134.20, -92.47, 134.99},
+{'c', -92.70, 135.78, -143.41 ,139.12, -146.60, 159.52},
+{'f', 1.000000,1.000000,1.000000,1.000000,0,0 },
+{'m', -98.30, 128.28, 0, 0, 0, 0},
+{'c', -98.30, 128.28, -96.53 ,128.94, -96.87, 129.69},
+{'c', -97.22, 130.44, -147.87 ,126.35, -154.00, 146.06},
+{'f', 1.000000,1.000000,1.000000,1.000000,0,0 },
+{'m', -109.01, 110.07, 0, 0, 0, 0},
+{'c', -109.01, 110.07, -107.70 ,111.45, -108.34, 111.97},
+{'c', -108.98, 112.49, -152.72 ,86.63, -166.87, 101.68},
+{'f', 1.000000,1.000000,1.000000,1.000000,0,0 },
+{'m', -116.55, 114.26, 0, 0, 0, 0},
+{'c', -116.55, 114.26, -115.10 ,115.48, -115.67, 116.07},
+{'c', -116.25, 116.66, -162.64 ,95.92, -174.99, 112.47},
+{'f', 1.000000,1.000000,1.000000,1.000000,0,0 },
+{'m', -119.15, 118.33, 0, 0, 0, 0},
+{'c', -119.15, 118.33, -117.55 ,119.34, -118.04, 120.01},
+{'c', -118.53, 120.67, -167.31 ,106.45, -177.29, 124.52},
+{'f', 1.000000,1.000000,1.000000,1.000000,0,0 },
+{'m', -108.42, 118.95, 0, 0, 0, 0},
+{'c', -108.42, 118.95, -107.30 ,120.48, -108.00, 120.92},
+{'c', -108.70, 121.35, -148.77 ,90.10, -164.73, 103.21},
+{'f', 1.000000,1.000000,1.000000,1.000000,0,0 },
+{'m', -128.20, 90.00, 0, 0, 0, 0},
+{'c', -128.20, 90.00, -127.60 ,91.80, -128.40, 92.00},
+{'c', -129.20, 92.20, -157.80 ,50.20, -177.00, 57.80},
+{'f', 1.000000,1.000000,1.000000,1.000000,0,0 },
+{'m', -127.50, 96.98, 0, 0, 0, 0},
+{'c', -127.50, 96.98, -126.53 ,98.61, -127.27, 98.97},
+{'c', -128.01, 99.34, -164.99 ,64.50, -182.10, 76.06},
+{'f', 1.000000,1.000000,1.000000,1.000000,0,0 },
+{'m', -127.62, 101.35, 0, 0, 0, 0},
+{'c', -127.62, 101.35, -126.50 ,102.88, -127.20, 103.31},
+{'c', -127.90, 103.75, -167.97 ,72.50, -183.93, 85.61},
+{'f', 1.000000,1.000000,1.000000,1.000000,0,0 },
+{'m', -129.83, 103.06, 0, 0, 0, 0},
+{'c', -129.33, 109.11, -128.34 ,115.68, -126.60, 118.80},
+{'c', -126.60, 118.80, -130.20 ,131.20, -121.40, 144.40},
+{'c', -121.40, 144.40, -121.80 ,151.60, -120.20, 154.80},
+{'c', -120.20, 154.80, -116.20 ,163.20, -111.40, 164.00},
+{'c', -107.52, 164.65, -98.79 ,167.72, -88.93, 169.12},
+{'c', -88.93, 169.12, -71.80 ,183.20, -75.00, 196.00},
+{'c', -75.00, 196.00, -75.40 ,212.40, -79.00, 214.00},
+{'c', -79.00, 214.00, -67.40 ,202.80, -77.00, 219.60},
+{'l', -81.40, 238.40, 0, 0, 0, 0},
+{'c', -81.40, 238.40, -55.80 ,216.80, -71.40, 235.20},
+{'l', -81.40, 261.20, 0, 0, 0, 0},
+{'c', -81.40, 261.20, -61.80 ,242.80, -69.00, 251.20},
+{'l', -72.20, 260.00, 0, 0, 0, 0},
+{'c', -72.20, 260.00, -29.00 ,232.80, -59.80, 262.40},
+{'c', -59.80, 262.40, -51.80 ,258.80, -47.40, 261.60},
+{'c', -47.40, 261.60, -40.60 ,260.40, -41.40, 262.00},
+{'c', -41.40, 262.00, -62.20 ,272.40, -65.80, 290.80},
+{'c', -65.80, 290.80, -57.40 ,280.80, -60.60, 291.60},
+{'l', -60.20, 303.20, 0, 0, 0, 0},
+{'c', -60.20, 303.20, -56.20 ,281.60, -56.60, 319.20},
+{'c', -56.60, 319.20, -37.40 ,301.20, -49.00, 322.00},
+{'l', -49.00, 338.80, 0, 0, 0, 0},
+{'c', -49.00, 338.80, -33.80 ,322.40, -40.20, 335.20},
+{'c', -40.20, 335.20, -30.20 ,326.40, -34.20, 341.60},
+{'c', -34.20, 341.60, -35.00 ,352.00, -30.60, 340.80},
+{'c', -30.60, 340.80, -14.60 ,310.20, -20.60, 336.40},
+{'c', -20.60, 336.40, -21.40 ,355.60, -16.60, 340.80},
+{'c', -16.60, 340.80, -16.20 ,351.20, -7.00, 358.40},
+{'c', -7.00, 358.40, -8.20 ,307.60, 4.60, 343.60},
+{'l', 8.60, 360.00, 0, 0, 0, 0},
+{'c', 8.60, 360.00, 11.40 ,350.80, 11.00, 345.60},
+{'c', 11.00, 345.60, 25.80 ,329.20, 19.00, 353.60},
+{'c', 19.00, 353.60, 34.20 ,330.80, 31.00, 344.00},
+{'c', 31.00, 344.00, 23.40 ,360.00, 25.00, 364.80},
+{'c', 25.00, 364.80, 41.80 ,330.00, 43.00, 328.40},
+{'c', 43.00, 328.40, 41.00 ,370.80, 51.80, 334.80},
+{'c', 51.80, 334.80, 57.40 ,346.80, 54.60, 351.20},
+{'c', 54.60, 351.20, 62.60 ,343.20, 61.80, 340.00},
+{'c', 61.80, 340.00, 66.40 ,331.80, 69.20, 345.40},
+{'c', 69.20, 345.40, 71.00 ,354.80, 72.60, 351.60},
+{'c', 72.60, 351.60, 76.60 ,375.60, 77.80, 352.80},
+{'c', 77.80, 352.80, 79.40 ,339.20, 72.20, 327.60},
+{'c', 72.20, 327.60, 73.00 ,324.40, 70.20, 320.40},
+{'c', 70.20, 320.40, 83.80 ,342.00, 76.60, 313.20},
+{'c', 76.60, 313.20, 87.80 ,321.20, 89.00, 321.20},
+{'c', 89.00, 321.20, 75.40 ,298.00, 84.20, 302.80},
+{'c', 84.20, 302.80, 79.00 ,292.40, 97.00, 304.40},
+{'c', 97.00, 304.40, 81.00 ,288.40, 98.60, 298.00},
+{'c', 98.60, 298.00, 106.60 ,304.40, 99.00, 294.40},
+{'c', 99.00, 294.40, 84.60 ,278.40, 106.60, 296.40},
+{'c', 106.60, 296.40, 118.20 ,312.80, 119.00, 315.60},
+{'c', 119.00, 315.60, 109.00 ,286.40, 104.60, 283.60},
+{'c', 104.60, 283.60, 113.00 ,247.20, 154.20, 262.80},
+{'c', 154.20, 262.80, 161.00 ,280.00, 165.40, 261.60},
+{'c', 165.40, 261.60, 178.20 ,255.20, 189.40, 282.80},
+{'c', 189.40, 282.80, 193.40 ,269.20, 192.60, 266.40},
+{'c', 192.60, 266.40, 199.40 ,267.60, 198.60, 266.40},
+{'c', 198.60, 266.40, 211.80 ,270.80, 213.00, 270.00},
+{'c', 213.00, 270.00, 219.80 ,276.80, 220.20, 273.20},
+{'c', 220.20, 273.20, 229.40 ,276.00, 227.40, 272.40},
+{'c', 227.40, 272.40, 236.20 ,288.00, 236.60, 291.60},
+{'l', 239.00, 277.60, 0, 0, 0, 0},
+{'l', 241.00, 280.40, 0, 0, 0, 0},
+{'c', 241.00, 280.40, 242.60 ,272.80, 241.80, 271.60},
+{'c', 241.00, 270.40, 261.80 ,278.40, 266.60, 299.20},
+{'l', 268.60, 307.60, 0, 0, 0, 0},
+{'c', 268.60, 307.60, 274.60 ,292.80, 273.00, 288.80},
+{'c', 273.00, 288.80, 278.20 ,289.60, 278.60, 294.00},
+{'c', 278.60, 294.00, 282.60 ,270.80, 277.80, 264.80},
+{'c', 277.80, 264.80, 282.20 ,264.00, 283.40, 267.60},
+{'l', 283.40, 260.40, 0, 0, 0, 0},
+{'c', 283.40, 260.40, 290.60 ,261.20, 290.60, 258.80},
+{'c', 290.60, 258.80, 295.00 ,254.80, 297.00, 259.60},
+{'c', 297.00, 259.60, 284.60 ,224.40, 303.00, 243.60},
+{'c', 303.00, 243.60, 310.20 ,254.40, 306.60, 235.60},
+{'c', 303.00, 216.80, 299.00 ,215.20, 303.80, 214.80},
+{'c', 303.80, 214.80, 304.60 ,211.20, 302.60, 209.60},
+{'c', 300.60, 208.00, 303.80 ,209.60, 303.80, 209.60},
+{'c', 303.80, 209.60, 308.60 ,213.60, 303.40, 191.60},
+{'c', 303.40, 191.60, 309.80 ,193.20, 297.80, 164.00},
+{'c', 297.80, 164.00, 300.60 ,161.60, 296.60, 153.20},
+{'c', 296.60, 153.20, 304.60 ,157.60, 307.40, 156.00},
+{'c', 307.40, 156.00, 307.00 ,154.40, 303.80, 150.40},
+{'c', 303.80, 150.40, 282.20 ,95.60, 302.60, 117.60},
+{'c', 302.60, 117.60, 314.45 ,131.15, 308.05, 108.35},
+{'c', 308.05, 108.35, 298.94 ,84.34, 299.72, 80.05},
+{'f', 1.000000,1.000000,1.000000,1.000000,0,0 },
+{'m', 299.72, 80.25, 0, 0, 0, 0},
+{'c', 300.35, 80.43, 302.55 ,81.55, 303.80, 83.20},
+{'c', 303.80, 83.20, 310.60 ,94.00, 305.40, 75.60},
+{'c', 305.40, 75.60, 296.20 ,46.80, 305.00, 58.00},
+{'c', 305.00, 58.00, 311.00 ,65.20, 307.80, 51.60},
+{'c', 303.94, 35.17, 301.40 ,28.80, 301.40, 28.80},
+{'c', 301.40, 28.80, 313.00 ,33.60, 286.20, -6.00},
+{'l', 295.00, -2.40, 0, 0, 0, 0},
+{'c', 295.00, -2.40, 275.40 ,-42.00, 253.80, -47.20},
+{'l', 245.80, -53.20, 0, 0, 0, 0},
+{'c', 245.80, -53.20, 284.20 ,-91.20, 271.40, -128.00},
+{'c', 271.40, -128.00, 264.60 ,-133.20, 255.00, -124.00},
+{'c', 255.00, -124.00, 248.60 ,-119.20, 242.60, -120.80},
+{'c', 242.60, -120.80, 211.80 ,-119.60, 209.80, -119.60},
+{'c', 207.80, -119.60, 173.00 ,-156.80, 107.40, -139.20},
+{'c', 107.40, -139.20, 102.20 ,-137.20, 97.80, -138.40},
+{'c', 97.80, -138.40, 79.40 ,-154.40, 30.60, -131.60},
+{'c', 30.60, -131.60, 20.60 ,-129.60, 19.00, -129.60},
+{'c', 17.40, -129.60, 14.60 ,-129.60, 6.60, -123.20},
+{'c', -1.40, -116.80, -1.80 ,-116.00, -3.80, -114.40},
+{'c', -3.80, -114.40, -20.20 ,-103.20, -25.00, -102.40},
+{'c', -25.00, -102.40, -36.60 ,-96.00, -41.00, -86.00},
+{'l', -44.60, -84.80, 0, 0, 0, 0},
+{'c', -44.60, -84.80, -46.20 ,-77.60, -46.60, -76.40},
+{'c', -46.60, -76.40, -51.40 ,-72.80, -52.20, -67.20},
+{'c', -52.20, -67.20, -61.00 ,-61.20, -60.60, -56.80},
+{'c', -60.60, -56.80, -62.20 ,-51.60, -63.00, -46.80},
+{'c', -63.00, -46.80, -70.20 ,-42.00, -69.40, -39.20},
+{'c', -69.40, -39.20, -77.00 ,-25.20, -75.80, -18.40},
+{'c', -75.80, -18.40, -82.20 ,-18.80, -85.00, -16.40},
+{'c', -85.00, -16.40, -85.80 ,-11.60, -87.40, -11.20},
+{'c', -87.40, -11.20, -90.20 ,-10.00, -87.80, -6.00},
+{'c', -87.80, -6.00, -89.40 ,-3.20, -89.80, -1.60},
+{'c', -89.80, -1.60, -89.00 ,1.20, -93.40, 6.80},
+{'c', -93.40, 6.80, -99.80 ,25.60, -97.80, 30.80},
+{'c', -97.80, 30.80, -97.40 ,35.60, -100.20, 37.20},
+{'c', -100.20, 37.20, -103.80 ,36.80, -95.40, 48.80},
+{'c', -95.40, 48.80, -94.60 ,50.00, -97.80, 52.40},
+{'c', -97.80, 52.40, -115.00 ,56.00, -117.40, 72.40},
+{'c', -117.40, 72.40, -131.00 ,87.20, -131.00, 92.40},
+{'c', -131.00, 94.70, -130.73 ,97.85, -130.03, 102.47},
+{'c', -130.03, 102.47, -130.60 ,110.80, -103.00, 111.60},
+{'f', 0.804000,0.469000,0.134000,1.000000,0,0 },
+{'m', -115.60, 102.60, 0, 0, 0, 0},
+{'c', -140.60, 63.20, -126.20 ,119.60, -126.20, 119.60},
+{'c', -117.40, 154.00, 12.20 ,116.40, 12.20, 116.40},
+{'c', 12.20, 116.40, 181.00 ,86.00, 192.20, 82.00},
+{'c', 203.40, 78.00, 298.60 ,84.40, 298.60, 84.40},
+{'l', 293.00, 67.60, 0, 0, 0, 0},
+{'c', 228.20, 21.20, 209.00 ,44.40, 195.40, 40.40},
+{'c', 181.80, 36.40, 184.20 ,46.00, 181.00, 46.80},
+{'c', 177.80, 47.60, 138.60 ,22.80, 132.20, 23.60},
+{'c', 125.80, 24.40, 100.46 ,0.65, 115.40, 32.40},
+{'c', 131.40, 66.40, 57.00 ,71.60, 40.20, 60.40},
+{'c', 23.40, 49.20, 47.40 ,78.80, 47.40, 78.80},
+{'c', 65.80, 98.80, 31.40 ,82.00, 31.40, 82.00},
+{'c', -3.00, 69.20, -27.00 ,94.80, -30.20, 95.60},
+{'c', -33.40, 96.40, -38.20 ,99.60, -39.00, 93.20},
+{'c', -39.80, 86.80, -47.31 ,70.10, -79.00, 96.40},
+{'c', -99.00, 113.00, -112.80 ,91.00, -112.80, 91.00},
+{'f', 0.804000,0.469000,0.134000,1.000000,0,0 },
+{'m', 133.51, 25.35, 0, 0, 0, 0},
+{'c', 127.11, 26.15, 101.74 ,2.41, 116.71, 34.15},
+{'c', 133.31, 69.35, 58.31 ,73.35, 41.51, 62.15},
+{'c', 24.71, 50.95, 48.71 ,80.55, 48.71, 80.55},
+{'c', 67.11, 100.55, 32.71 ,83.75, 32.71, 83.75},
+{'c', -1.69, 70.95, -25.69 ,96.55, -28.89, 97.35},
+{'c', -32.09, 98.15, -36.89 ,101.35, -37.69, 94.95},
+{'c', -38.49, 88.55, -45.87 ,72.01, -77.69, 98.15},
+{'c', -98.93, 115.49, -112.42 ,94.04, -112.42, 94.04},
+{'l', -115.62, 104.15, 0, 0, 0, 0},
+{'c', -140.62, 64.35, -125.55 ,122.66, -125.55, 122.66},
+{'c', -116.75, 157.06, 13.51 ,118.15, 13.51, 118.15},
+{'c', 13.51, 118.15, 182.31 ,87.75, 193.51, 83.75},
+{'c', 204.71, 79.75, 299.04 ,86.07, 299.04, 86.07},
+{'l', 293.51, 68.76, 0, 0, 0, 0},
+{'c', 228.71, 22.36, 210.31 ,46.15, 196.71, 42.15},
+{'c', 183.11, 38.15, 185.51 ,47.75, 182.31, 48.55},
+{'f', 0.938000,0.469000,0.201000,1.000000,0,0 },
+{'m', 134.82, 27.09, 0, 0, 0, 0},
+{'c', 128.42, 27.89, 103.69 ,3.86, 118.02, 35.89},
+{'c', 134.22, 72.09, 59.62 ,75.09, 42.82, 63.89},
+{'c', 26.02, 52.69, 50.02 ,82.29, 50.02, 82.29},
+{'c', 68.42, 102.29, 34.02 ,85.49, 34.02, 85.49},
+{'c', -0.38, 72.69, -24.38 ,98.29, -27.58, 99.09},
+{'c', -30.78, 99.89, -35.58 ,103.09, -36.38, 96.69},
+{'c', -37.18, 90.29, -44.43 ,73.92, -76.38, 99.89},
+{'c', -98.86, 117.98, -112.04 ,97.07, -112.04, 97.07},
+{'l', -115.64, 105.69, 0, 0, 0, 0},
+{'c', -139.44, 66.69, -124.89 ,125.71, -124.89, 125.71},
+{'c', -116.09, 160.11, 14.82 ,119.89, 14.82, 119.89},
+{'c', 14.82, 119.89, 183.62 ,89.49, 194.82, 85.49},
+{'c', 206.02, 81.49, 299.47 ,87.75, 299.47, 87.75},
+{'l', 294.02, 69.93, 0, 0, 0, 0},
+{'c', 229.22, 23.53, 211.62 ,47.89, 198.02, 43.89},
+{'c', 184.42, 39.89, 186.82 ,49.49, 183.62, 50.29},
+{'f', 0.938000,0.536000,0.268000,1.000000,0,0 },
+{'m', 136.13, 28.84, 0, 0, 0, 0},
+{'c', 129.73, 29.64, 105.00 ,5.61, 119.33, 37.64},
+{'c', 136.13, 75.19, 60.39 ,76.48, 44.13, 65.64},
+{'c', 27.33, 54.44, 51.33 ,84.04, 51.33, 84.04},
+{'c', 69.73, 104.04, 35.33 ,87.24, 35.33, 87.24},
+{'c', 0.93, 74.44, -23.07 ,100.04, -26.27, 100.84},
+{'c', -29.47, 101.64, -34.27 ,104.84, -35.07, 98.44},
+{'c', -35.87, 92.04, -42.99 ,75.84, -75.07, 101.64},
+{'c', -98.78, 120.47, -111.66 ,100.11, -111.66, 100.11},
+{'l', -115.66, 107.24, 0, 0, 0, 0},
+{'c', -137.46, 70.44, -124.24 ,128.76, -124.24, 128.76},
+{'c', -115.44, 163.16, 16.13 ,121.64, 16.13, 121.64},
+{'c', 16.13, 121.64, 184.93 ,91.24, 196.13, 87.24},
+{'c', 207.33, 83.24, 299.91 ,89.42, 299.91, 89.42},
+{'l', 294.53, 71.09, 0, 0, 0, 0},
+{'c', 229.73, 24.69, 212.93 ,49.64, 199.33, 45.64},
+{'c', 185.73, 41.64, 188.13 ,51.24, 184.93, 52.04},
+{'f', 0.938000,0.603000,0.402000,1.000000,0,0 },
+{'m', 137.44, 30.58, 0, 0, 0, 0},
+{'c', 131.04, 31.38, 106.81 ,7.13, 120.64, 39.38},
+{'c', 137.44, 78.58, 62.24 ,78.58, 45.44, 67.38},
+{'c', 28.64, 56.18, 52.64 ,85.78, 52.64, 85.78},
+{'c', 71.04, 105.78, 36.64 ,88.98, 36.64, 88.98},
+{'c', 2.24, 76.18, -21.76 ,101.78, -24.96, 102.58},
+{'c', -28.16, 103.38, -32.96 ,106.58, -33.76, 100.18},
+{'c', -34.56, 93.78, -41.55 ,77.75, -73.76, 103.38},
+{'c', -98.71, 122.97, -111.27 ,103.15, -111.27, 103.15},
+{'l', -115.67, 108.78, 0, 0, 0, 0},
+{'c', -135.47, 73.98, -123.58 ,131.82, -123.58, 131.82},
+{'c', -114.78, 166.22, 17.44 ,123.38, 17.44, 123.38},
+{'c', 17.44, 123.38, 186.24 ,92.98, 197.44, 88.98},
+{'c', 208.64, 84.98, 300.35 ,91.09, 300.35, 91.09},
+{'l', 295.04, 72.25, 0, 0, 0, 0},
+{'c', 230.24, 25.86, 214.24 ,51.38, 200.64, 47.38},
+{'c', 187.04, 43.38, 189.44 ,52.98, 186.24, 53.78},
+{'f', 0.938000,0.670000,0.469000,1.000000,0,0 },
+{'m', 138.75, 32.33, 0, 0, 0, 0},
+{'c', 132.35, 33.13, 106.38 ,9.68, 121.95, 41.13},
+{'c', 141.15, 79.93, 63.55 ,80.33, 46.75, 69.13},
+{'c', 29.95, 57.93, 53.95 ,87.53, 53.95, 87.53},
+{'c', 72.35, 107.53, 37.95 ,90.73, 37.95, 90.73},
+{'c', 3.55, 77.93, -20.45 ,103.53, -23.65, 104.33},
+{'c', -26.85, 105.13, -31.65 ,108.33, -32.45, 101.93},
+{'c', -33.25, 95.53, -40.11 ,79.67, -72.45, 105.13},
+{'c', -98.64, 125.46, -110.89 ,106.18, -110.89, 106.18},
+{'l', -115.69, 110.33, 0, 0, 0, 0},
+{'c', -133.69, 77.13, -122.93 ,134.87, -122.93, 134.87},
+{'c', -114.13, 169.27, 18.75 ,125.13, 18.75, 125.13},
+{'c', 18.75, 125.13, 187.55 ,94.73, 198.75, 90.73},
+{'c', 209.95, 86.73, 300.78 ,92.76, 300.78, 92.76},
+{'l', 295.55, 73.42, 0, 0, 0, 0},
+{'c', 230.75, 27.02, 215.55 ,53.13, 201.95, 49.13},
+{'c', 188.35, 45.13, 190.75 ,54.73, 187.55, 55.53},
+{'f', 1.000000,0.737000,0.536000,1.000000,0,0 },
+{'m', 140.06, 34.07, 0, 0, 0, 0},
+{'c', 133.66, 34.87, 107.31 ,11.61, 123.25, 42.87},
+{'c', 143.66, 82.87, 64.86 ,82.07, 48.05, 70.87},
+{'c', 31.25, 59.67, 55.26 ,89.27, 55.26, 89.27},
+{'c', 73.66, 109.27, 39.26 ,92.47, 39.26, 92.47},
+{'c', 4.86, 79.67, -19.14 ,105.27, -22.34, 106.07},
+{'c', -25.55, 106.87, -30.34 ,110.07, -31.14, 103.67},
+{'c', -31.95, 97.27, -38.67 ,81.58, -71.14, 106.87},
+{'c', -98.56, 127.95, -110.51 ,109.22, -110.51, 109.22},
+{'l', -115.71, 111.87, 0, 0, 0, 0},
+{'c', -131.71, 81.67, -122.27 ,137.93, -122.27, 137.93},
+{'c', -113.47, 172.33, 20.05 ,126.87, 20.05, 126.87},
+{'c', 20.05, 126.87, 188.86 ,96.47, 200.06, 92.47},
+{'c', 211.26, 88.47, 301.22 ,94.44, 301.22, 94.44},
+{'l', 296.06, 74.58, 0, 0, 0, 0},
+{'c', 231.26, 28.18, 216.86 ,54.87, 203.26, 50.87},
+{'c', 189.66, 46.87, 192.06 ,56.47, 188.86, 57.27},
+{'f', 1.000000,0.737000,0.603000,1.000000,0,0 },
+{'m', 141.37, 35.82, 0, 0, 0, 0},
+{'c', 134.97, 36.62, 107.52 ,13.94, 124.56, 44.62},
+{'c', 146.56, 84.22, 66.16 ,83.82, 49.36, 72.62},
+{'c', 32.56, 61.42, 56.56 ,91.02, 56.56, 91.02},
+{'c', 74.96, 111.02, 40.56 ,94.22, 40.56, 94.22},
+{'c', 6.16, 81.42, -17.84 ,107.02, -21.04, 107.82},
+{'c', -24.24, 108.62, -29.04 ,111.82, -29.84, 105.42},
+{'c', -30.64, 99.02, -37.23 ,83.49, -69.84, 108.62},
+{'c', -98.49, 130.44, -110.13 ,112.26, -110.13, 112.26},
+{'l', -115.73, 113.42, 0, 0, 0, 0},
+{'c', -130.13, 85.02, -121.62 ,140.98, -121.62, 140.98},
+{'c', -112.82, 175.38, 21.36 ,128.62, 21.36, 128.62},
+{'c', 21.36, 128.62, 190.16 ,98.22, 201.37, 94.22},
+{'c', 212.56, 90.22, 301.66 ,96.11, 301.66, 96.11},
+{'l', 296.56, 75.75, 0, 0, 0, 0},
+{'c', 231.76, 29.35, 218.16 ,56.62, 204.56, 52.62},
+{'c', 190.97, 48.62, 193.37 ,58.22, 190.16, 59.02},
+{'f', 1.000000,0.804000,0.737000,1.000000,0,0 },
+{'m', 142.67, 37.56, 0, 0, 0, 0},
+{'c', 136.27, 38.37, 108.83 ,15.69, 125.87, 46.37},
+{'c', 147.87, 85.97, 67.47 ,85.56, 50.67, 74.36},
+{'c', 33.87, 63.16, 57.87 ,92.77, 57.87, 92.77},
+{'c', 76.27, 112.77, 41.87 ,95.97, 41.87, 95.97},
+{'c', 7.47, 83.17, -16.53 ,108.77, -19.73, 109.56},
+{'c', -22.93, 110.36, -27.73 ,113.56, -28.53, 107.17},
+{'c', -29.33, 100.77, -35.79 ,85.41, -68.53, 110.36},
+{'c', -98.42, 132.93, -109.75 ,115.29, -109.75, 115.29},
+{'l', -115.75, 114.97, 0, 0, 0, 0},
+{'c', -129.35, 88.56, -120.96 ,144.04, -120.96, 144.04},
+{'c', -112.16, 178.44, 22.67 ,130.37, 22.67, 130.37},
+{'c', 22.67, 130.37, 191.47 ,99.97, 202.67, 95.97},
+{'c', 213.87, 91.97, 302.09 ,97.78, 302.09, 97.78},
+{'l', 297.07, 76.91, 0, 0, 0, 0},
+{'c', 232.27, 30.51, 219.47 ,58.37, 205.87, 54.37},
+{'c', 192.27, 50.37, 194.67 ,59.97, 191.47, 60.77},
+{'f', 1.000000,0.871000,0.804000,1.000000,0,0 },
+{'m', 143.98, 39.31, 0, 0, 0, 0},
+{'c', 137.58, 40.11, 110.53 ,17.22, 127.18, 48.11},
+{'c', 149.18, 88.91, 68.78 ,87.31, 51.98, 76.11},
+{'c', 35.18, 64.91, 59.18 ,94.51, 59.18, 94.51},
+{'c', 77.58, 114.51, 43.18 ,97.71, 43.18, 97.71},
+{'c', 8.78, 84.91, -15.22 ,110.51, -18.42, 111.31},
+{'c', -21.62, 112.11, -26.42 ,115.31, -27.22, 108.91},
+{'c', -28.02, 102.51, -34.35 ,87.32, -67.22, 112.11},
+{'c', -98.34, 135.42, -109.36 ,118.33, -109.36, 118.33},
+{'l', -115.76, 116.51, 0, 0, 0, 0},
+{'c', -128.76, 92.51, -120.31 ,147.09, -120.31, 147.09},
+{'c', -111.51, 181.49, 23.98 ,132.11, 23.98, 132.11},
+{'c', 23.98, 132.11, 192.78 ,101.71, 203.98, 97.71},
+{'c', 215.18, 93.71, 302.53 ,99.46, 302.53, 99.46},
+{'l', 297.58, 78.07, 0, 0, 0, 0},
+{'c', 232.78, 31.67, 220.78 ,60.11, 207.18, 56.11},
+{'c', 193.58, 52.11, 195.98 ,61.71, 192.78, 62.51},
+{'f', 1.000000,0.938000,0.871000,1.000000,0,0 },
+{'m', 145.29, 41.05, 0, 0, 0, 0},
+{'c', 138.89, 41.85, 112.92 ,18.41, 128.49, 49.85},
+{'c', 149.69, 92.66, 70.09 ,89.06, 53.29, 77.86},
+{'c', 36.49, 66.66, 60.49 ,96.26, 60.49, 96.26},
+{'c', 78.89, 116.26, 44.49 ,99.46, 44.49, 99.46},
+{'c', 10.09, 86.66, -13.91 ,112.26, -17.11, 113.06},
+{'c', -20.31, 113.86, -25.11 ,117.06, -25.91, 110.66},
+{'c', -26.71, 104.26, -32.91 ,89.23, -65.91, 113.86},
+{'c', -98.27, 137.91, -108.98 ,121.36, -108.98, 121.36},
+{'l', -115.78, 118.06, 0, 0, 0, 0},
+{'c', -128.58, 94.86, -119.65 ,150.15, -119.65, 150.15},
+{'c', -110.85, 184.55, 25.29 ,133.86, 25.29, 133.86},
+{'c', 25.29, 133.86, 194.09 ,103.46, 205.29, 99.46},
+{'c', 216.49, 95.46, 302.96 ,101.13, 302.96, 101.13},
+{'l', 298.09, 79.24, 0, 0, 0, 0},
+{'c', 233.29, 32.84, 222.09 ,61.86, 208.49, 57.86},
+{'c', 194.89, 53.85, 197.29 ,63.46, 194.09, 64.26},
+{'f', 1.000000,1.000000,0.938000,1.000000,0,0 },
+{'m', -115.80, 119.60, 0, 0, 0, 0},
+{'c', -128.60, 97.60, -119.00 ,153.20, -119.00, 153.20},
+{'c', -110.20, 187.60, 26.60 ,135.60, 26.60, 135.60},
+{'c', 26.60, 135.60, 195.40 ,105.20, 206.60, 101.20},
+{'c', 217.80, 97.20, 303.40 ,102.80, 303.40, 102.80},
+{'l', 298.60, 80.40, 0, 0, 0, 0},
+{'c', 233.80, 34.00, 223.40 ,63.60, 209.80, 59.60},
+{'c', 196.20, 55.60, 198.60 ,65.20, 195.40, 66.00},
+{'c', 192.20, 66.80, 153.00 ,42.00, 146.60, 42.80},
+{'c', 140.20, 43.60, 114.98 ,19.79, 129.80, 51.60},
+{'c', 152.03, 99.31, 69.04 ,89.23, 54.60, 79.60},
+{'c', 37.80, 68.40, 61.80 ,98.00, 61.80, 98.00},
+{'c', 80.20, 118.00, 45.80 ,101.20, 45.80, 101.20},
+{'c', 11.40, 88.40, -12.60 ,114.00, -15.80, 114.80},
+{'c', -19.00, 115.60, -23.80 ,118.80, -24.60, 112.40},
+{'c', -25.40, 106.00, -31.46 ,91.14, -64.60, 115.60},
+{'c', -98.20, 140.40, -108.60 ,124.40, -108.60, 124.40},
+{'f', 1.000000,1.000000,1.000000,1.000000,0,0 },
+{'m', -74.20, 149.60, 0, 0, 0, 0},
+{'c', -74.20, 149.60, -81.40 ,161.20, -60.60, 174.40},
+{'c', -60.60, 174.40, -59.20 ,175.80, -77.20, 171.60},
+{'c', -77.20, 171.60, -83.40 ,169.60, -85.00, 159.20},
+{'c', -85.00, 159.20, -89.80 ,154.80, -94.60, 149.20},
+{'f', 0.000000,0.000000,0.000000,1.000000,0,0 },
+{'m', 65.80, 102.00, 0, 0, 0, 0},
+{'c', 65.80, 102.00, 83.50 ,128.82, 82.90, 133.60},
+{'c', 81.60, 144.00, 81.40 ,153.60, 84.60, 157.60},
+{'c', 87.80, 161.60, 96.60 ,194.80, 96.60, 194.80},
+{'c', 96.60, 194.80, 96.20 ,196.00, 108.60, 158.00},
+{'c', 108.60, 158.00, 120.20 ,142.00, 100.20, 123.60},
+{'f', 0.804000,0.804000,0.804000,1.000000,0,0 },
+{'m', -54.20, 176.40, 0, 0, 0, 0},
+{'c', -54.20, 176.40, -43.00 ,183.60, -57.40, 214.80},
+{'l', -51.00, 212.40, 0, 0, 0, 0},
+{'c', -51.00, 212.40, -51.80 ,223.60, -55.00, 226.00},
+{'l', -47.80, 222.80, 0, 0, 0, 0},
+{'c', -47.80, 222.80, -43.00 ,230.80, -47.00, 235.60},
+{'c', -47.00, 235.60, -30.20 ,243.60, -31.00, 250.00},
+{'c', -31.00, 250.00, -24.60 ,242.00, -28.60, 235.60},
+{'c', -32.60, 229.20, -39.80 ,233.20, -39.00, 214.80},
+{'l', -47.80, 218.00, 0, 0, 0, 0},
+{'c', -47.80, 218.00, -42.20 ,209.20, -42.20, 202.80},
+{'l', -50.20, 205.20, 0, 0, 0, 0},
+{'c', -50.20, 205.20, -34.73 ,178.62, -45.40, 177.20},
+{'f', 0.000000,0.000000,0.000000,1.000000,0,0 },
+{'m', -21.80, 193.20, 0, 0, 0, 0},
+{'c', -21.80, 193.20, -19.00 ,188.80, -21.80, 189.60},
+{'c', -24.60, 190.40, -55.80 ,205.20, -61.80, 214.80},
+{'f', 0.804000,0.804000,0.804000,1.000000,0,0 },
+{'m', -11.40, 201.20, 0, 0, 0, 0},
+{'c', -11.40, 201.20, -8.60 ,196.80, -11.40, 197.60},
+{'c', -14.20, 198.40, -45.40 ,213.20, -51.40, 222.80},
+{'f', 0.804000,0.804000,0.804000,1.000000,0,0 },
+{'m', 1.80, 186.00, 0, 0, 0, 0},
+{'c', 1.80, 186.00, 4.60 ,181.60, 1.80, 182.40},
+{'c', -1.00, 183.20, -32.20 ,198.00, -38.20, 207.60},
+{'f', 0.804000,0.804000,0.804000,1.000000,0,0 },
+{'m', -21.40, 229.60, 0, 0, 0, 0},
+{'c', -21.40, 229.60, -21.40 ,223.60, -24.20, 224.40},
+{'c', -27.00, 225.20, -63.00 ,242.80, -69.00, 252.40},
+{'f', 0.804000,0.804000,0.804000,1.000000,0,0 },
+{'m', -20.20, 218.80, 0, 0, 0, 0},
+{'c', -20.20, 218.80, -19.00 ,214.00, -21.80, 214.80},
+{'c', -23.80, 214.80, -50.20 ,226.40, -56.20, 236.00},
+{'f', 0.804000,0.804000,0.804000,1.000000,0,0 },
+{'m', -34.60, 266.40, 0, 0, 0, 0},
+{'l', -44.60, 274.00, 0, 0, 0, 0},
+{'c', -44.60, 274.00, -34.20 ,266.40, -30.60, 267.60},
+{'c', -30.60, 267.60, -37.40 ,278.80, -38.20, 284.00},
+{'c', -38.20, 284.00, -27.80 ,271.20, -22.20, 271.60},
+{'c', -22.20, 271.60, -14.60 ,272.00, -14.60, 282.80},
+{'c', -14.60, 282.80, -9.00 ,272.40, -5.80, 272.80},
+{'c', -5.80, 272.80, -4.60 ,279.20, -5.80, 286.00},
+{'c', -5.80, 286.00, -1.80 ,278.40, 2.20, 280.00},
+{'c', 2.20, 280.00, 8.60 ,278.00, 7.80, 289.60},
+{'c', 7.80, 289.60, 7.80 ,300.00, 7.00, 302.80},
+{'c', 7.00, 302.80, 12.60 ,276.40, 15.00, 276.00},
+{'c', 15.00, 276.00, 23.00 ,274.80, 27.80, 283.60},
+{'c', 27.80, 283.60, 23.80 ,276.00, 28.60, 278.00},
+{'c', 28.60, 278.00, 39.40 ,279.60, 42.60, 286.40},
+{'c', 42.60, 286.40, 35.80 ,274.40, 41.40, 277.60},
+{'c', 41.40, 277.60, 48.20 ,277.60, 49.40, 284.00},
+{'c', 49.40, 284.00, 57.80 ,305.20, 59.80, 306.80},
+{'c', 59.80, 306.80, 52.20 ,285.20, 53.80, 285.20},
+{'c', 53.80, 285.20, 51.80 ,273.20, 57.00, 288.00},
+{'c', 57.00, 288.00, 53.80 ,274.00, 59.40, 274.80},
+{'c', 65.00, 275.60, 69.40 ,285.60, 77.80, 283.20},
+{'c', 77.80, 283.20, 87.40 ,288.80, 89.40, 219.60},
+{'f', 0.804000,0.804000,0.804000,1.000000,0,0 },
+{'m', -29.80, 173.60, 0, 0, 0, 0},
+{'c', -29.80, 173.60, -15.00 ,167.60, 25.00, 173.60},
+{'c', 25.00, 173.60, 32.20 ,174.00, 39.00, 165.20},
+{'c', 45.80, 156.40, 72.60 ,149.20, 79.00, 151.20},
+{'l', 88.60, 157.60, 0, 0, 0, 0},
+{'l', 89.40, 158.80, 0, 0, 0, 0},
+{'c', 89.40, 158.80, 101.80 ,169.20, 102.20, 176.80},
+{'c', 102.60, 184.40, 87.80 ,232.40, 78.20, 248.40},
+{'c', 68.60, 264.40, 59.00 ,276.80, 39.80, 274.40},
+{'c', 39.80, 274.40, 19.00 ,270.40, -6.60, 274.40},
+{'c', -6.60, 274.40, -35.80 ,272.80, -38.60, 264.80},
+{'c', -41.40, 256.80, -27.40 ,241.60, -27.40, 241.60},
+{'c', -27.40, 241.60, -23.00 ,233.20, -24.20, 218.80},
+{'f', 0.000000,0.000000,0.000000,1.000000,0,0 },
+{'m', -7.80, 175.60, 0, 0, 0, 0},
+{'c', 0.60, 194.00, -29.00 ,259.20, -29.00, 259.20},
+{'c', -31.00, 260.80, -16.34 ,266.85, -6.20, 264.40},
+{'c', 4.75, 261.76, 45.00 ,266.00, 45.00, 266.00},
+{'c', 68.60, 250.40, 81.40 ,206.00, 81.40, 206.00},
+{'c', 81.40, 206.00, 91.80 ,182.00, 74.20, 178.80},
+{'f', 0.938000,0.402000,0.536000,1.000000,0,0 },
+{'m', -9.83, 206.50, 0, 0, 0, 0},
+{'c', -6.50, 193.71, -4.92 ,181.91, -7.80, 175.60},
+{'c', -7.80, 175.60, 54.60 ,182.00, 65.80, 161.20},
+{'c', 70.04, 153.33, 84.80 ,184.00, 84.40, 193.60},
+{'c', 84.40, 193.60, 21.40 ,208.00, 6.60, 196.80},
+{'f', 0.737000,0.201000,0.335000,1.000000,0,0 },
+{'m', -5.40, 222.80, 0, 0, 0, 0},
+{'c', -5.40, 222.80, -3.40 ,230.00, -5.80, 234.00},
+{'c', -5.80, 234.00, -7.40 ,234.80, -8.60, 235.20},
+{'c', -8.60, 235.20, -7.40 ,238.80, -1.40, 240.40},
+{'c', -1.40, 240.40, 0.60 ,244.80, 3.00, 245.20},
+{'c', 5.40, 245.60, 10.20 ,251.20, 14.20, 250.00},
+{'c', 18.20, 248.80, 29.40 ,244.80, 29.40, 244.80},
+{'c', 29.40, 244.80, 35.00 ,241.60, 43.80, 245.20},
+{'c', 43.80, 245.20, 46.17 ,244.40, 46.60, 240.40},
+{'c', 47.10, 235.70, 50.20 ,232.00, 52.20, 230.00},
+{'c', 54.20, 228.00, 63.80 ,215.20, 62.60, 214.80},
+{'f', 0.670000,0.134000,0.268000,1.000000,0,0 },
+{'m', -9.80, 174.40, 0, 0, 0, 0},
+{'c', -9.80, 174.40, -12.60 ,196.80, -9.40, 205.20},
+{'c', -6.20, 213.60, -7.00 ,215.60, -7.80, 219.60},
+{'c', -8.60, 223.60, -4.20 ,233.60, 1.40, 239.60},
+{'l', 13.40, 241.20, 0, 0, 0, 0},
+{'c', 13.40, 241.20, 28.60 ,237.60, 37.80, 240.40},
+{'c', 37.80, 240.40, 46.79 ,241.74, 50.20, 226.80},
+{'c', 50.20, 226.80, 55.00 ,220.40, 62.20, 217.60},
+{'c', 69.40, 214.80, 76.60 ,173.20, 72.60, 165.20},
+{'c', 68.60, 157.20, 54.20 ,152.80, 38.20, 168.40},
+{'f', 1.000000,0.469000,0.469000,1.000000,0,0 },
+{'m', -8.20, 249.20, 0, 0, 0, 0},
+{'c', -8.20, 249.20, -9.00 ,247.20, -13.40, 246.80},
+{'c', -13.40, 246.80, -35.80 ,243.20, -44.20, 230.80},
+{'c', -44.20, 230.80, -51.00 ,225.20, -46.60, 236.80},
+{'c', -46.60, 236.80, -36.20 ,257.20, -29.40, 260.00},
+{'f', 1.000000,1.000000,0.804000,1.000000,0,0 },
+{'m', 71.74, 185.23, 0, 0, 0, 0},
+{'c', 72.40, 177.32, 74.35 ,168.71, 72.60, 165.20},
+{'c', 66.15, 152.31, 49.18 ,157.69, 38.20, 168.40},
+{'c', 22.20, 184.00, 20.20 ,167.20, -9.80, 174.40},
+{'c', -9.80, 174.40, -11.54 ,188.36, -10.71, 198.38},
+{'c', -10.71, 198.38, 26.60 ,186.80, 27.40, 192.40},
+{'c', 27.40, 192.40, 29.00 ,189.20, 38.20, 189.20},
+{'f', 0.804000,0.201000,0.268000,1.000000,0,0 },
+{'m', 28.60, 175.20, 0, 0, 0, 0},
+{'c', 28.60, 175.20, 33.40 ,180.00, 29.80, 189.60},
+{'f', 0.804000,0.201000,0.268000,1.000000,0,0 },
+{'m', -19.40, 260.00, 0, 0, 0, 0},
+{'c', -19.40, 260.00, -23.80 ,247.20, -15.00, 254.00},
+{'c', -15.00, 254.00, -10.20 ,256.00, -11.40, 257.60},
+{'f', 1.000000,1.000000,0.804000,1.000000,0,0 },
+{'m', -14.36, 261.20, 0, 0, 0, 0},
+{'c', -14.36, 261.20, -17.88 ,250.96, -10.84, 256.40},
+{'c', -10.84, 256.40, -6.42 ,258.85, -7.96, 259.28},
+{'f', 1.000000,1.000000,0.804000,1.000000,0,0 },
+{'m', -9.56, 261.20, 0, 0, 0, 0},
+{'c', -9.56, 261.20, -13.08 ,250.96, -6.04, 256.40},
+{'c', -6.04, 256.40, -1.67 ,258.71, -3.16, 259.28},
+{'f', 1.000000,1.000000,0.804000,1.000000,0,0 },
+{'m', -2.96, 261.40, 0, 0, 0, 0},
+{'c', -2.96, 261.40, -6.48 ,251.16, 0.56, 256.60},
+{'c', 0.56, 256.60, 4.94 ,258.93, 3.44, 259.48},
+{'f', 1.000000,1.000000,0.804000,1.000000,0,0 },
+{'m', 3.52, 261.32, 0, 0, 0, 0},
+{'c', 3.52, 261.32, 0.00 ,251.08, 7.04, 256.52},
+{'c', 7.04, 256.52, 10.88 ,258.12, 9.92, 259.40},
+{'f', 1.000000,1.000000,0.804000,1.000000,0,0 },
+{'m', 10.20, 262.00, 0, 0, 0, 0},
+{'c', 10.20, 262.00, 5.40 ,249.60, 14.60, 256.00},
+{'c', 14.60, 256.00, 19.40 ,258.00, 18.20, 259.60},
+{'f', 1.000000,1.000000,0.804000,1.000000,0,0 },
+{'m', -18.20, 244.80, 0, 0, 0, 0},
+{'c', -18.20, 244.80, -5.00 ,242.00, 1.00, 245.20},
+{'c', 1.00, 245.20, 7.00 ,246.40, 8.20, 246.00},
+{'f', 1.000000,1.000000,0.804000,1.000000,0,0 },
+{'m', 15.80, 253.60, 0, 0, 0, 0},
+{'c', 15.80, 253.60, 27.80 ,240.00, 39.80, 244.40},
+{'c', 46.82, 246.97, 45.80 ,243.60, 46.60, 240.80},
+{'f', 1.000000,1.000000,0.804000,1.000000,0,0 },
+{'m', 33.00, 237.60, 0, 0, 0, 0},
+{'c', 33.00, 237.60, 29.00 ,226.80, 26.20, 239.60},
+{'c', 23.40, 252.40, 20.20 ,256.00, 18.60, 258.80},
+{'c', 18.60, 258.80, 18.60 ,264.00, 27.00, 263.60},
+{'c', 27.00, 263.60, 37.80 ,263.20, 38.20, 260.40},
+{'f', 1.000000,1.000000,0.804000,1.000000,0,0 },
+{'m', 47.00, 244.80, 0, 0, 0, 0},
+{'f', 1.000000,1.000000,0.804000,1.000000,0,0 },
+{'m', 53.50, 228.40, 0, 0, 0, 0},
+{'f', 1.000000,1.000000,0.804000,1.000000,0,0 },
+{'m', -25.80, 265.20, 0, 0, 0, 0},
+{'c', -25.80, 265.20, -7.80 ,268.40, -3.40, 266.80},
+{'c', -3.40, 266.80, 5.40 ,266.80, -3.00, 268.80},
+{'c', -3.00, 268.80, -15.80 ,268.80, -23.80, 267.60},
+{'f', 0.737000,0.737000,0.737000,1.000000,0,0 },
+{'m', -11.80, 172.00, 0, 0, 0, 0},
+{'c', -11.80, 172.00, 5.80 ,172.00, 7.80, 172.80},
+{'c', 7.80, 172.80, 15.00 ,203.60, 11.40, 211.20},
+{'c', 11.40, 211.20, 10.20 ,214.00, 7.40, 208.40},
+{'c', 7.40, 208.40, -11.00 ,175.60, -14.20, 173.60},
+{'f', 1.000000,1.000000,0.804000,1.000000,0,0 },
+{'m', -88.90, 169.30, 0, 0, 0, 0},
+{'c', -88.90, 169.30, -80.00 ,171.00, -67.40, 173.60},
+{'c', -67.40, 173.60, -62.60 ,196.00, -59.40, 200.80},
+{'c', -56.20, 205.60, -59.80 ,205.60, -63.40, 202.80},
+{'c', -67.00, 200.00, -81.80 ,186.00, -83.80, 181.60},
+{'f', 1.000000,1.000000,0.804000,1.000000,0,0 },
+{'m', -67.04, 173.82, 0, 0, 0, 0},
+{'c', -67.04, 173.82, -61.24 ,175.37, -60.23, 177.58},
+{'c', -59.22, 179.79, -61.43 ,183.09, -61.43, 183.09},
+{'c', -61.43, 183.09, -62.43 ,186.40, -63.63, 184.24},
+{'f', 1.000000,1.000000,0.804000,1.000000,0,0 },
+{'m', -67.00, 173.60, 0, 0, 0, 0},
+{'c', -67.00, 173.60, -63.40 ,178.80, -59.80, 178.80},
+{'c', -56.20, 178.80, -55.82 ,178.39, -53.00, 179.00},
+{'c', -48.40, 180.00, -48.80 ,178.00, -42.20, 179.20},
+{'c', -39.56, 179.68, -37.00 ,178.80, -34.20, 180.00},
+{'c', -31.40, 181.20, -28.20 ,180.40, -27.00, 178.40},
+{'c', -25.80, 176.40, -21.00 ,172.20, -21.00, 172.20},
+{'c', -21.00, 172.20, -33.80 ,174.00, -36.60, 174.80},
+{'f', 0.000000,0.000000,0.000000,1.000000,0,0 },
+{'m', -22.40, 173.80, 0, 0, 0, 0},
+{'c', -22.40, 173.80, -28.85 ,177.30, -29.25, 179.70},
+{'c', -29.65, 182.10, -24.00 ,185.80, -24.00, 185.80},
+{'c', -24.00, 185.80, -21.25 ,190.40, -20.65, 188.00},
+{'f', 1.000000,1.000000,0.804000,1.000000,0,0 },
+{'m', -59.88, 179.26, 0, 0, 0, 0},
+{'c', -59.88, 179.26, -52.88 ,190.45, -52.66, 179.24},
+{'c', -52.66, 179.24, -52.10 ,177.98, -53.86, 177.96},
+{'f', 1.000000,1.000000,0.804000,1.000000,0,0 },
+{'m', -52.71, 179.51, 0, 0, 0, 0},
+{'c', -52.71, 179.51, -44.79 ,190.70, -45.42, 179.42},
+{'c', -45.42, 179.42, -45.41 ,179.09, -47.17, 178.94},
+{'f', 1.000000,1.000000,0.804000,1.000000,0,0 },
+{'m', -45.49, 179.52, 0, 0, 0, 0},
+{'c', -45.49, 179.52, -37.53 ,190.15, -38.20, 180.48},
+{'c', -38.20, 180.48, -38.08 ,179.25, -39.74, 178.95},
+{'f', 1.000000,1.000000,0.804000,1.000000,0,0 },
+{'m', -38.62, 179.60, 0, 0, 0, 0},
+{'c', -38.62, 179.60, -30.72 ,191.16, -30.37, 181.38},
+{'c', -30.37, 181.38, -28.73 ,180.00, -30.47, 179.78},
+{'f', 1.000000,1.000000,0.804000,1.000000,0,0 },
+{'m', -74.79, 183.13, 0, 0, 0, 0},
+{'l', -82.45, 181.60, 0, 0, 0, 0},
+{'c', -85.05, 176.60, -87.15 ,170.45, -87.15, 170.45},
+{'c', -87.15, 170.45, -80.80 ,171.45, -68.30, 174.25},
+{'c', -68.30, 174.25, -67.42 ,177.57, -65.95, 183.36},
+{'f', 0.938000,0.938000,0.737000,1.000000,0,0 },
+{'m', -9.72, 178.47, 0, 0, 0, 0},
+{'c', -11.39, 175.96, -12.71 ,174.21, -13.36, 173.80},
+{'c', -16.37, 171.92, -12.23 ,172.29, -11.10, 172.29},
+{'c', -11.10, 172.29, 5.47 ,172.29, 7.36, 173.05},
+{'c', 7.36, 173.05, 7.88 ,175.29, 8.56, 178.68},
+{'f', 0.938000,0.938000,0.737000,1.000000,0,0 },
+{'m', 43.88, 40.32, 0, 0, 0, 0},
+{'c', 71.60, 44.28, 97.12 ,8.64, 98.88, -1.04},
+{'c', 100.64, -10.72, 90.52 ,-22.60, 90.52, -22.60},
+{'c', 91.84, -25.68, 87.00 ,-39.76, 81.72, -49.00},
+{'c', 76.44, -58.24, 60.54 ,-57.27, 43.00, -58.24},
+{'c', 27.16, -59.12, 8.68 ,-35.80, 7.36, -34.04},
+{'c', 6.04, -32.28, 12.20 ,6.00, 13.52, 11.72},
+{'c', 14.84, 17.44, 12.20 ,43.84, 12.20, 43.84},
+{'f', 0.804000,0.469000,0.134000,1.000000,0,0 },
+{'m', 8.09, -33.39, 0, 0, 0, 0},
+{'c', 6.79, -31.66, 12.84 ,5.92, 14.14, 11.54},
+{'c', 15.43, 17.15, 12.84 ,43.07, 12.84, 43.07},
+{'c', 45.51, 34.19, 16.73 ,35.73, 43.94, 39.62},
+{'c', 71.16, 43.51, 96.22 ,8.51, 97.94, -0.99},
+{'c', 99.67, -10.50, 89.74 ,-22.16, 89.74, -22.16},
+{'c', 91.03, -25.18, 86.28 ,-39.01, 81.10, -48.08},
+{'c', 75.91, -57.15, 60.30 ,-56.20, 43.08, -57.15},
+{'f', 0.938000,0.536000,0.335000,1.000000,0,0 },
+{'m', 8.82, -32.74, 0, 0, 0, 0},
+{'c', 7.54, -31.05, 13.48 ,5.84, 14.75, 11.35},
+{'c', 16.02, 16.86, 13.48 ,42.30, 13.48, 42.30},
+{'c', 44.88, 33.15, 17.30 ,35.10, 44.01, 38.91},
+{'c', 70.72, 42.73, 95.31 ,8.38, 97.01, -0.94},
+{'c', 98.70, -10.27, 88.95 ,-21.72, 88.95, -21.72},
+{'c', 90.22, -24.69, 85.56 ,-38.26, 80.47, -47.16},
+{'c', 75.39, -56.06, 60.06 ,-55.12, 43.16, -56.06},
+{'f', 0.938000,0.670000,0.469000,1.000000,0,0 },
+{'m', 9.54, -32.10, 0, 0, 0, 0},
+{'c', 8.30, -30.43, 14.12 ,5.76, 15.37, 11.17},
+{'c', 16.62, 16.58, 14.12 ,41.54, 14.12, 41.54},
+{'c', 43.56, 32.50, 17.86 ,34.47, 44.07, 38.21},
+{'c', 70.28, 41.95, 94.41 ,8.26, 96.07, -0.90},
+{'c', 97.74, -10.05, 88.17 ,-21.28, 88.17, -21.28},
+{'c', 89.42, -24.19, 84.84 ,-37.50, 79.85, -46.24},
+{'c', 74.86, -54.98, 59.82 ,-54.05, 43.24, -54.98},
+{'f', 1.000000,0.804000,0.670000,1.000000,0,0 },
+{'m', 10.27, -31.45, 0, 0, 0, 0},
+{'c', 9.05, -29.82, 14.76 ,5.68, 15.98, 10.98},
+{'c', 17.21, 16.29, 14.76 ,40.77, 14.76, 40.77},
+{'c', 42.63, 31.85, 18.43 ,33.83, 44.14, 37.51},
+{'c', 69.84, 41.18, 93.50 ,8.13, 95.14, -0.85},
+{'c', 96.77, -9.82, 87.39 ,-20.84, 87.39, -20.84},
+{'c', 88.61, -23.70, 84.12 ,-36.75, 79.22, -45.32},
+{'c', 74.33, -53.89, 59.59 ,-52.98, 43.32, -53.89},
+{'f', 1.000000,0.938000,0.871000,1.000000,0,0 },
+{'m', 44.20, 36.80, 0, 0, 0, 0},
+{'c', 69.40, 40.40, 92.60 ,8.00, 94.20, -0.80},
+{'c', 95.80, -9.60, 86.60 ,-20.40, 86.60, -20.40},
+{'c', 87.80, -23.20, 83.40 ,-36.00, 78.60, -44.40},
+{'c', 73.80, -52.80, 59.35 ,-51.91, 43.40, -52.80},
+{'c', 29.00, -53.60, 12.20 ,-32.40, 11.00, -30.80},
+{'c', 9.80, -29.20, 15.40 ,5.60, 16.60, 10.80},
+{'c', 17.80, 16.00, 15.40 ,40.00, 15.40, 40.00},
+{'f', 1.000000,1.000000,1.000000,1.000000,0,0 },
+{'m', 90.60, 2.80, 0, 0, 0, 0},
+{'c', 90.60, 2.80, 62.80 ,10.40, 51.20, 8.80},
+{'c', 51.20, 8.80, 35.40 ,2.20, 26.60, 24.00},
+{'c', 26.60, 24.00, 23.00 ,31.20, 21.00, 33.20},
+{'f', 0.804000,0.804000,0.804000,1.000000,0,0 },
+{'m', 94.40, 0.60, 0, 0, 0, 0},
+{'c', 94.40, 0.60, 65.40 ,12.80, 55.40, 12.40},
+{'c', 55.40, 12.40, 39.00 ,7.80, 30.60, 22.40},
+{'c', 30.60, 22.40, 22.20 ,31.60, 19.00, 33.20},
+{'c', 19.00, 33.20, 18.60 ,34.80, 25.00, 30.80},
+{'l', 35.40, 36.00, 0, 0, 0, 0},
+{'c', 35.40, 36.00, 50.20 ,45.60, 59.80, 29.60},
+{'c', 59.80, 29.60, 63.80 ,18.40, 63.80, 16.40},
+{'c', 63.80, 14.40, 85.00 ,8.80, 86.60, 8.40},
+{'f', 0.000000,0.000000,0.000000,1.000000,0,0 },
+{'m', 47.00, 36.51, 0, 0, 0, 0},
+{'c', 40.13, 36.51, 31.75 ,32.65, 31.75, 26.40},
+{'c', 31.75, 20.15, 40.13 ,13.89, 47.00, 13.89},
+{'c', 53.87, 13.89, 59.45 ,18.95, 59.45, 25.20},
+{'f', 0.603000,0.804000,0.201000,1.000000,0,0 },
+{'m', 43.38, 19.83, 0, 0, 0, 0},
+{'c', 38.53, 20.55, 33.44 ,22.05, 33.51, 21.84},
+{'c', 35.05, 17.22, 41.41 ,13.89, 47.00, 13.89},
+{'c', 51.30, 13.89, 55.08 ,15.87, 57.32, 18.88},
+{'f', 0.402000,0.603000,0.000000,1.000000,0,0 },
+{'m', 55.40, 19.60, 0, 0, 0, 0},
+{'c', 55.40, 19.60, 51.00 ,16.40, 51.00, 18.60},
+{'f', 1.000000,1.000000,1.000000,1.000000,0,0 },
+{'m', 45.40, 27.73, 0, 0, 0, 0},
+{'c', 42.90, 27.73, 40.88 ,25.70, 40.88, 23.20},
+{'c', 40.88, 20.70, 42.90 ,18.68, 45.40, 18.68},
+{'c', 47.90, 18.68, 49.93 ,20.70, 49.93, 23.20},
+{'f', 0.000000,0.000000,0.000000,1.000000,0,0 },
+{'m', -58.60, 14.40, 0, 0, 0, 0},
+{'c', -58.60, 14.40, -61.80 ,-6.80, -59.40, -11.20},
+{'c', -59.40, -11.20, -48.60 ,-21.20, -49.00, -24.80},
+{'c', -49.00, -24.80, -49.40 ,-42.80, -50.60, -43.60},
+{'c', -51.80, -44.40, -59.40 ,-50.40, -65.40, -44.00},
+{'c', -65.40, -44.00, -75.80 ,-26.00, -75.00, -19.60},
+{'l', -75.00, -17.60, 0, 0, 0, 0},
+{'c', -75.00, -17.60, -82.60 ,-18.00, -84.20, -16.00},
+{'c', -84.20, -16.00, -85.40 ,-10.80, -86.60, -10.40},
+{'c', -86.60, -10.40, -89.40 ,-8.00, -87.40, -5.20},
+{'c', -87.40, -5.20, -89.40 ,-2.80, -89.00, 1.20},
+{'l', -81.40, 5.20, 0, 0, 0, 0},
+{'c', -81.40, 5.20, -79.40 ,19.60, -68.60, 24.80},
+{'f', 0.804000,0.469000,0.134000,1.000000,0,0 },
+{'m', -59.60, 12.56, 0, 0, 0, 0},
+{'c', -59.60, 12.56, -62.48 ,-6.52, -60.32, -10.48},
+{'c', -60.32, -10.48, -50.60 ,-19.48, -50.96, -22.72},
+{'c', -50.96, -22.72, -51.32 ,-38.92, -52.40, -39.64},
+{'c', -53.48, -40.36, -60.32 ,-45.76, -65.72, -40.00},
+{'c', -65.72, -40.00, -75.08 ,-23.80, -74.36, -18.04},
+{'l', -74.36, -16.24, 0, 0, 0, 0},
+{'c', -74.36, -16.24, -81.20 ,-16.60, -82.64, -14.80},
+{'c', -82.64, -14.80, -83.72 ,-10.12, -84.80, -9.76},
+{'c', -84.80, -9.76, -87.32 ,-7.60, -85.52, -5.08},
+{'c', -85.52, -5.08, -87.32 ,-2.92, -86.96, 0.68},
+{'l', -80.12, 4.28, 0, 0, 0, 0},
+{'c', -80.12, 4.28, -78.32 ,17.24, -68.60, 21.92},
+{'f', 1.000000,1.000000,1.000000,1.000000,0,0 },
+{'m', -51.05, -42.61, 0, 0, 0, 0},
+{'c', -52.14, -43.47, -59.63 ,-49.24, -65.48, -43.00},
+{'c', -65.48, -43.00, -75.62 ,-25.45, -74.84, -19.21},
+{'l', -74.84, -17.26, 0, 0, 0, 0},
+{'c', -74.84, -17.26, -82.25 ,-17.65, -83.81, -15.70},
+{'c', -83.81, -15.70, -84.98 ,-10.63, -86.15, -10.24},
+{'c', -86.15, -10.24, -88.88 ,-7.90, -86.93, -5.17},
+{'c', -86.93, -5.17, -88.88 ,-2.83, -88.49, 1.07},
+{'l', -81.08, 4.97, 0, 0, 0, 0},
+{'c', -81.08, 4.97, -79.13 ,19.01, -68.60, 24.08},
+{'c', -63.89, 26.35, -60.80 ,19.79, -58.85, 13.94},
+{'c', -58.85, 13.94, -61.97 ,-6.73, -59.63, -11.02},
+{'c', -59.63, -11.02, -49.10 ,-20.77, -49.49, -24.28},
+{'f', 0.938000,0.603000,0.335000,1.000000,0,0 },
+{'m', -51.50, -41.62, 0, 0, 0, 0},
+{'c', -52.48, -42.54, -59.86 ,-48.08, -65.56, -42.00},
+{'c', -65.56, -42.00, -75.44 ,-24.90, -74.68, -18.82},
+{'l', -74.68, -16.92, 0, 0, 0, 0},
+{'c', -74.68, -16.92, -81.90 ,-17.30, -83.42, -15.40},
+{'c', -83.42, -15.40, -84.56 ,-10.46, -85.70, -10.08},
+{'c', -85.70, -10.08, -88.36 ,-7.80, -86.46, -5.14},
+{'c', -86.46, -5.14, -88.36 ,-2.86, -87.98, 0.94},
+{'l', -80.76, 4.74, 0, 0, 0, 0},
+{'c', -80.76, 4.74, -78.86 ,18.42, -68.60, 23.36},
+{'c', -64.01, 25.57, -61.00 ,19.18, -59.10, 13.48},
+{'c', -59.10, 13.48, -62.14 ,-6.66, -59.86, -10.84},
+{'c', -59.86, -10.84, -49.60 ,-20.34, -49.98, -23.76},
+{'f', 1.000000,0.737000,0.603000,1.000000,0,0 },
+{'m', -51.95, -40.63, 0, 0, 0, 0},
+{'c', -52.82, -41.61, -60.09 ,-46.92, -65.64, -41.00},
+{'c', -65.64, -41.00, -75.26 ,-24.35, -74.52, -18.43},
+{'l', -74.52, -16.58, 0, 0, 0, 0},
+{'c', -74.52, -16.58, -81.55 ,-16.95, -83.03, -15.10},
+{'c', -83.03, -15.10, -84.14 ,-10.29, -85.25, -9.92},
+{'c', -85.25, -9.92, -87.84 ,-7.70, -85.99, -5.11},
+{'c', -85.99, -5.11, -87.84 ,-2.89, -87.47, 0.81},
+{'l', -80.44, 4.51, 0, 0, 0, 0},
+{'c', -80.44, 4.51, -78.59 ,17.83, -68.60, 22.64},
+{'c', -64.13, 24.79, -61.20 ,18.57, -59.35, 13.02},
+{'c', -59.35, 13.02, -62.31 ,-6.59, -60.09, -10.66},
+{'c', -60.09, -10.66, -50.10 ,-19.91, -50.47, -23.24},
+{'f', 1.000000,0.871000,0.804000,1.000000,0,0 },
+{'m', -59.60, 12.46, 0, 0, 0, 0},
+{'c', -59.60, 12.46, -62.48 ,-6.52, -60.32, -10.48},
+{'c', -60.32, -10.48, -50.60 ,-19.48, -50.96, -22.72},
+{'c', -50.96, -22.72, -51.32 ,-38.92, -52.40, -39.64},
+{'c', -53.16, -40.68, -60.32 ,-45.76, -65.72, -40.00},
+{'c', -65.72, -40.00, -75.08 ,-23.80, -74.36, -18.04},
+{'l', -74.36, -16.24, 0, 0, 0, 0},
+{'c', -74.36, -16.24, -81.20 ,-16.60, -82.64, -14.80},
+{'c', -82.64, -14.80, -83.72 ,-10.12, -84.80, -9.76},
+{'c', -84.80, -9.76, -87.32 ,-7.60, -85.52, -5.08},
+{'c', -85.52, -5.08, -87.32 ,-2.92, -86.96, 0.68},
+{'l', -80.12, 4.28, 0, 0, 0, 0},
+{'c', -80.12, 4.28, -78.32 ,17.24, -68.60, 21.92},
+{'f', 1.000000,1.000000,1.000000,1.000000,0,0 },
+{'m', -62.70, 6.20, 0, 0, 0, 0},
+{'c', -62.70, 6.20, -84.30 ,-4.00, -85.20, -4.80},
+{'c', -85.20, -4.80, -76.10 ,3.40, -75.30, 3.40},
+{'f', 0.804000,0.804000,0.804000,1.000000,0,0 },
+{'m', -79.80, 0.00, 0, 0, 0, 0},
+{'c', -79.80, 0.00, -61.40 ,3.60, -61.40, 8.00},
+{'c', -61.40, 10.91, -61.64 ,24.33, -67.00, 22.80},
+{'f', 0.000000,0.000000,0.000000,1.000000,0,0 },
+{'m', -71.40, 3.80, 0, 0, 0, 0},
+{'c', -71.40, 3.80, -62.42 ,5.27, -61.40, 8.00},
+{'c', -60.80, 9.60, -60.14 ,17.91, -65.60, 19.00},
+{'f', 0.603000,0.804000,0.201000,1.000000,0,0 },
+{'m', 14.60, 46.35, 0, 0, 0, 0},
+{'c', 14.10, 44.61, 15.41 ,44.74, 17.20, 44.20},
+{'c', 19.20, 43.60, 31.40 ,39.80, 32.20, 37.20},
+{'c', 33.00, 34.60, 46.20 ,39.00, 46.20, 39.00},
+{'c', 48.00, 39.80, 52.40 ,42.40, 52.40, 42.40},
+{'c', 57.20, 43.60, 63.80 ,44.00, 63.80, 44.00},
+{'c', 66.20, 45.00, 69.60 ,47.80, 69.60, 47.80},
+{'c', 84.20, 58.00, 96.60 ,50.80, 96.60, 50.80},
+{'c', 116.60, 44.20, 110.60 ,27.00, 110.60, 27.00},
+{'c', 107.60, 18.00, 110.80 ,14.60, 110.80, 14.60},
+{'c', 111.00, 10.80, 118.20 ,17.20, 118.20, 17.20},
+{'c', 120.80, 21.40, 121.60 ,26.40, 121.60, 26.40},
+{'c', 129.60, 37.60, 126.20 ,19.80, 126.20, 19.80},
+{'c', 126.40, 18.80, 123.60 ,15.20, 123.60, 14.00},
+{'c', 123.60, 12.80, 121.80 ,9.40, 121.80, 9.40},
+{'c', 118.80, 6.00, 121.20 ,-1.00, 121.20, -1.00},
+{'c', 123.00, -14.80, 120.80 ,-13.00, 120.80, -13.00},
+{'c', 119.60, -14.80, 110.40 ,-4.80, 110.40, -4.80},
+{'c', 108.20, -1.40, 102.20 ,0.20, 102.20, 0.20},
+{'c', 99.40, 2.00, 96.00 ,0.60, 96.00, 0.60},
+{'c', 93.40, 0.20, 87.80 ,7.20, 87.80, 7.20},
+{'c', 90.60, 7.00, 93.00 ,11.40, 95.40, 11.60},
+{'c', 97.80, 11.80, 99.60 ,9.20, 101.20, 8.60},
+{'c', 102.80, 8.00, 105.60 ,13.80, 105.60, 13.80},
+{'c', 106.00, 16.40, 100.40 ,21.20, 100.40, 21.20},
+{'c', 100.00, 25.80, 98.40 ,24.20, 98.40, 24.20},
+{'c', 95.40, 23.60, 94.20 ,27.40, 93.20, 32.00},
+{'c', 92.20, 36.60, 88.00 ,37.00, 88.00, 37.00},
+{'c', 86.40, 44.40, 85.20 ,41.40, 85.20, 41.40},
+{'c', 85.00, 35.80, 79.00 ,41.60, 79.00, 41.60},
+{'c', 77.80, 43.60, 73.20 ,41.40, 73.20, 41.40},
+{'c', 66.40, 39.40, 68.80 ,37.40, 68.80, 37.40},
+{'c', 70.60, 35.20, 81.80 ,37.40, 81.80, 37.40},
+{'c', 84.00, 35.80, 76.00 ,31.80, 76.00, 31.80},
+{'c', 75.40, 30.00, 76.40 ,25.60, 76.40, 25.60},
+{'c', 77.60, 22.40, 84.40 ,16.80, 84.40, 16.80},
+{'c', 93.80, 15.60, 91.00 ,14.00, 91.00, 14.00},
+{'c', 84.80, 8.80, 79.00 ,16.40, 79.00, 16.40},
+{'c', 76.80, 22.60, 59.40 ,37.60, 59.40, 37.60},
+{'c', 54.60, 41.00, 57.20 ,34.20, 53.20, 37.60},
+{'c', 49.20, 41.00, 28.60 ,32.00, 28.60, 32.00},
+{'c', 17.04, 30.81, 14.31 ,46.55, 10.78, 43.43},
+{'f', 0.000000,0.000000,0.000000,1.000000,0,0 },
+{'m', 209.40, -120.00, 0, 0, 0, 0},
+{'c', 209.40, -120.00, 183.80 ,-112.00, 181.00, -93.20},
+{'c', 181.00, -93.20, 178.60 ,-70.40, 199.00, -52.80},
+{'c', 199.00, -52.80, 199.40 ,-46.40, 201.40, -43.20},
+{'c', 201.40, -43.20, 199.80 ,-38.40, 218.60, -46.00},
+{'l', 245.80, -54.40, 0, 0, 0, 0},
+{'c', 245.80, -54.40, 252.20 ,-56.80, 257.40, -65.60},
+{'c', 262.60, -74.40, 277.80 ,-93.20, 274.20, -118.40},
+{'c', 274.20, -118.40, 275.40 ,-129.60, 269.40, -130.00},
+{'c', 269.40, -130.00, 261.00 ,-131.60, 253.80, -124.00},
+{'c', 253.80, -124.00, 247.00 ,-120.80, 244.60, -121.20},
+{'f', 0.000000,0.000000,0.000000,1.000000,0,0 },
+{'m', 264.02, -120.99, 0, 0, 0, 0},
+{'c', 264.02, -120.99, 266.12 ,-129.92, 261.28, -125.08},
+{'c', 261.28, -125.08, 254.24 ,-119.36, 246.76, -119.36},
+{'c', 246.76, -119.36, 232.24 ,-117.16, 227.84, -103.96},
+{'c', 227.84, -103.96, 223.88 ,-77.12, 231.80, -71.40},
+{'c', 231.80, -71.40, 236.64 ,-63.92, 243.68, -70.52},
+{'f', 0.000000,0.000000,0.000000,1.000000,0,0 },
+{'m', 263.65, -120.63, 0, 0, 0, 0},
+{'c', 263.65, -120.63, 265.74 ,-129.38, 260.99, -124.62},
+{'c', 260.99, -124.62, 254.07 ,-119.01, 246.73, -119.01},
+{'c', 246.73, -119.01, 232.47 ,-116.85, 228.15, -103.89},
+{'c', 228.15, -103.89, 224.26 ,-77.54, 232.04, -71.92},
+{'c', 232.04, -71.92, 236.79 ,-64.58, 243.71, -71.06},
+{'f', 0.201000,0.201000,0.201000,1.000000,0,0 },
+{'m', 263.27, -120.27, 0, 0, 0, 0},
+{'c', 263.27, -120.27, 265.35 ,-128.83, 260.69, -124.17},
+{'c', 260.69, -124.17, 253.91 ,-118.66, 246.70, -118.66},
+{'c', 246.70, -118.66, 232.71 ,-116.54, 228.47, -103.82},
+{'c', 228.47, -103.82, 224.65 ,-77.95, 232.28, -72.44},
+{'c', 232.28, -72.44, 236.94 ,-65.23, 243.73, -71.59},
+{'f', 0.402000,0.402000,0.402000,1.000000,0,0 },
+{'m', 262.90, -119.92, 0, 0, 0, 0},
+{'c', 262.90, -119.92, 264.97 ,-128.29, 260.39, -123.71},
+{'c', 260.39, -123.71, 253.74 ,-118.30, 246.66, -118.30},
+{'c', 246.66, -118.30, 232.94 ,-116.22, 228.78, -103.74},
+{'c', 228.78, -103.74, 225.03 ,-78.37, 232.52, -72.96},
+{'c', 232.52, -72.96, 237.10 ,-65.89, 243.75, -72.13},
+{'f', 0.603000,0.603000,0.603000,1.000000,0,0 },
+{'m', 262.53, -119.56, 0, 0, 0, 0},
+{'c', 262.53, -119.56, 264.59 ,-127.74, 260.10, -123.26},
+{'c', 260.10, -123.26, 253.57 ,-117.95, 246.63, -117.95},
+{'c', 246.63, -117.95, 233.17 ,-115.91, 229.09, -103.67},
+{'c', 229.09, -103.67, 225.42 ,-78.78, 232.76, -73.48},
+{'c', 232.76, -73.48, 237.25 ,-66.54, 243.78, -72.66},
+{'f', 0.804000,0.804000,0.804000,1.000000,0,0 },
+{'m', 262.15, -119.20, 0, 0, 0, 0},
+{'c', 262.15, -119.20, 264.20 ,-127.20, 259.80, -122.80},
+{'c', 259.80, -122.80, 253.40 ,-117.60, 246.60, -117.60},
+{'c', 246.60, -117.60, 233.40 ,-115.60, 229.40, -103.60},
+{'c', 229.40, -103.60, 225.80 ,-79.20, 233.00, -74.00},
+{'c', 233.00, -74.00, 237.40 ,-67.20, 243.80, -73.20},
+{'f', 1.000000,1.000000,1.000000,1.000000,0,0 },
+{'m', 50.60, 84.00, 0, 0, 0, 0},
+{'c', 50.60, 84.00, 30.20 ,64.80, 22.20, 64.00},
+{'c', 22.20, 64.00, -12.20 ,60.00, -27.00, 78.00},
+{'c', -27.00, 78.00, -9.40 ,57.60, 18.20, 63.20},
+{'c', 18.20, 63.20, -3.40 ,58.80, -15.80, 62.00},
+{'c', -15.80, 62.00, -32.60 ,62.00, -42.20, 76.00},
+{'l', -45.00, 80.80, 0, 0, 0, 0},
+{'c', -45.00, 80.80, -41.00 ,66.00, -22.60, 60.00},
+{'c', -22.60, 60.00, 0.20 ,55.20, 11.00, 60.00},
+{'c', 11.00, 60.00, -10.60 ,53.20, -20.60, 55.20},
+{'c', -20.60, 55.20, -51.00 ,52.80, -63.80, 79.20},
+{'c', -63.80, 79.20, -59.80 ,64.80, -45.00, 57.60},
+{'c', -45.00, 57.60, -31.40 ,48.80, -11.00, 51.60},
+{'c', -11.00, 51.60, 3.40 ,54.80, 8.60, 57.20},
+{'c', 13.80, 59.60, 12.60 ,56.80, 4.20, 52.00},
+{'c', 4.20, 52.00, -1.40 ,42.00, -15.40, 42.40},
+{'c', -15.40, 42.40, -58.20 ,46.00, -68.60, 58.00},
+{'c', -68.60, 58.00, -55.00 ,46.80, -44.60, 44.00},
+{'c', -44.60, 44.00, -22.20 ,36.00, -13.80, 36.80},
+{'c', -13.80, 36.80, 11.00 ,37.80, 18.60, 33.80},
+{'c', 18.60, 33.80, 7.40 ,38.80, 10.60, 42.00},
+{'c', 13.80, 45.20, 20.60 ,52.80, 20.60, 54.00},
+{'c', 20.60, 55.20, 44.80 ,77.30, 48.40, 81.70},
+{'f', 0.603000,0.134000,0.000000,1.000000,0,0 },
+{'m', 189.00, 278.00, 0, 0, 0, 0},
+{'c', 189.00, 278.00, 173.50 ,241.50, 161.00, 232.00},
+{'c', 161.00, 232.00, 187.00 ,248.00, 190.50, 266.00},
+{'f', 0.804000,0.804000,0.804000,1.000000,0,0 },
+{'m', 236.00, 285.50, 0, 0, 0, 0},
+{'c', 236.00, 285.50, 209.50 ,230.50, 191.00, 206.50},
+{'c', 191.00, 206.50, 234.50 ,244.00, 239.50, 270.50},
+{'l', 240.00, 276.00, 0, 0, 0, 0},
+{'l', 237.00, 273.50, 0, 0, 0, 0},
+{'f', 0.804000,0.804000,0.804000,1.000000,0,0 },
+{'m', 292.50, 237.00, 0, 0, 0, 0},
+{'c', 292.50, 237.00, 230.00 ,177.50, 228.50, 175.00},
+{'c', 228.50, 175.00, 289.00 ,241.00, 292.00, 248.50},
+{'f', 0.804000,0.804000,0.804000,1.000000,0,0 },
+{'m', 104.00, 280.50, 0, 0, 0, 0},
+{'c', 104.00, 280.50, 123.50 ,228.50, 142.50, 251.00},
+{'c', 142.50, 251.00, 157.50 ,261.00, 157.00, 264.00},
+{'c', 157.00, 264.00, 153.00 ,257.50, 135.00, 258.00},
+{'f', 0.804000,0.804000,0.804000,1.000000,0,0 },
+{'m', 294.50, 153.00, 0, 0, 0, 0},
+{'c', 294.50, 153.00, 249.50 ,124.50, 242.00, 123.00},
+{'c', 230.19, 120.64, 291.50 ,152.00, 296.50, 162.50},
+{'f', 0.804000,0.804000,0.804000,1.000000,0,0 },
+{'m', 143.80, 259.60, 0, 0, 0, 0},
+{'c', 143.80, 259.60, 164.20 ,257.60, 171.00, 250.80},
+{'l', 175.40, 254.40, 0, 0, 0, 0},
+{'l', 193.00, 216.00, 0, 0, 0, 0},
+{'l', 196.60, 221.20, 0, 0, 0, 0},
+{'c', 196.60, 221.20, 211.00 ,206.40, 210.20, 198.40},
+{'c', 209.40, 190.40, 223.00 ,204.40, 223.00, 204.40},
+{'c', 223.00, 204.40, 222.20 ,192.80, 229.40, 199.60},
+{'c', 229.40, 199.60, 227.00 ,184.00, 235.40, 192.00},
+{'c', 235.40, 192.00, 224.86 ,161.84, 247.40, 187.60},
+{'c', 253.00, 194.00, 248.60 ,187.20, 248.60, 187.20},
+{'c', 248.60, 187.20, 222.60 ,139.20, 244.20, 153.60},
+{'c', 244.20, 153.60, 246.20 ,130.80, 245.00, 126.40},
+{'c', 243.80, 122.00, 241.80 ,99.60, 237.00, 94.40},
+{'c', 232.20, 89.20, 237.40 ,87.60, 243.00, 92.80},
+{'c', 243.00, 92.80, 231.80 ,68.80, 245.00, 80.80},
+{'c', 245.00, 80.80, 241.40 ,65.60, 237.00, 62.80},
+{'c', 237.00, 62.80, 231.40 ,45.60, 246.60, 56.40},
+{'c', 246.60, 56.40, 242.20 ,44.00, 239.00, 40.80},
+{'c', 239.00, 40.80, 227.40 ,13.20, 234.60, 18.00},
+{'l', 239.00, 21.60, 0, 0, 0, 0},
+{'c', 239.00, 21.60, 232.20 ,7.60, 238.60, 12.00},
+{'c', 245.00, 16.40, 245.00 ,16.00, 245.00, 16.00},
+{'c', 245.00, 16.00, 223.80 ,-17.20, 244.20, 0.40},
+{'c', 244.20, 0.40, 236.04 ,-13.52, 232.60, -20.40},
+{'c', 232.60, -20.40, 213.80 ,-40.80, 228.20, -34.40},
+{'l', 233.00, -32.80, 0, 0, 0, 0},
+{'c', 233.00, -32.80, 224.20 ,-42.80, 216.20, -44.40},
+{'c', 208.20, -46.00, 218.60 ,-52.40, 225.00, -50.40},
+{'c', 231.40, -48.40, 247.00 ,-40.80, 247.00, -40.80},
+{'c', 247.00, -40.80, 259.80 ,-22.00, 263.80, -21.60},
+{'c', 263.80, -21.60, 243.80 ,-29.20, 249.80, -21.20},
+{'c', 249.80, -21.20, 264.20 ,-7.20, 257.00, -7.60},
+{'c', 257.00, -7.60, 251.00 ,-0.40, 255.80, 8.40},
+{'c', 255.80, 8.40, 237.34 ,-9.99, 252.20, 15.60},
+{'l', 259.00, 32.00, 0, 0, 0, 0},
+{'c', 259.00, 32.00, 234.60 ,7.20, 245.80, 29.20},
+{'c', 245.80, 29.20, 263.00 ,52.80, 265.00, 53.20},
+{'c', 267.00, 53.60, 271.40 ,62.40, 271.40, 62.40},
+{'l', 267.00, 60.40, 0, 0, 0, 0},
+{'l', 272.20, 69.20, 0, 0, 0, 0},
+{'c', 272.20, 69.20, 261.00 ,57.20, 267.00, 70.40},
+{'l', 272.60, 84.80, 0, 0, 0, 0},
+{'c', 272.60, 84.80, 252.20 ,62.80, 265.80, 92.40},
+{'c', 265.80, 92.40, 249.40 ,87.20, 258.20, 104.40},
+{'c', 258.20, 104.40, 256.60 ,120.40, 257.00, 125.60},
+{'c', 257.40, 130.80, 258.60 ,159.20, 254.20, 167.20},
+{'c', 249.80, 175.20, 260.20 ,194.40, 262.20, 198.40},
+{'c', 264.20, 202.40, 267.80 ,213.20, 259.00, 204.00},
+{'c', 250.20, 194.80, 254.60 ,200.40, 256.60, 209.20},
+{'c', 258.60, 218.00, 264.60 ,233.60, 263.80, 239.20},
+{'c', 263.80, 239.20, 262.60 ,240.40, 259.40, 236.80},
+{'c', 259.40, 236.80, 244.60 ,214.00, 246.20, 228.40},
+{'c', 246.20, 228.40, 245.00 ,236.40, 241.80, 245.20},
+{'c', 241.80, 245.20, 238.60 ,256.00, 238.60, 247.20},
+{'c', 238.60, 247.20, 235.40 ,230.40, 232.60, 238.00},
+{'c', 229.80, 245.60, 226.20 ,251.60, 223.40, 254.00},
+{'c', 220.60, 256.40, 215.40 ,233.60, 214.20, 244.00},
+{'c', 214.20, 244.00, 202.20 ,231.60, 197.40, 248.00},
+{'l', 185.80, 264.40, 0, 0, 0, 0},
+{'c', 185.80, 264.40, 185.40 ,252.00, 184.20, 258.00},
+{'f', 0.000000,0.000000,0.000000,1.000000,0,0 },
+{'m', 109.40, -97.20, 0, 0, 0, 0},
+{'c', 109.40, -97.20, 97.80 ,-105.20, 93.80, -104.80},
+{'c', 89.80, -104.40, 121.40 ,-113.60, 162.60, -86.00},
+{'c', 162.60, -86.00, 167.40 ,-83.20, 171.00, -83.60},
+{'c', 171.00, -83.60, 174.20 ,-81.20, 171.40, -77.60},
+{'c', 171.40, -77.60, 162.60 ,-68.00, 173.80, -56.80},
+{'c', 173.80, -56.80, 192.20 ,-50.00, 186.60, -58.80},
+{'c', 186.60, -58.80, 197.40 ,-54.80, 199.80, -50.80},
+{'c', 202.20, -46.80, 201.00 ,-50.80, 201.00, -50.80},
+{'c', 201.00, -50.80, 194.60 ,-58.00, 188.60, -63.20},
+{'c', 188.60, -63.20, 183.40 ,-65.20, 180.60, -73.60},
+{'c', 177.80, -82.00, 175.40 ,-92.00, 179.80, -95.20},
+{'c', 179.80, -95.20, 175.80 ,-90.80, 176.60, -94.80},
+{'c', 177.40, -98.80, 181.00 ,-102.40, 182.60, -102.80},
+{'c', 184.20, -103.20, 200.60 ,-119.00, 207.40, -119.40},
+{'c', 207.40, -119.40, 198.20 ,-118.00, 195.20, -119.00},
+{'c', 192.20, -120.00, 165.60 ,-131.40, 159.60, -132.60},
+{'c', 159.60, -132.60, 142.80 ,-139.20, 154.80, -137.20},
+{'c', 154.80, -137.20, 190.60 ,-133.40, 208.80, -120.20},
+{'c', 208.80, -120.20, 201.60 ,-128.60, 183.20, -135.60},
+{'c', 183.20, -135.60, 161.00 ,-148.20, 125.80, -143.20},
+{'c', 125.80, -143.20, 108.00 ,-140.00, 100.20, -138.20},
+{'c', 100.20, -138.20, 97.60 ,-138.80, 97.00, -139.20},
+{'c', 96.40, -139.60, 84.60 ,-148.60, 57.00, -141.60},
+{'c', 57.00, -141.60, 40.00 ,-137.00, 31.40, -132.20},
+{'c', 31.40, -132.20, 16.20 ,-131.00, 12.60, -127.80},
+{'c', 12.60, -127.80, -6.00 ,-113.20, -8.00, -112.40},
+{'c', -10.00, -111.60, -21.40 ,-104.00, -22.20, -103.60},
+{'c', -22.20, -103.60, 2.40 ,-110.20, 4.80, -112.60},
+{'c', 7.20, -115.00, 24.60 ,-117.60, 27.00, -116.20},
+{'c', 29.40, -114.80, 37.80 ,-115.40, 28.20, -114.80},
+{'c', 28.20, -114.80, 103.80 ,-100.00, 104.60, -98.00},
+{'f', 0.000000,0.000000,0.000000,1.000000,0,0 },
+{'m', 180.80, -106.40, 0, 0, 0, 0},
+{'c', 180.80, -106.40, 170.60 ,-113.80, 168.60, -113.80},
+{'c', 166.60, -113.80, 154.20 ,-124.00, 150.00, -123.60},
+{'c', 145.80, -123.20, 133.60 ,-133.20, 106.20, -125.00},
+{'c', 106.20, -125.00, 105.60 ,-127.00, 109.20, -127.80},
+{'c', 109.20, -127.80, 115.60 ,-130.00, 116.00, -130.60},
+{'c', 116.00, -130.60, 136.20 ,-134.80, 143.40, -131.20},
+{'c', 143.40, -131.20, 152.60 ,-128.60, 158.80, -122.40},
+{'c', 158.80, -122.40, 170.00 ,-119.20, 173.20, -120.20},
+{'c', 173.20, -120.20, 182.00 ,-118.00, 182.40, -116.20},
+{'c', 182.40, -116.20, 188.20 ,-113.20, 186.40, -110.60},
+{'f', 0.804000,0.469000,0.134000,1.000000,0,0 },
+{'m', 168.33, -108.51, 0, 0, 0, 0},
+{'c', 169.14, -107.88, 170.16 ,-107.78, 170.76, -106.97},
+{'c', 171.00, -106.66, 170.71 ,-106.33, 170.39, -106.23},
+{'c', 169.35, -105.92, 168.29 ,-106.49, 167.15, -105.90},
+{'c', 166.75, -105.69, 166.11 ,-105.87, 165.55, -106.02},
+{'c', 163.92, -106.46, 162.09 ,-106.49, 160.40, -105.80},
+{'c', 158.42, -106.93, 156.06 ,-106.34, 153.97, -107.35},
+{'c', 153.92, -107.37, 153.69 ,-107.03, 153.62, -107.05},
+{'c', 150.57, -108.20, 146.83 ,-107.92, 144.40, -110.20},
+{'c', 141.97, -110.61, 139.62 ,-111.07, 137.19, -111.75},
+{'c', 135.37, -112.26, 133.96 ,-113.25, 132.34, -114.08},
+{'c', 130.96, -114.79, 129.51 ,-115.31, 127.97, -115.69},
+{'c', 126.11, -116.14, 124.28 ,-116.03, 122.39, -116.55},
+{'c', 122.29, -116.57, 122.10 ,-116.23, 122.02, -116.25},
+{'c', 121.69, -116.36, 121.41 ,-116.94, 121.23, -116.89},
+{'c', 119.55, -116.37, 118.06 ,-117.34, 116.40, -117.00},
+{'c', 115.22, -118.22, 113.50 ,-117.98, 111.95, -118.42},
+{'c', 108.98, -119.27, 105.83 ,-118.00, 102.80, -119.00},
+{'c', 106.91, -120.84, 111.60 ,-119.61, 115.66, -121.68},
+{'c', 117.99, -122.86, 120.65 ,-121.76, 123.22, -122.52},
+{'c', 123.71, -122.67, 124.40 ,-122.87, 124.80, -122.20},
+{'c', 124.94, -122.33, 125.12 ,-122.57, 125.17, -122.55},
+{'c', 127.62, -121.39, 129.94 ,-120.11, 132.42, -119.05},
+{'c', 132.76, -118.90, 133.29 ,-119.14, 133.55, -118.93},
+{'c', 135.07, -117.72, 137.01 ,-117.82, 138.40, -116.60},
+{'c', 140.10, -117.10, 141.89 ,-116.72, 143.62, -117.35},
+{'c', 143.70, -117.37, 143.93 ,-117.03, 143.97, -117.05},
+{'c', 145.09, -117.80, 146.25 ,-117.53, 147.14, -117.23},
+{'c', 147.48, -117.11, 148.14 ,-116.86, 148.45, -116.79},
+{'c', 149.57, -116.52, 150.43 ,-116.03, 151.61, -115.85},
+{'c', 151.72, -115.83, 151.91 ,-116.17, 151.98, -116.15},
+{'c', 153.10, -115.71, 154.15 ,-115.76, 154.80, -114.60},
+{'c', 154.94, -114.73, 155.10 ,-114.97, 155.18, -114.95},
+{'c', 156.21, -114.61, 156.86 ,-113.85, 157.96, -113.61},
+{'c', 158.44, -113.51, 159.06 ,-112.88, 159.63, -112.70},
+{'c', 162.03, -111.97, 163.87 ,-110.44, 166.06, -109.55},
+{'f', 0.804000,0.469000,0.134000,1.000000,0,0 },
+{'m', 91.70, -122.74, 0, 0, 0, 0},
+{'c', 89.18, -124.46, 86.81 ,-125.57, 84.37, -127.36},
+{'c', 84.19, -127.49, 83.83 ,-127.32, 83.62, -127.44},
+{'c', 82.62, -128.05, 81.73 ,-128.63, 80.75, -129.33},
+{'c', 80.21, -129.71, 79.39 ,-129.70, 78.88, -129.96},
+{'c', 76.34, -131.25, 73.71 ,-131.81, 71.20, -133.00},
+{'c', 71.88, -133.64, 73.00 ,-133.39, 73.60, -134.20},
+{'c', 73.80, -133.92, 74.03 ,-133.64, 74.39, -133.83},
+{'c', 76.06, -134.73, 77.91 ,-134.88, 79.59, -134.79},
+{'c', 81.29, -134.70, 83.01 ,-134.40, 84.79, -134.12},
+{'c', 85.10, -134.08, 85.30 ,-133.56, 85.62, -133.46},
+{'c', 87.85, -132.79, 90.23 ,-133.32, 92.35, -132.48},
+{'c', 93.94, -131.85, 95.52 ,-131.03, 96.75, -129.75},
+{'c', 97.01, -129.50, 96.68 ,-129.19, 96.40, -129.00},
+{'c', 96.79, -129.11, 97.06 ,-128.90, 97.17, -128.59},
+{'c', 97.26, -128.35, 97.26 ,-128.05, 97.17, -127.81},
+{'c', 97.06, -127.50, 96.78 ,-127.40, 96.41, -127.35},
+{'c', 95.00, -127.16, 96.77 ,-128.54, 96.07, -128.09},
+{'c', 94.80, -127.27, 95.55 ,-125.87, 94.80, -124.60},
+{'c', 94.52, -124.79, 94.29 ,-125.01, 94.40, -125.40},
+{'c', 94.64, -124.88, 94.03 ,-124.59, 93.86, -124.27},
+{'f', 0.804000,0.469000,0.134000,1.000000,0,0 },
+{'m', 59.20, -115.39, 0, 0, 0, 0},
+{'c', 56.04, -116.19, 52.99 ,-116.07, 49.98, -117.35},
+{'c', 49.91, -117.37, 49.69 ,-117.03, 49.62, -117.05},
+{'c', 48.26, -117.65, 47.34 ,-118.61, 46.26, -119.66},
+{'c', 45.35, -120.55, 43.69 ,-120.16, 42.42, -120.65},
+{'c', 42.09, -120.77, 41.89 ,-121.28, 41.59, -121.32},
+{'c', 40.37, -121.48, 39.45 ,-122.43, 38.40, -123.00},
+{'c', 40.74, -123.80, 43.15 ,-123.76, 45.61, -124.15},
+{'c', 45.72, -124.17, 45.87 ,-123.84, 46.00, -123.84},
+{'c', 46.14, -123.84, 46.27 ,-124.07, 46.40, -124.20},
+{'c', 46.59, -123.92, 46.90 ,-123.59, 47.15, -123.85},
+{'c', 47.70, -124.39, 48.26 ,-124.20, 48.80, -124.16},
+{'c', 48.94, -124.15, 49.07 ,-123.84, 49.20, -123.84},
+{'c', 49.34, -123.84, 49.47 ,-124.16, 49.60, -124.16},
+{'c', 49.74, -124.16, 49.87 ,-123.84, 50.00, -123.84},
+{'c', 50.14, -123.84, 50.27 ,-124.07, 50.40, -124.20},
+{'c', 51.09, -123.42, 51.98 ,-123.97, 52.80, -123.79},
+{'c', 53.84, -123.57, 54.10 ,-122.42, 55.18, -122.12},
+{'c', 59.89, -120.82, 64.03 ,-118.67, 68.39, -116.58},
+{'c', 68.70, -116.44, 68.91 ,-116.19, 68.80, -115.80},
+{'c', 69.07, -115.80, 69.38 ,-115.89, 69.57, -115.76},
+{'c', 70.63, -115.02, 71.67 ,-114.48, 72.37, -113.38},
+{'c', 72.58, -113.04, 72.25 ,-112.63, 72.02, -112.68},
+{'f', 0.804000,0.469000,0.134000,1.000000,0,0 },
+{'m', 45.34, -71.18, 0, 0, 0, 0},
+{'c', 43.75, -72.40, 43.16 ,-74.43, 42.03, -76.22},
+{'c', 41.82, -76.56, 42.09 ,-76.88, 42.41, -76.96},
+{'c', 42.97, -77.12, 43.51 ,-76.64, 43.92, -76.44},
+{'c', 45.67, -75.58, 47.20 ,-74.34, 49.20, -74.20},
+{'c', 51.19, -71.97, 55.45 ,-71.58, 55.46, -68.20},
+{'c', 55.46, -67.34, 54.03 ,-68.26, 53.60, -67.40},
+{'c', 51.15, -68.40, 48.76 ,-68.30, 46.38, -69.77},
+{'f', 0.804000,0.469000,0.134000,1.000000,0,0 },
+{'m', 17.80, -123.76, 0, 0, 0, 0},
+{'c', 17.93, -123.75, 24.97 ,-123.52, 24.95, -123.41},
+{'c', 24.90, -123.10, 17.17 ,-122.05, 16.81, -122.22},
+{'c', 16.65, -122.30, 9.13 ,-119.87, 9.00, -120.00},
+{'f', 0.804000,0.469000,0.134000,1.000000,0,0 },
+{'m', 33.20, -114.00, 0, 0, 0, 0},
+{'c', 33.20, -114.00, 18.40 ,-112.20, 14.00, -111.00},
+{'c', 9.60, -109.80, -9.00 ,-102.20, -12.00, -100.20},
+{'c', -12.00, -100.20, -25.40 ,-94.80, -42.40, -74.80},
+{'c', -42.40, -74.80, -34.80 ,-78.20, -32.60, -81.00},
+{'c', -32.60, -81.00, -19.00 ,-93.60, -19.20, -91.00},
+{'c', -19.20, -91.00, -7.00 ,-99.60, -7.60, -97.40},
+{'c', -7.60, -97.40, 16.80 ,-108.60, 14.80, -105.40},
+{'c', 14.80, -105.40, 36.40 ,-110.00, 35.40, -108.00},
+{'c', 35.40, -108.00, 54.20 ,-103.60, 51.40, -103.40},
+{'c', 51.40, -103.40, 45.60 ,-102.20, 52.00, -98.60},
+{'c', 52.00, -98.60, 48.60 ,-94.20, 43.20, -98.20},
+{'c', 37.80, -102.20, 40.80 ,-100.00, 35.80, -99.00},
+{'c', 35.80, -99.00, 33.20 ,-98.20, 28.60, -102.20},
+{'c', 28.60, -102.20, 23.00 ,-106.80, 14.20, -103.20},
+{'c', 14.20, -103.20, -16.40 ,-90.60, -18.40, -90.00},
+{'c', -18.40, -90.00, -22.00 ,-87.20, -24.40, -83.60},
+{'c', -24.40, -83.60, -30.20 ,-79.20, -33.20, -77.80},
+{'c', -33.20, -77.80, -46.00 ,-66.20, -47.20, -64.80},
+{'c', -47.20, -64.80, -50.60 ,-59.60, -51.40, -59.20},
+{'c', -51.40, -59.20, -45.00 ,-63.00, -43.00, -65.00},
+{'c', -43.00, -65.00, -29.00 ,-75.00, -23.60, -75.80},
+{'c', -23.60, -75.80, -19.20 ,-78.80, -18.40, -80.20},
+{'c', -18.40, -80.20, -4.00 ,-89.40, 0.20, -89.40},
+{'c', 0.20, -89.40, 9.40 ,-84.20, 11.80, -91.20},
+{'c', 11.80, -91.20, 17.60 ,-93.00, 23.20, -91.80},
+{'c', 23.20, -91.80, 26.40 ,-94.40, 25.60, -96.60},
+{'c', 25.60, -96.60, 27.20 ,-98.40, 28.20, -94.60},
+{'c', 28.20, -94.60, 31.60 ,-91.00, 36.40, -93.00},
+{'c', 36.40, -93.00, 40.40 ,-93.20, 38.40, -90.80},
+{'c', 38.40, -90.80, 34.00 ,-87.00, 22.20, -86.80},
+{'c', 22.20, -86.80, 9.80 ,-86.20, -6.60, -78.60},
+{'c', -6.60, -78.60, -36.40 ,-68.20, -45.60, -57.80},
+{'c', -45.60, -57.80, -52.00 ,-49.00, -57.40, -47.80},
+{'c', -57.40, -47.80, -63.20 ,-47.00, -69.20, -39.60},
+{'c', -69.20, -39.60, -59.40 ,-45.40, -50.40, -45.40},
+{'c', -50.40, -45.40, -46.40 ,-47.80, -50.20, -44.20},
+{'c', -50.20, -44.20, -53.80 ,-36.60, -52.20, -31.20},
+{'c', -52.20, -31.20, -52.80 ,-26.00, -53.60, -24.40},
+{'c', -53.60, -24.40, -61.40 ,-11.60, -61.40, -9.20},
+{'c', -61.40, -6.80, -60.20 ,3.00, -59.80, 3.60},
+{'c', -59.40, 4.20, -60.80 ,2.00, -57.00, 4.40},
+{'c', -53.20, 6.80, -50.40 ,8.40, -49.60, 11.20},
+{'c', -48.80, 14.00, -51.60 ,5.80, -51.80, 4.00},
+{'c', -52.00, 2.20, -56.20 ,-5.00, -55.40, -7.40},
+{'c', -55.40, -7.40, -54.40 ,-6.40, -53.60, -5.00},
+{'c', -53.60, -5.00, -54.20 ,-5.60, -53.60, -9.20},
+{'c', -53.60, -9.20, -52.80 ,-14.40, -51.40, -17.60},
+{'c', -50.00, -20.80, -48.00 ,-24.60, -47.60, -25.40},
+{'c', -47.20, -26.20, -47.20 ,-32.00, -45.80, -29.40},
+{'l', -42.40, -26.80, 0, 0, 0, 0},
+{'c', -42.40, -26.80, -45.20 ,-29.40, -43.00, -31.60},
+{'c', -43.00, -31.60, -44.00 ,-37.20, -42.20, -39.80},
+{'c', -42.20, -39.80, -35.20 ,-48.20, -33.60, -49.20},
+{'c', -32.00, -50.20, -33.40 ,-49.80, -33.40, -49.80},
+{'c', -33.40, -49.80, -27.40 ,-54.00, -33.20, -52.40},
+{'c', -33.20, -52.40, -37.20 ,-50.80, -40.20, -50.80},
+{'c', -40.20, -50.80, -47.80 ,-48.80, -43.80, -53.00},
+{'c', -39.80, -57.20, -29.80 ,-62.60, -26.00, -62.40},
+{'l', -25.20, -60.80, 0, 0, 0, 0},
+{'l', -14.00, -63.20, 0, 0, 0, 0},
+{'l', -15.20, -62.40, 0, 0, 0, 0},
+{'c', -15.20, -62.40, -15.40 ,-62.60, -11.20, -63.00},
+{'c', -7.00, -63.40, -1.20 ,-62.00, 0.20, -63.80},
+{'c', 1.60, -65.60, 5.00 ,-66.60, 4.60, -65.20},
+{'c', 4.20, -63.80, 4.00 ,-61.80, 4.00, -61.80},
+{'c', 4.00, -61.80, 9.00 ,-67.60, 8.40, -65.40},
+{'c', 7.80, -63.20, -0.40 ,-58.00, -1.80, -51.80},
+{'l', 8.60, -60.00, 0, 0, 0, 0},
+{'l', 12.20, -63.00, 0, 0, 0, 0},
+{'c', 12.20, -63.00, 15.80 ,-60.80, 16.00, -62.40},
+{'c', 16.20, -64.00, 20.80 ,-69.80, 22.00, -69.60},
+{'c', 23.20, -69.40, 25.20 ,-72.20, 25.00, -69.60},
+{'c', 24.80, -67.00, 32.40 ,-61.60, 32.40, -61.60},
+{'c', 32.40, -61.60, 35.60 ,-63.40, 37.00, -62.00},
+{'c', 38.40, -60.60, 42.60 ,-81.80, 42.60, -81.80},
+{'l', 67.60, -92.40, 0, 0, 0, 0},
+{'l', 111.20, -95.80, 0, 0, 0, 0},
+{'l', 94.20, -102.60, 0, 0, 0, 0},
+{'f', 0.000000,0.000000,0.000000,1.000000,0,0 },
+{'m', 51.40, 85.00, 0, 0, 0, 0},
+{'c', 51.40, 85.00, 36.40 ,68.20, 28.00, 65.60},
+{'f', 0.000000,0.000000,0.000000,1.000000,0,0 },
+{'m', 24.80, 64.20, 0, 0, 0, 0},
+{'c', 24.80, 64.20, -0.40 ,56.20, -15.80, 60.40},
+{'f', 0.000000,0.000000,0.000000,1.000000,0,0 },
+{'m', 21.20, 63.00, 0, 0, 0, 0},
+{'c', 21.20, 63.00, 4.20 ,55.80, -10.60, 53.60},
+{'c', -10.60, 53.60, -27.20 ,51.00, -43.80, 58.20},
+{'f', 0.000000,0.000000,0.000000,1.000000,0,0 },
+{'m', 22.20, 63.40, 0, 0, 0, 0},
+{'c', 22.20, 63.40, 6.80 ,52.40, 5.80, 51.00},
+{'c', 5.80, 51.00, -1.20 ,40.00, -14.20, 39.60},
+{'f', 0.000000,0.000000,0.000000,1.000000,0,0 },
+{'m', 20.89, 54.41, 0, 0, 0, 0},
+{'c', 22.44, 55.87, 49.40 ,84.80, 49.40, 84.80},
+{'c', 84.60, 121.40, 56.60 ,87.20, 56.60, 87.20},
+{'c', 49.00, 82.40, 39.80 ,63.60, 39.80, 63.60},
+{'c', 38.60, 60.80, 53.80 ,70.80, 53.80, 70.80},
+{'c', 57.80, 71.60, 71.40 ,90.80, 71.40, 90.80},
+{'c', 64.60, 88.40, 69.40 ,95.60, 69.40, 95.60},
+{'c', 72.20, 97.60, 92.60 ,113.20, 92.60, 113.20},
+{'c', 96.20, 117.20, 100.20 ,118.80, 100.20, 118.80},
+{'c', 114.20, 113.60, 107.80 ,126.80, 107.80, 126.80},
+{'c', 110.20, 133.60, 115.80 ,122.00, 115.80, 122.00},
+{'c', 127.00, 105.20, 110.60 ,107.60, 110.60, 107.60},
+{'c', 80.60, 110.40, 73.80 ,94.40, 73.80, 94.40},
+{'c', 71.40, 92.00, 80.20 ,94.40, 80.20, 94.40},
+{'c', 88.60, 96.40, 73.00 ,82.00, 73.00, 82.00},
+{'c', 75.40, 82.00, 84.60 ,88.80, 84.60, 88.80},
+{'c', 95.00, 98.00, 97.00 ,96.00, 97.00, 96.00},
+{'c', 115.00, 87.20, 125.40 ,94.80, 125.40, 94.80},
+{'c', 127.40, 96.40, 121.80 ,103.20, 123.40, 108.40},
+{'c', 125.00, 113.60, 129.80 ,126.00, 129.80, 126.00},
+{'c', 127.40, 127.60, 127.80 ,138.40, 127.80, 138.40},
+{'c', 144.60, 161.60, 135.00 ,159.60, 135.00, 159.60},
+{'c', 119.40, 159.20, 134.20 ,166.80, 134.20, 166.80},
+{'c', 137.40, 168.80, 146.20 ,176.00, 146.20, 176.00},
+{'c', 143.40, 174.80, 141.80 ,180.00, 141.80, 180.00},
+{'c', 146.60, 184.00, 143.80 ,188.80, 143.80, 188.80},
+{'c', 137.80, 190.00, 136.60 ,194.00, 136.60, 194.00},
+{'c', 143.40, 202.00, 133.40 ,202.40, 133.40, 202.40},
+{'c', 137.00, 206.80, 132.20 ,218.80, 132.20, 218.80},
+{'c', 127.40, 218.80, 121.00 ,224.40, 121.00, 224.40},
+{'c', 123.40, 229.20, 113.00 ,234.80, 113.00, 234.80},
+{'c', 104.60, 236.40, 107.40 ,243.20, 107.40, 243.20},
+{'c', 99.40, 249.20, 97.00 ,265.20, 97.00, 265.20},
+{'c', 96.20, 275.60, 93.80 ,278.80, 99.00, 276.80},
+{'c', 104.20, 274.80, 103.40 ,262.40, 103.40, 262.40},
+{'c', 98.60, 246.80, 141.40 ,230.80, 141.40, 230.80},
+{'c', 145.40, 229.20, 146.20 ,224.00, 146.20, 224.00},
+{'c', 148.20, 224.40, 157.00 ,232.00, 157.00, 232.00},
+{'c', 164.60, 243.20, 165.00 ,234.00, 165.00, 234.00},
+{'c', 166.20, 230.40, 164.60 ,224.40, 164.60, 224.40},
+{'c', 170.60, 202.80, 156.60 ,196.40, 156.60, 196.40},
+{'c', 146.60, 162.80, 160.60 ,171.20, 160.60, 171.20},
+{'c', 163.40, 176.80, 174.20 ,182.00, 174.20, 182.00},
+{'l', 177.80, 179.60, 0, 0, 0, 0},
+{'c', 176.20, 174.80, 184.60 ,168.80, 184.60, 168.80},
+{'c', 187.40, 175.20, 193.40 ,167.20, 193.40, 167.20},
+{'c', 197.00, 142.80, 209.40 ,157.20, 209.40, 157.20},
+{'c', 213.40, 158.40, 214.60 ,151.60, 214.60, 151.60},
+{'c', 218.20, 141.20, 214.60 ,127.60, 214.60, 127.60},
+{'c', 218.20, 127.20, 227.80 ,133.20, 227.80, 133.20},
+{'c', 230.60, 129.60, 221.40 ,112.80, 225.40, 115.20},
+{'c', 229.40, 117.60, 233.80 ,119.20, 233.80, 119.20},
+{'c', 234.60, 117.20, 224.60 ,104.80, 224.60, 104.80},
+{'c', 220.20, 102.00, 215.00 ,81.60, 215.00, 81.60},
+{'c', 222.20, 85.20, 212.20 ,70.00, 212.20, 70.00},
+{'c', 212.20, 66.80, 218.20 ,55.60, 218.20, 55.60},
+{'c', 217.40, 48.80, 218.20 ,49.20, 218.20, 49.20},
+{'c', 221.00, 50.40, 229.00 ,52.00, 222.20, 45.60},
+{'c', 215.40, 39.20, 223.00 ,34.40, 223.00, 34.40},
+{'c', 227.40, 31.60, 213.80 ,32.00, 213.80, 32.00},
+{'c', 208.60, 27.60, 209.00 ,23.60, 209.00, 23.60},
+{'c', 217.00, 25.60, 202.60 ,11.20, 200.20, 7.60},
+{'c', 197.80, 4.00, 207.40 ,-1.20, 207.40, -1.20},
+{'c', 220.60, -4.80, 209.00 ,-8.00, 209.00, -8.00},
+{'c', 189.40, -7.60, 200.20 ,-18.40, 200.20, -18.40},
+{'c', 206.20, -18.00, 204.60 ,-20.40, 204.60, -20.40},
+{'c', 199.40, -21.60, 189.80 ,-28.00, 189.80, -28.00},
+{'c', 185.80, -31.60, 189.40 ,-30.80, 189.40, -30.80},
+{'c', 206.20, -29.60, 177.40 ,-40.80, 177.40, -40.80},
+{'c', 185.40, -40.80, 167.40 ,-51.20, 167.40, -51.20},
+{'c', 165.40, -52.80, 162.20 ,-60.40, 162.20, -60.40},
+{'c', 156.20, -65.60, 151.40 ,-72.40, 151.40, -72.40},
+{'c', 151.00, -76.80, 146.20 ,-81.60, 146.20, -81.60},
+{'c', 134.60, -95.20, 129.00 ,-94.80, 129.00, -94.80},
+{'c', 114.20, -98.40, 109.00 ,-97.60, 109.00, -97.60},
+{'l', 56.20, -93.20, 0, 0, 0, 0},
+{'c', 29.80, -80.40, 37.60 ,-59.40, 37.60, -59.40},
+{'c', 44.00, -51.00, 53.20 ,-54.80, 53.20, -54.80},
+{'c', 57.80, -61.00, 69.40 ,-58.80, 69.40, -58.80},
+{'c', 89.80, -55.60, 87.20 ,-59.20, 87.20, -59.20},
+{'c', 84.80, -63.80, 68.60 ,-70.00, 68.40, -70.60},
+{'c', 68.20, -71.20, 59.40 ,-74.60, 59.40, -74.60},
+{'c', 56.40, -75.80, 52.00 ,-85.00, 52.00, -85.00},
+{'c', 48.80, -88.40, 64.60 ,-82.60, 64.60, -82.60},
+{'c', 63.40, -81.60, 70.80 ,-77.60, 70.80, -77.60},
+{'c', 88.20, -78.60, 98.80 ,-67.80, 98.80, -67.80},
+{'c', 109.60, -51.20, 109.80 ,-59.40, 109.80, -59.40},
+{'c', 112.60, -68.80, 100.80 ,-90.00, 100.80, -90.00},
+{'c', 101.20, -92.00, 109.40 ,-85.40, 109.40, -85.40},
+{'c', 110.80, -87.40, 111.60 ,-81.60, 111.60, -81.60},
+{'c', 111.80, -79.20, 115.60 ,-71.20, 115.60, -71.20},
+{'c', 118.40, -58.20, 122.00 ,-65.60, 122.00, -65.60},
+{'l', 126.60, -56.20, 0, 0, 0, 0},
+{'c', 128.00, -53.60, 122.00 ,-46.00, 122.00, -46.00},
+{'c', 121.80, -43.20, 122.60 ,-43.40, 117.00, -35.80},
+{'c', 111.40, -28.20, 114.80 ,-23.80, 114.80, -23.80},
+{'c', 113.40, -17.20, 122.20 ,-17.60, 122.20, -17.60},
+{'c', 124.80, -15.40, 128.20 ,-15.40, 128.20, -15.40},
+{'c', 130.00, -13.40, 132.40 ,-14.00, 132.40, -14.00},
+{'c', 134.00, -17.80, 140.20 ,-15.80, 140.20, -15.80},
+{'c', 141.60, -18.20, 149.80 ,-18.60, 149.80, -18.60},
+{'c', 150.80, -21.20, 151.20 ,-22.80, 154.60, -23.40},
+{'c', 158.00, -24.00, 133.40 ,-67.00, 133.40, -67.00},
+{'c', 139.80, -67.80, 131.60 ,-80.20, 131.60, -80.20},
+{'c', 129.40, -86.80, 140.80 ,-72.20, 143.00, -70.80},
+{'c', 145.20, -69.40, 146.20 ,-67.20, 144.60, -67.40},
+{'c', 143.00, -67.60, 141.20 ,-65.40, 142.60, -65.20},
+{'c', 144.00, -65.00, 157.00 ,-50.00, 160.40, -39.80},
+{'c', 163.80, -29.60, 169.80 ,-25.60, 176.00, -19.60},
+{'c', 182.20, -13.60, 181.40 ,10.60, 181.40, 10.60},
+{'c', 181.00, 19.40, 187.00 ,30.00, 187.00, 30.00},
+{'c', 189.00, 33.80, 184.80 ,52.00, 184.80, 52.00},
+{'c', 182.80, 54.20, 184.20 ,55.00, 184.20, 55.00},
+{'c', 185.20, 56.20, 192.00 ,69.40, 192.00, 69.40},
+{'c', 190.20, 69.20, 193.80 ,72.80, 193.80, 72.80},
+{'c', 199.00, 78.80, 192.60 ,75.80, 192.60, 75.80},
+{'c', 186.60, 74.20, 193.60 ,84.00, 193.60, 84.00},
+{'c', 194.80, 85.80, 185.80 ,81.20, 185.80, 81.20},
+{'c', 176.60, 80.60, 188.20 ,87.80, 188.20, 87.80},
+{'c', 196.80, 95.00, 185.40 ,90.60, 185.40, 90.60},
+{'c', 180.80, 88.80, 184.00 ,95.60, 184.00, 95.60},
+{'c', 187.20, 97.20, 204.40 ,104.20, 204.40, 104.20},
+{'c', 204.80, 108.00, 201.80 ,113.00, 201.80, 113.00},
+{'c', 202.20, 117.00, 200.00 ,120.40, 200.00, 120.40},
+{'c', 198.80, 128.60, 198.20 ,129.40, 198.20, 129.40},
+{'c', 194.00, 129.60, 186.60 ,143.40, 186.60, 143.40},
+{'c', 184.80, 146.00, 174.60 ,158.00, 174.60, 158.00},
+{'c', 172.60, 165.00, 154.60 ,157.80, 154.60, 157.80},
+{'c', 148.00, 161.20, 150.00 ,157.80, 150.00, 157.80},
+{'c', 149.60, 155.60, 154.40 ,149.60, 154.40, 149.60},
+{'c', 161.40, 147.00, 158.80 ,136.20, 158.80, 136.20},
+{'c', 162.80, 134.80, 151.60 ,132.00, 151.80, 130.80},
+{'c', 152.00, 129.60, 157.80 ,128.20, 157.80, 128.20},
+{'c', 165.80, 126.20, 161.40 ,123.80, 161.40, 123.80},
+{'c', 160.80, 119.80, 163.80 ,114.20, 163.80, 114.20},
+{'c', 175.40, 113.40, 163.80 ,97.20, 163.80, 97.20},
+{'c', 153.00, 89.60, 152.00 ,83.80, 152.00, 83.80},
+{'c', 164.60, 75.60, 156.40 ,63.20, 156.60, 59.60},
+{'c', 156.80, 56.00, 158.00 ,34.40, 158.00, 34.40},
+{'c', 156.00, 28.20, 153.00 ,14.60, 153.00, 14.60},
+{'c', 155.20, 9.40, 162.60 ,-3.20, 162.60, -3.20},
+{'c', 165.40, -7.40, 174.20 ,-12.20, 172.00, -15.20},
+{'c', 169.80, -18.20, 162.00 ,-16.40, 162.00, -16.40},
+{'c', 154.20, -17.80, 154.80 ,-12.60, 154.80, -12.60},
+{'c', 153.20, -11.60, 152.40 ,-6.60, 152.40, -6.60},
+{'c', 151.68, 1.33, 142.80 ,7.60, 142.80, 7.60},
+{'c', 131.60, 13.80, 140.80 ,17.80, 140.80, 17.80},
+{'c', 146.80, 24.40, 137.00 ,24.60, 137.00, 24.60},
+{'c', 126.00, 22.80, 134.20 ,33.00, 134.20, 33.00},
+{'c', 145.00, 45.80, 142.00 ,48.60, 142.00, 48.60},
+{'c', 131.80, 49.60, 144.40 ,58.80, 144.40, 58.80},
+{'c', 144.40, 58.80, 143.60 ,56.80, 143.80, 58.60},
+{'c', 144.00, 60.40, 147.00 ,64.60, 147.80, 66.60},
+{'c', 148.60, 68.60, 144.60 ,68.80, 144.60, 68.80},
+{'c', 145.20, 78.40, 129.80 ,74.20, 129.80, 74.20},
+{'c', 129.80, 74.20, 129.80 ,74.20, 128.20, 74.40},
+{'c', 126.60, 74.60, 115.40 ,73.80, 109.60, 71.60},
+{'c', 103.80, 69.40, 97.00 ,69.40, 97.00, 69.40},
+{'c', 97.00, 69.40, 93.00 ,71.20, 85.40, 71.00},
+{'c', 77.80, 70.80, 69.80 ,73.60, 69.80, 73.60},
+{'c', 65.40, 73.20, 74.00 ,68.80, 74.20, 69.00},
+{'c', 74.40, 69.20, 80.00 ,63.60, 72.00, 64.20},
+{'c', 50.20, 65.83, 39.40 ,55.60, 39.40, 55.60},
+{'c', 37.40, 54.20, 34.80 ,51.40, 34.80, 51.40},
+{'c', 24.80, 49.40, 36.20 ,63.80, 36.20, 63.80},
+{'c', 37.40, 65.20, 36.00 ,66.20, 36.00, 66.20},
+{'c', 35.20, 64.60, 27.40 ,59.20, 27.40, 59.20},
+{'f', 0.000000,0.000000,0.000000,1.000000,0,0 },
+{'m', -3.00, 42.80, 0, 0, 0, 0},
+{'c', -3.00, 42.80, 8.60 ,48.40, 11.20, 51.20},
+{'c', 13.80, 54.00, 27.80 ,65.40, 27.80, 65.40},
+{'c', 27.80, 65.40, 22.40 ,63.40, 19.80, 61.60},
+{'c', 17.20, 59.80, 6.40 ,51.60, 6.40, 51.60},
+{'f', 0.268000,0.000000,0.000000,1.000000,0,0 },
+{'m', -61.01, 11.60, 0, 0, 0, 0},
+{'c', -60.67, 11.46, -61.20 ,8.74, -61.40, 8.20},
+{'c', -62.42, 5.47, -71.40 ,4.00, -71.40, 4.00},
+{'c', -71.63, 5.37, -71.68 ,6.96, -71.58, 8.60},
+{'f', 0.603000,0.804000,0.201000,1.000000,0,0 },
+{'m', -61.01, 11.40, 0, 0, 0, 0},
+{'c', -61.46, 11.56, -61.02 ,8.67, -61.20, 8.20},
+{'c', -62.22, 5.47, -71.40 ,3.90, -71.40, 3.90},
+{'c', -71.63, 5.26, -71.68 ,6.86, -71.58, 8.50},
+{'f', 0.402000,0.603000,0.000000,1.000000,0,0 },
+{'m', -65.40, 11.55, 0, 0, 0, 0},
+{'c', -66.03, 11.55, -66.53 ,10.41, -66.53, 9.00},
+{'c', -66.53, 7.59, -66.03 ,6.46, -65.40, 6.46},
+{'c', -64.78, 6.46, -64.27 ,7.59, -64.27, 9.00},
+{'f', 0.000000,0.000000,0.000000,1.000000,0,0 },
+{'f', 0.000000,0.000000,0.000000,1.000000,0,0 },
+{'m', -111.00, 109.60, 0, 0, 0, 0},
+{'c', -111.00, 109.60, -116.60 ,119.60, -91.80, 113.60},
+{'c', -91.80, 113.60, -77.80 ,112.40, -75.40, 110.00},
+{'c', -74.20, 110.80, -65.83 ,113.73, -63.00, 114.40},
+{'c', -56.20, 116.00, -47.80 ,106.00, -47.80, 106.00},
+{'c', -47.80, 106.00, -43.20 ,95.50, -40.40, 95.50},
+{'c', -37.60, 95.50, -40.80 ,97.10, -40.80, 97.10},
+{'c', -40.80, 97.10, -47.40 ,107.20, -47.00, 108.80},
+{'c', -47.00, 108.80, -52.20 ,128.80, -68.20, 129.60},
+{'c', -68.20, 129.60, -84.35 ,130.55, -83.00, 136.40},
+{'c', -83.00, 136.40, -74.20 ,134.00, -71.80, 136.40},
+{'c', -71.80, 136.40, -61.00 ,136.00, -69.00, 142.40},
+{'l', -75.80, 154.00, 0, 0, 0, 0},
+{'c', -75.80, 154.00, -75.66 ,157.92, -85.80, 154.40},
+{'c', -95.60, 151.00, -105.90 ,138.10, -105.90, 138.10},
+{'f', 0.000000,0.000000,0.000000,1.000000,0,0 },
+{'m', -112.20, 113.60, 0, 0, 0, 0},
+{'c', -112.20, 113.60, -114.20 ,123.20, -77.40, 112.80},
+{'c', -77.40, 112.80, -73.00 ,112.80, -70.60, 113.60},
+{'c', -68.20, 114.40, -56.20 ,117.20, -54.20, 116.00},
+{'c', -54.20, 116.00, -61.40 ,129.60, -73.00, 128.00},
+{'c', -73.00, 128.00, -86.20 ,129.60, -85.80, 134.40},
+{'c', -85.80, 134.40, -81.80 ,141.60, -77.00, 144.00},
+{'c', -77.00, 144.00, -74.20 ,146.40, -74.60, 149.60},
+{'c', -75.00, 152.80, -77.80 ,154.40, -79.80, 155.20},
+{'c', -81.80, 156.00, -85.00 ,152.80, -86.60, 152.80},
+{'c', -88.20, 152.80, -96.60 ,146.40, -101.00, 141.60},
+{'c', -105.40, 136.80, -113.80 ,124.80, -113.40, 122.00},
+{'f', 0.938000,0.603000,0.603000,1.000000,0,0 },
+{'m', -109.00, 131.05, 0, 0, 0, 0},
+{'c', -106.40, 135.00, -103.20 ,139.20, -101.00, 141.60},
+{'c', -96.60, 146.40, -88.20 ,152.80, -86.60, 152.80},
+{'c', -85.00, 152.80, -81.80 ,156.00, -79.80, 155.20},
+{'c', -77.80, 154.40, -75.00 ,152.80, -74.60, 149.60},
+{'c', -74.20, 146.40, -77.00 ,144.00, -77.00, 144.00},
+{'c', -80.07, 142.47, -82.81 ,138.98, -84.39, 136.65},
+{'c', -84.39, 136.65, -84.20 ,139.20, -89.40, 138.40},
+{'c', -94.60, 137.60, -99.80 ,134.80, -101.40, 131.60},
+{'c', -103.00, 128.40, -105.40 ,126.00, -103.80, 129.60},
+{'c', -102.20, 133.20, -99.80 ,136.80, -98.20, 137.20},
+{'c', -96.60, 137.60, -97.00 ,138.80, -99.40, 138.40},
+{'f', 0.737000,0.402000,0.402000,1.000000,0,0 },
+{'m', -111.60, 110.00, 0, 0, 0, 0},
+{'c', -111.60, 110.00, -109.80 ,96.40, -108.60, 92.40},
+{'c', -108.60, 92.40, -109.40 ,85.60, -107.00, 81.40},
+{'c', -104.60, 77.20, -102.60 ,71.00, -99.60, 65.60},
+{'c', -96.60, 60.20, -96.40 ,56.20, -92.40, 54.60},
+{'c', -88.40, 53.00, -82.40 ,44.40, -79.60, 43.40},
+{'c', -76.80, 42.40, -77.00 ,43.20, -77.00, 43.20},
+{'c', -77.00, 43.20, -70.20 ,28.40, -56.60, 32.40},
+{'c', -56.60, 32.40, -72.80 ,29.60, -57.00, 20.20},
+{'c', -57.00, 20.20, -61.80 ,21.30, -58.50, 14.30},
+{'c', -56.30, 9.63, -56.80 ,16.40, -67.80, 28.20},
+{'c', -67.80, 28.20, -72.80 ,36.80, -78.00, 39.80},
+{'c', -83.20, 42.80, -95.20 ,49.80, -96.40, 53.60},
+{'c', -97.60, 57.40, -100.80 ,63.20, -102.80, 64.80},
+{'c', -104.80, 66.40, -107.60 ,70.60, -108.00, 74.00},
+{'c', -108.00, 74.00, -109.20 ,78.00, -110.60, 79.20},
+{'c', -112.00, 80.40, -112.20 ,83.60, -112.20, 85.60},
+{'c', -112.20, 87.60, -114.20 ,90.40, -114.00, 92.80},
+{'c', -114.00, 92.80, -113.20 ,111.80, -113.60, 113.80},
+{'f', 0.603000,0.134000,0.000000,1.000000,0,0 },
+{'m', -120.20, 114.60, 0, 0, 0, 0},
+{'c', -120.20, 114.60, -122.20 ,113.20, -126.60, 119.20},
+{'c', -126.60, 119.20, -119.30 ,152.20, -119.30, 153.60},
+{'c', -119.30, 153.60, -118.20 ,151.50, -119.50, 144.30},
+{'c', -120.80, 137.10, -121.70 ,124.40, -121.70, 124.40},
+{'f', 1.000000,1.000000,1.000000,1.000000,0,0 },
+{'m', -98.60, 54.00, 0, 0, 0, 0},
+{'c', -98.60, 54.00, -116.20 ,57.20, -115.80, 86.40},
+{'l', -116.60, 111.20, 0, 0, 0, 0},
+{'c', -116.60, 111.20, -117.80 ,85.60, -119.00, 84.00},
+{'c', -120.20, 82.40, -116.20 ,71.20, -119.40, 77.20},
+{'c', -119.40, 77.20, -133.40 ,91.20, -125.40, 112.40},
+{'c', -125.40, 112.40, -123.90 ,115.70, -126.90, 111.10},
+{'c', -126.90, 111.10, -131.50 ,98.50, -130.40, 92.10},
+{'c', -130.40, 92.10, -130.20 ,89.90, -128.30, 87.10},
+{'c', -128.30, 87.10, -119.70 ,75.40, -117.00, 73.10},
+{'c', -117.00, 73.10, -115.20 ,58.70, -99.80, 53.50},
+{'f', 0.603000,0.134000,0.000000,1.000000,0,0 },
+{'m', 40.80, -12.20, 0, 0, 0, 0},
+{'c', 41.46, -12.55, 41.45 ,-13.52, 42.03, -13.70},
+{'c', 43.18, -14.04, 43.34 ,-15.11, 43.86, -15.89},
+{'c', 44.73, -17.21, 44.93 ,-18.74, 45.51, -20.23},
+{'c', 45.78, -20.93, 45.81 ,-21.89, 45.50, -22.55},
+{'c', 44.32, -25.03, 43.62 ,-27.48, 42.18, -29.91},
+{'c', 41.91, -30.36, 41.65 ,-31.15, 41.45, -31.75},
+{'c', 40.98, -33.13, 39.73 ,-34.12, 38.87, -35.44},
+{'c', 38.58, -35.88, 39.10 ,-36.81, 38.39, -36.89},
+{'c', 37.49, -37.00, 36.04 ,-37.58, 35.81, -36.55},
+{'c', 35.22, -33.97, 36.23 ,-31.44, 37.20, -29.00},
+{'c', 36.42, -28.31, 36.75 ,-27.39, 36.90, -26.62},
+{'c', 37.61, -23.01, 36.42 ,-19.66, 35.66, -16.19},
+{'c', 35.63, -16.08, 35.97 ,-15.89, 35.95, -15.82},
+{'c', 34.72, -13.14, 33.27 ,-10.69, 31.45, -8.31},
+{'c', 30.70, -7.32, 29.82 ,-6.40, 29.33, -5.34},
+{'c', 28.96, -4.55, 28.55 ,-3.59, 28.80, -2.60},
+{'c', 25.36, 0.18, 23.11 ,4.03, 20.50, 7.87},
+{'c', 20.04, 8.55, 20.33 ,9.76, 20.88, 10.03},
+{'c', 21.70, 10.43, 22.65 ,9.40, 23.12, 8.56},
+{'c', 23.51, 7.86, 23.86 ,7.21, 24.36, 6.57},
+{'c', 24.49, 6.39, 24.31 ,5.97, 24.45, 5.85},
+{'c', 27.08, 3.50, 28.75 ,0.57, 31.20, -1.80},
+{'c', 33.15, -2.13, 34.69 ,-3.13, 36.44, -4.14},
+{'c', 36.74, -4.32, 37.27 ,-4.07, 37.56, -4.26},
+{'c', 39.31, -5.44, 39.31 ,-7.48, 39.41, -9.39},
+{'f', 0.000000,0.000000,0.000000,1.000000,0,0 },
+{'m', 31.96, -16.67, 0, 0, 0, 0},
+{'c', 32.08, -16.74, 31.93 ,-17.17, 32.04, -17.38},
+{'c', 32.20, -17.71, 32.60 ,-17.89, 32.76, -18.22},
+{'c', 32.87, -18.43, 32.71 ,-18.81, 32.85, -18.96},
+{'c', 35.18, -21.40, 35.44 ,-24.43, 34.40, -27.40},
+{'c', 35.42, -28.02, 35.48 ,-29.28, 35.06, -30.13},
+{'c', 34.21, -31.83, 34.01 ,-33.76, 33.04, -35.30},
+{'c', 32.24, -36.57, 30.66 ,-37.81, 29.29, -36.51},
+{'c', 28.87, -36.11, 28.55 ,-35.32, 28.82, -34.61},
+{'c', 28.89, -34.45, 29.17 ,-34.30, 29.15, -34.22},
+{'c', 29.04, -33.89, 28.49 ,-33.67, 28.49, -33.40},
+{'c', 28.46, -31.90, 27.50 ,-30.39, 28.13, -29.06},
+{'c', 28.91, -27.43, 29.72 ,-25.58, 30.40, -23.80},
+{'c', 29.17, -21.68, 30.20 ,-19.23, 28.45, -17.36},
+{'c', 28.31, -17.21, 28.32 ,-16.83, 28.44, -16.62},
+{'c', 28.73, -16.14, 29.14 ,-15.73, 29.62, -15.44},
+{'c', 29.83, -15.32, 30.18 ,-15.32, 30.38, -15.44},
+{'f', 0.000000,0.000000,0.000000,1.000000,0,0 },
+{'m', 94.77, -26.98, 0, 0, 0, 0},
+{'c', 96.16, -25.18, 96.45 ,-22.39, 94.40, -21.00},
+{'c', 94.95, -17.69, 98.30 ,-19.67, 100.40, -20.20},
+{'c', 100.29, -20.59, 100.52 ,-20.93, 100.80, -20.94},
+{'c', 101.86, -20.95, 102.54 ,-21.98, 103.60, -21.80},
+{'c', 104.03, -23.36, 105.67 ,-24.06, 106.32, -25.44},
+{'c', 108.04, -29.13, 107.45 ,-33.41, 104.87, -36.65},
+{'c', 104.67, -36.91, 104.88 ,-37.42, 104.76, -37.79},
+{'c', 104.00, -40.00, 101.94 ,-40.31, 100.00, -41.00},
+{'c', 98.82, -44.88, 98.16 ,-48.91, 96.40, -52.60},
+{'c', 94.79, -52.85, 94.09 ,-54.59, 92.75, -55.31},
+{'c', 91.42, -56.03, 90.85 ,-54.45, 90.89, -53.40},
+{'c', 90.90, -53.20, 91.35 ,-52.97, 91.18, -52.61},
+{'c', 91.11, -52.45, 90.84 ,-52.33, 90.84, -52.20},
+{'c', 90.85, -52.06, 91.07 ,-51.93, 91.20, -51.80},
+{'c', 90.28, -50.98, 88.86 ,-50.50, 88.56, -49.36},
+{'c', 87.61, -45.65, 90.18 ,-42.52, 91.85, -39.32},
+{'c', 92.44, -38.19, 91.71 ,-36.92, 90.95, -35.71},
+{'c', 90.51, -35.01, 90.62 ,-33.89, 90.89, -33.03},
+{'f', 0.000000,0.000000,0.000000,1.000000,0,0 },
+{'m', 57.61, -8.59, 0, 0, 0, 0},
+{'c', 56.12, -6.74, 52.71 ,-4.17, 55.63, -2.24},
+{'c', 55.82, -2.11, 56.19 ,-2.11, 56.37, -2.24},
+{'c', 58.39, -3.81, 60.39 ,-4.71, 62.83, -5.29},
+{'c', 62.95, -5.32, 63.22 ,-4.86, 63.59, -5.02},
+{'c', 65.21, -5.72, 67.22 ,-5.66, 68.40, -7.00},
+{'c', 72.17, -6.78, 75.73 ,-7.89, 79.12, -9.20},
+{'c', 80.28, -9.65, 81.55 ,-10.21, 82.75, -10.71},
+{'c', 84.13, -11.29, 85.33 ,-12.21, 86.45, -13.35},
+{'c', 86.58, -13.49, 86.93 ,-13.40, 87.20, -13.40},
+{'c', 87.16, -14.26, 88.12 ,-14.39, 88.37, -15.01},
+{'c', 88.46, -15.24, 88.31 ,-15.64, 88.44, -15.74},
+{'c', 90.58, -17.37, 91.50 ,-19.39, 90.33, -21.77},
+{'c', 90.05, -22.34, 89.80 ,-22.96, 89.23, -23.44},
+{'c', 88.15, -24.35, 87.05 ,-23.50, 86.00, -23.80},
+{'c', 85.84, -23.17, 85.11 ,-23.34, 84.73, -23.15},
+{'c', 83.87, -22.71, 82.53 ,-23.29, 81.67, -22.85},
+{'c', 80.31, -22.16, 79.07 ,-21.99, 77.65, -21.61},
+{'c', 77.34, -21.53, 76.56 ,-21.63, 76.40, -21.00},
+{'c', 76.27, -21.13, 76.12 ,-21.37, 76.01, -21.35},
+{'c', 74.10, -20.95, 72.84 ,-20.74, 71.54, -19.04},
+{'c', 71.44, -18.91, 71.00 ,-19.09, 70.84, -18.95},
+{'c', 69.88, -18.15, 69.48 ,-16.91, 68.38, -16.24},
+{'c', 68.17, -16.12, 67.82 ,-16.29, 67.63, -16.16},
+{'c', 66.98, -15.73, 66.62 ,-15.09, 65.97, -14.64},
+{'c', 65.64, -14.41, 65.25 ,-14.73, 65.28, -14.99},
+{'c', 65.52, -16.94, 66.17 ,-18.72, 65.60, -20.60},
+{'c', 67.68, -23.12, 70.19 ,-25.07, 72.00, -27.80},
+{'c', 72.02, -29.97, 72.71 ,-32.11, 72.59, -34.19},
+{'c', 72.58, -34.38, 72.30 ,-35.12, 72.17, -35.46},
+{'c', 71.86, -36.32, 72.76 ,-37.38, 71.92, -38.11},
+{'c', 70.52, -39.31, 69.22 ,-38.43, 68.40, -37.00},
+{'c', 66.56, -36.61, 64.50 ,-35.92, 62.92, -37.15},
+{'c', 61.91, -37.94, 61.33 ,-38.84, 60.53, -39.90},
+{'c', 59.55, -41.20, 59.88 ,-42.64, 59.95, -44.20},
+{'c', 59.96, -44.33, 59.65 ,-44.47, 59.65, -44.60},
+{'c', 59.65, -44.73, 59.87 ,-44.87, 60.00, -45.00},
+{'c', 59.29, -45.63, 59.02 ,-46.68, 58.00, -47.00},
+{'c', 58.30, -48.09, 57.63 ,-48.98, 56.76, -49.28},
+{'c', 54.76, -49.97, 53.09 ,-48.06, 51.19, -47.98},
+{'c', 50.68, -47.97, 50.21 ,-49.00, 49.56, -49.33},
+{'c', 49.13, -49.54, 48.43 ,-49.58, 48.07, -49.31},
+{'c', 47.38, -48.81, 46.79 ,-48.69, 46.03, -48.49},
+{'c', 44.41, -48.05, 43.14 ,-46.96, 41.66, -46.10},
+{'c', 40.17, -45.25, 39.22 ,-43.81, 38.14, -42.49},
+{'c', 37.20, -41.34, 37.06 ,-38.92, 38.48, -38.42},
+{'c', 40.32, -37.77, 41.63 ,-40.48, 43.59, -40.15},
+{'c', 43.90, -40.10, 44.11 ,-39.79, 44.00, -39.40},
+{'c', 44.39, -39.29, 44.61 ,-39.52, 44.80, -39.80},
+{'c', 45.66, -38.78, 46.82 ,-38.44, 47.76, -37.57},
+{'c', 48.73, -36.67, 50.48 ,-37.09, 51.49, -36.09},
+{'c', 53.02, -34.59, 52.46 ,-31.91, 54.40, -30.60},
+{'c', 53.81, -29.29, 53.21 ,-28.01, 52.87, -26.58},
+{'c', 52.59, -25.38, 53.58 ,-24.18, 54.80, -24.27},
+{'c', 56.05, -24.36, 56.31 ,-25.12, 56.80, -26.20},
+{'c', 57.07, -25.93, 57.54 ,-25.64, 57.49, -25.42},
+{'c', 57.04, -23.03, 56.01 ,-21.04, 55.55, -18.61},
+{'c', 55.49, -18.29, 55.19 ,-18.09, 54.80, -18.20},
+{'c', 54.33, -14.05, 50.28 ,-11.66, 47.73, -8.49},
+{'c', 47.33, -7.99, 47.33 ,-6.74, 47.74, -6.34},
+{'c', 49.14, -4.95, 51.10 ,-6.50, 52.80, -7.00},
+{'c', 53.01, -8.21, 53.87 ,-9.15, 55.20, -9.09},
+{'c', 55.46, -9.08, 55.70 ,-9.62, 56.02, -9.75},
+{'c', 56.37, -9.89, 56.87 ,-9.67, 57.16, -9.87},
+{'c', 58.88, -11.06, 60.29 ,-12.17, 62.03, -13.36},
+{'c', 62.22, -13.49, 62.57 ,-13.33, 62.78, -13.44},
+{'c', 63.11, -13.60, 63.29 ,-13.98, 63.62, -14.17},
+{'c', 63.97, -14.37, 64.21 ,-14.08, 64.40, -13.80},
+{'c', 63.75, -13.45, 63.75 ,-12.49, 63.17, -12.29},
+{'c', 62.39, -12.02, 61.83 ,-11.51, 61.16, -11.06},
+{'c', 60.87, -10.87, 60.21 ,-11.12, 60.10, -10.94},
+{'f', 0.000000,0.000000,0.000000,1.000000,0,0 },
+{'m', 2.20, -58.00, 0, 0, 0, 0},
+{'c', 2.20, -58.00, -7.04 ,-60.87, -18.20, -35.20},
+{'c', -18.20, -35.20, -20.60 ,-30.00, -23.00, -28.00},
+{'c', -25.40, -26.00, -36.60 ,-22.40, -38.60, -18.40},
+{'l', -49.00, -2.40, 0, 0, 0, 0},
+{'c', -49.00, -2.40, -34.20 ,-18.40, -31.00, -20.80},
+{'c', -31.00, -20.80, -23.00 ,-29.20, -26.20, -22.40},
+{'c', -26.20, -22.40, -40.20 ,-11.60, -39.00, -2.40},
+{'c', -39.00, -2.40, -44.60 ,12.00, -45.40, 14.00},
+{'c', -45.40, 14.00, -29.40 ,-18.00, -27.00, -19.20},
+{'c', -24.60, -20.40, -23.40 ,-20.40, -24.60, -16.80},
+{'c', -25.80, -13.20, -26.20 ,3.20, -29.00, 5.20},
+{'c', -29.00, 5.20, -21.00 ,-15.20, -21.80, -18.40},
+{'c', -21.80, -18.40, -18.60 ,-22.00, -16.20, -16.80},
+{'l', -17.40, -0.80, 0, 0, 0, 0},
+{'l', -13.00, 11.20, 0, 0, 0, 0},
+{'c', -13.00, 11.20, -15.40 ,0.00, -13.80, -15.60},
+{'c', -13.80, -15.60, -15.80 ,-26.00, -11.80, -20.40},
+{'c', -7.80, -14.80, 1.80 ,-8.80, 1.80, -4.00},
+{'c', 1.80, -4.00, -3.40 ,-21.60, -12.60, -26.40},
+{'l', -16.60, -20.40, 0, 0, 0, 0},
+{'l', -17.80, -22.40, 0, 0, 0, 0},
+{'c', -17.80, -22.40, -21.40 ,-23.20, -17.00, -30.00},
+{'c', -12.60, -36.80, -13.00 ,-37.60, -13.00, -37.60},
+{'c', -13.00, -37.60, -6.60 ,-30.40, -5.00, -30.40},
+{'c', -5.00, -30.40, 8.20 ,-38.00, 9.40, -13.60},
+{'c', 9.40, -13.60, 16.20 ,-28.00, 7.00, -34.80},
+{'c', 7.00, -34.80, -7.80 ,-36.80, -6.60, -42.00},
+{'l', 0.60, -54.40, 0, 0, 0, 0},
+{'f', 0.000000,0.000000,0.000000,1.000000,0,0 },
+{'m', -17.80, -41.60, 0, 0, 0, 0},
+{'c', -17.80, -41.60, -30.60 ,-41.60, -33.80, -36.40},
+{'l', -41.00, -26.80, 0, 0, 0, 0},
+{'c', -41.00, -26.80, -23.80 ,-36.80, -19.80, -38.00},
+{'f', 0.000000,0.000000,0.000000,1.000000,0,0 },
+{'m', -57.80, -35.20, 0, 0, 0, 0},
+{'c', -57.80, -35.20, -59.80 ,-34.00, -60.20, -31.20},
+{'c', -60.60, -28.40, -63.00 ,-28.00, -62.20, -25.20},
+{'c', -61.40, -22.40, -59.40 ,-20.00, -59.40, -24.00},
+{'c', -59.40, -28.00, -57.80 ,-30.00, -57.00, -31.20},
+{'f', 0.000000,0.000000,0.000000,1.000000,0,0 },
+{'m', -66.60, 26.00, 0, 0, 0, 0},
+{'c', -66.60, 26.00, -75.00 ,22.00, -78.20, 18.40},
+{'c', -81.40, 14.80, -80.95 ,19.97, -85.80, 19.60},
+{'c', -91.65, 19.16, -90.60 ,3.20, -90.60, 3.20},
+{'l', -94.60, 10.80, 0, 0, 0, 0},
+{'c', -94.60, 10.80, -95.80 ,25.20, -87.80, 22.80},
+{'c', -83.89, 21.63, -82.60 ,23.20, -84.20, 24.00},
+{'c', -85.80, 24.80, -78.60 ,25.20, -81.40, 26.80},
+{'c', -84.20, 28.40, -69.80 ,23.20, -72.20, 33.60},
+{'f', 0.000000,0.000000,0.000000,1.000000,0,0 },
+{'m', -79.20, 40.40, 0, 0, 0, 0},
+{'c', -79.20, 40.40, -94.60 ,44.80, -98.20, 35.20},
+{'c', -98.20, 35.20, -103.00 ,37.60, -100.80, 40.60},
+{'c', -98.60, 43.60, -97.40 ,44.00, -97.40, 44.00},
+{'c', -97.40, 44.00, -92.00 ,45.20, -92.60, 46.00},
+{'c', -93.20, 46.80, -95.60 ,50.20, -95.60, 50.20},
+{'f', 0.000000,0.000000,0.000000,1.000000,0,0 },
+{'m', 149.20, 118.60, 0, 0, 0, 0},
+{'c', 148.77, 120.73, 147.10 ,121.54, 145.20, 122.20},
+{'c', 143.28, 121.24, 140.69 ,118.14, 138.80, 120.20},
+{'c', 138.33, 119.72, 137.55 ,119.66, 137.20, 119.00},
+{'c', 136.74, 118.10, 137.01 ,117.06, 136.67, 116.26},
+{'c', 136.12, 114.98, 135.41 ,113.62, 135.60, 112.20},
+{'c', 137.41, 111.49, 138.00 ,109.58, 137.53, 107.82},
+{'c', 137.46, 107.56, 137.03 ,107.37, 137.23, 107.02},
+{'c', 137.42, 106.69, 137.73 ,106.47, 138.00, 106.20},
+{'c', 137.87, 106.33, 137.72 ,106.57, 137.61, 106.55},
+{'c', 137.00, 106.44, 137.12 ,105.81, 137.25, 105.42},
+{'c', 137.84, 103.67, 139.85 ,103.41, 141.20, 104.60},
+{'c', 141.46, 104.03, 141.97 ,104.23, 142.40, 104.20},
+{'c', 142.35, 103.62, 142.76 ,103.09, 142.96, 102.67},
+{'c', 143.47, 101.58, 145.10 ,102.68, 145.90, 102.07},
+{'c', 146.98, 101.25, 148.04 ,100.55, 149.12, 101.15},
+{'c', 150.93, 102.16, 152.64 ,103.37, 153.84, 105.11},
+{'c', 154.41, 105.95, 154.65 ,107.23, 154.59, 108.19},
+{'c', 154.55, 108.83, 153.17 ,108.48, 152.83, 109.41},
+{'c', 152.19, 111.16, 154.02 ,111.68, 154.77, 113.02},
+{'c', 154.97, 113.37, 154.71 ,113.67, 154.39, 113.77},
+{'c', 153.98, 113.90, 153.20 ,113.71, 153.33, 114.16},
+{'f', 1.000000,1.000000,1.000000,1.000000,0,0 },
+{'m', 139.60, 138.20, 0, 0, 0, 0},
+{'c', 139.59, 136.46, 137.99 ,134.71, 139.20, 133.00},
+{'c', 139.34, 133.13, 139.47 ,133.36, 139.60, 133.36},
+{'c', 139.74, 133.36, 139.87 ,133.13, 140.00, 133.00},
+{'c', 141.50, 135.22, 145.15 ,136.15, 145.01, 138.99},
+{'c', 144.98, 139.44, 143.90 ,140.36, 144.80, 141.00},
+{'c', 142.99, 142.35, 142.93 ,144.72, 142.00, 146.60},
+{'c', 140.76, 146.31, 139.55 ,145.95, 138.40, 145.40},
+{'c', 138.75, 143.91, 138.64 ,142.23, 139.46, 140.91},
+{'f', 1.000000,1.000000,1.000000,1.000000,0,0 },
+{'m', -26.60, 129.20, 0, 0, 0, 0},
+{'c', -26.60, 129.20, -43.46 ,139.34, -29.40, 124.00},
+{'c', -20.60, 114.40, -10.60 ,108.80, -10.60, 108.80},
+{'c', -10.60, 108.80, -0.20 ,104.40, 3.40, 103.20},
+{'c', 7.00, 102.00, 22.20 ,96.80, 25.40, 96.40},
+{'c', 28.60, 96.00, 38.20 ,92.00, 45.00, 96.00},
+{'c', 51.80, 100.00, 59.80 ,104.40, 59.80, 104.40},
+{'c', 59.80, 104.40, 43.40 ,96.00, 39.80, 98.40},
+{'c', 36.20, 100.80, 29.00 ,100.40, 23.00, 103.60},
+{'c', 23.00, 103.60, 8.20 ,108.00, 5.00, 110.00},
+{'c', 1.80, 112.00, -8.60 ,123.60, -10.20, 122.80},
+{'c', -11.80, 122.00, -9.80 ,121.60, -8.60, 118.80},
+{'c', -7.40, 116.00, -9.40 ,114.40, -17.40, 120.80},
+{'f', 0.804000,0.804000,0.804000,1.000000,0,0 },
+{'m', -19.20, 123.23, 0, 0, 0, 0},
+{'c', -19.20, 123.23, -17.79 ,110.19, -9.31, 111.86},
+{'c', -9.31, 111.86, -1.08 ,107.69, 1.64, 105.72},
+{'c', 1.64, 105.72, 9.78 ,104.02, 11.09, 103.40},
+{'c', 29.57, 94.70, 44.29 ,99.22, 44.84, 98.10},
+{'c', 45.38, 96.98, 65.01 ,104.10, 68.61, 108.19},
+{'c', 69.01, 108.63, 58.38 ,102.59, 48.69, 100.70},
+{'c', 40.41, 99.08, 18.81 ,100.94, 7.91, 106.48},
+{'c', 4.93, 107.99, -4.01 ,113.77, -6.54, 113.66},
+{'f', 0.000000,0.000000,0.000000,1.000000,0,0 },
+{'m', -23.00, 148.80, 0, 0, 0, 0},
+{'c', -23.00, 148.80, -38.20 ,146.40, -21.40, 144.80},
+{'c', -21.40, 144.80, -3.40 ,142.80, 0.60, 137.60},
+{'c', 0.60, 137.60, 14.20 ,128.40, 17.00, 128.00},
+{'c', 19.80, 127.60, 49.80 ,120.40, 50.20, 118.00},
+{'c', 50.60, 115.60, 56.20 ,115.60, 57.80, 116.40},
+{'c', 59.40, 117.20, 58.60 ,118.40, 55.80, 119.20},
+{'c', 53.00, 120.00, 21.80 ,136.40, 15.40, 137.60},
+{'c', 9.00, 138.80, -2.60 ,146.40, -7.40, 147.60},
+{'f', 0.804000,0.804000,0.804000,1.000000,0,0 },
+{'m', -3.48, 141.40, 0, 0, 0, 0},
+{'c', -3.48, 141.40, -12.06 ,140.57, -3.46, 139.75},
+{'c', -3.46, 139.75, 5.36 ,136.33, 7.40, 133.67},
+{'c', 7.40, 133.67, 14.37 ,128.96, 15.80, 128.75},
+{'c', 17.23, 128.55, 31.19 ,124.86, 31.40, 123.63},
+{'c', 31.60, 122.40, 65.67 ,109.82, 70.09, 113.01},
+{'c', 73.00, 115.11, 63.10 ,113.44, 53.47, 117.85},
+{'c', 52.11, 118.47, 18.26 ,133.05, 14.98, 133.67},
+{'c', 11.70, 134.28, 5.76 ,138.17, 3.31, 138.79},
+{'f', 0.000000,0.000000,0.000000,1.000000,0,0 },
+{'m', -11.40, 143.60, 0, 0, 0, 0},
+{'c', -11.40, 143.60, -6.20 ,143.20, -7.40, 144.80},
+{'c', -8.60, 146.40, -11.00 ,145.60, -11.00, 145.60},
+{'f', 0.000000,0.000000,0.000000,1.000000,0,0 },
+{'m', -18.60, 145.20, 0, 0, 0, 0},
+{'c', -18.60, 145.20, -13.40 ,144.80, -14.60, 146.40},
+{'c', -15.80, 148.00, -18.20 ,147.20, -18.20, 147.20},
+{'f', 0.000000,0.000000,0.000000,1.000000,0,0 },
+{'m', -29.00, 146.80, 0, 0, 0, 0},
+{'c', -29.00, 146.80, -23.80 ,146.40, -25.00, 148.00},
+{'c', -26.20, 149.60, -28.60 ,148.80, -28.60, 148.80},
+{'f', 0.000000,0.000000,0.000000,1.000000,0,0 },
+{'m', -36.60, 147.60, 0, 0, 0, 0},
+{'c', -36.60, 147.60, -31.40 ,147.20, -32.60, 148.80},
+{'c', -33.80, 150.40, -36.20 ,149.60, -36.20, 149.60},
+{'f', 0.000000,0.000000,0.000000,1.000000,0,0 },
+{'m', 1.80, 108.00, 0, 0, 0, 0},
+{'c', 1.80, 108.00, 6.20 ,108.00, 5.00, 109.60},
+{'c', 3.80, 111.20, 0.60 ,110.80, 0.60, 110.80},
+{'f', 0.000000,0.000000,0.000000,1.000000,0,0 },
+{'m', -8.20, 113.60, 0, 0, 0, 0},
+{'c', -8.20, 113.60, -1.69 ,111.46, -4.20, 114.80},
+{'c', -5.40, 116.40, -7.80 ,115.60, -7.80, 115.60},
+{'f', 0.000000,0.000000,0.000000,1.000000,0,0 },
+{'m', -19.40, 118.40, 0, 0, 0, 0},
+{'c', -19.40, 118.40, -14.20 ,118.00, -15.40, 119.60},
+{'c', -16.60, 121.20, -19.00 ,120.40, -19.00, 120.40},
+{'f', 0.000000,0.000000,0.000000,1.000000,0,0 },
+{'m', -27.00, 124.40, 0, 0, 0, 0},
+{'c', -27.00, 124.40, -21.80 ,124.00, -23.00, 125.60},
+{'c', -24.20, 127.20, -26.60 ,126.40, -26.60, 126.40},
+{'f', 0.000000,0.000000,0.000000,1.000000,0,0 },
+{'m', -33.80, 129.20, 0, 0, 0, 0},
+{'c', -33.80, 129.20, -28.60 ,128.80, -29.80, 130.40},
+{'c', -31.00, 132.00, -33.40 ,131.20, -33.40, 131.20},
+{'f', 0.000000,0.000000,0.000000,1.000000,0,0 },
+{'m', 5.28, 135.60, 0, 0, 0, 0},
+{'c', 5.28, 135.60, 12.20 ,135.07, 10.61, 137.19},
+{'c', 9.01, 139.32, 5.81 ,138.26, 5.81, 138.26},
+{'f', 0.000000,0.000000,0.000000,1.000000,0,0 },
+{'m', 15.68, 130.80, 0, 0, 0, 0},
+{'c', 15.68, 130.80, 22.60 ,130.27, 21.01, 132.40},
+{'c', 19.41, 134.53, 16.21 ,133.46, 16.21, 133.46},
+{'f', 0.000000,0.000000,0.000000,1.000000,0,0 },
+{'m', 26.48, 126.40, 0, 0, 0, 0},
+{'c', 26.48, 126.40, 33.40 ,125.87, 31.81, 128.00},
+{'c', 30.21, 130.12, 27.01 ,129.06, 27.01, 129.06},
+{'f', 0.000000,0.000000,0.000000,1.000000,0,0 },
+{'m', 36.88, 121.60, 0, 0, 0, 0},
+{'c', 36.88, 121.60, 43.80 ,121.07, 42.21, 123.19},
+{'c', 40.61, 125.33, 37.41 ,124.26, 37.41, 124.26},
+{'f', 0.000000,0.000000,0.000000,1.000000,0,0 },
+{'m', 9.28, 103.60, 0, 0, 0, 0},
+{'c', 9.28, 103.60, 16.20 ,103.07, 14.61, 105.19},
+{'c', 13.01, 107.33, 9.01 ,107.06, 9.01, 107.06},
+{'f', 0.000000,0.000000,0.000000,1.000000,0,0 },
+{'m', 19.28, 100.40, 0, 0, 0, 0},
+{'c', 19.28, 100.40, 26.20 ,99.87, 24.61, 102.00},
+{'c', 23.01, 104.12, 18.61 ,103.86, 18.61, 103.86},
+{'f', 0.000000,0.000000,0.000000,1.000000,0,0 },
+{'m', -3.40, 140.40, 0, 0, 0, 0},
+{'c', -3.40, 140.40, 1.80 ,140.00, 0.60, 141.60},
+{'c', -0.60, 143.20, -3.00 ,142.40, -3.00, 142.40},
+{'f', 0.000000,0.000000,0.000000,1.000000,0,0 },
+{'m', -76.60, 41.20, 0, 0, 0, 0},
+{'c', -76.60, 41.20, -81.00 ,50.00, -81.40, 53.20},
+{'c', -81.40, 53.20, -80.60 ,44.40, -79.40, 42.40},
+{'f', 0.603000,0.134000,0.000000,1.000000,0,0 },
+{'m', -95.00, 55.20, 0, 0, 0, 0},
+{'c', -95.00, 55.20, -98.20 ,69.60, -97.80, 72.40},
+{'c', -97.80, 72.40, -99.00 ,60.80, -98.60, 59.60},
+{'f', 0.603000,0.134000,0.000000,1.000000,0,0 },
+{'m', -74.20, -19.40, 0, 0, 0, 0},
+{'l', -74.40, -16.20, 0, 0, 0, 0},
+{'l', -76.60, -16.00, 0, 0, 0, 0},
+{'c', -76.60, -16.00, -62.40 ,-3.40, -61.80, 4.20},
+{'f', 0.804000,0.804000,0.804000,1.000000,0,0 },
+{'m', -70.22, -18.14, 0, 0, 0, 0},
+{'c', -70.65, -18.55, -70.43 ,-19.30, -70.84, -19.56},
+{'c', -71.64, -20.07, -69.54 ,-20.13, -69.77, -20.84},
+{'c', -70.15, -22.05, -69.96 ,-22.07, -70.08, -23.35},
+{'c', -70.14, -23.95, -69.55 ,-25.49, -69.17, -25.93},
+{'c', -67.72, -27.58, -69.05 ,-30.51, -67.41, -32.06},
+{'c', -67.10, -32.35, -66.73 ,-32.90, -66.44, -33.32},
+{'c', -65.78, -34.28, -64.60 ,-34.77, -63.65, -35.60},
+{'c', -63.33, -35.88, -63.53 ,-36.70, -62.96, -36.61},
+{'c', -62.25, -36.49, -61.01 ,-36.62, -61.05, -35.78},
+{'c', -61.16, -33.66, -62.49 ,-31.94, -63.77, -30.28},
+{'c', -63.32, -29.57, -63.78 ,-28.94, -64.06, -28.38},
+{'c', -65.40, -25.76, -65.21 ,-22.92, -65.39, -20.08},
+{'c', -65.39, -19.99, -65.70 ,-19.92, -65.69, -19.86},
+{'c', -65.34, -17.53, -64.75 ,-15.33, -63.87, -13.10},
+{'c', -63.51, -12.17, -63.04 ,-11.28, -62.89, -10.35},
+{'c', -62.77, -9.66, -62.67 ,-8.83, -63.08, -8.12},
+{'c', -61.05, -5.23, -62.35 ,-2.58, -61.19, 0.95},
+{'c', -60.98, 1.57, -59.29 ,3.49, -59.75, 3.33},
+{'c', -62.26, 2.46, -62.37 ,2.06, -62.55, 1.30},
+{'c', -62.70, 0.68, -63.03 ,-0.70, -63.26, -1.30},
+{'c', -63.33, -1.46, -63.50 ,-3.35, -63.58, -3.47},
+{'c', -65.09, -5.85, -63.73 ,-5.67, -65.10, -8.03},
+{'c', -66.53, -8.71, -67.50 ,-9.82, -68.62, -10.98},
+{'c', -68.82, -11.18, -67.67 ,-11.91, -67.86, -12.12},
+{'c', -68.95, -13.41, -70.10 ,-14.18, -69.76, -15.67},
+{'f', 0.000000,0.000000,0.000000,1.000000,0,0 },
+{'m', -73.80, -16.40, 0, 0, 0, 0},
+{'c', -73.80, -16.40, -73.40 ,-9.60, -71.00, -8.00},
+{'c', -68.60, -6.40, -69.80 ,-7.20, -73.00, -8.40},
+{'c', -76.20, -9.60, -75.00 ,-10.40, -75.00, -10.40},
+{'c', -75.00, -10.40, -77.80 ,-10.00, -75.40, -8.00},
+{'c', -73.00, -6.00, -69.40 ,-3.60, -71.00, -3.60},
+{'c', -72.60, -3.60, -80.20 ,-7.60, -80.20, -10.40},
+{'c', -80.20, -13.20, -81.20 ,-17.30, -81.20, -17.30},
+{'c', -81.20, -17.30, -80.10 ,-18.10, -75.30, -18.00},
+{'f', 0.000000,0.000000,0.000000,1.000000,0,0 },
+{'m', -74.60, 2.20, 0, 0, 0, 0},
+{'c', -74.60, 2.20, -83.12 ,-0.59, -101.60, 2.80},
+{'c', -101.60, 2.80, -92.57 ,0.72, -73.80, 3.00},
+{'f', 1.000000,1.000000,1.000000,1.000000,0,0 },
+{'m', -72.50, 2.13, 0, 0, 0, 0},
+{'c', -72.50, 2.13, -80.75 ,-1.39, -99.45, 0.39},
+{'c', -99.45, 0.39, -90.28 ,-0.90, -71.77, 3.00},
+{'f', 1.000000,1.000000,1.000000,1.000000,0,0 },
+{'m', -70.71, 2.22, 0, 0, 0, 0},
+{'c', -70.71, 2.22, -78.68 ,-1.90, -97.46, -1.51},
+{'c', -97.46, -1.51, -88.21 ,-2.12, -70.05, 3.14},
+{'f', 1.000000,1.000000,1.000000,1.000000,0,0 },
+{'m', -69.44, 2.44, 0, 0, 0, 0},
+{'c', -69.44, 2.44, -76.27 ,-1.86, -93.14, -2.96},
+{'c', -93.14, -2.96, -84.80 ,-2.79, -68.92, 3.32},
+{'f', 1.000000,1.000000,1.000000,1.000000,0,0 },
+{'m', 45.84, 12.96, 0, 0, 0, 0},
+{'c', 45.84, 12.96, 44.91 ,13.61, 45.12, 12.42},
+{'c', 45.34, 11.24, 73.55 ,-1.93, 77.16, -1.68},
+{'f', 1.000000,1.000000,1.000000,1.000000,0,0 },
+{'m', 42.45, 13.60, 0, 0, 0, 0},
+{'c', 42.45, 13.60, 41.57 ,14.31, 41.69, 13.12},
+{'c', 41.81, 11.93, 68.90 ,-3.42, 72.52, -3.45},
+{'f', 1.000000,1.000000,1.000000,1.000000,0,0 },
+{'m', 39.16, 14.97, 0, 0, 0, 0},
+{'c', 39.16, 14.97, 38.33 ,15.75, 38.37, 14.55},
+{'c', 38.42, 13.35, 58.23 ,-2.15, 68.05, -4.02},
+{'f', 1.000000,1.000000,1.000000,1.000000,0,0 },
+{'m', 36.28, 16.84, 0, 0, 0, 0},
+{'c', 36.28, 16.84, 35.54 ,17.53, 35.58, 16.45},
+{'c', 35.62, 15.37, 53.45 ,1.43, 62.28, -0.26},
+{'f', 1.000000,1.000000,1.000000,1.000000,0,0 },
+{'m', 4.60, 164.80, 0, 0, 0, 0},
+{'c', 4.60, 164.80, -10.60 ,162.40, 6.20, 160.80},
+{'c', 6.20, 160.80, 24.20 ,158.80, 28.20, 153.60},
+{'c', 28.20, 153.60, 41.80 ,144.40, 44.60, 144.00},
+{'c', 47.40, 143.60, 63.80 ,140.00, 64.20, 137.60},
+{'c', 64.60, 135.20, 70.60 ,132.80, 72.20, 133.60},
+{'c', 73.80, 134.40, 73.80 ,143.60, 71.00, 144.40},
+{'c', 68.20, 145.20, 49.40 ,152.40, 43.00, 153.60},
+{'c', 36.60, 154.80, 25.00 ,162.40, 20.20, 163.60},
+{'f', 0.804000,0.804000,0.804000,1.000000,0,0 },
+{'m', 77.60, 127.40, 0, 0, 0, 0},
+{'c', 77.60, 127.40, 74.60 ,129.00, 73.40, 131.60},
+{'c', 73.40, 131.60, 67.00 ,142.20, 52.80, 145.40},
+{'c', 52.80, 145.40, 29.80 ,154.40, 22.00, 156.40},
+{'c', 22.00, 156.40, 8.60 ,161.40, 1.20, 160.60},
+{'c', 1.20, 160.60, -5.80 ,160.80, 0.40, 162.40},
+{'c', 0.40, 162.40, 20.60 ,160.40, 24.00, 158.60},
+{'c', 24.00, 158.60, 39.60 ,153.40, 42.60, 150.80},
+{'c', 45.60, 148.20, 63.80 ,143.20, 66.00, 141.20},
+{'f', 0.000000,0.000000,0.000000,1.000000,0,0 },
+{'m', 18.88, 158.91, 0, 0, 0, 0},
+{'c', 18.88, 158.91, 24.11 ,158.69, 22.96, 160.23},
+{'c', 21.80, 161.78, 19.36 ,160.91, 19.36, 160.91},
+{'f', 0.000000,0.000000,0.000000,1.000000,0,0 },
+{'m', 11.68, 160.26, 0, 0, 0, 0},
+{'c', 11.68, 160.26, 16.91 ,160.04, 15.76, 161.59},
+{'c', 14.60, 163.14, 12.15 ,162.26, 12.15, 162.26},
+{'f', 0.000000,0.000000,0.000000,1.000000,0,0 },
+{'m', 1.25, 161.51, 0, 0, 0, 0},
+{'c', 1.25, 161.51, 6.48 ,161.28, 5.33, 162.83},
+{'c', 4.17, 164.38, 1.73 ,163.51, 1.73, 163.51},
+{'f', 0.000000,0.000000,0.000000,1.000000,0,0 },
+{'m', -6.38, 162.06, 0, 0, 0, 0},
+{'c', -6.38, 162.06, -1.15 ,161.83, -2.31, 163.38},
+{'c', -3.46, 164.93, -5.91 ,164.05, -5.91, 164.05},
+{'f', 0.000000,0.000000,0.000000,1.000000,0,0 },
+{'m', 35.41, 151.51, 0, 0, 0, 0},
+{'c', 35.41, 151.51, 42.38 ,151.21, 40.84, 153.27},
+{'c', 39.31, 155.34, 36.05 ,154.17, 36.05, 154.17},
+{'f', 0.000000,0.000000,0.000000,1.000000,0,0 },
+{'m', 45.73, 147.09, 0, 0, 0, 0},
+{'c', 45.73, 147.09, 51.69 ,143.79, 51.16, 148.85},
+{'c', 50.88, 151.41, 46.36 ,149.75, 46.36, 149.75},
+{'f', 0.000000,0.000000,0.000000,1.000000,0,0 },
+{'m', 54.86, 144.27, 0, 0, 0, 0},
+{'c', 54.86, 144.27, 62.02 ,140.57, 60.29, 146.03},
+{'c', 59.51, 148.49, 55.49 ,146.94, 55.49, 146.94},
+{'f', 0.000000,0.000000,0.000000,1.000000,0,0 },
+{'m', 64.38, 139.45, 0, 0, 0, 0},
+{'c', 64.38, 139.45, 68.73 ,134.55, 69.80, 141.21},
+{'c', 70.21, 143.75, 65.01 ,142.11, 65.01, 142.11},
+{'f', 0.000000,0.000000,0.000000,1.000000,0,0 },
+{'m', 26.83, 156.00, 0, 0, 0, 0},
+{'c', 26.83, 156.00, 32.06 ,155.77, 30.91, 157.32},
+{'c', 29.76, 158.87, 27.31 ,158.00, 27.31, 158.00},
+{'f', 0.000000,0.000000,0.000000,1.000000,0,0 },
+{'m', 62.43, 34.60, 0, 0, 0, 0},
+{'c', 62.43, 34.60, 61.71 ,35.27, 61.71, 34.20},
+{'c', 61.71, 33.13, 79.19 ,19.86, 88.03, 18.48},
+{'f', 1.000000,1.000000,1.000000,1.000000,0,0 },
+{'m', 65.40, 98.40, 0, 0, 0, 0},
+{'c', 65.40, 98.40, 87.40 ,120.80, 96.60, 124.40},
+{'c', 96.60, 124.40, 105.80 ,135.60, 101.80, 161.60},
+{'c', 101.80, 161.60, 98.60 ,169.20, 95.40, 148.40},
+{'c', 95.40, 148.40, 98.60 ,123.20, 87.40, 139.20},
+{'c', 87.40, 139.20, 79.00 ,129.30, 85.40, 129.60},
+{'c', 85.40, 129.60, 88.60 ,131.60, 89.00, 130.00},
+{'c', 89.40, 128.40, 81.40 ,114.80, 64.20, 100.40},
+{'f', 0.000000,0.000000,0.000000,1.000000,0,0 },
+{'m', 7.00, 137.20, 0, 0, 0, 0},
+{'c', 7.00, 137.20, 6.80 ,135.40, 8.60, 136.20},
+{'c', 10.40, 137.00, 104.60 ,143.20, 136.20, 167.20},
+{'f', 1.000000,1.000000,1.000000,1.000000,0,0 },
+{'m', 17.40, 132.80, 0, 0, 0, 0},
+{'c', 17.40, 132.80, 17.20 ,131.00, 19.00, 131.80},
+{'c', 20.80, 132.60, 157.40 ,131.60, 181.00, 164.00},
+{'f', 1.000000,1.000000,1.000000,1.000000,0,0 },
+{'m', 29.00, 128.80, 0, 0, 0, 0},
+{'c', 29.00, 128.80, 28.80 ,127.00, 30.60, 127.80},
+{'c', 32.40, 128.60, 205.80 ,115.60, 229.40, 148.00},
+{'f', 1.000000,1.000000,1.000000,1.000000,0,0 },
+{'m', 39.00, 124.00, 0, 0, 0, 0},
+{'c', 39.00, 124.00, 38.80 ,122.20, 40.60, 123.00},
+{'c', 42.40, 123.80, 164.60 ,85.20, 188.20, 117.60},
+{'f', 1.000000,1.000000,1.000000,1.000000,0,0 },
+{'m', -19.00, 146.80, 0, 0, 0, 0},
+{'c', -19.00, 146.80, -19.20 ,145.00, -17.40, 145.80},
+{'c', -15.60, 146.60, 2.20 ,148.80, 4.20, 187.60},
+{'f', 1.000000,1.000000,1.000000,1.000000,0,0 },
+{'m', -27.80, 148.40, 0, 0, 0, 0},
+{'c', -27.80, 148.40, -28.00 ,146.60, -26.20, 147.40},
+{'c', -24.40, 148.20, -10.20 ,143.60, -13.00, 182.40},
+{'f', 1.000000,1.000000,1.000000,1.000000,0,0 },
+{'m', -35.80, 148.80, 0, 0, 0, 0},
+{'c', -35.80, 148.80, -36.00 ,147.00, -34.20, 147.80},
+{'c', -32.40, 148.60, -17.00 ,149.20, -29.40, 171.60},
+{'f', 1.000000,1.000000,1.000000,1.000000,0,0 },
+{'m', 11.53, 104.47, 0, 0, 0, 0},
+{'c', 11.53, 104.47, 11.08 ,106.46, 12.63, 105.25},
+{'c', 28.70, 92.62, 61.14 ,33.72, 116.83, 28.09},
+{'f', 1.000000,1.000000,1.000000,1.000000,0,0 },
+{'m', 22.73, 102.67, 0, 0, 0, 0},
+{'c', 22.73, 102.67, 21.36 ,101.47, 23.23, 100.85},
+{'c', 25.10, 100.22, 137.54 ,27.72, 176.83, 35.69},
+{'f', 1.000000,1.000000,1.000000,1.000000,0,0 },
+{'m', 1.89, 108.77, 0, 0, 0, 0},
+{'c', 1.89, 108.77, 1.38 ,110.37, 3.09, 109.39},
+{'c', 12.06, 104.27, 15.68 ,47.06, 59.25, 45.80},
+{'f', 1.000000,1.000000,1.000000,1.000000,0,0 },
+{'m', -18.04, 119.79, 0, 0, 0, 0},
+{'c', -18.04, 119.79, -19.11 ,121.08, -17.16, 120.83},
+{'c', -6.92, 119.49, 14.49 ,78.22, 58.93, 83.30},
+{'f', 1.000000,1.000000,1.000000,1.000000,0,0 },
+{'m', -6.80, 113.67, 0, 0, 0, 0},
+{'c', -6.80, 113.67, -7.61 ,115.14, -5.74, 114.51},
+{'c', 4.06, 111.24, 17.14 ,66.62, 61.73, 63.08},
+{'f', 1.000000,1.000000,1.000000,1.000000,0,0 },
+{'m', -25.08, 124.91, 0, 0, 0, 0},
+{'c', -25.08, 124.91, -25.95 ,125.95, -24.37, 125.75},
+{'c', -16.07, 124.67, 1.27 ,91.24, 37.26, 95.35},
+{'f', 1.000000,1.000000,1.000000,1.000000,0,0 },
+{'m', -32.68, 130.82, 0, 0, 0, 0},
+{'c', -32.68, 130.82, -33.68 ,131.87, -32.09, 131.75},
+{'c', -27.92, 131.44, 2.71 ,98.36, 21.18, 113.86},
+{'f', 1.000000,1.000000,1.000000,1.000000,0,0 },
+{'m', 36.85, 98.90, 0, 0, 0, 0},
+{'c', 36.85, 98.90, 35.65 ,97.54, 37.59, 97.16},
+{'c', 39.52, 96.77, 160.22 ,39.06, 198.18, 51.93},
+{'f', 1.000000,1.000000,1.000000,1.000000,0,0 },
+{'m', 3.40, 163.20, 0, 0, 0, 0},
+{'c', 3.40, 163.20, 3.20 ,161.40, 5.00, 162.20},
+{'c', 6.80, 163.00, 22.20 ,163.60, 9.80, 186.00},
+{'f', 1.000000,1.000000,1.000000,1.000000,0,0 },
+{'m', 13.80, 161.60, 0, 0, 0, 0},
+{'c', 13.80, 161.60, 13.60 ,159.80, 15.40, 160.60},
+{'c', 17.20, 161.40, 35.00 ,163.60, 37.00, 202.40},
+{'f', 1.000000,1.000000,1.000000,1.000000,0,0 },
+{'m', 20.60, 160.00, 0, 0, 0, 0},
+{'c', 20.60, 160.00, 20.40 ,158.20, 22.20, 159.00},
+{'c', 24.00, 159.80, 48.60 ,163.20, 72.20, 195.60},
+{'f', 1.000000,1.000000,1.000000,1.000000,0,0 },
+{'m', 28.23, 157.97, 0, 0, 0, 0},
+{'c', 28.23, 157.97, 27.79 ,156.21, 29.68, 156.77},
+{'c', 31.57, 157.32, 52.00 ,155.42, 90.10, 189.60},
+{'f', 1.000000,1.000000,1.000000,1.000000,0,0 },
+{'m', 38.62, 153.57, 0, 0, 0, 0},
+{'c', 38.62, 153.57, 38.19 ,151.81, 40.08, 152.37},
+{'c', 41.97, 152.92, 76.80 ,157.42, 128.50, 192.40},
+{'f', 1.000000,1.000000,1.000000,1.000000,0,0 },
+{'m', -1.80, 142.00, 0, 0, 0, 0},
+{'c', -1.80, 142.00, -2.00 ,140.20, -0.20, 141.00},
+{'c', 1.60, 141.80, 55.00 ,144.40, 85.40, 171.20},
+{'f', 1.000000,1.000000,1.000000,1.000000,0,0 },
+{'m', -11.80, 146.00, 0, 0, 0, 0},
+{'c', -11.80, 146.00, -12.00 ,144.20, -10.20, 145.00},
+{'c', -8.40, 145.80, 16.20 ,149.20, 39.80, 181.60},
+{'f', 1.000000,1.000000,1.000000,1.000000,0,0 },
+{'m', 49.50, 148.96, 0, 0, 0, 0},
+{'c', 49.50, 148.96, 48.94 ,147.24, 50.86, 147.66},
+{'c', 52.79, 148.07, 87.86 ,150.00, 141.98, 181.10},
+{'f', 1.000000,1.000000,1.000000,1.000000,0,0 },
+{'m', 57.90, 146.56, 0, 0, 0, 0},
+{'c', 57.90, 146.56, 57.34 ,144.84, 59.26, 145.25},
+{'c', 61.19, 145.67, 96.26 ,147.60, 150.38, 178.70},
+{'f', 1.000000,1.000000,1.000000,1.000000,0,0 },
+{'m', 67.50, 141.56, 0, 0, 0, 0},
+{'c', 67.50, 141.56, 66.94 ,139.84, 68.86, 140.25},
+{'c', 70.79, 140.67, 113.86 ,145.00, 203.58, 179.30},
+{'f', 1.000000,1.000000,1.000000,1.000000,0,0 },
+{'m', -43.80, 148.40, 0, 0, 0, 0},
+{'c', -43.80, 148.40, -38.60 ,148.00, -39.80, 149.60},
+{'c', -41.00, 151.20, -43.40 ,150.40, -43.40, 150.40},
+{'f', 0.000000,0.000000,0.000000,1.000000,0,0 },
+{'m', -13.00, 162.40, 0, 0, 0, 0},
+{'c', -13.00, 162.40, -7.80 ,162.00, -9.00, 163.60},
+{'c', -10.20, 165.20, -12.60 ,164.40, -12.60, 164.40},
+{'f', 0.000000,0.000000,0.000000,1.000000,0,0 },
+{'m', -21.80, 162.00, 0, 0, 0, 0},
+{'c', -21.80, 162.00, -16.60 ,161.60, -17.80, 163.20},
+{'c', -19.00, 164.80, -21.40 ,164.00, -21.40, 164.00},
+{'f', 0.000000,0.000000,0.000000,1.000000,0,0 },
+{'m', -117.17, 150.18, 0, 0, 0, 0},
+{'c', -117.17, 150.18, -112.12 ,151.50, -113.78, 152.62},
+{'c', -115.44, 153.74, -117.45 ,152.20, -117.45, 152.20},
+{'f', 0.000000,0.000000,0.000000,1.000000,0,0 },
+{'m', -115.17, 140.58, 0, 0, 0, 0},
+{'c', -115.17, 140.58, -110.12 ,141.91, -111.78, 143.02},
+{'c', -113.44, 144.14, -115.45 ,142.60, -115.45, 142.60},
+{'f', 0.000000,0.000000,0.000000,1.000000,0,0 },
+{'m', -122.37, 136.18, 0, 0, 0, 0},
+{'c', -122.37, 136.18, -117.32 ,137.50, -118.98, 138.62},
+{'c', -120.64, 139.74, -122.65 ,138.20, -122.65, 138.20},
+{'f', 0.000000,0.000000,0.000000,1.000000,0,0 },
+{'m', -42.60, 211.20, 0, 0, 0, 0},
+{'c', -42.60, 211.20, -44.20 ,211.20, -48.20, 213.20},
+{'c', -50.20, 213.20, -61.40 ,216.80, -67.00, 226.80},
+{'f', 0.804000,0.804000,0.804000,1.000000,0,0 },
+{'m', 45.12, 303.85, 0, 0, 0, 0},
+{'c', 45.26, 304.11, 45.31 ,304.52, 45.60, 304.54},
+{'c', 46.26, 304.58, 47.49 ,304.88, 47.37, 304.25},
+{'c', 46.52, 299.94, 45.65 ,295.00, 41.52, 293.20},
+{'c', 40.88, 292.92, 39.43 ,293.33, 39.36, 294.21},
+{'c', 39.23, 295.74, 39.12 ,297.09, 39.42, 298.55},
+{'c', 39.73, 299.98, 41.88 ,299.99, 42.80, 298.60},
+{'f', 0.804000,0.804000,0.804000,1.000000,0,0 },
+{'m', 34.04, 308.58, 0, 0, 0, 0},
+{'c', 34.79, 309.99, 34.66 ,311.85, 36.07, 312.42},
+{'c', 36.81, 312.71, 38.66 ,311.74, 38.25, 310.66},
+{'c', 37.44, 308.60, 37.06 ,306.36, 35.67, 304.55},
+{'c', 35.47, 304.29, 35.71 ,303.75, 35.55, 303.43},
+{'c', 34.95, 302.21, 33.81 ,301.47, 32.40, 301.80},
+{'c', 31.29, 304.00, 32.43 ,306.13, 33.95, 307.84},
+{'f', 0.804000,0.804000,0.804000,1.000000,0,0 },
+{'m', -5.56, 303.39, 0, 0, 0, 0},
+{'c', -5.67, 303.01, -5.71 ,302.55, -5.54, 302.23},
+{'c', -5.01, 301.20, -4.22 ,300.07, -4.56, 299.05},
+{'c', -4.91, 298.00, -6.02 ,298.18, -6.67, 298.75},
+{'c', -7.81, 299.74, -7.86 ,301.57, -8.55, 302.93},
+{'c', -8.74, 303.31, -8.69 ,303.89, -9.13, 304.28},
+{'c', -9.61, 304.70, -10.05 ,306.22, -9.95, 306.79},
+{'c', -9.90, 307.11, -10.08 ,317.01, -9.86, 316.75},
+{'c', -9.24, 316.02, -6.19 ,306.28, -6.12, 305.39},
+{'f', 0.804000,0.804000,0.804000,1.000000,0,0 },
+{'m', -31.20, 296.60, 0, 0, 0, 0},
+{'c', -28.57, 294.10, -25.78 ,291.14, -26.22, 287.43},
+{'c', -26.34, 286.45, -28.11 ,286.98, -28.30, 287.82},
+{'c', -29.10, 291.45, -31.14 ,294.11, -33.71, 296.50},
+{'c', -35.90, 298.55, -37.77 ,304.89, -38.00, 305.40},
+{'f', 0.804000,0.804000,0.804000,1.000000,0,0 },
+{'m', -44.78, 290.63, 0, 0, 0, 0},
+{'c', -44.25, 290.26, -44.55 ,289.77, -44.34, 289.44},
+{'c', -43.38, 287.98, -42.08 ,286.74, -42.07, 285.00},
+{'c', -42.06, 284.72, -42.44 ,284.41, -42.78, 284.64},
+{'c', -43.05, 284.82, -43.40 ,284.95, -43.50, 285.08},
+{'c', -45.53, 287.53, -46.93 ,290.20, -48.38, 293.01},
+{'c', -48.56, 293.37, -49.70 ,297.86, -49.39, 297.97},
+{'c', -49.15, 298.06, -47.43 ,293.88, -47.22, 293.76},
+{'f', 0.804000,0.804000,0.804000,1.000000,0,0 },
+{'m', -28.04, 310.18, 0, 0, 0, 0},
+{'c', -27.60, 309.31, -26.02 ,308.11, -26.14, 307.22},
+{'c', -26.25, 306.29, -25.79 ,304.85, -26.70, 305.54},
+{'c', -27.95, 306.48, -31.40 ,307.83, -31.67, 313.64},
+{'f', 0.804000,0.804000,0.804000,1.000000,0,0 },
+{'m', -13.60, 293.00, 0, 0, 0, 0},
+{'c', -13.20, 292.33, -12.49 ,292.81, -12.03, 292.54},
+{'c', -11.38, 292.17, -10.77 ,291.61, -10.48, 290.96},
+{'c', -9.51, 288.81, -7.74 ,287.00, -7.60, 284.60},
+{'c', -9.09, 283.20, -9.77 ,285.24, -10.40, 286.20},
+{'c', -11.72, 284.55, -12.72 ,286.43, -14.02, 286.95},
+{'c', -14.09, 286.98, -14.30 ,286.63, -14.38, 286.65},
+{'c', -15.56, 287.10, -16.24 ,288.18, -17.23, 288.96},
+{'c', -17.41, 289.09, -17.81 ,288.91, -17.96, 289.05},
+{'c', -18.61, 289.65, -19.58 ,289.98, -19.86, 290.66},
+{'c', -20.97, 293.36, -24.11 ,295.46, -26.00, 303.00},
+{'c', -25.62, 303.91, -21.49 ,296.36, -21.00, 295.66},
+{'c', -20.16, 294.46, -20.05 ,297.32, -18.77, 296.66},
+{'c', -18.72, 296.63, -18.53 ,296.87, -18.40, 297.00},
+{'c', -18.21, 296.72, -17.99 ,296.49, -17.60, 296.60},
+{'c', -17.60, 296.20, -17.73 ,295.64, -17.53, 295.49},
+{'c', -16.30, 294.51, -16.38 ,293.44, -15.60, 292.20},
+{'f', 0.804000,0.804000,0.804000,1.000000,0,0 },
+{'m', 46.20, 347.40, 0, 0, 0, 0},
+{'c', 46.20, 347.40, 53.60 ,327.00, 49.20, 315.80},
+{'c', 49.20, 315.80, 60.60 ,337.40, 56.00, 348.60},
+{'c', 56.00, 348.60, 55.60 ,338.20, 51.60, 333.20},
+{'f', 0.804000,0.804000,0.804000,1.000000,0,0 },
+{'m', 31.40, 344.80, 0, 0, 0, 0},
+{'c', 31.40, 344.80, 36.80 ,336.00, 28.80, 317.60},
+{'c', 28.80, 317.60, 28.00 ,338.00, 21.20, 349.00},
+{'f', 0.804000,0.804000,0.804000,1.000000,0,0 },
+{'m', 21.40, 342.80, 0, 0, 0, 0},
+{'c', 21.40, 342.80, 21.20 ,322.80, 21.60, 319.80},
+{'c', 21.60, 319.80, 17.80 ,336.40, 7.60, 346.00},
+{'f', 0.804000,0.804000,0.804000,1.000000,0,0 },
+{'m', 11.80, 310.80, 0, 0, 0, 0},
+{'c', 11.80, 310.80, 17.80 ,324.40, 7.80, 342.80},
+{'c', 7.80, 342.80, 14.20 ,330.60, 9.40, 323.60},
+{'f', 0.804000,0.804000,0.804000,1.000000,0,0 },
+{'m', -7.40, 342.40, 0, 0, 0, 0},
+{'c', -7.40, 342.40, -8.40 ,326.80, -6.60, 324.60},
+{'c', -6.60, 324.60, -6.40 ,318.20, -6.80, 317.20},
+{'c', -6.80, 317.20, -2.80 ,311.00, -2.60, 318.40},
+{'c', -2.60, 318.40, -1.20 ,326.20, 1.60, 330.80},
+{'c', 1.60, 330.80, 5.20 ,336.20, 5.00, 342.60},
+{'f', 0.804000,0.804000,0.804000,1.000000,0,0 },
+{'m', -11.00, 314.80, 0, 0, 0, 0},
+{'c', -11.00, 314.80, -17.60 ,325.60, -19.40, 344.60},
+{'c', -19.40, 344.60, -20.80 ,338.40, -17.00, 324.00},
+{'f', 0.804000,0.804000,0.804000,1.000000,0,0 },
+{'m', -32.80, 334.60, 0, 0, 0, 0},
+{'c', -32.80, 334.60, -27.80 ,329.20, -26.40, 324.20},
+{'c', -26.40, 324.20, -22.80 ,308.40, -29.20, 317.00},
+{'c', -29.20, 317.00, -29.00 ,325.00, -37.20, 332.40},
+{'f', 0.804000,0.804000,0.804000,1.000000,0,0 },
+{'m', -38.60, 329.60, 0, 0, 0, 0},
+{'c', -38.60, 329.60, -35.20 ,312.20, -34.40, 311.40},
+{'c', -34.40, 311.40, -32.60 ,308.00, -35.40, 311.20},
+{'c', -35.40, 311.20, -44.20 ,330.40, -48.20, 337.00},
+{'f', 0.804000,0.804000,0.804000,1.000000,0,0 },
+{'m', -44.40, 313.00, 0, 0, 0, 0},
+{'c', -44.40, 313.00, -32.80 ,290.60, -54.60, 316.40},
+{'f', 0.804000,0.804000,0.804000,1.000000,0,0 },
+{'m', -59.80, 298.40, 0, 0, 0, 0},
+{'c', -59.80, 298.40, -55.00 ,279.60, -52.40, 279.80},
+{'c', -52.40, 279.80, -44.20 ,270.80, -50.80, 281.40},
+{'c', -50.80, 281.40, -56.80 ,291.00, -56.20, 300.80},
+{'f', 0.804000,0.804000,0.804000,1.000000,0,0 },
+{'m', 270.50, 287.00, 0, 0, 0, 0},
+{'c', 270.50, 287.00, 258.50 ,277.00, 256.00, 273.50},
+{'c', 256.00, 273.50, 269.50 ,292.00, 269.50, 299.00},
+{'f', 0.804000,0.804000,0.804000,1.000000,0,0 },
+{'m', 276.00, 265.00, 0, 0, 0, 0},
+{'c', 276.00, 265.00, 255.00 ,250.00, 251.50, 242.50},
+{'c', 251.50, 242.50, 278.00 ,272.00, 278.00, 276.50},
+{'f', 0.804000,0.804000,0.804000,1.000000,0,0 },
+{'m', 293.00, 111.00, 0, 0, 0, 0},
+{'c', 293.00, 111.00, 281.00 ,103.00, 279.50, 105.00},
+{'c', 279.50, 105.00, 290.00 ,111.50, 292.50, 120.00},
+{'f', 0.804000,0.804000,0.804000,1.000000,0,0 },
+{'m', 301.50, 191.50, 0, 0, 0, 0},
+{'l', 284.00, 179.50, 0, 0, 0, 0},
+{'c', 284.00, 179.50, 303.00 ,196.50, 303.50, 200.50},
+{'f', 0.804000,0.804000,0.804000,1.000000,0,0 },
+{'m', -89.25, 169.00, 0, 0, 0, 0},
+{'f', 0.804000,0.804000,0.804000,1.000000,0,0 },
+{'l', -67.25, 173.75, 0, 0, 0, 0},
+{'m', -39.00, 331.00, 0, 0, 0, 0},
+{'f', 0.804000,0.804000,0.804000,1.000000,0,0 },
+{'m', -33.50, 336.00, 0, 0, 0, 0},
+{'f', 0.804000,0.804000,0.804000,1.000000,0,0 },
+{'m', 20.50, 344.50, 0, 0, 0, 0},
+{'f', 0.804000,0.804000,0.804000,1.000000,0,0 },
+{'m', 301.50, 191.50, 0, 0, 0, 0},
+{'l', 284.00, 179.50, 0, 0, 0, 0},
+{'c', 284.00, 179.50, 303.00 ,196.50, 303.50, 200.50},
+{'f', 0.804000,0.804000,0.804000,1.000000,0,0 },
+{'m', -89.25, 169.00, 0, 0, 0, 0},
+{'f', 0.804000,0.804000,0.804000,1.000000,0,0 },
+{'l', -67.25, 173.75, 0, 0, 0, 0},
+{'m', -39.00, 331.00, 0, 0, 0, 0},
+{'f', 0.804000,0.804000,0.804000,1.000000,0,0 },
+{'m', -33.50, 336.00, 0, 0, 0, 0},
+{'f', 0.804000,0.804000,0.804000,1.000000,0,0 },
+{'m', 20.50, 344.50, 0, 0, 0, 0},
+{'f', 0.804000,0.804000,0.804000,1.000000,0,0 },
+{'m', 301.50, 191.50, 0, 0, 0, 0},
+{'l', 284.00, 179.50, 0, 0, 0, 0},
+{'c', 284.00, 179.50, 303.00 ,196.50, 303.50, 200.50},
+{'f', 0.804000,0.804000,0.804000,1.000000,0,0 },
+{'m', -89.25, 169.00, 0, 0, 0, 0},
+{'f', 0.804000,0.804000,0.804000,1.000000,0,0 },
+{'l', -67.25, 173.75, 0, 0, 0, 0},
+{'m', -39.00, 331.00, 0, 0, 0, 0},
+{'f', 0.804000,0.804000,0.804000,1.000000,0,0 },
+{'m', -33.50, 336.00, 0, 0, 0, 0},
+{'f', 0.804000,0.804000,0.804000,1.000000,0,0 },
+{'m', 20.50, 344.50, 0, 0, 0, 0},
+{'f', 0.804000,0.804000,0.804000,1.000000,0,0 }};
diff --git a/test/tighten-bounds.c b/test/tighten-bounds.c
new file mode 100644
index 000000000..f5430e447
--- /dev/null
+++ b/test/tighten-bounds.c
@@ -0,0 +1,172 @@
+/*
+ * Copyright © 2011 Uli Schlachter
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Uli Schlachter <psychon@znc.in>
+ */
+
+#include "cairo-test.h"
+
+static void path_none (cairo_t *cr, int size)
+{
+}
+
+static void path_box (cairo_t *cr, int size)
+{
+ cairo_rectangle (cr, 0, 0, size, size);
+}
+
+static void path_box_unaligned (cairo_t *cr, int size)
+{
+ cairo_rectangle (cr, 0.5, 0.5, size - 1, size - 1);
+}
+
+static void path_triangle (cairo_t *cr, int size)
+{
+ cairo_move_to (cr, 0, 0);
+ cairo_line_to (cr, size/2, size);
+ cairo_line_to (cr, size, 0);
+ cairo_close_path (cr);
+}
+
+static void path_circle (cairo_t *cr, int size)
+{
+ cairo_arc (cr, size / 2.0, size / 2.0, size / 2.0, 0, 2 * M_PI);
+}
+
+static void (* const path_funcs[])(cairo_t *cr, int size) = {
+ path_none,
+ path_box,
+ path_box_unaligned,
+ path_triangle,
+ path_circle
+};
+
+#define SIZE 20
+#define PAD 2
+#define TYPES 6
+/* All-clipped is boring, thus we skip path_none for clipping */
+#define CLIP_OFFSET 1
+#define IMAGE_WIDTH ((ARRAY_LENGTH (path_funcs) - CLIP_OFFSET) * TYPES * (SIZE + PAD) - PAD)
+#define IMAGE_HEIGHT (ARRAY_LENGTH (path_funcs) * (SIZE + PAD) - PAD)
+
+static void
+draw_idx (cairo_t *cr, int i, int j, int type)
+{
+ cairo_bool_t little_path;
+ cairo_bool_t empty_clip;
+ cairo_bool_t little_clip;
+
+ /* The lowest bit controls the path, the rest the clip */
+ little_path = type & 1;
+
+ /* We don't want the combination "empty_clip = TRUE, little_clip = FALSE"
+ * (== all clipped).
+ */
+ switch (type >> 1)
+ {
+ case 0:
+ empty_clip = FALSE;
+ little_clip = FALSE;
+ break;
+ case 1:
+ empty_clip = FALSE;
+ little_clip = TRUE;
+ break;
+ case 2:
+ empty_clip = TRUE;
+ little_clip = TRUE;
+ break;
+ default:
+ return;
+ }
+
+ cairo_save (cr);
+
+ /* Thanks to the fill rule, drawing something twice removes it again */
+ cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
+
+ path_funcs[i] (cr, SIZE);
+ if (empty_clip)
+ path_funcs[i] (cr, SIZE);
+ if (little_clip)
+ {
+ cairo_save (cr);
+ cairo_translate (cr, SIZE / 4, SIZE / 4);
+ path_funcs[i] (cr, SIZE / 2);
+ cairo_restore (cr);
+ }
+ cairo_clip (cr);
+
+ path_funcs[j] (cr, SIZE);
+ path_funcs[j] (cr, SIZE);
+ if (little_path)
+ {
+ /* Draw the object again in the center of itself */
+ cairo_save (cr);
+ cairo_translate (cr, SIZE / 4, SIZE / 4);
+ path_funcs[j] (cr, SIZE / 2);
+ cairo_restore (cr);
+ }
+ cairo_fill (cr);
+ cairo_restore (cr);
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ size_t i, j, k;
+
+ cairo_set_source_rgb (cr, 0, 1, 0);
+ cairo_paint (cr);
+
+ /* Set an unbounded operator so that we can see how accurate the bounded
+ * extents were.
+ */
+ cairo_set_operator (cr, CAIRO_OPERATOR_IN);
+ cairo_set_source_rgb (cr, 1, 1, 1);
+
+ for (j = 0; j < ARRAY_LENGTH (path_funcs); j++) {
+ cairo_save (cr);
+ for (i = CLIP_OFFSET; i < ARRAY_LENGTH (path_funcs); i++) {
+ for (k = 0; k < TYPES; k++) {
+ cairo_save (cr);
+ cairo_rectangle (cr, 0, 0, SIZE, SIZE);
+ cairo_clip (cr);
+ draw_idx (cr, i, j, k);
+ cairo_restore (cr);
+ cairo_translate (cr, SIZE + PAD, 0);
+ }
+ }
+ cairo_restore (cr);
+ cairo_translate (cr, 0, SIZE + PAD);
+ }
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (tighten_bounds,
+ "Tests that we tighten the bounds after tessellation.",
+ "fill", /* keywords */
+ NULL, /* requirements */
+ IMAGE_WIDTH, IMAGE_HEIGHT,
+ NULL, draw)
diff --git a/test/toy-font-face.c b/test/toy-font-face.c
new file mode 100644
index 000000000..cbebf840a
--- /dev/null
+++ b/test/toy-font-face.c
@@ -0,0 +1,149 @@
+/*
+ * Copyright © 2005,2008 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ * Behdad Esfahbod <behdad@behdad.org>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "cairo-test.h"
+
+#include <cairo.h>
+#include <assert.h>
+#include <string.h>
+
+#if CAIRO_HAS_WIN32_FONT
+#define CAIRO_FONT_FAMILY_DEFAULT "Arial"
+#elif CAIRO_HAS_QUARTZ_FONT
+#define CAIRO_FONT_FAMILY_DEFAULT "Helvetica"
+#elif CAIRO_HAS_FT_FONT
+#define CAIRO_FONT_FAMILY_DEFAULT ""
+#else
+#define CAIRO_FONT_FAMILY_DEFAULT "@cairo:"
+#endif
+
+
+static cairo_test_status_t
+preamble (cairo_test_context_t *ctx)
+{
+ cairo_t *cr;
+ cairo_surface_t *surface;
+ cairo_font_face_t *font_face;
+ cairo_status_t status;
+
+ surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, 0, 0);
+ cr = cairo_create (surface);
+ cairo_surface_destroy (surface);
+
+ font_face = cairo_font_face_reference (cairo_get_font_face (cr));
+ assert (cairo_font_face_get_type (font_face) == CAIRO_FONT_TYPE_TOY);
+ assert (cairo_toy_font_face_get_family (font_face) != NULL);
+ assert (cairo_toy_font_face_get_slant (font_face) == CAIRO_FONT_SLANT_NORMAL);
+ assert (cairo_toy_font_face_get_weight (font_face) == CAIRO_FONT_WEIGHT_NORMAL);
+ status = cairo_font_face_status(font_face);
+ cairo_font_face_destroy (font_face);
+
+ if (status)
+ return cairo_test_status_from_status (ctx, status);
+
+ cairo_select_font_face (cr,
+ "bizarre",
+ CAIRO_FONT_SLANT_OBLIQUE,
+ CAIRO_FONT_WEIGHT_BOLD);
+ font_face = cairo_font_face_reference (cairo_get_font_face (cr));
+ assert (cairo_font_face_get_type (font_face) == CAIRO_FONT_TYPE_TOY);
+ assert (0 == (strcmp) (cairo_toy_font_face_get_family (font_face), "bizarre"));
+ assert (cairo_toy_font_face_get_slant (font_face) == CAIRO_FONT_SLANT_OBLIQUE);
+ assert (cairo_toy_font_face_get_weight (font_face) == CAIRO_FONT_WEIGHT_BOLD);
+ status = cairo_font_face_status(font_face);
+ cairo_font_face_destroy (font_face);
+
+ if (status)
+ return cairo_test_status_from_status (ctx, status);
+
+ font_face = cairo_toy_font_face_create ("bozarre",
+ CAIRO_FONT_SLANT_OBLIQUE,
+ CAIRO_FONT_WEIGHT_BOLD);
+ assert (cairo_font_face_get_type (font_face) == CAIRO_FONT_TYPE_TOY);
+ assert (0 == (strcmp) (cairo_toy_font_face_get_family (font_face), "bozarre"));
+ assert (cairo_toy_font_face_get_slant (font_face) == CAIRO_FONT_SLANT_OBLIQUE);
+ assert (cairo_toy_font_face_get_weight (font_face) == CAIRO_FONT_WEIGHT_BOLD);
+ status = cairo_font_face_status(font_face);
+ cairo_font_face_destroy (font_face);
+
+ if (status)
+ return cairo_test_status_from_status (ctx, status);
+
+ font_face = cairo_toy_font_face_create (NULL,
+ CAIRO_FONT_SLANT_OBLIQUE,
+ CAIRO_FONT_WEIGHT_BOLD);
+ assert (cairo_font_face_get_type (font_face) == CAIRO_FONT_TYPE_TOY);
+ assert (0 == (strcmp) (cairo_toy_font_face_get_family (font_face), CAIRO_FONT_FAMILY_DEFAULT));
+ assert (cairo_toy_font_face_get_slant (font_face) == CAIRO_FONT_SLANT_NORMAL);
+ assert (cairo_toy_font_face_get_weight (font_face) == CAIRO_FONT_WEIGHT_NORMAL);
+ assert (cairo_font_face_status(font_face) == CAIRO_STATUS_NULL_POINTER);
+ cairo_font_face_destroy (font_face);
+
+ font_face = cairo_toy_font_face_create ("\xff",
+ CAIRO_FONT_SLANT_OBLIQUE,
+ CAIRO_FONT_WEIGHT_BOLD);
+ assert (cairo_font_face_get_type (font_face) == CAIRO_FONT_TYPE_TOY);
+ assert (0 == (strcmp) (cairo_toy_font_face_get_family (font_face), CAIRO_FONT_FAMILY_DEFAULT));
+ assert (cairo_toy_font_face_get_slant (font_face) == CAIRO_FONT_SLANT_NORMAL);
+ assert (cairo_toy_font_face_get_weight (font_face) == CAIRO_FONT_WEIGHT_NORMAL);
+ assert (cairo_font_face_status(font_face) == CAIRO_STATUS_INVALID_STRING);
+ cairo_font_face_destroy (font_face);
+
+ font_face = cairo_toy_font_face_create ("sans",
+ -1,
+ CAIRO_FONT_WEIGHT_BOLD);
+ assert (cairo_font_face_get_type (font_face) == CAIRO_FONT_TYPE_TOY);
+ assert (0 == (strcmp) (cairo_toy_font_face_get_family (font_face), CAIRO_FONT_FAMILY_DEFAULT));
+ assert (cairo_toy_font_face_get_slant (font_face) == CAIRO_FONT_SLANT_NORMAL);
+ assert (cairo_toy_font_face_get_weight (font_face) == CAIRO_FONT_WEIGHT_NORMAL);
+ assert (cairo_font_face_status(font_face) == CAIRO_STATUS_INVALID_SLANT);
+ cairo_font_face_destroy (font_face);
+
+ font_face = cairo_toy_font_face_create ("sans",
+ CAIRO_FONT_SLANT_OBLIQUE,
+ -1);
+ assert (cairo_font_face_get_type (font_face) == CAIRO_FONT_TYPE_TOY);
+ assert (0 == (strcmp) (cairo_toy_font_face_get_family (font_face), CAIRO_FONT_FAMILY_DEFAULT));
+ assert (cairo_toy_font_face_get_slant (font_face) == CAIRO_FONT_SLANT_NORMAL);
+ assert (cairo_toy_font_face_get_weight (font_face) == CAIRO_FONT_WEIGHT_NORMAL);
+ assert (cairo_font_face_status(font_face) == CAIRO_STATUS_INVALID_WEIGHT);
+ cairo_font_face_destroy (font_face);
+
+ cairo_destroy (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (toy_font_face,
+ "Check the construction of 'toy' font faces",
+ "font, api", /* keywords */
+ NULL, /* requirements */
+ 0, 0,
+ preamble, NULL)
diff --git a/test/transforms.c b/test/transforms.c
new file mode 100644
index 000000000..17b139687
--- /dev/null
+++ b/test/transforms.c
@@ -0,0 +1,112 @@
+/*
+ * Copyright © 2005 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl Worth <cworth@cworth.org>
+ */
+
+#include "cairo-test.h"
+
+#define WIDTH 45
+#define HEIGHT 30
+
+static void
+draw_L_shape (cairo_t *cr)
+{
+ cairo_move_to (cr, 0, 0);
+ cairo_rel_line_to (cr, 0, 10);
+ cairo_rel_line_to (cr, 5, 0);
+
+ cairo_save (cr);
+ cairo_identity_matrix (cr);
+ cairo_set_line_width (cr, 2.0);
+ cairo_stroke (cr);
+ cairo_restore (cr);
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ /* We draw in the default black, so paint white first. */
+ cairo_save (cr);
+ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */
+ cairo_paint (cr);
+ cairo_restore (cr);
+
+ cairo_translate (cr, 5, 5);
+
+ draw_L_shape (cr);
+
+ cairo_translate (cr, 10, 0);
+
+ cairo_save (cr);
+ {
+ cairo_scale (cr, 2, 2);
+ draw_L_shape (cr);
+ }
+ cairo_restore (cr);
+
+ cairo_translate (cr, 15, 0);
+
+ cairo_save (cr);
+ {
+ cairo_rotate (cr, M_PI / 2.0);
+ draw_L_shape (cr);
+ }
+ cairo_restore (cr);
+
+ cairo_translate (cr, 5, 0);
+
+ cairo_save (cr);
+ {
+ cairo_matrix_t skew_y = {
+ 1, -1,
+ 0, 1,
+ 0, 0
+ };
+ cairo_transform (cr, &skew_y);
+ draw_L_shape (cr);
+ }
+ cairo_restore (cr);
+
+ cairo_translate (cr, 5, 10);
+
+ cairo_save (cr);
+ {
+ cairo_matrix_t skew_x = {
+ 1.0, 0.0,
+ -0.5, 1.0,
+ 0.0, 0.0
+ };
+ cairo_transform (cr, &skew_x);
+ draw_L_shape (cr);
+ }
+ cairo_restore (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (transforms,
+ "Test various transformations.",
+ "transforms, api", /* keywords */
+ NULL, /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw)
diff --git a/test/translate-show-surface.c b/test/translate-show-surface.c
new file mode 100644
index 000000000..9f7af8db2
--- /dev/null
+++ b/test/translate-show-surface.c
@@ -0,0 +1,79 @@
+/*
+ * Copyright © 2005 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+/* Bug history
+ *
+ * 2005-04-11 Carl Worth <cworth@cworth.org>
+ *
+ * It appears that calling cairo_show_surface after cairo_translate
+ * somehow applies the translation twice to the surface being
+ * shown. This is pretty easy to demonstrate by bringing up xsvg on
+ * an SVG file with an <image> and panning around a bit with the
+ * arrow keys.
+ *
+ * This is almost certainly a regression, and I suspect there may be
+ * some interaction with the fix for move-to-show-surface.
+ *
+ * 2005-04-12 Carl Worth <cworth@cworth.org>
+ *
+ * I committed a fix for this bug today.
+ */
+
+#include "cairo-test.h"
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_surface_t *surface;
+ uint32_t colors[4] = {
+ 0xffffffff, 0xffff0000,
+ 0xff00ff00, 0xff0000ff
+ };
+ int i;
+
+ for (i=0; i < 4; i++) {
+ surface = cairo_image_surface_create_for_data ((unsigned char *) &colors[i],
+ CAIRO_FORMAT_RGB24,
+ 1, 1, 4);
+ cairo_save (cr);
+ {
+ cairo_translate (cr, i % 2, i / 2);
+ cairo_set_source_surface (cr, surface, 0, 0);
+ cairo_paint (cr);
+ }
+ cairo_restore (cr);
+ cairo_surface_finish (surface); /* colors will go out of scope */
+ cairo_surface_destroy (surface);
+ }
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (translate_show_surface,
+ "Tests calls to cairo_show_surface after cairo_translate",
+ "transform", /* keywords */
+ NULL, /* requirements */
+ 2, 2,
+ NULL, draw)
diff --git a/test/trap-clip.c b/test/trap-clip.c
new file mode 100644
index 000000000..f1a24ca8d
--- /dev/null
+++ b/test/trap-clip.c
@@ -0,0 +1,213 @@
+/*
+ * Copyright © 2005 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Kristian Høgsberg <krh@redhat.com>
+ */
+
+#include "cairo-test.h"
+#include <math.h>
+#include <stdio.h>
+
+#define WIDTH 16
+#define HEIGHT 16
+#define PAD 2
+
+static const char *png_filename = "romedalen.png";
+static cairo_surface_t *image;
+
+static void
+set_solid_pattern (const cairo_test_context_t *ctx, cairo_t *cr, int x, int y)
+{
+ cairo_set_source_rgb (cr, 0, 0, 0.6);
+}
+
+static void
+set_translucent_pattern (const cairo_test_context_t *ctx, cairo_t *cr, int x, int y)
+{
+ cairo_set_source_rgba (cr, 0, 0, 0.6, 0.5);
+}
+
+static void
+set_gradient_pattern (const cairo_test_context_t *ctx, cairo_t *cr, int x, int y)
+{
+ cairo_pattern_t *pattern;
+
+ pattern =
+ cairo_pattern_create_linear (x, y, x + WIDTH, y + HEIGHT);
+ cairo_pattern_add_color_stop_rgba (pattern, 0, 1, 1, 1, 1);
+ cairo_pattern_add_color_stop_rgba (pattern, 1, 0, 0, 0.4, 1);
+ cairo_set_source (cr, pattern);
+ cairo_pattern_destroy (pattern);
+}
+
+static void
+set_image_pattern (const cairo_test_context_t *ctx, cairo_t *cr, int x, int y)
+{
+ cairo_pattern_t *pattern;
+
+ if (image == NULL || cairo_surface_status (image)) {
+ cairo_surface_destroy (image);
+ image = cairo_test_create_surface_from_png (ctx, png_filename);
+ }
+
+ pattern = cairo_pattern_create_for_surface (image);
+ cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT);
+ cairo_set_source (cr, pattern);
+ cairo_pattern_destroy (pattern);
+}
+
+static void
+draw_rect (cairo_t *cr, int x, int y)
+{
+ cairo_new_path (cr);
+ cairo_rectangle (cr, x, y, WIDTH, HEIGHT);
+ cairo_fill (cr);
+}
+
+static void
+draw_rects (cairo_t *cr, int x, int y)
+{
+ int width = WIDTH / 3;
+ int height = HEIGHT / 2;
+
+ cairo_new_path (cr);
+ cairo_rectangle (cr, x, y, width, height);
+ cairo_rectangle (cr, x + width, y + height, width, height);
+ cairo_rectangle (cr, x + 2 * width, y, width, height);
+ cairo_fill (cr);
+}
+
+static void
+draw_polygon (cairo_t *cr, int x, int y)
+{
+ cairo_new_path (cr);
+ cairo_move_to (cr, x, y);
+ cairo_line_to (cr, x, y + HEIGHT);
+ cairo_line_to (cr, x + WIDTH / 2, y + 3 * HEIGHT / 4);
+ cairo_line_to (cr, x + WIDTH, y + HEIGHT);
+ cairo_line_to (cr, x + WIDTH, y);
+ cairo_line_to (cr, x + WIDTH / 2, y + HEIGHT / 4);
+ cairo_close_path (cr);
+ cairo_fill (cr);
+}
+
+static void
+clip_none (cairo_t *cr, int x, int y)
+{
+}
+
+static void
+clip_rect (cairo_t *cr, int x, int y)
+{
+ cairo_new_path (cr);
+ cairo_rectangle (cr, x + (int)WIDTH / 6, y + (int)HEIGHT / 6,
+ 4 * ((int)WIDTH / 6), 4 * ((int)WIDTH / 6));
+ cairo_clip (cr);
+ cairo_new_path (cr);
+}
+
+static void
+clip_rects (cairo_t *cr, int x, int y)
+{
+ int height = HEIGHT / 3;
+
+ cairo_new_path (cr);
+ cairo_rectangle (cr, x, y, WIDTH, height);
+ cairo_rectangle (cr, x, y + 2 * height, WIDTH, height);
+ cairo_clip (cr);
+ cairo_new_path (cr);
+}
+
+static void
+clip_circle (cairo_t *cr, int x, int y)
+{
+ cairo_new_path (cr);
+ cairo_arc (cr, x + WIDTH / 2, y + HEIGHT / 2,
+ WIDTH / 3, 0, 2 * M_PI);
+ cairo_clip (cr);
+ cairo_new_path (cr);
+}
+
+static void (* const pattern_funcs[])(const cairo_test_context_t *ctx, cairo_t *cr, int x, int y) = {
+ set_solid_pattern,
+ set_translucent_pattern,
+ set_gradient_pattern,
+ set_image_pattern,
+};
+
+static void (* const draw_funcs[])(cairo_t *cr, int x, int y) = {
+ draw_rect,
+ draw_rects,
+ draw_polygon,
+};
+
+static void (* const clip_funcs[])(cairo_t *cr, int x, int y) = {
+ clip_none,
+ clip_rect,
+ clip_rects,
+ clip_circle,
+};
+
+#define IMAGE_WIDTH (ARRAY_LENGTH (pattern_funcs) * (WIDTH + PAD) + PAD)
+#define IMAGE_HEIGHT (ARRAY_LENGTH (draw_funcs) * ARRAY_LENGTH (clip_funcs) * (HEIGHT + PAD) + PAD)
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ const cairo_test_context_t *ctx = cairo_test_get_context (cr);
+ size_t i, j, k, x, y;
+
+ for (k = 0; k < ARRAY_LENGTH (clip_funcs); k++) {
+ for (j = 0; j < ARRAY_LENGTH (draw_funcs); j++) {
+ for (i = 0; i < ARRAY_LENGTH (pattern_funcs); i++) {
+ x = i * (WIDTH + PAD) + PAD;
+ y = (ARRAY_LENGTH (draw_funcs) * k + j) * (HEIGHT + PAD) + PAD;
+
+ cairo_save (cr);
+
+ cairo_move_to (cr, x, y);
+ clip_funcs[k] (cr, x, y);
+ pattern_funcs[i] (ctx, cr, x, y);
+ draw_funcs[j] (cr, x, y);
+ if (cairo_status (cr))
+ cairo_test_log (ctx, "%d %d HERE!\n", (int)i, (int)j);
+
+ cairo_restore (cr);
+ }
+ }
+ }
+
+ if (cairo_status (cr) != CAIRO_STATUS_SUCCESS)
+ cairo_test_log (ctx, "%d %d .HERE!\n", (int)i, (int)j);
+
+ cairo_surface_destroy (image);
+ image = NULL;
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (trap_clip,
+ "Trapezoid clipping",
+ "clip, trap", /* keywords */
+ NULL, /* requirements */
+ IMAGE_WIDTH, IMAGE_HEIGHT,
+ NULL, draw)
diff --git a/test/twin-antialias-gray.c b/test/twin-antialias-gray.c
new file mode 100644
index 000000000..8e00370b0
--- /dev/null
+++ b/test/twin-antialias-gray.c
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2008 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Chris Wilson not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Chris Wilson makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_font_options_t *options;
+
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+ cairo_set_source_rgb (cr, 0, 0, 0);
+
+ cairo_set_antialias (cr, CAIRO_ANTIALIAS_GRAY);
+
+ cairo_select_font_face (cr,
+ "@cairo:",
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_NORMAL);
+
+ options = cairo_font_options_create ();
+ cairo_font_options_set_antialias (options, CAIRO_ANTIALIAS_GRAY);
+ cairo_set_font_options (cr, options);
+ cairo_font_options_destroy (options);
+
+ cairo_set_font_size (cr, 16);
+
+ cairo_move_to (cr, 4, 14);
+ cairo_show_text (cr, "Is cairo's twin giza?");
+
+ cairo_move_to (cr, 4, 34);
+ cairo_text_path (cr, "Is cairo's twin giza?");
+ cairo_fill (cr);
+
+ cairo_move_to (cr, 4, 54);
+ cairo_text_path (cr, "Is cairo's twin giza?");
+ cairo_set_line_width (cr, 2/16.);
+ cairo_stroke (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (twin_antialias_gray,
+ "Tests the internal font (with antialiasing reduced)",
+ "twin, font", /* keywords */
+ "target=raster", /* requirements */
+ 140, 60,
+ NULL, draw)
diff --git a/test/twin-antialias-mixed.c b/test/twin-antialias-mixed.c
new file mode 100644
index 000000000..da4121a1d
--- /dev/null
+++ b/test/twin-antialias-mixed.c
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2009 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Chris Wilson not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Chris Wilson makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+static cairo_scaled_font_t *
+create_twin (cairo_t *cr, cairo_antialias_t antialias)
+{
+ cairo_font_options_t *options;
+
+ cairo_select_font_face (cr,
+ "@cairo:",
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_NORMAL);
+
+ options = cairo_font_options_create ();
+ cairo_font_options_set_antialias (options, antialias);
+ cairo_set_font_options (cr, options);
+ cairo_font_options_destroy (options);
+
+ return cairo_scaled_font_reference (cairo_get_scaled_font (cr));
+}
+
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_scaled_font_t *subpixel, *gray, *none;
+
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+ cairo_set_source_rgb (cr, 0, 0, 0);
+
+ cairo_set_font_size (cr, 16);
+ subpixel = create_twin (cr, CAIRO_ANTIALIAS_SUBPIXEL);
+ gray = create_twin (cr, CAIRO_ANTIALIAS_GRAY);
+ none = create_twin (cr, CAIRO_ANTIALIAS_NONE);
+
+ cairo_move_to (cr, 4, 14);
+ cairo_set_scaled_font (cr, subpixel);
+ cairo_show_text (cr, "Is cairo's");
+ cairo_set_scaled_font (cr, gray);
+ cairo_show_text (cr, " twin");
+ cairo_set_scaled_font (cr, none);
+ cairo_show_text (cr, " giza?");
+
+ cairo_move_to (cr, 4, 34);
+ cairo_set_scaled_font (cr, gray);
+ cairo_show_text (cr, "Is cairo's");
+ cairo_set_scaled_font (cr, none);
+ cairo_show_text (cr, " twin");
+ cairo_set_scaled_font (cr, subpixel);
+ cairo_show_text (cr, " giza?");
+
+ cairo_move_to (cr, 4, 54);
+ cairo_set_scaled_font (cr, none);
+ cairo_show_text (cr, "Is cairo's");
+ cairo_set_scaled_font (cr, gray);
+ cairo_show_text (cr, " twin");
+ cairo_set_scaled_font (cr, subpixel);
+ cairo_show_text (cr, " giza?");
+
+ cairo_scaled_font_destroy (none);
+ cairo_scaled_font_destroy (gray);
+ cairo_scaled_font_destroy (subpixel);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (twin_antialias_mixed,
+ "Tests the internal font (with intermixed antialiasing)",
+ "twin, font", /* keywords */
+ "target=raster", /* requirements */
+ 140, 60,
+ NULL, draw)
diff --git a/test/twin-antialias-none.c b/test/twin-antialias-none.c
new file mode 100644
index 000000000..a5b713db3
--- /dev/null
+++ b/test/twin-antialias-none.c
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2008 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Chris Wilson not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Chris Wilson makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_font_options_t *options;
+
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+ cairo_set_source_rgb (cr, 0, 0, 0);
+
+ cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE);
+
+ cairo_select_font_face (cr,
+ "@cairo:",
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_NORMAL);
+
+ options = cairo_font_options_create ();
+ cairo_font_options_set_antialias (options, CAIRO_ANTIALIAS_NONE);
+ cairo_set_font_options (cr, options);
+ cairo_font_options_destroy (options);
+
+ cairo_set_font_size (cr, 16);
+
+ cairo_move_to (cr, 4, 14);
+ cairo_show_text (cr, "Is cairo's twin giza?");
+
+ cairo_move_to (cr, 4, 34);
+ cairo_text_path (cr, "Is cairo's twin giza?");
+ cairo_fill (cr);
+
+ cairo_move_to (cr, 4, 54);
+ cairo_text_path (cr, "Is cairo's twin giza?");
+ cairo_set_line_width (cr, 2/16.);
+ cairo_stroke (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (twin_antialias_none,
+ "Tests the internal font (with antialiasing disabled)",
+ "twin, font", /* keywords */
+ "target=raster", /* requirements */
+ 140, 60,
+ NULL, draw)
diff --git a/test/twin-antialias-subpixel.c b/test/twin-antialias-subpixel.c
new file mode 100644
index 000000000..e0262863c
--- /dev/null
+++ b/test/twin-antialias-subpixel.c
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2008 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Chris Wilson not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Chris Wilson makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_font_options_t *options;
+
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+ cairo_set_source_rgb (cr, 0, 0, 0);
+
+ cairo_set_antialias (cr, CAIRO_ANTIALIAS_SUBPIXEL);
+
+ cairo_select_font_face (cr,
+ "@cairo:",
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_NORMAL);
+
+ options = cairo_font_options_create ();
+ cairo_font_options_set_antialias (options, CAIRO_ANTIALIAS_SUBPIXEL);
+ cairo_set_font_options (cr, options);
+ cairo_font_options_destroy (options);
+
+ cairo_set_font_size (cr, 16);
+
+ cairo_move_to (cr, 4, 14);
+ cairo_show_text (cr, "Is cairo's twin giza?");
+
+ cairo_move_to (cr, 4, 34);
+ cairo_text_path (cr, "Is cairo's twin giza?");
+ cairo_fill (cr);
+
+ cairo_move_to (cr, 4, 54);
+ cairo_text_path (cr, "Is cairo's twin giza?");
+ cairo_set_line_width (cr, 2/16.);
+ cairo_stroke (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (twin_antialias_subpixel,
+ "Tests the internal font (with subpixel antialiasing)",
+ "twin, font", /* keywords */
+ "target=raster", /* requirements */
+ 140, 60,
+ NULL, draw)
diff --git a/test/twin.c b/test/twin.c
new file mode 100644
index 000000000..08865f077
--- /dev/null
+++ b/test/twin.c
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2008 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Chris Wilson not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Chris Wilson makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+ cairo_set_source_rgb (cr, 0, 0, 0);
+
+ cairo_select_font_face (cr,
+ "@cairo:",
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_NORMAL);
+ cairo_set_font_size (cr, 16);
+
+ cairo_move_to (cr, 4, 14);
+ cairo_show_text (cr, "Is cairo's twin giza?");
+
+ cairo_move_to (cr, 4, 34);
+ cairo_text_path (cr, "Is cairo's twin giza?");
+ cairo_fill (cr);
+
+ cairo_move_to (cr, 4, 54);
+ cairo_text_path (cr, "Is cairo's twin giza?");
+ cairo_set_line_width (cr, 2/16.);
+ cairo_stroke (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (twin,
+ "Tests the internal font",
+ "twin, font", /* keywords */
+ NULL, /* requirements */
+ 140, 60,
+ NULL, draw)
diff --git a/test/unaligned-box.c b/test/unaligned-box.c
new file mode 100644
index 000000000..552691934
--- /dev/null
+++ b/test/unaligned-box.c
@@ -0,0 +1,73 @@
+/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */
+/*
+ * Copyright 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+#define WIDTH 48
+#define HEIGHT 52
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ int sx, sy;
+
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+ cairo_set_source_rgb (cr, 0, 0, 0);
+
+ cairo_translate(cr, 2, 2);
+
+ for (sx = 1; sx <= 4; sx++) {
+ cairo_save (cr);
+ for (sy = 1; sy <= 4; sy++) {
+ cairo_rectangle (cr, 0, 0, sx, sy);
+ cairo_fill (cr);
+
+ cairo_rectangle (cr, sx + 1 + .5, 0, sx, sy);
+ cairo_fill (cr);
+
+ cairo_rectangle (cr, 0, sy + 1 + .5, sx, sy);
+ cairo_fill (cr);
+
+ cairo_rectangle (cr, sx + 1 + .5, sy + 1 + .5, sx-.5, sy-.5);
+ cairo_fill (cr);
+
+ cairo_translate (cr, 2*sx + 3, 0);
+ }
+ cairo_restore (cr);
+ cairo_translate (cr, 0, 2*sy + 3);
+ }
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (unaligned_box,
+ "Tests handling of various boundary conditions for unaligned rectangles.",
+ "fill", /* keywords */
+ NULL, /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw)
diff --git a/test/unantialiased-shapes.c b/test/unantialiased-shapes.c
new file mode 100644
index 000000000..b53ed0d6e
--- /dev/null
+++ b/test/unantialiased-shapes.c
@@ -0,0 +1,98 @@
+/*
+ * Copyright © 2005 Billy Biggs
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Billy Biggs not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Billy Biggs makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * BILLY BIGGS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL BILLY BIGGS BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Billy Biggs <vektor@dumbterm.net>
+ */
+
+#include "cairo-test.h"
+
+/* The star shape from the SVG test suite, from the fill rule test */
+static void
+big_star_path (cairo_t *cr)
+{
+ cairo_move_to (cr, 40, 0);
+ cairo_rel_line_to (cr, 25, 80);
+ cairo_rel_line_to (cr, -65, -50);
+ cairo_rel_line_to (cr, 80, 0);
+ cairo_rel_line_to (cr, -65, 50);
+ cairo_close_path (cr);
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ int i;
+
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ cairo_paint (cr);
+
+ cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE);
+
+ /* Try a circle */
+ cairo_arc (cr, 40, 40, 20, 0, 2 * M_PI);
+ cairo_set_source_rgb (cr, 1, 0, 0);
+ cairo_fill (cr);
+
+ /* Try using clipping to draw a circle */
+ cairo_arc (cr, 100, 40, 20, 0, 2 * M_PI);
+ cairo_clip (cr);
+ cairo_rectangle (cr, 80, 20, 40, 40);
+ cairo_set_source_rgb (cr, 0, 0, 1);
+ cairo_fill (cr);
+
+ /* Reset the clipping */
+ cairo_reset_clip (cr);
+
+ /* Draw a bunch of lines */
+ cairo_set_line_width (cr, 1.0);
+ cairo_set_source_rgb (cr, 0, 1, 0);
+ for (i = 0; i < 10; i++) {
+ cairo_move_to (cr, 10, 70 + (i * 4));
+ cairo_line_to (cr, 120, 70 + (i * 18));
+ cairo_stroke (cr);
+ }
+
+ /* Try filling a poly */
+ cairo_translate (cr, 160, 120);
+ cairo_set_source_rgb (cr, 1, 1, 0);
+ big_star_path (cr);
+ cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
+ cairo_fill (cr);
+ cairo_translate (cr, -160, -120);
+
+ /* How about some curves? */
+ cairo_set_source_rgb (cr, 1, 0, 1);
+ for (i = 0; i < 10; i++) {
+ cairo_move_to (cr, 150, 50 + (i * 5));
+ cairo_curve_to (cr, 250, 50, 200, (i * 10), 300, 50 + (i * 10));
+ cairo_stroke (cr);
+ }
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (unantialiased_shapes,
+ "Test shape drawing without antialiasing",
+ "fill, stroke", /* keywords */
+ "target=raster", /* requirements */
+ 320, 240,
+ NULL, draw)
diff --git a/test/unbounded-operator.c b/test/unbounded-operator.c
new file mode 100644
index 000000000..ac1c50d1d
--- /dev/null
+++ b/test/unbounded-operator.c
@@ -0,0 +1,185 @@
+/*
+ * Copyright © 2005 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Kristian Høgsberg <krh@redhat.com>
+ * Owen Taylor <otaylor@redhat.com>
+ */
+
+#include "cairo-test.h"
+#include <math.h>
+#include <stdio.h>
+
+#define WIDTH 16
+#define HEIGHT 16
+#define PAD 2
+
+static void
+draw_mask (cairo_t *cr, int x, int y)
+{
+ cairo_surface_t *mask_surface;
+ cairo_t *cr2;
+
+ double width = (int)(0.9 * WIDTH);
+ double height = (int)(0.9 * HEIGHT);
+ x += 0.05 * WIDTH;
+ y += 0.05 * HEIGHT;
+
+ mask_surface = cairo_surface_create_similar (cairo_get_group_target (cr),
+ CAIRO_CONTENT_ALPHA,
+ width, height);
+ cr2 = cairo_create (mask_surface);
+ cairo_surface_destroy (mask_surface);
+
+ cairo_save (cr2);
+ cairo_set_source_rgba (cr2, 0, 0, 0, 0); /* transparent */
+ cairo_set_operator (cr2, CAIRO_OPERATOR_SOURCE);
+ cairo_paint (cr2);
+ cairo_restore (cr2);
+
+ cairo_set_source_rgb (cr2, 1, 1, 1); /* white */
+
+ cairo_arc (cr2, 0.5 * width, 0.5 * height, 0.45 * height, 0, 2 * M_PI);
+ cairo_fill (cr2);
+
+ cairo_mask_surface (cr, cairo_get_target (cr2), x, y);
+ cairo_destroy (cr2);
+}
+
+static void
+draw_glyphs (cairo_t *cr, int x, int y)
+{
+ cairo_text_extents_t extents;
+
+ cairo_set_font_size (cr, 0.8 * HEIGHT);
+
+ cairo_text_extents (cr, "FG", &extents);
+ cairo_move_to (cr,
+ x + floor ((WIDTH - extents.width) / 2 + 0.5) - extents.x_bearing,
+ y + floor ((HEIGHT - extents.height) / 2 + 0.5) - extents.y_bearing);
+ cairo_show_text (cr, "FG");
+}
+
+static void
+draw_polygon (cairo_t *cr, int x, int y)
+{
+ double width = (int)(0.9 * WIDTH);
+ double height = (int)(0.9 * HEIGHT);
+ x += 0.05 * WIDTH;
+ y += 0.05 * HEIGHT;
+
+ cairo_new_path (cr);
+ cairo_move_to (cr, x, y);
+ cairo_line_to (cr, x, y + height);
+ cairo_line_to (cr, x + width / 2, y + 3 * height / 4);
+ cairo_line_to (cr, x + width, y + height);
+ cairo_line_to (cr, x + width, y);
+ cairo_line_to (cr, x + width / 2, y + height / 4);
+ cairo_close_path (cr);
+ cairo_fill (cr);
+}
+
+static void
+draw_rects (cairo_t *cr, int x, int y)
+{
+ double block_width = (int)(0.33 * WIDTH + 0.5);
+ double block_height = (int)(0.33 * HEIGHT + 0.5);
+ int i, j;
+
+ for (i = 0; i < 3; i++)
+ for (j = 0; j < 3; j++)
+ if ((i + j) % 2 == 0)
+ cairo_rectangle (cr,
+ x + block_width * i, y + block_height * j,
+ block_width, block_height);
+
+ cairo_fill (cr);
+}
+
+static void (*const draw_funcs[])(cairo_t *cr, int x, int y) = {
+ draw_mask,
+ draw_glyphs,
+ draw_polygon,
+ draw_rects
+};
+
+static cairo_operator_t operators[] = {
+ CAIRO_OPERATOR_IN, CAIRO_OPERATOR_OUT,
+ CAIRO_OPERATOR_DEST_IN, CAIRO_OPERATOR_DEST_ATOP
+};
+
+#define IMAGE_WIDTH (ARRAY_LENGTH (operators) * (WIDTH + PAD) + PAD)
+#define IMAGE_HEIGHT (ARRAY_LENGTH (draw_funcs) * (HEIGHT + PAD) + PAD)
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ const cairo_test_context_t *ctx = cairo_test_get_context (cr);
+ size_t i, j, x, y;
+ cairo_pattern_t *pattern;
+
+ cairo_select_font_face (cr, CAIRO_TEST_FONT_FAMILY " Sans",
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_NORMAL);
+
+ for (j = 0; j < ARRAY_LENGTH (draw_funcs); j++) {
+ for (i = 0; i < ARRAY_LENGTH (operators); i++) {
+ x = i * (WIDTH + PAD) + PAD;
+ y = j * (HEIGHT + PAD) + PAD;
+
+ cairo_save (cr);
+
+ pattern = cairo_pattern_create_linear (x + WIDTH, y,
+ x, y + HEIGHT);
+ cairo_pattern_add_color_stop_rgba (pattern, 0.2,
+ 0.0, 0.0, 1.0, 1.0); /* Solid blue */
+ cairo_pattern_add_color_stop_rgba (pattern, 0.8,
+ 0.0, 0.0, 1.0, 0.0); /* Transparent blue */
+ cairo_set_source (cr, pattern);
+ cairo_pattern_destroy (pattern);
+
+ cairo_rectangle (cr, x, y, WIDTH, HEIGHT);
+ cairo_fill_preserve (cr);
+ cairo_clip (cr);
+
+ cairo_set_operator (cr, operators[i]);
+ cairo_set_source_rgb (cr, 1.0, 0.0, 0.0);
+
+ draw_funcs[j] (cr, x, y);
+ if (cairo_status (cr))
+ cairo_test_log (ctx, "%d %d HERE!\n", (int)i, (int)j);
+
+ cairo_restore (cr);
+ }
+ }
+
+ if (cairo_status (cr) != CAIRO_STATUS_SUCCESS)
+ cairo_test_log (ctx, "%d %d .HERE!\n", (int)i, (int)j);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (unbounded_operator,
+ "Operators with an effect for transparent source/mask",
+ "operator", /* keywords */
+ NULL, /* requirements */
+ IMAGE_WIDTH, IMAGE_HEIGHT,
+ NULL, draw)
diff --git a/test/unclosed-strokes.c b/test/unclosed-strokes.c
new file mode 100644
index 000000000..40a76eb6b
--- /dev/null
+++ b/test/unclosed-strokes.c
@@ -0,0 +1,83 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+#define LINE_WIDTH 10.
+#define SIZE (5 * LINE_WIDTH)
+#define PAD (2 * LINE_WIDTH)
+
+static void
+make_path (cairo_t *cr)
+{
+ cairo_move_to (cr, 0, 0);
+ cairo_rel_line_to (cr, -SIZE/2, SIZE);
+ cairo_rel_line_to (cr, SIZE, 0);
+ /* back to the start, but do not close */
+ cairo_rel_line_to (cr, -SIZE/2, -SIZE);
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_save (cr);
+ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */
+ cairo_paint (cr);
+ cairo_restore (cr);
+
+ cairo_set_line_width (cr, LINE_WIDTH);
+ cairo_translate (cr, PAD + SIZE / 2., PAD);
+
+ cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT);
+ cairo_set_line_join (cr, CAIRO_LINE_JOIN_BEVEL);
+ make_path (cr);
+ cairo_stroke (cr);
+
+ cairo_translate (cr, 0, SIZE + PAD);
+
+ cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
+ cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND);
+ make_path (cr);
+ cairo_stroke (cr);
+
+ cairo_translate (cr, 0, SIZE + PAD);
+
+ cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE);
+ cairo_set_line_join (cr, CAIRO_LINE_JOIN_MITER);
+ make_path (cr);
+ cairo_stroke (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (unclosed_strokes,
+ "Test coincident end-points are capped and not joined",
+ "stroke, caps", /* keywords */
+ NULL, /* requirements */
+ PAD + SIZE + PAD,
+ 3 * (PAD + SIZE) + PAD,
+ NULL, draw)
+
diff --git a/test/update-refs.sh b/test/update-refs.sh
new file mode 100755
index 000000000..104eeb8d9
--- /dev/null
+++ b/test/update-refs.sh
@@ -0,0 +1,84 @@
+#!/bin/bash
+
+# This script can be used to update the reference images using certain
+# test results as a baseline.
+#
+# Our test suite expects nearly pixel-perfection, but in some cases we
+# give the renderer some flexibility and so these cases will show up as
+# test failures. So, this script can be used to do a visual check and
+# if they "look" ok, to go ahead and update the reference image by
+# copying the test output.
+#
+# NOTE: When adding to this file, make sure to thoroughly document the
+# rationale when and why the existing reference images can be updated
+# from regular test output, such that people other than you can
+# intelligently keep the test reference images updated.
+
+if [ ! -d output ] || [ ! -d reference ]; then
+ echo "This script must be run in cairo's test directory after the full testsuite has been run."
+ exit
+fi
+
+PDIFF="./pdiff/perceptualdiff"
+
+# Returns 1 if images are different, 0 if they're essentially identical
+images_differ() {
+ # Check if bytewise identical
+ if cmp --silent "${1}" "${2}"; then
+ # Images are identical
+ return 0
+ fi
+
+ # Run perceptualdiff with minimum threshold
+ pdiff_output=$($PDIFF "${1}" "${2}" -threshold 1)
+ result=${pdiff_output%:*}
+ notes=$(echo "${pdiff_output#*: }" | tail -n 1)
+ if [ "$result" = "PASS" ] && [ "$notes" = "Images are binary identical" ]; then
+ return 0
+ fi
+
+ return 1
+}
+
+# ----------------------------------------------------------------------
+# pixman-downscale images
+#
+# The *-95 tests check rendering at a difficult to downsize dimension.
+# The border pixels between different colored areas can be blurred in
+# different ways resulting in some color variation that is acceptable
+# but throws off the testsuite. So a visual check is sufficient to
+# verify the results aren't crazily off.
+
+# Use the ARGB32 format of the image file as the main reference
+for file in $(ls ./output/pixman-downscale-*-95.image.argb32.out.png); do
+ dest=$(basename ${file/.image.argb32.out./.ref.})
+ echo "$file -> ./reference/${dest}"
+ cp $file ./reference/${dest}
+done
+echo
+
+# If the ARGB32 format of a given backend's file differs from the main reference,
+# then use it as the backend reference
+for file in $(ls ./output/pixman-downscale-*-95.*.argb32.out.png); do
+ ref=$(basename ${file/-95.*.argb32.out.png/-95.ref.png})
+ if ! images_differ "./reference/${ref}" "${file}"; then
+ dest=$(basename ${file/.argb32.out.png/.ref.png})
+ echo "${file} -> ./reference/${dest}"
+ cp ${file} ./reference/${dest}
+ fi
+done
+echo
+
+# If the RGB24 format differs from existing ref image, then use it as a ref.
+for file in $(ls ./output/pixman-downscale-*-95.*.rgb24.out.png); do
+ ref=$(basename ${file/.rgb24.out.png/.ref.png})
+ if [ ! -e "./reference/${ref}" ]; then
+ ref=$(basename ${file/-95.*.rgb24.out.png/-95.ref.png})
+ fi
+
+ if ! images_differ "./reference/${ref}" "${file}"; then
+ dest=$(basename ${file/.rgb24.out.png/.rgb24.ref.png})
+ echo "${file} -> ./reference/${dest}"
+ cp ${file} ./reference/${dest}
+ fi
+done
diff --git a/test/user-data.c b/test/user-data.c
new file mode 100644
index 000000000..532107aa2
--- /dev/null
+++ b/test/user-data.c
@@ -0,0 +1,110 @@
+/*
+ * Copyright © 2005 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Kristian Høgsberg <krh@redhat.com>
+ */
+
+#include "cairo-test.h"
+
+#include <assert.h>
+
+static void
+destroy_data1 (void *p)
+{
+ *(int *) p = 1;
+}
+
+static void
+destroy_data2 (void *p)
+{
+ *(int *) p = 2;
+}
+
+static cairo_test_status_t
+preamble (cairo_test_context_t *ctx)
+{
+ static const cairo_user_data_key_t key1, key2;
+ cairo_surface_t *surface;
+ cairo_status_t status;
+ int data1, data2;
+
+ data1 = 0;
+ data2 = 0;
+
+ surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 1, 1);
+ status = cairo_surface_set_user_data (surface, &key1, &data1, destroy_data1);
+ if (status)
+ goto error;
+
+ status = cairo_surface_set_user_data (surface, &key2, &data2, destroy_data2);
+ if (status)
+ goto error;
+
+ assert (cairo_surface_get_user_data (surface, &key1) == &data1);
+ status = cairo_surface_set_user_data (surface, &key1, NULL, NULL);
+ if (status)
+ goto error;
+
+ assert (cairo_surface_get_user_data (surface, &key1) == NULL);
+ assert (data1 == 1);
+ assert (data2 == 0);
+
+ status = cairo_surface_set_user_data (surface, &key2, NULL, NULL);
+ if (status)
+ goto error;
+
+ assert (data2 == 2);
+
+ data1 = 0;
+ status = cairo_surface_set_user_data (surface, &key1, &data1, NULL);
+ if (status)
+ goto error;
+
+ status = cairo_surface_set_user_data (surface, &key1, NULL, NULL);
+ if (status)
+ goto error;
+
+ assert (data1 == 0);
+ assert (cairo_surface_get_user_data (surface, &key1) == NULL);
+
+ status = cairo_surface_set_user_data (surface, &key1, &data1, destroy_data1);
+ if (status)
+ goto error;
+
+ cairo_surface_destroy (surface);
+
+ assert (data1 == 1);
+ assert (data2 == 2);
+
+ return CAIRO_TEST_SUCCESS;
+
+error:
+ cairo_surface_destroy (surface);
+ return cairo_test_status_from_status (ctx, status);
+}
+
+CAIRO_TEST (user_data,
+ "Test setting and getting random bits of user data.",
+ "api", /* keywords */
+ NULL, /* requirements */
+ 0, 0,
+ preamble, NULL)
diff --git a/test/user-font-mask.c b/test/user-font-mask.c
new file mode 100644
index 000000000..cf548e649
--- /dev/null
+++ b/test/user-font-mask.c
@@ -0,0 +1,253 @@
+/*
+ * Copyright © 2006, 2008 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Contributor(s):
+ * Kristian Høgsberg <krh@redhat.com>
+ * Behdad Esfahbod <behdad@behdad.org>
+ * Adrian Johnson <ajohnson@redneon.com>
+ */
+
+#include "cairo-test.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+
+/*#define ROTATED 1*/
+
+#define BORDER 10
+#define TEXT_SIZE 64
+#define WIDTH (TEXT_SIZE * 15 + 2*BORDER)
+#ifndef ROTATED
+ #define HEIGHT ((TEXT_SIZE + 2*BORDER)*2)
+#else
+ #define HEIGHT WIDTH
+#endif
+#define END_GLYPH 0
+#define TEXT "cairo"
+
+/* Reverse the bits in a byte with 7 operations (no 64-bit):
+ * Devised by Sean Anderson, July 13, 2001.
+ * Source: http://graphics.stanford.edu/~seander/bithacks.html#ReverseByteWith32Bits
+ */
+#define CAIRO_BITSWAP8(c) ((((c) * 0x0802LU & 0x22110LU) | ((c) * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16)
+
+#ifdef WORDS_BIGENDIAN
+#define CAIRO_BITSWAP8_IF_LITTLE_ENDIAN(c) (c)
+#else
+#define CAIRO_BITSWAP8_IF_LITTLE_ENDIAN(c) CAIRO_BITSWAP8(c)
+#endif
+
+
+
+/* Simple glyph definition. data is an 8x8 bitmap.
+ */
+typedef struct {
+ unsigned long ucs4;
+ int width;
+ char data[8];
+} test_scaled_font_glyph_t;
+
+static cairo_user_data_key_t test_font_face_glyphs_key;
+
+static cairo_status_t
+test_scaled_font_init (cairo_scaled_font_t *scaled_font,
+ cairo_t *cr,
+ cairo_font_extents_t *metrics)
+{
+ metrics->ascent = 1;
+ metrics->descent = 0;
+ return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_status_t
+test_scaled_font_unicode_to_glyph (cairo_scaled_font_t *scaled_font,
+ unsigned long unicode,
+ unsigned long *glyph)
+{
+ test_scaled_font_glyph_t *glyphs = cairo_font_face_get_user_data (cairo_scaled_font_get_font_face (scaled_font),
+ &test_font_face_glyphs_key);
+ int i;
+
+ for (i = 0; glyphs[i].ucs4 != (unsigned long) -1; i++)
+ if (glyphs[i].ucs4 == unicode) {
+ *glyph = i;
+ return CAIRO_STATUS_SUCCESS;
+ }
+
+ /* Not found. Default to glyph 0 */
+ return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_status_t
+test_scaled_font_render_glyph (cairo_scaled_font_t *scaled_font,
+ unsigned long glyph,
+ cairo_t *cr,
+ cairo_text_extents_t *metrics)
+{
+ test_scaled_font_glyph_t *glyphs = cairo_font_face_get_user_data (cairo_scaled_font_get_font_face (scaled_font),
+ &test_font_face_glyphs_key);
+ int i;
+ unsigned char *data;
+ cairo_surface_t *image;
+ cairo_pattern_t *pattern;
+ cairo_matrix_t matrix;
+ uint8_t byte;
+
+ /* FIXME: We simply crash on out-of-bound glyph indices */
+
+ metrics->x_advance = (glyphs[glyph].width + 1) / 8.0;
+
+ image = cairo_image_surface_create (CAIRO_FORMAT_A1, glyphs[glyph].width, 8);
+ if (cairo_surface_status (image))
+ return cairo_surface_status (image);
+
+ data = cairo_image_surface_get_data (image);
+ for (i = 0; i < 8; i++) {
+ byte = glyphs[glyph].data[i];
+ *data = CAIRO_BITSWAP8_IF_LITTLE_ENDIAN (byte);
+ data += cairo_image_surface_get_stride (image);
+ }
+ cairo_surface_mark_dirty (image);
+
+ pattern = cairo_pattern_create_for_surface (image);
+ cairo_surface_destroy (image);
+
+ cairo_matrix_init_identity (&matrix);
+ cairo_matrix_scale (&matrix, 1.0/8.0, 1.0/8.0);
+ cairo_matrix_translate (&matrix, 0, -8);
+ cairo_matrix_invert (&matrix);
+ cairo_pattern_set_matrix (pattern, &matrix);
+
+ cairo_set_source (cr, pattern);
+ cairo_mask (cr, pattern);
+ cairo_pattern_destroy (pattern);
+
+ return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_status_t
+_user_font_face_create (cairo_font_face_t **out)
+{
+ static const test_scaled_font_glyph_t glyphs [] = {
+ { 'c', 6, { 0x00, 0x38, 0x44, 0x80, 0x80, 0x80, 0x44, 0x38 } },
+ { 'a', 6, { 0x00, 0x70, 0x88, 0x3c, 0x44, 0x84, 0x8c, 0x74 } },
+ { 'i', 1, { 0x80, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 } },
+ { 'r', 6, { 0x00, 0xb8, 0xc4, 0x80, 0x80, 0x80, 0x80, 0x80 } },
+ { 'o', 7, { 0x00, 0x38, 0x44, 0x82, 0x82, 0x82, 0x44, 0x38 } },
+ { -1, 8, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
+ };
+
+ cairo_font_face_t *user_font_face;
+ cairo_status_t status;
+
+ user_font_face = cairo_user_font_face_create ();
+ cairo_user_font_face_set_init_func (user_font_face, test_scaled_font_init);
+ cairo_user_font_face_set_render_glyph_func (user_font_face, test_scaled_font_render_glyph);
+ cairo_user_font_face_set_unicode_to_glyph_func (user_font_face, test_scaled_font_unicode_to_glyph);
+
+ status = cairo_font_face_set_user_data (user_font_face,
+ &test_font_face_glyphs_key,
+ (void*) glyphs, NULL);
+ if (status) {
+ cairo_font_face_destroy (user_font_face);
+ return status;
+ }
+
+ *out = user_font_face;
+ return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_font_face_t *font_face;
+ const char text[] = TEXT;
+ cairo_font_extents_t font_extents;
+ cairo_text_extents_t extents;
+ cairo_status_t status;
+
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+#ifdef ROTATED
+ cairo_translate (cr, TEXT_SIZE, 0);
+ cairo_rotate (cr, .6);
+#endif
+
+ status = _user_font_face_create (&font_face);
+ if (status) {
+ return cairo_test_status_from_status (cairo_test_get_context (cr),
+ status);
+ }
+
+ cairo_set_font_face (cr, font_face);
+ cairo_font_face_destroy (font_face);
+
+ cairo_set_font_size (cr, TEXT_SIZE);
+
+ cairo_font_extents (cr, &font_extents);
+ cairo_text_extents (cr, text, &extents);
+
+ /* logical boundaries in red */
+ cairo_move_to (cr, 0, BORDER);
+ cairo_rel_line_to (cr, WIDTH, 0);
+ cairo_move_to (cr, 0, BORDER + font_extents.ascent);
+ cairo_rel_line_to (cr, WIDTH, 0);
+ cairo_move_to (cr, 0, BORDER + font_extents.ascent + font_extents.descent);
+ cairo_rel_line_to (cr, WIDTH, 0);
+ cairo_move_to (cr, BORDER, 0);
+ cairo_rel_line_to (cr, 0, 2*BORDER + TEXT_SIZE);
+ cairo_move_to (cr, BORDER + extents.x_advance, 0);
+ cairo_rel_line_to (cr, 0, 2*BORDER + TEXT_SIZE);
+ cairo_set_source_rgb (cr, 1, 0, 0);
+ cairo_set_line_width (cr, 2);
+ cairo_stroke (cr);
+
+ /* ink boundaries in green */
+ cairo_rectangle (cr,
+ BORDER + extents.x_bearing, BORDER + font_extents.ascent + extents.y_bearing,
+ extents.width, extents.height);
+ cairo_set_source_rgb (cr, 0, 1, 0);
+ cairo_set_line_width (cr, 2);
+ cairo_stroke (cr);
+
+ /* text in black */
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ cairo_move_to (cr, BORDER, BORDER + font_extents.ascent);
+ cairo_show_text (cr, text);
+
+
+ /* filled version of text in blue */
+ cairo_set_source_rgb (cr, 0, 0, 1);
+ cairo_move_to (cr, BORDER, BORDER + font_extents.height + 2*BORDER + font_extents.ascent);
+ cairo_text_path (cr, text);
+ cairo_fill (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (user_font_mask,
+ "Tests a user-font using cairo_mask with bitmap images",
+ "user-font, mask", /* keywords */
+ NULL, /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw)
diff --git a/test/user-font-proxy.c b/test/user-font-proxy.c
new file mode 100644
index 000000000..6a39d8ed8
--- /dev/null
+++ b/test/user-font-proxy.c
@@ -0,0 +1,222 @@
+/*
+ * Copyright © 2006, 2008 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Contributor(s):
+ * Kristian Høgsberg <krh@redhat.com>
+ * Behdad Esfahbod <behdad@behdad.org>
+ */
+
+#include "cairo-test.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+
+/*#define ROTATED 1*/
+
+#define BORDER 10
+#define TEXT_SIZE 64
+#define WIDTH (TEXT_SIZE * 12 + 2*BORDER)
+#ifndef ROTATED
+ #define HEIGHT ((TEXT_SIZE + 2*BORDER)*2)
+#else
+ #define HEIGHT WIDTH
+#endif
+#define TEXT "geez... cairo user-font"
+
+static cairo_user_data_key_t fallback_font_key;
+
+static cairo_status_t
+test_scaled_font_init (cairo_scaled_font_t *scaled_font,
+ cairo_t *cr,
+ cairo_font_extents_t *extents)
+{
+ cairo_status_t status;
+
+ cairo_set_font_face (cr,
+ cairo_font_face_get_user_data (cairo_scaled_font_get_font_face (scaled_font),
+ &fallback_font_key));
+
+ status = cairo_scaled_font_set_user_data (scaled_font,
+ &fallback_font_key,
+ cairo_scaled_font_reference (cairo_get_scaled_font (cr)),
+ (cairo_destroy_func_t) cairo_scaled_font_destroy);
+ if (unlikely (status)) {
+ cairo_scaled_font_destroy (cairo_get_scaled_font (cr));
+ return status;
+ }
+
+ cairo_font_extents (cr, extents);
+
+ return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_status_t
+test_scaled_font_render_glyph (cairo_scaled_font_t *scaled_font,
+ unsigned long glyph,
+ cairo_t *cr,
+ cairo_text_extents_t *extents)
+{
+ cairo_glyph_t cairo_glyph;
+
+ cairo_glyph.index = glyph;
+ cairo_glyph.x = 0;
+ cairo_glyph.y = 0;
+
+ cairo_set_font_face (cr,
+ cairo_font_face_get_user_data (cairo_scaled_font_get_font_face (scaled_font),
+ &fallback_font_key));
+
+ cairo_show_glyphs (cr, &cairo_glyph, 1);
+ cairo_glyph_extents (cr, &cairo_glyph, 1, extents);
+
+ return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_status_t
+test_scaled_font_text_to_glyphs (cairo_scaled_font_t *scaled_font,
+ const 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 *fallback_scaled_font;
+
+ fallback_scaled_font = cairo_scaled_font_get_user_data (scaled_font,
+ &fallback_font_key);
+
+ return cairo_scaled_font_text_to_glyphs (fallback_scaled_font, 0, 0,
+ utf8, utf8_len,
+ glyphs, num_glyphs,
+ clusters, num_clusters, cluster_flags);
+}
+
+static cairo_status_t
+_user_font_face_create (cairo_font_face_t **out)
+{
+ cairo_font_face_t *user_font_face;
+ cairo_font_face_t *fallback_font_face;
+ cairo_status_t status;
+
+ user_font_face = cairo_user_font_face_create ();
+ cairo_user_font_face_set_init_func (user_font_face, test_scaled_font_init);
+ cairo_user_font_face_set_render_glyph_func (user_font_face, test_scaled_font_render_glyph);
+ cairo_user_font_face_set_text_to_glyphs_func (user_font_face, test_scaled_font_text_to_glyphs);
+
+ /* This also happens to be default font face on cairo_t, so does
+ * not make much sense here. For demonstration only.
+ */
+ fallback_font_face = cairo_toy_font_face_create ("",
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_NORMAL);
+
+ status = cairo_font_face_set_user_data (user_font_face,
+ &fallback_font_key,
+ fallback_font_face,
+ (cairo_destroy_func_t) cairo_font_face_destroy);
+ if (status) {
+ cairo_font_face_destroy (fallback_font_face);
+ cairo_font_face_destroy (user_font_face);
+ return status;
+ }
+
+ *out = user_font_face;
+ return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ const char text[] = TEXT;
+ cairo_font_extents_t font_extents;
+ cairo_text_extents_t extents;
+ cairo_font_face_t *font_face;
+ cairo_status_t status;
+
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+#ifdef ROTATED
+ cairo_translate (cr, TEXT_SIZE, 0);
+ cairo_rotate (cr, .6);
+#endif
+
+ status = _user_font_face_create (&font_face);
+ if (status) {
+ return cairo_test_status_from_status (cairo_test_get_context (cr),
+ status);
+ }
+
+ cairo_set_font_face (cr, font_face);
+ cairo_font_face_destroy (font_face);
+
+ cairo_set_font_size (cr, TEXT_SIZE);
+
+ cairo_font_extents (cr, &font_extents);
+ cairo_text_extents (cr, text, &extents);
+
+ /* logical boundaries in red */
+ cairo_move_to (cr, 0, BORDER);
+ cairo_rel_line_to (cr, WIDTH, 0);
+ cairo_move_to (cr, 0, BORDER + font_extents.ascent);
+ cairo_rel_line_to (cr, WIDTH, 0);
+ cairo_move_to (cr, 0, BORDER + font_extents.ascent + font_extents.descent);
+ cairo_rel_line_to (cr, WIDTH, 0);
+ cairo_move_to (cr, BORDER, 0);
+ cairo_rel_line_to (cr, 0, 2*BORDER + TEXT_SIZE);
+ cairo_move_to (cr, BORDER + extents.x_advance, 0);
+ cairo_rel_line_to (cr, 0, 2*BORDER + TEXT_SIZE);
+ cairo_set_source_rgb (cr, 1, 0, 0);
+ cairo_set_line_width (cr, 2);
+ cairo_stroke (cr);
+
+ /* ink boundaries in green */
+ cairo_rectangle (cr,
+ BORDER + extents.x_bearing, BORDER + font_extents.ascent + extents.y_bearing,
+ extents.width, extents.height);
+ cairo_set_source_rgb (cr, 0, 1, 0);
+ cairo_set_line_width (cr, 2);
+ cairo_stroke (cr);
+
+ /* text in gray */
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ cairo_move_to (cr, BORDER, BORDER + font_extents.ascent);
+ cairo_show_text (cr, text);
+
+
+ /* filled version of text in light blue */
+ cairo_set_source_rgb (cr, 0, 0, 1);
+ cairo_move_to (cr, BORDER, BORDER + font_extents.height + BORDER + font_extents.ascent);
+ cairo_text_path (cr, text);
+ cairo_fill (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (user_font_proxy,
+ "Tests a user-font using a native font in its render_glyph",
+ "font, user-font", /* keywords */
+ "cairo >= 1.7.4", /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw)
diff --git a/test/user-font-rescale.c b/test/user-font-rescale.c
new file mode 100644
index 000000000..6f03b8e66
--- /dev/null
+++ b/test/user-font-rescale.c
@@ -0,0 +1,368 @@
+/*
+ * Copyright © 2008 Jeff Muizelaar
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Jeff Muizelaar not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Jeff Muizelaar makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * JEFF MUIZELAAR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL JEFF MUIZELAAR BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Contributor(s):
+ * Jeff Muizelaar <jeff@infidigm.net>
+ * Kristian Høgsberg <krh@redhat.com>
+ * Behdad Esfahbod <behdad@behdad.org>
+ */
+
+#include "cairo-test.h"
+
+#include <math.h>
+
+#define BORDER 10
+#define TEXT_SIZE 32
+#define WIDTH (TEXT_SIZE * 13.75 + 2*BORDER)
+#define HEIGHT ((TEXT_SIZE + 2*BORDER)*3 + BORDER)
+#define TEXT "test of rescaled glyphs"
+
+static const cairo_user_data_key_t rescale_font_closure_key;
+
+struct rescaled_font {
+ cairo_font_face_t *substitute_font;
+ cairo_scaled_font_t *measuring_font;
+ unsigned long glyph_count;
+ unsigned long start;
+ double *desired_width;
+ double *rescale_factor;
+};
+
+static cairo_status_t
+test_scaled_font_render_glyph (cairo_scaled_font_t *scaled_font,
+ unsigned long glyph,
+ cairo_t *cr,
+ cairo_text_extents_t *metrics)
+{
+ cairo_font_face_t *user_font;
+ struct rescaled_font *r;
+ cairo_glyph_t cairo_glyph;
+
+ cairo_glyph.index = glyph;
+ cairo_glyph.x = 0;
+ cairo_glyph.y = 0;
+
+ user_font = cairo_scaled_font_get_font_face (scaled_font);
+ r = cairo_font_face_get_user_data (user_font, &rescale_font_closure_key);
+ cairo_set_font_face (cr, r->substitute_font);
+
+ if (glyph - r->start < r->glyph_count) {
+ cairo_matrix_t matrix;
+
+ if (isnan (r->rescale_factor[glyph - r->start])) {
+ double desired_width;
+ double actual_width;
+ cairo_text_extents_t extents;
+
+ /* measure the glyph and compute the necessary rescaling factor */
+ cairo_scaled_font_glyph_extents (r->measuring_font,
+ &cairo_glyph, 1,
+ &extents);
+
+ desired_width = r->desired_width[glyph - r->start];
+ actual_width = extents.x_advance;
+
+ r->rescale_factor[glyph - r->start] = desired_width / actual_width;
+ }
+
+ /* scale the font so that the glyph width matches the desired width */
+ cairo_get_font_matrix (cr, &matrix);
+ cairo_matrix_scale (&matrix, r->rescale_factor[glyph - r->start], 1.);
+ cairo_set_font_matrix (cr, &matrix);
+ }
+
+ cairo_show_glyphs (cr, &cairo_glyph, 1);
+ cairo_glyph_extents (cr, &cairo_glyph, 1, metrics);
+
+ return CAIRO_STATUS_SUCCESS;
+}
+
+static void
+unichar_to_utf8 (uint32_t ucs4, char utf8[7])
+{
+ int i, charlen, first;
+
+ if (ucs4 < 0x80) {
+ first = 0;
+ charlen = 1;
+ } else if (ucs4 < 0x800) {
+ first = 0xc0;
+ charlen = 2;
+ } else if (ucs4 < 0x10000) {
+ first = 0xe0;
+ charlen = 3;
+ } else if (ucs4 < 0x200000) {
+ first = 0xf0;
+ charlen = 4;
+ } else if (ucs4 < 0x4000000) {
+ first = 0xf8;
+ charlen = 5;
+ } else {
+ first = 0xfc;
+ charlen = 6;
+ }
+
+ for (i = charlen - 1; i > 0; --i) {
+ utf8[i] = (ucs4 & 0x3f) | 0x80;
+ ucs4 >>= 6;
+ }
+ utf8[0] = ucs4 | first;
+ utf8[charlen] = '\0';
+}
+
+static cairo_status_t
+test_scaled_font_unicode_to_glyph (cairo_scaled_font_t *scaled_font,
+ unsigned long unicode,
+ unsigned long *glyph_index)
+{
+ cairo_font_face_t *user_font;
+ struct rescaled_font *r;
+ int num_glyphs;
+ cairo_glyph_t *glyphs = NULL;
+ cairo_status_t status;
+ char utf8[7];
+
+ user_font = cairo_scaled_font_get_font_face (scaled_font);
+
+ unichar_to_utf8 (unicode, utf8);
+ r = cairo_font_face_get_user_data (user_font, &rescale_font_closure_key);
+ status = cairo_scaled_font_text_to_glyphs (r->measuring_font, 0, 0,
+ utf8, -1,
+ &glyphs, &num_glyphs,
+ NULL, NULL, NULL);
+ if (status)
+ return status;
+
+ *glyph_index = glyphs[0].index;
+
+ cairo_glyph_free (glyphs);
+ return CAIRO_STATUS_SUCCESS;
+}
+
+static void rescale_font_closure_destroy (void *data)
+{
+ struct rescaled_font *r = data;
+
+ cairo_font_face_destroy (r->substitute_font);
+ cairo_scaled_font_destroy (r->measuring_font);
+ free (r->desired_width);
+ free (r->rescale_factor);
+ free (r);
+}
+
+static cairo_status_t
+create_rescaled_font (cairo_font_face_t *substitute_font,
+ int glyph_start,
+ int glyph_count,
+ double *desired_width,
+ cairo_font_face_t **out)
+{
+ cairo_font_face_t *user_font_face;
+ struct rescaled_font *r;
+ cairo_font_options_t *options;
+ cairo_status_t status;
+ cairo_matrix_t m;
+ unsigned long i;
+
+ user_font_face = cairo_user_font_face_create ();
+ cairo_user_font_face_set_render_glyph_func (user_font_face, test_scaled_font_render_glyph);
+ cairo_user_font_face_set_unicode_to_glyph_func (user_font_face, test_scaled_font_unicode_to_glyph);
+
+ r = xmalloc (sizeof (struct rescaled_font));
+ r->substitute_font = cairo_font_face_reference (substitute_font);
+
+ /* we don't want any hinting when doing the measuring */
+ options = cairo_font_options_create ();
+ cairo_font_options_set_hint_style (options, CAIRO_HINT_STYLE_NONE);
+ cairo_font_options_set_hint_metrics (options, CAIRO_HINT_METRICS_OFF);
+
+ cairo_matrix_init_identity (&m);
+
+ r->measuring_font = cairo_scaled_font_create (r->substitute_font,
+ &m, &m,
+ options);
+ cairo_font_options_destroy (options);
+
+
+ r->start = glyph_start;
+ r->glyph_count = glyph_count;
+ r->desired_width = xcalloc (sizeof (double), r->glyph_count);
+ r->rescale_factor = xcalloc (sizeof (double), r->glyph_count);
+
+ for (i = 0; i < r->glyph_count; i++) {
+ r->desired_width[i] = desired_width[i];
+ /* use NaN to specify unset */
+ r->rescale_factor[i] = cairo_test_NaN ();
+ }
+
+ status = cairo_font_face_set_user_data (user_font_face,
+ &rescale_font_closure_key,
+ r, rescale_font_closure_destroy);
+ if (status) {
+ rescale_font_closure_destroy (r);
+ cairo_font_face_destroy (user_font_face);
+ return status;
+ }
+
+ *out = user_font_face;
+ return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_status_t
+get_user_font_face (cairo_font_face_t *substitute_font,
+ const char *text,
+ cairo_font_face_t *old,
+ cairo_font_face_t **out)
+{
+ cairo_font_options_t *options;
+ cairo_matrix_t m;
+ cairo_scaled_font_t *measure;
+ int i;
+ double *widths;
+ int count;
+ int num_glyphs;
+ unsigned long min_index, max_index;
+ cairo_status_t status;
+
+ cairo_glyph_t *glyphs = NULL;
+
+ /* we don't want any hinting when doing the measuring */
+ options = cairo_font_options_create ();
+ cairo_font_options_set_hint_style (options, CAIRO_HINT_STYLE_NONE);
+ cairo_font_options_set_hint_metrics (options, CAIRO_HINT_METRICS_OFF);
+
+ cairo_matrix_init_identity (&m);
+ measure = cairo_scaled_font_create (old, &m, &m, options);
+
+ status = cairo_scaled_font_text_to_glyphs (measure, 0, 0,
+ text, -1,
+ &glyphs, &num_glyphs,
+ NULL, NULL, NULL);
+ cairo_font_options_destroy (options);
+
+ if (status) {
+ cairo_scaled_font_destroy (measure);
+ return status;
+ }
+
+ /* find the glyph range the text covers */
+ max_index = glyphs[0].index;
+ min_index = glyphs[0].index;
+ for (i=0; i<num_glyphs; i++) {
+ if (glyphs[i].index < min_index)
+ min_index = glyphs[i].index;
+ if (glyphs[i].index > max_index)
+ max_index = glyphs[i].index;
+ }
+
+ count = max_index - min_index + 1;
+ widths = xcalloc (sizeof (double), count);
+ /* measure all of the necessary glyphs individually */
+ for (i=0; i<num_glyphs; i++) {
+ cairo_text_extents_t extents;
+ cairo_scaled_font_glyph_extents (measure, &glyphs[i], 1, &extents);
+ widths[glyphs[i].index - min_index] = extents.x_advance;
+ }
+
+ status = cairo_scaled_font_status (measure);
+ cairo_scaled_font_destroy (measure);
+ cairo_glyph_free (glyphs);
+
+ if (status == CAIRO_STATUS_SUCCESS) {
+ status = create_rescaled_font (substitute_font,
+ min_index, count, widths,
+ out);
+ }
+
+ free (widths);
+ return status;
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_font_extents_t font_extents;
+ cairo_text_extents_t extents;
+ cairo_font_face_t *rescaled;
+ cairo_font_face_t *old;
+ cairo_font_face_t *substitute;
+ const char text[] = TEXT;
+ cairo_status_t status;
+
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+ cairo_select_font_face (cr,
+ CAIRO_TEST_FONT_FAMILY " Sans",
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_NORMAL);
+
+ cairo_set_font_size (cr, TEXT_SIZE);
+
+ cairo_font_extents (cr, &font_extents);
+ cairo_text_extents (cr, text, &extents);
+
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ cairo_move_to (cr, BORDER, BORDER + font_extents.ascent);
+ cairo_show_text (cr, text);
+
+ /* same text in 'mono' with widths that match the 'sans' version */
+ old = cairo_font_face_reference (cairo_get_font_face (cr));
+ cairo_select_font_face (cr,
+ CAIRO_TEST_FONT_FAMILY " Sans Mono",
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_NORMAL);
+ substitute = cairo_get_font_face (cr);
+
+ status = get_user_font_face (substitute, text, old, &rescaled);
+ cairo_font_face_destroy (old);
+ if (status) {
+ return cairo_test_status_from_status (cairo_test_get_context (cr),
+ status);
+ }
+
+ cairo_set_font_face (cr, rescaled);
+ cairo_font_face_destroy (rescaled);
+
+ cairo_set_source_rgb (cr, 0, 0, 1);
+ cairo_move_to (cr, BORDER, BORDER + font_extents.height + 2*BORDER + font_extents.ascent);
+ cairo_show_text (cr, text);
+
+ /* mono text */
+ cairo_select_font_face (cr,
+ CAIRO_TEST_FONT_FAMILY " Sans Mono",
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_NORMAL);
+
+ cairo_set_source_rgb (cr, 0, 0, 1);
+ cairo_move_to (cr, BORDER, BORDER + 2*font_extents.height + 4*BORDER + font_extents.ascent);
+ cairo_show_text (cr, text);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (user_font_rescale,
+ "Tests drawing text with user defined widths",
+ "user-font, font", /* keywords */
+ NULL, /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw)
diff --git a/test/user-font.c b/test/user-font.c
new file mode 100644
index 000000000..435d5616f
--- /dev/null
+++ b/test/user-font.c
@@ -0,0 +1,267 @@
+/*
+ * Copyright © 2006, 2008 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Contributor(s):
+ * Kristian Høgsberg <krh@redhat.com>
+ * Behdad Esfahbod <behdad@behdad.org>
+ */
+
+#include "cairo-test.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+
+/*#define ROTATED 1*/
+
+#define BORDER 10
+#define TEXT_SIZE 64
+#define WIDTH (TEXT_SIZE * 15 + 2*BORDER)
+#ifndef ROTATED
+ #define HEIGHT ((TEXT_SIZE + 2*BORDER)*2)
+#else
+ #define HEIGHT WIDTH
+#endif
+#define TEXT "geez... cairo user-font"
+
+#define END_GLYPH 0
+#define STROKE 126
+#define CLOSE 127
+
+/* Simple glyph definition: 1 - 15 means lineto (or moveto for first
+ * point) for one of the points on this grid:
+ *
+ * 1 2 3
+ * 4 5 6
+ * 7 8 9
+ * ----10 11 12----(baseline)
+ * 13 14 15
+ */
+typedef struct {
+ unsigned long ucs4;
+ int width;
+ char data[16];
+} test_scaled_font_glyph_t;
+
+static cairo_user_data_key_t test_font_face_glyphs_key;
+
+static cairo_status_t
+test_scaled_font_init (cairo_scaled_font_t *scaled_font,
+ cairo_t *cr,
+ cairo_font_extents_t *metrics)
+{
+ metrics->ascent = .75;
+ metrics->descent = .25;
+ return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_status_t
+test_scaled_font_unicode_to_glyph (cairo_scaled_font_t *scaled_font,
+ unsigned long unicode,
+ unsigned long *glyph)
+{
+ test_scaled_font_glyph_t *glyphs = cairo_font_face_get_user_data (cairo_scaled_font_get_font_face (scaled_font),
+ &test_font_face_glyphs_key);
+ int i;
+
+ for (i = 0; glyphs[i].ucs4 != (unsigned long) -1; i++)
+ if (glyphs[i].ucs4 == unicode) {
+ *glyph = i;
+ return CAIRO_STATUS_SUCCESS;
+ }
+
+ /* Not found. Default to glyph 0 */
+ return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_status_t
+test_scaled_font_render_glyph (cairo_scaled_font_t *scaled_font,
+ unsigned long glyph,
+ cairo_t *cr,
+ cairo_text_extents_t *metrics)
+{
+ test_scaled_font_glyph_t *glyphs = cairo_font_face_get_user_data (cairo_scaled_font_get_font_face (scaled_font),
+ &test_font_face_glyphs_key);
+ int i;
+ const char *data;
+ div_t d;
+ double x, y;
+
+ /* FIXME: We simply crash on out-of-bound glyph indices */
+
+ metrics->x_advance = glyphs[glyph].width / 4.0;
+
+ cairo_set_line_width (cr, 0.1);
+ cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND);
+ cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
+
+ data = glyphs[glyph].data;
+ for (i = 0; data[i] != END_GLYPH; i++) {
+ switch (data[i]) {
+ case STROKE:
+ cairo_new_sub_path (cr);
+ break;
+
+ case CLOSE:
+ cairo_close_path (cr);
+ break;
+
+ default:
+ d = div (data[i] - 1, 3);
+ x = d.rem / 4.0 + 0.125;
+ y = d.quot / 5.0 + 0.4 - 1.0;
+ cairo_line_to (cr, x, y);
+ }
+ }
+ cairo_stroke (cr);
+
+ return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_status_t
+_user_font_face_create (cairo_font_face_t **out)
+{
+ /* Simple glyph definition: 1 - 15 means lineto (or moveto for first
+ * point) for one of the points on this grid:
+ *
+ * 1 2 3
+ * 4 5 6
+ * 7 8 9
+ * ----10 11 12----(baseline)
+ * 13 14 15
+ */
+ static const test_scaled_font_glyph_t glyphs [] = {
+ { 'a', 3, { 4, 6, 12, 10, 7, 9, STROKE, END_GLYPH } },
+ { 'c', 3, { 6, 4, 10, 12, STROKE, END_GLYPH } },
+ { 'e', 3, { 12, 10, 4, 6, 9, 7, STROKE, END_GLYPH } },
+ { 'f', 3, { 3, 2, 11, STROKE, 4, 6, STROKE, END_GLYPH } },
+ { 'g', 3, { 12, 10, 4, 6, 15, 13, STROKE, END_GLYPH } },
+ { 'h', 3, { 1, 10, STROKE, 7, 5, 6, 12, STROKE, END_GLYPH } },
+ { 'i', 1, { 1, 1, STROKE, 4, 10, STROKE, END_GLYPH } },
+ { 'l', 1, { 1, 10, STROKE, END_GLYPH } },
+ { 'n', 3, { 10, 4, STROKE, 7, 5, 6, 12, STROKE, END_GLYPH } },
+ { 'o', 3, { 4, 10, 12, 6, CLOSE, END_GLYPH } },
+ { 'r', 3, { 4, 10, STROKE, 7, 5, 6, STROKE, END_GLYPH } },
+ { 's', 3, { 6, 4, 7, 9, 12, 10, STROKE, END_GLYPH } },
+ { 't', 3, { 2, 11, 12, STROKE, 4, 6, STROKE, END_GLYPH } },
+ { 'u', 3, { 4, 10, 12, 6, STROKE, END_GLYPH } },
+ { 'z', 3, { 4, 6, 10, 12, STROKE, END_GLYPH } },
+ { ' ', 1, { END_GLYPH } },
+ { '-', 2, { 7, 8, STROKE, END_GLYPH } },
+ { '.', 1, { 10, 10, STROKE, END_GLYPH } },
+ { -1, 0, { END_GLYPH } },
+ };
+
+ cairo_font_face_t *user_font_face;
+ cairo_status_t status;
+
+ user_font_face = cairo_user_font_face_create ();
+ cairo_user_font_face_set_init_func (user_font_face, test_scaled_font_init);
+ cairo_user_font_face_set_render_glyph_func (user_font_face, test_scaled_font_render_glyph);
+ cairo_user_font_face_set_unicode_to_glyph_func (user_font_face, test_scaled_font_unicode_to_glyph);
+
+ status = cairo_font_face_set_user_data (user_font_face,
+ &test_font_face_glyphs_key,
+ (void*) glyphs, NULL);
+ if (status) {
+ cairo_font_face_destroy (user_font_face);
+ return status;
+ }
+
+ *out = user_font_face;
+ return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_font_face_t *font_face;
+ const char text[] = TEXT;
+ cairo_font_extents_t font_extents;
+ cairo_text_extents_t extents;
+ cairo_status_t status;
+
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+#ifdef ROTATED
+ cairo_translate (cr, TEXT_SIZE, 0);
+ cairo_rotate (cr, .6);
+#endif
+
+ status = _user_font_face_create (&font_face);
+ if (status) {
+ return cairo_test_status_from_status (cairo_test_get_context (cr),
+ status);
+ }
+
+ cairo_set_font_face (cr, font_face);
+ cairo_font_face_destroy (font_face);
+
+ cairo_set_font_size (cr, TEXT_SIZE);
+
+ cairo_font_extents (cr, &font_extents);
+ cairo_text_extents (cr, text, &extents);
+
+ /* logical boundaries in red */
+ cairo_move_to (cr, 0, BORDER);
+ cairo_rel_line_to (cr, WIDTH, 0);
+ cairo_move_to (cr, 0, BORDER + font_extents.ascent);
+ cairo_rel_line_to (cr, WIDTH, 0);
+ cairo_move_to (cr, 0, BORDER + font_extents.ascent + font_extents.descent);
+ cairo_rel_line_to (cr, WIDTH, 0);
+ cairo_move_to (cr, BORDER, 0);
+ cairo_rel_line_to (cr, 0, 2*BORDER + TEXT_SIZE);
+ cairo_move_to (cr, BORDER + extents.x_advance, 0);
+ cairo_rel_line_to (cr, 0, 2*BORDER + TEXT_SIZE);
+ cairo_set_source_rgb (cr, 1, 0, 0);
+ cairo_set_line_width (cr, 2);
+ cairo_stroke (cr);
+
+ /* ink boundaries in green */
+ cairo_rectangle (cr,
+ BORDER + extents.x_bearing, BORDER + font_extents.ascent + extents.y_bearing,
+ extents.width, extents.height);
+ cairo_set_source_rgb (cr, 0, 1, 0);
+ cairo_set_line_width (cr, 2);
+ cairo_stroke (cr);
+
+ /* text in black */
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ cairo_move_to (cr, BORDER, BORDER + font_extents.ascent);
+ cairo_show_text (cr, text);
+
+
+ /* filled version of text in blue */
+ cairo_set_source_rgb (cr, 0, 0, 1);
+ cairo_move_to (cr, BORDER, BORDER + font_extents.height + 2*BORDER + font_extents.ascent);
+ cairo_text_path (cr, text);
+ cairo_fill (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (user_font,
+ "Tests user font feature",
+ "font, user-font", /* keywords */
+ "cairo >= 1.7.4", /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw)
diff --git a/test/white-in-noop.c b/test/white-in-noop.c
new file mode 100644
index 000000000..e6a93e801
--- /dev/null
+++ b/test/white-in-noop.c
@@ -0,0 +1,52 @@
+/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */
+/*
+ * Copyright 2011 Andrea Canciani
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Andrea Canciani <ranma42@gmail.com>
+ */
+
+#include "cairo-test.h"
+
+#define HEIGHT 4
+#define WIDTH 4
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ cairo_paint (cr);
+
+ cairo_set_operator (cr, CAIRO_OPERATOR_IN);
+
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (white_in_noop,
+ "Test an invalid optimization of the IN operator with white sources",
+ "operator", /* keywords */
+ NULL, /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw)
diff --git a/test/world-map.c b/test/world-map.c
new file mode 100644
index 000000000..f775bb0d5
--- /dev/null
+++ b/test/world-map.c
@@ -0,0 +1,151 @@
+/*
+ * Copyright © 2006 Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+#include "cairo-test.h"
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#define WIDTH 800
+#define HEIGHT 400
+
+typedef enum {
+ WM_NEW_PATH,
+ WM_MOVE_TO,
+ WM_LINE_TO,
+ WM_HLINE_TO,
+ WM_VLINE_TO,
+ WM_REL_LINE_TO,
+ WM_END
+} wm_type_t;
+
+typedef struct _wm_element {
+ wm_type_t type;
+ double x;
+ double y;
+} wm_element_t;
+
+#include "world-map.h"
+
+enum {
+ STROKE = 1,
+ FILL = 2,
+};
+
+static cairo_test_status_t
+draw_world_map (cairo_t *cr, int width, int height, int mode)
+{
+ const wm_element_t *e;
+ double cx, cy;
+
+ cairo_set_line_width (cr, 0.2);
+
+ cairo_set_source_rgb (cr, .68, .85, .90); /* lightblue */
+ cairo_rectangle (cr, 0, 0, 800, 400);
+ cairo_fill (cr);
+
+ e = &countries[0];
+ while (1) {
+ switch (e->type) {
+ case WM_NEW_PATH:
+ case WM_END:
+ if (mode & FILL) {
+ cairo_set_source_rgb (cr, .75, .75, .75); /* silver */
+ cairo_fill_preserve (cr);
+ }
+ if (mode & STROKE) {
+ cairo_set_source_rgb (cr, .50, .50, .50); /* gray */
+ cairo_stroke (cr);
+ }
+ cairo_new_path (cr);
+ cairo_move_to (cr, e->x, e->y);
+ break;
+ case WM_MOVE_TO:
+ cairo_close_path (cr);
+ cairo_move_to (cr, e->x, e->y);
+ break;
+ case WM_LINE_TO:
+ cairo_line_to (cr, e->x, e->y);
+ break;
+ case WM_HLINE_TO:
+ cairo_get_current_point (cr, &cx, &cy);
+ cairo_line_to (cr, e->x, cy);
+ break;
+ case WM_VLINE_TO:
+ cairo_get_current_point (cr, &cx, &cy);
+ cairo_line_to (cr, cx, e->y);
+ break;
+ case WM_REL_LINE_TO:
+ cairo_rel_line_to (cr, e->x, e->y);
+ break;
+ }
+ if (e->type == WM_END)
+ break;
+ e++;
+ }
+
+ cairo_new_path (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+draw_world_map_stroke (cairo_t *cr, int width, int height)
+{
+ return draw_world_map (cr, width, height, STROKE);
+}
+
+static cairo_test_status_t
+draw_world_map_fill (cairo_t *cr, int width, int height)
+{
+ return draw_world_map (cr, width, height, FILL);
+}
+
+static cairo_test_status_t
+draw_world_map_both (cairo_t *cr, int width, int height)
+{
+ return draw_world_map (cr, width, height, FILL | STROKE);
+}
+
+CAIRO_TEST (world_map,
+ "Tests a complex drawing (part of the performance suite)",
+ "fill, stroke", /* keywords */
+ NULL, /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw_world_map_both)
+CAIRO_TEST (world_map_stroke,
+ "Tests a complex drawing (part of the performance suite)",
+ "stroke", /* keywords */
+ NULL, /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw_world_map_stroke)
+CAIRO_TEST (world_map_fill,
+ "Tests a complex drawing (part of the performance suite)",
+ "fill", /* keywords */
+ NULL, /* requirements */
+ WIDTH, HEIGHT,
+ NULL, draw_world_map_fill)
diff --git a/test/world-map.h b/test/world-map.h
new file mode 100644
index 000000000..af58b80f1
--- /dev/null
+++ b/test/world-map.h
@@ -0,0 +1,196 @@
+/* The data for this test case was provided by Gary Nicholson
+ * <gary@imapping.co.nz> who originally created an interactive SVG map
+ * of the world as can be seen here:
+ *
+ * http://www.wherearewe.co.nz/svg.html
+ *
+ * The data is used here by permission from Gary given on 2006-11-08:
+ *
+ * Thanks for asking, I don't need any attribution if you are
+ * only using the vectors and not the entire map with
+ * interactivity etc. So feel free to do what you wish with
+ * the data.
+ */
+
+#define N(x,y) { WM_NEW_PATH, x, y }
+#define M(x,y) { WM_MOVE_TO, x, y }
+#define L(x,y) { WM_LINE_TO, x, y }
+#define H(x,y) { WM_HLINE_TO, x, y }
+#define V(x,y) { WM_VLINE_TO, x, y }
+#define l(x,y) { WM_REL_LINE_TO, x, y }
+#define E(x,y) { WM_END, x, y }
+
+static const wm_element_t countries[] = {
+N(413.519,90.071),l(.136,-.348),l(-.31,-.204),l(-.017,-.327),l(.213,-.322),l(.245,-.147),l(.142,-.08),l(.225,.072),l(.062,.301),l(.41,.312),l(.466,.096),l(-.044,.288),l(-.248,.144),l(.074,.353),l(-.145,-.063),l(-.568,-.011),l(-.642,-.063),
+N(421.683,94.397),l(.193,.336),l(-.266,.274),l(.214,.288),l(-.09,.192),l(.622,.062),l(.008,.144),l(.55,.242),l(.579,-.332),l(.215,.117),l(-.029,.171),l(-.126,.309),l(.112,.212),l(-.038,.192),l(-.315,-.051),l(-.176,-.162),l(-.283,.091),l(-.081,.273),l(.244,.131),l(-.228,.415),l(-.244,-.333),l(-.469,.05),l(-.071,.122),l(-.216,.03),l(-.23,-.142),l(-.143,-.354),l(-.371,.081),l(.019,.333),l(-.425,.384),l(-.018,.535),l(-.285,.151),l(-.385,-.312),l(.098,-.182),l(-.311,-.071),l(-.534,-.363),l(-.016,-.415),l(-.777,.404),l(.103,.212),l(-.349,.432),l(-.275,.16),l(-.629,-.168),l(-.627,.204),l(-.599,-.062),l(-.102,-.424),l(-.312,-.806),l(-.616,.147),l(-.854,.668),l(-.369,-.111),l(.238,-.226),l(.013,-.322),l(-.08,-.137),l(.089,-.294),l(.718,-.418),l(-.038,-.315),l(.575,-.24),l(.012,-.076),l(.528,-.494),l(.173,-.035),l(-.116,-.089),l(-.153,-.028),l(.221,-.302),l(.446,.007),l(-.005,.096),l(.473,.007),l(.385,-.309),l(.271,.089),l(.272,-.117),l(.271,.096),l(.567,-.158),l(.278,.11),l(.354,-.021),l(-.179,-.199),l(.709,-.199),l(.017,.151),l(.199,-.014),l(.149,.089),l(.852,.007),l(.664,.261),
+N(421.394,104.558),l(.104,.175),l(.04,.256),l(-.06,.475),l(.118,.054),l(.062,.333),l(-.076,.795),l(-.211,.327),l(-.118,.724),l(-.292,.501),l(-.298,-.043),l(-.057,-.196),l(-.41,-.076),l(-.227,-.152),l(.284,-.207),l(-.07,-.076),l(-.437,-.098),l(.257,-.332),l(-.11,-.071),l(-.291,.071),l(-.053,-.147),l(.115,-.022),l(.175,-.158),l(-.094,-.153),l(-.257,-.082),l(.015,-.164),l(.247,-.12),l(-.284,-.218),l(.241,-.284),l(.6,-.305),l(.27,-.022),l(.04,-.125),l(.292,-.043),l(.195,.104),l(.096,-.142),l(-.022,-.344),l(.072,-.224),l(.143,-.011),M(396.323,103.853),l(.375,-.122),l(.411,-.365),l(.549,-2.299),l(.397,-.091),l(-.21,-.29),l(-.226,.259),l(.125,-1.144),l(.223,-.826),l(.115,.153),l(.496,.306),l(.191,.382),l(.191,.229),l(-.281,-.673),l(-.63,-.582),l(-.242,-.233),l(.024,-.249),l(.359,-.477),l(-.202,-.375),l(-.2,-.274),l(-.326,-.216),l(-.685,-.1),l(-.515,-.571),l(-.416,-.323),l(.278,-.426),l(-.233,-.181),l(-.343,-.131),l(-.511,-.142),l(-.184,-.173),l(.247,-.376),l(-.329,-.173),l(-.509,.179),l(-.489,-.249),l(-.824,-.251),l(-.619,-.181),l(-.325,.014),l(-.215,-.25),l(-.91,.167),l(-.059,-.25),l(-.265,-.125),l(-.367,-.042),l(-.056,-.104),l(.861,-.083),l(-.085,-.229),l(-.526,-.104),l(.442,-.104),l(.086,-.205),l(-.275,.017),l(-.263,-.021),l(-.417,.083),l(.04,-.438),l(.303,.012),l(.305,-.146),l(.526,-.088),l(.562,-.174),l(.215,.188),l(.18,-.167),l(.474,.063),l(.112,-.26),l(.272,-.059),l(.764,-.078),l(.393,.366),l(.275,.26),l(.342,.083),l(.652,-.271),l(.317,.167),l(.276,-.127),l(.457,-.124),l(.029,.23),l(.591,-.065),l(.3,-.103),l(-.265,-.188),l(-.028,-.251),l(.056,-.345),l(-.037,-.428),l(-.131,.021),l(-.562,-.682),l(-.11,-.407),l(.927,.126),l(.607,-.105),l(-.084,.397),l(.248,.419),l(.342,-.146),l(1.241,.104),l(.501,.146),l(.079,-.014),l(.525,-.093),l(.662,-.27),l(-.534,-.124),l(.055,-.204),l(.166,-.175),l(.753,-.322),l(.756,-.181),l(.902,-.215),l(.314,-.235),l(.302,-.264),l(-.053,-.775),l(.135,-.542),l(.521,-.25),l(.46,-.16),l(.916,-.092),l(.177,-.096),l(.208,.447),l(.311,.335),l(.266,.127),l(.141,-.071),l(.41,-.208),l(.153,.17),l(.202,.458),l(.194,.133),l(.518,-.012),l(.159,.301),l(.259,-.012),l(.576,.048),l(.375,.168),l(-.159,.241),l(.091,.175),l(-.072,.198),l(.285,.122),l(.406,-.075),l(.446,-.035),l(.193,-.313),l(.245,-.072),l(-.119,.373),l(.146,.18),l(-.039,.228),l(.529,.048),l(.341,.192),l(.371,.204),l(.127,.228),l(.694,-.174),l(.079,.114),l(.642,.063),l(.568,.011),l(.145,.063),l(.428,.319),l(.337,.277),l(.395,-.055),l(.045,.145),l(.689,-.062),l(.072,-.048),l(.233,.007),l(.095,.186),l(.456,.09),l(.479,-.014),l(.605,.193),l(-.954,.806),l(-.054,.213),l(-.054,.358),l(-.321,.372),l(-.075,.295),l(.091,.076),l(-.216,.701),l(.135,.233),l(-.385,.309),l(-.473,-.007),l(.005,-.096),L(415.96,94.5),l(-.221,.302),l(.153,.028),l(.116,.089),l(-.173,.035),l(-.528,.494),l(-.012,.076),l(-.575,.24),l(.038,.315),l(-.718,.418),l(-.089,.294),l(.08,.137),l(-.013,.322),l(-.238,.226),l(.369,.111),l(.854,-.668),l(.616,-.147),l(.312,.806),l(.102,.424),l(-.624,.301),l(.532,.344),l(.025,.292),l(.43,.192),l(-.199,.272),l(-.541,.353),l(-.183,-.111),l(-.437,.186),l(.352,.358),l(.616,.191),l(.135,.331),l(-.175,.01),l(-.315,.371),l(.193,.442),l(.754,.391),l(.849,-.07),l(.062,.281),l(-.146,.469),l(-.346,.23),l(-.221,.215),l(-.833,.488),l(-.889,.659),l(-.427,.087),l(-.318,.043),l(-.798,.159),l(-.405,-.028),l(-.471,-.156),l(-.851,-.499),l(-.315,-.085),l(-.354,.029),l(-.231,.072),l(-.511,-.056),l(-.752,-.313),l(-.602,.044),l(-.731,.345),l(-.357,.258),l(-.555,.559),l(-.147,.386),l(.099,.514),l(.091,.379),l(-.334,-.091),l(-.75,.137),l(-.039,.136),l(-.485,-.015),l(-.427,-.197),l(-.395,.167),l(-.261,-.015),l(-.036,-.152),l(-.335,-.091),l(-.206,.03),l(-.374,.076),l(-.187,-.076),l(-.035,-.289),l(-.091,-.213),l(-1.252,-.304),l(-.355,0),l(.017,.319),l(-.542,-.015),l(-.337,.061),l(-.037,-.122),l(-.767,.03),l(-.084,-.114),l(-.028,-.038),l(-.431,-.152),l(-.131,.076),l(-.262,-.03),l(-.056,.076),l(-.507,-.395),l(-.15,.061),l(-1.088,-.334),l(-.112,.106),l(-.15,-.03),l(-.094,-.106),l(.205,-.243),l(-.058,-.122),l(-.469,.03),l(-.472,-.243),
+N(681.312,116.395),l(.235,-.171),l(.283,-.256),l(.633,-.738),l(.315,-.157),l(.595,.011),l(.579,.068),l(.511,.096),l(.309,-.115),l(.571,-.678),l(.682,.621),l(1.178,1.611),l(.329,.495),l(.269,.664),l(.002,.75),l(-.034,.947),l(-.129,.637),l(.143,.113),l(.5,-.043),l(-.121,.41),l(-.282,.523),l(-.5,.75),l(-.316,.312),l(-.243,.043),l(-.567,-.211),l(-.256,.1),l(-.607,.58),l(-.431,-.083),l(-.289,-.225),l(-.544,.1),l(-.526,.199),l(-1.188,.835),l(-.462,.043),l(-.46,.312),l(-.055,-.564),l(-.056,-.324),l(-.163,-.705),l(-.137,-.395),l(.167,-.453),l(.499,-.468),l(0,-.353),l(.226,-.425),l(-.044,-.141),l(-.378,-.311),l(-.095,-.296),l(.015,-.467),l(-.087,-.339),l(-.289,-.126),l(-.603,-.084),l(.654,-.411),l(.303,-.114),l(.654,.268),l(.254,-.241),l(-.029,-.283),l(-.764,-.89),l(-.113,-.311),l(-.137,-.105),
+N(475.646,121.847),l(-.018,.175),l(.338,.391),l(-.295,-.009),l(-.132,.108),l(-.104,-.059),l(-.327,-.021),l(-.121,.33),l(-.783,.257),l(-.384,.046),l(-.099,.053),l(0,.21),l(-.217,.006),l(-.072,-.192),l(-.402,.023),l(-.547,-.146),l(-.191,-.087),l(0,-.21),l(-.161,-.105),l(-.122,-.403),l(.082,-.035),l(.12,.1),l(.147,-.006),l(.405,-.304),l(.253,-.006),l(.328,.092),l(.077,-.086),l(.088,-.286),l(-.053,-.175),l(.627,.093),l(.658,.027),l(.367,-.056),l(.818,-.233),l(.689,-.304),l(.535,-.158),l(-.475,.295),l(-.436,.231),l(-.596,.444),
+N(704.404,117.274),l(.197,-.099),l(1.108,-.271),l(.057,.354),l(-.481,.284),l(-.232,.241),l(-.068,.453),l(.139,.367),l(.291,.056),l(.221,-.114),l(.418,-.354),l(.24,-.085),l(1.656,-.697),l(.389,-.213),l(.46,-.326),l(.349,-.638),l(.76,-.412),l(.347,-.327),l(.191,-.269),l(.142,-.51),l(.538,-.582),l(-.01,-.142),l(.344,-.567),l(.159,-.468),l(.139,-.609),l(-.043,-.467),l(-.33,-.198),l(-.128,-.24),l(.234,-.213),l(.166,-.284),l(-.155,-1.023),l(.544,-.343),l(.176,-.242),l(.327,-.328),l(.192,0),l(.21,.355),l(.199,.227),l(.303,-.058),l(.799,-.257),l(-.169,-.526),l(-.311,-.028),l(-.36,-.312),l(.694,-.415),l(.441,.156),l(.336,.227),l(.025,.199),l(-.016,.868),l(.058,.611),l(.22,.127),l(.243,.312),l(.717,1.432),l(.001,.496),l(-.246,.709),l(-.709,.766),l(-.226,.439),l(.064,.368),l(-.15,.071),l(-.737,.285),l(-.161,.113),l(-.164,.199),l(-.174,.453),l(.02,.396),l(.094,.254),l(.131,.792),l(-.04,.693),l(-.686,.751),l(-.242,.736),l(.02,.707),l(.198,.296),l(.422,.353),l(-.617,.298),l(-.193,.127),l(-.166,.17),l(-.174,.834),l(-1.081,.439),l(-.094,-.282),l(.294,-.665),l(.184,-.523),l(-.198,-.126),l(-.514,.241),l(-.578,.623),l(-.476,.001),l(-.346,.312),l(-.066,.748),l(-.354,.269),l(-.188,-.028),l(-.066,-.155),l(.003,-.606),l(-.149,-.155),l(-.211,.042),l(-.309,.156),l(-.344,.311),l(-.325,.523),l(-.866,-.055),l(-.505,.057),l(-.631,.1),l(-.458,-.549),l(-.685,-.323),l(-.26,.254),l(-.067,.184),l(-.177,.353),l(.037,.056),l(.417,.197),l(.416,.323),l(-.293,.198),l(-.829,.129),l(-.433,.241),l(-.463,.622),l(-.522,.847),l(-.688,-.365),l(-.565,-.21),l(-.285,-.197),l(-.014,-.169),l(-.194,-.818),l(.099,-.155),l(.495,-.325),l(.179,-.269),l(-.067,-.282),l(-.18,-.042),l(-.601,.17),l(-.341,-.028),l(-.789,-.167),l(-.475,.128),l(-.427,.227),l(-.437,.184),l(-.269,-.098),l(-.256,-.027),l(-1.647,.398),l(-.814,.298),l(-.21,-.31),l(-.452,-.042),l(-.413,.438),l(-.006,.635),l(-.756,-.238),l(-.579,-.055),l(-1.1,.073),l(-.267,-.14),l(.072,-.339),l(.179,-.283),l(.483,.013),l(.499,-.114),l(.751,-.467),l(2.201,-1.953),l(.28,-.015),l(.427,-.128),l(.056,.424),l(.495,-.128),l(1.278,-.257),l(.933,-.058),l(1.183,-.172),l(.892,-.256),l(.068,.452),l(.377,.268),l(.167,-.085),l(.654,-.199),l(.446,-.34),l(-.003,-.353),l(.114,-.467),l(.465,-.51),l(.698,-.581),l(.371,-.453),l(-.062,-1.117),l(.182,-.213),M(695.464,127.756),l(-.292,-.197),l(-.223,-.268),l(-.101,-.381),l(-.177,-.395),l(-.492,-.535),l(.731,-.382),l(.287,-.269),l(.456,-.593),l(.409,.253),l(.615,-.015),l(.483,-.185),l(.311,-.339),l(.451,-.311),l(.454,-.029),l(.316,.169),l(.862,.224),l(.153,.254),l(-.1,.127),l(-.102,.423),l(-.292,.24),l(-.864,.876),l(-.181,-.211),l(-.424,-.295),l(-.467,-.042),l(-.612,.213),l(-.193,.184),l(-.245,.495),l(-.165,.508),l(-.153,.212),l(-.448,.269),M(691.12,131.448),l(-.366,-.042),l(-.056,-.141),l(.268,-.537),l(.128,-.593),l(-.334,-.112),l(-.239,.198),l(-.155,.466),l(-.381,.452),l(-.326,-.211),l(-.059,-.211),l(.322,-.466),l(.032,-.296),l(-.356,-.917),l(.169,-.113),l(.687,-.58),l(.083,-.141),l(.034,-.466),l(-.532,-.789),l(-.333,-.042),l(-.162,.269),l(-.419,.495),l(-.249,-.112),l(-.23,-.508),l(-.376,-.267),l(-.261,-.366),l(.41,-.325),l(.733,.083),l(.706,-.171),l(.315,-.466),l(.241,-.283),l(.484,-.058),l(.478,.056),l(.249,.38),l(.27,.168),l(.43,.084),l(.628,-.213),l(.225,.395),l(-.569,.438),l(.405,.239),l(.443,.437),l(.079,.254),l(-.596,.58),l(-.242,.41),l(-.104,.367),l(-.085,.621),l(-.109,.649),l(-.242,.353),l(-.194,.099),l(-.165,.071),l(-.197,.184),l(-.479,.678),M(711.938,108.369),l(-.222,-.241),l(-.077,-.271),l(.325,-.642),l(-.055,-.342),l(-.549,-.198),l(-.168,-.171),l(-.146,-.812),l(.583,-.386),l(.522,-.172),l(.646,-.373),l(.037,-.356),l(-.318,-.285),l(.277,-.3),l(.224,-.015),l(.661,.427),l(.373,.085),l(.532,-.201),l(-.004,-1.186),l(.455,-.187),l(.45,-.244),l(.074,-.743),l(.007,-.844),l(-.398,-.758),l(-.098,-.473),l(.166,-.216),l(.618,-.346),l(.063,.072),l(.507,.43),l(.904,.816),l(1.07,.842),l(1.083,.684),l(.627,.285),l(.528,.17),l(1.02,.198),l(.282,.042),l(.304,-.086),l(.866,-.66),l(.461,-.144),l(.002,.1),l(-.308,.358),l(-.335,.558),l(.198,.414),l(.469,.599),l(.197,.356),l(-.561,.272),l(-.447,.244),l(-.534,.158),l(-.365,.015),l(-.488,-.199),l(-.453,.015),l(-.363,.144),l(-.345,.229),l(-.754,.786),l(-.396,.5),l(-.26,.599),l(-.4,-.07),l(-.425,-.241),l(-2.031,-.965),l(-.461,-.085),l(-.72,.044),l(-1.038,.587),l(-.153,-.299),l(-.372,-.356),l(-.339,.029),l(-.266,.115),l(-.439,.272),l(.049,.299),l(1.16,.497),l(.56,.298),l(.302,.27),l(-.391,.214),l(-.303,.029),l(-.305,-.128),l(-.261,.043),l(-.324,.314),l(-.388,.471),l(-.347,.114),
+N(597.917,139.685),l(1.251,-1.545),l(.609,-.539),l(.348,-.239),l(.149,-.103),l(.417,-.016),l(.309,.294),l(.479,.208),l(1.659,.047),l(.371,.041),l(.312,.209),l(.329,.619),l(-.07,.156),l(.042,.24),l(.326,.294),l(.313,.069),l(.258,.238),l(.017,.282),l(-.217,.58),l(-.624,.06),l(-1.036,.062),l(-1.238,-.063),l(-.335,-.125),l(-.301,-.055),l(-.531,.313),l(-.544,.074),l(-.085,-.021),l(-.869,-.214),l(-.559,-.081),l(-.637,-.18),l(-.235,-.493),l(.092,-.113),
+N(362.764,152.723),l(.072,-.625),l(.395,-.876),l(.52,-.552),l(.488,-.566),l(.244,-.509),l(1.175,-2.559),l(.238,-.241),l(1.404,-1.175),l(.345,-.495),l(.051,-.918),l(.305,-1.088),l(.651,-1.075),l(.399,-.34),l(.404,-.198),l(.838,-.51),l(.361,-.495),l(.334,-.777),l(.428,-.851),l(1.635,-.04),l(2.511,0),l(2.677,-.001),l(1.718,.004),l(1.42,-.008),l(.027,.876),l(-.03,1.752),l(.002,.65),l(-.104,.396),l(-.56,-.011),l(-6.005,-.022),l(-.557,.074),l(-.047,.509),l(-.07,2.261),l(-.099,2.6),l(-.144,.128),l(-.809,.287),l(-.726,.315),l(-.575,.427),l(-.249,.383),l(-.01,.707),l(.164,1.539),l(.051,1.102),l(-.212,-.027),l(-.732,.033),l(-2.396,-.014),l(-5.055,-.056),l(-.474,-.013),
+N(514.551,145.841),l(-.374,.027),l(-.336,-.083),l(-.008,-.615),l(-.153,-.437),l(-.108,-.791),l(.187,-.607),l(.188,-.11),l(-.059,-.187),l(.177,-.607),l(.33,-.269),l(.312,.083),l(.069,.315),l(.26,.093),l(.063,.199),l(.116,.326),l(-.106,.42),l(.031,.708),l(.118,.254),l(-.104,.381),l(-.327,.467),l(-.275,.433),
+N(514.177,145.868),l(.374,-.027),l(.008,.288),l(.361,.14),l(.153,.128),l(.186,-.093),l(-.046,.443),l(.397,.001),l(.402,.127),l(.687,-.093),l(.103,-.21),l(.183,-.058),l(.218,.117),l(.424,-.042),l(.595,.112),l(.224,-.035),l(.079,-.105),l(1.358,.222),l(.732,-.14),l(-.022,-.292),l(.225,.175),l(.375,-.016),l(.157,-.099),l(.312,-.422),l(.232,-.073),l(.267,-.495),l(.131,-.297),l(.711,-.637),l(.813,-.889),l(.163,.105),l(.229,-.178),l(.85,-.708),l(.313,-.433),l(.15,.161),l(-.248,.42),l(-.107,.299),l(-.004,.176),l(.099,.064),l(.121,-.024),l(.454,.042),l(.09,.324),l(.001,.508),l(-.003,.358),l(-.49,.034),l(-.401,-.083),l(-.107,.396),l(.073,1.326),l(-.199,.34),l(-.536,.596),l(.003,.946),l(.024,2.075),l(.063,.183),l(-.152,.057),l(-.584,.469),l(-.839,-.108),l(-3.387,-.446),l(-3.362,-.375),l(-.261,-.902),l(-.548,-1.154),l(-1.043,-2.198),
+N(668.627,151.365),l(-.102,-.056),l(-.107,-.325),l(-.922,-1.212),l(-.332,-.987),l(-.03,-.438),l(.156,-.749),l(.546,-.792),l(1.312,-1.852),l(.259,-.184),l(.425,-.128),l(.229,-.184),l(.358,-.227),l(.228,.127),l(.554,.394),l(-.334,.424),l(-.084,.142),l(.023,.31),l(-.067,.622),l(-.203,.296),l(-.182,.354),l(-.065,.692),l(-.1,.494),l(-.317,.805),l(-.473,.707),l(-.417,.833),l(-.014,.353),l(-.114,.438),l(-.228,.142),
+N(389.765,144.543),l(.1,.084),l(.895,.531),l(2.054,1.344),l(.811,.575),l(3.283,2.241),l(1.924,1.26),l(1.292,.824),l(.397,.253),l(2.472,1.469),l(.181,.253),l(-.096,.396),l(.082,.183),l(.393,.28),l(1.111,1.039),l(.229,.027),l(.47,-.314),l(.588,.562),l(.375,.167),l(.748,.024),l(.309,.111),l(.277,.352),l(.099,.522),l(-.161,.679),l(.146,.564),l(2.176,-.408),l(.064,1.017),l(.034,2.203),l(.001,.96),l(-.08,.89),l(-.145,.919),l(-.434,1.246),l(-.596,.794),l(-.339,.271),l(-.29,.129),l(-2.533,.085),l(-1.808,.124),l(-.209,.072),l(-.562,.427),l(-.579,.272),l(-.678,-.053),l(-.581,-.081),l(-1.062,-.173),l(-.36,-.059),l(-.356,-.125),l(-.37,.073),l(-1.22,.713),l(-.947,.458),l(-.304,.228),l(-.314,.793),l(-.274,-.027),l(-.324,-.182),l(-.518,-.209),l(-.272,.101),l(-.638,.625),l(-.492,.667),l(-.393,.822),l(-.174,.227),l(-.45,.102),l(-.551,-.364),l(-.293,-.281),l(-.273,.058),l(-.397,.384),l(-.355,1.217),l(-.292,1.047),l(-.317,.369),l(-.543,.271),l(-.448,.158),l(-.257,.016),l(-.141,.255),l(.058,.749),l(-.133,.876),l(-.261,.92),l(-.172,.326),l(-.046,.156),l(-.08,.043),l(-.159,.1),l(-.604,.399),l(-.352,.059),l(-.148,-.239),l(-.117,-.381),l(-.004,-.297),l(-.147,-.211),l(-.257,-.041),l(-.239,.114),l(-.571,.483),l(-.362,.469),l(-.35,.228),l(-.455,-.436),l(-.566,-.321),l(-.352,.059),l(-.522,.54),l(-.559,-.901),l(-.194,-1.143),l(-.349,-.718),l(-.474,-.478),l(-.265,-.451),l(-.271,-.832),l(-.022,-.339),l(-.246,-.281),l(-.323,-.055),l(-.684,.428),l(-.3,.327),l(-.43,.243),l(-.565,-.152),l(-.356,-.153),l(-.338,-.026),l(-.475,.413),l(-.252,.256),l(-.536,-.265),l(-.882,-.715),l(-.18,-.183),l(-.113,-.028),l(.062,-.142),l(.004,-.565),l(-.082,-.833),l(-.265,-.337),l(-.554,-.322),l(-.181,-.197),l(-.22,-.479),l(-.144,-.663),l(-.251,-1.1),l(.057,-.339),l(.506,-.399),l(.332,-.284),l(.018,-.607),l(.181,-.552),l(.252,-.256),l(.402,-.073),l(.261,.111),l(.568,.83),l(.214,.168),l(.454,.082),l(.107,-.269),l(-.055,-.296),l(.06,-.212),l(.535,.124),l(.713,.137),l(.485,.054),l(.387,-.031),l(.945,-.344),l(1.953,-.026),l(6.457,-.01),l(.379,-1.613),l(-.724,-.787),l(-.186,-1.468),l(-.202,-2.386),l(-.325,-2.753),l(-.178,-1.736),l(-.19,-1.468),l(-.908,-7.962),l(-.049,-.776),l(3.231,-.089),l(.523,-.13),
+N(525.37,142.384),l(.312,-.429),l(.155,-.17),l(.084,.833),l(-.423,.707),l(-.118,.156),l(-.121,.024),l(-.099,-.064),l(.004,-.176),l(.107,-.299),l(.248,-.42),l(-.15,-.161),M(525.923,144.712),l(0,.22),l(.456,.762),l(.408,.465),l(.782,.634),l(.677,.394),l(1.008,.52),l(.392,.154),l(.277,.014),l(.576,-.029),l(.364,.112),l(.873,.973),l(.518,.648),l(.46,.422),l(.81,.365),l(.025,.212),l(-.67,1.06),l(-.615,.721),l(-.883,.807),l(-.776,1.541),l(-.242,.142),l(-.562,-.083),l(-.235,-.084),l(-.252,.071),l(-.278,.509),l(-.062,1.115),l(.001,.791),l(.134,.621),l(-.403,.142),l(-1.046,.073),l(-.627,.27),l(-.367,.283),l(-.29,.495),l(-.131,.551),l(-.204,.283),l(-.444,.255),l(-.544,.1),l(-.292,0),l(-.386,-.042),l(-.326,.029),l(-.382,.283),l(-.22,.297),l(-.125,.508),l(.003,.353),l(-.091,.311),l(-.631,.396),l(-.344,.043),l(-.776,-.21),l(-.717,.058),l(-.896,.27),l(-.768,.298),l(-.283,.099),l(-.416,.145),l(-.241,-.306),l(-.483,-.689),l(.006,-.296),l(-.127,-.253),l(-.933,-1.364),l(-.604,-.971),l(-.226,-.634),l(-.092,-.663),l(1.691,-.815),l(2.35,-1.213),l(5.346,-2.982),l(-.155,-1.453),l(-.581,-.914),l(-.063,-.183),l(-.024,-2.075),l(-.003,-.946),l(.536,-.596),l(.199,-.34),l(-.073,-1.326),l(.107,-.396),l(.401,.083),l(.49,-.034),
+N(405.733,173.04),l(-.568,-.971),l(-.562,-.025),l(-.37,.044),l(-.516,-.181),l(-.97,-.757),l(-.114,-.226),l(.335,-.439),l(-.018,-.212),l(-.179,-.268),l(-.502,-.42),l(-.389,-.266),l(-.422,-.492),l(-.426,-.93),l(-.019,-.396),l(.173,-.665),l(.581,.081),l(.678,.053),l(.579,-.272),l(.562,-.427),l(.209,-.072),l(1.808,-.124),l(2.533,-.085),l(.29,-.129),l(.339,-.271),l(.596,-.794),l(.434,-1.246),l(.145,-.919),l(.08,-.89),l(-.001,-.96),l(-.034,-2.203),l(-.064,-1.017),l(1.672,-.321),l(1.82,-.364),l(3.084,-2.617),l(.834,-.655),l(2.308,-1.454),l(1.607,-.956),l(4.012,-2.241),l(1.632,-.843),l(.265,-.186),l(.832,.137),l(1.646,.442),l(1.008,.333),l(.258,.182),l(1.192,.911),l(.231,-.157),l(1.519,-.729),l(.364,2.145),l(.169,1.298),l(.42,1.028),l(.554,.802),l(.703,.604),l(-.388,.722),l(-.265,.99),l(-.168,1.088),l(-.084,.989),l(.022,.537),l(-.062,.707),l(-.019,1.045),l(-.034,1.088),l(-.056,.466),l(-2.43,2.613),l(-.591,.78),l(-.87,1.333),l(-.572,.794),l(-.007,.678),l(.123,.719),l(.014,.269),l(-.951,.034),l(-.437,.2),l(-.453,.299),l(-.761,.697),l(-.259,.058),l(-.609,-.208),l(-.724,-.193),l(-.884,-.221),l(-.531,-.04),l(-.709,.047),l(-.628,.103),l(-.774,.287),l(-.403,.327),l(-.629,.399),l(-.273,.059),l(-.934,.005),l(-.965,-.277),l(-1.173,-.742),l(-.354,-.083),l(-.467,.116),l(-1.337,.544),l(-.37,.002),l(-.209,-.098),l(-1.095,-1.223),l(-.821,-.277),l(-1.111,-.121),l(-1.174,.108),l(-1.064,.188),l(-.676,.4),l(-.687,1.614),l(-.353,.482),l(-.158,.849),l(-.092,.961),l(-.902,-.503),l(-.727,-.589),l(-.339,-.28),l(-.321,.073),l(-.577,.3),
+N(431.763,171.063),l(-.351,-.407),l(-.575,-.52),l(-.173,-.394),l(-.014,-.269),l(-.123,-.719),l(.007,-.678),l(.572,-.794),l(.87,-1.333),l(.591,-.78),l(2.43,-2.613),l(.056,-.466),l(.034,-1.088),l(.019,-1.045),l(.062,-.707),l(-.022,-.537),l(.084,-.989),l(.168,-1.088),l(.265,-.99),l(.388,-.722),l(-.703,-.604),l(-.554,-.802),l(-.42,-1.028),l(-.169,-1.298),l(-.364,-2.145),l(1.818,-.858),l(.41,-.059),l(5.231,2.554),l(4.941,2.372),l(5.577,2.792),l(1.981,.963),l(-.02,1.045),l(-.016,.946),l(-.036,.636),l(.085,2.5),l(-.038,.749),l(.036,1.002),l(.031,1.229),l(-.04,.283),l(-.839,-.009),l(-1.245,.05),l(-.229,.143),l(-.417,1.245),l(-.583,.809),l(-.122,.438),l(.131,.677),l(-.149,.212),l(-.718,.428),l(-.053,.24),l(.342,.662),l(-.087,.34),l(-.542,.596),l(-.316,.609),l(.219,.352),l(.517,-.088),l(.338,.012),l(.141,.225),l(.221,1.228),l(.137,.522),l(.155,.295),l(.444,.407),l(.266,.465),l(.026,.367),l(-.15,.425),l(-.559,-.208),l(-.321,-.012),l(-.322,.086),l(-.939,.613),l(-.372,.228),l(-.165,.382),l(-.005,.41),l(-.196,.284),l(-2.649,2.275),l(-.386,.087),l(-2.181,.055),l(-.434,.059),l(-.209,.199),l(-.117,.806),l(-.646,1.176),l(-.258,.143),l(-.368,.031),l(-.881,-.009),l(-.818,.273),l(-.754,.386),l(-.466,.271),l(-.224,.03),l(-.225,-.069),l(-.494,-.661),l(-1.363,.686),l(-.449,.158),l(-.24,-.027),l(-.096,-.084),l(-.208,-.183),l(-.382,-1.057),l(-.638,-1.07),l(-1.343,-1.179),l(-1.088,-1.067),l(.323,-.539),l(.29,-.312),l(.24,-.1),l(.481,.082),l(1.187,.191),l(.674,-.032),l(.225,-.143),l(-.047,-.127),l(-.208,-.21),l(-.381,-.633),l(-.205,-.578),l(-.169,-1.228),l(.134,-.651),l(-.119,-1.2),l(-.395,-.887),l(-.923,-1.238),l(-.208,-.083),l(-.627,-.109),
+N(627.173,150.012),l(.483,-.229),l(.515,-.13),l(.341,.012),l(.597,.392),l(.325,.097),l(.584,-.413),l(.332,-.115),l(1.595,-.052),l(.807,-.117),l(.341,-.157),l(.696,-.554),l(.521,-.328),l(.298,-.101),l(.623,.575),l(.771,.235),l(.66,.053),l(.777,-.047),l(.237,.21),l(.056,.38),l(-.472,.75),l(.096,.521),l(.273,.365),l(.943,.615),l(.621,.166),l(.909,.107),l(.197,.143),l(-.19,.132),l(-.826,.482),l(.106,.465),l(-.203,.212),l(-1.261,-.054),l(-.136,.198),l(.057,.395),l(-.283,.382),l(-.585,.792),l(-.221,.142),l(-.533,.241),l(-.171,.127),l(-.27,.396),l(-.303,.932),l(-.388,.975),l(.268,.225),l(.469,.563),l(1.112,1.071),l(.023,.24),l(.042,.522),l(.087,.254),l(.42,.493),l(1.096,.83),l(1.282,1.296),l(.26,.197),l(.636,.069),l(.313,.38),l(.282,1.016),l(.302,.578),l(.638,.605),l(.293,.663),l(.341,1.382),l(.524,2.809),l(-.295,.438),l(-.235,.495),l(.05,.819),l(-.095,.41),l(.056,.664),l(-.027,.099),l(-.364,.551),l(-.447,.439),l(-.254,.127),l(-.509,.1),l(-.419,.17),l(-.501,.354),l(-.591,.622),l(-.579,.354),l(-.325,.043),l(-.512,-.197),l(-.404,-.31),l(-.179,-.141),l(-.153,.424),l(.051,.494),l(.048,.353),l(-.205,.721),l(-.388,.424),l(-.326,.071),l(-.235,-.07),l(-.246,.481),l(-.427,.326),l(-.523,.142),l(-.417,.213),l(-.459,.565),l(-.196,.269),l(-.406,.297),l(-.264,.099),l(-.365,-.042),l(.078,-.861),l(.1,-1.313),l(.151,-.494),l(.215,-.283),l(-.02,-.353),l(-.475,-.437),l(-.749,-.238),l(-.091,-.066),l(.3,-.289),l(.646,-.229),l(.915,-.528),l(.599,-.229),l(.497,.011),l(.688,.194),l(.17,-.27),l(-.03,-.197),l(-.568,-.435),l(-.216,-.422),l(.234,-.425),l(.99,-.571),l(.521,-.229),l(.932,-.443),l(.599,-.187),l(.385,-.285),l(.217,-.509),l(-.054,-1.073),l(.05,-.424),l(.076,-.367),l(-.455,-1.014),l(-.029,-.663),l(.215,-.905),l(.155,-.918),l(-.064,-.578),l(-.214,-.437),l(-.529,-.477),l(-.072,-.282),l(.226,-.439),l(-.136,-.395),l(-.358,-.308),l(-.685,-.391),l(-.471,-.52),l(-.57,-.914),l(-1.683,-2.121),l(-.698,-.772),l(-.637,-.646),l(-.632,-.476),l(-1.234,-.741),l(-.162,-.098),l(-.043,-.494),l(.277,-.369),l(.311,-.101),l(.476,.068),l(.287,-.058),l(.261,-.185),l(.255,-.326),l(-.009,-.508),l(-.87,-.968),l(-.434,-.675),l(-.262,-.083),l(-.39,.171),l(-.509,.483),l(-.287,.058),l(-.47,-.195),l(-.607,-.434),l(-.334,-.689),l(-.338,-.929),l(-.543,-.604),l(-.613,-.575),l(-.45,-.745),
+N(217.961,150.385),l(.304,-.043),l(.84,-.27),l(-.17,-.254),l(-.312,-.112),l(-.369,-.056),l(-.651,.016),l(-.497,-.042),l(-.645,.157),l(-1.193,.92),l(-.371,.029),l(-.653,.001),l(-.211,.113),l(-.189,.452),l(-.396,.284),l(-.32,.043),l(-.786,.086),l(.259,-.325),l(.473,-.312),l(-.128,-.593),l(.282,-.382),l(.114,-.099),l(1.258,-.61),l(1.625,-.47),l(1.164,-.087),l(.842,-.157),l(.825,.041),l(.566,-.044),l(.73,.168),l(.848,.083),l(.603,.197),l(.557,.112),l(.477,.013),l(.499,.268),l(.573,.536),l(.382,.253),l(.581,.168),l(.768,.111),l(1.229,.351),l(1.02,.492),l(.453,.31),l(.374,.55),l(.33,.141),l(.479,.041),l(1.704,.519),l(1.018,.167),l(.327,.239),l(-.344,.58),l(.233,.155),l(.559,.042),l(.756,-.072),l(.495,.168),l(.507,.38),l(.591,.281),l(.381,.296),l(-.233,.085),l(-.981,.087),l(-1.15,.398),l(-.626,.058),l(-1.054,-.209),l(-.9,-.041),l(-.934,.186),l(-.943,.115),l(-.484,.029),l(-.449,-.07),l(.353,-.382),l(.728,-.623),l(.173,-.396),L(229,154.204),l(-.181,-.127),l(-.622,-.14),l(-.7,.001),l(-.603,-.112),l(-.651,-.338),l(-.141,-.748),l(-.258,-.536),l(-.218,-.155),l(-.396,-.027),l(-1.005,.044),l(-.836,-.139),l(-.621,-.225),l(-.956,-.493),l(-.739,-.238),l(-.615,-.069),l(-1.154,-.068),l(-.489,-.098),l(-.855,-.352),
+N(634.036,168.444),l(.808,-.64),l(.121,-.438),l(-.002,-.945),l(-.157,-.507),l(-.419,-.703),l(-.979,-1.279),l(-.255,-.464),l(-.107,-.366),l(-.058,-1.524),l(-.435,-.632),l(-.688,-.659),l(-.285,-.535),l(-.052,-.282),l(-.266,-.153),l(-.893,-.192),l(-.403,-.012),l(-.286,.453),l(-.2,.538),l(-.543,.257),l(-.223,.072),l(-.59,-.265),l(-.835,-.348),l(-.346,.03),l(-1.173,1.178),l(-.37,.411),l(-.481,-.138),l(-.145,-.324),l(.027,-.494),l(.117,-.438),l(.528,-1.569),l(.085,-.41),l(-.249,-1.311),l(-.045,-.113),l(-.414,.045),l(-.489,.2),l(-.423,.003),l(-.186,-.154),l(-.066,-.367),l(.106,-.805),l(-.01,-.423),l(-.118,-.168),l(-.295,-.182),l(-.541,-.166),l(.193,-.185),l(.582,-.455),l(.442,-.581),l(.53,-.61),l(.502,-.355),l(.178,.196),l(.321,.21),l(.769,.08),l(.266,-.213),l(.109,-.339),l(-.119,-.521),l(-.228,-.366),l(-.138,-.592),l(.043,-.325),l(.24,-.241),l(.679,-.314),l(.45,.745),l(.613,.575),l(.543,.604),l(.338,.929),l(.334,.689),l(.607,.434),l(.47,.195),l(.287,-.058),l(.509,-.483),l(.39,-.171),l(.262,.083),l(.434,.675),l(.87,.968),l(.009,.508),l(-.255,.326),l(-.261,.185),l(-.287,.058),l(-.476,-.068),l(-.311,.101),l(-.277,.369),l(.043,.494),l(.162,.098),l(1.234,.741),l(.632,.476),l(.637,.646),l(.698,.772),l(1.683,2.121),l(.57,.914),l(.471,.52),l(.685,.391),l(.358,.308),l(.136,.395),l(-.226,.439),l(.072,.282),l(.529,.477),l(.214,.437),l(.064,.578),l(-.155,.918),l(-.209,.114),l(-.975,.429),l(-.3,.072),l(-.373,-.351),l(-.444,-.181),l(-.476,.186),l(-.392,.285),l(.107,.296),l(.187,.182),l(.103,.211),l(-.095,.24),l(-.248,.058),l(-.469,-.251),l(-.341,-.111),l(-.736,-.165),l(-.533,-.251),
+N(60.074,72.607),l(-.099,.228),l(-.491,.472),l(-.395,.183),l(-.462,.062),L(58,73.461),l(-.961,-.362),l(-.153,-.197),l(.169,-.289),l(.54,-.274),l(.341,-.32),l(.716,.364),l(.3,.091),l(.465,-.26),l(.215,-.213),l(.064,-.366),l(.485,-.047),l(1.107,.135),l(.536,.334),l(.133,.213),l(-.756,.062),l(-.429,0),l(-.59,.184),l(-.11,.092),M(40.092,77.571),l(-.729,-.029),l(-.097,-.24),l(.011,-.3),l(.802,-.243),l(.326,-.211),l(.593,-.423),l(.448,-.137),l(.646,-.077),l(1.427,.253),l(.711,.24),l(-.079,.211),l(-.303,.046),l(-.754,-.074),l(-.496,.031),l(-1.077,.183),l(-.269,.226),l(-1.161,.543),M(38.426,77.979),l(-.515,-.209),l(-.139,-.285),l(.381,-.227),l(.674,.27),l(.093,.195),l(-.122,.15),l(-.372,.105),M(37.896,78.449),l(-.256,.084),l(-.558,.151),l(-1.109,-.058),l(-.387,.135),l(-.398,.434),l(-.31,.15),l(-.854,-.207),l(-.135,-.224),l(.497,-.359),l(.5,-.315),l(.955,-.166),l(.863,-.346),l(.39,.089),l(.461,.224),l(.341,.409),M(29.628,81.29),l(-.168,-.594),l(-.324,-.476),l(.839,-.136),l(.424,.088),l(.436,.238),l(-.244,.268),l(-.26,.06),l(-.073,.297),l(-.22,.09),l(-.412,.164),M(27.543,81.591),l(-.39,.031),l(-.741,.165),l(-.311,-.133),l(-.088,-.178),l(.104,-.119),l(.336,-.268),l(.294,-.09),l(.584,.222),l(.212,.371),M(54.394,157.986),l(-.559,-.356),l(-.044,-.884),l(-.243,-.677),l(.482,-.402),l(-.035,-.2),l(-.156,-.26),l(.052,-.149),l(.173,-.046),l(.354,.158),l(.652,.279),l(.593,.425),l(-.015,.275),l(.238,.046),l(.12,.287),l(.306,.149),l(-.062,.161),L(56,156.933),l(-.172,.204),l(-.766,.195),l(-.374,.23),l(-.295,.425),M(23.015,59.92),l(-1.613,-.646),l(-.75,-.205),l(-.792,-.062),l(-.9,.065),l(-.291,-.095),l(-.431,-.222),l(.179,-.287),l(.516,-.049),l(1.135,.221),l(.579,-.001),l(.543,-.081),l(.538,-.001),l(.828,.285),l(1.725,.362),l(.429,.237),l(.046,.111),l(-.569,-.03),l(-.646,.033),l(-.527,.365),M(99.855,70.993),l(.467,.929),l(-.071,.167),l(-.879,-.272),l(-.621,-.075),l(.067,.441),l(-.056,.228),l(-.935,-.607),L(97.03,71.41),l(.396,-.458),l(.263,-.153),l(.612,-.078),l(.784,.38),l(.771,-.108),M(100.975,73.606),l(.128,.272),l(-.086,.273),l(-.318,.483),l(-.559,-.815),l(-.597,-.909),l(-.04,-.228),l(.095,-.213),l(.407,.029),l(.568,.197),l(.402,.91),M(106.858,78.207),l(-1.872,-1.166),l(-.566,-.555),l(.01,-.467),l(-.559,-.843),l(.071,-.106),l(.456,.06),l(.274,.256),l(1.165,.48),l(.086,.196),l(-.059,.136),l(-.149,.226),l(.296,.436),l(.839,.374),l(.007,.974),M(140.191,127.819),l(-.043,-.094),l(-.198,-.36),l(-.049,-.067),l(-.032,.042),l(-.028,.05),l(-.04,-.092),l(.002,-.664),l(-.331,-.604),l(-.472,-.451),l(-.661,-.451),l(-.512,-.197),l(-.114,-.052),l(-.145,.034),l(.002,.092),l(-.088,.025),l(-.1,-.042),l(-.146,-.143),l(.076,-.076),l(-.073,-.202),l(-.228,-.252),l(-.283,-.025),l(-.312,.084),l(-.932,-.336),l(-.286,-.328),l(-.428,-.244),l(-.383,.042),l(-.932,-.16),l(-.721,.051),l(-.12,-.185),l(-.234,-.067),l(-.046,-.177),l(.094,-.117),l(-.157,-.504),l(.133,-.464),l(-.227,-.096),l(-.127,.008),l(-.249,-.134),l(0,-.101),l(.075,-.093),l(-.029,-.219),l(-.347,-.185),l(-.254,-.286),l(-.415,-.219),l(-.391,-.623),l(-.202,-.076),l(-.203,-.311),l(-.409,-.219),l(-.156,-.529),l(-.002,-.227),l(.178,.007),l(.147,-.164),l(.029,-.326),l(-.208,-.251),l(-.192,-.045),l(-.22,.037),l(-.303,-.126),l(-.535,-.514),l(.078,-.21),l(-.091,-.312),l(-.129,-.067),l(-.044,-.463),l(.058,-.152),l(.119,-.025),l(.099,.067),l(.073,.076),l(-.086,.101),l(.153,.202),l(.285,.126),l(.116,.118),l(.203,.017),l(-.385,-.564),l(-.183,-.144),l(-.021,-.236),l(-.184,-.109),l(-.051,-.344),l(-.13,.006),l(-.011,.144),l(.048,.446),l(-.093,.017),l(-.293,-.194),l(-.119,.042),l(-.516,-.404),l(-.136,-.363),l(-.377,-.514),l(-.531,-.379),l(-.624,-.583),l(-.123,-.142),l(.114,-.101),l(-.327,-.751),l(.161,-.43),l(-.254,-.479),l(-.22,-.355),l(-.738,-.782),l(-.104,-.299),l(.099,-.627),l(.252,-.628),l(.166,-.357),l(.059,-.856),l(-.215,-.785),l(-.692,-1.486),l(-.153,-.916),l(.096,-.287),l(.231,-.244),l(.402,-.201),l(.365,-.717),l(-.365,-.573),l(-.066,-.33),l(.424,-1.593),l(.153,-.575),l(.061,-.634),l(.091,-.778),l(.019,-.179),l(-.153,-.16),l(.08,-.231),l(-.103,-.167),l(.157,-.077),l(-.03,-.186),l(-.046,-.186),l(-.031,-.103),l(-.004,-.058),l(.322,.096),l(.209,-.019),l(.062,-.097),l(-.211,.006),l(-.614,-.122),l(.062,-.707),l(-.103,-.328),l(.017,-.277),l(.587,-.225),l(-.345,-.019),l(-.16,-.142),l(-.129,0),l(-.053,.045),l(.042,.116),l(-.12,.052),l(-.133,-.979),l(-.927,-1.463),l(-.017,-.465),l(.129,-.131),l(.544,.086),l(.632,.217),l(.785,.114),l(.641,.028),l(.546,-.044),l(.415,.086),l(.547,.318),l(.039,.435),l(-.42,.407),l(-.413,.347),l(.532,.146),l(.184,.188),l(.251,.169),l(.029,-.228),l(.161,-.232),l(.393,-.305),l(.21,-.581),l(.102,-.465),l(-.064,-.421),l(-.356,-.958),l(-.158,-.305),l(-.655,-.516),l(.194,.013),l(2.579,.001),l(1.335,.022),l(4.588,-.025),l(3.938,.008),l(2.87,-.001),l(1.687,.006),l(5.117,-.028),l(.74,.011),l(4.13,.021),l(1.089,-.035),l(3.821,.023),l(.875,-.005),l(3.617,-.004),l(4.84,.018),l(.601,-.003),l(2.935,.014),l(2.131,-.012),l(2.781,.029),l(2.915,-.016),l(2.105,.003),l(1.348,-.007),l(2.798,.029),l(2.687,-.029),l(.68,.003),l(-.387,-.588),l(-.131,-.347),l(.501,-.036),l(.896,.748),l(.279,.371),l(.468,.46),l(.833,.451),l(.518,-.076),l(1.425,.208),l(.02,.185),l(.271,-.012),l(.338,.48),l(.16,-.247),l(.502,.013),l(.241,.271),l(.469,.086),l(.064,.185),l(.506,.098),l(.573,-.141),l(.219,-.06),l(.412,-.191),l(.373,-.075),l(.028,.282),l(.197,.116),l(.855,-.083),l(.474,.041),l(.156,.115),l(.196,.144),l(.542,-.049),l(.707,.074),l(1.469,-.592),l(.805,-.189),l(.797,.227),l(.977,.386),l(3.975,1.576),l(2.15,1.061),l(.101,.429),l(.46,.465),l(.628,-.024),l(.178,.135),l(.184,.294),l(.916,.181),l(.307,.235),l(-.11,.318),l(.26,.33),l(2.529,1.05),l(.876,3.16),l(.054,.545),l(-.028,.746),l(-.377,.576),l(-.294,.544),l(-.264,.433),l(-.414,.294),l(-.707,.525),l(-.044,.218),l(.012,.33),l(.371,.427),l(.497,.169),l(.573,.068),l(.524,-.117),l(.925,-.506),l(.939,-.478),l(.88,-.262),l(.919,-.062),l(.944,-.163),l(1.464,-.452),l(.875,-.427),l(-.047,-.362),l(-.16,-.471),l(-.018,-.319),l(.162,-.375),l(.47,-.203),l(.93,-.091),l(1.123,.01),l(1.305,.138),l(1.156,-.197),l(.44,-.275),l(.163,-.512),l(.146,-.434),l(.545,-.164),l(1.754,-.814),l(.534,-.305),l(.968,-.523),l(1.76,-.009),l(2.508,.029),l(1.855,.004),l(1.093,.095),l(.174,-.375),l(.363,-.435),l(.402,-.06),l(1.161,.124),l(1.139,-1.45),l(1.139,-2.22),l(.514,-.626),l(.632,-.526),l(.273,.085),l(.505,.36),l(.381,.085),l(.41,-.176),l(.771,.025),l(.488,.288),l(.174,.274),l(.31,2.819),l(-.077,.229),l(.606,.231),l(.224,0),l(.042,.154),l(-.143,.069),l(.02,.256),l(-.192,.077),l(.16,.291),l(.188,-.153),l(.349,.495),l(-.268,.281),l(.299,-.04),l(.171,.093),l(-.511,.374),l(-.509,.093),l(-.297,-.12),l(-.013,.253),l(-.138,.067),l(-.077,-.107),l(-.231,-.08),l(-.277,.133),l(-.101,.28),l(-.171,-.013),l(-.15,.16),l(-.175,-.347),l(-.746,.28),l(-.204,-.093),l(.12,.413),l(-.666,-.213),l(.199,-.48),l(-.149,-.04),l(-.364,.52),l(-.332,.56),l(-.342,.333),l(-.324,-.227),l(-.249,.439),l(-.346,-.08),l(.122,-.307),l(-.325,.253),l(.165,.16),l(-.326,.293),l(-.318,-.133),l(.105,-.226),l(-.654,.253),l(.065,.359),l(-.264,.04),l(-.161,.373),l(-.352,.106),l(-.333,.679),l(-.404,.505),l(.173,.146),l(.068,.212),l(.168,.053),l(.083,-.08),l(.169,.013),l(-.122,.146),l(-.547,.106),l(.053,.093),l(-.392,.292),l(-.068,.159),l(.337,.027),l(.282,.093),l(.599,.704),l(.055,.398),l(.399,.106),l(.691,-.239),l(-.022,-.186),l(-.14,-.027),l(-.254,-.279),l(-.097,-.04),l(-.009,-.066),l(.196,0),l(.23,.133),l(.218,.358),l(.031,.425),l(-1.599,.292),l(-.032,-.385),l(-.124,-.066),l(-.109,.226),l(-.164,.04),l(-.03,.093),l(-.105,-.106),l(-.159,.266),l(-.164,.04),l(-.294,.04),l(-.045,-.332),l(.198,-.332),l(-.443,.119),l(-.154,-.146),l(-.082,.252),l(-.087,.664),l(-1.429,.132),l(-1.694,.159),l(-1.182,.345),l(-.787,.358),l(-.097,.212),l(-.32,.053),l(-.144,.172),l(-.032,-.04),l(.308,-.756),l(.024,-.106),l(-.071,.027),l(-.41,.994),l(-.079,-.08),l(-.406,.292),l(.218,.318),l(.553,.093),l(-.46,1.515),l(-.302,.429),l(-.259,-.092),l(.043,.251),l(-.062,.185),l(-.237,.145),l(-.462,.501),l(-.292,.304),l(-.167,.026),l(-.075,-.119),l(.177,-.31),l(-.113,-.178),l(-.43,.013),l(-.447,-.343),l(-.148,-.053),l(-.329,-.541),l(.315,-.257),l(.151,-.245),l(-.271,.119),l(-.362,.37),l(.489,.845),l(.033,.356),l(.387,.581),l(.28,.066),l(.104,.765),l(-.101,.238),l(-.151,.23),l(-.125,-.013),l(-.487,.666),l(-.396,.798),l(.034,.053),l(-.13,.132),l(-.107,-.125),l(-.374,.725),l(.026,.125),l(-.226,.04),l(-.137,-.263),l(.342,-.864),l(.195,-.29),l(.247,-.119),l(.061,-.237),l(-.093,-.059),l(-.374,.119),l(.226,-.383),l(-.218,.04),l(-.176,-.093),l(.012,-.191),l(.242,-.04),l(-.077,-.33),l(-.439,.296),l(-.241,-.204),l(-.157,.053),l(-.23,-.396),l(.355,-.171),l(.357,-.053),l(-.005,-.06),l(-.604,-.316),l(-.092,.165),l(-.072,0),l(.107,-.323),l(.089,-.02),l(.21,.159),l(.131,-.06),l(-.098,-.224),l(-.353,-.066),l(-.065,-.112),l(.096,-.112),l(.336,.02),l(.193,-.284),l(-.281,.046),l(-.158,-.059),l(.241,-.37),l(.652,-.152),l(-.328,-.06),l(.146,-.409),l(-.28,.093),l(-.096,.132),l(.11,.079),l(-.315,.191),l(-.035,-.224),l(-.093,.053),l(.051,.224),l(-.081,.086),l(-.051,-.158),l(-.097,-.066),l(-.103,.416),l(-.447,-.079),l(.402,.501),l(-.294,.666),l(.07,.237),l(.272,.488),l(-.055,.139),l(-.466,-.317),l(-.1,-.211),l(.026,.205),l(.174,.218),l(.421,.237),l(.132,.508),l(-.631,-.402),l(-.354,-.007),l(-.118,-.283),l(-.155,-.053),l(.066,.25),l(-.541,-.323),l(-.33,.04),l(.015,-.29),l(.427,-.323),l(-.428,.079),l(-.19,.468),l(.204,.231),l(.457,.046),l(.202,.25),l(.954,.297),l(-.047,.092),l(.554,.165),l(.158,.132),l(-.22,.468),l(-.227,.06),l(-1.042,-.804),l(.708,.811),l(.626,.171),l(-.248,.092),l(.323,.079),l(-.045,.079),l(.061,.06),l(-.034,.25),l(-.312,-.191),l(-.071,.073),l(.104,.211),l(-.216,.02),l(-.656,-.56),l(-.023,.026),l(.419,.475),l(.309,.158),l(.182,-.026),l(.191,.21),l(.018,.31),l(-.298,.059),l(-.492,-.534),l(-.474,-.198),l(-.199,.16),l(.046,.044),l(.44,.145),l(.488,.382),l(-.047,.237),l(.442,-.033),l(.031,-.119),l(.748,.119),l(.151,.382),l(.406,1.212),l(.448,.803),l(-.14,-.092),l(-.262,-.349),l(-.059,-.132),l(-.359,-1.172),l(-.147,-.277),l(-.056,.31),l(.135,0),l(.034,.198),l(-.292,-.066),l(.173,.283),l(.144,.099),l(.228,.58),l(-.144,-.053),l(-.211,-.382),l(.002,.224),l(-.52,-.303),l(-.06,.059),l(.266,.303),l(-.247,.119),l(-.526,-.204),l(.225,.204),l(-.375,.211),l(-.173,-.02),l(-.251,-.21),l(-.024,-.217),l(.083,-.158),l(-.081,-.053),l(-.091,.204),l(.044,.23),l(.116,.211),l(-.107,.158),l(.894,.02),l(.571,-.145),l(.125,.165),l(-.113,.191),l(-.072,.369),l(.14,.066),l(.092,-.257),l(.135,-.369),l(.18,-.105),l(.266,.31),l(.047,.296),l(-.166,.25),l(-.163,-.013),l(-.063,-.099),l(-.316,.474),l(-.254,.197),l(-.483,-.053),l(-.203,-.065),l(-.147,-.066),l(-.136,-.245),l(-.151,.014),l(.141,.244),l(-.075,.013),l(-.538,-.125),l(-.436,-.151),l(.162,.185),l(.269,.026),l(.833,.335),l(-.034,.119),l(-.396,.145),l(.247,.007),l(-.19,.25),l(-.281,.138),l(-.149,0),l(-.481,-.375),l(.242,.395),l(.43,.164),l(.302,-.171),l(.292,.026),l(.11,-.204),l(.04,.178),l(.217,.04),l(.048,.079),l(-.428,.322),l(-.013,.085),l(-.261,.072),l(-1.498,.214),l(-.865,.895),l(-.487,.609),l(-.13,.127),l(-.935,.143),l(-.528,.128),l(-.617,.241),l(-.678,.539),l(-.225,.424),l(-.096,.354),l(-.819,.694),l(-.693,.383),l(-.429,.199),l(-.797,.086),l(-.35,.58),l(-.177,.198),l(-.809,1.125),l(-.273,.781),l(-.459,1.249),l(.236,1.455),l(.387,.925),l(.456,.873),l(.934,1.562),l(.352,1.746),l(.486,1.194),l(-.075,.092),l(.287,.276),l(.123,.333),l(.062,.827),l(-.301,1.536),l(-.064,.278),l(-.31,.415),l(.108,.424),l(-.02,.252),l(-.393,.551),l(-.017,-.092),l(.129,-.241),l(-.025,-.138),l(-.256,.035),l(-.38,.137),l(-.291,-.126),l(-.509,.138),l(-.12,-.329),l(.014,-.233),l(-.567,-1.068),l(-.764,-.138),l(-.204,-.352),l(-.113,-.819),l(-.423,-.229),l(-.144,-.702),l(-.373,.093),l(-.608,-1.08),l(-.375,-.482),l(.296,0),l(.375,-.438),l(.048,-.226),l(-.167,-.226),l(-.471,.407),l(-.277,-.208),l(.126,-.573),l(.147,-.758),l(.158,-1.043),l(-.293,-.452),l(-.258,-.169),l(-.496,-.126),l(-.832,-.987),l(-.875,-.804),l(-.528,-.168),l(-.43,.072),l(-.536,.298),l(-.456,.354),l(-1.202,.299),l(-.273,-.213),l(-.131,-.62),l(-.253,-.254),l(-.264,-.113),l(-.752,-.069),l(-.516,-.296),l(-.22,-.233),l(-.504,.138),l(-1.052,.115),l(-.653,-.184),l(-.047,.298),l(-.64,.099),l(-.183,0),l(-.578,-.926),l(-.238,.781),l(-.447,-.135),l(-.65,.001),l(-1.328,-.04),l(-.672,.439),l(-.39,.055),l(-1,-.459),l(-.096,.009),l(-.142,.014),l(-.362,.528),l(.201,.229),l(.303,0),l(.211,0),l(.537,-.207),l(.406,.092),l(.676,.482),l(-.68,.373),l(.02,.254),l(.263,.353),l(.593,.146),l(.229,.217),l(.35,.334),l(-.533,.136),l(-.503,-.084),l(-.276,-.419),l(-.79,-.271),l(-.224,-.211),l(-.265,-.056),l(-.013,.02),l(-.209,.32),l(.209,.154),l(.248,.183),l(-.248,.179),l(-.069,.05),l(-.447,-.459),l(-.476,.192),l(-.287,.291),l(-1.025,-.472),l(-.419,-.494),l(-1.16,-.642),l(-.615,.066),l(.554,.393),l(-.307,.187),l(-1.17,-.083),l(-.886,-.252),l(-.896,-.168),l(-1.547,.173),l(-.632,.328),l(-.392,-.015),l(-.433,-.031),l(-.135,-.49),l(-.333,.057),l(-.112,.184),l(.474,.731),l(-.877,.64),l(-.808,.577),l(-.915,.317),l(-.419,.043),l(-.414,-.056),l(-.728,-.111),l(-.126,.198),l(.437,.437),l(-.239,.396),l(-.327,.199),l(-.631,.114),l(-.737,.27),l(-.268,.17),l(.558,.352),l(.111,.169),l(-.659,.694),l(-.154,.297),l(-.012,.848),l(.144,.636),l(.271,.762),l(.425,.903),l(-.347,-.119),l(-.816,-.377),l(-.296,.001),l(-.416,.116),l(-.264,-.069),l(-1.029,-.56),l(-.921,-.32),l(-.375,-.365),l(-.336,-.592),l(-.332,-.932),l(-.078,-.467),l(-.268,-.253),l(-.657,-.576),l(-.845,-1.042),l(-.744,-1.227),l(-.663,-1.029),l(-.363,-.366),l(-.412,-.252),l(-.783,-.321),l(-.475,-.082),l(-.643,.018),l(-.468,.201),l(-.576,.541),l(-.418,.413),l(-.283,.37),l(-.416,.158),l(-.501,-.011),l(-.337,-.069),l(-1.104,-.503),l(-1.092,-.659),l(-.445,-.549),l(-.318,-.847),l(-.284,-.678),l(-.179,-.226),l(-.708,-.491),l(-.837,-.519),l(-.766,-.632),l(-.631,-.662),l(-.209,-.112),l(-1.892,-.046),l(-1.858,-.003),l(-.096,.892),l(-.213,.101),l(-1.867,.011),l(-.966,-.037),l(-1.544,-.02),l(-1.662,-.019),l(-.338,-.055),l(-3.516,-1.112),l(-2.811,-.933),l(-1.186,-.39),l(-.267,-.154),l(-.316,-.31),l(-2.381,.084),l(-2.367,.155),l(-.34,.017),M(49.818,152.776),l(-.122,.086),l(-.279,.03),l(-.111,-.131),l(-.177,-.005),l(-.324,.051),l(-.304,-.39),l(-.071,-.263),l(.339,-.01),l(.299,-.253),l(.188,.218),l(.106,.294),l(.223,.096),l(.233,.279),M(52.785,154.312),l(-.155,-.081),l(-.085,-.356),l(-.461,-.321),l(.095,-.229),l(.143,-.058),l(.366,.209),l(.344,.055),l(.616,.356),l(-.005,.172),l(-.294,.184),l(-.563,.069),M(111.683,77.224),l(-.138,.415),l(-.45,.067),l(-.324,.113),l(-.295,.247),l(-.321,-.137),l(-.185,-.21),l(.087,-.443),l(.086,-.443),l(-.438,-.675),l(-.463,-.319),l(-.199,-.271),l(-1.281,.055),l(-.437,.098),l(-.153,.161),l(-.496,.097),l(-.019,-.193),l(-.034,-.432),l(.212,-.272),l(.184,-.212),l(-.378,-.347),l(-.641,-.438),l(-.693,-.696),l(-.723,-.317),l(-.453,-.136),l(.132,-.35),l(-.569,-.592),l(-.099,-.213),l(.371,-.229),l(-.068,-.122),l(-.301,-.152),l(-.445,-.076),l(-.392,-.274),l(-.237,-.259),l(-.57,-.305),l(-1,-.411),l(-.479,-.765),l(-.217,-.583),l(-.367,-.399),l(-.357,.016),l(-.101,.814),l(.42,.873),l(.104,.306),l(-.047,.153),l(-.701,-.136),l(-.272,-.076),l(-.511,-.504),l(-.4,-.459),l(-.537,.139),l(-1.219,-.228),l(1.263,.718),l(.032,.214),l(-1.62,.171),l(-1.093,-.35),l(-1.388,-.948),l(-.543,-.292),l(-.664,-.043),l(-.079,0),l(-.933,-.213),l(-1.3,-.536),l(.928,-.248),l(.135,-.169),L(90.8,67.129),l(-.384,-.153),l(-.792,.156),l(-.454,.14),l(-.656,.017),l(-1.058,-.06),l(-1.068,-.245),l(.027,-.247),l(-.148,-.186),l(-.325,-.108),l(-.359,.016),l(-.47,.202),l(-1.036,.049),l(-1.465,-.122),L(80.46,66.64),l(-.786,-.091),l(-.248,-.108),l(-.651,-.387),l(-.427,-.527),l(-.301,.218),l(-.788,.157),l(-.89,-.293),l(-.234,-.326),l(-.417,-.139),l(-.872,-.248),l(-1.538,-.23),l(-.817,-.248),l(-.671,-.342),l(-.553,.235),l(-.675,.079),l(.06,.437),l(-.193,.062),l(-.389,.25),l(-.249,.405),l(1.119,.293),l(.174,.294),l(-.096,.388),l(-.428,.449),l(-.458,.001),l(-.804,-.214),l(-.586,-.061),l(-.568,.094),l(-.978,.603),l(-1.066,.217),l(-.936,.448),l(-1.035,.448),l(-1.095,.109),l(.178,-.308),l(.063,-.123),l(.72,-.401),l(-.093,-.385),l(-.655,-.523),l(.004,-.108),L(64.1,66.19),l(.411,-.482),l(.157,-.42),l(.736,-.312),l(.87,-.235),l(1.165,-.018),l(1.085,.123),l(.239,-.156),l(-1.239,-.466),l(-.971,-.389),l(-1.043,.049),l(-.226,.219),l(-.449,.095),l(-.573,.438),l(-.865,.375),l(-1.019,.282),L(61.553,65.9),l(-.406,.094),l(-.298,.14),l(.131,.325),l(-.177,.526),l(-.563,.34),l(-.564,.078),L(59,67.544),l(-.592,.278),l(-.681,.601),l(-.035,.292),l(.38,.168),l(.36,.03),l(.667,.106),l(.465,.229),l(-.075,.184),l(-.43,.338),l(-.625,.2),l(-.557,.277),l(-.423,.398),l(-.544,.383),l(-.675,.093),l(-1.434,.308),l(-.678,.397),l(-1.036,.337),l(-.7,.367),l(.52,.5),l(-.1,.167),l(-1.106,.412),l(-.897,.153),l(-.778,.168),L(49.51,74.19),l(-1.214,.456),L(48.1,74.828),l(-.274,.394),l(-.753,.439),l(-1.193,.229),l(-1.234,.184),l(-.973,-.345),l(.001,-.181),l(.332,-.348),l(.763,-.273),l(.306,-.212),l(.445,-.364),l(1.171,-.441),l(1.403,.073),l(-.12,-.212),l(.02,-.516),l(.47,-.304),l(.725,-.291),l(.754,-.366),l(.266,-.214),l(.002,-.731),l(.246,-.749),l(.693,-.49),l(.194,-.398),l(.034,-.412),l(-.633,.122),l(-1.251,.186),l(-.676,-.029),l(-.5,-.597),l(-.266,.062),l(-.613,.216),l(-.136,.23),l(.239,.352),l(.021,.352),l(-.169,.046),L(47,70.115),l(-.567,-.32),l(-.487,-.397),l(-.509,-.291),l(-.56,-.03),l(-.812,-.106),l(-.91,.094),l(.028,.138),l(-.644,.338),l(-1.175,.14),l(-.649,-.09),l(-.064,-.123),l(-.082,-.107),l(-.125,-1.028),l(.3,-.508),l(-.142,-.431),l(-.864,-1.002),l(-1.43,.437),l(-.738,.078),l(-.406,.202),l(-1.091,.094),l(-.4,-.23),l(-.394,-.355),l(-.466,-.325),l(-1.007,-.463),l(-.179,-.28),l(.292,-.171),l(.337,-.437),l(.704,.139),l(1.312,.309),l(.69,.03),l(.238,-.234),l(-.375,-.482),l(-.458,-.264),l(-.363,0),l(-.541,.22),l(-.528,-.015),l(-1.342,-.513),l(-.623,-.186),l(-.197,.016),l(-.858,-.029),l(-.024,-.078),l(-.623,-.985),l(.79,-.19),l(.071,-.456),l(.495,-.221),l(.102,-.299),l(.227,-.347),l(.893,-.491),l(.337,-.38),l(.386,-.301),l(.527,-.476),l(.39,-.175),l(.719,.109),l(.98,.268),l(.485,.094),l(.752,-.144),l(.427,-.254),l(.675,-.429),l(1.252,-.257),l(.774,-.033),l(.955,-.049),l(.354,-.175),l(.187,-.478),l(-.259,-.669),l(-.814,-.686),l(.026,-.096),l(.927,-.034),l(.343,-.256),l(-.25,-.384),l(-.497,-.256),l(-.367,-.08),l(-1.88,.389),L(39.33,56.53),l(-.534,.289),l(-.496,.065),l(-1.907,-.333),l(-.848,-.031),L(34.8,56.49),l(-1.27,.162),l(-1.265,-.029),l(-1.349,-.174),l(-.53,-.207),l(-.183,-.788),l(.144,-.146),l(.636,-.033),l(1.008,-.002),l(.446,-.179),l(-1.057,-.241),l(-1.912,-.304),L(28.13,54.31),l(-1.285,-.208),l(.219,-.114),l(.781,-.262),l(1.568,-.214),l(1.325,-.328),l(.958,-.214),l(1.058,-.361),l(.953,-.23),l(1.399,-.281),l(1.513,.128),l(-.158,.523),l(.023,.277),l(1.051,.161),l(1.359,.095),l(1.074,-.019),l(.657,-.099),l(.784,-.246),l(.55,-.295),l(.262,-.083),l(.752,.064),l(.751,.113),l(1.021,-.051),l(.2,-.327),l(.007,-.18),l(-.689,-.064),l(-1.946,-.292),l(-1.283,-.047),l(-.312,-.755),l(-1.473,-.162),l(-.96,-.031),l(-1.573,-.096),l(-.194,-.511),l(-.484,-.312),l(-1.042,-.461),l(-.512,-.148),l(-2.66,-.659),l(-2.008,-.545),l(.317,-.167),l(.812,-.402),l(.086,-.485),l(2.136,-.054),l(.99,-.069),l(1.829,-.288),l(.784,-.354),l(.452,-.623),l(.788,-.575),l(.616,-.525),l(.818,-.41),l(.742,-.224),l(1.066,-.104),l(1.133,-.241),l(1.047,-.036),l(1.804,.065),l(.146,-.188),l(-.156,-.205),L(44.47,42.83),l(.018,-.206),l(1.936,-.089),l(1.143,.032),l(.974,-.054),l(1.344,-.14),l(1.098,-.416),l(.918,-.417),l(.957,-.019),l(.282,.051),l(.675,.241),l(.156,.172),l(-.383,.139),l(.017,.344),l(1.049,.136),l(.424,.034),l(.536,-.293),l(.297,-.208),l(1.419,.187),l(1.534,.049),l(1.062,.049),l(.715,.033),l(.711,.257),l(.359,.274),l(.783,.358),l(.494,.085),l(.421,-.086),l(1.292,.117),l(1.124,.015),l(1.556,-.054),l(1.449,-.088),l(1.213,.1),l(1.377,.254),l(.883,.118),l(3.424,.13),l(1.279,.168),l(.743,.169),l(2.027,-.038),l(2.339,-.141),l(1.123,.236),l(2.441,.791),l(1.206,.301),l(.227,.008),l(.102,.483),l(-.003,2.855),l(.039,2.259),l(.052,2.335),l(.129,2.796),l(-.026,2.183),l(-.043,4.334),l(.026,2.167),l(.089,1.046),l(.196,.279),l(.84,.074),l(2.424,-.122),l(.739,.059),l(.332,.388),l(.173,.387),l(.348,.292),l(2.162,1.318),l(.945,.673),l(.238,-.325),l(.848,-.205),l(1.225,-.67),l(.731,-.498),l(.495,-.126),l(.832,.073),l(.316,.199),l(.371,.492),l(.35,.322),l(2.048,1.175),l(.814,.58),l(1.769,1.768),l(1.67,1.882),l(.512,.393),l(.189,.029),l(.98,.314),l(2.025,.763),l(.402,.255),l(-.163,.788),l(.393,.777),
+N(643.755,159.873),l(-1.092,-.52),l(-.637,-.337),l(-.203,-1.284),l(.036,-.282),l(.24,-.241),l(.42,-.241),l(.721,-.623),l(.493,.056),l(.049,-.17),l(.24,-.396),l(.239,.028),l(.573,.225),l(.321,-.312),l(.439,-.001),l(.798,-.171),l(.596,.69),l(-.163,.17),l(-.443,.354),l(-.412,.538),l(-.285,.734),l(.14,.296),l(-.22,.311),l(-.292,.085),l(-1.026,.383),l(-.532,.707),M(627.173,150.012),l(-.679,.314),l(-.24,.241),l(-.043,.325),l(.138,.592),l(.228,.366),l(.119,.521),l(-.109,.339),l(-.266,.213),l(-.769,-.08),l(-.321,-.21),l(-.178,-.196),l(-.153,-.239),l(-.111,-.38),l(-.628,.413),l(-.647,.159),l(-.246,-.083),l(-.378,-.266),l(-.341,-.746),l(-.291,-.379),l(-.481,.045),l(-.507,.003),l(-.228,-.098),l(-.117,-.352),l(.729,-1.584),l(-.033,-.268),l(-.521,-.096),l(-.554,.074),l(-.202,-.324),l(-.277,-1.762),l(-.156,-.126),l(-.479,.017),l(-.771,.089),l(-.819,.442),l(-.312,.086),l(-.216,-.069),l(0,-.268),l(.224,-.58),l(-.163,-.705),l(-.075,-.465),l(.617,-.85),l(.191,-.198),l(.487,-.271),l(.611,-.525),l(.429,-.722),l(.353,-.862),l(-.02,-.875),l(-.195,-1.649),l(-.146,-.14),l(-.504,.031),l(-.287,-.041),l(-.217,-.309),l(-.243,-.901),l(-.397,-.435),l(-.504,-.279),l(-.277,.044),l(-.306,.34),l(-.001,.127),l(-.624,-.081),l(-.73,-.179),l(-.657,-.081),l(-.3,-.055),l(-.102,-.056),l(.138,-.269),l(.354,-.454),l(-.046,-.38),l(-.716,-.715),l(-.455,-.392),l(-1.377,.84),l(-.377,.044),l(-.975,-.319),l(-.286,-.167),l(-.355,.087),l(-.546,.299),l(-1.105,.726),l(-.829,.258),l(-.543,.37),l(-1.123,1.107),l(-.397,.27),l(-.714,.216),l(-.784,.033),l(-.189,.1),l(-.329,-.619),l(-.312,-.209),l(-.371,-.041),l(-1.659,-.047),L(601,137.538),l(-.309,-.294),l(-.417,.016),l(-.149,.103),l(-.348,.239),l(-.609,.539),l(-1.251,1.545),l(-.212,-.662),l(.052,-.861),l(-.139,-.183),l(-.231,-.069),l(-.471,.102),l(-.345,.129),l(-.655,-.159),l(-.339,.281),l(-.341,-.116),l(-.849,.066),l(-.319,-.364),l(-.63,-.281),l(-.407,0),l(-.08,.331),l(-.271,.083),l(-.685,-.38),l(.01,.364),l(-.237,.099),l(-.141,-.463),l(-.54,-.496),l(-.365,.066),l(-.935,-.066),l(-.014,-.265),l(.175,-.396),l(-.326,-.017),l(-.333,.248),l(-1.451,-.893),l(.069,-.281),l(-.178,-.38),l(-.289,-.166),l(-.71,.116),l(-.158,.166),l(-.657,-.794),l(-.454,-.281),l(-.15,.132),l(-.472,-.215),l(-.726,-.595),l(-.867,-.264),l(-.132,-.612),l(-1.079,-.199),l(-.186,.182),l(-.275,-.066),l(-.134,.513),l(-.276,.314),l(-.299,-.05),l(-.24,-.43),l(-.859,-.596),l(-.154,.066),l(-.756,-.248),l(.116,-.364),l(-1.078,-.579),l(-.363,.116),l(-.772,-.843),l(-.383,-.248),l(-.477,.314),l(-.198,-.066),l(-.099,-.43),l(.215,-.215),l(-.272,-.364),l(.104,-.446),l(-.579,-.595),l(-.157,-.694),l(.785,-.198),l(.033,.364),l(.337,.264),l(.368,-.049),l(.376,-.281),l(.578,-.364),l(-.367,-.694),l(.104,-.414),l(-.68,-.099),l(-.044,-.182),l(-.092,-.078),l(-.718,-.096),l(-.294,-.221),l(-.037,-.552),l(-.073,-.589),l(.184,-.184),l(.331,-.221),l(-.221,-.258),l(-.441,-.405),l(-.81,-.11),l(-.221,-.515),l(-.441,-1.03),l(0,-.515),l(-.502,.152),l(-.147,-.126),l(-.305,-.111),l(-1.337,-.104),l(-.565,-.436),l(-.178,-.09),l(-.104,-.199),l(-.239,0),l(-.52,.196),l(-.252,-.281),l(-.198,-.218),l(-.301,-.07),l(.312,-.516),l(-.007,-.501),l(-.213,-.247),l(-.373,-.323),l(-.625,.009),l(-.282,.128),l(-.004,-.456),l(-.554,-.117),l(-.296,-.047),l(-.281,.21),l(-.105,-.112),l(-.313,-.14),l(-.048,-.088),l(-.236,-.012),l(-.01,-.269),l(.574,.059),l(.192,-.145),l(.354,-.136),l(.08,-.249),l(.181,-.185),l(-.2,-.163),l(.152,-.36),l(-.245,-.237),l(.126,-.428),l(-.049,-.123),l(-.152,-.012),l(-.028,-.246),l(.009,-.284),l(-.295,-.494),l(-.273,-.154),l(-.692,-.039),l(-.22,-.06),l(-.229,.162),l(-.463,.045),l(-.325,-.394),l(-.077,-.305),l(.207,-.223),l(-.023,-1.031),l(.011,-.069),l(.139,-.739),l(.129,-.213),l(.274,-.186),l(1.422,-.704),l(1.737,-.734),l(.359,-.03),l(.06,.071),l(.183,.567),l(.344,.055),l(.507,-.145),l(.885,-.132),l(.268,-.243),l(.463,-.784),l(.467,-.472),l(.238,-.03),l(1.248,.235),l(.459,-.017),l(.478,-.102),l(.646,-.345),l(.638,-.701),l(.405,-.301),l(.445,-.145),l(1.338,-.349),l(.97,-.219),l(.325,-.187),l(.051,-.157),l(-.031,-.194),l(-.139,-.86),l(.02,-.399),l(.32,-.401),l(.705,-.546),l(.222,-.33),l(-.119,-.47),l(-.29,-.441),l(-.345,-.627),l(-.03,-1.357),l(-.483,-.141),l(-.366,.06),l(-.232,-.185),l(.068,-.215),l(.215,-.302),l(.393,-.188),l(1.799,-.254),l(1.082,-.207),l(.35,-.06),l(.5,.184),l(1.133,.238),l(.394,-.074),l(.231,-.145),l(.156,-.245),l(-.126,-.286),l(-.622,-.514),l(.137,-.418),l(.286,-.605),l(.438,-.794),l(.516,-1.141),l(.427,-.507),l(1.096,.254),l(.721,.141),l(.594,.141),l(1.402,.079),l(.718,-.062),l(.417,-.103),l(.444,-.392),l(.157,-.39),l(-.213,-.707),l(-.097,-.75),l(.34,-.581),l(.428,-.277),l(1.199,-.093),l(.289,-.06),l(.306,-.219),l(.035,-.478),l(.011,-.275),l(.279,-.262),l(.542,-.148),l(.551,-.034),l(.228,-.014),l(.569,-.003),l(.244,-.074),l(.062,.145),l(.131,.405),l(.24,.563),l(.371,.433),l(1.301,.745),l(.834,.415),l(.614,.069),l(.731,.167),l(.633,.144),l(.354,.143),l(.568,.618),l(1.07,1.451),l(.401,.66),l(-.215,.447),l(-.237,.75),l(-.214,.389),l(-.369,.347),l(-.035,.129),l(.105,.43),l(.233,.229),l(.724,.312),l(1.062,.181),l(1.505,.021),l(.995,.038),l(.668,.083),l(.998,.224),l(.632,.268),l(1.645,.806),l(.839,.31),l(.744,.096),l(.105,.542),l(1.571,2.161),l(.467,.439),l(.444,.254),l(1.979,.018),l(1.241,.207),l(.802,.109),l(1.165,.022),l(2.861,-.059),l(.937,.023),l(1.164,.022),l(1.69,.119),l(.521,.168),l(.815,.551),l(1.006,.365),l(1.599,.433),l(.929,.123),l(.663,-.061),l(.61,.067),l(.253,.297),l(.433,.197),l(.481,-.017),l(.686,-.289),l(1.44,-.534),l(.303,-.101),l(.736,-.274),l(.816,-.289),l(1.204,-.349),l(1.339,-.007),l(1.514,-.065),l(.987,.08),l(.651,-.061),l(1.941,-.737),l(.265,-.172),l(1.111,-1.046),l(.67,-.389),l(1.265,-.292),l(.326,-.259),l(.123,-.271),l(-.188,-.228),l(-.599,-.411),l(-.389,-.569),l(-.003,-.343),l(.214,-.401),l(.539,-.589),l(.457,-.231),l(.316,-.073),l(.718,.154),l(.668,.382),l(.592,.125),l(.982,-.005),l(.744,-.047),l(.742,-.433),l(1.192,-.91),l(.224,.013),l(.438,.012),l(.624,.054),l(.896,-.134),l(.638,-.248),l(.347,-.188),l(.241,-.216),l(.312,-.82),l(.363,-.333),l(.47,-.204),l(.464,-.045),l(.483,.127),l(.353,-.189),l(.831,-.278),l(.539,-.146),l(.937,-.221),l(.854,-.033),l(.432,.099),l(1.074,.008),l(.464,.127),l(.414,-.218),l(.107,-.217),l(-.048,-.273),l(-.599,-.501),l(-.879,-.99),l(-.797,-.5),l(-.538,-.199),l(-.928,-.212),l(-.438,.002),l(-1.191,.786),l(-.292,-.07),l(-.431,-.416),l(-.317,-.085),l(-.576,.018),l(-.754,.062),l(-.929,.395),l(-.342,.045),l(-.051,-.029),l(-.269,-.836),l(.381,-.58),l(1.224,-1.959),l(.687,-1.207),l(.295,-.31),l(.046,.018),l(.452,.172),l(1.126,.574),l(.343,-.016),l(.438,-.089),l(2.44,-.752),l(.779,-.339),l(.123,-.233),l(-.056,-.306),l(-.35,-.348),l(-.062,-.146),l(.103,-.249),l(.422,-.426),l(.416,-.543),l(.667,-.779),l(.599,-.545),l(1.371,-.608),l(.167,-.794),l(-.107,-.249),l(-.465,-.306),l(-.558,-.026),l(-.822,.078),l(.119,-.25),l(.375,-.282),l(1.193,-.787),l(.478,-.165),l(.602,-.136),l(1.854,-.143),l(.836,-.123),l(1.203,-.109),l(.917,-.049),l(1.148,.215),l(1.037,.481),l(.683,.188),l(1.386,-.125),l(.539,.026),l(.763,.467),l(.742,.952),l(1.087,2.384),l(.94,1.588),l(.927,1.903),l(.436,.389),l(.507,.2),l(1.247,.341),l(1.523,.253),l(2.659,.839),l(.205,.144),l(.297,.866),l(.44,1.283),l(.261,.446),l(.68,-.033),l(.649,-.018),l(1.657,-.052),l(.604,-.22),l(.953,-.308),l(1.357,-.31),l(1.181,-.208),l(.902,-.034),l(.246,.114),l(.064,.259),l(.116,.389),l(.017,.504),l(-.566,.407),l(-.66,.393),l(-.291,.707),l(-.278,.893),l(-.538,1.066),l(-.627,1.08),l(-.329,.432),l(-.551,.69),l(-.47,.347),l(-.547,-.098),l(-.679,-.225),l(-.685,-.24),l(-.396,-.041),l(-1.664,.982),l(-.048,.557),l(.332,.897),l(.062,.656),l(-.006,.613),l(-.025,.385),l(-.097,.128),l(.112,.299),l(-.156,.329),l(-.511,.43),l(-1.252,.462),l(-.111,.058),l(-.579,-.68),l(-.247,.001),l(-.253,.129),l(-.383,.358),l(-.23,.713),l(-.955,.532),l(-.62,.259),l(-.538,.017),l(-.452,-.054),l(-.333,-.126),l(-.392,.059),l(-.273,.243),l(-.025,.342),l(.508,.765),l(.046,.113),l(-.527,.159),l(-.975,.048),l(-.508,-.153),l(-.493,-.253),l(-.273,-.396),l(-.448,.017),l(-.386,.13),l(-.686,1.027),l(-.636,.543),l(-1.032,.545),l(-1.533,.604),l(-.52,.329),l(-.415,.442),l(-.379,.528),l(-.066,-.092),l(-.417,.171),l(-1.222,.13),l(-.728,.171),l(-2.248,.925),l(-.632,.37),l(-.566,.469),l(-.604,.271),l(-.336,.015),l(.13,-.255),l(.862,-.682),l(.33,-.354),l(-.47,-.113),l(-.37,.072),l(-.153,-.297),l(.058,-.156),l(.953,-.781),l(.269,-.384),l(.55,-.413),l(.159,-.2),l(-.057,-.298),l(-.73,-.553),l(-.727,-.283),l(-.131,-.014),l(-.628,.03),l(-.166,.015),l(-.494,.371),l(-1.146,1.183),l(-.355,.157),l(-.643,.086),l(-.613,.243),l(-.36,.199),L(665.49,112),l(-.136,.411),l(-.131,.255),l(-.251,.255),l(-.437,.128),l(-.493,-.013),l(-.326,.27),l(-.307,.114),l(-.455,-.565),l(-.355,-.014),l(-.349,.128),l(-.396,.638),l(-.301,.694),l(.088,.34),l(.245,.368),l(.558,.268),l(.8,.268),l(1.21,-.045),l(.29,.254),l(-.019,.538),l(-.123,.581),l(.057,.538),l(.261,.283),l(.733,.069),l(.698,-.157),l(.76,-.525),l(.509,-.497),l(.552,-.228),l(.534,-.128),l(.287,.07),l(.895,.621),l(.543,.197),l(1.023,-.087),l(.361,.027),l(.471,.141),l(.274,0),l(-.248,.708),l(-.057,.552),l(-.612,-.197),l(-.297,-.084),l(-.525,.058),l(-1.677,.555),l(-.707,.44),l(-.072,.735),l(-.522,.157),l(-.146,-.113),l(-.017,-.269),l(-.127,-.084),l(-.501,.114),l(.138,.466),l(-.152,.368),l(-.485,.496),l(-1.397,1.119),l(-.126,.226),l(.039,.55),l(.62,.225),l(.712,.492),l(.785,.521),l(.391,.535),l(.424,1.241),l(.668,.647),l(.175,.437),l(-.13,.677),l(.172,.183),l(.694,.295),l(.399,.592),l(.562,.253),l(.272,.268),l(.087,.31),l(-.049,.155),l(-.789,.369),l(.088,.07),l(.425,.31),l(.314,.79),l(-.019,.296),l(-.141,.184),l(-.534,.043),l(-.651,.213),l(-.948,.552),l(-.849,.213),l(-.629,.297),l(.72,.21),l(.378,.056),l(.944,-.425),l(.488,-.058),l(.162,.056),l(.524,.592),l(.387,.168),l(.456,.027),l(.009,.155),l(-.231,.311),l(-.382,.227),l(-.304,.241),l(.11,.155),l(.326,-.029),l(.202,.084),l(-.184,.325),l(-.298,.749),l(-.192,.649),l(.028,.353),l(-.22,.452),l(-.209,.127),l(-.35,-.338),l(-.146,.142),l(-.569,.763),l(-.401,.622),l(-.215,.622),l(-.127,.296),l(-.595,.425),l(-.251,.438),l(-.254,.184),l(-.569,.029),l(-.382,.227),l(.279,.719),l(-.264,.508),l(.076,.593),l(-.093,.269),l(-.207,.269),l(-.532,.199),l(-.161,.282),l(-.174,.396),l(-.294,.636),l(-.626,.354),l(-.412,.495),l(-.492,-.14),l(-.443,-.069),l(-.142,.113),l(-.145,.198),l(.118,.833),l(-.213,.142),l(-.772,.651),l(-.356,.127),l(-.628,.171),l(-.563,.467),l(-.571,.213),l(-.107,.113),l(-.008,.48),l(-.133,.156),l(-.568,.058),l(-.5,.114),l(-.341,.438),l(-.364,-.126),l(-.52,-.168),l(-.274,.057),l(-.315,.326),l(-.435,.198),l(-.643,.1),l(-.047,-.465),l(-.52,.057),l(-.699,.213),l(-.32,.198),l(-.285,-.042),l(-.401,-.493),l(-.163,-.155),l(-.191,.283),l(.095,.169),l(-.045,.212),l(-.047,.691),l(-.209,.297),l(-.416,.114),l(-.501,-.182),l(-.123,.282),l(-.001,.24),l(-.146,.155),l(-.615,.058),l(-.366,.114),l(-.596,.043),l(-.463,-.211),l(-.217,.1),l(-.439,.48),l(-.227,.071),l(-.774,-.041),l(-.747,.227),l(-.406,.326),l(-.451,-.027),l(-.277,-.084),l(-.011,.057),l(-.069,.353),l(-.29,.396),l(.011,.113),l(.48,.634),l(.269,.126),l(.043,.198),l(-.36,.269),l(-.763,.157),l(-.481,-.719),l(-.241,-.691),l(.012,-.395),l(.396,-.777),l(-.015,-.169),l(-.587,-.253),l(-.226,.071),l(-.206,.297),l(-.454,.072),l(-.676,-.21),l(-.574,-.733),l(-.196,.085),l(-.017,.169),l(-.159,.396),l(-.27,.128),l(-.332,-.056),l(-.481,.043),l(-.055,.038),l(-.197,-.143),l(-.909,-.107),l(-.621,-.166),l(-.943,-.615),l(-.273,-.365),l(-.096,-.521),l(.472,-.75),l(-.056,-.38),l(-.237,-.21),l(-.777,.047),l(-.66,-.053),l(-.771,-.235),l(-.623,-.575),l(-.298,.101),l(-.521,.328),l(-.696,.554),l(-.341,.157),l(-.807,.117),l(-1.595,.052),l(-.332,.115),l(-.584,.413),l(-.325,-.097),l(-.597,-.392),l(-.341,-.012),l(-.515,.13),l(-.483,.229),
+N(241.073,156.152),l(.017,.52),l(.098,1.215),l(.012,.212),l(-.379,.455),l(-.011,.17),l(.485,1.358),l(-.669,-.577),l(-.445,-.056),l(-.761,.143),l(-.877,-.012),l(-.666,-.14),l(-.574,-.056),l(-.474,.1),l(-.378,.354),l(-.135,-.042),l(-.993,-.549),l(-.171,-.325),l(.04,-.198),l(.269,-.184),l(1.051,.097),l(.631,.111),l(1.125,.167),l(.654,.041),l(.61,-.185),l(.386,-.156),l(-.198,-.155),l(-.692,-.464),l(-.136,-.296),l(.184,-.707),l(-.202,-.296),l(-.394,-.154),l(-.913,-.14),l(-.305,-.211),l(.04,-.184),l(.119,-.085),l(.344,-.1),l(.724,-.058),l(.781,.125),l(1.081,.294),l(.576,.056),l(.147,-.089),
+N(241.295,160.082),l(-.485,-1.358),l(.011,-.17),l(.379,-.455),l(-.012,-.212),l(-.098,-1.215),l(-.017,-.52),l(.503,-.279),l(.393,.14),l(.342,0),l(.384,-.17),l(.369,-.043),l(.14,.198),l(.177,.112),l(1,.309),l(.657,-.072),l(.213,.395),l(.335,.338),l(.528,.324),l(.335,.084),l(.643,.21),l(.916,.45),l(.399,.352),l(.231,.311),l(-.191,.17),l(-.144,.297),l(-.314,.368),l(-.238,-.098),l(-.476,-.592),l(-.378,-.042),l(-.788,.058),l(-.288,-.098),l(-.373,0),l(-.329,.1),l(-.763,.539),l(-.396,-.056),l(-.319,-.494),l(-.166,-.028),l(-.155,.057),l(-.658,.326),l(-.344,.778),l(-.41,.65),l(-.289,-.112),l(-.325,-.551),
+N(668.053,167.796),l(-.131,-.099),l(-.74,-.732),l(-.444,-1.255),l(.037,-.424),l(.054,-.706),l(-.292,-.465),l(.18,-.382),l(.978,.704),l(.202,-.424),l(.023,-.41),l(-.101,-.438),l(-.026,-.579),l(.145,-.438),l(.025,-.664),l(.082,-.861),l(.074,-.636),l(.38,-.862),l(.188,-.127),l(.337,-.142),l(.523,.055),l(1.21,.52),l(.576,.042),l(.188,-.212),l(.277,-.17),l(.199,.141),l(.018,.396),l(-.266,.438),l(-.045,.48),l(.14,.79),l(.541,.394),l(.182,.325),l(-.427,1.271),l(-.31,.467),l(-.834,.608),l(-.555,.312),l(-.082,.099),l(.003,.268),l(-.078,.565),l(-.28,.424),l(.127,.211),l(.35,.733),l(.345,1.101),l(.26,.62),l(.093,.028),l(.451,.324),l(.296,.07),l(.161,-.325),l(.485,-.537),l(.197,-.029),l(.418,.112),l(.226,.211),l(.179,.635),l(.286,.353),l(.326,.084),l(.505,-.58),l(.621,.267),l(.141,.028),l(.078,.127),l(-.168,.156),l(-.378,.156),l(-.208,.212),l(.936,1.226),l(-.315,.184),l(-.568,-.196),l(-.404,-.098),l(-.094,-.48),l(-.229,-.31),l(-.599,-.535),l(-.753,-.577),l(-.258,0),l(-.099,.226),l(.371,.776),l(-.218,.283),l(-.727,-.775),l(-.982,-.548),l(-.309,.015),l(-.344,.142),l(-.182,.255),l(-.14,.071),l(-.395,.057),l(-.322,-.225),l(-.591,-.366),l(-.195,-.423),l(.64,-.608),l(.323,.211),l(.358,.084),l(.4,-.199),l(-.151,-.169),l(-.713,-.295),l(-.422,-.395),l(-.522,-.168),l(-.239,.607),M(669.676,172.974),l(-.452,-.366),l(-.349,-.408),l(-.051,-.226),l(-.364,-1.114),l(-.459,-.521),l(.685,-.058),l(.868,.012),l(.314,.169),l(.274,.451),l(.028,.861),l(-.097,.48),l(-.214,.283),l(-.185,.438),M(679.073,175.368),l(-.562,-.267),l(-.178,-.254),l(-.237,-.169),l(-.064,-.127),l(.139,-.339),l(-.091,-.423),l(-.55,-.352),l(-.662,-.479),l(-.147,-.466),l(.513,-.1),l(1.017,-.143),l(.371,.112),l(.283,.409),l(.069,.818),l(.123,.805),l(.257,.79),l(-.112,.127),l(-.167,.057),M(671.406,176.824),l(.022,-.353),l(.186,-1.342),l(.061,-1.172),l(.482,.395),l(.576,.281),l(.366,.028),l(.634,-.185),l(.027,.438),l(-.079,.396),l(-.24,.269),l(-.184,.198),l(-.908,.651),l(-.943,.397),M(664.721,177.812),l(-.366,-.027),l(.127,-.297),l(.202,-.099),l(.314,-.396),l(.265,-.523),l(.082,-.607),l(.138,-.509),l(.326,-.184),l(.14,.183),l(-.16,.283),l(.276,.55),l(.212,.564),l(-.108,.113),l(-.664,.354),l(-.406,.368),l(-.377,.227),M(673.781,179.981),l(-.385,-.366),l(-.828,-.591),l(-.206,-.38),l(.099,-.368),l(.565,-.213),l(.22,-.269),l(.487,-1.822),l(.438,-.185),l(.271,.028),l(.113,.126),l(.049,.282),l(-.373,.905),l(-.089,.226),l(-.315,1.413),l(.165,.296),l(.214,.465),l(-.213,.41),l(-.212,.043),M(661.179,181.308),l(-.317,-.042),l(.215,-.48),l(.343,-.467),l(.35,-.34),l(.592,-.354),l(.636,-.496),l(.933,-1.089),l(.11,.55),l(-.118,.424),l(-.267,.297),l(-.24,.184),l(-.516,.213),l(-.172,.127),l(-.244,.622),l(-.327,.269),l(-.591,.171),l(-.386,.41),M(680.678,185.402),l(-.201,-.098),l(-.098,-.438),l(-.361,-.748),l(-.297,-.112),l(-.381,.608),l(-.361,.82),l(.246,.38),l(.166,.395),l(.148,.677),l(-.158,.495),l(-.383,.509),l(-.305,-.253),l(-.176,-.268),l(.201,-.41),l(-.076,-.325),l(-.363,-.07),l(-.361,.665),l(-.173,-.056),l(-1.114,-.619),l(-.557,-.549),l(-.206,-.508),l(-.037,-.635),l(.466,-.905),l(-.108,-.479),l(-.466,-.409),l(-.778,-.295),l(-.292,.043),l(-.062,.17),l(-.129,.226),l(-.5,.255),l(-.661,.058),l(-.027,-.494),l(-.174,-.24),l(-.399,.199),l(-.504,.961),l(-.525,.863),l(-.219,-.084),l(-.119,-.127),l(-.034,-.197),l(.054,-.311),l(.359,-.749),l(.185,-.537),l(.263,-.283),l(.383,-.184),l(.564,-.044),l(.219,-.127),l(.134,-.466),l(.205,-.156),l(.549,-.241),l(.777,-.101),l(.292,.353),l(.102,.72),l(.317,-.156),l(.485,-.058),l(.207,-.184),l(.207,-.565),l(.358,-.255),l(.479,.21),l(.186,.084),l(.158,-1.087),l(.29,-.015),l(.264,.465),l(.315,-.481),l(.205,-.142),l(.392,.098),l(.133,-.227),l(-.048,-.706),l(-.172,-.564),l(.146,-.353),l(.413,.549),l(.711,.803),l(.229,.48),l(.083,.324),l(-.336,.735),l(.237,.226),l(.537,-.1),l(.076,.423),l(-.114,.424),l(.056,.692),l(.207,.437),l(-.002,.438),l(-.111,.424),l(-.283,.579),l(-.332,.622),
+N(251.898,160.229),l(-.547,-.112),l(-.073,-.212),l(.051,-.551),l(-.109,-.24),l(.11,-.17),l(.235,-.071),l(.543,.069),l(.404,-.015),l(1.505,.11),l(.393,.168),l(.113,.141),l(-.188,.354),l(-.07,.099),l(-.283,.227),l(-.335,.043),l(-.739,-.083),l(-.657,.072),l(-.354,.17),
+N(228.82,160.519),l(-.299,-.056),l(-.693,-.224),l(-.229,-.268),l(-.47,-.366),l(-.465,-.084),l(-.142,-.211),l(.53,-.284),l(.704,-.072),l(1.364,.251),l(.97,.351),l(.651,.267),l(.279,.282),l(-.04,.198),l(-.332,.071),l(-.751,-.295),l(-.543,.058),l(-.227,.255),l(-.308,.128),
+N(400.72,175.499),l(-.595,-.119),l(-.161,-.032),l(-.976,.458),l(-1.429,-.006),l(-.867,-.037),l(-2.119,.041),l(-.271,.157),l(-.125,.34),l(.261,1.934),l(.02,.41),l(-.191,.17),l(-.63,-.434),l(-.644,-.166),l(-.769,.075),l(-.608,.159),l(-.446,.257),l(-.368,.115),l(-.354,-.083),l(-.452,-.223),l(-.52,-.562),l(-.15,-.465),l(-.308,-.252),l(-.545,.003),l(-.259,-.168),l(.08,-.043),l(.046,-.156),l(.172,-.326),l(.261,-.92),l(.133,-.876),l(-.058,-.749),l(.141,-.255),l(.257,-.016),l(.448,-.158),l(.543,-.271),l(.317,-.369),l(.292,-1.047),l(.355,-1.217),l(.397,-.384),l(.273,-.058),l(.293,.281),l(.551,.364),l(.45,-.102),l(.174,-.227),l(.393,-.822),l(.492,-.667),l(.638,-.625),l(.272,-.101),l(.518,.209),l(.324,.182),l(.274,.027),l(.314,-.793),l(.304,-.228),l(.947,-.458),l(1.22,-.713),l(.37,-.073),l(.356,.125),l(.36,.059),l(1.062,.173),l(-.173,.665),l(.019,.396),l(.426,.93),l(.422,.492),l(.389,.266),l(.502,.42),l(.179,.268),l(.018,.212),l(-.335,.439),l(.114,.226),l(.97,.757),l(.516,.181),l(.37,-.044),l(.562,.025),l(.568,.971),l(.131,.367),l(-.237,.764),l(-.415,.468),l(-.337,.158),l(-.739,-.095),l(-.418,.045),l(-.415,.271),l(-.366,.553),l(-.24,.157),l(-.062,.142),l(-.29,-.041),l(-.611,-.166),l(-1.013,-.163),
+N(209.823,175.47),l(-.388,-.645),l(-.932,-.888),l(-1.003,-1.085),l(-.837,-.817),l(-.723,-.464),l(-.196,-.183),l(-.023,-.226),l(.625,-.03),l(1.001,-.125),l(.29,-.143),l(.293,-.412),l(.005,-.961),l(.882,-.034),l(.513,-.583),l(.725,.42),l(1.207,-.997),l(.503,-.794),l(.294,-.242),l(.259,.013),l(.328,.182),l(.463,.097),l(.248,-.086),l(.424,-.229),l(1.425,-.486),l(.23,.519),l(.038,.339),l(-.057,.509),l(-.214,.707),l(-.543,.806),l(-.1,.749),l(.042,.904),l(-.245,1.13),l(-.188,.735),l(-.101,1.385),l(.031,.55),l(.184,.466),l(.188,.363),l(-.281,.274),l(-.767,-.149),l(-.241,-.46),l(-.285,.077),l(-.394,-.107),l(-.603,.25),l(-1.651,-.599),l(-.43,.271),
+N(634.036,168.444),l(.533,.251),l(.736,.165),l(.341,.111),l(.469,.251),l(.248,-.058),l(.095,-.24),l(-.103,-.211),l(-.187,-.182),l(-.107,-.296),l(.392,-.285),l(.476,-.186),l(.444,.181),l(.373,.351),l(.3,-.072),l(.975,-.429),l(.209,-.114),l(-.215,.905),l(.029,.663),l(.455,1.014),l(-.076,.367),l(-.05,.424),l(.054,1.073),l(-.217,.509),l(-.385,.285),l(-.599,.187),l(-.932,.443),l(-.521,.229),l(-.99,.571),l(-.234,.425),l(.216,.422),l(.568,.435),l(.03,.197),l(-.17,.27),l(-.688,-.194),l(-.497,-.011),l(-.599,.229),l(-.915,.528),l(-.646,.229),l(-.3,.289),l(-.256,-.188),l(-.248,-.268),l(-.35,-.042),l(-.382,.142),l(-.205,-.042),l(-.293,.043),l(-.183,-.113),l(.142,-.311),l(.182,-.226),l(-.04,-.254),l(-.283,-.395),l(-.277,.043),l(-.462,.298),l(-.339,.015),l(-.171,-1.044),l(-.649,-1.488),l(.146,-.176),l(-.16,-.479),l(-.487,-.717),l(-.219,-.648),l(-.026,-.635),l(.076,-.382),l(.146,-.297),l(.92,-1.233),l(.521,-.441),l(.383,-.101),l(1.172,-.091),l(.798,.066),l(.558,-.074),l(.575,.039),l(.599,.109),l(.301,.167),
+N(214.474,175.913),l(.821,.884),l(.385,.623),l(.314,.322),l(.225,.046),l(.465,.645),l(.441,.352),l(-.014,.006),l(-.074,.123),l(-.478,-.184),l(-.219,.205),l(-.014,.321),l(0,.58),l(.507,.307),l(-.396,.368),l(.125,.532),l(-.374,.369),l(.243,.184),l(-.204,.609),l(.003,-.466),l(-.296,-.307),l(.01,-.568),l(-.377,-.148),l(-.238,-.102),l(-.111,.082),l(.325,.41),l(.084,.225),l(-.113,.062),l(-.726,-.299),l(-.13,-.282),l(.251,-.339),l(.04,-.382),l(-.182,-.338),l(-.486,-.324),l(-.695,-.287),l(-.079,-.144),l(-.689,-.103),l(-.316,-.327),l(.007,-.421),l(-.146,-.255),l(-.249,-.098),l(-.576,-.353),l(-.416,-.266),l(.225,.512),l(.086,.222),l(.422,.044),l(.181,.266),l(-.544,.573),l(-.144,-.262),l(-.356,-.282),l(-.561,-.211),l(-.323,-.239),l(-.147,-.24),l(-.104,-.494),l(.128,-.421),l(.332,-.225),l(-.008,-.389),l(-.554,-.225),l(.363,-.123),l(-.057,-.227),l(-.238,.017),l(.43,-.271),l(1.651,.599),l(.603,-.25),l(.394,.107),l(.285,-.077),l(.241,.46),l(.767,.149),l(.281,-.274),
+N(436.304,195.359),l(-.209,-.451),l(-.194,-.804),l(-.498,-.802),l(-1.217,-1.236),l(-.112,-.324),l(-.064,-.791),l(-.432,-.605),l(-.4,-.661),l(-.207,-.592),l(-.273,-1.185),l(-.112,-.776),l(.064,-.424),l(.144,-.198),l(.528,-.399),l(.4,-.511),l(.866,-1.743),l(.354,-.327),l(.208,-.114),l(.096,.084),l(.24,.027),l(.449,-.158),l(1.363,-.686),l(.494,.661),l(.225,.069),l(.224,-.03),l(.466,-.271),l(.754,-.386),l(.818,-.273),l(.881,.009),l(.368,-.031),l(.258,-.143),l(.646,-1.176),l(.117,-.806),l(.209,-.199),l(.434,-.059),l(2.181,-.055),l(.386,-.087),l(2.649,-2.275),l(.196,-.284),l(.005,-.41),l(.165,-.382),l(.372,-.228),l(.939,-.613),l(.322,-.086),l(.321,.012),l(.559,.208),l(1.342,1.673),l(.347,.549),l(.122,.536),l(-.416,1.472),l(.01,.664),l(.158,.211),l(.802,-.019),l(.272,-.001),l(.207,.126),l(.252,.493),l(.223,.225),l(.797,.447),l(.799,.235),l(.351,.196),l(.223,.267),l(-.148,.481),l(.173,.395),l(.445,.351),l(.558,.378),l(.717,.434),l(.207,.168),l(.206,.366),l(.059,.72),l(.285,.436),l(.367,.224),l(.814,.165),l(.558,.477),l(.157,.352),l(-.083,.679),l(.031,.07),l(-.496,.145),l(-.962,.344),l(-.319,-.026),l(-.287,-.167),l(-.687,-.264),l(-1.15,-.361),l(-.4,.13),l(-.082,.551),l(-.13,.241),l(-.256,.058),l(-.399,-.026),l(-.862,-.207),l(-.593,.102),l(-.93,.373),l(-.93,.486),l(-.271,.016),l(-.559,-.35),l(-.383,-.153),l(-.353,.186),l(-.677,1.36),l(-.176,.157),l(-.591,-.067),l(-1.934,-.511),l(-1.422,-.189),l(-.512,-.322),l(-.159,-.239),l(-.334,-.394),l(-.75,-.518),l(-.432,-.167),l(-.479,.06),l(-.529,.3),l(-.353,.341),l(-.785,.979),l(-.097,.297),l(.096,.452),l(-.017,.353),l(-.063,.594),l(-.16,.058),l(-.751,.287),l(-.895,-.093),l(-.624,-.138),l(-.367,-.054),l(-.975,.175),l(-.479,.102),l(-.255,.228),l(-.222,1.287),l(-.158,.523),l(-.365,.497),l(-.303,.312),
+N(371.324,180.419),l(1.088,-1.235),l(.643,-.866),l(.238,-.157),l(.594,.039),l(1.137,-.148),l(.466,.04),l(.42,.224),l(.456,.421),l(.475,.619),l(.252,.761),l(.165,1.369),l(.26,.656),l(-.259,.502),l(-1.184,1.151),l(-.63,.724),l(-.285,.256),l(-.061,.103),l(-.631,-.523),l(-.661,-.408),l(-.483,-.196),l(-.033,-.141),l(.061,-.297),l(-.05,-.184),l(-.531,-.21),l(-.792,-.549),l(-.389,-.366),l(-.375,-.465),l(.494,-.241),l(.174,-.227),l(-.034,-.155),l(-.484,-.211),l(-.065,-.113),l(.022,-.173),
+N(579.606,186.906),l(-.493,-.083),l(-.265,-.197),l(-.21,-.353),l(-.246,-.621),l(-.361,-1.256),l(-.034,-.649),l(.005,-.763),l(-.02,-.904),l(-.24,-.696),l(.188,-.513),l(-.298,-.35),l(.068,-.28),l(.423,.023),l(.349,-.43),l(.053,-.367),l(.226,-.369),l(-.152,-.537),l(.529,.48),l(.699,.38),l(.234,.395),l(.549,.776),l(.175,.324),l(-.099,.339),l(.024,.141),l(.592,.338),l(.266,.733),l(.798,1.368),l(.136,.508),l(-.193,.735),l(-.397,.679),l(-.369,.396),l(-.514,.425),l(-.78,.284),l(-.642,.043),
+N(217.111,178.792),l(.52,.307),l(.195,.512),l(.02,.374),l(.363,.155),l(.628,.024),l(.244,-.205),l(.398,.43),l(.726,.082),l(.458,-.083),l(1.348,-.751),l(.514,-.046),l(1.387,-.921),l(.373,.144),l(.742,.069),l(.071,.156),l(.789,-.017),l(.767,.21),l(.666,.38),l(.644,.563),l(.406,.666),l(.084,.327),l(.228,.149),l(.509,1.038),l(-.322,.062),l(-.094,.43),l(-.584,.409),l(-.085,-.307),l(-.19,-.082),l(.045,.45),l(-.228,.082),l(-.256,.753),l(-.378,-.825),l(-.441,-.762),l(-.137,-.452),l(.179,-.24),l(.22,-.085),l(.786,.125),l(-.336,-.193),l(-.125,-.164),l(-.096,-.471),l(-.309,.307),l(-.439,.041),l(-.244,-.378),l(-.031,-.269),l(-.193,-.282),l(-.132,.151),l(-.226,-.287),l(-.11,.102),l(-.132,-.266),l(-.456,-.192),l(-.562,-.013),l(-.499,.241),l(-.382,.108),l(-.07,.359),l(.081,.234),l(-.529,.318),l(-.374,.184),l(-.335,.029),l(-.345,.41),l(.049,.296),l(.316,.297),l(.464,.43),l(.178,.386),l(-.011,.146),l(-.281,.081),l(-.243,-.042),l(-.431,.391),l(-.568,.105),l(-.339,-.042),l(-.189,-.146),l(.108,-.164),l(-.349,-.833),l(-.244,-.353),l(-.177,.674),l(-.812,-.409),l(-.227,-.757),l(-.207,.041),l(-.96,-.123),l(-.434,-.266),l(-.599,0),l(-.314,.113),l(-.361,.495),l(.204,-.609),l(-.243,-.184),l(.374,-.369),l(-.125,-.532),l(.396,-.368),l(-.507,-.307),l(0,-.58),l(.014,-.321),l(.219,-.205),l(.478,.184),l(.074,-.123),
+N(266.015,188.956),l(-.503,-.647),l(-.732,-.745),l(-.324,-.521),l(.071,-.212),l(.395,-.539),l(-.008,-.58),l(.061,-.452),l(1.032,-.19),l(.41,-.144),l(.308,-.299),l(-.141,-.282),l(-.62,-.604),l(-.074,-.212),l(.101,-.255),l(1.655,-1.239),l(.061,-.41),l(-.095,-.296),l(.072,.049),l(.496,.338),l(.856,.521),l(.695,.521),l(.587,.663),l(.128,.409),l(-.036,.734),l(.148,.945),l(.298,-.593),l(.22,-.099),l(.6,.182),l(.101,.127),l(.507,.295),l(.708,.549),l(.401,.493),l(.374,.649),l(-.015,.339),l(-.142,.496),l(-.082,.862),l(-.183,.27),l(-1.131,.091),l(-.169,.17),l(.078,.777),l(-.095,.467),l(-.328,.694),l(.571,.831),l(.532,.675),l(.561,.067),l(.185,.295),l(.246,.832),l(.49,1.127),l(.332,.563),l(-.06,.212),l(-.943,-.022),l(-.934,.429),l(-1,.331),l(-.505,.314),l(-.694,.513),l(-.686,.075),l(-.613,-.392),l(-1.103,-.897),l(-.15,-.296),l(-.008,-.396),l(.072,-.354),l(-.167,-.31),l(-.281,-.394),l(-.156,-.465),l(.213,-.962),l(.547,-1.416),l(.179,-.368),l(-.435,-.958),l(-.533,-.138),l(-.304,.001),l(.452,-1.09),l(-.04,-.212),l(-.26,-.111),l(-.516,-.124),l(-.302,.058),l(-.375,.257),
+N(377.518,182.142),l(.193,-.376),l(.252,-.242),l(.367,-.143),l(.528,-.046),l(.338,.097),l(.165,.366),l(.22,.846),l(.009,.65),l(-.044,.283),l(.277,.323),l(.404,.322),l(.321,.026),l(.756,-.922),l(.143,-.086),l(.337,.097),l(.339,.224),l(-.062,.17),l(.119,.55),l(-.059,.438),l(-.501,.865),l(.05,.183),l(.194,.183),l(.369,.097),l(.592,-.032),l(1.264,1.334),l(.131,.282),l(-.059,.452),l(-.247,.849),l(-.105,.565),l(-.041,.919),l(-1.513,-.643),l(-1.221,-.619),l(-1.012,-.562),l(-.403,-.423),l(-1.129,-1.113),l(-1.111,-.76),l(-.723,-.337),l(-.901,-.535),l(-.66,-.548),l(.061,-.103),l(.285,-.256),l(.63,-.724),l(1.184,-1.151),l(.259,-.502),
+N(429.505,210.684),l(.484,.336),l(.177,.013),l(.443,-.271),l(.327,-.581),l(1.495,-.532),l(.054,.424),l(.042,.664),l(.147,.211),l(.57,-.328),l(.554,-.399),l(.931,-.811),l(.364,-.229),l(1.025,-.938),l(.086,-.706),l(-.122,-.72),l(.074,-.396),l(.193,-1.159),l(.343,-.751),l(.47,-.836),l(.41,-.454),l(.809,-.599),l(.525,-.229),l(.459,-.427),l(.139,-.523),l(.169,-.708),l(.115,-.61),l(.254,-1.342),l(.196,-2.021),l(.156,-.764),l(.094,-.551),l(.349,-.821),l(.558,-.837),l(.398,-1.203),l(.031,-.156),l(-.128,-.197),l(.16,-.058),l(.063,-.594),l(.017,-.353),l(-.096,-.452),l(.097,-.297),l(.785,-.979),l(.353,-.341),l(.529,-.3),l(.479,-.06),l(.432,.167),l(.75,.518),l(.334,.394),l(.159,.239),l(.512,.322),l(1.422,.189),l(1.934,.511),l(.591,.067),l(.176,-.157),l(.677,-1.36),l(.353,-.186),l(.383,.153),l(.559,.35),l(.271,-.016),l(.93,-.486),l(.93,-.373),l(.593,-.102),l(.862,.207),l(.399,.026),l(.256,-.058),l(.13,-.241),l(.082,-.551),l(.4,-.13),l(1.15,.361),l(.687,.264),l(.287,.167),l(.319,.026),l(.962,-.344),l(.496,-.145),l(.143,.239),l(.795,.772),l(.348,.493),l(.525,.477),l(.366,.195),l(.352,-.016),l(.258,-.242),l(.529,-.37),l(.384,.012),l(.684,.631),l(.16,-.1),l(.436,-.582),l(.258,-.157),l(.207,.083),l(1.032,.926),l(1.288,1.32),l(.063,.028),l(.159,.183),l(-.018,.424),l(-.26,1.88),l(.128,.253),l(.191,.027),l(.479,.04),l(.271,.182),l(.111,.31),l(-.191,.453),l(-1.195,1.066),l(-1.241,.996),l(-.255,.284),l(-.395,.681),l(-.217,1.02),l(-.107,.507),l(.021,.593),l(-.025,.734),l(.057,.748),l(-.076,.27),l(-.188,.298),l(-.426,.412),l(-.301,.171),l(-.269,.256),l(-.122,.425),l(-.49,1.358),l(.197,.338),l(.689,.999),l(.087,.381),l(-.04,.438),l(.014,.636),l(.237,.634),l(.017,1.329),l(-.064,.762),l(.425,1.439),l(-.102,.848),l(.122,.693),l(.486,.631),l(.936,.898),l(.428,.78),l(.689,1.804),l(-.563,.068),l(-3.015,.499),l(-.347,.214),l(-.154,.198),l(-.797,1.276),l(-.029,.622),l(.372,2.088),l(-.377,1.175),l(-.3,1.02),l(.043,.296),l(.456,.605),l(.837,.843),l(.445,.279),l(.515,.012),l(.448,-.455),l(.362,-.186),l(.136,.183),l(.032,.791),l(.028,1.427),l(-.041,.551),l(-.371,-.012),l(-1.355,-.091),l(-.348,-.21),l(-.381,-.647),l(-.561,-.731),l(-.416,-.351),l(-.477,-.252),l(-.895,-.263),l(-.38,-.28),l(-.728,-1.423),l(-.212,.354),l(-.522,.682),l(-.366,.087),l(-.325,-.111),l(-.922,-.164),l(-.925,-.249),l(-.489,-.194),l(-.58,-1.014),l(-.175,.071),l(-1.146,.289),l(-.195,-.056),l(-.172,-.352),l(-.365,-.379),l(-.678,-.096),l(-1.24,-.147),l(-.991,.146),l(-.859,.26),l(-.61,.004),l(-.199,-.197),l(-.007,-.254),l(.198,-.905),l(.003,-.466),l(-.306,-.62),l(-.844,-.998),l(-.117,-.211),l(-.021,-.212),l(.296,-1.033),l(.07,-1.06),l(-.109,-.607),l(-.303,-.605),l(.057,-.354),l(.177,-.693),l(-.052,-.183),l(-.322,-.098),l(-1.231,.093),l(-.88,.019),l(-.212,-.168),l(.055,-.48),l(-.181,-.225),l(-2.016,.082),l(-.112,.001),l(-.089,.354),l(.027,.593),l(-.286,.892),l(-.184,.411),l(-.993,.006),l(-.899,-.122),l(-1.021,.246),l(-.88,.034),l(-.292,-.168),l(-.64,-.787),l(-.597,-1.07),l(-.537,-1.409),l(-.059,-.579),l(-.121,-.521),l(-.082,-.127),l(-.321,-.111),l(-.385,-.012),l(-1.104,-.008),l(-.88,.034),l(-.624,.003),l(-1.312,-.048),l(-.945,-.052),l(-.783,.02),l(-.432,.03),l(-.318,.101),l(-.896,.062),l(-.699,.314),l(-.56,.06),l(-.112,-.013),l(-.322,-.922),l(.012,-.053),l(.74,-.3),l(-.017,-.085),l(.1,-.89),l(.094,-.143),l(.317,-.199),l(.583,-.568),
+N(468.568,202.653),l(1.277,-.05),l(4.659,0),l(1.448,-.033),l(4.663,2.568),l(3.553,1.984),l(.137,.381),l(-.116,.552),l(.07,.239),l(2.427,1.752),l(1.067,.807),l(-.237,.427),l(-.419,1.329),l(-.137,1.017),l(.109,.551),l(.665,.987),l(.768,.577),l(-.024,.282),l(-.263,.354),l(-.371,1.046),l(.037,.17),l(.306,.041),l(.118,.226),l(-.172,.692),l(-.019,.946),l(.411,1.793),l(.18,.564),l(.401,.465),l(.823,.55),l(.396,.268),l(.177,.228),l(-1.157,.836),l(-.515,.342),l(-1.218,.402),l(-1.243,.559),l(-.448,.031),l(-.646,-.42),l(-.276,-.083),l(-.21,.326),l(-.543,.766),l(-.396,.144),l(-.42,-.054),l(-.964,.006),l(-.963,.02),l(-.512,-.294),l(-.323,-.394),l(-.229,-.083),l(-.123,.128),l(-.643,.356),l(-.526,.088),l(-1.019,-.149),l(-.898,-.018),l(-.196,-.559),l(-.135,-.766),l(-.053,-.584),l(-.135,-.946),l(-.448,-.841),l(-.663,-.538),l(-1.014,-.107),l(-.223,.016),l(-.385,-.407),l(-.732,-.349),l(-1.574,-.57),l(-1.269,-.6),l(-.729,-.265),l(-.263,-.21),l(-.703,-.641),l(-.689,-1.804),l(-.428,-.78),l(-.936,-.898),l(-.486,-.631),l(-.122,-.693),l(.102,-.848),l(-.425,-1.439),l(.064,-.762),l(1.252,-.348),l(.388,-.539),l(.645,-1.204),l(.687,-.853),l(.346,-.271),l(.044,-.212),l(-.148,-.239),l(-.273,-.125),l(-.401,-.068),l(-.211,-.211),l(.158,-.976),l(.304,-.016),l(.396,-.158),l(.142,-.17),l(.104,-.481),l(-.167,-.493),l(-.364,-.888),l(-.121,-.748),
+N(464.786,206.235),l(-.197,-.338),l(.49,-1.358),l(.122,-.425),l(.269,-.256),l(.301,-.171),l(.426,-.412),l(.064,.042),l(.546,.223),l(.431,-.045),l(.458,-.427),l(.554,-.398),l(.319,-.017),l(.121,.748),l(.364,.888),l(.167,.493),l(-.104,.481),l(-.142,.17),l(-.396,.158),l(-.304,.016),l(-.559,.031),l(-.508,.159),l(-.391,.567),l(-.158,.085),l(-.396,.13),l(-.789,-.32),l(-.688,-.024),
+N(465.79,210.652),l(-.017,-1.329),l(-.237,-.634),l(-.014,-.636),l(.04,-.438),l(-.087,-.381),l(-.689,-.999),l(.688,.024),l(.789,.32),l(.396,-.13),l(.158,-.085),l(.391,-.567),l(.508,-.159),l(.559,-.031),l(-.158,.976),l(.211,.211),l(.401,.068),l(.273,.125),l(.148,.239),l(-.044,.212),l(-.346,.271),l(-.687,.853),l(-.645,1.204),l(-.388,.539),l(-1.252,.348),
+N(427.243,211.207),l(.536,-.414),l(.68,-.513),l(.351,-.13),l(.695,.533),l(-.583,.568),l(-.317,.199),l(-.094,.143),l(-.1,.89),l(.017,.085),l(-.74,.3),l(.143,-.625),l(-.082,-.24),l(-.505,-.796),M(427.998,213.843),l(.112,.013),l(.56,-.06),l(.699,-.314),l(.896,-.062),l(.318,-.101),l(.432,-.03),l(.783,-.02),l(.945,.052),l(1.312,.048),l(.624,-.003),l(.88,-.034),l(1.104,.008),l(.385,.012),l(.321,.111),l(.082,.127),l(.121,.521),l(.059,.579),l(.537,1.409),l(.597,1.07),l(.64,.787),l(.292,.168),l(.88,-.034),l(1.021,-.246),l(.899,.122),l(.993,-.006),l(.184,-.411),l(.286,-.892),l(-.027,-.593),l(.089,-.354),l(.112,-.001),l(2.016,-.082),l(.181,.225),l(-.055,.48),l(.212,.168),l(.88,-.019),l(1.231,-.093),l(.322,.098),l(.052,.183),l(-.177,.693),l(-.057,.354),l(.303,.605),l(.109,.607),l(-.07,1.06),l(-.296,1.033),l(.021,.212),l(.117,.211),l(.844,.998),l(.306,.62),l(-.003,.466),l(-.198,.905),l(.007,.254),l(.199,.197),l(.61,-.004),l(.859,-.26),l(.991,-.146),l(1.24,.147),l(-.214,1.344),l(.195,1.059),l(.269,.323),l(.089,.254),l(-.132,.368),l(-.436,.44),l(-.124,.594),l(-.125,.086),l(-.517,-.04),l(-3.408,.091),l(-.051,.877),l(.015,1.342),l(-.024,3.249),l(.017,.848),l(.023,.594),l(.099,.438),l(.308,.394),l(.471,.436),l(1.354,1.391),l(.611,.632),l(-.93,.218),l(-1.96,.379),l(-1.044,.203),l(-.717,-.08),l(-1.164,.063),l(-.408,-.083),l(-.349,-.21),l(-2.024,.026),l(-.697,-.024),l(-.622,-.151),l(-.401,-.322),l(-.305,-.366),l(-.408,-.096),l(-.989,-.023),l(-2.59,.016),l(-1.636,-.019),l(-.631,-.011),l(-1.296,-.006),l(-2.201,.013),l(-.636,-.151),l(-.463,-.309),l(-.45,-.478),l(-.294,-.083),l(-.499,.088),l(-.591,.286),l(-.778,.513),l(-.758,-.462),l(-.352,.144),l(-.248,.197),l(.048,-1.809),l(-.017,-.805),l(-.029,-.649),l(.397,-.34),l(.221,-.269),l(.26,-.707),l(.163,-.734),l(.184,-1.398),l(.239,-.976),l(.321,-.918),l(.584,-.665),l(.183,-.565),l(.268,-.354),l(.64,-.228),l(.268,-.325),l(.423,-.679),l(.364,-1.201),l(.053,-.664),l(-.046,-.848),l(-.191,-.959),l(-.201,-.536),l(-.492,-.705),l(-.476,-.776),l(-.268,-.775),l(.139,-.495),l(.476,-.382),l(.158,-.156),l(.107,-.424),l(-.006,-.479),l(-.199,-.579),l(-.489,-.69),l(-.441,-.733),l(-.203,-1.031),l(-.181,-.423),l(-.276,-.366),l(-.666,-.974),l(-.072,-.15),
+N(452.198,239.34),l(-.611,-.632),l(-1.354,-1.391),l(-.471,-.436),l(-.308,-.394),l(-.099,-.438),l(-.023,-.594),l(-.017,-.848),l(.024,-3.249),l(-.015,-1.342),l(.051,-.877),l(3.408,-.091),l(.517,.04),l(.125,-.086),l(.124,-.594),l(.436,-.44),l(.132,-.368),l(-.089,-.254),l(-.269,-.323),l(-.195,-1.059),l(.214,-1.344),l(.678,.096),l(.365,.379),l(.172,.352),l(.195,.056),l(1.146,-.289),l(.175,-.071),l(.58,1.014),l(.489,.194),l(.925,.249),l(.922,.164),l(.325,.111),l(.366,-.087),l(.522,-.682),l(.212,-.354),l(.728,1.423),l(.38,.28),l(.895,.263),l(.477,.252),l(.416,.351),l(.561,.731),l(.381,.647),l(.348,.21),l(1.355,.091),l(.371,.012),l(.041,-.551),l(-.028,-1.427),l(-.032,-.791),l(-.136,-.183),l(-.362,.186),l(-.448,.455),l(-.515,-.012),l(-.445,-.279),l(-.837,-.843),l(-.456,-.605),l(-.043,-.296),l(.3,-1.02),l(.377,-1.175),l(-.372,-2.088),l(.029,-.622),l(.797,-1.276),l(.154,-.198),l(.347,-.214),l(3.015,-.499),l(.563,-.068),l(.703,.641),l(.263,.21),l(.729,.265),l(1.269,.6),l(1.574,.57),l(.732,.349),l(.385,.407),l(.559,.887),l(.434,.859),l(.013,.324),l(-.183,.27),l(-.709,.344),l(-.011,.127),l(.04,.594),l(-.091,1.682),l(.08,.353),l(.216,.168),l(.511,.266),l(.072,.197),l(-.197,.241),l(-.472,.258),l(-.792,.259),l(-.146,.34),l(-.094,.764),l(-.3,.807),l(.2,.479),l(.261,.408),l(.394,.125),l(-1.264,.53),l(-1.696,.575),l(-.932,.4),l(-2.165,.578),l(-.187,.128),l(-.009,.495),l(.152,.465),l(.087,.438),l(-.505,-.096),l(-.999,.049),l(-.794,.259),l(-.636,.54),l(-.312,.539),l(-.019,.579),l(-.168,.199),l(-.285,.114),l(-.999,.062),l(-.621,.202),l(-.306,.341),l(-.777,.937),l(-.562,.738),l(-.825,.951),l(-.354,.045),l(-.803,-.165),l(-.421,-.309),l(-.334,.129),l(-.521,.286),l(-.404,.017),l(-.594,-.209),l(-.264,-.097),l(-.154,-.169),l(-.163,-.027),l(-.187,-.154),l(-.456,-.393),l(-.294,-.055),l(-1.089,-.093),l(-.086,-.099),l(-.165,-.056),l(-1.845,.364),
+N(477.231,225.874),l(-.224,1.184),l(-.107,.48),l(.252,.917),l(.177,1.017),l(.149,.408),l(.238,.268),l(.803,.588),l(1.189,1.166),l(.454,.661),l(.14,.48),l(-.155,2.346),l(-.04,.41),l(-.214,.213),l(-.432,.073),l(-.322,.017),l(-.229,.213),l(-.076,.622),l(.08,.509),l(.029,.479),l(-.096,.283),l(-.185,-.111),l(-.562,-.463),l(-.763,-1.112),l(-.484,-.548),l(-.234,-.423),l(.036,-.212),l(.499,-.61),l(.116,-.227),l(.025,-.693),l(-.1,-.96),l(-.22,-.479),l(-.261,-.056),l(-.674,.061),l(-.702,.132),l(-.27,-.211),l(-.343,-.407),l(-.382,-.549),l(-.195,-.041),l(-.394,-.125),l(-.261,-.408),l(-.2,-.479),l(.3,-.807),l(.094,-.764),l(.146,-.34),l(.792,-.259),l(.472,-.258),l(.197,-.241),l(-.072,-.197),l(-.511,-.266),l(-.216,-.168),l(-.08,-.353),l(.091,-1.682),l(-.04,-.594),l(.011,-.127),l(.709,-.344),l(.183,-.27),l(-.013,-.324),l(-.434,-.859),l(-.559,-.887),l(.223,-.016),l(1.014,.107),l(.663,.538),l(.448,.841),l(.135,.946),l(.053,.584),l(.135,.766),l(.196,.559),
+N(245.934,224.314),l(.939,.136),l(1.122,.304),l(.355,-.03),l(.946,-.824),l(.336,.026),l(.48,.025),l(.415,-.243),l(1.471,-1.109),l(.874,-.485),l(.36,-.158),l(.934,-.076),l(1.283,.021),l(.045,.748),l(-.079,.621),l(-.064,.622),l(.036,.818),l(.141,.635),l(.335,.591),l(.813,.928),l(1.1,.939),l(.316,.097),l(.787,.023),l(.355,-.03),l(.676,.25),l(.688,.307),l(.75,.603),l(.3,.098),l(.882,.037),l(.096,.014),l(.385,.774),l(.398,.308),l(.22,.084),l(1.148,-.077),l(.636,.123),l(.537,.166),l(.403,.237),l(.085,.169),l(-.038,.565),l(.203,1.029),l(.03,.706),l(.138,2.032),l(.249,.944),l(.153,.112),l(.967,.036),l(.5,.012),l(1.615,.019),l(.693,.024),l(.042,.296),l(-.261,.835),l(.067,.563),l(.436,.407),l(.73,.362),l(.316,.479),l(.307,.774),l(.022,.494),l(-.185,1.173),l(-.238,.834),l(-.38,.765),l(-.421,.666),l(-.089,-.084),l(-1.952,-.991),l(-.352,-.054),l(-.928,.02),l(-.843,-.01),l(-.126,.128),l(-1.076,.204),l(-1.104,.162),l(-.784,.202),l(-.33,.044),l(-.332,.383),l(-.698,1.105),l(-.278,.341),l(-.133,.509),l(.016,.635),l(-.385,1.188),l(-.395,1.104),l(-.149,.325),l(-.592,-.109),l(-1.33,-.077),l(-.686,.004),l(-1.034,1.784),l(-.416,-1.084),l(-.341,-.309),l(-.37,-.195),l(-.531,-.067),l(-.527,.045),l(-.901,.034),l(-.615,-.194),l(-.193,-.169),l(-.322,-.181),l(-.292,.27),l(-2.026,2.087),l(-1.047,.006),l(-.272,-.182),l(-.397,-2.144),l(-.278,-.973),l(-.212,-.563),l(-.769,-1.11),l(-.249,-.676),l(.04,-.354),l(.437,-1.555),l(-.017,-.282),l(-.761,-.744),l(-.25,-.521),l(-.193,-1.213),l(-.304,-.647),l(-.555,-.745),l(-.152,-.253),l(-.018,-.142),l(-.132,-.295),l(-.049,-.48),l(.12,-.227),l(.723,-.61),l(.285,-.439),l(-.015,-.522),l(-.604,-1.168),l(-.022,-.48),l(.159,-.34),l(.21,-.368),l(-.347,-.845),l(.102,-.452),l(.532,-.582),l(.221,-.34),l(.156,-.34),l(-.236,-.902),l(-.057,-.522),l(.143,-.848),l(.15,-.523),l(.437,-.736),l(-.08,-.24),l(-.922,-1.646),l(-1.109,-1.843),
+N(473.575,260.04),l(-1.331,.011),l(-.192,.058),l(-.068,-.382),l(-.261,-.889),l(.071,-.495),l(-.075,-.296),l(-.095,-.324),l(.03,-.806),l(.057,-1.301),l(-.072,-.763),l(-.147,-.678),l(-.33,-.944),l(-.441,-.689),l(-.181,-.946),l(-.295,-1.199),l(-.159,-.183),l(.448,-.384),l(.396,-.412),l(1.68,-1.706),l(.114,-.227),l(-.09,-.367),l(.075,-.834),l(.229,-.481),l(.736,-.683),l(.205,-.341),l(.168,-.41),l(-.594,-.845),l(-.118,-.805),l(-.113,-.494),l(.128,-.283),l(.448,-.596),l(.201,-.411),l(-.132,-.805),l(-.086,-1.144),l(-.031,-.791),l(-.178,-.818),l(-.441,-.379),l(-.515,-.224),l(-1.167,-.347),l(-1.042,-.445),l(-.658,-.223),l(-1.438,-.006),l(-.137,-.14),l(-.025,-.495),l(-.011,-.212),l(-.087,-.438),l(-.152,-.465),l(.009,-.495),l(.187,-.128),l(2.165,-.578),l(.932,-.4),l(1.696,-.575),l(1.264,-.53),l(.195,.041),l(.382,.549),l(.343,.407),l(.27,.211),l(.702,-.132),l(.674,-.061),l(.261,.056),l(.22,.479),l(.1,.96),l(-.025,.693),l(-.116,.227),l(-.499,.61),l(-.036,.212),l(.234,.423),l(.484,.548),l(.763,1.112),l(.562,.463),l(.185,.111),l(.096,-.283),l(-.029,-.479),l(-.08,-.509),l(.076,-.622),l(.229,-.213),l(.322,-.017),l(.432,-.073),l(.214,-.213),l(.04,-.41),l(.155,-2.346),l(-.14,-.48),l(-.454,-.661),l(-1.189,-1.166),l(-.803,-.588),l(-.238,-.268),l(-.149,-.408),l(-.177,-1.017),l(-.252,-.917),l(.107,-.48),l(.224,-1.184),l(.898,.018),l(1.019,.149),l(.526,-.088),l(.643,-.356),l(.123,-.128),l(.229,.083),l(.323,.394),l(.512,.294),l(.963,-.02),l(.964,-.006),l(.42,.054),l(.396,-.144),l(.543,-.766),l(.21,-.326),l(.276,.083),l(.646,.42),l(.448,-.031),l(1.243,-.559),l(1.218,-.402),l(.515,-.342),l(1.157,-.836),l(.128,.167),l(.212,.479),l(-.185,.579),l(-.302,.453),l(-.198,.255),l(.181,.451),l(.129,.72),l(-.012,.466),l(.182,1.115),l(-.101,.58),l(-.258,.325),l(.374,.705),l(.154,.494),l(-.006,1.115),l(-.004,.819),l(.043,.184),l(.185,.127),l(.327,.084),l(.015,.269),l(-.165,.494),l(-.563,.58),l(.184,.381),l(-.08,.283),l(-.418,.565),l(-.802,.906),l(-.512,.622),l(-.72,.651),l(-1.36,.751),l(-1.48,.653),l(-.73,.228),l(-1.308,.582),l(-.852,.637),l(-1.286,1.443),l(-.886,.85),l(-1.193,.878),l(-1.181,.836),l(-.268,.128),l(-.035,.96),l(-.083,.495),l(.058,.127),l(.719,.535),l(.188,.381),l(-.166,.452),l(-.085,.184),l(.461,1.511),l(.071,.564),l(.06,.155),l(.246,.014),l(.171,-.128),l(.141,-.085),l(.043,.607),l(-.234,2.218),l(-.284,.82),l(.325,.196),l(.152,.057),l(-.025,.325),l(-.157,.311),l(-.516,.566),l(-.699,.538),l(-.664,.34),l(-1.266,.412),l(-.796,.312),l(-.688,.228),l(-.895,.524),l(-.652,.665),l(-.337,.51),l(.292,.338),l(.589,.338),l(.045,.325),l(-.149,1.022),
+N(499.85,236.166),l(.544,-.071),l(.622,-.369),l(.18,.028),l(.346,.098),l(.269,-.085),l(.396,-.368),l(.911,-.143),l(.311,.281),l(.305,-.028),l(.101,-.185),l(-.171,-.366),l(.771,-.539),l(.423,-.198),l(.322,.226),l(.389,-.213),l(-.308,-.494),l(.207,-.282),l(.505,-.425),l(.229,.296),l(.229,.056),l(.558,-.594),l(-.158,-.197),l(-.253,-.409),l(.094,-.297),l(.243,.014),l(.27,-.071),l(.172,-.34),l(-.297,-.875),l(.06,-.339),l(.255,-.043),l(.117,.07),l(.253,.438),l(.28,.099),l(.2,-.41),l(.692,-.524),l(.235,-.367),l(.134,-.452),l(.168,-.692),l(-.133,-.354),l(.003,-.226),l(.537,-.468),l(.356,.324),l(.455,.648),l(.612,.281),l(.141,.198),l(.213,.847),l(.294,1.821),l(.093,.663),l(.231,.791),l(.391,.733),l(.163,.466),l(-.038,.367),l(-.069,.155),l(-.058,.099),l(-.537,.807),l(-.22,-.127),l(-.189,-.366),l(-.555,-.748),l(-.297,.143),l(-.05,.424),l(.193,.875),l(.396,.521),l(.079,.396),l(-.307,.636),l(-.746,1.005),l(-.045,.452),l(.041,.89),l(-.18,.946),l(-.709,2.12),l(-.825,2.572),l(-1.254,3.788),l(-1.324,4.48),l(-.518,1.568),l(-.188,.255),l(-.508,.637),l(-.2,.113),l(-1.369,.102),l(-.999,.327),l(-.474,.468),l(-.813,.086),l(-.363,-.465),l(-.196,-.142),l(-.546,-.182),l(-.37,.071),l(-.269,-.057),l(-.863,-.718),l(-.104,-.24),l(-.02,-.565),l(-.104,-.239),l(-.46,-.366),l(-.124,-.282),l(.001,-.721),l(.345,-1.088),l(-.094,-.325),l(-.287,-.479),l(-.62,-.931),l(-.189,-.494),l(.075,-.664),l(.391,-1.37),l(.228,-.213),l(.474,-.185),l(.768,-1.371),l(.686,-1.174),l(.104,-.325),l(.151,-1.103),l(-.11,-.353),l(-.278,-.226),l(-.354,-.366),l(.066,-.184),l(.252,-.509),l(-.521,-.861),l(-.117,-.677),l(-.069,-.494),l(-.231,-.721),l(.024,-.112),l(.517,-.693),l(.362,-.594),l(.163,-.438),l(.007,-1.073),l(.484,-.016),
+N(468.138,234.908),l(.011,.212),l(.025,.495),l(.137,.14),l(1.438,.006),l(.658,.223),l(1.042,.445),l(1.167,.347),l(.515,.224),l(.441,.379),l(.178,.818),l(.031,.791),l(.086,1.144),l(.132,.805),l(-.201,.411),l(-.448,.596),l(-.128,.283),l(.113,.494),l(.118,.805),l(.594,.845),l(-.168,.41),l(-.205,.341),l(-.736,.683),l(-.229,.481),l(-.075,.834),l(.09,.367),l(-.114,.227),l(-1.68,1.706),l(-.396,.412),l(-.448,.384),l(-.342,-.225),l(-.547,-.124),l(-.442,-.025),l(-.529,.145),l(-.31,.016),l(-.99,-.403),l(-.597,-.139),l(-.72,-.023),l(-.067,-.042),l(-.186,-.098),l(-.306,-.451),l(-.479,-.35),l(-.549,-.167),l(-.938,-.136),l(-.352,-.153),l(-.524,-.873),l(-.163,-.564),l(.032,-.565),l(-.127,-.239),l(-.78,.019),l(-.201,-.098),l(-.109,-.211),l(.051,-.537),l(-.106,-.169),l(-.552,-.266),l(-.533,-.223),l(-.57,-.321),l(-.563,-.491),l(-.377,-.662),l(-.246,-.96),l(-.469,-.604),l(-.43,-.478),l(-.267,-.451),l(.103,-.227),l(.594,.209),l(.404,-.017),l(.521,-.286),l(.334,-.129),l(.421,.309),l(.803,.165),l(.354,-.045),l(.825,-.951),l(.562,-.738),l(.777,-.937),l(.306,-.341),l(.621,-.202),l(.999,-.062),l(.285,-.114),l(.168,-.199),l(.019,-.579),l(.312,-.539),l(.636,-.54),l(.794,-.259),l(.999,-.049),l(.505,.096),
+N(444.673,255.519),l(-.006,3.434),l(.031,1.894),l(.025,2.246),l(-.057,.205),l(-.454,.318),l(-.545,.302),l(-.581,.498),l(-.427,.034),l(-.581,-.166),l(-.745,-.042),l(-.892,.048),l(-.517,-.039),l(-.296,-.212),l(-.055,-.528),l(-.042,-.345),l(-.193,-.222),l(-.637,-.348),l(-.329,-.127),l(-.335,.116),l(-.109,.217),l(-.317,.416),l(-.584,.27),l(-.152,.068),l(-.458,-.491),l(-1.041,-1.001),l(-.458,-.606),l(-.359,-1.03),l(-.345,-.72),l(-.136,-.493),l(.12,-.269),l(.053,-.34),l(-.458,-.719),l(-.231,-.861),l(.148,-.861),l(-.002,-.48),l(-.537,-1.326),l(-.496,-2.244),l(.772,-.02),l(.04,-.678),l(-.077,-.749),l(-.456,-.006),l(.016,-.06),l(-.099,-.522),l(-.26,-.508),l(-1.018,-1.283),l(-.343,-.55),l(-1.102,-2.158),l(-.841,-1.623),l(-.9,-1.509),l(-.988,-1.269),l(-.511,-1.044),l(-.122,-.396),l(-.045,-.551),l(.015,-.578),l(.248,-.197),l(.352,-.144),l(.758,.462),l(.778,-.513),l(.591,-.286),l(.499,-.088),l(.294,.083),l(.45,.478),l(.463,.309),l(.636,.151),l(2.201,-.013),l(1.296,.006),l(.631,.011),l(1.636,.019),l(2.59,-.016),l(.989,.023),l(.408,.096),l(.305,.366),l(.401,.322),l(.622,.151),l(.697,.024),l(2.024,-.026),l(.349,.21),l(.408,.083),l(1.164,-.063),l(.717,.08),l(1.044,-.203),l(1.96,-.379),l(.93,-.218),l(1.845,-.364),l(.165,.056),l(.086,.099),l(1.089,.093),l(.294,.055),l(.456,.393),l(-.811,.315),l(-.891,.02),l(-.284,.143),l(-.993,.938),l(-.209,.029),l(-.62,-.773),l(-1.048,.134),l(-2.962,.47),l(-1.183,.021),l(.005,1.215),l(-.007,1.286),l(-.025,.876),l(-.043,1.201),l(.002,3.561),l(-.586,.046),l(-1.564,.052),l(-.146,.028),l(-.106,2.657),l(-.009,1.201),l(.013,1.624),l(.007,.806),
+N(248.453,316.576),l(-.306,.101),l(-.892,-.087),l(-.538,-.293),l(-.236,-.015),l(-.311,.163),l(-.418,.398),l(-.498,.192),l(-1.156,.091),l(-.349,.09),l(-.358,.207),l(-.267,.621),l(-.114,.341),l(.06,.532),l(-.163,.622),l(-.104,.148),l(-.453,.031),l(-.534,.104),l(-.956,-.413),l(.667,-.639),l(.326,-.444),l(.582,-.4),l(.025,-.147),l(-.372,-.177),l(-.273,-.117),l(-1.353,.534),l(-1.01,-.013),l(-.545,.163),l(-.202,-.339),l(.128,-.192),l(.959,-.268),l(.266,.028),l(.792,-.208),l(.441,-.118),l(-.605,-.162),l(-.582,.002),l(-.77,.001),l(-.014,-.413),l(.265,-.31),l(-.007,-.191),l(-.446,-.073),l(-.356,-.44),l(-.66,.384),l(-.669,-.175),l(.292,-.53),l(.041,-.177),l(-.378,.045),l(-.361,.147),l(-.416,-.396),l(-.215,-.117),l(.413,-.279),l(.114,-.177),l(-.091,-.278),l(-.053,-.073),l(-.351,.03),l(-.773,-.424),l(-.135,-.059),l(.844,-.192),l(.253,-.161),l(.1,-.294),l(.396,-.366),l(.049,-.234),l(-.641,.06),l(-.257,.104),l(-.312,-.073),l(-.256,-.672),l(.573,-.395),l(-.565,-.378),l(-.12,-.421),l(.757,-.452),l(-.14,-.421),l(-.686,.422),l(-.091,-1.523),l(.399,-.596),l(-.185,-.825),l(.013,-.218),l(.593,.014),l(.41,.245),l(.711,.071),l(.171,-.246),l(.002,-.159),l(-.896,-.447),l(-.867,.146),l(-.317,-.173),l(-.536,.059),l(-.017,-.231),l(.339,-.333),l(.025,-.246),l(-.067,-.087),l(.186,-.202),l(.536,.014),l(.229,-.377),l(.01,-.216),l(-.722,-.389),l(-.354,-.129),l(-.886,.045),l(-.332,-.101),l(-.024,-.49),l(-.939,.16),l(-.115,-.101),l(.122,-.145),l(1.032,-.521),l(.251,-.116),l(.4,-.404),l(.266,-.389),l(.833,-.06),l(.268,.201),l(.059,.346),l(-.648,.202),l(-.323,.274),l(.11,.505),l(.117,.058),l(.191,-.102),l(.268,-.39),l(.183,-.087),l(.242,.101),l(-.037,.317),l(.057,.504),l(.886,-.996),l(.161,-.678),l(.056,-.647),l(.237,-.375),l(.079,-.058),l(.631,-.217),l(-.201,-.071),l(-.438,-.143),l(-.056,-.158),l(.101,-.273),l(.246,-.072),l(.571,-.245),l(.599,-.431),l(.271,-.459),l(-.061,-.229),l(-.394,-.157),l(-.662,-.399),l(-.053,-.372),l(.139,-.243),l(.105,-.458),l(-.06,-.828),l(.366,-.33),l(.676,-.272),l(-.431,-.585),l(-.053,-.784),l(.133,-.158),l(.554,-.157),l(.054,-.314),l(-.116,-.285),l(-.317,-.085),l(-.272,-.198),l(.233,-.329),l(.087,-.313),l(-.401,-.185),l(-.274,-.014),l(-.161,.101),l(-.476,.414),l(-.548,.058),l(-.087,.001),l(-.289,-.199),l(-.16,-.484),l(-.399,-.726),l(-.133,-.697),l(.188,-.911),l(.137,-.413),l(.722,-.739),l(.535,-.767),l(-.006,-.326),l(-.544,-1.757),l(.001,-.608),l(.088,-.567),l(-.076,-.438),l(-.528,-.891),l(-.04,-.298),l(.236,-.198),l(.499,.098),l(.182,-.085),l(.2,-.142),l(.097,-.143),l(.41,-1.288),l(.252,-.481),l(.304,-.935),l(.18,-.65),l(.664,-.808),l(.363,-.722),l(.201,-.636),l(.252,-.946),l(.311,-.691),l(.187,-.128),l(.273,-.382),l(.013,-.296),l(-.312,-.847),l(.082,-.184),l(.455,-.452),l(.206,-.339),l(.028,-.24),l(-.093,-.226),l(-.166,-.805),l(-.292,-2.088),l(-.098,-.86),l(.031,-.565),l(.412,-.565),l(.37,-.537),l(.207,-.564),l(.007,-.734),l(-.339,-.521),l(-.098,-.409),l(.295,-.96),l(.218,-.941),l(.127,-.556),l(.461,-.594),l(.171,-.918),l(.243,-.975),l(.126,-.805),l(.082,-.565),l(-.063,-1.087),l(.422,-.664),l(.211,-.494),l(-.221,-.932),l(-.048,-.833),l(.148,-.24),l(-.022,-.917),l(.229,-.607),l(-.124,-.297),l(-.365,-.084),l(.06,-.324),l(-.046,-.396),l(.223,-.198),l(.402,-.198),l(.137,-.424),l(-.008,-.819),l(.093,-.593),l(.182,-.918),l(-.004,-2.344),l(-.172,-2.074),l(-.042,-1.539),l(-.194,-.974),l(-.15,-.387),l(.852,-.275),l(.259,-.298),l(.228,-.933),l(.15,-.199),l(.586,-.187),l(.152,.253),l(.555,.745),l(.304,.647),l(.193,1.213),l(.25,.521),l(.761,.744),l(.017,.282),l(-.437,1.555),l(-.04,.354),l(.249,.676),l(.769,1.11),l(.212,.563),l(.278,.973),l(.397,2.144),l(.272,.182),l(1.047,-.006),l(.107,.056),l(.212,.14),l(.161,.154),l(-.093,.636),l(-.541,1.457),l(-.36,.256),l(-1.346,.53),l(-.819,.372),l(-.204,.312),l(.25,.817),l(-.421,.722),l(-.007,.579),l(.113,.437),l(.34,.449),l(.03,.226),l(-.273,.369),l(-.161,.382),l(.114,.507),l(.53,.477),l(.011,.227),l(-.152,.311),l(-.333,.017),l(-.791,.089),l(-.329,.835),l(-.464,.835),l(-.608,.694),l(-.282,.439),l(-.823,1.839),l(.167,1.466),l(.054,.762),l(-.124,.185),l(-.492,.271),l(-.292,.34),l(-.388,1.201),l(-.156,.961),l(.285,.633),l(.408,1.154),l(.784,2.816),l(.055,.69),l(-.075,.41),l(-1.083,1.854),l(-.319,.595),l(.088,.409),l(.189,1.06),l(-.078,.325),l(-1.334,1.11),l(-.231,.312),l(-.142,1.075),l(.014,1.16),l(.249,1.103),l(.437,.932),l(-.202,.143),l(-.951,.529),l(-.126,.17),l(-.053,.312),l(-.511,2.427),l(-.316,.541),l(-.1,.37),l(.123,1.835),l(.231,.867),l(.012,.427),l(-.596,.317),l(-.172,.172),l(-.106,.271),l(.094,1.226),l(.125,.128),l(.555,.111),l(.088,.655),l(-.191,1.458),l(.252,.585),l(.26,.185),l(.789,.11),l(.302,.17),l(-.007,.186),l(-.245,.202),l(-.322,.13),l(-.726,.033),l(-.757,.146),l(.176,.171),l(.586,.298),l(.552,.385),l(.017,.216),l(-.767,.794),l(-.059,1.094),l(.158,1.035),l(-.216,.896),l(-.212,.434),l(-.226,.262),l(-.598,.161),l(-.28,.219),l(-.249,.781),l(.446,.648),l(-.069,.188),l(-.296,1.218),l(-.307,.263),l(-1.729,1.01),l(-.271,.292),l(-.037,.45),l(.28,1.309),l(.508,1.123),l(.218,.043),l(.961,-.283),l(.654,-.121),l(.187,.248),l(.231,2.285),l(.778,.568),l(.669,.041),l(1.41,-.052),l(2.827,.132),l(.841,.217),l(1.385,.36),l(.286,.039),M(236.642,296.773),l(-.394,-.113),l(-.43,-.028),l(-.21,-.171),l(-.133,-.229),l(.21,-.457),l(.15,-.657),l(-.087,-.514),l(.011,-.414),l(.364,-.728),l(.817,-.116),l(.36,.327),l(.044,.328),l(-.688,.443),l(-.146,.229),l(.493,.771),l(-.194,1.058),l(-.167,.271),M(238.177,317.937),l(-.445,-.177),l(.083,-.842),l(-.849,.075),l(-.073,-.368),l(.218,-.354),l(.823,.102),l(.508,-.207),l(.205,.103),l(.054,.812),l(-.267,.34),l(-.257,.518),M(247.801,322.062),l(-1.033,.102),l(-.467,-.118),l(-.55,-.237),l(-.42,.001),l(-.481,.104),l(-.935,.226),l(-.496,.03),l(.125,-.343),l(.202,-.312),l(-.104,-.312),l(.906,-.15),l(1.434,.058),l(.433,.323),l(.706,-.007),l(-.622,-.689),l(-.307,-.163),l(-.56,-.117),l(-.178,-.089),l(-.188,.03),l(-.338,-.341),l(-.229,-.4),l(1.611,-.581),l(-.044,-.296),l(-.165,-.147),l(-1.819,.285),l(-.292,-.222),l(.263,-.474),l(.146,-.163),l(1.074,-.52),l(.868,-.637),l(.414,.28),l(1.153,.062),l(-.008,1.144),l(-.098,3.675),
+N(456.133,239.67),l(.187,.154),l(.163,.027),l(.154,.169),l(.264,.097),l(-.103,.227),l(.267,.451),l(.43,.478),l(.469,.604),l(.246,.96),l(.377,.662),l(.563,.491),l(.57,.321),l(.533,.223),l(.552,.266),l(.106,.169),l(-.051,.537),l(.109,.211),l(.201,.098),l(.78,-.019),l(.127,.239),l(-.032,.565),l(.163,.564),l(.524,.873),l(.352,.153),l(.938,.136),l(.549,.167),l(.479,.35),l(.306,.451),l(.186,.098),l(-.317,.411),l(-.388,.327),l(-.507,.243),l(-.747,.075),l(-.304,.115),l(-.7,.823),l(-.586,.583),l(-.362,.229),l(-.747,.357),l(-.388,.355),l(-.107,.636),l(-.222,.666),l(-.247,.241),l(-.634,.357),l(-.98,.33),l(-.249,.214),l(-.217,.708),l(-.345,.963),l(-.288,.354),l(-.237,.129),l(-.584,.116),l(-.43,-.026),l(-.473,.06),l(-.511,-.011),l(-.819,-.193),l(-.744,-.32),l(-.979,-.645),l(-.545,-.039),l(-.333,.186),l(-.084,.24),l(-.585,1.134),l(-.382,.469),l(-.651,.625),l(-.632,.428),l(-.8,.372),l(-.823,.033),l(-.854,.047),l(-.368,-.097),l(-.11,-.183),l(.003,-.48),l(.243,-.609),l(.166,-.538),l(-.21,-.762),l(-.547,-.943),l(-.716,-.787),l(-.528,-.067),l(-.007,-.806),l(-.013,-1.624),l(.009,-1.201),l(.106,-2.657),l(.146,-.028),l(1.564,-.052),l(.586,-.046),l(-.002,-3.561),l(.043,-1.201),l(.025,-.876),l(.007,-1.286),l(-.005,-1.215),l(1.183,-.021),l(2.962,-.47),l(1.048,-.134),l(.62,.773),l(.209,-.029),l(.993,-.938),l(.284,-.143),l(.891,-.02),l(.811,-.315),
+N(279.288,257.295),l(.02,.239),l(-.544,1.57),l(-.375,.468),l(-1.007,.74),l(-.301,.27),l(-.352,.51),l(-.609,-.363),l(-.35,-.097),l(-.235,.029),l(-.387,.172),l(-.745,.131),l(-.71,.005),l(-.564,-.096),l(-.992,-.333),l(-.607,-.025),l(-1.187,.332),l(-.19,-.056),l(.064,-.212),l(.425,-.426),l(.486,-.398),l(.11,-.198),l(-.21,-.619),l(.048,-.227),l(.625,-.851),l(.617,-1.203),l(.018,-.268),l(-.939,-.503),l(-.65,-.18),l(-1.448,-.697),l(-1.632,-1.106),l(-.671,-.307),l(-1.173,-.204),l(-.498,-.237),l(-.835,-.588),l(-.576,-.562),l(-1.271,-1.376),l(-.782,-.913),l(-.225,-.337),l(-.19,-.056),l(.149,-.325),l(.395,-1.104),l(.385,-1.188),l(-.016,-.635),l(.133,-.509),l(.278,-.341),l(.698,-1.105),l(.332,-.383),l(.33,-.044),l(.784,-.202),l(1.104,-.162),l(1.076,-.204),l(.126,-.128),l(.843,.01),l(.928,-.02),l(.352,.054),l(1.952,.991),l(.089,.084),l(.253,.408),l(.084,.663),l(.521,.872),l(.104,.959),l(-.132,.862),l(-.086,.721),l(-.006,.72),l(.372,.04),l(.818,.15),l(.925,.221),l(.346,-.03),l(.709,-.413),l(.115,-.001),l(.724,.278),l(.843,.404),l(.121,.437),l(.487,2.524),l(.254,.563),l(.224,.055),l(1.29,-.445),l(.234,.112),l(.491,.336),l(.019,.141),l(-.321,.75),l(-.298,.835),l(-.222,.819),l(-.027,.777),l(.063,.423),
+N(444.673,255.519),l(.528,.067),l(.716,.787),l(.547,.943),l(.21,.762),l(-.166,.538),l(-.243,.609),l(-.003,.48),l(.11,.183),l(.368,.097),l(.854,-.047),l(.823,-.033),l(.8,-.372),l(.632,-.428),l(.651,-.625),l(.382,-.469),l(.585,-1.134),l(.084,-.24),l(.333,-.186),l(.545,.039),l(.979,.645),l(.744,.32),l(.819,.193),l(.511,.011),l(.473,-.06),l(.43,.026),l(.584,-.116),l(.237,-.129),l(.288,-.354),l(.345,-.963),l(.217,-.708),l(.249,-.214),l(.98,-.33),l(.634,-.357),l(.247,-.241),l(.222,-.666),l(.107,-.636),l(.388,-.355),l(.747,-.357),l(.362,-.229),l(.586,-.583),l(.7,-.823),l(.304,-.115),l(.747,-.075),l(.507,-.243),l(.388,-.327),l(.317,-.411),l(.067,.042),l(.72,.023),l(.597,.139),l(.99,.403),l(.31,-.016),l(.529,-.145),l(.442,.025),l(.547,.124),l(.342,.225),l(.159,.183),l(.295,1.199),l(.181,.946),l(.441,.689),l(.33,.944),l(.147,.678),l(.072,.763),l(-.057,1.301),l(-.03,.806),l(.095,.324),l(-1.449,-.585),l(-.279,.199),l(-.657,.979),l(-.28,.567),l(-.005,.325),l(.39,.676),l(.307,.465),l(.458,.322),l(.671,.109),l(.595,-.004),l(.076,-.594),l(.064,-.198),l(.312,-.186),l(.131,-.015),l(.192,-.058),l(1.331,-.011),l(-.182,1.195),l(-.352,.849),l(-.182,.184),l(-.404,.1),l(-.093,.24),l(.199,.536),l(-.104,.467),l(-.248,.354),l(-.569,.453),l(-.923,.581),l(-.591,.75),l(-1.383,1.98),l(-.631,.834),l(-1.242,1.373),l(-1.193,1.062),l(-.829,.863),l(-1.434,1.034),l(-1.379,1.091),l(-.552,.382),l(-.989,.638),l(-.676,.298),l(-.782,.101),l(-.98,-.012),l(-.549,.071),l(-.132,.354),l(.013,.127),l(-.109,.085),l(-.449,-.098),l(-.553,-.126),l(-.303,.015),l(-.25,.198),l(-.272,.312),l(-.226,.113),l(-.36,-.056),l(-.768,-.408),l(-.759,-.168),l(-.542,-.013),l(-.31,.113),l(-.38,.27),l(-.482,-.099),l(-.645,-.21),l(-.295,.1),l(-.638,.043),l(-.589,.214),l(-.729,.538),l(-.72,.086),l(-.44,-.013),l(-.667,-.084),l(-.738,.072),l(-.575,.199),l(-.827,.82),l(-1.251,-.576),l(-.092,-.509),l(-.218,-.183),l(-.479,-.056),l(-.28,.085),l(-.257,-.479),l(-.343,-.056),l(-.149,.255),l(-.035,.197),l(-.312,-.112),l(-.119,-.226),l(.267,-.495),l(.103,-.424),l(-.857,-1.354),l(-.323,-.282),l(-.134,-.226),l(.173,-.17),l(.636,-.044),l(.172,-.424),l(.06,-.819),l(-.163,-.663),l(-.186,-.522),l(-.61,-1.143),l(-.75,-1.029),l(-.472,-.903),l(-.612,-1.383),l(-.646,-1.467),l(-.573,-.818),l(-.436,-.467),l(.152,-.068),l(.584,-.27),l(.317,-.416),l(.109,-.217),l(.335,-.116),l(.329,.127),l(.637,.348),l(.193,.222),l(.042,.345),l(.055,.528),l(.296,.212),l(.517,.039),l(.892,-.048),l(.745,.042),l(.581,.166),l(.427,-.034),l(.581,-.498),l(.545,-.302),l(.454,-.318),l(.057,-.205),l(-.025,-2.246),l(-.031,-1.894),l(.006,-3.434),M(462.462,268.501),l(.412,-.044),l(.194,-.553),l(.633,-.343),l(1.035,-.303),l(.263,-.199),l(.582,-1.007),l(.268,-.326),l(.143,-.241),l(-.104,-.226),l(-.967,-.744),l(-.33,-.337),l(-.422,-.266),l(-.308,.086),l(-.995,.359),l(-.65,.329),l(-.513,.567),l(-.275,.44),l(-.691,.611),l(.12,.409),l(.582,.858),l(.285,.366),l(.739,.561),M(432.955,250.661),l(.456,.006),l(.077,.749),l(-.04,.678),l(-.772,.02),l(-.078,-.354),l(-.028,-.396),l(.285,-.297),l(.101,-.406),
+N(471.719,258.047),l(.075,.296),l(-.071,.495),l(.261,.889),l(.068,.382),l(-.131,.015),l(-.312,.186),l(-.064,.198),l(-.076,.594),l(-.595,.004),l(-.671,-.109),l(-.458,-.322),l(-.307,-.465),l(-.39,-.676),l(.005,-.325),l(.28,-.567),l(.657,-.979),l(.279,-.199),l(1.449,.585),
+N(462.462,268.501),l(-.739,-.561),l(-.285,-.366),l(-.582,-.858),l(-.12,-.409),l(.691,-.611),l(.275,-.44),l(.513,-.567),l(.65,-.329),l(.995,-.359),l(.308,-.086),l(.422,.266),l(.33,.337),l(.967,.744),l(.104,.226),l(-.143,.241),l(-.268,.326),l(-.582,1.007),l(-.263,.199),l(-1.035,.303),l(-.633,.343),l(-.194,.553),l(-.412,.044),
+N(790.15,283.022),l(.738,.197),l(.008,-.227),l(-.242,-.524),l(.052,-.284),l(.233,.014),l(.389,.17),l(.37,.751),l(.277,.964),l(.48,.17),l(1.753,.691),l(.506,.113),l(.37,-.072),l(.699,-.483),l(.885,-.343),l(.4,.027),l(.329,.17),l(.066,.454),l(-.022,.198),l(-.402,1.236),l(-.283,.072),l(-.761,.058),l(-.035,.683),l(-.124,.156),l(-.424,.029),l(-.746,.016),l(-.432,.2),l(-.271,.284),l(.041,.384),l(.254,.525),l(-.002,.213),l(-.151,.199),l(-.646,.515),l(-.898,1.129),l(-.847,1.058),l(-.756,.587),l(-.68,.316),l(-.337,-.171),l(-.47,-.313),l(-.237,-.328),l(.056,-.314),l(.288,-.386),l(.307,-.671),l(.398,-.5),l(-.031,-.343),l(-.271,-.128),l(-.761,-.582),l(-.421,-.185),l(-.593,-.184),l(-.98,-.452),l(-.306,-.256),l(-.11,-.17),l(.081,-.128),l(.419,-.157),l(1.389,-.685),l(.209,-.512),l(-.078,-.695),l(.087,-.312),l(.396,-.441),l(.032,-.383),l(-.482,-.837),l(.081,-.567),l(-.156,-.311),l(-.479,-.655),l(-.574,-.678),l(.102,-.164),l(-.145,-.304),l(-.291,-.351),l(-.336,-.188),l(-.29,-.163),l(.117,.233),l(.497,.515),l(.049,.141),l(-.169,0),l(-.211,-.281),l(-.525,-.631),l(-.622,-.771),l(-.518,-.561),l(.001,-.117),l(-.268,-.257),l(.04,-.141),l(.013,-.14),l(-.048,-.188),l(-.197,-.396),l(-.379,-.42),l(-.347,-.257),l(.163,-.046),l(.205,.093),l(.358,-.047),l(.131,-.093),l(.084,.28),l(-.149,.187),l(.186,.303),l(.177,.21),l(.167,.116),l(.228,.164),l(.041,-.141),l(.269,.023),l(.519,.257),l(.42,.117),l(.274,.07),l(.128,.257),l(-.011,.141),l(.185,.023),l(.146,-.188),l(.185,.023),l(-.022,.164),l(.227,.351),l(.249,.187),l(.233,.28),l(-.18,.023),l(-.076,.164),l(.093,.163),l(-.242,-.023),l(-.175,-.047),l(.143,.117),l(.251,.188),l(.23,.233),l(.352,.28),l(.063,.234),l(.019,.21),l(-.261,-.047),l(.096,.164),l(.239,.351),l(.256,.188),l(-.292,.023),l(-.226,0),l(-.205,-.047),l(-.006,.141),l(.306,.14),l(.324,.164),l(-.09,.211),l(.205,.046),l(.265,-.023),l(.226,0),l(.223,.141),l(-.114,.07),l(-.031,.141),l(.025,.141),l(.136,.06),M(782.939,297.694),l(-.088,.158),l(-.558,.13),l(-.309,.288),l(-.322,.101),l(-.246,.244),l(-.692,-.242),l(-.16,.086),l(.15,.216),l(.429,.415),l(-.141,.173),l(.02,.259),l(-.064,.431),l(-.218,-.071),l(-.976,-.099),l(.418,.229),l(.449,.244),l(-.278,.49),l(-.427,.896),l(-.212,.549),l(-.418,.318),l(-.673,.349),l(-.171,.246),l(-.259,.145),l(-.581,.233),l(-.593,.406),l(-.398,.015),l(-1.156,-.258),l(-.628,.112),l(-.585,-.442),l(-.812,-.158),l(-.373,-.066),l(-.162,-.308),l(-.467,-.098),l(-.24,.142),l(-.062,.168),l(-.78,.095),l(-.214,-.166),l(-.515,-.095),l(-.146,-.286),l(.432,-.089),l(-.223,-.216),l(.328,-.116),l(.322,-.001),l(-.452,-.482),l(.82,.266),l(-.464,-.576),l(.121,-.145),l(.946,.156),l(.082,-.13),l(-.141,-.173),l(-.201,-.216),l(-.06,-.288),l(.283,-.303),l(.569,-.246),l(.328,-.374),l(.561,-.375),l(.102,-.302),l(.998,-.575),l(1.106,-.275),l(.713,-.331),l(.544,-.36),l(.377,-.101),l(.685,-.575),l(.066,-.272),l(.48,-.302),l(.373,-.015),l(.787,-.331),l(.664,-.402),l(.126,-.215),l(-.008,-.172),l(.266,-.144),l(.448,-.302),l(-.109,-.501),l(.076,-.214),l(.166,-.44),l(.306,.048),l(.066,-.152),l(.58,-.259),l(.444,-.272),l(.137,-.285),l(.131,-1.187),l(.512,-.647),l(.372,.047),l(.365,.165),l(.032,.259),l(.337,.06),l(.187,.186),l(.231,.799),l(.312,.242),l(.973,-.645),l(.426,-.029),l(.367,.113),l(.222,.5),l(-.197,.399),l(.299,.429),l(.066,.271),l(-.611,.659),l(-.261,.401),l(-.476,.358),l(-.868,.746),l(-.578,.359),l(-.295,.13),l(-.236,.258),l(-.389,.159),l(-.271,.258),l(.416,.407),l(.428,.047),l(.421,.289),l(-.276,.113),l(-.484,.07),l(-.503,-.296),l(-.488,.131),l(-.352,.158),
+N(247.899,318.387),l(.008,-1.144),l(.821,.289),l(.06,.206),l(-.354,.312),l(-.534,.337),M(248.453,316.576),l(-.286,-.039),l(-1.385,-.36),l(-.841,-.217),l(-2.827,-.132),l(-1.41,.052),l(-.669,-.041),l(-.778,-.568),l(-.231,-2.285),l(-.187,-.248),l(-.654,.121),l(-.961,.283),l(-.218,-.043),l(-.508,-1.123),l(-.28,-1.309),l(.037,-.45),l(.271,-.292),l(1.729,-1.01),l(.307,-.263),l(.296,-1.218),l(.069,-.188),l(-.446,-.648),l(.249,-.781),l(.28,-.219),l(.598,-.161),l(.226,-.262),l(.212,-.434),l(.216,-.896),l(-.158,-1.035),l(.059,-1.094),l(.767,-.794),l(-.017,-.216),l(-.552,-.385),l(-.586,-.298),l(-.176,-.171),l(.757,-.146),l(.726,-.033),l(.322,-.13),l(.245,-.202),l(.007,-.186),l(-.302,-.17),l(-.789,-.11),l(-.26,-.185),l(-.252,-.585),l(.191,-1.458),l(-.088,-.655),l(-.555,-.111),l(-.125,-.128),l(-.094,-1.226),l(.106,-.271),l(.172,-.172),l(.596,-.317),l(-.012,-.427),l(-.231,-.867),l(-.123,-1.835),l(.1,-.37),l(.316,-.541),l(.511,-2.427),l(.053,-.312),l(.126,-.17),l(.951,-.529),l(.202,-.143),l(-.437,-.932),l(-.249,-1.103),l(-.014,-1.16),l(.142,-1.075),l(.231,-.312),l(1.334,-1.11),l(.078,-.325),l(-.189,-1.06),l(-.088,-.409),l(.319,-.595),l(1.083,-1.854),l(.075,-.41),l(-.055,-.69),l(-.784,-2.816),l(-.408,-1.154),l(-.285,-.633),l(.156,-.961),l(.388,-1.201),l(.292,-.34),l(.492,-.271),l(.124,-.185),l(-.054,-.762),l(-.167,-1.466),l(.823,-1.839),l(.282,-.439),l(.608,-.694),l(.464,-.835),l(.329,-.835),l(.791,-.089),l(.333,-.017),l(.152,-.311),l(-.011,-.227),l(-.53,-.477),l(-.114,-.507),l(.161,-.382),l(.273,-.369),l(-.03,-.226),l(-.34,-.449),l(-.113,-.437),l(.007,-.579),l(.421,-.722),l(-.25,-.817),l(.204,-.312),l(.819,-.372),l(1.346,-.53),l(.36,-.256),l(.541,-1.457),l(.093,-.636),l(-.161,-.154),l(-.212,-.14),l(-.107,-.056),l(2.026,-2.087),l(.292,-.27),l(.322,.181),l(.193,.169),l(.615,.194),l(.901,-.034),l(.527,-.045),l(.531,.067),l(.37,.195),l(.341,.309),l(.416,1.084),l(1.034,-1.784),l(.686,-.004),l(1.33,.077),l(.592,.109),l(.19,.056),l(.225,.337),l(.782,.913),l(1.271,1.376),l(.576,.562),l(.835,.588),l(.498,.237),l(1.173,.204),l(.671,.307),l(1.632,1.106),l(1.448,.697),l(.65,.18),l(.939,.503),l(-.018,.268),l(-.617,1.203),l(-.625,.851),l(-.048,.227),l(.21,.619),l(-.11,.198),l(-.486,.398),l(-.425,.426),l(-.064,.212),l(.19,.056),l(1.187,-.332),l(.607,.025),l(.992,.333),l(.564,.096),l(.71,-.005),l(.745,-.131),l(.387,-.172),l(.235,-.029),l(.35,.097),l(.609,.363),l(.352,-.51),l(.301,-.27),l(1.007,-.74),l(.375,-.468),l(.544,-1.57),l(-.02,-.239),l(.957,-.161),l(.462,-.017),l(.206,.196),l(.517,1.154),l(-.094,1.638),l(-.161,.467),l(-.521,.313),l(-1.754,.744),l(-.348,.242),l(-1.633,1.448),l(-1.435,1.363),l(-1.805,1.816),l(-.833,.88),l(-.214,.27),l(-.443,.524),l(-.065,.452),l(-.595,2.359),l(-.103,.522),l(.049,.847),l(.168,.986),l(-.118,.325),l(-.48,.524),l(-.24,.495),l(-.011,.522),l(.194,.577),l(-.054,.338),l(-.162,.273),l(-.26,.325),l(.015,.226),l(.924,.831),l(.68,.281),l(.715,.281),l(.283,.169),l(.281,.325),l(-.025,.325),l(-.362,.523),l(-.043,.396),l(.105,.339),l(.174,.269),l(.466,.325),l(.522,.168),l(.109,.113),l(.226,.892),l(-.308,.481),l(-.75,.937),l(-.729,.766),l(-.313,.737),l(-.368,.284),l(-.832,.342),l(-1.04,.342),l(-1.92,.401),l(-1.795,.188),l(-1.361,.116),l(-.945,.044),l(-1.175,-.11),l(-.934,-.226),l(-.128,.199),l(.036,.808),l(.322,.312),l(.308,.184),l(-.09,.298),l(-.381,.624),l(-.345,.498),l(-.069,.385),l(.392,.682),l(.066,.285),l(-.208,.214),l(-.105,.057),l(-1.251,.473),l(-1.137,.116),l(-.814,-.069),l(-.967,-.34),l(-1.47,-.396),l(-.246,.057),l(-.23,.271),l(.041,.598),l(.429,.684),l(.037,.398),l(-.242,.643),l(.092,.385),l(.773,.54),l(.796,.084),l(.369,-.2),l(-.387,-.398),l(.872,-.188),l(.383,-.043),l(.234,1.041),l(.052,.3),l(-.144,.157),l(-.299,.101),l(-.448,.072),l(-.261,-.157),l(-.104,-.299),l(-.115,-.071),l(-1.046,.073),l(-.67,.201),l(-.212,.101),l(.151,.214),l(.591,.07),l(.47,.113),l(.452,.113),l(.06,.028),l(-.864,.388),l(-.776,.287),l(-.577,.602),l(.003,.414),l(.161,.787),l(-.081,.258),l(-.815,.817),l(.022,.215),l(.423,.371),l(-.491,.116),l(-1.194,.088),l(-.48,.087),l(-.632,.246),l(-.619,.389),l(-.56,.548),l(-.549,.821),l(-.052,.389),l(.061,.375),l(.312,.591),l(.48,.446),l(.98,.633),l(.657,.244),l(.97,.143),l(.362,.086),l(.14,.274),l(-.151,.796),l(-.128,.348),l(-.342,.464),l(-.189,.145),l(-1.08,.524),l(-1.541,.814),l(-.712,.698),l(-.179,.276),l(-.093,.45),l(.111,.523),l(-.169,.451),l(-.239,.32),l(-.97,.454),l(-.969,.25),l(-.421,.221),l(-.323,.396),l(-.226,.791),l(-.054,.514),l(.2,.777),l(.547,.896),l(.699,.779),l(.235,.339),l(-.101,.032),M(247.899,318.387),l(.18,.182),l(.148,.073),l(.607,-.075),l(.344,.133),l(.648,.725),l(.908,.665),l(.993,.756),l(.525,.222),l(.73,.37),l(.246,.074),l(.42,-.001),l(.483,.163),l(1.283,.027),l(.142,-.016),l(-.006,.224),l(-.19,.209),l(-.492,.06),l(-1.198,.092),l(-.777,.196),l(-.364,0),l(-1.179,-.355),l(-.753,-.088),l(-1.15,-.027),l(-.814,-.014),l(-.831,.081),l(.098,-3.675),
+N(346.758,54.457),l(.127,-.162),l(.42,-.179),l(.894,.015),l(.674,-.098),l(-.354,-.227),l(-.405,-.34),l(.317,-.342),l(.277,0),l(.956,.42),l(.67,.048),l(.3,-.163),l(-.191,-.26),l(-.625,-.373),l(.366,-.245),l(1.037,.226),l(.957,.08),l(.746,.275),l(.446,.551),l(-.119,.405),l(-.441,.292),l(.922,.806),l(.553,-.356),l(.352,-.13),l(.63,-.114),l(.49,-.179),l(.061,-.21),l(-.169,-.778),l(.542,-.245),l(.501,.454),l(.426,.307),l(.489,.209),l(.215,.016),l(.185,-.13),l(-.264,-.454),l(.243,-.163),l(.27,-.033),l(.817,-.164),l(.683,.438),l(.536,.242),l(.542,.063),l(.05,-.178),l(-.358,-.535),l(1.006,.145),l(1.439,.079),l(.787,-.115),l(.427,-.229),l(-.021,-.716),l(1.167,.08),l(.635,.471),l(1.118,.323),l(.683,.015),l(.273,.243),l(-.252,.552),l(.786,.29),l(1.674,.159),l(.127,.145),l(.143,.548),l(-.07,.387),l(-.152,.256),l(-.152,.256),l(-.443,.129),l(-.815,.018),l(-.195,.096),l(-.04,.431),l(-.515,.463),l(-.497,.16),l(-.568,-.031),l(-.422,-.159),l(-.817,.495),l(-.539,.144),l(-1.46,.463),l(-.853,.113),l(-.726,.001),l(-.771,.097),l(-.784,.587),l(-.473,.127),l(-1.078,.097),l(-.709,-.03),l(-1.316,-.171),l(-.608,-.142),l(-1.283,-.489),l(-1.058,-.093),l(-.443,.064),l(-1.041,-.014),l(-1.834,-.124),l(-.297,-.206),l(.434,-.191),l(1.127,-.352),l(.701,-.59),l(-.818,-.015),l(-.51,-.126),l(-.428,-.398),l(-.253,-.095),l(-.358,.081),l(-1.564,.115),l(-.557,.033),l(-.37,-.223),l(.141,-.192),l(.388,-.129),l(.669,-.097),l(.794,-.017),l(.729,-.114),l(1.049,-.098),l(.376,-.194),l(.178,-.322),l(-.144,-.258),l(-.358,-.177),l(-.426,-.015),l(-.478,-.145),l(-1.005,-.047),l(-.821,.099),l(-.424,.162),l(-.676,.082),l(-1.041,-.272),l(-.16,-.21),
+N(462.829,67.958),l(.145,.053),l(.16,.131),l(-.043,.174),l(-.175,.044),l(-.189,0),l(-.116,0),l(-.088,.043),l(-.058,.131),l(-.175,.277),l(-.219,.204),l(-.319,.131),l(-.204,.131),l(-.088,.16),l(.029,.16),l(.131,.437),l(.073,.189),l(.029,.16),l(-.175,.131),l(0,.175),l(.175,.233),l(.203,.087),l(.088,.073),l(0,.073),l(.015,.087),l(.043,.146),l(.175,.043),l(.059,.059),l(-.175,.073),l(-.262,.043),l(-.16,.058),l(-.059,.102),l(-.087,.116),l(-.131,0),L(461.402,72),l(-.015,.087),l(-.116,.058),l(.081,.106),l(-.125,.025),l(-.087,-.015),l(-.306,-.043),l(-.16,-.058),l(-.175,-.073),l(-.204,-.044),l(-.131,.102),l(-.204,-.029),l(-.131,.044),l(-.16,.087),l(-.146,.014),l(-.146,-.087),l(-.116,-.029),l(-.175,0),l(-.204,-.117),l(-.116,-.174),l(-.203,-.117),l(-.146,-.043),l(-.072,-.117),l(-.189,0),l(-.247,-.043),l(-.204,-.117),l(-.029,0),l(-.276,-.014),l(-.102,-.102),l(-.248,-.043),l(-.116,-.102),l(-.189,-.087),l(0,.073),l(-.116,.087),l(-.131,-.058),l(-.015,-.073),l(-.087,-.029),l(-.103,0),l(-.276,.117),l(-.102,.029),l(-.131,.015),l(-.219,.015),l(-.146,.043),l(-.262,.029),l(-.276,.087),l(-.116,.102),l(-.087,0),l(.156,-.19),l(-.003,-.351),l(.183,-.238),l(-.368,-.21),l(-.605,.437),l(-.334,-.251),l(-.527,-.038),l(.043,-.942),l(-.396,.188),l(-.336,-.415),l(.158,-.202),l(-.209,-.254),l(.265,-.074),l(-.092,-.252),l(.344,-.042),l(1.026,-.084),l(-.006,-.132),l(.561,-.108),l(.133,-.188),l(.436,.101),l(.074,-.113),l(.317,.05),l(.083,-.215),l(1.104,.193),l(.446,-.294),l(.091,.165),l(.514,-.089),l(1.383,.029),l(1.152,.167),l(.305,.12),l(.592,-.045),l(.971,.09),l(.426,-.108),l(.271,-.24),l(-.006,-.009),
+N(461.353,72.251),l(.37,-.004),l(-.015,.116),l(0,.117),l(.232,.073),l(.204,.087),l(.087,.073),l(.204,.058),l(-.015,.087),l(-.029,.116),l(-.015,.087),l(-.102,.073),l(-.087,.015),l(-.103,.029),l(.131,.087),l(-.072,.131),l(.029,.117),l(-.073,.087),l(-.102,.073),l(-.044,.102),l(.204,-.059),l(.146,-.015),l(.131,.073),l(.087,.014),l(.073,.044),l(-.059,.087),l(-.043,.073),l(.116,.102),l(.131,.058),l(.029,.16),l(.146,.102),l(.16,.043),l(-.059,.087),l(.131,.117),l(-.015,.189),l(.088,.233),l(-.044,.087),l(-.015,.117),l(-.061,.042),l(-.241,.044),l(-.24,.051),l(-.12,.12),l(-.223,.034),l(-.137,.154),l(-.137,.085),l(-.069,.103),l(-.068,.206),l(-.188,.035),l(-.239,-.035),l(-.24,-.034),l(-.325,-.034),l(-.359,0),l(-.172,.068),l(-.103,.137),l(-.223,.085),l(-.154,0),l(-.103,-.017),l(-.086,.052),l(-.377,-.035),l(-.273,-.068),l(-.154,-.171),l(-.138,-.154),l(-.325,-.137),l(-.497,-.223),l(-.342,-.24),l(-.377,-.034),l(-.583,-.035),l(-.325,-.12),l(-.291,-.188),l(-.086,-.257),l(-.188,.017),l(-.171,.068),l(-.36,.171),l(-.394,.017),l(-.24,0),l(-.273,.085),l(-.24,-.085),l(-.309,-.103),l(-.6,-.017),l(-.291,.069),l(-.359,-.069),l(-.291,-.051),l(-.154,.034),l(-.274,.069),l(-.103,-.052),l(-.12,-.137),l(-.154,0),l(-.257,.068),l(-.188,0),l(-.754,-.017),l(-.445,-.085),l(-.754,.171),l(-.599,.154),l(-.429,.103),l(-.257,.137),l(-.052,.188),l(-.526,.026),l(-.065,-.059),l(.073,-.837),l(.035,-.302),l(.127,-.167),l(.672,-.379),l(.034,-.717),l(.267,-.162),l(.267,-.273),l(.217,-.203),l(.296,-.026),l(1.056,-.199),l(.166,-.046),l(.162,-.066),l(.29,0),l(.049,.237),l(.657,.388),l(.422,.162),l(.23,.473),l(.091,.15),l(.441,.196),l(.785,.059),l(.868,-.244),l(.24,-.122),l(.178,-.288),l(-.052,-.394),l(-.193,-.869),l(.198,-.243),l(.045,-.055),l(.087,0),l(.116,-.102),l(.276,-.087),l(.262,-.029),l(.146,-.043),l(.219,-.015),l(.131,-.015),l(.102,-.029),l(.276,-.117),l(.103,0),l(.087,.029),l(.015,.073),l(.131,.058),l(.116,-.087),l(0,-.073),l(.189,.087),l(.116,.102),l(.248,.043),l(.102,.102),l(.276,.014),l(.029,0),l(.204,.117),l(.247,.043),l(.189,0),l(.072,.117),l(.146,.043),l(.203,.117),l(.116,.174),l(.204,.117),l(.175,0),l(.116,.029),l(.146,.087),l(.146,-.014),l(.16,-.087),l(.131,-.044),l(.204,.029),l(.131,-.102),l(.204,.044),l(.175,.073),l(.16,.058),l(.306,.043),l(.087,.015),l(.125,-.025),
+N(451.02,79.165),l(-.029,-.038),l(-.034,-.137),l(-.018,-.171),l(.068,-.206),l(.068,-.154),l(.224,-.12),l(-.052,-.12),l(-.018,-.137),l(-.171,-.069),l(-.188,-.034),l(-.103,-.103),l(-.086,-.137),l(-.223,.017),l(-.257,0),l(-.445,0),l(-.223,.051),l(-.086,-.103),l(-.514,-.068),l(-.257,-.069),l(-.223,-.12),l(-.24,0),l(-.086,-.052),l(-.051,-.154),l(-.12,.034),l(-.353,.096),l(-.043,-.077),l(.128,-.012),l(.034,-.183),l(-.439,-.646),l(-.008,-.14),l(-.042,-.727),l(-.112,-.102),l(.526,-.026),l(.052,-.188),l(.257,-.137),l(.429,-.103),l(.599,-.154),l(.754,-.171),l(.445,.085),l(.754,.017),l(.188,0),l(.257,-.068),l(.154,0),l(.12,.137),l(.103,.052),l(.274,-.069),l(.154,-.034),l(.291,.051),l(.359,.069),l(.291,-.069),l(.6,.017),l(.309,.103),l(.24,.085),l(.273,-.085),l(.24,0),l(.394,-.017),l(.36,-.171),l(.171,-.068),l(.188,-.017),l(.086,.257),l(.291,.188),l(.325,.12),l(.583,.035),l(.377,.034),l(.342,.24),l(.497,.223),l(.325,.137),l(.138,.154),l(.154,.171),l(.273,.068),l(.377,.035),l(-.017,.171),l(-.086,.154),l(-.034,.12),l(-.12,.137),l(-.086,.137),l(.343,.034),l(.274,.052),l(.085,.051),l(-.119,.051),l(-.086,0),l(-.103,.154),l(-.018,.154),l(-.171,.017),l(-.12,-.086),l(-.12,.051),l(-.239,-.034),l(-.154,.034),l(-.086,.154),l(-.103,.154),l(-.257,.068),l(-.429,0),l(-.137,.137),l(-.12,.12),l(-.034,.154),l(-.086,.171),l(.103,.171),l(-.068,.137),l(-.239,.154),l(0,.137),l(-.068,.085),l(-.069,.137),l(.172,.034),l(.205,0),l(.138,.206),l(-.086,.188),l(-.274,.017),l(-.223,-.068),l(0,-.154),l(-.034,-.085),l(-.086,-.069),l(-.171,.051),l(-.12,.086),l(-.291,-.034),l(-.068,.137),l(-.24,.12),l(-.154,0),l(-.188,-.034),l(-.273,.103),l(.086,.171),l(-.069,.12),l(-.171,.034),l(-.137,-.034),l(-.206,.051),l(-.377,.154),l(-.291,0),l(-.068,-.103),l(-.12,-.051),l(-.239,.051),l(-.377,.017),l(-.24,.034),l(-.291,-.034),l(-.154,.034),l(-.093,-.035),l(-.09,-.171),l(-.016,-.029),l(-.099,-.186),l(-.284,-.487),l(-.679,-.243),l(-.04,-.014),l(-.641,.021),
+N(452.867,80.273),l(.093,.035),l(.154,-.034),l(.291,.034),l(.24,-.034),l(.377,-.017),l(.239,-.051),l(.12,.051),l(.068,.103),l(.291,0),l(.377,-.154),l(.206,-.051),l(.137,.034),l(.171,-.034),l(.069,-.12),l(-.086,-.171),l(.273,-.103),l(.188,.034),l(.154,0),l(.24,-.12),l(.068,-.137),l(.291,.034),l(.12,-.086),l(.171,-.051),l(.086,.069),l(.034,.085),l(0,.154),l(.223,.068),l(.274,-.017),l(.086,-.188),l(-.138,-.206),l(-.205,0),l(-.172,-.034),l(.069,-.137),l(.068,-.085),l(0,-.137),l(.239,-.154),l(.068,-.137),l(-.103,-.171),l(.086,-.171),l(.034,-.154),l(.12,-.12),l(.137,-.137),l(.429,0),l(.257,-.068),l(.103,-.154),l(.086,-.154),l(.154,-.034),l(.239,.034),l(.12,-.051),l(.12,.086),l(.171,-.017),l(.018,-.154),l(.103,-.154),l(.086,0),l(.119,-.051),l(-.085,-.051),l(-.274,-.052),l(-.343,-.034),l(.086,-.137),l(.12,-.137),l(.034,-.12),l(.086,-.154),l(.017,-.171),l(.086,-.052),l(.103,.017),l(.154,0),l(.223,-.085),l(.103,-.137),l(.172,-.068),l(.359,0),l(.325,.034),l(.24,.034),l(.239,.035),l(.188,-.035),l(.068,-.206),l(.069,-.103),l(.137,-.085),l(.137,-.154),l(.223,-.034),l(.12,-.12),l(.24,-.051),l(.241,-.044),l(.165,.147),l(.229,.066),l(.197,-.131),l(.181,.016),l(.312,.033),l(.132,.148),l(.082,.148),l(.197,-.033),l(.214,-.065),l(.361,-.049),l(.312,.049),l(.296,.065),l(.147,.017),l(0,.115),l(-.164,.099),l(-.017,.099),l(.065,.148),l(.164,.148),l(.197,0),l(.214,-.197),l(.279,-.016),l(.165,0),l(.147,-.099),l(.23,-.083),l(.131,.049),l(.099,.049),l(.247,-.049),l(.542,.115),l(.132,.131),l(.279,.099),l(.099,.099),l(.147,.099),l(.165,.033),l(.147,-.033),l(.049,.115),l(-.065,.115),l(0,.083),l(-.033,.164),l(-.131,.165),l(.197,.247),l(.147,.099),l(.05,.164),l(-.066,.131),l(-.114,0),l(0,.083),l(-.115,.082),l(-.099,.049),l(-.033,.165),l(-.049,.147),l(.345,.049),l(.132,.181),l(.082,.115),l(.181,-.049),l(.132,.033),l(-.099,.115),l(-.066,.131),l(.017,.099),l(.214,.017),l(.164,.263),l(.115,.23),l(.443,.213),l(.23,.066),l(.279,.082),l(.164,.099),l(.066,.148),l(-.099,.197),l(-.066,.181),l(.182,.066),l(.361,-.066),l(.378,.066),l(.361,.099),l(.263,.066),l(-.032,.065),l(-.066,.049),l(-.082,.017),l(.099,.181),l(.296,.148),l(.279,.066),l(.033,.131),l(-.065,.164),l(-.296,0),l(-.148,.083),l(-.049,.065),l(-.444,.247),l(-.525,.099),l(-.51,-.016),l(-.197,-.132),l(-.328,-.049),l(-.362,.017),l(-.131,.165),l(-.099,.131),l(.017,.164),l(.279,.263),l(.296,.164),l(0,.165),l(-.132,.066),l(.099,.148),l(.147,.131),l(-.082,.099),l(.033,.164),l(.033,.23),l(-.033,.099),l(.164,.082),l(.082,.115),l(.165,.066),l(.002,.142),l(-.519,-.005),l(-.522,.056),l(-.112,.131),l(-.205,-.056),l(-.187,-.037),l(-.336,.075),l(-.057,.13),l(-.111,.112),l(-.317,.187),l(-.188,.261),l(-.261,.224),l(-.057,.206),l(.243,.205),l(.056,.149),l(-.131,.206),l(-.261,-.019),l(-.149,-.056),l(-.149,-.206),l(-.112,-.056),l(-.187,-.075),l(-.224,-.037),l(-.225,.037),l(-.242,.075),l(-.299,.019),l(-.149,-.131),l(-.224,.075),l(-.188,.093),l(-.316,.056),l(-.188,-.056),l(-.037,-.205),l(-.112,-.131),l(-.168,-.131),l(-.13,.038),l(-.131,.075),l(-.168,0),l(-.299,.149),l(-.131,.149),l(-.168,0),l(-.094,-.187),l(-.13,-.075),l(-.206,0),l(-.224,.112),l(-.131,-.187),l(-.224,-.093),l(-.131,.112),l(-.354,.056),l(-.262,-.112),l(-.112,0),l(-.019,.205),l(-.168,.093),l(-.093,-.056),l(.056,-.224),l(-.243,-.038),l(-.187,-.056),l(-.541,.112),l(0,-.149),l(-.187,0),l(.019,-.224),l(-.28,-.037),l(-.242,.075),l(-.523,-.112),l(-.578,-.056),l(-.075,-.056),l(-.522,0),l(-.205,-.168),l(-.262,.019),l(-.522,-.093),l(-.467,.075),l(-.485,0),l(-.354,-.056),l(-.355,.056),l(-.354,.056),l(-.485,-.038),l(-.485,.019),l(-.205,.187),l(-.037,.168),l(-.374,.168),l(-.373,.206),l(-.112,-.112),l(-.261,0),l(-.374,-.019),l(-.037,.131),l(0,.045),l(-.126,-.137),l(.315,-.752),l(-.013,-.25),l(-.218,-.146),l(-.149,-.176),l(-.421,-.146),l(-.289,-.012),l(.128,-.292),l(.291,-.328),l(.571,-.244),l(.44,-.03),l(.263,-.208),l(.023,-.236),l(-.172,-.502),l(-.615,-1.5),l(-.16,-.302),
+N(400.125,81.146),l(.633,.305),l(.208,.207),l(.208,.37),l(-.038,.193),l(-.545,.563),l(.714,.176),l(.396,-.311),l(.527,-.119),l(.602,.028),l(.807,.176),l(.467,.354),l(.235,.752),l(-.077,.221),l(-.322,.414),l(-1.068,.473),l(-.767,.561),l(-.96,.237),l(1.223,.167),l(.501,.043),l(.354,-.104),l(.39,.117),l(-.066,.516),l(-.997,.308),l(.005,.199),l(-.479,-.084),l(-1.068,.443),l(-.879,-.142),l(-.293,-.048),l(-1.119,.211),l(-.587,-.211),l(-.598,.112),l(-1.584,.141),l(.137,.295),l(-.907,-.168),l(-.264,.168),l(-.911,-.337),l(-.334,.143),l(-.913,.089),l(-.093,.569),l(-.337,.316),l(-.37,.042),l(-.272,-.252),l(-.53,-.172),l(-.135,.151),l(-.527,-.077),l(-.948,.324),l(-.701,.552),l(-.326,-.231),l(-.775,-.147),l(1.2,-.472),l(.492,-.476),l(.447,-.097),l(.468,-.388),l(.118,-.485),l(.242,.063),l(.367,-.211),l(-.008,-.274),l(1.013,-.105),l(.76,.119),l(.927,.007),l(.073,-.338),l(.308,-.142),l(.321,-.556),l(-.939,.394),l(-.725,.016),l(-1.467,-.482),l(-1.866,-.055),l(-.399,-.191),l(-.156,-.162),l(.417,-.325),l(.983,-.194),l(.721,-.237),l(.38,-.384),l(.066,-.827),l(-.119,-.192),l(-.713,.046),l(-.34,-.044),l(.288,-.355),l(.387,-.223),l(.802,-.253),l(1.394,-.062),l(.922,-.076),l(-.316,-.548),l(.172,-.683),l(.253,-.461),l(-.045,-.312),l(-.834,.061),l(-.484,-.296),l(-.2,-.312),l(.309,-.507),l(.617,-.433),l(-.347,-.104),l(-.596,-.088),l(-.735,.3),l(-.476,.061),l(-.753,-.222),l(-.088,.194),l(-.222,.194),l(-.672,-.103),l(-.464,-.133),l(.1,-.343),l(.348,-.36),l(.604,-.706),l(-.293,-.134),l(-.305,-.39),l(.028,-.24),l(.304,-.106),l(.3,-.196),l(-.194,-.496),l(-.306,.076),l(-.636,.453),l(-.442,.031),l(-.526,.287),l(-.14,-.421),l(.302,-.527),l(.438,-.559),l(.065,-.257),l(-.417,-.195),l(-.196,-.045),l(-.218,.302),l(-.394,.257),l(-.493,-.165),l(.299,-.575),l(.54,-.455),l(.09,-.136),l(-.225,-.575),l(.366,-.092),l(.225,-.197),l(-.672,-.515),l(.432,-.351),l(.752,.151),l(.387,-.092),l(-.645,-.759),l(.975,-.169),l(-.457,-.502),l(.416,-.382),l(.924,.365),l(.824,-.093),l(.686,-.139),l(.867,-.047),l(.612,.014),l(.303,.259),l(-.307,.29),l(-1.726,.704),l(-.46,.274),l(-.218,.441),l(.222,.182),l(.784,.029),l(.877,-.078),l(.685,-.001),l(.53,.075),l(1.563,-.064),l(.458,.378),l(-.363,.425),l(-.212,.323),l(.098,.112),l(-.565,.66),l(-.226,.111),l(-.339,.437),l(-.696,.261),l(-.382,.038),l(.451,.186),l(.508,.167),l(-.116,.015),l(-.272,.19),l(-.61,.052),l(-.275,.196),l(-1.337,-.025),l(.404,.223),l(.302,0),l(.492,.093),l(.432,-.006),l(.519,-.223),l(.413,-.025),l(.449,.161),l(.656,.164),l(.673,.566),l(.496,.228),l(.118,.165),l(-.067,.238),l(.312,.78),l(.371,.536),l(.438,.189),l(.714,.107),l(.59,.549),l(.688,.593),l(.135,.52),l(-.188,.49),l(.257,.124),M(387.915,77.13),l(-.128,-.325),l(.149,-.335),l(.38,-.089),l(.079,.501),l(-.307,.251),l(-.173,-.003),M(386.786,80.184),l(-.178,-.272),l(-.967,.072),l(.123,-.256),l(-.364,-.15),l(-.26,-.257),l(-.335,-.107),l(-.253,.364),l(-.751,.257),l(-.778,-.192),l(-.401,-.278),l(-.101,-.278),l(.86,-.278),l(-.483,-.257),l(.817,-.107),l(.385,-.484),l(-.029,-.235),l(.449,-.09),l(.508,-.15),l(.781,-.077),l(.424,.044),l(.389,.104),l(.362,-.046),l(.218,.149),l(.519,.791),l(.047,.179),l(-.081,.298),l(.308,.446),l(-.155,.328),l(-.402,.328),l(-.354,.12),l(-.299,.038),
+N(578.943,106.217),l(-.41,-.375),l(-.466,-.098),l(-.663,0),l(-.196,-.27),l(-.27,-.147),l(-.147,-.344),l(-.564,.049),l(-.981,-.246),l(-.662,.074),l(-1.35,-.024),l(-.662,-.098),l(-.712,-.221),l(-.785,.147),l(-.761,0),l(-.858,.024),l(-.441,.27),l(-.54,-.098),l(-.908,-.196),l(-.735,-.246),l(-.761,-.27),l(-.589,-.074),l(-.688,.123),l(-.466,.368),l(-.245,.736),l(.024,.442),l(-.344,-.123),l(-.81,-.123),l(-.688,-.196),l(-.883,-.245),l(-.883,-.147),l(-.663,.098),l(-.736,.123),l(-.318,.368),l(-.393,.442),l(.044,.273),l(-.322,.031),l(-.377,.377),l(-.283,-.126),l(-.22,.063),l(-.346,.283),l(-.534,.471),l(-.755,.189),l(-.943,.377),l(-.282,.188),l(-.221,.472),l(-.439,.188),l(-.504,.44),l(.157,.409),l(-.125,.188),l(-.66,0),l(-.44,-.346),l(.062,-.283),l(-.062,-.283),l(-.44,-.314),l(-.346,0),l(-1.006,.094),l(-.691,.032),l(-.503,-.063),l(-.346,-1.069),l(-.221,-.817),l(-1.006,0),l(-.031,-.754),l(.188,-.409),l(.031,-1.038),l(-.66,.314),l(-.66,-1.006),l(-.597,-.22),l(-.724,-.723),l(-1.1,.409),l(-2.767,-.188),l(-2.578,.346),l(-2.012,-1.666),l(-5.722,-2.986),l(-5.658,1.289),l(-.056,8.174),l(-.158,-.014),l(-.341,.106),l(-.489,.043),l(-.447,-.255),l(-.638,-.703),l(-.256,-.511),l(-.617,-.383),l(-.681,-.383),l(-.512,-.234),l(-.979,.085),l(-1.277,.298),l(-.937,.532),l(-.529,.453),l(.092,-.399),l(-.06,-.18),l(-.12,-.12),l(.14,-.26),l(.2,-.2),l(.14,-.32),l(.04,-.3),l(.18,-.2),l(-.159,-.24),l(-.4,-.16),l(-.459,.06),l(-.18,-.16),l(-.3,.06),l(-.2,.04),l(-.199,-.18),l(-.221,-.32),l(-.319,-.28),l(-.34,0),l(-.359,.02),l(0,-.2),l(.08,-.28),l(-.2,-.379),l(-.239,-.12),l(-.2,-.24),l(-.399,-.799),l(-.08,-.28),l(-.56,-.12),l(-.699,-.08),l(-.14,-.16),l(.02,-.439),l(.16,-.12),l(.3,-.06),l(.399,.02),l(.34,.02),l(.479,.14),l(.539,.18),l(.18,-.08),l(.36,-.08),l(-.2,-.16),l(-.26,-.12),l(-.399,-.2),l(-.2,-.24),l(.26,-.36),l(.28,-.04),l(.08,-.26),l(.18,-.299),l(.12,-.14),l(.26,.04),l(.319,-.08),l(.16,-.1),l(.339,.12),l(.24,0),l(1.119,-.04),l(.999,.14),l(.499,.02),l(-.159,-.08),l(-.34,-.2),l(-.479,-.12),l(-.021,-.3),l(.2,-.2),l(.279,-.22),l(.221,-.28),l(.119,-.52),l(.12,-.28),l(-.16,-.24),l(-.14,-.16),l(.1,-.2),l(.26,-.2),l(-.119,-.12),l(-.101,-.3),l(-.359,-.12),l(-.359,-.04),l(-.68,-.1),l(-.2,.16),l(-.199,.08),l(-.52,.08),l(-.46,-.12),l(-.319,-.26),l(-.26,-.06),l(-.68,-.12),l(-.56,.06),l(-.659,.319),l(-.42,.02),l(-.799,.5),l(-.72,.28),l(-.499,.06),l(-.42,-.02),l(-.279,.24),l(-.213,.18),l(-.616,-.19),l(-.857,-.377),l(-.068,-.308),l(.343,-.103),l(.309,.103),l(.445,.103),l(.138,-.103),l(-.96,-1.131),l(-.343,-.514),l(-.479,-.206),l(-.515,-.445),l(-.514,-.034),l(-.343,.034),l(-.583,-.206),l(-.103,.343),l(-.514,-.514),l(.068,-.309),l(-.138,-.377),l(-1.37,-.343),l(.65,-1.165),l(.446,-.274),l(.239,-.206),l(-.239,-.274),l(-.343,-.171),l(.205,-1.303),l(.823,-.137),l(.343,-.549),l(.103,-.308),l(.411,-.069),l(.514,.24),l(.48,.548),l(.514,.411),l(.651,0),l(.411,-.24),l(.068,-.446),l(-.171,-.411),l(-.068,-.445),l(.479,-.206),l(.891,-.411),l(.172,-.24),l(.309,-.309),l(.514,-.171),l(.549,-.068),l(.788,-.377),l(.548,-.343),l(.515,-.309),l(.651,.069),l(.479,0),l(.309,.274),l(.651,-.137),l(.273,-.137),l(.617,-.24),l(.411,.069),l(.411,.514),l(.788,.035),l(.617,-.069),l(.96,.171),l(0,.343),l(.582,.206),l(.789,.343),l(.411,.274),l(.068,.583),l(.274,.137),l(.239,-.274),l(-.205,-.48),l(-.034,-.24),l(.72,.068),l(.582,.548),l(.686,.137),l(.411,.24),l(.686,-.171),l(.274,-.274),l(.377,-.343),l(.514,-.377),l(.823,.068),l(.65,.035),l(.651,.411),l(.617,-.068),l(.137,-.412),l(1.062,-.103),l(.754,.103),l(.274,.548),l(.926,.309),l(.754,.137),l(.411,.171),l(.651,-.343),l(.171,-.309),l(.24,0),l(.343,.343),l(.959,.034),l(1.577,-.411),l(.137,-.309),l(.138,-.686),l(-.24,-.24),l(-1.165,-.171),l(-.274,-.308),l(-.651,-.069),l(-.377,-.137),l(.068,-.171),l(-.377,-.137),l(-.239,0),l(-.164,-.274),l(.467,-.067),l(.735,-.368),l(.588,-.147),l(.331,-.294),l(-.441,-.478),l(-.146,-.257),l(.662,-.515),l(.698,-.184),l(1.103,.147),l(.515,-.073),l(.11,-.257),l(-.956,-.294),l(-1.065,-.11),l(0,-.331),l(.294,-.074),l(-.294,-.221),l(-.074,-.441),l(.185,-.515),l(.33,-.074),l(1.066,.147),l(.515,0),l(.772,0),l(.368,-.184),l(1.396,-.405),l(1.029,-.037),l(.735,-.11),l(1.545,-.11),l(.588,-.073),l(.331,.073),l(.221,-.331),l(.625,-.331),l(1.177,-.037),l(2.021,-.405),l(1.876,-.073),l(.625,-.074),l(.367,-.368),V(0,77.39),l(.515,-.037),l(.589,-.184),l(.11,-.221),l(.735,-.037),l(.919,.147),l(.515,.11),l(.772,.257),l(.625,-.11),l(.882,-.037),l(.368,.404),l(-.037,.331),l(.147,.221),l(.515,.22),l(-.11,.331),l(-.147,.257),l(.073,.331),l(-.33,.037),l(.184,.257),l(.478,.074),l(.295,-.147),l(.44,.11),l(.368,-.147),l(.367,.074),l(.331,-.221),l(.294,.11),l(.295,.368),l(.367,.221),l(.147,-.147),l(.184,-.147),l(.478,.037),l(.405,.294),l(.478,.11),l(.441,-.221),l(.367,0),l(-.146,.294),l(-.441,.184),l(-.331,.441),l(.331,.184),l(.441,-.11),l(.771,-.073),l(.441,.037),l(.552,.184),l(.294,-.294),l(.772,-.441),l(1.103,-.257),l(.956,-.515),l(.772,-.221),l(.515,-.22),l(.809,-.074),l(0,.441),l(-.515,.11),l(-.11,.368),l(1.104,.588),l(.809,.294),l(1.287,.772),l(1.066,1.029),l(1.69,2.133),l(.846,.882),l(1.104,1.434),l(.515,-.257),l(.331,-.257),l(.367,-.515),l(.92,0),l(.367,.331),l(0,.368),l(.478,0),l(.258,.257),l(.184,.184),l(.589,0),l(.992,0),l(.993,-.221),l(.771,-.221),l(.993,-.037),l(.698,.441),l(.772,.588),l(.331,.625),l(.956,.147),l(.588,.552),l(.662,.699),l(.882,.073),l(.993,.074),l(.478,-.368),l(.625,-.184),l(-.073,.331),l(.441,.331),l(.294,.478),l(.589,0),l(.064,.145),l(-.551,.034),l(-.542,.148),l(-.279,.262),l(-.011,.275),l(-.035,.478),l(-.306,.219),l(-.289,.06),l(-1.199,.093),l(-.428,.277),l(-.34,.581),l(.097,.75),l(.213,.707),l(-.157,.39),l(-.444,.392),l(-.417,.103),l(-.718,.062),l(-1.402,-.079),l(-.594,-.141),l(-.721,-.141),l(-1.096,-.254),l(-.427,.507),l(-.516,1.141),L(584.2,97.43),l(-.286,.605),l(-.137,.418),l(.622,.514),l(.126,.286),l(-.156,.245),l(-.231,.145),l(-.394,.074),l(-1.133,-.238),l(-.5,-.184),l(-.35,.06),l(-1.082,.207),l(-1.799,.254),l(-.393,.188),l(-.215,.302),l(-.068,.215),l(.232,.185),l(.366,-.06),l(.483,.141),l(.03,1.357),l(.345,.627),l(.29,.441),l(.119,.47),l(-.222,.33),l(-.705,.546),l(-.32,.401),l(-.02,.399),l(.139,.86),
+N(386.786,80.184),l(-.304,.038),l(-.223,.09),l(.241,.252),l(.361,.771),l(.287,1.213),l(-.061,.281),l(-.359,.341),l(-.242,.414),l(-.145,.473),l(-.185,.044),l(-.284,-.058),l(-.616,.031),l(-.15,.212),l(-.913,.042),l(-.84,.132),l(-.247,.144),l(-.661,.286),l(-.903,.498),l(-.628,.035),l(-.879,.283),l(-1.28,.084),l(.053,-.378),l(-.089,-.441),l(-.848,.1),l(-.171,-.487),l(.734,-.254),l(-1.186,-.021),l(.062,-.233),l(1.286,.027),l(.198,-.104),l(.039,-.222),l(.107,-.31),l(.515,-.134),l(.692,-.031),l(.13,-.281),l(-1.07,.099),l(.387,-.437),l(-.187,-.159),l(.481,-.468),l(.694,-.011),l(.163,-.089),l(-.174,-.311),l(-.348,.177),l(-.309,-.131),l(-.319,.03),l(-.391,-.177),l(-.414,.001),l(-.182,.106),L(378,81.478),l(.309,-.306),l(-.29,-.142),l(.759,-.126),l(-.139,-.301),l(.391,-.235),l(-.481,-.214),l(-.59,.128),L(378,79.792),l(.38,-.268),l(.215,-.16),l(.928,.187),l(.336,-.075),l(.527,.038),l(1.102,.123),l(-.214,-.358),L(382.132,79),l(.198,-.321),l(-1.373,0),l(.154,-.15),l(.569,-.107),l(.061,-.29),l(.291,-.479),l(.505,-.181),l(.804,-.169),l(.22,.302),l(.354,.149),l(.156,-.031),l(.029,.235),l(-.385,.484),l(-.817,.107),l(.483,.257),l(-.86,.278),l(.101,.278),l(.401,.278),l(.778,.192),l(.751,-.257),l(.253,-.364),l(.335,.107),l(.26,.257),l(.364,.15),l(-.123,.256),l(.967,-.072),l(.178,.272),
+N(452.998,85.535),V(0,85.49),l(.037,-.131),l(.374,.019),l(.261,0),l(.112,.112),l(.373,-.206),l(.374,-.168),l(.037,-.168),l(.205,-.187),l(.485,-.019),l(.485,.038),l(.354,-.056),l(.355,-.056),l(.354,.056),l(.485,0),l(.467,-.075),l(.522,.093),l(.262,-.019),l(.205,.168),l(.522,0),l(.075,.056),l(.578,.056),l(.523,.112),l(.242,-.075),l(.28,.037),l(-.019,.224),l(.187,0),l(0,.149),l(.541,-.112),l(.187,.056),l(.243,.038),l(-.056,.224),l(.093,.056),l(.168,-.093),l(.019,-.205),l(.112,0),l(.262,.112),l(.354,-.056),l(.131,-.112),l(.224,.093),l(.131,.187),l(.224,-.112),l(.206,0),l(.13,.075),l(.094,.187),l(.168,0),l(.131,-.149),l(.299,-.149),l(.168,0),l(.131,-.075),l(.13,-.038),l(.168,.131),l(.112,.131),l(.037,.205),l(.188,.056),l(.316,-.056),l(.188,-.093),l(.224,-.075),l(.149,.131),l(.299,-.019),l(.242,-.075),l(.225,-.037),l(.224,.037),l(.187,.075),l(.112,.056),l(.149,.206),l(.149,.056),l(.261,.019),l(.131,-.206),l(-.056,-.149),l(-.243,-.205),l(.057,-.206),l(.261,-.224),l(.188,-.261),l(.317,-.187),l(.111,-.112),l(.057,-.13),l(.336,-.075),l(.187,.037),l(.205,.056),l(.112,-.131),l(.522,-.056),l(.519,.005),l(.357,.089),l(.469,.022),l(.313,-.156),l(.179,-.291),l(.134,-.268),l(.536,.246),l(.536,-.022),l(.67,-.223),l(.692,.112),l(.514,-.134),l(.201,.268),l(.312,.134),l(.246,.335),l(.134,.201),l(.246,.156),l(.312,.156),l(0,.268),l(-.312,-.022),l(-.312,.134),l(.134,.291),l(.111,.357),l(.269,.29),l(.647,0),l(.156,.112),l(.514,-.067),l(.38,.022),l(0,.312),l(.402,0),l(0,.357),l(.224,.268),l(.089,.246),l(-.089,.179),l(.089,.224),l(.179,.089),l(.291,.29),l(.268,-.179),l(.47,-.067),l(.268,.067),l(.469,.291),l(.201,-.067),l(.179,.022),l(.179,.156),l(.425,-.112),l(.312,-.112),l(.269,0),l(.536,-.134),l(.357,-.067),l(.111,.156),l(.268,.179),l(0,.134),l(.201,.179),l(.022,.134),l(.402,.044),l(.179,.179),l(.224,.112),l(.29,-.134),l(.045,-.157),l(.224,-.067),l(.29,.268),l(.425,.067),l(.469,.112),l(.268,.112),l(.357,-.067),l(.201,.179),l(.291,.089),l(.469,.022),l(.111,.224),l(.357,.156),l(.269,0),l(.134,-.044),l(.201,-.089),l(.156,.089),l(-.089,.111),l(-.022,.179),l(.111,.089),l(.09,.179),l(-.045,.224),l(-.201,.089),l(-.156,.067),l(-.357,.201),l(-.312,.044),l(.223,.246),l(.269,.089),l(.29,.044),l(-.134,.156),l(-.312,0),l(-.246,0),l(-.045,.179),l(-.044,.224),l(.156,.067),l(.179,.067),l(.044,.134),l(.045,.179),l(.09,.201),l(.066,.067),l(-.156,.491),l(-.156,.291),l(0,.156),l(-.335,.134),l(-.805,-.157),l(-.736,.045),l(-.269,0),l(-.022,.179),l(-.223,.179),l(-.38,.134),l(-.357,.022),l(-.224,.089),l(-.09,.514),l(0,.224),l(-.021,.112),l(-.012,.126),l(-.779,.104),l(-.971,.06),l(-.511,.405),l(-.729,.189),l(-1.135,.075),l(-1.119,.248),l(-.502,.318),l(-.463,.059),l(-.453,-.316),l(-.369,.621),l(-.31,.188),l(-.477,.044),l(-.438,-.057),l(-.959,.031),l(-.5,.16),l(.641,.287),l(1.957,1.004),l(.053,.172),l(-.093,.188),l(.163,.244),l(.562,.042),l(.511,-.13),l(.675,-.146),l(1.052,.013),l(.439,.114),l(-.235,.259),l(-.106,.245),l(-.228,.144),l(-.578,.116),l(-.31,.029),l(-.591,-.157),l(-.473,.044),l(-.71,.489),l(-1.007,.045),l(-.538,.188),l(-.527,.488),l(-.269,.101),l(-.786,-.07),l(-.588,-.171),l(.364,-.746),l(-.096,-.416),l(-.264,-.287),l(-.854,-.286),l(-.193,-.014),l(-.629,.016),l(-.151,.043),l(-.16,-.187),l(.887,-.505),l(.644,-.261),l(.772,-.188),l(.221,-.116),l(-.246,-.46),l(-.435,-.071),l(-.799,.044),l(-1.015,.045),l(-.698,-.1),l(-.195,-.101),l(-.418,-.432),l(.584,-.405),l(-.528,-.605),l(-.378,.361),l(-.541,.001),l(-1.001,.146),l(-.565,.131),l(-.694,.722),l(-1.003,.867),l(-.754,.203),l(-.223,.044),l(-.287,.504),l(.079,.158),l(.178,.093),l(-.706,-.131),l(-.665,.261),l(-.457,0),l(-.033,.189),l(-.609,-.047),l(-.398,-.166),l(-.119,-.249),l(-.15,.02),l(.055,-.077),l(.102,-.025),l(.126,.013),l(.113,.013),l(.189,0),l(.088,-.114),l(0,-.088),l(-.063,-.113),l(.025,-.113),l(.126,-.063),l(.051,-.063),l(.075,-.013),l(.089,-.025),l(.088,-.063),l(.089,-.088),l(.024,-.126),l(-.013,-.114),l(.14,-.013),l(.29,-.063),l(.075,-.076),l(-.025,-.088),l(-.062,-.088),l(.126,-.114),l(.037,-.063),l(-.012,-.088),l(-.114,-.113),l(.051,-.101),l(-.088,-.151),l(-.063,-.101),l(.202,-.151),l(.239,-.025),l(.126,-.088),l(.113,.025),l(.013,.088),l(-.013,.214),l(.063,.013),l(.113,0),V(0,96.92),l(-.013,-.063),l(.101,.038),l(.063,.051),l(.025,-.076),l(.075,-.038),l(.139,-.012),l(0,.075),l(.089,.063),l(.075,0),l(.126,.164),l(.076,-.076),l(.075,-.076),l(.013,-.05),l(.101,-.025),l(.177,0),l(-.037,.189),l(.176,.025),l(.038,-.038),l(.038,-.038),l(.139,.013),l(.227,0),l(.038,-.025),l(.075,-.076),l(-.126,-.013),l(-.164,-.126),l(-.101,-.051),l(-.075,-.05),l(.013,-.038),l(.101,-.063),l(-.025,-.113),l(.038,-.101),l(-.013,-.126),l(-.051,-.139),l(-.101,-.063),l(-.177,-.076),l(-.075,0),l(-.151,-.126),l(-.151,-.063),l(-.151,-.038),l(.051,-.151),l(.037,-.088),l(-.037,-.051),l(-.127,.038),l(-.062,-.114),l(.113,-.038),l(-.013,-.189),l(.089,-.075),l(-.025,-.101),l(-.038,-.088),l(-.113,0),l(-.102,.05),l(-.088,.051),l(-.113,-.088),l(-.089,-.101),l(-.188,-.101),l(-.139,-.025),l(-.102,-.139),l(-.05,-.139),l(.177,-.139),l(0,-.189),l(.024,-.114),l(.051,-.05),l(-.126,-.063),l(.164,-.151),l(-.113,-.025),l(-.076,-.063),l(-.062,-.126),l(-.14,-.013),l(-.062,.101),l(-.126,-.025),l(-.215,-.025),l(-.126,-.189),l(-.05,-.189),l(-.417,-.075),l(-.277,.012),l(-.062,.051),l(-.076,.101),l(-.062,-.05),l(0,-.076),l(-.089,-.025),l(-.101,.038),l(.038,-.05),l(.088,-.101),l(-.025,-.063),l(-.113,0),l(-.177,.038),l(-.126,-.025),l(-.101,.013),l(-.076,-.076),l(-.05,-.063),l(-.101,-.063),l(-.151,-.013),l(-.139,-.05),l(-.14,-.126),l(-.214,-.088),l(-.038,-.013),l(-.126,.025),l(-.05,.025),l(-.114,-.051),l(-.088,-.025),l(-.139,.025),l(-.177,.051),l(-.177,-.025),l(-.062,.038),l(-.126,.114),l(-.202,0),l(-.265,-.038),l(-.126,.051),l(-.315,-.114),l(-.088,.101),l(.012,.113),l(-.126,0),l(-.075,-.063),l(-.126,.114),l(-.06,.052),l(-.634,.08),l(-.151,.311),l(-.278,.178),l(-1.992,.191),l(-.186,.215),l(-.243,.119),l(-.339,.06),l(-.188,-.227),l(-.327,.004),l(-.025,-.231),l(-.363,.045),l(-1.115,-.066),l(-.958,-.193),l(-.241,.107),l(-.787,-.121),l(-.136,.085),l(-.678,-.387),l(-.554,-.2),l(-.668,-.301),l(-.166,.015),l(1.047,-1.471),l(.653,.018),l(-.349,-.383),l(-.044,-.552),l(.082,-.306),l(1.509,-1.218),l(.599,-.398),l(.286,-.181),l(.429,-.013),l(.255,-.24),l(.009,-.314),l(-.328,-.302),l(.085,-.133),l(.298,-.048),l(-.316,-.193),l(-.816,-.835),l(.074,-.242),l(-.161,-.175),
+N(660.044,89.132),l(-.295,.31),l(-.687,1.207),l(-1.224,1.959),l(-.381,.58),l(.269,.836),l(.051,.029),l(.342,-.045),l(.929,-.395),l(.754,-.062),l(.576,-.018),l(.317,.085),l(.431,.416),l(.292,.07),l(1.191,-.786),l(.438,-.002),l(.928,.212),l(.538,.199),l(.797,.5),l(.879,.99),l(.599,.501),l(.048,.273),l(-.107,.217),l(-.414,.218),l(-.464,-.127),l(-1.074,-.008),l(-.432,-.099),l(-.854,.033),l(-.937,.221),l(-.539,.146),l(-.831,.278),l(-.353,.189),l(-.483,-.127),l(-.464,.045),l(-.47,.204),l(-.363,.333),l(-.312,.82),l(-.241,.216),l(-.347,.188),l(-.638,.248),l(-.896,.134),l(-.624,-.054),l(-.438,-.012),l(-.224,-.013),l(-1.192,.91),l(-.742,.433),l(-.744,.047),l(-.982,.005),l(-.592,-.125),l(-.668,-.382),l(-.718,-.154),l(-.316,.073),l(-.457,.231),l(-.539,.589),l(-.214,.401),l(.003,.343),l(.389,.569),l(.599,.411),l(.188,.228),l(-.123,.271),l(-.326,.259),l(-1.265,.292),l(-.67,.389),l(-1.111,1.046),l(-.265,.172),l(-1.941,.737),l(-.651,.061),l(-.987,-.08),l(-1.514,.065),l(-1.339,.007),l(-1.204,.349),l(-.816,.289),l(-.736,.274),l(-.303,.101),l(-1.44,.534),l(-.686,.289),l(-.481,.017),l(-.433,-.197),l(-.253,-.297),l(-.61,-.067),l(-.663,.061),l(-.929,-.123),l(-1.599,-.433),l(-1.006,-.365),l(-.815,-.551),l(-.521,-.168),l(-1.69,-.119),l(-1.164,-.022),l(-.937,-.023),l(-2.861,.059),l(-1.165,-.022),l(-.802,-.109),l(-1.241,-.207),l(-1.979,-.018),l(-.444,-.254),l(-.467,-.439),l(-1.571,-2.161),l(-.105,-.542),l(-.744,-.096),l(-.839,-.31),l(-1.645,-.806),l(-.632,-.268),l(-.998,-.224),l(-.668,-.083),l(-.995,-.038),l(-1.505,-.021),l(-1.062,-.181),l(-.724,-.312),l(-.233,-.229),l(-.105,-.43),l(.035,-.129),l(.369,-.347),l(.214,-.389),l(.237,-.75),l(.215,-.447),l(-.401,-.66),l(-1.07,-1.451),l(-.568,-.618),l(-.354,-.143),l(-.633,-.144),l(-.731,-.167),l(-.614,-.069),l(-.834,-.415),l(-1.301,-.745),l(-.371,-.433),l(-.24,-.563),l(-.131,-.405),l(-.062,-.145),l(.154,-.044),l(.799,-.425),l(.599,-.207),l(1.387,-.08),l(.603,-.148),l(.727,-.381),l(.017,-.012),l(.971,-.692),l(.787,-.398),l(1.143,-.341),l(1.512,-.476),l(.84,-.18),l(.953,.097),l(.932,.156),l(1.842,.122),l(.831,.083),l(.694,.755),l(.393,.406),l(.699,.113),l(1.458,-.008),l(.719,.083),l(.85,-.004),l(.875,.068),l(.312,.114),l(.576,.186),l(.562,-.018),l(.755,-.28),l(.31,-.162),l(.744,-.572),l(.163,-.526),l(-.116,-.204),l(-.396,-.304),l(-.409,-.86),l(.098,-.293),l(.905,-.839),l(1.269,-.96),l(.84,.201),l(1.028,.098),l(1.036,.185),l(1.748,.328),l(.702,.231),l(.989,.317),l(.767,.143),l(.145,.204),l(.004,.541),l(.182,.481),l(.408,.451),l(.421,.333),l(1.643,.531),l(.673,.113),l(2.48,-.538),l(.796,-.077),l(1.172,.037),l(1.423,.022),l(.769,.229),l(1.333,.75),l(.623,.331),l(1.132,.313),l(.812,.373),l(1.318,.254),l(.905,.241),l(.984,.082),l(.739,.039),l(1.602,-.11),l(1.018,-.063),l(.532,-.075),l(.867,-.106),l(1.147,-.136),l(.526,-.163),l(.604,-.264),l(.447,-.394),l(.755,-.498),l(1.165,-.487),l(.333,-.002),l(.609,-.047),l(.74,.156),l(.751,.506),l(.34,.129),l(.86,.169),l(1.228,-.297),l(.622,-.018),l(.431,.168),
+N(406.183,86.551),l(1.051,-.494),l(.485,-.089),l(.574,.087),l(.465,-.016),l(.209,-.147),l(.477,.098),l(.407,.042),l(.52,-.034),l(-.025,-.157),l(.307,.012),l(.307,0),l(.267,-.182),l(.313,.242),l(.173,-.121),l(.228,.061),l(.292,.375),l(.535,-.109),l(.754,.375),l(-.11,.423),l(-.172,.097),l(.001,.338),l(.672,-.024),l(.344,.177),l(.282,.365),l(.038,.468),l(-.422,.376),l(-.225,-.072),l(-.142,.08),l(-.245,.147),l(-.213,.322),l(.017,.327),l(.31,.204),l(-.136,.348),l(-.079,-.114),l(-.694,.174),l(-.127,-.228),l(-.371,-.204),l(-.341,-.192),l(-.529,-.048),l(.039,-.228),l(-.146,-.18),l(.119,-.373),l(-.245,.072),l(-.193,.313),l(-.446,.035),l(-.406,.075),l(-.285,-.122),l(.072,-.198),l(-.091,-.175),l(.159,-.241),l(-.375,-.168),l(-.576,-.048),l(-.259,.012),l(-.159,-.301),l(-.518,.012),l(-.194,-.133),l(-.202,-.458),l(-.153,-.17),l(-.41,.208),l(-.141,.071),l(-.266,-.127),l(-.311,-.335),l(-.208,-.447),
+N(438.22,91.952),l(.039,-.044),l(.065,-.105),l(.014,-.131),l(.092,-.066),l(.146,-.119),l(.026,-.04),l(.171,-.053),l(.093,-.026),l(.092,.053),l(.132,.053),l(.158,0),l(.065,-.026),l(.093,0),l(.065,.026),l(.065,.026),l(.093,-.026),l(.145,-.04),l(.132,0),l(.118,-.053),l(.079,-.053),l(.066,-.026),l(.105,-.026),l(.039,0),l(.053,-.079),l(.04,-.092),l(.079,-.079),l(.092,.026),l(.105,-.04),l(.145,-.066),l(.053,-.105),l(.053,-.079),l(.026,-.132),l(.026,-.092),l(.053,-.092),l(.118,-.013),l(.105,-.013),l(.132,-.079),l(.119,-.053),l(.118,-.092),l(.053,-.079),l(.132,-.066),l(.065,-.04),L(442,89.998),l(.145,.013),l(.105,.026),l(.066,-.04),l(.065,-.066),l(.071,.012),l(.285,.041),l(.03,.228),l(.43,-.048),l(.183,-.24),l(.193,.016),l(.062,-.112),l(.261,-.024),l(.194,.24),l(.073,.169),l(.331,-.025),l(.066,.18),l(-.026,.083),l(.003,.204),l(.389,-.083),l(.18,.12),l(.149,-.135),l(.104,-.177),l(.558,-.204),l(.168,.056),l(.483,-.046),l(.46,.254),l(.373,-.18),l(.073,-.137),l(.508,.041),l(.561,-.076),l(.129,.13),l(.703,.186),l(.104,.216),l(.424,.101),l(.831,.33),l(-1.047,1.471),l(-.629,.076),l(-.437,-.143),l(-.534,-.359),l(-1.062,.035),l(-.717,.047),l(-1.024,.759),L(444.857,93),l(-.59,-.072),l(-.499,.061),l(-.761,.134),l(-.255,.001),l(-.334,.568),l(-1.651,-.036),l(-.414,-.027),l(-.617,-.17),l(-.399,-.172),l(-.245,.146),l(-.761,-.547),l(-.155,-.26),l(.097,-.581),l(-.053,-.093),
+N(442.391,98.111),l(-.589,.203),l(-.433,.031),l(-.668,.047),l(-.58,-.098),l(-1.116,-.671),l(-1.412,-.612),l(-.215,-.197),l(-.364,-.333),l(-.304,-.59),l(.346,-.299),l(.154,-.294),l(-.204,-.188),l(.04,-.375),l(.409,-.062),l(.157,-.206),l(-.136,-.196),l(-.452,-.063),l(.223,-.197),l(.325,0),l(.164,.134),l(.701,-.054),l(.019,-.367),l(.636,-.291),l(.245,-.146),l(.399,.172),l(.617,.17),l(.414,.027),l(1.651,.036),l(.334,-.568),l(.255,-.001),l(.761,-.134),l(.499,-.061),l(.59,.072),l(.427,-.063),l(1.024,-.759),l(.717,-.047),l(1.062,-.035),l(.534,.359),l(.437,.143),l(.629,-.076),l(.166,-.015),l(.668,.301),l(.554,.2),l(.678,.387),l(-.45,.338),l(-1.125,.267),l(-.581,.408),l(-.968,1.451),l(-.63,.84),l(-.753,.567),l(-.361,.16),l(-.724,.047),l(-.264,.103),l(-.176,-.002),l(-.907,-.067),l(-.889,.077),l(-1.535,.529),
+N(459.717,92.836),l(.06,-.052),l(.126,-.114),l(.075,.063),l(.126,0),l(-.012,-.113),l(.088,-.101),l(.315,.114),l(.126,-.051),l(.265,.038),l(.202,0),l(.126,-.114),l(.062,-.038),l(.177,.025),l(.177,-.051),l(.139,-.025),l(.088,.025),l(.114,.051),l(.05,-.025),l(.126,-.025),l(.038,.013),l(.214,.088),l(.14,.126),l(.139,.05),l(.151,.013),l(.101,.063),l(.05,.063),l(.076,.076),l(.101,-.013),l(.126,.025),l(.177,-.038),l(.113,0),l(.025,.063),l(-.088,.101),l(-.038,.05),l(.101,-.038),l(.089,.025),l(0,.076),l(.062,.05),l(.076,-.101),l(.062,-.051),l(.277,-.012),l(.417,.075),l(.05,.189),l(.126,.189),l(.215,.025),l(.126,.025),l(.062,-.101),l(.14,.013),l(.062,.126),l(.076,.063),l(.113,.025),l(-.164,.151),l(.126,.063),l(-.051,.05),l(-.024,.114),l(0,.189),l(-.177,.139),l(.05,.139),l(.102,.139),l(.139,.025),l(.188,.101),l(.089,.101),l(.113,.088),l(.088,-.051),l(.102,-.05),l(.113,0),l(.038,.088),l(.025,.101),l(-.089,.075),l(.013,.189),l(-.113,.038),l(.062,.114),l(.127,-.038),l(.037,.051),l(-.037,.088),l(-.051,.151),l(.151,.038),l(.151,.063),l(.151,.126),l(.075,0),l(.177,.076),l(.101,.063),l(.051,.139),l(.013,.126),l(-.038,.101),l(.025,.113),l(-.101,.063),l(-.013,.038),l(.075,.05),l(.101,.051),l(.164,.126),l(.126,.013),l(-.075,.076),l(-.038,.025),l(-.227,0),l(-.139,-.013),l(-.038,.038),l(-.038,.038),l(-.176,-.025),l(.037,-.189),l(-.177,0),l(-.101,.025),l(-.013,.05),l(-.075,.076),l(-.076,.076),l(-.126,-.164),l(-.075,0),l(-.089,-.063),l(0,-.075),l(-.139,.012),l(-.075,.038),l(-.025,.076),l(-.063,-.051),l(-.101,-.038),l(.013,.063),l(0,.088),l(-.113,0),l(-.063,-.013),l(.013,-.214),l(-.013,-.088),l(-.113,-.025),l(-.126,.088),l(-.239,.025),l(-.202,.151),l(.063,.101),l(.088,.151),l(-.051,.101),l(.114,.113),l(.012,.088),l(-.037,.063),l(-.126,.114),l(.062,.088),l(.025,.088),l(-.075,.076),l(-.29,.063),l(-.14,.013),l(.013,.114),l(-.024,.126),l(-.089,.088),l(-.088,.063),l(-.089,.025),l(-.075,.013),l(-.051,.063),l(-.126,.063),l(-.025,.113),l(.063,.113),l(0,.088),l(-.088,.114),l(-.189,0),l(-.113,-.013),l(-.126,-.013),l(-.102,.025),l(-.055,.077),l(-.03,.004),l(-.062,-.237),l(-.218,-.106),l(.16,-.071),l(-.021,-.267),l(-.104,-.561),l(.323,-.978),l(.027,-.404),l(-.353,-.856),l(-.604,-.286),l(-1.037,-1.119),L(460.567,93),l(-.626,-.191),l(-.225,.028),
+N(445.722,97.573),l(.176,.002),l(.264,-.103),l(.724,-.047),l(.361,-.16),l(.753,-.567),l(.63,-.84),l(.968,-1.451),l(.581,-.408),l(1.125,-.267),l(.45,-.338),l(.136,-.085),l(.787,.121),l(.241,-.107),l(.958,.193),l(1.115,.066),l(.363,-.045),l(.025,.231),l(.327,-.004),l(.188,.227),l(.339,-.06),l(.243,-.119),l(.186,-.215),l(1.992,-.191),l(.278,-.178),l(.151,-.311),l(.634,-.08),l(.225,-.028),L(460.567,93),l(.767,1.17),l(1.037,1.119),l(.604,.286),l(.353,.856),l(-.027,.404),l(-.323,.978),l(.104,.561),l(.021,.267),l(-.16,.071),l(.218,.106),l(.062,.237),l(.03,-.004),l(.15,-.02),l(.119,.249),l(.398,.166),l(.609,.047),l(.033,-.189),l(.457,0),l(.665,-.261),l(.706,.131),l(.149,.079),l(.062,.259),l(-.293,.446),l(-.27,.316),l(-.436,.044),l(-.382,.043),l(-.382,.245),l(-.515,.617),l(-.252,.645),l(-.096,.787),l(-.044,.223),l(-.671,-.12),l(-1.346,-.336),l(-.514,-.226),l(-.295,-.042),l(-.671,-.369),l(-.562,-.04),l(-.618,.218),l(-1.904,.771),l(-.38,.059),l(-1.385,-.35),l(-.3,-.013),l(-.69,.261),l(-.34,.031),l(-1.151,-.395),l(-.506,-.002),l(-.771,.189),l(-.266,.023),l(-.048,-.189),l(.234,-.318),l(-.352,-.106),l(-.392,-.204),l(-.418,-.186),l(-.146,-.33),l(.32,-.201),l(.351,.012),l(-.114,-.13),l(-.625,-.248),l(-.253,.13),l(-.215,.283),l(-.147,.118),l(-.414,-.239),l(-.194,-.139),l(-.594,-.059),l(-.02,-.189),l(-.234,0),l(-.245,-.036),l(-.052,-.165),l(.178,-.094),l(.271,-.071),l(-.239,-.083),l(-.183,-.059),l(.124,-.146),l(.19,-.127),l(-.069,-.142),l(-.306,-.118),l(-.555,-.141),l(-.712,-.471),l(.058,-.088),l(-.104,-.119),l(.075,-.356),l(-.202,-.036),l(-.19,-.237),l(-.569,-.178),l(-.054,-.309),
+N(420.177,113.472),l(-.274,-.042),l(-.253,-.155),l(-.367,-.325),l(-.096,-.213),l(.202,-.738),l(.097,-.681),l(-.046,-.583),l(-.133,-.569),l(-.503,-.44),l(-.094,-.271),l(.181,-.157),l(.366,-.015),l(.801,-.001),l(.339,-.172),l(.861,-.543),l(.633,.625),l(.451,.754),l(-.014,.271),l(-.204,.285),l(-.145,.484),l(.149,.894),l(-.11,.525),l(-.377,.695),l(-.405,-.198),l(-.52,.03),l(-.143,.1),l(-.149,.27),l(-.248,.17),M(433.783,118.446),l(-.712,-.084),l(-.902,-.607),l(-.772,-.239),l(-1.904,-.817),l(-.833,-.126),l(-.232,-.127),l(-.173,-.283),l(.139,-.34),l(.328,-.34),l(.264,-.1),l(.629,.112),l(.569,-.341),l(.68,.424),l(.403,.141),l(.722,-.016),l(1.403,-.187),l(1.38,-.329),l(.148,.085),l(.043,.127),l(-.112,.127),l(-.536,.823),l(-.153,.497),l(.009,.382),l(.411,.509),l(-.179,.128),l(-.43,.567),l(-.188,.015),M(431.244,98.829),l(-.281,-.329),l(-.242,-.027),l(-.281,.196),l(-.156,-.125),l(-.47,-.071),l(-.114,.32),l(-.458,.054),l(-1.001,.364),l(.078,-.151),l(-.452,.133),l(-.063,.249),l(-.157,.044),l(-.01,.125),l(.303,.08),l(.021,.302),l(.193,.119),l(.253,.236),l(-.104,.213),l(-.449,.254),l(.016,.272),l(.143,.554),l(.783,.814),l(2.008,.889),l(.29,.357),l(.134,.558),l(.274,.557),l(.395,.585),l(.694,.57),l(.254,.274),l(.446,.195),l(.041,.21),l(.408,.167),l(1.17,.255),l(1.254,-.105),l(.388,.141),l(.024,.212),l(-.465,.247),l(-.258,.294),l(.262,.213),l(.954,.283),l(1.168,.411),l(.829,.366),l(1.589,.739),l(.058,.185),l(.719,.458),l(.31,.475),l(-.198,.435),l(-.152,.337),l(-.455,-.281),l(-.318,-.167),l(-.109,-.486),l(-.263,-.17),l(-.512,-.099),l(-.483,-.009),l(-.439,-.236),l(.086,-.217),l(-.353,-.065),l(-.301,.098),l(-.232,.262),l(-.259,.399),l(-.273,.208),l(.043,.271),l(-.197,.303),l(-.007,.298),l(.76,.342),l(.611,.271),l(-.093,.314),l(.03,.432),l(.133,.142),l(-.191,.238),l(-.659,-.024),l(-.41,.219),l(-.202,.228),l(.11,.595),l(-.536,.303),l(-.617,.866),l(-.595,.048),l(-.167,-.071),l(-.184,-.14),l(-.002,-.508),l(.364,-.141),l(.317,-.542),l(-.236,-.184),l(.361,-.249),l(.361,.074),l(.133,-.17),l(-.077,-.34),l(-.211,-.181),l(-.206,-.924),l(-.367,-.516),l(-.15,-.607),l(-.201,-.352),l(-.334,.058),l(-.187,.171),l(-.899,-.496),l(-.286,-.065),l(.208,-.291),l(-.092,-.398),l(-.461,-.34),l(-.909,.247),l(.034,-.109),l(.322,-.194),l(-.276,-.27),l(-.29,-.003),l(-.42,.19),l(-.242,-.512),l(-.198,-.207),l(-.124,-.228),l(-.663,-.241),l(-.505,-.027),l(-.654,-.127),l(-.745,-.355),l(-.548,-.441),l(-.959,-.612),l(-1.036,-.826),l(-.872,-.384),l(-.805,-.67),l(-.566,-.856),l(-.434,-1.043),l(-.347,-.443),l(-.505,-.457),l(-.483,-.243),l(-1.188,-.341),l(-.579,-.142),l(-.5,.044),l(-1.078,.647),l(-.46,.359),l(-.646,.173),l(-.303,.043),l(.146,-.469),l(-.062,-.281),l(-.849,.07),l(-.754,-.391),l(-.193,-.442),l(.315,-.371),l(.175,-.01),l(-.135,-.331),l(-.616,-.191),l(-.352,-.358),l(.437,-.186),l(.183,.111),l(.541,-.353),l(.199,-.272),l(-.43,-.192),l(-.025,-.292),l(-.532,-.344),l(.624,-.301),l(.599,.062),l(.627,-.204),l(.629,.168),l(.275,-.16),l(.349,-.432),l(-.103,-.212),l(.777,-.404),l(.016,.415),l(.534,.363),l(.311,.071),l(-.098,.182),l(.385,.312),l(.285,-.151),l(.018,-.535),l(.425,-.384),l(-.019,-.333),l(.371,-.081),l(.143,.354),l(.23,.142),l(.216,-.03),l(.071,-.122),l(.469,-.05),l(.244,.333),l(.228,-.415),l(-.244,-.131),l(.081,-.273),l(.283,-.091),l(.176,.162),l(.315,.051),l(.038,-.192),l(-.112,-.212),l(.126,-.309),l(.631,.171),l(.597,.034),l(.329,-.411),l(.366,-.096),l(.183,.083),l(.445,-.11),l(.301,.103),l(.856,-.227),l(.023,.363),l(.318,.096),l(.32,.391),l(1.311,.247),l(.894,.082),l(.478,.112),l(.116,.199),l(-.614,.303),l(.098,.151),l(.297,.002),l(.187,.185),l(-.367,.285),l(.336,.089),l(-.127,.361),l(.36,.11),l(.284,.198),l(-.056,.214),
+N(430.73,96.731),l(1.04,.065),l(.179,.107),l(.612,-.009),l(.287,.152),l(.646,-.5),l(.566,-.107),l(.85,.08),l(.298,-.196),l(.89,.116),l(-.082,-.393),l(.693,-.157),l(.304,.59),l(.364,.333),l(-.035,-.009),l(-.1,-.073),l(-.145,-.036),l(-.172,0),l(-.145,.009),l(-.055,.063),l(0,.072),l(.019,.09),l(.009,.082),l(-.063,.009),l(-.136,-.009),l(-.108,-.036),l(-.091,.063),l(-.045,.082),l(-.081,.063),l(-.082,.045),l(-.081,.009),l(-.163,.036),l(-.117,.036),l(-.108,.036),l(-.055,.045),l(-.153,-.009),l(-.127,.072),l(-.063,.054),l(-.018,.082),l(.036,.072),l(.081,.054),l(.063,.055),l(.045,.045),l(.019,.063),l(.018,.09),l(-.036,.108),l(-.018,.063),l(-.046,.1),l(-.108,0),l(-.081,-.009),l(-.091,.027),l(-.108,.009),l(-.117,.054),l(-.091,.018),l(-.081,.027),l(-.1,.045),l(-.055,.063),l(-.036,.027),l(.055,.018),l(.063,.009),l(.026,.027),l(.037,.072),l(-.046,.063),l(-.027,.009),l(-.081,.027),l(-.009,.045),l(.045,.081),l(0,.072),l(.045,.1),l(-.054,.072),l(-.063,-.018),l(-.1,.045),l(-.117,.018),l(-.127,-.036),l(-.063,-.027),l(-.1,-.063),l(-.099,0),l(-.063,-.027),l(-.118,-.045),l(-.018,.045),l(-.027,.045),l(-.1,.027),l(-.136,0),l(-.054,-.045),l(-.072,-.063),l(-.127,-.018),l(-.019,-.09),l(-.026,-.018),l(-.063,-.054),l(-.055,-.027),l(-.018,-.054),l(-.01,-.054),l(-.036,-.009),l(-.063,.018),l(-.036,.054),l(-.009,.027),l(-.054,.063),l(-.019,.018),l(-.018,.081),l(-.063,.045),l(-.046,.018),l(-.062,.054),l(-.036,.009),l(-.254,0),l(-.108,-.027),l(-.108,.027),l(-.145,.009),l(-.1,-.009),l(-.1,-.036),l(-.045,-.019),l(-.055,0),l(0,.037),l(0,.036),l(-.045,.027),l(-.045,.018),l(-.136,-.009),l(-.027,-.036),l(-.108,.018),l(-.019,.018),l(-.136,.018),l(-.063,.018),l(-.126,.018),l(-.272,-.063),l(.428,-.077),l(.113,-.16),l(.056,-.214),l(-.284,-.198),l(-.36,-.11),l(.127,-.361),l(-.336,-.089),l(.367,-.285),l(-.187,-.185),l(-.297,-.002),l(-.098,-.151),l(.614,-.303),l(-.116,-.199),
+N(439.573,104.709),l(-1.051,-.672),l(-.185,-.222),l(-.783,-.149),l(-.203,-.159),l(-.403,-.115),l(-.683,.177),l(-.326,-.486),l(-1.112,-.627),l(-.584,-.678),l(.277,.007),l(.608,.016),l(-.583,-.221),l(-.659,-.469),l(-.183,-.407),l(.086,-.452),l(-.289,-.336),l(-.646,-.418),l(-.378,-.126),l(-.258,.579),l(-.142,.116),l(.03,.15),l(-.284,.106),l(-.154,.248),l(-.213,.053),l(-.496,-.647),l(-.063,-.286),l(-.259,-.612),l(.065,-.012),l(.272,.063),l(.126,-.018),l(.063,-.018),l(.136,-.018),l(.019,-.018),l(.108,-.018),l(.027,.036),l(.136,.009),l(.045,-.018),l(.045,-.027),l(0,-.036),l(0,-.037),l(.055,0),l(.045,.019),l(.1,.036),l(.1,.009),l(.145,-.009),l(.108,-.027),l(.108,.027),l(.254,0),l(.036,-.009),l(.062,-.054),l(.046,-.018),l(.063,-.045),l(.018,-.081),l(.019,-.018),l(.054,-.063),l(.009,-.027),l(.036,-.054),l(.063,-.018),l(.036,.009),l(.01,.054),l(.018,.054),l(.055,.027),l(.063,.054),l(.026,.018),l(.019,.09),l(.127,.018),l(.072,.063),l(.054,.045),l(.136,0),l(.1,-.027),l(.027,-.045),l(.018,-.045),l(.118,.045),l(.063,.027),l(.099,0),l(.1,.063),l(.063,.027),l(.127,.036),l(.117,-.018),l(.1,-.045),l(.063,.018),l(.054,-.072),l(-.045,-.1),l(0,-.072),l(-.045,-.081),l(.009,-.045),l(.081,-.027),l(.027,-.009),l(.046,-.063),l(-.037,-.072),l(-.026,-.027),l(-.063,-.009),l(-.055,-.018),l(.036,-.027),l(.055,-.063),l(.1,-.045),l(.081,-.027),l(.091,-.018),l(.117,-.054),l(.108,-.009),l(.091,-.027),l(.081,.009),l(.108,0),l(.046,-.1),l(.018,-.063),l(.036,-.108),l(-.018,-.09),l(-.019,-.063),l(-.045,-.045),l(-.063,-.055),l(-.081,-.054),l(-.036,-.072),l(.018,-.082),l(.063,-.054),l(.127,-.072),l(.153,.009),l(.055,-.045),l(.108,-.036),l(.117,-.036),l(.163,-.036),l(.081,-.009),l(.082,-.045),l(.081,-.063),l(.045,-.082),l(.091,-.063),l(.108,.036),l(.136,.009),l(.063,-.009),l(-.009,-.082),l(-.019,-.09),l(0,-.072),l(.055,-.063),l(.145,-.009),l(.172,0),l(.145,.036),l(.1,.073),l(.035,.009),l(.215,.197),l(1.412,.612),l(1.116,.671),l(.58,.098),l(.668,-.047),l(.433,-.031),l(.589,-.203),l(.201,.142),l(.056,.089),l(.022,.112),l(-.022,.078),l(.045,.044),l(.011,.067),l(-.078,.056),l(-.011,.146),l(.078,.067),l(.145,-.034),l(.101,.034),l(.045,.089),l(-.078,.011),l(-.056,-.022),l(-.022,.078),l(.033,.1),l(-.045,.034),l(-.044,.022),l(.066,.111),l(.168,-.022),l(.033,.078),l(.123,.1),l(.122,0),l(.101,0),l(.09,.078),l(.122,.011),l(.134,0),l(.012,.078),l(-.033,.056),l(-.135,-.011),l(-.089,-.034),l(-.067,.022),l(-.078,-.011),l(-.066,-.045),l(-.056,-.011),l(-.045,.011),l(.033,.067),l(-.101,.089),l(-.078,0),l(0,.156),l(.045,.067),l(-.033,.078),l(.022,.078),l(.011,.078),l(-.089,.033),l(-.09,-.033),l(-.056,.067),l(.078,.089),l(-.078,.011),l(-.189,.022),l(-.201,-.022),l(-.145,-.123),l(.056,-.101),l(-.045,-.089),l(-.123,-.011),l(-.022,-.112),l(-.145,-.056),l(-.146,-.045),l(-.101,.089),l(-.1,-.011),l(-.156,-.078),l(-.067,-.022),l(-.146,0),l(-.156,-.045),l(-.111,.067),l(-.134,.045),l(-.134,-.045),l(-.111,-.067),l(-.112,0),l(-.122,.089),l(-.168,.078),l(-.156,-.067),l(-.268,-.089),l(-.179,.011),l(-.156,.011),l(-.189,-.056),l(-.168,-.011),l(-.156,-.089),l(-.089,.078),l(-.111,.022),l(-.057,-.056),l(-.234,-.078),l(-.156,-.056),l(-.134,-.045),l(-.089,-.011),l(-.134,.123),l(-.112,-.011),l(-.223,-.022),l(-.168,-.033),l(-.212,.022),l(-.101,.111),l(-.145,.145),l(-.123,.201),l(-.201,-.022),l(-.256,-.134),l(-.156,-.19),l(-.101,-.111),l(-.312,-.034),l(-.123,.044),l(-.089,.179),l(-.045,.167),l(.045,.134),l(0,.078),l(.033,.212),l(-.123,.067),l(.022,.089),l(.134,.078),l(.09,.089),l(.122,.034),l(.101,.033),l(.179,.179),l(.146,.234),l(.089,.134),l(.022,.123),l(.156,.111),l(-.078,.056),l(-.012,.1),l(.022,.146),l(.168,-.011),l(.089,.111),l(.056,.123),l(.112,.111),l(.167,.045),l(.167,.033),l(.369,.357),l(.021,.167),l(.078,.044),l(.213,.078),l(.379,.357),l(.224,.123),l(.223,.067),l(.101,.056),l(0,.112),l(.078,.279),l(.201,.078),l(.189,.167),l(.146,.112),l(.245,.123),l(.067,.212),l(-.284,.083),M(439.792,104.833),l(.132,-.118),l(.134,.011),l(.123,.034),l(.045,.078),l(.066,.089),l(.146,.089),l(.179,.078),l(.212,.011),l(.312,.257),l(.045,.067),l(.134,-.033),l(.123,.022),l(.089,.034),l(.062,.063),l(.005,.004),l(-.022,.089),l(.033,.078),l(.082,.072),l(.029,.092),l(-.002,.1),l(-.589,-.367),l(-.549,-.371),l(-.789,-.378),
+N(451.009,101.725),l(-.328,.346),l(-.383,.374),l(-.18,.302),l(.056,.271),l(1.326,1.122),l(.028,.2),l(-.302,.302),l(-.762,.333),l(-.246,.301),l(-.008,.514),l(-.013,.208),l(-.058,-.017),l(-.072,.029),l(-.16,.022),l(-.145,.021),l(-.116,.022),l(-.058,.015),l(-.102,-.051),l(-.087,.043),l(-.088,.021),l(-.102,-.043),l(-.064,-.021),l(-.131,.116),l(-.087,.08),l(-.152,-.015),l(-.196,-.007),l(-.064,.007),l(-.175,-.043),l(-.152,.087),l(-.151,.102),l(-.109,.058),l(.059,.072),l(-.029,.058),l(-.116,0),l(-.094,-.109),l(-.131,-.058),l(-.087,-.073),l(-.08,.065),l(-.116,.058),l(-.246,.058),l(-.225,.058),l(-.088,.058),l(-.058,.167),l(.029,.13),l(-.029,.072),l(-.072,.087),l(-.188,0),l(-.14,-.049),l(-.018,-.109),l(-.733,-.866),l(-.382,-.369),l(-.058,-.004),l(.109,-.286),l(0,-.067),l(-.078,-.067),l(-.101,0),l(-.056,-.056),l(.022,-.089),l(.111,-.033),l(.146,.011),l(.167,.033),l(.057,-.033),l(.021,-.067),l(.09,-.044),l(.134,-.022),l(.089,-.011),l(-.011,-.089),l(-.101,-.101),l(-.167,-.067),l(-.134,-.045),l(-.057,-.044),l(-.111,.022),l(-.078,-.045),l(-.033,-.067),l(-.123,-.101),l(-.078,-.1),l(-.066,-.022),l(-.067,.044),l(-.078,-.011),l(-.101,-.056),l(-.279,-.078),l(-.078,-.022),l(-.056,-.033),l(-.167,-.134),l(-.101,-.146),l(-.111,-.111),l(-.168,-.078),l(-.156,-.101),l(-.223,-.056),l(0,-.101),l(.179,-.101),l(.089,-.111),l(.078,-.011),l(.067,.034),l(.078,.044),l(.1,.022),l(.045,-.022),l(.012,-.134),l(.011,-.19),l(-.134,-.145),l(-.179,-.19),l(-.212,-.134),l(-.101,-.145),l(.101,.022),l(.101,.011),l(.145,.056),l(.224,.044),l(.134,-.078),l(.089,-.056),l(.067,-.078),l(-.089,-.044),l(-.135,-.022),l(-.089,-.089),l(-.123,-.078),l(-.156,-.089),l(-.033,-.101),l(-.045,-.1),l(-.212,.011),l(-.167,-.056),l(-.078,-.1),l(-.022,-.134),l(.078,-.067),l(0,-.089),l(-.033,-.1),l(.056,-.056),l(.066,-.078),l(.156,-.156),l(.156,-.223),l(.034,-.167),l(.056,-.1),l(-.022,-.067),l(-.123,-.022),l(-.179,-.011),l(-.156,0),l(-.212,.112),l(-.078,-.089),l(.056,-.067),l(.09,.033),l(.089,-.033),l(-.011,-.078),l(-.022,-.078),l(.033,-.078),l(-.045,-.067),l(0,-.156),l(.078,0),l(.101,-.089),l(-.033,-.067),l(.045,-.011),l(.056,.011),l(.066,.045),l(.078,.011),l(.067,-.022),l(.089,.034),l(.135,.011),l(.033,-.056),l(-.012,-.078),l(-.134,0),l(-.122,-.011),l(-.09,-.078),l(-.101,0),l(-.122,0),l(-.123,-.1),l(-.033,-.078),l(-.168,.022),l(-.066,-.111),l(.044,-.022),l(.045,-.034),l(-.033,-.1),l(.022,-.078),l(.056,.022),l(.078,-.011),l(-.045,-.089),l(-.101,-.034),l(-.145,.034),l(-.078,-.067),l(.011,-.146),l(.078,-.056),l(-.011,-.067),l(-.045,-.044),l(.022,-.078),l(-.022,-.112),l(-.056,-.089),l(-.201,-.142),l(1.535,-.529),l(.889,-.077),l(.907,.067),l(.054,.309),l(.569,.178),l(.19,.237),l(.202,.036),l(-.075,.356),l(.104,.119),l(-.058,.088),l(.712,.471),l(.555,.141),l(.306,.118),l(.069,.142),l(-.19,.127),l(-.124,.146),l(.183,.059),l(.239,.083),l(-.271,.071),l(-.178,.094),l(.052,.165),l(.245,.036),l(.234,0),l(.02,.189),l(.594,.059),l(.194,.139),l(.414,.239),l(.147,-.118),l(.215,-.283),l(.253,-.13),l(.625,.248),l(.114,.13),l(-.351,-.012),l(-.32,.201),l(.146,.33),l(.418,.186),
+N(551.198,117.997),l(-.351,-.48),l(-.236,-.126),l(-1.217,-.05),l(-.646,-.011),l(-.096,-.016),l(.091,-.726),l(-.062,-.503),l(.157,-.251),l(.062,-.22),l(-.503,-.094),l(-.534,-.283),l(-.566,-.189),l(-.471,.063),l(-.378,-.251),l(-1.132,-.597),l(-.565,-.22),l(-.943,-.597),l(-.314,.063),l(-1.006,-.503),l(-.377,-.44),l(-1.194,-.597),l(-1.384,-.975),l(0,-.283),l(-.188,-.44),l(-.283,-.188),l(-.408,-.597),l(-.126,-.566),l(-.22,-.377),l(-.881,-.251),l(-.188,.157),l(-.439,.063),l(-.535,-.126),l(-.439,.032),l(-.503,.094),l(-.314,-.157),l(-.691,-.314),l(.094,-.22),l(.157,-.188),l(-.188,-.22),l(.031,-.188),l(.188,-.157),l(-.439,-.283),l(0,-.22),l(-.032,-.22),l(-.251,-.22),l(-.534,-.094),l(-.692,-.095),l(-.22,-.314),l(-.346,-.032),l(-.629,-.377),l(-.472,-.095),l(-.188,.063),l(-.565,.157),l(.251,.251),l(.188,.377),l(-.597,-.283),l(-.283,0),l(-.126,.126),l(-.22,.346),l(-.283,.126),l(-.629,0),l(-.503,.251),l(-.503,.409),l(-.062,.628),l(.314,.409),l(-.126,.314),l(-1.383,.032),l(-1.03,-.063),l(.056,-8.174),l(5.658,-1.289),l(5.722,2.986),l(2.012,1.666),l(2.578,-.346),l(2.767,.188),l(1.1,-.409),l(.724,.723),l(.597,.22),l(.66,1.006),l(.66,-.314),l(-.031,1.038),l(-.188,.409),l(.031,.754),l(1.006,0),l(.221,.817),l(.346,1.069),l(.503,.063),l(.691,-.032),l(1.006,-.094),l(.346,0),l(.44,.314),l(.062,.283),l(-.062,.283),l(.44,.346),l(.66,0),l(.125,-.188),l(-.157,-.409),l(.504,-.44),l(.439,-.188),l(.221,-.472),l(.282,-.188),l(.943,-.377),l(.755,-.189),l(.534,-.471),l(.346,-.283),l(.22,-.063),l(.283,.126),l(.377,-.377),l(.322,-.031),l(.349,-.126),l(.441,.246),l(-.368,.172),l(-.368,.171),l(-.221,.049),l(-.073,.196),l(-.295,.049),l(-.294,.172),l(-.196,.147),l(-.441,.295),l(-.172,.098),l(-.024,.123),l(.294,.049),l(.295,.074),l(.146,.123),l(.418,-.147),l(.098,.221),l(.172,.221),l(.368,.27),l(.589,0),l(.393,0),l(.049,-.393),l(.221,.049),l(.196,-.196),l(.024,-.245),l(.196,.098),l(.196,.172),l(.172,.294),l(.049,.147),l(.393,.024),l(.147,-.024),l(.073,.246),l(.025,.098),l(.343,-.025),l(.319,.147),l(.245,.196),l(.516,.074),l(.466,.024),l(.172,.123),l(-.49,.221),l(-.197,.147),l(-.221,.147),l(-.49,-.024),l(-.245,-.049),l(.049,.171),l(0,.147),l(-.319,0),l(-.172,.049),l(-.343,.196),l(-.221,.196),l(-.271,.049),l(-.221,.196),l(-.245,-.147),l(-.319,-.098),l(-.294,-.098),l(-.221,.025),l(-.246,.073),l(-.318,-.073),l(-.042,.098),l(-.345,-.005),l(-.409,.031),l(-.188,-.283),l(-.251,-.063),l(-.126,-.188),l(.251,-.126),l(.409,-.346),l(.188,-.22),l(-.252,-.251),l(-.439,-.377),l(-.221,.251),l(-.471,.346),l(-.692,.188),l(-.22,.157),l(-.252,-.22),l(-.22,-.157),l(-.346,0),l(.031,.22),l(-.283,.314),l(.189,.314),l(-.032,.346),l(-.062,.126),l(-.472,-.095),l(-.565,.095),l(-.503,.094),l(.251,.125),l(.534,-.031),l(.126,.094),l(-.251,.063),l(-.188,.063),l(-.032,.346),l(-.188,0),l(-.251,.157),l(-.063,.409),l(-.282,.188),l(-1.069,-.094),l(-.629,-.126),l(-.472,.283),l(-.125,.471),l(.251,.283),l(.346,.188),l(.157,.157),l(.44,.032),l(.346,0),l(.126,.22),l(-.126,.22),l(-.031,.472),l(.126,.409),l(.471,.314),l(.126,.283),l(-.157,.22),l(-.503,.346),l(-.283,.503),l(-.377,.377),l(.063,.377),l(-.375,.843),
+N(439.792,104.833),l(-.113,-.054),l(-.105,-.07),l(.284,-.083),l(-.067,-.212),l(-.245,-.123),l(-.146,-.112),l(-.189,-.167),l(-.201,-.078),l(-.078,-.279),l(0,-.112),l(-.101,-.056),l(-.223,-.067),l(-.224,-.123),l(-.379,-.357),l(-.213,-.078),l(-.078,-.044),l(-.021,-.167),l(-.369,-.357),l(-.167,-.033),l(-.167,-.045),l(-.112,-.111),l(-.056,-.123),l(-.089,-.111),l(-.168,.011),l(-.022,-.146),l(.012,-.1),l(.078,-.056),l(-.156,-.111),l(-.022,-.123),l(-.089,-.134),l(-.146,-.234),l(-.179,-.179),l(-.101,-.033),l(-.122,-.034),l(-.09,-.089),l(-.134,-.078),l(-.022,-.089),l(.123,-.067),l(-.033,-.212),l(0,-.078),l(-.045,-.134),l(.045,-.167),l(.089,-.179),l(.123,-.044),l(.312,.034),l(.101,.111),l(.156,.19),l(.256,.134),l(.201,.022),l(.123,-.201),l(.145,-.145),l(.101,-.111),l(.212,-.022),l(.168,.033),l(.223,.022),l(.112,.011),l(.134,-.123),l(.089,.011),l(.134,.045),l(.156,.056),l(.234,.078),l(.057,.056),l(.111,-.022),l(.089,-.078),l(.156,.089),l(.168,.011),l(.189,.056),l(.156,-.011),l(.179,-.011),l(.268,.089),l(.156,.067),l(.168,-.078),l(.122,-.089),l(.112,0),l(.111,.067),l(.134,.045),l(.134,-.045),l(.111,-.067),l(.156,.045),l(.146,0),l(.067,.022),l(.156,.078),l(.1,.011),l(.101,-.089),l(.146,.045),l(.145,.056),l(.022,.112),l(.123,.011),l(.045,.089),l(-.056,.101),l(.145,.123),l(.201,.022),l(.189,-.022),l(.078,-.011),l(.212,-.112),l(.156,0),l(.179,.011),l(.123,.022),l(.022,.067),l(-.056,.1),l(-.034,.167),l(-.156,.223),l(-.156,.156),l(-.066,.078),l(-.056,.056),l(.033,.1),l(0,.089),l(-.078,.067),l(.022,.134),l(.078,.1),l(.167,.056),l(.212,-.011),l(.045,.1),l(.033,.101),l(.156,.089),l(.123,.078),l(.089,.089),l(.135,.022),l(.089,.044),l(-.067,.078),l(-.089,.056),l(-.134,.078),l(-.224,-.044),l(-.145,-.056),l(-.101,-.011),l(-.101,-.022),l(.101,.145),l(.212,.134),l(.179,.19),l(.134,.145),l(-.011,.19),l(-.012,.134),l(-.045,.022),l(-.1,-.022),l(-.078,-.044),l(-.067,-.034),l(-.078,.011),l(-.089,.111),l(-.179,.101),l(-.056,-.033),l(-.156,.056),l(-.112,-.022),l(-.066,-.044),l(-.112,.033),l(-.078,.056),l(.012,.078),l(.089,.1),l(.123,.167),l(.056,.101),l(-.056,.101),l(-.111,0),l(-.09,-.056),l(-.056,-.089),l(-.056,-.044),l(-.123,-.011),l(-.122,.056),l(-.168,.078),l(-.045,.101),l(-.044,.089),l(-.112,.101),l(.034,.089),l(.011,.1),L(442,104.458),l(-.134,.011),l(-.111,.022),l(-.101,.089),l(-.012,.134),l(.012,.112),l(.011,.145),l(.012,.044),l(.066,.112),l(.078,.089),l(.045,.101),l(-.09,.089),l(-.183,.108),l(-.062,-.063),l(-.089,-.034),l(-.123,-.022),l(-.134,.033),l(-.045,-.067),l(-.312,-.257),l(-.212,-.011),l(-.179,-.078),l(-.146,-.089),l(-.066,-.089),l(-.045,-.078),l(-.123,-.034),l(-.134,-.011),l(-.132,.118),
+N(450.198,105.998),l(.013,-.208),l(.008,-.514),l(.246,-.301),l(.762,-.333),l(.302,-.302),l(-.028,-.2),l(-1.326,-1.122),l(-.056,-.271),l(.18,-.302),l(.383,-.374),l(.328,-.346),l(.392,.204),l(.352,.106),l(-.234,.318),l(.048,.189),l(.266,-.023),l(.771,-.189),l(.506,.002),l(1.151,.395),l(.34,-.031),l(.69,-.261),l(.3,.013),l(1.385,.35),l(.38,-.059),l(1.904,-.771),l(.618,-.218),l(.562,.04),l(.671,.369),l(.295,.042),l(.514,.226),l(1.346,.336),l(.671,.12),l(-.066,.335),l(-.077,.258),l(-.261,.086),l(-.313,-.028),l(-.339,.129),l(-.327,.73),l(-.039,.586),l(-.075,.143),l(-.404,.115),l(-.338,.372),l(-.017,.257),l(.252,-.036),l(.255,.224),l(.033,.154),l(.391,.375),l(.01,.223),l(-1.333,-.005),l(-.527,-.111),l(-.497,.045),l(-.629,.374),l(-.498,.445),l(-.363,-.026),l(-.344,.216),l(.097,.327),l(-.086,.257),l(-1.117,.277),l(-.388,.031),l(-.619,-.21),l(-1.473,-.505),l(-.584,.06),l(-.799,.261),l(-1.855,.195),l(-.09,.029),l(-.047,-.199),l(.104,-.3),l(.006,-.499),l(-.225,-.469),l(-.358,-.383),l(-.666,-.296),l(-.134,-.213),l(.007,-.106),
+N(381.009,107),l(-.121,-.278),l(.138,-.4),l(.343,-.5),l(-.358,-.471),l(-.304,-.428),l(-.514,-.07),l(-.164,-.1),l(-.053,-.329),l(.163,-.243),l(.409,-.272),l(.365,-.101),l(.563,-.03),l(.634,-.03),l(.133,-.172),l(.068,-.415),l(.535,-.273),l(.763,.042),l(1.078,.37),l(.763,.07),l(.756,-.087),l(.577,-.173),l(.508,-.144),l(.354,-.001),l(.629,.285),l(.694,.156),l(.939,.084),l(1.538,.04),l(.583,.027),l(.957,.141),l(.491,-.158),l(.419,-.229),l(.531,.027),l(.891,.47),l(.67,-.016),l(.335,.062),l(.472,.243),l(.469,-.03),l(.058,.122),l(-.205,.243),l(.094,.106),l(.15,.03),l(.112,-.106),l(1.088,.334),l(.15,-.061),l(.507,.395),l(.056,-.076),l(.262,.03),l(.131,-.076),l(.431,.152),l(.028,.038),l(.084,.114),l(.767,-.03),l(.037,.122),l(.337,-.061),l(.542,.015),l(-.017,-.319),l(.355,0),l(1.252,.304),l(.091,.213),l(.035,.289),l(.187,.076),l(.374,-.076),l(.206,-.03),l(.335,.091),l(.036,.152),l(.261,.015),l(.395,-.167),l(.427,.197),l(.485,.015),l(.039,-.136),l(.75,-.137),l(.334,.091),l(-.001,.088),l(-.001,.463),l(.156,.1),l(-.062,.485),l(-1.112,.528),l(-.95,.385),l(-.267,.328),l(-1.046,.198),l(-.664,.116),l(-.96,.301),l(-.323,.326),l(-.053,.2),l(.261,.128),l(-.088,.157),l(-.628,.143),l(-.594,.783),l(-.886,.787),l(-.096,.192),l(-.18,.361),l(-.245,.45),l(.353,.827),l(.072,.111),l(.084,.13),l(.648,.295),l(.103,.185),l(-.621,.327),l(-.215,.105),l(-.515,.252),l(-.286,.479),l(-.224,.085),l(-.461,.926),l(.155,.322),l(-.257,.099),l(-.992,.049),l(-.581,.242),l(-.425,.327),l(-.274,.757),l(-.663,.496),l(-.258,-.213),l(-.599,.028),l(-.305,.27),l(-.342,0),l(-.121,-.113),l(-3.282,.042),l(-.69,.524),l(-1.021,.17),l(-.35,.382),l(-.028,.283),l(-.083,.085),l(-.073,-.212),l(-.068,-.014),l(.005,.241),l(-.389,.127),l(-.421,-.142),l(-.788,-.467),l(-.224,-.382),l(.036,-.262),l(-.345,-.113),l(-.125,-.213),l(.175,-.163),l(-.468,-.51),l(-.702,-.284),L(385,117.498),l(-.484,-.135),l(-.586,.039),l(.008,-.018),l(.304,-.951),l(.242,-.37),l(.884,-.643),l(-.408,-.31),l(-.812,-.123),l(.17,-.455),l(.506,-.655),l(.347,-.371),l(-.163,-.198),l(-.455,-.551),l(-.488,-.494),l(.288,-.129),l(.482,-.045),l(.458,-.229),l(.043,-.199),l(-.057,-.938),l(.132,-.983),l(-.072,-.456),l(.051,-.442),l(.084,-.072),l(1.234,-.506),l(.288,-.216),l(-.062,-.242),l(-.842,-.495),l(-.15,-.242),l(-.272,-.227),l(-.335,-.055),l(-.531,.26),L(382.981,107),l(-.531,-.439),l(-.55,.188),L(381.009,107),
+N(489.685,103.693),l(.112,-.309),l(.26,-.166),l(.284,.047),l(.07,.047),l(.402,.023),l(.449,.023),l(.283,.095),l(.284,.142),l(.188,.094),l(.189,.047),l(.331,0),l(.213,0),l(.212,.166),l(.261,.095),l(.307,.071),l(.355,.047),l(.307,0),l(.426,-.095),l(.544,0),l(.401,.166),l(.189,0),l(.283,-.047),l(.354,.166),l(.095,.142),l(.284,.213),l(.52,.118),l(.354,.071),l(.236,.118),l(.308,.119),l(-.142,.118),l(-.048,.118),l(.261,.118),l(.212,.071),l(.261,-.118),l(.283,0),l(.166,-.166),l(.094,-.095),l(.213,-.071),l(.354,0),l(.261,.071),l(.188,.142),l(.142,-.166),l(.095,-.071),l(.118,0),l(.236,.118),l(.143,.094),l(.212,0),l(.189,.118),l(.213,.166),l(.378,0),l(.354,.024),l(.118,.142),l(-.118,.189),l(-.118,.307),l(.354,.284),l(.284,.166),l(.26,.094),l(.284,.047),l(.236,-.023),l(.236,.071),l(.126,.189),l(-.268,.189),l(-.143,.142),l(-.095,.071),l(.143,.26),l(.213,.307),l(.614,.166),l(.118,.213),l(-.095,.331),l(-.236,.095),l(-.236,.047),l(-.26,-.189),l(-.143,-.071),l(-.188,-.023),l(-.284,.047),l(-.638,-.189),l(-.189,-.213),l(-.331,-.189),l(-.473,-.024),l(-.236,0),l(-.418,.308),l(-.291,.094),l(-.378,.047),l(-.591,.095),l(-.592,-.047),l(-.401,.118),l(-.426,.023),l(-.308,.095),l(-.307,-.024),l(-.377,.108),l(-.031,-.028),l(-1.326,-1.018),l(-.41,-.041),l(-.761,.36),l(-.226,.072),l(-.491,-.068),l(-1.212,-.082),l(.083,-.065),l(.322,-.585),l(.032,-.143),l(-.064,-.728),l(-.331,-1.084),l(-.206,-.399),l(-.639,-.513),l(-.341,-.128),l(-.916,-.155),l(-.679,-.271),l(-.341,-.243),
+N(443.617,107.095),l(-.065,-.035),l(-.435,-.156),l(-.017,-.15),l(-.501,-.485),l(-.848,-.3),l(-.033,-.021),l(.002,-.1),l(-.029,-.092),l(-.082,-.072),l(-.033,-.078),l(.022,-.089),l(-.005,-.004),l(.183,-.108),l(.09,-.089),l(-.045,-.101),l(-.078,-.089),l(-.066,-.112),l(-.012,-.044),l(-.011,-.145),l(-.012,-.112),l(.012,-.134),l(.101,-.089),l(.111,-.022),l(.134,-.011),l(.056,-.056),l(-.011,-.1),l(-.034,-.089),l(.112,-.101),l(.044,-.089),l(.045,-.101),l(.168,-.078),l(.122,-.056),l(.123,.011),l(.056,.044),l(.056,.089),l(.09,.056),l(.111,0),l(.056,-.101),l(-.056,-.101),l(-.123,-.167),l(-.089,-.1),l(-.012,-.078),l(.078,-.056),l(.112,-.033),l(.066,.044),l(.112,.022),l(.156,-.056),l(.056,.033),l(0,.101),l(.223,.056),l(.156,.101),l(.168,.078),l(.111,.111),l(.101,.146),l(.167,.134),l(.056,.033),l(.078,.022),l(.279,.078),l(.101,.056),l(.078,.011),l(.067,-.044),l(.066,.022),l(.078,.1),l(.123,.101),l(.033,.067),l(.078,.045),l(.111,-.022),l(.057,.044),l(.134,.045),l(.167,.067),l(.101,.101),l(.011,.089),l(-.089,.011),l(-.134,.022),l(-.09,.044),l(-.021,.067),l(-.057,.033),l(-.167,-.033),l(-.146,-.011),l(-.111,.033),l(-.022,.089),l(.056,.056),l(.101,0),l(.078,.067),l(0,.067),l(-.109,.286),l(-.361,-.022),l(-.727,-.11),l(-.273,.273),l(-.279,.515),l(.133,.427),l(-.002,.342),
+N(558.52,110.652),l(.042,-.098),l(.318,.073),l(.246,-.073),l(.221,-.025),l(.294,.098),l(.319,.098),l(.245,.147),l(.221,-.196),l(.271,-.049),l(.221,-.196),l(.343,-.196),l(.172,-.049),l(.319,0),l(0,-.147),l(-.049,-.171),l(.245,.049),l(.49,.024),l(.221,-.147),l(.197,-.147),l(.49,-.221),l(-.172,-.123),l(-.466,-.024),l(-.516,-.074),l(-.245,-.196),l(-.319,-.147),l(-.343,.025),l(-.025,-.098),l(-.073,-.246),l(-.147,.024),l(-.393,-.024),l(-.049,-.147),l(-.172,-.294),l(-.196,-.172),l(-.196,-.098),l(-.024,.245),l(-.196,.196),l(-.221,-.049),l(-.049,.393),l(-.393,0),l(-.589,0),l(-.368,-.27),l(-.172,-.221),l(-.098,-.221),l(-.418,.147),l(-.146,-.123),l(-.295,-.074),l(-.294,-.049),l(.024,-.123),l(.172,-.098),l(.441,-.295),l(.196,-.147),l(.294,-.172),l(.295,-.049),l(.073,-.196),l(.221,-.049),l(.368,-.171),l(.368,-.172),l(-.441,-.246),l(-.349,.126),l(-.044,-.273),l(.393,-.442),l(.318,-.368),l(.736,-.123),l(.663,-.098),l(.883,.147),l(.883,.245),l(.688,.196),l(.81,.123),l(.344,.123),l(-.024,-.442),l(.245,-.736),l(.466,-.368),l(.688,-.123),l(.589,.074),l(.761,.27),l(.735,.246),l(.908,.196),l(.54,.098),l(.441,-.27),l(.858,-.024),l(.761,0),l(.785,-.147),l(.712,.221),l(.662,.098),l(1.35,.024),l(.662,-.074),l(.981,.246),l(.564,-.049),l(.147,.344),l(.27,.147),l(.196,.27),l(.663,0),l(.466,.098),l(.41,.375),l(.031,.194),l(-.051,.157),l(-.325,.187),l(-.97,.219),l(-1.338,.349),l(-.445,.145),l(-.405,.301),l(-.638,.701),l(-.646,.345),l(-.478,.102),l(-.459,.017),l(-1.248,-.235),l(-.238,.03),l(-.467,.472),l(-.463,.784),l(-.268,.243),l(-.885,.132),l(-.507,.145),l(-.344,-.055),l(-.183,-.567),l(-.06,-.071),l(-.359,.03),l(-1.737,.734),l(-1.422,.704),l(-.274,.186),l(-.129,.213),l(-.139,.739),l(-.196,-.073),l(-.344,.098),l(-.344,.171),l(-.539,0),l(-.663,-.073),l(-.834,.221),l(-.172,.147),l(-.196,0),l(-.172,-.319),l(-.368,.024),l(-.318,.172),l(-.074,-.221),l(-.049,-.172),l(-.122,.024),l(-.319,-.123),l(-.049,-.147),l(-.221,-.024),l(-.442,.123),l(-.343,.049),l(.024,.221),l(-.295,.049),l(-.393,-.074),l(-.073,-.196),l(-.147,-.123),l(-.368,-.098),l(-.49,.147),l(-.196,-.073),l(-.688,.024),l(-.564,0),l(-.589,.024),l(-.122,-.098),l(-.049,-.147),l(-.099,-.27),l(.099,-.245),l(.196,-.196),l(.098,.221),l(.196,-.074),l(-.049,-.196),l(.098,-.27),l(.123,0),l(.981,-.196),l(.515,.147),l(.516,.196),l(.099,.172),l(.196,0),l(.024,-.246),l(.441,-.196),l(.302,-.147),
+N(685.343,114.455),l(-.571,.678),l(-.309,.115),l(-.511,-.096),l(-.579,-.068),l(-.595,-.011),l(-.315,.157),l(-.633,.738),l(-.283,.256),l(-.235,.171),l(-.268,-.206),l(-.35,.34),l(-.319,.199),l(-.373,-.608),l(-.398,-.112),l(-.649,.78),l(-.195,-.382),l(-.232,-.254),l(-.683,-.367),l(-.169,-.453),l(.095,-.312),l(.429,-.411),l(.754,-.229),l(.056,-.269),l(-.591,-.282),l(.407,-.879),l(.189,-.34),l(-.199,-.269),l(-.632,-.296),l(-.139,0),l(-.381,.029),l(-.312,.143),l(-.234,-.07),l(-.52,-.368),l(-.167,-.233),l(.379,-.528),l(.415,-.442),l(.52,-.329),l(1.533,-.604),l(1.032,-.545),l(.636,-.543),l(.686,-1.027),l(.386,-.13),l(.448,-.017),l(.273,.396),l(.493,.253),l(.508,.153),l(.975,-.048),l(.527,-.159),l(-.046,-.113),l(-.508,-.765),l(.025,-.342),l(.273,-.243),l(.392,-.059),l(.333,.126),l(.452,.054),l(.538,-.017),l(.62,-.259),l(.955,-.532),l(.23,-.713),l(.383,-.358),l(.253,-.129),l(.247,-.001),l(.579,.68),l(.298,.439),l(.167,.393),l(-1.356,.923),l(-.408,.457),l(-.112,.414),l(.09,.427),l(-.154,.456),l(-.187,.868),l(-.668,.115),l(-.36,.229),l(-.497,.385),l(-.766,.641),l(-.468,.214),l(-.678,.03),l(-.577,.199),l(-.265,.228),l(-.248,.312),l(-.364,.893),l(.284,.326),l(1.225,.847),l(.419,.354),
+N(536.625,121.017),l(-.078,-.028),l(-.15,-.692),l(-.01,-.565),l(-.038,-.848),l(-.185,-.211),l(-.787,.075),l(-.696,-.01),l(-.655,-.506),l(-1.803,-1.362),l(-.597,-.336),l(-.66,-.167),l(-.5,-.054),l(-.788,-.066),l(-.822,-.335),l(-.708,-.251),l(-.402,-.437),l(-1.055,-.107),l(-.519,-.054),l(-.343,.129),l(-.517,.343),l(-.333,.03),l(-.78,-.038),l(-.609,.032),l(-.413,.144),l(-.476,.328),l(-.621,.654),l(-.466,.3),l(-.562,.13),l(-.441,-.025),l(-.066,-.376),l(-.128,-.681),l(-.106,-.447),l(.128,-.298),l(0,-.383),l(0,-.532),l(.106,-.191),l(.106,-.298),l(.085,-.234),l(-.085,-.212),l(-.256,-.128),l(-.319,-.191),l(-.213,-.255),l(-.042,-.149),l(-.171,0),l(-.191,-.042),l(-.361,-.106),l(-.191,.192),l(-.086,-.234),l(.086,-.106),l(.148,-.255),l(.128,.106),l(.383,-.042),l(.426,.085),l(.128,.021),l(.043,-.128),l(-.319,-.213),l(-.256,-.021),l(-.085,-.277),l(.17,-.255),l(.213,-.191),l(-.404,-.042),l(-.319,.085),l(-.383,0),l(-.319,-.085),l(-.128,.149),l(-.17,-.255),l(-.149,-.298),l(0,-.34),l(-.042,-.298),l(.17,-.213),l(.106,-.319),l(.043,-.255),l(.105,-.277),l(.086,-.234),l(.213,.34),l(.063,.128),l(.17,.17),l(.405,-.085),l(.383,.128),l(.106,-.149),l(-.021,-.149),l(.106,0),l(.148,.021),l(.064,.319),l(.106,.191),l(.298,-.021),l(.298,-.063),l(.256,-.106),l(.233,.085),l(.192,.064),l(.085,-.128),l(-.149,-.191),l(-.042,-.213),l(.191,-.042),l(.106,.149),l(.233,.085),l(.256,-.085),l(.213,-.064),l(.021,-.234),l(-.171,-.341),l(-.34,-.234),l(-.532,-.319),l(-.426,-.213),l(-.063,-.319),l(-.043,-.34),l(-.213,-.17),l(0,-.213),l(0,-.213),l(-.085,-.127),l(-.554,-.064),l(-.617,.085),l(-.426,.021),l(-.446,.127),l(-.192,.277),l(-.085,.298),l(.128,.192),l(-.063,.276),l(-.086,.405),l(.064,.234),l(.021,.298),l(-.256,-.553),l(-.361,-.319),l(.042,-.17),l(-.063,-.191),l(-.274,-.143),l(.529,-.453),l(.937,-.532),l(1.277,-.298),l(.979,-.085),l(.512,.234),l(.681,.383),l(.617,.383),l(.256,.511),l(.638,.703),l(.447,.255),l(.489,-.043),l(.341,-.106),l(.158,.014),l(1.03,.063),l(1.383,-.032),l(.126,-.314),l(-.314,-.409),l(.062,-.628),l(.503,-.409),l(.503,-.251),l(.629,0),l(.283,-.126),l(.22,-.346),l(.126,-.126),l(.283,0),l(.597,.283),l(-.188,-.377),l(-.251,-.251),l(.565,-.157),l(.188,-.063),l(.472,.095),l(.629,.377),l(.346,.032),l(.22,.314),l(.692,.095),l(.534,.094),l(.251,.22),l(.032,.22),l(0,.22),l(.439,.283),l(-.188,.157),l(-.031,.188),l(.188,.22),l(-.157,.188),l(-.094,.22),l(.691,.314),l(.314,.157),l(.503,-.094),l(.439,-.032),l(.535,.126),l(.439,-.063),l(.188,-.157),l(.881,.251),l(.22,.377),l(.126,.566),l(.408,.597),l(.283,.188),l(.188,.44),l(0,.283),l(1.384,.975),l(1.194,.597),l(.377,.44),l(1.006,.503),l(.314,-.063),l(.943,.597),l(.565,.22),l(1.132,.597),l(.378,.251),l(.471,-.063),l(.566,.189),l(.534,.283),l(.503,.094),l(-.062,.22),l(-.157,.251),l(.062,.503),l(-.091,.726),l(-1.454,-.244),l(-.565,-.294),l(-.445,.356),l(-.417,.2),l(-1.135,.205),l(-.432,.809),l(-.203,.991),l(-.103,.128),l(-.508,.243),l(-1.985,.689),l(-.568,.159),l(-.119,.199),l(-.001,.466),l(-.22,.199),l(-.636,.3),l(-.534,.031),l(-.573,-.082),l(-.999,-.348),l(-.937,-.193),l(-.193,-.112),
+N(445.294,112.196),l(-.07,-.115),l(-.138,-.469),l(-.5,-.452),l(-.966,-.541),l(.024,-.141),l(.23,.062),l(.023,-.237),l(-.345,-.414),l(.418,-.616),l(-.182,-.22),l(.188,-.563),l(-.251,-.282),l(.182,-.396),l(.268,-.079),l(-.027,-.45),l(-.331,-.081),l(-.2,-.107),l(.002,-.342),l(-.133,-.427),l(.279,-.515),l(.273,-.273),l(.727,.11),l(.361,.022),l(.058,.004),l(.382,.369),l(.733,.866),l(.018,.109),l(.035,.218),l(-.132,.429),l(.074,.641),l(.298,.668),l(.722,.608),l(-.09,.029),l(-.449,.842),l(-.402,.386),l(-.496,.472),l(-.583,.884),
+N(451.512,108.463),l(-.507,.16),l(-.532,.245),l(-.622,-.054),l(-.361,-.041),l(-.365,.159),l(-.395,.429),l(-.606,.146),l(-.809,.076),l(-.722,-.608),l(-.298,-.668),l(-.074,-.641),l(.132,-.429),l(-.035,-.218),l(.14,.049),l(.188,0),l(.072,-.087),l(.029,-.072),l(-.029,-.13),l(.058,-.167),l(.088,-.058),l(.225,-.058),l(.246,-.058),l(.116,-.058),l(.08,-.065),l(.087,.073),l(.131,.058),l(.094,.109),l(.116,0),l(.029,-.058),l(-.059,-.072),l(.109,-.058),l(.151,-.102),l(.152,-.087),l(.175,.043),l(.064,-.007),l(.196,.007),l(.152,.015),l(.087,-.08),l(.131,-.116),l(.064,.021),l(.102,.043),l(.088,-.021),l(.087,-.043),l(.102,.051),l(.058,-.015),l(.116,-.022),l(.145,-.021),l(.16,-.022),l(.072,-.029),l(.058,.017),l(-.007,.106),l(.134,.213),l(.666,.296),l(.358,.383),l(.225,.469),l(-.006,.499),l(-.104,.3),l(.047,.199),
+N(383.93,117.402),l(-.249,.101),l(-.517,.291),l(-.439,.052),l(-.548,-.178),l(-.58,0),l(-.28,-.073),l(-.719,.292),l(-.058,-.177),l(.389,-1.012),l(-.021,-.856),l(-.182,-.115),l(.244,-.542),l(-.054,-.397),l(.13,-.114),l(-.144,-.141),l(-.375,.085),l(-.476,.097),l(-.108,-.449),l(.48,-.052),l(.283,-.22),l(-.042,-.17),l(-.178,-.226),l(-.3,.417),l(-.413,.136),l(-.357,-.042),l(-.059,-.188),l(.198,-.397),l(.138,-.616),l(-.039,-.303),l(.258,-.114),l(.403,-.503),l(.45,-1.098),l(-.12,-.115),l(.612,-1.783),l(-.35,-.924),l(-.007,-.42),l(-.146,-.378),l(.255,-.271),l(.891,-.251),l(.55,-.188),l(.531,.439),l(1.822,.047),l(.531,-.26),l(.335,.055),l(.272,.227),l(.15,.242),l(.842,.495),l(.062,.242),l(-.288,.216),l(-1.234,.506),l(-.084,.072),l(-.051,.442),l(.072,.456),l(-.132,.983),l(.057,.938),l(-.043,.199),l(-.458,.229),l(-.482,.045),l(-.288,.129),l(.488,.494),l(.455,.551),l(.163,.198),l(-.347,.371),l(-.506,.655),l(-.17,.455),l(.812,.123),l(.408,.31),l(-.884,.643),l(-.242,.37),l(-.304,.951),l(-.008,.018),
+N(500.121,117.572),l(-.407,-.016),l(-.433,.388),l(-.164,.126),l(-.318,-.105),l(-.102,-.269),l(.03,-.259),l(-.274,-.151),l(-.366,-.082),l(-.244,.234),l(-.343,-.023),l(-.811,-.153),l(-.364,.032),l(-.304,-.16),l(-.437,.094),l(-.266,.143),l(-.23,.043),l(-.064,-.245),l(-.207,-.023),l(-.24,.292),l(-.693,.304),l(-1.185,.224),l(-.711,-.039),l(-.747,-.123),l(-.439,.073),l(-1.498,.673),l(-.567,.13),l(-1.104,.176),l(-.556,-.153),l(-1.532,-.444),l(-.278,.03),l(-.929,.373),l(-.746,.075),l(-.575,-.025),l(-.777,-.166),l(-.222,.001),l(-.142,-.035),l(-.055,.319),l(.102,.452),l(.243,.423),l(-.627,.127),l(-.156,.374),l(-.2,.169),l(-.171,-.041),l(-.114,.127),l(-.39,-.125),l(-.311,.001),l(-.245,-.459),l(-.119,-.093),l(.097,-.175),l(.242,-.197),l(.617,-.403),l(.021,-.175),l(-.049,-.134),l(-.279,-.28),l(-.146,-.053),l(-.487,.368),l(-.23,.041),l(-.137,.064),l(.092,.041),l(-.118,.216),l(-.172,.023),l(-.063,-.047),l(-.076,.088),l(-.297,.058),l(-.332,-.222),l(-.447,-.198),l(-.461,-.157),l(-.395,.046),l(-.849,.548),l(-.337,.286),l(.006,.204),l(-.141,.046),l(-.122,.07),l(-.005,.082),l(-.179,-.169),l(-.604,.206),l(-.689,.185),l(-.594,-.013),l(-.587,-.07),l(-.678,-.267),l(-.963,-.819),l(-1.181,-.479),l(-1.034,-.182),l(-.692,.072),l(-.119,.255),l(-.097,.609),l(-.053,.411),l(-.173,.156),l(-.256,0),l(-.253,-.155),l(-1.12,.243),l(-.423,-.027),l(-.386,-.183),l(-.657,-1.159),l(-.42,.354),l(-.764,-.451),l(-.451,.057),l(-.562,.412),l(-.227,-.382),l(.066,-.127),l(.242,-.17),l(-.116,-.17),l(-.989,-.012),l(-.545,-.013),l(-.088,-.269),l(.571,-.199),l(-.074,-.241),l(-.284,-.198),l(-.454,-.07),l(-.084,-.297),l(.041,-.34),l(.087,-.284),l(-.089,-.255),l(-.396,-.126),l(-.627,-.353),l(-.371,.086),l(-.265,-.084),l(-.004,-.255),l(.171,-.501),l(.131,.059),l(.478,.311),l(.567,-.271),l(-.396,-.283),l(.021,-.124),l(-.296,-.128),l(.03,-.128),l(.571,-.159),l(.152,-.113),l(-.068,-.142),l(-.149,-.088),l(-.337,-.035),l(.01,-.187),l(.18,-.07),l(-.163,-.164),l(-.198,-.117),l(-.009,-.152),l(-.227,-.012),l(.263,-.181),l(.296,-.275),l(.161,-.035),l(.07,-.16),l(-.341,-.042),l(-.573,.12),l(-.905,.164),l(-.166,-.035),l(.046,-.33),l(.127,-.125),l(-.003,-.199),l(-.029,-.286),l(.13,-.264),l(.299,.012),l(.184,-.41),l(.175,-.023),l(.63,-.422),l(.514,.012),l(.133,-.129),l(.479,-.047),l(.128,.211),l(.268,.102),l(.169,.028),l(.529,.022),l(.147,-.129),l(-.067,-.129),l(-.269,-.129),l(.286,-.094),l(.324,.036),l(.117,.082),l(-.219,.223),l(.213,-.026),l(1.053,-.073),l(.619,.042),l(.379,.046),l(.279,.047),l(.155,-.176),l(-.086,-.094),l(-.468,-.035),l(-.212,-.118),l(.275,-.212),l(1.386,-.151),l(.417,-.012),l(.377,-.117),l(-.442,-.012),l(-.592,.023),l(-.215,0),l(-.068,-.146),l(-.611,-.382),l(.325,-.528),l(.926,.14),l(1.244,.048),l(.264,-.117),l(1.086,.321),l(1.051,-.031),l(.414,-.243),l(-.041,-.27),l(.624,-.244),l(.455,-.214),l(1.218,-.573),l(.598,-.215),l(1.039,-.23),l(.889,-.073),l(.758,.07),l(.905,.126),l(.798,.041),l(.753,-.372),l(.216,.527),l(.416,.298),l(.278,.099),l(.592,.013),l(.622,-.144),l(.453,.74),l(.492,.255),l(.574,-.172),l(.391,.056),l(.968,.582),l(1.265,.04),l(1.094,.197),l(.749,-.001),l(1.084,-.272),l(.514,-.044),l(.651,.141),l(.764,.098),l(.787,-.016),l(.554,-.144),l(1.518,-.573),l(.424,-.335),l(1.212,.082),l(.491,.068),l(.226,-.072),l(.761,-.36),l(.41,.041),l(1.326,1.018),l(.031,.028),l(.795,.722),l(.026,.199),l(-.421,.813),l(.033,.412),l(.284,.211),l(1.413,.12),l(.492,.451),l(-.072,.211),l(-.409,-.023),l(-.231,.141),l(-.009,.433),l(-.584,.267),l(-.039,.27),l(.264,.67),l(-.122,.375),l(.224,.492),l(.09,.117),l(.106,-.105),l(.288,.203),l(.039,.207),l(-.229,.281),l(-.287,.535),l(-.06,.128),l(.213,.14),l(.424,.111),l(-.145,.245),l(.099,.421),l(.42,.374),l(.275,.035),l(.023,.308),M(462.617,106.804),l(.241,.211),l(-.019,.287),l(.115,.285),l(.077,.071),l(.593,.355),l(.819,.241),l(.605,.155),l(.152,.121),L(464.943,109),l(-.304,.166),l(-.515,-.072),l(-.94,-.246),l(-.326,.07),l(-.209,.152),l(-1.019,-.012),l(-.357,.384),l(-.109,.273),l(-.833,.316),l(-.612,.282),l(-.222,.258),l(-.307,.152),l(-.268,.293),l(-.255,.082),l(.164,-.258),l(.019,-.141),l(-.062,-.176),l(.584,-.293),l(.22,-.141),l(-.226,-.191),l(-.082,.015),l(-.653,-.056),l(-.229,-.148),l(.326,-.546),l(.387,-.558),l(.678,-.631),l(-.127,-.227),l(-.427,-.197),l(-.105,0),l(.498,-.445),l(.629,-.374),l(.497,-.045),l(.527,.111),l(1.333,.005),
+N(509.077,114.955),l(-.72,-.317),l(-.268,.016),l(-.356,-.433),l(-.374,-.105),l(-.13,-.363),l(.532,-.27),l(.095,-.222),l(-.43,-.176),l(-.027,-.188),l(.63,-.129),l(.094,-.155),l(-.061,-.113),l(-.487,-.21),l(-.351,-.281),l(-.306,-.166),l(-.456,.234),l(-1.058,.492),l(-.374,.445),l(-.642,.188),l(-.254,.255),l(-.014,-.027),l(.094,-.118),l(-.094,-.213),l(-.189,-.071),l(.26,-.095),l(.166,-.047),l(-.261,-.189),l(-.236,-.236),l(.236,-.118),l(.095,-.189),l(-.283,-.047),l(-.354,-.024),l(-.284,-.118),l(-.213,-.212),l(-.236,-.024),l(-.26,-.354),l(-.283,-.142),l(-.048,-.094),l(.166,0),l(.378,0),l(.165,-.236),l(0,-.236),l(-.213,-.024),l(-.188,-.142),l(-.544,-.331),l(-.283,-.354),l(.047,-.284),l(.402,-.142),l(-.119,-.236),l(-.212,-.166),l(-.426,-.071),l(-.284,-.095),l(.071,-.094),l(.071,-.118),l(-.284,-.095),l(-.087,-.212),l(.418,-.308),l(.236,0),l(.473,.024),l(.331,.189),l(.189,.213),l(.638,.189),l(.284,-.047),l(.188,.023),l(.143,.071),l(.26,.189),l(.236,-.047),l(.236,-.095),l(.095,-.331),l(-.118,-.213),l(-.614,-.166),l(-.213,-.307),l(-.143,-.26),l(.095,-.071),l(.143,-.142),l(.268,-.189),l(.229,-.023),l(.023,.166),l(.213,-.047),l(.189,0),l(.142,.189),l(.473,.284),l(.095,.118),l(.118,0),l(.283,.284),l(0,.308),l(.591,.094),l(.449,.142),l(.379,-.047),l(.165,-.213),l(.308,-.331),l(.283,-.094),l(.496,-.284),l(.292,-.449),l(.465,.331),l(.236,.378),l(.26,.189),l(.284,.307),l(.095,.52),l(.142,.236),l(.283,.26),l(.284,.165),l(0,.166),l(.449,.236),l(.473,-.047),l(.378,.071),l(.284,.166),l(.236,.189),l(.095,.189),l(0,.142),l(-.355,-.142),l(-.401,-.047),l(-.213,0),l(-.26,.047),l(-.142,.118),l(-.402,.071),l(-.213,.142),l(-.047,.189),l(-.023,.473),l(-.118,.26),l(-.095,.236),l(-.095,.378),l(.213,.236),l(-.023,.189),l(-.237,-.071),l(-.094,.095),l(-.071,.331),l(-.071,.26),l(-.118,-.047),l(-.094,-.236),l(-.143,-.095),l(-.165,.095),l(-.047,.307),l(.07,.166),l(-.118,.118),l(-.118,.095),l(.095,.26),l(-.363,.91),M(499.844,111.738),l(.709,.061),l(.142,-.047),l(.26,-.071),l(.236,.236),l(.071,.166),l(.378,.142),l(.213,.071),l(.308,-.118),l(.52,0),l(-.071,.213),l(.024,.236),l(.118,.023),l(.331,.166),l(-.071,.236),l(.421,.763),l(-.009,.001),l(-.253,-.133),l(-.416,.038),l(-.512,-.025),l(-.421,-.125),l(-.335,-.211),l(-.294,-.402),l(-.551,-.223),l(-.281,-.417),l(-.265,-.381),l(-.252,-.197),
+N(455.452,122.442),l(.049,-.209),l(-.057,-.128),l(-.812,-.256),l(-.691,-.006),l(-.506,-.116),l(-.484,.017),l(-.121,-.046),l(-.103,-.093),l(.139,-.56),l(.315,-.005),l(-.005,-.088),l(-.009,-.122),l(.069,-.07),l(.083,.157),l(.021,.146),l(.303,.021),l(.172,.055),l(.184,-.076),l(-.014,-.082),l(.108,-.029),l(.157,.105),l(-.037,.093),l(-.099,.006),l(-.04,.053),l(.088,.023),l(.144,.035),l(.094,.046),l(.021,.128),l(.353,.041),l(.846,-.122),l(.509,.016),l(.035,.13),l(.192,.035),l(.608,.064),l(.307,.051),l(.358,-.121),l(.09,.05),l(-.101,.312),l(.163,.11),l(.105,0),l(.325,-.169),l(.286,-.058),l(.078,.052),l(.154,-.07),l(.232,-.146),l(-.083,.187),l(.015,.186),l(-.183,.268),l(-.582,-.046),l(-.349,.081),l(-.335,-.017),l(-1.994,.169),M(445.294,112.196),l(.583,-.884),l(.496,-.472),l(.402,-.386),l(.449,-.842),l(.09,-.029),l(.809,-.076),l(.606,-.146),l(.395,-.429),l(.365,-.159),l(.361,.041),l(.622,.054),l(.532,-.245),l(.507,-.16),l(.09,-.029),l(1.855,-.195),l(.799,-.261),l(.584,-.06),l(1.473,.505),l(.619,.21),l(.388,-.031),l(1.117,-.277),l(.086,-.257),l(-.097,-.327),l(.344,-.216),l(.363,.026),l(.105,0),l(.427,.197),l(.127,.227),l(-.678,.631),l(-.387,.558),l(-.326,.546),l(-.062,-.407),l(-.794,-.056),l(-.743,-.041),l(-.566,-.125),l(-.062,-.144),l(-.459,.186),l(-.248,.123),l(-.403,.012),l(-.031,-.247),l(-.335,.029),l(-.301,.314),l(-.431,.186),l(-.31,.03),l(-.306,-.159),l(-.252,.07),l(-.004,.133),l(.169,.185),l(.169,.34),l(.308,.059),l(.826,.609),l(-.166,.07),l(-.369,-.258),l(-.015,-.105),l(-.276,-.082),l(-.331,-.105),l(-.116,.099),l(-.211,.007),l(.069,.129),l(-.016,.129),l(.338,.164),l(.145,-.012),l(.114,.234),l(-.03,.129),l(-.245,.023),l(-.445,-.457),l(-.341,-.141),l(-.207,-.059),l(-.128,-.012),l(.003,.094),l(-.075,.035),l(.138,.164),l(.102,.105),l(.154,.141),l(.193,.059),l(.153,.035),l(.103,.094),l(-.093,.058),l(-.494,-.046),l(-.253,-.035),l(.035,-.176),l(-.137,-.293),l(-.164,-.188),l(-.401,-.108),l(-.472,-.373),l(.258,-.118),l(.025,-.136),l(-.053,-.122),l(-.182,-.035),l(-.153,.199),l(-.465,.176),l(.245,.224),l(-.25,.371),l(-.05,.249),l(.13,.121),l(.065,.172),l(.311,.338),l(.133,.036),l(.131,.479),l(.579,.421),l(.359,.467),l(-.172,.14),l(-.237,.082),l(.106,-.187),l(-.121,-.187),l(-.142,-.128),l(-.139,-.035),l(-.151,-.047),l(-.29,.175),l(.102,.188),l(.153,.081),l(.08,.316),l(-.193,.187),l(-.652,.141),l(.248,.046),l(.27,.14),l(.391,.058),l(.188,.222),l(.257,-.012),l(.155,.012),l(.048,.126),l(.367,.269),l(.306,.014),l(.138,.292),l(.282,.012),l(.27,0),l(.348,.303),l(.015,.128),l(-.193,.082),l(.238,.782),l(-.153,.175),l(-.185,0),l(-.226,-.385),l(-.222,-.047),l(-.207,-.278),l(-.101,-.142),l(-.17,0),l(-.496,.14),l(-.479,.105),l(-.184,.128),l(.315,.093),l(.013,.188),l(.007,.291),l(.229,.117),l(.153,-.026),l(.225,-.079),l(-.021,.198),l(.235,.175),l(-.519,.093),l(.002,.117),l(-.169,.062),l(-.309,-.086),l(.121,-.21),l(-.186,-.086),l(-.508,-.056),l(-.158,-.092),l(-.008,.206),l(.194,.453),l(.193,.17),l(-.045,.163),l(.209,.204),l(.213,.96),l(-.688,-.31),l(-.331,.071),l(-.298,.439),l(-.442,-.735),l(-.46,-.367),l(-.452,.44),l(-.428,-.353),l(-.127,-.297),l(.212,-.425),l(-.028,-.241),l(-.215,-.269),l(-.491,-.424),l(-.167,-.226),l(.017,-.17),l(.471,-.61),l(.609,.098),l(.425,-.298),l(.202,.042),l(1.668,.663),l(.337,-.1),l(.483,-.355),l(-.266,-.049),l(-.27,-.056),l(-1.204,-.493),l(-1.127,-.083),l(-.367,.058),l(-.66,.058),l(-.427,.143),l(-.89,-1.118),l(.269,-.1),l(.253,.056),l(.218,-.114),l(.122,-.185),l(-.339,-.24),l(-.235,.114),l(-.496,-.042),l(-1.035,-.721),l(-.199,-.325),
+N(504.136,113.458),l(-.327,.328),l(-.377,.03),l(-.421,-.763),l(.071,-.236),l(-.331,-.166),l(-.118,-.023),l(-.024,-.236),l(.071,-.213),l(-.52,0),l(-.308,.118),l(-.213,-.071),l(-.378,-.142),l(-.071,-.166),l(-.236,-.236),l(-.26,.071),l(-.142,.047),l(-.709,-.061),l(-.492,-.451),l(-1.413,-.12),l(-.284,-.211),l(-.033,-.412),l(.421,-.813),l(-.026,-.199),l(-.795,-.722),l(.377,-.108),l(.307,.024),l(.308,-.095),l(.426,-.023),l(.401,-.118),l(.592,.047),l(.591,-.095),l(.378,-.047),l(.291,-.094),l(.087,.212),l(.284,.095),l(-.071,.118),l(-.071,.094),l(.284,.095),l(.426,.071),l(.212,.166),l(.119,.236),l(-.402,.142),l(-.047,.284),l(.283,.354),l(.544,.331),l(.188,.142),l(.213,.024),l(0,.236),l(-.165,.236),l(-.378,0),l(-.166,0),l(.048,.094),l(.283,.142),l(.26,.354),l(.236,.024),l(.213,.212),l(.284,.118),l(.354,.024),l(.283,.047),l(-.095,.189),l(-.236,.118),l(.236,.236),l(.261,.189),l(-.166,.047),l(-.26,.095),l(.189,.071),l(.094,.213),l(-.094,.118),l(.014,.027),
+N(566.651,117.4),l(-.565,-.153),l(-.496,-.054),l(-.264,-.151),l(-.564,.227),l(-.974,.147),l(-.137,-.059),l(.129,-.176),l(-.198,-.077),l(-.678,.03),l(-.739,.315),l(-.592,.486),l(-.589,.064),l(-.745,.495),l(-.351,.03),l(-.368,-.026),l(-.128,-.084),l(-.164,-.409),l(-.199,-.521),l(.185,-.444),l(.099,-.775),l(.029,-.255),l(-.17,-.187),l(-.484,.093),l(.156,-.597),l(-.576,-.45),l(-.153,-.056),l(-.384,.016),l(-.286,.162),l(-.134,.363),l(-.435,.428),l(-.049,.425),l(.006,.255),l(-.208,.228),l(-.442,.158),l(-.133,-.013),l(-.587,-.152),l(-.292,.058),l(-.073,.185),l(.007,.311),l(-.3,.313),l(-.21,.128),l(-.381,.016),l(-.63,-.237),l(-.325,.001),l(-.581,.286),l(-.58,.343),l(-.485,.144),l(-.245,-.041),l(-.129,-.141),l(-.04,-.055),l(.375,-.843),l(-.063,-.377),l(.377,-.377),l(.283,-.503),l(.503,-.346),l(.157,-.22),l(-.126,-.283),l(-.471,-.314),l(-.126,-.409),l(.031,-.472),l(.126,-.22),l(-.126,-.22),l(-.346,0),l(-.44,-.032),l(-.157,-.157),l(-.346,-.188),l(-.251,-.283),l(.125,-.471),l(.472,-.283),l(.629,.126),l(1.069,.094),l(.282,-.188),l(.063,-.409),l(.251,-.157),l(.188,0),l(.032,-.346),l(.188,-.063),l(.251,-.063),l(-.126,-.094),l(-.534,.031),l(-.251,-.125),l(.503,-.094),l(.565,-.095),l(.472,.095),l(.062,-.126),l(.032,-.346),l(-.189,-.314),l(.283,-.314),l(-.031,-.22),l(.346,0),l(.22,.157),l(.252,.22),l(.22,-.157),l(.692,-.188),l(.471,-.346),l(.221,-.251),l(.439,.377),l(.252,.251),l(-.188,.22),l(-.409,.346),l(-.251,.126),l(.126,.188),l(.251,.063),l(.188,.283),l(.409,-.031),l(.345,.005),l(-.302,.147),l(-.441,.196),l(-.024,.246),l(-.196,0),l(-.099,-.172),l(-.516,-.196),l(-.515,-.147),l(-.981,.196),l(-.123,0),l(-.098,.27),l(.049,.196),l(-.196,.074),l(-.098,-.221),l(-.196,.196),l(-.099,.245),l(.099,.27),l(.049,.147),l(.122,.098),l(.589,-.024),l(.564,0),l(.688,-.024),l(.196,.073),l(.49,-.147),l(.368,.098),l(.147,.123),l(.073,.196),l(.393,.074),l(.295,-.049),l(-.024,-.221),l(.343,-.049),l(.442,-.123),l(.221,.024),l(.049,.147),l(.319,.123),l(.122,-.024),l(.049,.172),l(.074,.221),l(.318,-.172),l(.368,-.024),l(.172,.319),l(.196,0),l(.172,-.147),l(.834,-.221),l(.663,.073),l(.539,0),l(.344,-.171),l(.344,-.098),l(.196,.073),l(-.011,.069),l(.023,1.031),l(-.207,.223),l(.077,.305),l(.325,.394),l(.463,-.045),l(.229,-.162),l(.22,.06),l(.692,.039),l(.273,.154),l(.295,.494),l(-.009,.284),l(.028,.246),l(.152,.012),l(.049,.123),l(-.126,.428),l(.245,.237),l(-.152,.36),l(.2,.163),l(-.181,.185),l(-.08,.249),l(-.354,.136),
+N(500.121,117.572),l(-.023,-.308),l(-.275,-.035),l(-.42,-.374),l(-.099,-.421),l(.145,-.245),l(-.424,-.111),l(-.213,-.14),l(.06,-.128),l(.287,-.535),l(.229,-.281),l(-.039,-.207),l(-.288,-.203),l(-.106,.105),l(-.09,-.117),l(-.224,-.492),l(.122,-.375),l(-.264,-.67),l(.039,-.27),l(.584,-.267),l(.009,-.433),l(.231,-.141),l(.409,.023),l(.072,-.211),l(.252,.197),l(.265,.381),l(.281,.417),l(.551,.223),l(.294,.402),l(.335,.211),l(.421,.125),l(.512,.025),l(.416,-.038),l(.253,.133),l(.009,-.001),l(.377,-.03),l(.327,-.328),l(.254,-.255),l(.642,-.188),l(.374,-.445),l(1.058,-.492),l(.456,-.234),l(.306,.166),l(.351,.281),l(.487,.21),l(.061,.113),l(-.094,.155),l(-.63,.129),l(.027,.188),l(.43,.176),l(-.095,.222),l(-.532,.27),l(.13,.363),l(.374,.105),l(.356,.433),l(.268,-.016),l(.72,.317),l(.015,.007),l(-.05,.707),l(-.143,.581),l(.205,.48),l(.494,.252),l(.925,.235),l(.827,.052),l(.424,.097),l(.162,.282),l(.312,.451),l(.687,.463),l(1.902,.513),l(.841,.052),l(.438,-.059),l(1.354,-.262),l(1.192,-.148),l(1.469,-.079),l(.41,-.229),l(.185,-.354),l(-.131,-.905),l(.015,0),l(.441,.025),l(.562,-.13),l(.466,-.3),l(.621,-.654),l(.476,-.328),l(.413,-.144),l(.609,-.032),l(.78,.038),l(.333,-.03),l(.517,-.343),l(.343,-.129),l(.519,.054),l(1.055,.107),l(.402,.437),l(.708,.251),l(.822,.335),l(.788,.066),l(.5,.054),l(.66,.167),l(.597,.336),l(1.803,1.362),l(.655,.506),l(.696,.01),l(.787,-.075),l(.185,.211),l(.038,.848),l(.01,.565),l(.15,.692),l(.078,.028),l(-.145,.241),l(-.084,.339),l(-.246,.807),l(-.49,1.272),l(-.222,.297),l(-.596,.384),l(-.016,.141),l(.119,.663),l(.096,.098),l(.738,.235),l(.026,.183),l(-.661,.935),l(-.034,.155),l(.254,1.085),l(.167,1.283),l(.143,.775),l(.191,.21),l(.209,.041),l(1.198,.275),l(.401,.167),l(.144,.366),l(.046,.437),l(-.425,.553),l(-.853,.795),l(-.853,1.034),l(.802,1.083),l(.71,1.068),l(.353,.464),l(.695,.391),l(1.144,.388),l(.409,.224),l(.168,.38),l(.111,1.34),l(.185,.394),l(.652,.053),l(.186,.281),l(-.036,.974),l(-.188,.255),l(-.209,.072),l(-1,.077),l(-.697,.258),l(-.794,.47),l(-.285,.383),l(-.31,.792),l(-.049,.354),l(-.182,.954),l(-.502,.028),l(-1.079,-.153),l(-.236,-.197),l(-.605,-.253),l(-.403,-.056),l(-1.43,.003),l(-.783,-.041),l(-.602,.072),l(-.475,-.38),l(-.163,-.126),l(-.835,-.026),l(-.576,.001),l(-.465,.014),l(-.212,-.239),l(-.756,-.125),l(-.305,-.183),l(-.162,-.014),l(-.021,-.5),l(-.295,-.128),l(-.103,-.514),l(-.292,-.349),l(-.013,-.639),l(-.309,-.493),l(-.237,.012),l(-.035,-.181),l(-.526,-.126),l(-.807,-.013),l(-.374,.017),l(-.209,.222),l(-.329,.018),l(-.517,.075),l(-.188,.364),l(-.538,.138),l(-.383,.443),l(-.368,.283),l(-.253,.043),l(-1.292,-.689),l(-.958,-.104),l(-.562,-.359),l(-1.088,-.317),l(-.247,-.301),l(-.324,-.282),l(-.497,-.592),l(-.997,-.436),l(-.584,-.083),l(-.194,-.028),l(-.58,-.465),l(-.596,-1.058),l(-.635,-1.114),l(-.209,-.268),l(.005,-.593),l(-.767,-.761),l(-.506,-.719),l(-.921,.143),l(-.46,-.042),l(-.13,-.126),l(-.291,-.056),l(-.191,-.268),l(-.029,-.565),l(-.448,.1),l(-.166,.099),l(-.32,.678),l(-.195,.184),l(-.355,.012),l(-.014,-.12),l(-.351,-.224),l(-.686,-.546),l(.064,-.212),l(-.007,-.395),l(-.164,-.465),l(-.215,-.013),l(-.551,.003),l(-.034,-.325),l(.055,-.579),l(.197,-.622),l(.014,-.508),l(-.112,-.239),l(-.29,-.28),l(-.774,-.603),l(-.436,-.209),l(-1.242,-.925),l(-.533,-.025),l(-.321,.115),L(503,127.106),l(.033,-.819),l(-1.02,-.954),l(-.312,-.351),l(-.002,-.184),l(.133,-.875),l(.235,-.763),l(1.142,-.98),l(-.422,-.761),l(.013,-.254),l(.468,-.596),l(-1.067,-.107),l(-.761,-.208),l(-.065,-.198),l(-.563,-1.086),l(-.69,-1.397),
+N(535.734,133.791),l(.853,-1.034),l(.853,-.795),l(.425,-.553),l(-.046,-.437),l(-.144,-.366),l(-.401,-.167),l(-1.198,-.275),l(-.209,-.041),l(-.191,-.21),l(-.143,-.775),l(-.167,-1.283),l(-.254,-1.085),l(.034,-.155),l(.661,-.935),l(-.026,-.183),l(-.738,-.235),l(-.096,-.098),l(-.119,-.663),l(.016,-.141),l(.596,-.384),l(.222,-.297),l(.49,-1.272),l(.246,-.807),l(.084,-.339),l(.145,-.241),l(.193,.112),l(.937,.193),l(.999,.348),l(.573,.082),l(.534,-.031),l(.636,-.3),l(.22,-.199),l(.001,-.466),l(.119,-.199),l(.568,-.159),l(1.985,-.689),l(.508,-.243),l(.103,-.128),l(.203,-.991),l(.432,-.809),l(1.135,-.205),l(.417,-.2),l(.445,-.356),l(.565,.294),l(1.454,.244),l(.096,.016),l(.646,.011),l(1.217,.05),l(.236,.126),l(.351,.48),l(.04,.055),l(.129,.141),l(.245,.041),l(.485,-.144),l(.58,-.343),l(.581,-.286),l(.325,-.001),l(.63,.237),l(.381,-.016),l(.21,-.128),l(.3,-.313),l(-.007,-.311),l(.073,-.185),l(.292,-.058),l(.587,.152),l(.133,.013),l(.442,-.158),l(.208,-.228),l(-.006,-.255),l(.049,-.425),l(.435,-.428),l(.134,-.363),l(.286,-.162),l(.384,-.016),l(.153,.056),l(.576,.45),l(-.156,.597),l(.484,-.093),l(.17,.187),l(-.029,.255),l(-.099,.775),l(-.185,.444),l(.199,.521),l(.164,.409),l(.128,.084),l(.368,.026),l(.351,-.03),l(.745,-.495),l(.589,-.064),l(.592,-.486),l(.739,-.315),l(.678,-.03),l(.198,.077),l(-.129,.176),l(.137,.059),l(.974,-.147),l(.564,-.227),l(.264,.151),l(.496,.054),l(.565,.153),l(-.192,.145),l(-.574,-.059),l(.01,.269),l(.236,.012),l(.048,.088),l(-.148,.142),l(-.358,.004),l(-.455,.297),l(-.332,-.005),l(-.338,.179),l(-.647,-.144),l(-1.345,.012),l(-1.148,.152),l(-.53,.292),l(-.272,.19),l(-.559,.395),l(-.246,-.023),l(-.258,.214),l(-.464,.413),l(.01,.32),l(.411,.271),l(.01,.336),l(.232,.171),l(-.119,.483),l(.198,.477),l(-.324,.426),l(-.524,.355),l(-.4,.341),l(-.13,.283),l(.223,.478),l(.033,.31),l(-.289,.255),l(-.513,.215),l(-.698,-.039),l(-.997,-.122),l(-.355,.129),l(.35,.336),l(.365,.407),l(.129,.281),l(.088,.437),l(-.199,.255),l(-.315,.115),l(-.513,.031),l(-.416,.115),l(-.292,.228),l(-.224,.424),l(-.288,.834),l(-.139,1.214),l(-.021,.084),l(-.34,.383),l(-.237,.086),l(-1.001,-.375),l(-.562,-.025),l(-.559,.243),l(-.362,.271),l(-.321,.693),l(-.254,.086),l(-.516,-.082),l(-.644,-.039),l(-.283,.072),l(-.597,.441),l(-.412,.369),l(-.188,.34),l(-.232,.876),l(-.099,.903),l(-.069,.184),l(-.247,.156),l(-1.066,.274),l(-1.183,.19),l(-.964,.175),l(-1.234,.12),l(-1.005,-.135),l(-.349,.002),l(-1.187,.218),l(-.742,-.024),l(-.541,-.039),l(-.854,-.235),l(-1.069,-.248),l(-.63,-.194),l(-.887,-.32),
+N(486.696,126.295),l(5.257,-2.711),l(.589,-2.701),l(-.024,-.467),l(-.187,-.508),l(.009,-.255),l(.23,-.355),l(.31,-.214),l(.866,-.174),l(.457,-.371),l(.944,-.883),l(-.059,-.24),l(.23,-.043),l(.266,-.143),l(.437,-.094),l(.304,.16),l(.364,-.032),l(.811,.153),l(.343,.023),l(.244,-.234),l(.366,.082),l(.274,.151),l(-.03,.259),l(.102,.269),l(.318,.105),l(.164,-.126),l(.433,-.388),l(.407,.016),l(.69,1.397),l(.563,1.086),l(.065,.198),l(.761,.208),l(1.067,.107),l(-.468,.596),l(-.013,.254),l(.422,.761),l(-1.142,.98),l(-.235,.763),l(-.133,.875),l(.002,.184),l(.312,.351),l(1.02,.954),L(503,127.106),l(.075,.155),l(.321,-.115),l(.533,.025),l(1.242,.925),l(.436,.209),l(.774,.603),l(.29,.28),l(.112,.239),l(-.014,.508),l(-.197,.622),l(-.055,.579),l(.034,.325),l(.551,-.003),l(.215,.013),l(.164,.465),l(.007,.395),l(-.064,.212),l(.686,.546),l(.351,.224),l(.014,.12),l(-.096,.003),l(-.664,.101),l(-.408,-.056),l(-.157,.057),l(-.103,.127),l(-1.271,.044),l(-.518,.13),l(-.343,.693),l(-.463,.609),l(-.521,.568),l(-4.048,-.132),l(-1.557,-.697),l(-.812,-.277),l(-.118,-.253),l(-.047,-.818),l(.118,-.396),l(-.135,-.366),l(-.973,.048),l(-.141,-.07),l(-.399,-.633),l(-.258,-.196),l(-2.44,-1.101),l(-1.14,-.473),l(-2.034,-.934),l(-.757,-.222),l(-1.129,-.459),l(-.093,-.056),l(-.093,-.056),l(-.311,-.69),l(-.87,-1.632),
+N(479.916,127.377),l(-.082,-.085),l(.047,-.122),l(-.021,-.183),l(-.201,-.128),l(-.183,-.346),l(.398,-.209),l(.041,-.099),l(.526,-.396),l(-.048,-.058),l(-.223,-.099),l(.077,-.151),l(.298,-.25),l(.599,-.006),l(-.14,-.146),l(-.035,-.046),l(.078,-.111),l(.177,-.163),l(.169,-.116),l(.299,-.239),l(-.068,-.058),l(.023,-.163),l(-.09,-.047),l(-.031,-.221),l(-.241,-.157),l(-.222,-.058),l(.204,-.204),l(-.125,-.052),l(-.053,-.116),l(-.12,.058),l(-.335,.052),l(-.388,-.023),l(-.225,-.564),l(.129,-.593),l(.072,-.064),l(-.1,-.507),l(-.42,-.326),l(.126,-.093),l(.036,-.152),l(.117,-.128),l(-.093,-.222),l(.107,-.012),l(.259,-.32),l(-.061,-.112),l(.311,-.001),l(.39,.125),l(.114,-.127),l(.171,.041),l(.2,-.169),l(.156,-.374),l(.627,-.127),l(-.243,-.423),l(-.102,-.452),l(.055,-.319),l(.142,.035),l(.222,-.001),l(.777,.166),l(.575,.025),l(.746,-.075),l(.929,-.373),l(.278,-.03),l(1.532,.444),l(.556,.153),l(1.104,-.176),l(.567,-.13),l(1.498,-.673),l(.439,-.073),l(.747,.123),l(.711,.039),l(1.185,-.224),l(.693,-.304),l(.24,-.292),l(.207,.023),l(.064,.245),l(.059,.24),l(-.944,.883),l(-.457,.371),l(-.866,.174),l(-.31,.214),l(-.23,.355),l(-.009,.255),l(.187,.508),l(.024,.467),l(-.589,2.701),l(-5.257,2.711),l(-.161,.071),l(-2.96,1.541),l(-1.139,.656),l(-.253,.016),l(-.365,-.167),l(-1.902,-1.034),
+N(426.068,126.434),l(-.093,.981),l(.064,.564),l(-.093,.269),l(-.802,.428),l(-.579,.314),l(-1.473,1.138),l(-.126,.354),l(.274,.973),l(-.147,.537),l(-.155,.227),l(-.864,.598),l(-.22,.143),l(-.564,-1.536),l(-.699,-2.242),l(-.323,-.464),l(-.363,-.252),l(-.432,-.181),l(-.484,-.831),l(-.225,-.465),l(-.363,-.28),l(-.452,-.097),l(-.336,-.774),l(-.301,-.888),l(.112,-.509),l(1,-.853),l(.414,-.355),l(.163,-.411),l(.048,-.537),l(-.052,-.594),l(-.026,-.892),l(-.012,-1.429),l(.114,-.439),l(.685,-.627),l(.012,-.184),l(.508,-.185),l(.633,-.455),l(.591,-.228),l(.703,-.016),l(.643,.183),l(.247,.212),l(.059,.241),l(.25,.538),l(.27,.084),l(.417,-.171),l(.584,-.44),l(.401,-.17),l(.034,.354),l(-.265,.567),l(-.638,.511),l(-.275,.468),l(.005,.283),l(.202,.438),l(.508,.466),l(.351,.127),l(.303,.848),l(-.094,.212),l(-.541,.764),l(-.59,.34),l(-1.017,.92),l(-.216,.339),l(.287,.451),l(.587,.55),l(.528,.295),l(.284,.056),l(.396,-.227),l(.316,.084),l(.244,.635),l(.582,.239),
+N(381.402,139.704),l(-.027,-.876),l(.069,-2.006),l(.037,-.382),l(.686,-.314),l(1.512,-.998),l(.963,-.542),l(1.265,.078),l(.397,-.059),l(.181,-.693),l(.864,-.033),l(.777,-.174),l(.527,-.229),l(.524,-.356),l(.484,-.652),l(1.109,-.332),l(1.52,-.701),l(.129,-.227),l(-.296,-.62),l(-.025,-.396),l(.079,-.227),l(.265,-.114),l(1.186,-.12),l(.381,-.186),l(.309,-.553),l(1.022,.022),l(.67,-.018),l(1.826,.004),l(.34,-1.033),l(-.07,-.211),l(-.507,-.322),L(397,126.646),l(-.158,-.465),l(.016,-1.271),l(.022,-.833),l(-.165,-.889),l(-.189,-.211),l(-.563,-.279),l(-.259,-.508),l(.351,0),l(.66,-.143),l(.541,-.256),l(.369,-.566),l(.405,-.312),l(.509,-.086),l(.407,-.157),l(.679,-.27),l(.324,.226),l(.176,.017),l(.249,.024),l(.238,-.142),l(.407,-.51),l(.613,-.426),l(.682,-.355),l(.614,-.171),l(1.16,-.116),l(1.587,-.06),l(.513,-.072),l(.634,-.312),l(.578,.211),l(.564,-.072),l(.585,-.313),l(.343,-.1),l(.939,.012),l(.513,-.015),l(.307,.056),l(.221,.042),l(.322,.113),l(.816,.168),l(.529,-.015),l(.772,-.171),l(.705,-.2),l(.612,-.554),l(.994,.508),l(.339,.099),l(.312,-.143),l(.314,-.241),l(.228,-.156),l(.528,.042),l(.388,.197),l(.162,.269),l(.269,.126),l(.516,-.086),l(1.093,-.158),l(-.012,.184),l(-.685,.627),l(-.114,.439),l(.012,1.429),l(.026,.892),l(.052,.594),l(-.048,.537),l(-.163,.411),l(-.414,.355),l(-1,.853),l(-.112,.509),l(.301,.888),l(.336,.774),l(.452,.097),l(.363,.28),l(.225,.465),l(.484,.831),l(.432,.181),l(.363,.252),l(.323,.464),l(.699,2.242),l(.564,1.536),l(-.204,.156),l(-.241,.383),l(.88,1.605),l(.147,.833),l(.052,.691),l(-.1,.862),l(.101,.748),l(-.16,.622),l(-.158,.495),l(.457,1.156),l(-.061,.664),l(-.086,.17),l(-.666,.47),l(-.249,.128),l(-.152,.283),l(1.272,1.702),l(.249,.917),l(.562,.873),l(.244,.154),l(.544,-.201),l(.702,.165),l(1.028,.347),l(.178,.168),l(.86,1.506),l(.098,.07),l(-.265,.186),l(-1.632,.843),l(-4.012,2.241),l(-1.607,.956),l(-2.308,1.454),l(-.834,.655),l(-3.084,2.617),l(-1.82,.364),l(-1.672,.321),l(-2.176,.408),l(-.146,-.564),l(.161,-.679),l(-.099,-.522),l(-.277,-.352),l(-.309,-.111),l(-.748,-.024),l(-.375,-.167),l(-.588,-.562),l(-.47,.314),l(-.229,-.027),l(-1.111,-1.039),l(-.393,-.28),l(-.082,-.183),l(.096,-.396),l(-.181,-.253),l(-2.472,-1.469),l(-.397,-.253),l(-1.292,-.824),l(-1.924,-1.26),l(-3.283,-2.241),l(-.811,-.575),l(-2.054,-1.344),l(-.895,-.531),l(-.1,-.084),l(-1.414,-.91),l(-4.12,-2.42),l(-2.829,-1.509),
+N(395.704,122.189),l(.259,.508),l(.563,.279),l(.189,.211),l(.165,.889),l(-.022,.833),l(-.016,1.271),l(.158,.465),l(.598,.788),l(.507,.322),l(.07,.211),l(-.34,1.033),l(-1.826,-.004),l(-.67,.018),l(-1.022,-.022),l(-.309,.553),l(-.381,.186),l(-1.186,.12),l(-.265,.114),l(-.079,.227),l(.025,.396),l(.296,.62),l(-.129,.227),l(-1.52,.701),l(-1.109,.332),l(-.484,.652),l(-.524,.356),l(-.527,.229),l(-.777,.174),l(-.864,.033),l(-.181,.693),l(-.397,.059),l(-1.265,-.078),l(-.963,.542),l(-1.512,.998),l(-.686,.314),l(-.037,.382),l(-.069,2.006),l(-1.42,.008),l(-1.718,-.004),l(-2.677,.001),l(-2.511,0),l(-1.635,.04),l(.141,-.28),l(.431,-.411),l(.427,-.085),l(1.296,-.285),l(1.143,-.455),l(.453,-.312),l(1.147,-.85),l(1.149,-.878),l(1.043,-1.104),l(.46,-.693),l(.133,-.509),l(-.05,-.494),l(-.427,-.776),l(-.09,-.678),l(.099,-.508),l(.396,-.636),l(.706,-.863),l(.211,-.65),l(-.063,-.367),l(.071,-.353),l(1.285,-1.203),l(.724,-.481),l(.916,-.327),l(1.266,-.469),l(.73,-.397),l(.558,-.552),l(.537,-.736),l(.466,-.905),l(.829,-1.925),l(.269,-.128),l(.54,-.171),l(.19,.127),l(.684,.848),l(.138,.099),l(1.148,.507),l(.661,-.001),l(.595,.042),l(1.304,-.074),l(.522,-.228),l(.437,-.27),l(.398,.551),l(.256,.099),l(.798,.097),l(.361,0),
+N(480.248,123.437),l(.388,.023),l(.335,-.052),l(.12,-.058),l(.053,.116),l(.125,.052),l(-.204,.204),l(.222,.058),l(.241,.157),l(.031,.221),l(.09,.047),l(-.023,.163),l(.068,.058),l(-.299,.239),l(-.169,.116),l(-.177,.163),l(-.078,.111),l(.035,.046),l(.14,.146),l(-.599,.006),l(-.298,.25),l(-.077,.151),l(.223,.099),l(.048,.058),l(-.526,.396),l(-.041,.099),l(-.398,.209),l(-.07,-.023),l(-.088,.041),l(-.067,.193),l(-.009,.167),l(-.355,.07),l(-.07,-.099),l(-.151,-.022),l(-.372,.051),l(.26,-.291),l(.097,-.361),l(.169,-.227),l(.328,-.681),l(-.017,-.232),l(.181,0),l(.138,-.192),l(.072,-.32),l(.018,-.32),l(.409,-.431),l(.232,-.07),l(.116,-.174),l(-.048,-.157),
+N(184.444,142.729),l(-.367,.82),l(-.518,.821),l(-.186,.763),l(-.179,1.159),l(.017,1.851),l(-.133,1.187),l(-.016,1.13),l(.564,1.737),l(.275,.805),l(.624,.945),l(.76,.903),l(.191,.452),l(.481,.521),l(.529,.974),l(.729,1.228),l(.375,.296),l(.677,.069),l(.436,-.015),l(.577,.154),l(.593,.451),l(.503,.508),l(.773,.069),l(1.016,-.242),l(1.55,-.456),l(1.396,-.3),l(.803,-.157),l(-.02,.542),l(.838,.223),l(.264,-.286),l(.293,-.199),l(-.104,-.247),l(-.393,-.175),l(1.073,-.62),l(.633,-.62),l(.086,-.827),l(.498,-.429),l(-.094,-.477),l(.092,-1.145),l(.254,-.699),l(.625,-.334),l(.164,-.043),l(.757,-.198),l(.701,-.1),l(1.088,-.229),l(1.016,-.37),l(.594,-.058),l(.499,.056),l(1.139,.181),l(.502,-.194),l(.378,.093),l(.62,.507),l(.047,.297),l(-.079,.424),l(-.298,.382),l(-.541,.496),l(-.433,.425),l(-.317,.445),l(-.02,.7),l(-.254,.297),l(-.188,.354),l(.155,.155),l(.337,-.138),l(-.101,.652),l(-.262,1.196),L(205.356,159),l(-.062,.24),l(-.34,-.534),l(-.167,-.452),l(-.072,-.155),l(-.386,.34),l(-.02,.549),l(-.437,.016),l(-.178,.447),l(-.599,.857),l(-.386,-.27),l(-.278,.095),l(.025,.329),l(-2.332,-.006),l(-1.792,-.005),l(-.04,1.24),l(-.999,.032),l(.396,.223),l(.495,.541),l(.624,.231),l(.359,.69),l(.532,.223),l(-.211,.683),l(-1.762,-.007),l(-1.06,.007),l(-1.076,1.812),l(.305,.397),l(-.207,.238),l(.054,.553),l(.044,.454),l(-.704,-.555),l(-.952,-.888),l(-.956,-.761),l(-1.069,-.859),l(-.534,-.352),l(-.053,-.071),l(-.639,-.252),l(-1.048,-.21),l(-.657,.044),l(-.817,.397),l(-1.1,.567),l(-.756,.256),l(-.931,-.069),l(-.724,-.21),l(-.48,-.197),l(-1.305,-.195),l(-.588,-.267),l(-.644,-.422),l(-.935,-.521),l(-.785,-.267),l(-1.711,-.392),l(-.963,-.365),l(-.722,-.366),l(-1.074,-.436),l(-.592,-.352),l(-1.123,-1),l(-.207,-.07),l(-.606,.058),l(-.689,-.14),l(-1.835,-.575),l(-.565,-.536),l(-.503,-.634),l(-.495,-.395),l(-1.049,-.577),l(-.619,-.267),l(-.5,-.494),l(-.742,-.987),l(-.363,-.55),l(-.038,-.113),l(.15,-.155),l(.504,-.086),l(.18,-.17),l(.047,-.184),l(-.331,-.367),l(.457,-.679),l(.041,-.381),l(-.172,-.466),l(-.744,-.959),l(.121,-.297),l(.146,-.17),l(-.07,-.268),l(-.665,-.62),l(-1.495,-1.777),l(-.546,-.493),l(-.963,-1.058),l(-.474,-.522),l(-.815,-.578),l(-.322,-.197),l(-.158,-.268),l(-.058,-.48),l(-.144,-.183),l(-.329,-.197),l(-.609,-.197),l(-.408,-.31),l(-.366,-.522),l(-.271,-.028),l(-.414,.114),l(-.238,-.155),l(-.163,-.367),l(-.005,-.325),l(.459,-.736),l(-.126,-.339),l(-.751,-.62),l(-.439,.255),l(-.375,-.621),l(-.118,-.353),l(-.359,-.211),l(-.61,-.168),l(-.319,-.296),l(-.125,-.254),l(.05,-.381),l(.084,-.269),l(-.185,-.226),l(-.561,-.21),l(-.46,-.098),l(-.46,-.253),l(-.935,-.86),l(-.478,-.706),l(-.281,-.551),l(-.646,-.832),l(-.736,-1.073),l(-.184,-.423),l(-.38,-.678),l(-.242,-.338),l(-.152,-.452),l(.042,-.509),l(.032,-.311),l(-.56,-.239),l(-.795,-.196),l(-.06,-.452),l(-.128,-.155),l(-.458,-.183),l(-.289,.326),l(-.251,.043),l(-1.43,-.647),l(-.285,1.004),l(-.045,.438),l(.033,.084),l(.265,.339),l(.264,.296),l(.028,1.046),l(.088,.509),l(.51,.677),l(.143,.169),l(.643,.267),l(.601,.536),l(.525,.663),l(.602,1.214),l(.44,.282),l(.328,.042),l(.237,.169),l(.325,1.398),l(.102,.169),l(.246,.155),l(.497,.056),l(.133,.056),l(.215,.438),l(.161,.65),l(.445,.79),l(.49,-.071),l(.223,-.142),l(.245,.452),l(.344,1.469),l(.531,1.059),l(.649,1.2),l(.069,.593),l(-.014,.522),l(.26,.353),l(.378,.154),l(.389,-.17),l(.234,-.198),l(.588,.804),l(.258,.579),l(.464,.253),l(.281,.014),l(.133,.311),l(-.196,.537),l(-.136,.127),l(-.691,.595),l(-.254,-.042),l(-.251,-.409),l(-.24,-.734),l(-.617,-.578),l(-.625,-.309),l(-.516,-.479),l(-.834,-.507),l(-1.143,-.986),l(-.416,-.451),l(-.162,-.269),l(.216,-.989),l(-.035,-.254),l(-.488,-1.002),l(-.238,-.381),l(-.327,-.282),l(-.44,-.098),l(-.5,-.31),l(-.675,-.677),l(-.305,.142),l(-.363,-.056),l(-1.262,-.746),l(-.722,-.31),l(-.896,-.973),l(-.139,-.127),l(-.246,-.254),l(.679,.15),l(.599,.013),l(.588,-.284),l(.244,-.326),l(.093,-.636),l(-.01,-.184),l(-.458,-.635),l(-.466,-.452),l(-1.1,-.888),l(-.986,-.493),l(-.402,-.338),l(-.203,-.522),l(-.272,-.649),l(-.091,-.155),l(-.447,-.126),l(-.15,-.353),l(-.026,-.594),l(-.203,-.395),l(-.623,-.734),l(-.434,-.706),l(-.003,-.254),l(.212,-.382),l(-.777,-.62),l(-.254,-.325),l(-.22,-.485),l(.34,-.017),l(2.367,-.155),l(2.381,-.084),l(.316,.31),l(.267,.154),l(1.186,.39),l(2.811,.933),l(3.516,1.112),l(.338,.055),l(1.662,.019),l(1.544,.02),l(.966,.037),l(1.867,-.011),l(.213,-.101),l(.096,-.892),l(1.858,.003),l(1.892,.046),l(.209,.112),l(.631,.662),l(.766,.632),l(.837,.519),l(.708,.491),l(.179,.226),l(.284,.678),l(.318,.847),l(.445,.549),l(1.092,.659),l(1.104,.503),l(.337,.069),l(.501,.011),l(.416,-.158),l(.283,-.37),l(.418,-.413),l(.576,-.541),l(.468,-.201),l(.643,-.018),l(.475,.082),l(.783,.321),l(.412,.252),l(.363,.366),l(.663,1.029),l(.744,1.227),l(.845,1.042),l(.657,.576),l(.268,.253),l(.078,.467),l(.332,.932),l(.336,.592),l(.375,.365),l(.921,.32),l(1.029,.56),l(.264,.069),l(.416,-.116),l(.296,-.001),l(.816,.377),l(.347,.119),
+N(507.047,133.665),l(.055,.197),l(.134,.691),l(-.336,-.028),l(-.513,.513),l(.421,.194),l(.418,-.206),l(.306,.021),l(.698,1.84),l(-.644,.044),l(-1.07,-.05),l(-.185,-.239),l(-.334,-.619),l(-.408,-.054),l(-1.657,-.259),l(.521,-.568),l(.463,-.609),l(.343,-.693),l(.518,-.13),l(1.271,-.044),
+N(606.155,150.953),l(.595,.152),l(.255,.14),l(.25,-.129),l(.273,-.368),l(.015,-.678),l(-.152,-.93),l(.228,-.185),l(.401,-.144),l(.191,-.354),l(-.146,-1.594),l(.133,-.283),l(.811,.32),l(.391,.11),l(.309,.013),l(.17,-.128),l(1.148,-2.25),l(0,-.324),l(-.192,-.408),l(.045,-.212),l(.938,-1.134),l(.136,-.382),l(-.057,-.761),l(.197,-.354),l(1.446,-.883),l(.719,-.512),l(.312,-.129),l(.558,.082),l(.853,.221),l(.295,-.058),l(-.184,-.718),l(.072,-.283),l(.596,-.582),l(.112,-.24),l(.018,-.508),l(.001,-.127),l(.306,-.34),l(.277,-.044),l(.504,.279),l(.397,.435),l(.243,.901),l(.217,.309),l(.287,.041),l(.504,-.031),l(.146,.14),l(.195,1.649),l(.02,.875),l(-.353,.862),l(-.429,.722),l(-.611,.525),l(-.487,.271),l(-.191,.198),l(-.617,.85),l(.075,.465),l(.163,.705),l(-.224,.58),l(0,.268),l(.216,.069),l(.312,-.086),l(.819,-.442),l(.771,-.089),l(.479,-.017),l(.156,.126),l(.277,1.762),l(.202,.324),l(.554,-.074),l(.521,.096),l(.033,.268),l(-.729,1.584),l(.117,.352),l(.228,.098),l(.507,-.003),l(.481,-.045),l(.291,.379),l(.341,.746),l(.378,.266),l(.246,.083),l(.647,-.159),l(.628,-.413),l(.111,.38),l(.153,.239),l(-.502,.355),l(-.53,.61),l(-.442,.581),l(-.582,.455),l(-.193,.185),l(-.08,.085),l(-.158,.071),l(-.645,.06),l(-.436,.172),l(-.528,.342),l(-.394,.595),l(-1.078,.316),l(-.62,.018),l(-.474,-.082),l(-.362,.411),l(-.143,.368),l(-.036,.819),l(-.114,.509),l(.064,.409),l(-.086,.24),l(-.163,.001),l(-.588,.131),l(.739,.884),l(.069,.183),l(.112,.875),l(.254,.14),l(1.091,.953),l(.148,.324),l(.646,1.041),l(.163,.338),l(-.194,.241),l(-.451,.229),l(-.128,.226),l(.231,1.185),l(-.171,.198),l(-.812,.428),l(.178,.38),l(.6,1.436),l(.54,.477),l(.606,.604),l(.203,.479),l(.088,.663),l(-.086,.636),l(.006,.254),l(.488,1.183),l(.586,1.225),l(-.077,.297),l(-1.011,1.559),l(-1.01,1.7),l(-.098,.374),l(-.359,-.181),l(-.075,-.805),l(.461,-.665),l(.174,-.495),l(.122,-.777),l(.287,-.466),l(-.512,-.027),l(-.104,-.084),l(-.004,-.282),l(.195,-.509),l(-.177,-1.524),l(-.246,-.832),l(-.639,-1.185),l(-.488,-1.312),l(-.347,-.846),l(-.179,-.875),l(-.174,-1.736),l(-.117,-.677),l(-.034,-.564),l(-.051,-.212),l(-.344,-.084),l(-.148,-.098),l(-.304,-.917),l(-.516,-.677),l(-.226,-.225),l(-.247,.029),l(-.081,.988),l(-.158,.424),l(-.43,.41),l(-.59,.284),l(-1.089,.511),l(-.359,.622),l(-.298,.297),l(-.196,.142),l(-.237,-.282),l(-.007,-.438),l(-.212,.015),l(-.338,.354),l(-.321,-.013),l(-.166,-.211),l(.147,-.495),l(-.001,-.113),l(-.621,.171),l(-.276,.127),l(-.247,.283),l(-.355,-.126),l(-.002,-.466),l(.553,-1.54),l(.162,-.791),l(.001,-.889),l(-.101,-1.059),l(-.384,-.973),l(-.431,-1.072),l(-.196,-.296),l(-.281,.537),l(-.32,-.126),l(-.526,-.366),l(.482,-.17),l(.312,-.015),l(-.149,-.479),l(-.054,-.268),l(-.684,-.775),l(-.182,-.183),l(-.19,-.028),l(-.407,.1),l(-.38,-.267),l(.086,-.438),l(-.026,-.141),l(-.209,-.112),l(-.365,.043),l(-.577,-.465),l(-.504,-.606),l(-.117,-.244),l(.252,-.341),l(.801,-.527),l(-.194,-1.607),
+N(605.297,153.429),l(-.126,-.264),l(-.269,-.55),l(-.223,-1.213),l(-.611,-1.41),l(-.357,-.395),l(-.73,.354),l(-.393,0),l(-.034,-.084),l(-.242,-.211),l(-.356,-.592),l(-.124,-.042),l(-.152,.127),l(-.026,.537),l(.374,.79),l(-.006,.424),l(-.143,.169),l(-.455,.086),l(-.235,.537),l(-.261,.1),l(-.255,-.437),l(-.311,-.395),l(-.073,-.057),l(-.163,.669),l(-.28,.249),l(-.203,.043),l(-.271,-.536),l(-.495,.636),l(-.359,-.265),l(-.147,-.532),l(-.402,-1.775),l(-.325,-1.409),l(-.352,-.45),l(-.04,-.254),l(.505,-.765),l(.029,-.269),l(-.193,-.21),l(-1.042,-.431),l(-.339,-.323),l(.548,-.61),l(.4,-.299),l(.502,-.13),l(.382,-.101),l(.047,-.155),l(-.126,-.112),l(-1.224,-.938),l(-.494,-.237),l(-.083,-.155),l(.124,-.283),l(.555,-.525),l(.234,-.171),l(1.252,.303),l(.339,.266),l(.372,.266),l(.489,-.06),l(.417,.054),l(.129,.324),l(.053,.479),l(.079,.719),l(.095,.099),l(.537,.109),l(.547,.053),l(.916,-.062),l(.559,-.003),l(2.473,.198),l(.111,.098),l(.057,.127),l(-.012,.79),l(-.159,.34),l(-.938,.767),l(-.498,.13),l(-.651,.356),l(-.131,.283),l(.009,.522),l(.001,.381),l(.23,.281),l(.249,.267),l(.529,.448),l(.224,-.354),l(.395,-1.159),l(.281,-.115),l(.4,-.044),l(.064,.578),l(.627,2.479),l(.037,.466),l(.194,1.607),l(-.801,.527),l(-.252,.341),
+N(627.408,186.411),l(-.086,.337),l(-.495,.35),l(-.11,.575),l(-.644,.089),l(-.05,-.478),l(-.309,-.163),l(-.279,.28),l(-.244,.394),l(-.204,-.083),l(-.118,-.239),l(.213,-.398),l(-.041,-.21),l(-.055,-.226),l(-.261,-.238),l(-.447,-.119),l(-.106,-.466),l(-.571,.013),l(-.448,.17),l(.013,-.104),l(.128,-.297),l(-.15,-.183),l(-.411,.212),l(-.301,-.07),l(-.38,-.38),l(-.116,-.508),l(.064,-.282),l(-.151,-.438),l(-.229,-.169),l(-.388,.043),l(-.39,-.719),l(-.209,-.508),l(-.3,-.324),l(-.311,-.155),l(-.456,-.395),l(-.343,.1),l(-.218,.142),l(-.216,-.381),l(-.04,-.607),l(.163,-.749),l(.559,-1.738),l(.29,-.848),l(-.087,-.044),l(.098,-.374),l(1.01,-1.7),l(1.011,-1.559),l(.077,-.297),l(-.586,-1.225),l(-.488,-1.183),l(-.006,-.254),l(.086,-.636),l(-.088,-.663),l(-.203,-.479),l(-.606,-.604),l(-.54,-.477),l(-.6,-1.436),l(-.178,-.38),l(.812,-.428),l(.171,-.198),l(-.231,-1.185),l(.128,-.226),l(.451,-.229),l(.194,-.241),l(-.163,-.338),l(-.646,-1.041),l(-.148,-.324),l(-1.091,-.953),l(-.254,-.14),l(-.112,-.875),l(-.069,-.183),l(-.739,-.884),l(.588,-.131),l(.163,-.001),l(.086,-.24),l(-.064,-.409),l(.114,-.509),l(.036,-.819),l(.143,-.368),l(.362,-.411),l(.474,.082),l(.62,-.018),l(1.078,-.316),l(.394,-.595),l(.528,-.342),l(.436,-.172),l(.645,-.06),l(.158,-.071),l(.08,-.085),l(.541,.166),l(.295,.182),l(.118,.168),l(.01,.423),l(-.106,.805),l(.066,.367),l(.186,.154),l(.423,-.003),l(.489,-.2),l(.414,-.045),l(.045,.113),l(.249,1.311),l(-.085,.41),l(-.528,1.569),l(-.117,.438),l(-.027,.494),l(.145,.324),l(.481,.138),l(.37,-.411),l(1.173,-1.178),l(.346,-.03),l(.835,.348),l(.59,.265),l(.223,-.072),l(.543,-.257),l(.2,-.538),l(.286,-.453),l(.403,.012),l(.893,.192),l(.266,.153),l(.052,.282),l(.285,.535),l(.688,.659),l(.435,.632),l(.058,1.524),l(.107,.366),l(.255,.464),l(.979,1.279),l(.419,.703),l(.157,.507),l(.002,.945),l(-.121,.438),l(-.808,.64),l(-.301,-.167),l(-.599,-.109),l(-.575,-.039),l(-.558,.074),l(-.798,-.066),l(-1.172,.091),l(-.383,.101),l(-.521,.441),l(-.92,1.233),l(-.146,.297),l(-.076,.382),l(.026,.635),l(.219,.648),l(.487,.717),l(.16,.479),l(-.146,.176),l(-.026,-.063),l(-.286,-.183),l(-.458,-.084),l(-.9,-.887),l(-.434,-.154),l(-.304,-.014),l(-.572,.227),l(-.391,-.112),l(-.29,-.141),l(-.337,-.014),l(0,-.282),l(.19,-1.243),l(-.107,-.184),l(-.719,-.055),l(-.248,-.084),l(-.521,.043),l(-.443,.212),l(-.244,.297),l(.207,.593),l(-.103,.339),l(-.318,.707),l(.083,.579),l(.054,.41),l(-.293,.664),l(-.583,1.187),l(-.7,1.682),l(-.255,1.314),l(.104,1.171),l(.172,.296),l(.229,.169),l(.55,-.072),l(.396,-.142),l(.252,.07),l(.135,.353),l(.009,.325),l(-.08,.466),l(.141,.282),l(.178,.211),l(.271,-.094),l(.17,.46),l(.209,.974),l(-.032,.254),l(.127,.737),l(.434,.871),l(.167,.155),l(.801,.281),l(.539,.112),l(.467,-.058),l(.294,.197),l(.266,.612),l(.664,.544),l(.212,.145),
+N(204.31,158.989),l(-.175,.412),l(.612,-.173),l(.026,.429),l(-.419,1.241),l(.178,.269),l(-.237,.795),l(.189,.318),l(-.092,.397),l(-.358,.875),l(-.3,.35),l(-.36,.032),l(-.054,.286),l(-.388,.238),l(0,.286),l(-.69,.016),l(.215,-4.297),l(-.025,-.329),l(.278,-.095),l(.386,.27),l(.599,-.857),l(.178,-.447),l(.437,-.016),
+N(200.276,169.481),l(-.151,-.056),l(-.928,-.342),l(-.614,.032),l(-.766,-.032),l(-.608,-.239),l(-.909,-.656),l(-.513,-.419),l(-.044,-.454),l(-.054,-.553),l(.207,-.238),l(-.305,-.397),l(1.076,-1.812),l(1.06,-.007),l(1.762,.007),l(.211,-.683),l(-.532,-.223),l(-.359,-.69),l(-.624,-.231),l(-.495,-.541),l(-.396,-.223),l(.999,-.032),l(.04,-1.24),l(1.792,.005),l(2.332,.006),l(-.215,4.297),l(.69,-.016),l(.303,.095),l(.311,.302),l(.14,-.191),l(-.066,-.381),l(.336,.157),l(.458,.367),l(-1.507,1.208),l(-.499,.238),l(-.177,.493),l(.162,.604),l(-.438,.302),l(-.467,.048),l(-.043,.254),l(.164,.159),l(-.351,.111),l(-.184,.302),l(-.22,-.016),l(-.565,.461),l(-.012,.223),
+N(204.413,165.093),l(.312,-.03),l(.612,-.27),l(.639,-.058),l(.743,.126),l(.478,.069),l(1.443,.04),l(.699,-.228),l(.379,-.199),l(.567,.267),l(.788,-.03),l(.763,-.101),l(.63,-.001),l(.5,.126),l(.564,.253),l(-.038,.353),l(-.102,.226),l(.228,.282),l(.787,.238),l(.557,.069),l(.244,.524),l(-1.425,.486),l(-.424,.229),l(-.248,.086),l(-.463,-.097),l(-.328,-.182),l(-.259,-.013),l(-.294,.242),l(-.503,.794),l(-1.207,.997),l(-.725,-.42),l(-.513,.583),l(-.882,.034),l(-.005,.961),l(-.293,.412),l(-.29,.143),l(-1.001,.125),l(-.311,-.661),l(-.025,-.085),l(-.478,-.3),l(.085,-.731),l(-.128,-.175),l(-.272,0),l(-.541,-.276),l(-.433,.34),l(-.365,-.016),l(-.066,-.271),l(-.565,-.35),l(-.409,-.08),l(-.208,-.418),l(-.677,-.17),l(.438,-.302),l(-.162,-.604),l(.177,-.493),l(.499,-.238),l(1.507,-1.208),
+N(205.532,170.085),l(.035,.076),l(-.203,.057),l(.01,.265),l(-.237,.334),l(-.68,-.046),l(-.853,-.139),l(-1.697,-.505),l(-1.305,-.435),l(-.325,-.21),l(.012,-.223),l(.565,-.461),l(.22,.016),l(.184,-.302),l(.351,-.111),l(-.164,-.159),l(.043,-.254),l(.467,-.048),l(.677,.17),l(.208,.418),l(.409,.08),l(.565,.35),l(.066,.271),l(.365,.016),l(.433,-.34),l(.541,.276),l(.272,0),l(.128,.175),l(-.085,.731),
+N(242.38,173.617),l(-.128,-.105),l(-.84,.171),l(-.534,.156),l(-.414,.2),l(-.056,.288),l(.048,.497),l(-.129,.396),l(-.227,-.027),l(-.381,.059),l(-.99,1.758),l(-.172,.722),l(-.241,.722),l(-.709,1.191),l(.402,.025),l(.234,-.1),l(.384,-.017),l(.31,.606),l(.855,1.45),l(.103,.395),l(-.226,1.132),l(.099,.353),l(.401,.309),l(.429,.548),l(.397,.252),l(.496,-.017),l(1.163,-.12),l(1.167,-.05),l(.521,.181),l(.64,.321),l(.188,.253),l(.847,.998),l(.554,.576),l(.144,0),l(.522,-.13),l(.76,-.174),l(1.99,-.224),l(.644,.081),l(-.409,.525),l(-.085,1.004),l(-.379,.511),l(-.147,.326),l(.026,.254),l(.035,.438),l(.048,.367),l(.162,.804),l(.447,.789),l(.256,.437),l(.486,.647),l(.121,.282),l(-.731,.612),l(-.479,.526),l(.51,.491),l(.797,1.182),l(-.52,.286),l(-.834,.57),l(-.412,.158),l(-.463,.017),l(-2.812,-.082),l(-.64,-.024),l(-.042,.325),l(-.013,1.031),l(.178,.154),l(.896,.122),l(.177,.084),l(.293,.408),l(.052,.367),l(-.384,-.04),l(-.417,-.11),l(-.687,.032),l(-.493,.187),l(-.111,.085),l(-.001,1.071),l(0,.554),l(.192,.197),l(.688,.363),l(.192,.183),l(-.031,.777),l(.399,.562),l(.031,.212),l(-.326,1.428),l(-.706,4.411),l(-.073,.382),l(-.133,.198),l(-.156,-.14),l(-.575,-.703),l(-.237,-.126),l(-.161,.058),l(-.448,.031),l(1.155,-1.956),l(.035,-.198),l(-.127,-.069),l(-1.299,-.84),l(-.509,-.209),l(-.708,.442),l(-.397,-.182),l(-.523,-.421),l(-.452,.427),l(-.337,.157),l(-.496,.031),l(-1.038,-.008),l(-.573,-.152),l(-.092,-.281),l(.004,-.396),l(-.173,-.296),l(-.479,-.039),l(-.366,-.14),l(-.078,-.282),l(-.251,-.761),l(-.988,-.672),l(-.526,-.364),l(-.208,-.62),l(-.208,-.324),l(-.513,-.435),l(-.897,-.418),l(-.927,-.107),l(-.081,-.112),l(-.269,-.162),l(-.197,-.118),l(-.709,-.631),l(-.128,-.056),l(-.89,.401),l(-.67,.061),l(-.977,-.277),l(-.355,-.309),l(-.166,-.493),l(-.227,-.225),l(-1.432,-.656),l(-1.496,-.803),l(.033,-.068),l(-.117,-.311),l(-.181,-.282),l(.108,-.212),l(.509,-.114),l(.465,.112),l(.186,-.325),l(-.348,-.564),l(.086,-.424),l(.314,-.227),l(.878,-.058),l(.193,.042),l(.41,-.227),l(.445,-.679),l(.45,-.961),l(.651,-1.061),l(-.122,-.268),l(-.56,-.408),l(-.071,-.184),l(.306,-.721),l(.089,-.523),l(-.149,-.861),l(-.371,-.86),l(.085,-.254),l(.49,-.143),l(.135,-.212),l(-.088,-.198),l(-.565,-.479),l(-.042,-.226),l(.103,-.198),l(.242,-.326),l(.036,-.254),l(-.173,-.282),l(-.739,-.719),l(-.364,-.396),l(.256,-.753),l(.228,-.082),l(-.045,-.45),l(.19,.082),l(.085,.307),l(.584,-.409),l(.094,-.43),l(.322,-.062),l(-.509,-1.038),l(-.228,-.149),l(-.084,-.327),l(.142,.075),l(.42,.338),l(.397,.507),l(.22,.508),l(.235,.197),l(.199,-.17),l(.147,-.241),l(-.332,-.776),l(.02,-.212),l(.176,-.297),l(.445,-.34),l(.399,-.297),l(.501,-.736),l(.327,-.156),l(.684,-.101),l(.217,-.382),l(-.104,-.381),l(.174,-.777),l(.067,-.65),l(.207,-.48),l(.498,-.439),l(.429,-.283),l(.592,-.242),l(.113,0),l(.374,.206),l(.22,.443),l(.281,-.34),l(.031,-.438),l(.199,-.551),l(.22,-.071),l(.267,.126),l(.855,.041),l(.562,-.001),l(.623,-.27),l(.237,-.254),l(.476,-.298),l(.848,-.256),l(.435,-.396),l(.278,-.551),l(.333,-.255),l(.469,-.17),l(.58,.013),l(.526,.338),l(.155,.126),l(.155,.339),l(-.285,.332),
+N(408.6,174.04),l(-.062,.777),l(.164,.762),l(.388,.718),l(-.316,.962),l(-.19,.566),l(-.223,.298),l(-.656,.414),l(-.095,.34),l(.116,.592),l(-.078,.368),l(-.433,.13),l(-.257,.03),l(-.237,.397),l(.002,.381),l(.003,.48),l(-.012,.876),l(-.09,.989),l(.217,1.439),l(-.121,1.188),l(.006,.234),l(-.333,.015),l(-1.232,.144),l(-.669,.052),l(-.106,-.205),l(-.295,-1.072),l(.188,-.708),l(.026,-.833),l(-.036,-.537),l(-.135,-.974),l(-.006,-.862),l(-.035,-.522),l(.013,-.579),l(-.442,-1.311),l(-.164,-.691),l(-.403,-.323),l(-.468,-.294),l(-.18,-.395),l(.141,-.594),l(.046,-.424),l(.062,-.142),l(.24,-.157),l(.366,-.553),l(.415,-.271),l(.418,-.045),l(.739,.095),l(.337,-.158),l(.415,-.468),l(.237,-.764),l(-.131,-.367),l(.577,-.3),l(.321,-.073),l(.339,.28),l(.727,.589),l(.902,.503),
+N(394.266,178.814),l(.191,-.17),l(-.02,-.41),l(-.261,-1.934),l(.125,-.34),l(.271,-.157),l(2.119,-.041),l(.867,.037),l(1.429,.006),l(.976,-.458),l(.161,.032),l(.595,.119),l(-.25,.849),l(.05,.254),l(.633,.915),l(.244,.451),l(-.188,.721),l(.02,.396),l(.265,1.114),l(.181,.592),l(.503,.788),l(.032,.155),l(-.286,.242),l(-.174,.382),l(.01,1.314),l(-.011,.72),l(.021,.551),l(.18,.479),l(.468,.577),l(.752,.608),l(-.503,.682),l(-.304,.099),l(-.593,-.013),l(-.992,.144),l(-.463,.185),l(-.188,.098),l(-.898,.469),l(-1.263,.398),l(-.942,.412),l(-.958,.567),l(-.578,-.324),l(-.945,-.436),l(-.074,-.124),l(-.066,-.741),l(-.554,-1.155),l(-.263,-.747),l(-.103,-.706),l(.327,-1.005),l(.437,-1.274),l(.521,-.851),l(.203,-.595),l(-.334,-1.438),l(-.189,-1.285),l(-.178,-.154),
+N(400.72,175.499),l(1.013,.163),l(.611,.166),l(.29,.041),l(-.046,.424),l(-.141,.594),l(.18,.395),l(.468,.294),l(.403,.323),l(.164,.691),l(.442,1.311),l(-.013,.579),l(.035,.522),l(.006,.862),l(.135,.974),l(.036,.537),l(-.026,.833),l(-.188,.708),l(.295,1.072),l(.106,.205),l(-.452,.035),l(-.479,.128),l(-.368,.212),l(-.023,.04),l(-.752,-.608),l(-.468,-.577),l(-.18,-.479),l(-.021,-.551),l(.011,-.72),l(-.01,-1.314),l(.174,-.382),l(.286,-.242),l(-.032,-.155),l(-.503,-.788),l(-.181,-.592),l(-.265,-1.114),l(-.02,-.396),l(.188,-.721),l(-.244,-.451),l(-.633,-.915),l(-.05,-.254),l(.25,-.849),
+N(383.772,190.418),l(.041,-.919),l(.105,-.565),l(.247,-.849),l(.059,-.452),l(-.131,-.282),l(-1.264,-1.334),l(-.592,.032),l(-.369,-.097),l(-.194,-.183),l(-.05,-.183),l(.501,-.865),l(.059,-.438),l(-.119,-.55),l(.062,-.17),l(.047,-.099),l(.602,-.554),l(.188,-.354),l(-.179,-.21),l(-.296,-.549),l(.03,-.127),l(.158,-.199),l(.304,-.03),l(.548,.223),l(.304,.012),l(.19,-.143),l(-.051,-.226),l(-.648,-.561),l(-.309,-.351),l(.332,-.37),l(.125,-.283),l(-.197,-.31),l(-.695,-.405),l(-.214,-.409),l(.264,-.623),l(.379,-.397),l(.522,-.54),l(.352,-.059),l(.566,.321),l(.455,.436),l(.35,-.228),l(.362,-.469),l(.571,-.483),l(.239,-.114),l(.257,.041),l(.147,.211),l(.004,.297),l(.117,.381),l(.148,.239),l(.352,-.059),l(.604,-.399),l(.159,-.1),l(.259,.168),l(.545,-.003),l(.308,.252),l(.15,.465),l(.52,.562),l(.452,.223),l(.354,.083),l(.368,-.115),l(.446,-.257),l(.608,-.159),l(.769,-.075),l(.644,.166),l(.63,.434),l(.178,.154),l(.189,1.285),l(.334,1.438),l(-.203,.595),l(-.521,.851),l(-.437,1.274),l(-.327,1.005),l(.103,.706),l(.263,.747),l(.554,1.155),l(.066,.741),l(-.119,-.201),l(-.289,-.197),l(-.208,.015),l(-.143,.24),l(-.096,.042),l(-.48,-.027),l(-.705,-.167),l(-.608,-.083),l(-2.352,.062),l(-1.279,.243),l(-.575,.199),l(-1.07,.369),l(-1.739,.781),l(-.701,.425),l(-.256,-.013),l(-.075,-.032),
+N(627.408,186.411),l(.035,.024),l(.523,.098),l(1.061,1.198),l(.693,.916),l(.506,.762),l(.081,.579),l(-.023,.805),l(-.134,.862),l(.07,1.073),l(-.07,.636),l(.097,.494),l(.196,.381),l(.53,.493),l(.338,.536),l(.705,1.608),l(.062,.127),l(-.366,-.069),l(-.895,-.055),l(-.401,.142),l(-.175,-.07),l(-.521,-.437),l(-.885,-.605),l(-.6,-.337),l(-1.231,-.675),l(-1.02,-.732),l(-.217,-.254),l(-.16,-.988),l(-.438,-.691),l(-.895,-.817),l(-.195,-.663),l(.039,-.494),l(.03,-.283),l(-.107,-.409),l(-.399,-.634),l(-.347,-1.849),l(-.188,-.72),l(.043,-.362),l(.448,-.17),l(.571,-.013),l(.106,.466),l(.447,.119),l(.261,.238),l(.055,.226),l(.041,.21),l(-.213,.398),l(.118,.239),l(.204,.083),l(.244,-.394),l(.279,-.28),l(.309,.163),l(.05,.478),l(.644,-.089),l(.11,-.575),l(.495,-.35),l(.086,-.337),M(643.95,196.042),l(.081,.044),l(.375,.408),l(.397,.141),l(.861,.083),l(.413,.168),l(.761,.436),l(.335,.042),l(.337,-.1),l(-.503,-.535),l(.169,-.551),l(.365,-.608),l(.528,-1.258),l(.584,-.27),l(1.481,-.342),l(1.018,-.299),l(.428,-.326),l(.524,-1.021),l(.523,-.323),l(.87,-1.117),l(.22,-.212),l(.244,-.147),l(.112,-.068),l(.084,.126),l(.062,.37),l(.234,-.012),l(.111,.259),l(.309,.271),l(.383,-.271),l(1.234,-.42),l(-.025,-.086),l(-.197,-.197),l(.013,-.247),l(.024,-.111),l(-.148,-.444),l(-.11,-.174),l(.167,-.042),l(.188,.143),l(.085,-.016),l(.449,-.084),l(.161,-.283),l(-.036,-.24),l(-.478,-.366),l(.197,-.396),l(.436,-.071),l(.511,.041),l(.154,-.605),l(.408,-.313),l(.284,-.48),l(.531,-.58),l(.498,-1.032),l(.075,-.17),l(.322,.465),l(.33,.098),l(.315,-.424),l(.305,.494),l(.351,.282),l(.402,.211),l(.075,.338),l(-.182,.354),l(-.234,.452),l(.037,.198),l(.631,-.128),l(.472,-.128),l(.115,.226),l(-.349,.495),l(.742,-.1),l(.357,-.085),l(.269,.056),l(1.035,.662),l(.345,.14),l(.1,.24),l(-.158,.269),l(-.201,.155),l(-.44,.143),l(-.594,.029),l(-.683,-.083),l(-.355,.311),l(.096,.254),l(.888,.69),l(-.161,.311),l(-.458,.199),l(-.646,.1),l(-.518,.114),l(-.067,.15),l(-.182,-.09),l(-.753,-.292),l(-.446,-.04),l(-.624,.018),l(-.651,-.081),l(-.748,-.081),l(-.464,.017),l(-.247,.157),l(-.381,.638),l(-.119,.565),l(.106,.988),l(-.22,.383),l(-.646,.244),l(-.218,.34),l(.076,.748),l(-.928,1.785),l(-.387,.299),l(-.864,.175),l(-.465,.172),l(-.467,.356),l(-.287,.03),l(-.559,-.152),l(-.524,-.223),l(-.557,-.251),l(-.431,-.11),l(-.479,.074),l(-.531,.441),l(-.403,.525),l(-.528,.342),l(-.399,.172),l(-.543,-.11),l(-.526,-.223),l(-.255,.001),l(-.928,.416),l(-.446,-.28),l(-.304,-.083),l(-1,-.983),l(-.253,-.295),l(-.288,-.792),
+N(274.556,195.884),l(.06,-.212),l(-.332,-.563),l(-.49,-1.127),l(-.246,-.832),l(-.185,-.295),l(-.561,-.067),l(-.532,-.675),l(-.571,-.831),l(.328,-.694),l(.095,-.467),l(-.078,-.777),l(.169,-.17),l(1.131,-.091),l(.183,-.27),l(.082,-.862),l(.142,-.496),l(.015,-.339),l(.326,-.312),l(.382,-.057),l(1.392,.463),l(.465,.042),l(.083,-.41),l(.141,-.085),l(.337,.027),l(.833,.012),l(.863,-.03),l(.723,.069),l(.63,.182),l(.999,.427),l(-.647,.876),l(-.391,.751),l(-.137,.594),l(.094,.381),l(.134,.635),l(.086,.664),l(.521,.844),l(.029,.438),l(-.424,1.472),l(-.489,.963),l(-1.05,-.488),l(-.319,.001),l(-.534,.385),l(-.398,.059),l(-.418,-.139),l(-.642,-.124),l(-.172,.156),l(-.2,.326),l(.611,1.014),l(-.528,-.054),l(-1.108,-.276),l(-.4,-.04),
+N(285.859,190.719),l(.015,.422),l(-1.102,1.646),l(-.427,.765),l(-.439,.992),l(-.464,.681),l(-.299,.214),l(-.56,-.025),l(-1.11,-.389),l(-.882,.613),l(-.225,-.069),l(-.649,-.505),l(.489,-.963),l(.424,-1.472),l(-.029,-.438),l(-.521,-.844),l(-.086,-.664),l(-.134,-.635),l(-.094,-.381),l(.137,-.594),l(.391,-.751),l(.647,-.876),l(.218,.093),l(1.033,.294),l(.55,.196),l(.799,.549),l(1.264,1.084),l(.545,.564),l(.317,.465),l(.193,.028),
+N(429.505,210.684),l(-.695,-.533),l(-.351,.13),l(-.68,.513),l(-.536,.414),l(-.112,-.177),l(-.392,-.86),l(-1.381,-1.344),l(.184,-.295),l(.413,-.229),l(.803,.307),l(.343,-.681),l(-.052,-.296),l(-.274,-.253),l(-.39,-.521),l(-.116,-.366),l(.058,-.495),l(.127,-.1),l(.909,-.146),l(.604,-.243),l(.125,-.213),l(.167,-.807),l(.174,-.185),l(.239,-.029),l(.193,.14),l(.341,.479),l(.405,.521),l(.386,.195),l(.287,-.016),l(.188,-.228),l(.362,-.482),l(.29,.253),l(.167,.578),l(.146,.112),l(.304,.068),l(.255,-.114),l(.184,-.68),l(.243,-1.089),l(.131,-1.229),l(.229,-1.047),l(-.114,-.338),l(-.161,-.127),l(-.384,-.082),l(-.528,-.208),l(-.242,-.31),l(-.132,-.437),l(.008,-.109),l(.021,-.3),l(.157,-.284),l(.492,-.398),l(.556,-.441),l(.094,-.354),l(-.389,-.902),l(-.369,-.322),l(-.592,-.067),l(-.939,.5),l(-.463,-.025),l(-.146,-.253),l(-.068,-.734),l(.077,-.679),l(.396,-.468),l(.56,.109),l(.863,.023),l(.878,-.076),l(.271,.055),l(.479,.04),l(.56,.124),l(.576,.194),l(.864,.334),l(.863,.292),l(.271,-.086),l(-.1,-.861),l(.159,-.185),l(.303,-.312),l(.365,-.497),l(.158,-.523),l(.222,-1.287),l(.255,-.228),l(.479,-.102),l(.975,-.175),l(.367,.054),l(.624,.138),l(.895,.093),l(.751,-.287),l(.128,.197),l(-.031,.156),l(-.398,1.203),l(-.558,.837),l(-.349,.821),l(-.094,.551),l(-.156,.764),l(-.196,2.021),l(-.254,1.342),l(-.115,.61),l(-.169,.708),l(-.139,.523),l(-.459,.427),l(-.525,.229),l(-.809,.599),l(-.41,.454),l(-.47,.836),l(-.343,.751),l(-.193,1.159),l(-.074,.396),l(.122,.72),l(-.086,.706),l(-1.025,.938),l(-.364,.229),l(-.931,.811),l(-.554,.399),l(-.57,.328),l(-.147,-.211),l(-.042,-.664),l(-.054,-.424),l(-1.495,.532),l(-.327,.581),l(-.443,.271),l(-.177,-.013),l(-.484,-.336),
+N(425.506,195.522),l(.045,-.495),l(.88,.093),l(1.773,.088),l(.831,.038),l(1.022,.149),l(-.396,.468),l(-.077,.679),l(.068,.734),l(.146,.253),l(.463,.025),l(.939,-.5),l(.592,.067),l(.369,.322),l(.389,.902),l(-.094,.354),l(-.556,.441),l(-.492,.398),l(-.157,.284),l(-.021,.3),l(-.008,.109),l(.132,.437),l(.242,.31),l(.528,.208),l(.384,.082),l(.161,.127),l(.114,.338),l(-.229,1.047),l(-.131,1.229),l(-.243,1.089),l(-.184,.68),l(-.255,.114),l(-.304,-.068),l(-.146,-.112),l(-.167,-.578),l(-.29,-.253),l(-.362,.482),l(-.188,.228),l(-.287,.016),l(-.386,-.195),l(-.405,-.521),l(-.341,-.479),l(-.193,-.14),l(-.239,.029),l(-.174,.185),l(-.167,.807),l(-.125,.213),l(-.604,.243),l(-.909,.146),l(-.127,.1),l(-.058,.495),l(.116,.366),l(.39,.521),l(.274,.253),l(.052,.296),l(-.343,.681),l(-.803,-.307),l(-.413,.229),l(-.184,.295),l(-.038,-.037),l(-.563,-.493),l(-.532,-.55),l(-.259,-.466),l(-1.318,-1.169),l(.286,-.312),l(-.369,-.281),l(-.528,-.056),l(-.918,-1.438),l(.382,-.297),l(.111,-.1),l(-.321,-.395),l(-.464,-.14),l(-.29,-.564),l(-.369,-.451),l(.319,-.17),l(.541,-.411),l(.223,-.396),l(.291,-.976),l(.089,-.295),l(.415,.07),l(.495,.013),l(-.064,-.211),l(-.56,-.352),l(-.561,-.451),l(.208,-.042),l(.271,-.128),l(.142,-.617),l(.83,-.043),l(.927,.008),l(1.245,.021),l(.575,-.032),l(-.001,-.155),l(-.02,-.551),l(-.026,-1.836),
+N(422.536,195.513),l(1.005,-.007),l(1.965,.017),l(.026,1.836),l(.02,.551),l(.001,.155),l(-.575,.032),l(-1.245,-.021),l(-.927,-.008),l(-.83,.043),l(.033,-.146),l(-.049,-.297),l(-.144,-.084),l(-.416,-.098),l(.287,-.467),l(.447,-.523),l(.335,-.58),l(.066,-.403),M(419.636,193.273),l(-.484,-.049),l(-.049,-.218),l(.049,-.291),l(.242,-.097),l(.024,-.146),l(0,-.291),l(.17,-.097),l(.169,-.121),l(.219,.048),l(.218,.048),l(.097,.194),l(-.193,.169),l(-.146,.243),l(-.17,.339),l(-.146,.267),
+N(222.291,207.801),l(.188,-.126),l(.264,-.312),l(.585,-1.061),l(.038,-.269),l(-.209,-.733),l(.058,-.391),l(-.478,.617),l(-.732,.623),l(-.333,-.098),l(-.601,-.324),l(-.408,-.408),l(.389,-.283),l(.1,-.24),l(-.167,-.579),l(.005,-.438),l(.133,-.466),l(-.109,-.282),l(-.362,-.649),l(.193,-.17),l(.48,-.198),l(.721,-.454),l(-.319,-.395),l(0,-.226),l(.175,-.354),l(.497,-.462),l(.157,-.146),l(.14,-.848),l(-.116,-.452),l(-.082,-.184),l(.11,-.226),l(.686,-.101),l(.891,-.341),l(.396,-.241),l(.474,-.382),l(.09,-.186),l(1.496,.803),l(1.432,.656),l(.227,.225),l(.166,.493),l(.355,.309),l(.977,.277),l(.67,-.061),l(.89,-.401),l(.128,.056),l(.709,.631),l(.197,.118),l(.269,.162),l(.081,.112),l(.387,.76),l(.321,.789),l(-.08,.255),l(-.352,.384),l(-.547,1.147),l(-.533,.779),l(-.71,.725),l(-1.001,.755),l(-.336,.087),l(-1.028,.303),l(-.901,.358),l(-.809,.499),l(-.59,.653),l(-.284,.51),l(-.987,2.506),l(-.267,.312),l(-.242,.072),l(-.398,-.068),l(-.398,-.491),l(-.191,-.479),l(-.312,-.252),l(-.815,.005),l(-.444,-.11),l(-.105,-.197),l(-.097,-.494),l(.233,-.34),l(.029,-.495),l(.005,-.569),
+N(245.934,224.314),l(1.109,1.843),l(.922,1.646),l(.08,.24),l(-.437,.736),l(-.15,.523),l(-.143,.848),l(.057,.522),l(.236,.902),l(-.156,.34),l(-.221,.34),l(-.532,.582),l(-.102,.452),l(.347,.845),l(-.21,.368),l(-.159,.34),l(.022,.48),l(.604,1.168),l(.015,.522),l(-.285,.439),l(-.723,.61),l(-.12,.227),l(.049,.48),l(.132,.295),l(.018,.142),l(-.586,.187),l(-.15,.199),l(-.228,.933),l(-.259,.298),l(-.852,.275),l(-.201,-.517),l(-.289,-.31),l(-1.422,-.618),l(-.313,-.239),l(-.233,-.678),l(-.315,-.38),l(-.559,-.225),l(-.504,-.281),l(-.489,-.254),l(-.616,-.309),l(-.873,-.464),l(-.673,-.366),l(-.866,-.379),l(-.838,-.337),l(-1.271,-.845),l(-1.354,-.985),l(-1.232,-1.099),l(-.594,-.705),l(-.42,-.677),l(.008,-.438),l(0,-.903),l(-.269,-.606),l(-.781,-1.043),l(-1.389,-2.778),l(-.285,-.268),l(-.467,-.211),l(-.074,-.085),l(.055,-.536),l(-.02,-.396),l(-.149,-.396),l(-1.208,-2.199),l(-.997,-1.961),l(-.688,-1.27),l(-1.365,-1.917),l(-.272,-.353),l(-.598,-.973),l(-.462,-.423),l(-.75,-.437),l(-.914,-.365),l(-.61,-.365),l(.119,-.17),l(.181,-.113),l(.609,-.029),l(.144,-.41),l(-.118,-.282),l(-.592,-.874),l(-.353,-.437),l(-.258,-.72),l(.01,-.24),l(.244,-.523),l(.582,-.622),l(1.02,-.878),l(.47,-.198),l(.317,-.214),l(-.005,.569),l(-.029,.495),l(-.233,.34),l(.097,.494),l(.105,.197),l(.444,.11),l(.815,-.005),l(.312,.252),l(.191,.479),l(.398,.491),l(.398,.068),l(.242,-.072),l(.267,-.312),l(.987,-2.506),l(.284,-.51),l(.59,-.653),l(.809,-.499),l(.901,-.358),l(1.028,-.303),l(.336,-.087),l(1.001,-.755),l(.71,-.725),l(.533,-.779),l(.547,-1.147),l(.352,-.384),l(.08,-.255),l(-.321,-.789),l(-.387,-.76),l(.927,.107),l(.897,.418),l(.513,.435),l(.208,.324),l(.208,.62),l(.526,.364),l(.988,.672),l(.251,.761),l(.078,.282),l(.366,.14),l(.479,.039),l(.173,.296),l(-.004,.396),l(.092,.281),l(.573,.152),l(1.038,.008),l(.496,-.031),l(.337,-.157),l(.452,-.427),l(.523,.421),l(.397,.182),l(.708,-.442),l(.509,.209),l(1.299,.84),l(.127,.069),l(-.035,.198),l(-1.155,1.956),l(.448,-.031),l(.161,-.058),l(.237,.126),l(.575,.703),l(.156,.14),l(.136,.324),l(-.341,.186),l(-.793,-.235),l(-.493,-.096),l(-.322,.072),l(-.604,.441),l(-.371,.115),l(-.669,-.066),l(-1.895,.773),l(-.701,.442),l(-.372,.172),l(-.599,1.415),l(-.319,.511),l(-.021,.155),l(.277,.86),l(.012,.112),l(-.625,.498),l(-.62,.328),l(-.349,.342),l(-.247,.622),l(.106,.564),l(.619,.957),l(1.333,2.166),l(.106,.127),l(-.247,.495),l(-.208,.312),l(1.085,.12),l(.415,.04),l(.312,.182),l(.241,.323),l(.096,.663),l(1.843,.032),l(.762,-.499),l(.648,-.484),l(.326,-.114),l(-.059,1.511),l(-.098,1.173),l(.108,.353),l(.317,.337),l(.285,.068),l(.358,-.072),l(.786,-.259),l(.42,-.045),
+N(279.288,257.295),l(-.063,-.423),l(.027,-.777),l(.222,-.819),l(.298,-.835),l(.321,-.75),l(-.019,-.141),l(-.491,-.336),l(-.234,-.112),l(-1.29,.445),l(-.224,-.055),l(-.254,-.563),l(-.487,-2.524),l(-.121,-.437),l(-.843,-.404),l(-.724,-.278),l(-.115,.001),l(-.709,.413),l(-.346,.03),l(-.925,-.221),l(-.818,-.15),l(-.372,-.04),l(.006,-.72),l(.086,-.721),l(.132,-.862),l(-.104,-.959),l(-.521,-.872),l(-.084,-.663),l(-.253,-.408),l(.421,-.666),l(.38,-.765),l(.238,-.834),l(.185,-1.173),l(-.022,-.494),l(-.307,-.774),l(-.316,-.479),l(-.73,-.362),l(-.436,-.407),l(-.067,-.563),l(.261,-.835),l(-.042,-.296),l(-.693,-.024),l(-1.615,-.019),l(-.5,-.012),l(-.967,-.036),l(-.153,-.112),l(-.249,-.944),l(-.138,-2.032),l(-.03,-.706),l(-.203,-1.029),l(.038,-.565),l(-.085,-.169),l(-.403,-.237),l(-.537,-.166),l(-.636,-.123),l(-1.148,.077),l(-.22,-.084),l(-.398,-.308),l(-.385,-.774),l(-.096,-.014),l(-.882,-.037),l(-.3,-.098),l(-.75,-.603),l(-.688,-.307),l(-.676,-.25),l(-.355,.03),l(-.787,-.023),l(-.316,-.097),l(-1.1,-.939),l(-.813,-.928),l(-.335,-.591),l(-.141,-.635),l(-.036,-.818),l(.064,-.622),l(.079,-.621),l(-.045,-.748),l(-1.283,-.021),l(-.934,.076),l(-.36,.158),l(-.874,.485),l(-1.471,1.109),l(-.415,.243),l(-.48,-.025),l(-.336,-.026),l(-.946,.824),l(-.355,.03),l(-1.122,-.304),l(-.939,-.136),l(-.42,.045),l(-.786,.259),l(-.358,.072),l(-.285,-.068),l(-.317,-.337),l(-.108,-.353),l(.098,-1.173),l(.059,-1.511),l(-.326,.114),l(-.648,.484),l(-.762,.499),l(-1.843,-.032),l(-.096,-.663),l(-.241,-.323),l(-.312,-.182),l(-.415,-.04),l(-1.085,-.12),l(.208,-.312),l(.247,-.495),l(-.106,-.127),l(-1.333,-2.166),l(-.619,-.957),l(-.106,-.564),l(.247,-.622),l(.349,-.342),l(.62,-.328),l(.625,-.498),l(-.012,-.112),l(-.277,-.86),l(.021,-.155),l(.319,-.511),l(.599,-1.415),l(.372,-.172),l(.701,-.442),l(1.895,-.773),l(.669,.066),l(.371,-.115),l(.604,-.441),l(.322,-.072),l(.493,.096),l(.793,.235),l(.341,-.186),l(-.136,-.324),l(.133,-.198),l(.073,-.382),l(.706,-4.411),l(.326,-1.428),l(-.031,-.212),l(-.399,-.562),l(.031,-.777),l(-.192,-.183),l(-.688,-.363),l(-.192,-.197),l(0,-.554),l(.001,-1.071),l(.111,-.085),l(.493,-.187),l(.687,-.032),l(.417,.11),l(.384,.04),l(-.052,-.367),l(-.293,-.408),l(-.177,-.084),l(-.896,-.122),l(-.178,-.154),l(.013,-1.031),l(.042,-.325),l(.64,.024),l(2.812,.082),l(.463,-.017),l(.412,-.158),l(.834,-.57),l(.52,-.286),l(.148,.168),l(.138,.437),l(.161,.861),l(.088,.452),l(.199,.437),l(.432,.054),l(.694,.546),l(.482,.223),l(.414,-.073),l(.757,-.697),l(.083,.183),l(.186,.776),l(.271,-.016),l(.645,-.739),l(.74,-.654),l(.554,-.286),l(.652,-.173),l(.235,-.213),l(.259,-.666),l(.203,-.199),l(.652,-.131),l(.569,-.272),l(.265,-.27),l(-.15,-.253),l(-.434,-.125),l(-.96,-.051),l(-.166,-.239),l(-.079,-.55),l(-.302,-1.524),l(-.391,-.69),l(-.616,-.688),l(.041,-.184),l(.159,-.029),l(.309,.125),l(.896,.461),l(.385,.04),l(1.149,-.035),l(.344,.224),l(.628,.618),l(.348,-.115),l(.232,-1.117),l(.284,-.115),l(.465,.054),l(.557,-.074),l(.807,-.23),l(1.74,-.9),l(.592,-.385),l(.163,-.326),l(-.103,-.169),l(.375,-.257),l(.302,-.058),l(.516,.124),l(.26,.111),l(.04,.212),l(-.452,1.09),l(.304,-.001),l(.533,.138),l(.435,.958),l(-.179,.368),l(-.547,1.416),l(-.213,.962),l(.156,.465),l(.281,.394),l(.167,.31),l(-.072,.354),l(.008,.396),l(.15,.296),l(1.103,.897),l(.613,.392),l(.686,-.075),l(.694,-.513),l(.505,-.314),l(1,-.331),l(.934,-.429),l(.943,.022),l(.4,.04),l(1.108,.276),l(.528,.054),l(-.611,-1.014),l(.2,-.326),l(.172,-.156),l(.642,.124),l(.418,.139),l(.398,-.059),l(.534,-.385),l(.319,-.001),l(1.05,.488),l(.649,.505),l(.225,.069),l(.882,-.613),l(1.11,.389),l(.56,.025),l(.299,-.214),l(.464,-.681),l(.439,-.992),l(.427,-.765),l(1.102,-1.646),l(-.015,-.422),l(.409,-.241),l(.276,.141),l(.235,.423),l(.164,.791),l(.414,1.34),l(.108,.607),l(.472,1.383),l(.296,.55),l(.324,.324),l(.978,.21),l(.196,.338),l(.038,.551),l(-.045,.254),l(-.524,.354),l(-.933,1.414),l(-.238,.325),l(-.51,.411),l(-.41,.231),l(-.244,.138),l(-.798,.778),l(-.544,.947),l(-.419,1.018),l(-.402,.453),l(.271,.112),l(.512,-.072),l(.497,-.198),l(1.202,-.709),l(.112,-.028),l(.299,.889),l(.442,.818),l(.255,.112),l(.287,.07),l(1.135,-.031),l(.592,-.058),l(.737,-.298),l(-.277,.679),l(-.017,.584),l(.448,-.557),l(1.254,-1.006),l(.289,-.156),l(.306,-.382),l(.499,-.933),l(.272,-.396),l(.256,-.099),l(1.006,-.003),l(.352,-.198),l(.175,0),l(.687,.549),l(.654,.267),l(.32,-.028),l(.814,.28),l(1.069,.45),l(.334,.281),l(.269,.593),l(.08,.028),l(.176,-.015),l(.402,-.354),l(.319,.042),l(.302,.254),l(.538,.789),l(.205,.396),l(-.13,.254),l(-.308,.41),l(-.116,.424),l(.091,.466),l(.171,.396),l(.825,-.821),l(.369,-.156),l(.609,-.156),l(.995,-.454),l(.224,-.028),l(.367,.069),l(.764,.38),l(.907,.436),l(.462,.098),l(1.117,.167),l(1.118,.083),l(.464,-.058),l(.48,-.029),l(.577,-.171),l(.416,-.016),l(1.131,.351),l(.731,.408),l(.762,.479),l(.586,.437),l(1.595,1.395),l(.742,.662),l(.821,.605),l(.41,.338),l(.477,.196),l(.734,.168),l(1.247,.097),l(.912,.04),l(.445,.197),l(.265,.465),l(.087,.607),l(.592,2.004),l(.268,1.143),l(.062,.988),l(-.076,.579),l(-.179,.904),l(-.243,.848),l(-.559,1.301),l(-.518,.849),l(-1.347,1.175),l(-1.388,1.288),l(-.44,.198),l(-.354,.043),l(-.39,.637),l(-.094,.396),l(-.012,.353),l(-.504,1.074),l(-.6,.976),l(-.8,1.104),l(-.266,.212),l(-.194,.015),l(-.079,-.423),l(-.278,-.296),l(-.367,-.084),l(-.064,.79),l(-.538,1.64),l(-.049,.734),l(-.077,.607),l(.318,2.738),l(.078,.988),l(-.577,2.543),l(-.039,.663),l(.14,.649),l(.043,.085),l(-.759,.495),l(-.404,.51),l(-.261,.791),l(-.04,.367),l(.245,1.468),l(-.106,.367),l(-.214,.283),l(-.676,.608),l(-.752,1.498),l(-1.01,1.4),l(-.201,.537),l(-.055,.311),l(.144,.945),l(-1.203,.37),l(-.544,.283),l(-.355,.368),l(-.084,.466),l(.021,.367),l(-.401,.114),l(-.864,-.041),l(-.979,.172),l(-.654,.001),l(-.764,-.055),l(-.465,-.112),l(-.922,.072),l(-.736,.002),l(-.214,.607),l(-.295,.198),l(-.795,.312),l(-.481,.453),l(-.21,.354),l(-.747,-.267),l(-.35,.071),l(-.563,.255),l(-1.864,1.232),l(-.528,.396),l(-.725,.383),l(-.616,.438),l(-.532,.679),l(-.486,.241),l(-.567,.072),l(-.278,-.014),l(.006,.24),l(.336,.225),l(.12,.536),l(-.111,.537),l(-.099,.282),l(-.282,.156),l(-.084,.155),l(.384,.648),l(.036,1.186),l(.05,1.045),l(-.057,.311),l(-.11,.594),l(-.198,.621),l(-.464,.735),l(-.566,.495),l(-.788,.524),l(-.866,1.046),l(-.208,.396),l(-.476,1.145),l(-.499,.933),l(-.75,1.004),l(-.69,.623),l(-.801,.78),l(.321,-.808),l(.436,-.594),l(.629,-.566),l(.605,-1.158),l(-.06,-.254),l(-.356,.142),l(-.397,-.014),l(-.633,-.21),l(-.075,.155),l(.002,.297),l(-.401,1.215),l(-.349,.48),l(-.661,.438),l(-.317,.283),l(-.225,.424),l(-.013,.354),l(-.448,1.709),l(-.481,.763),l(-.787,.934),l(-1.076,.979),l(-.101,-.313),l(-.258,-.746),l(.103,-.269),l(.634,-.766),l(.017,-.269),l(-.333,-.379),l(-.163,-.027),l(-.131,-.197),l(-.853,-1.109),l(-.474,-.435),l(-.999,-.587),l(-.55,-.194),l(-.617,-.194),l(-.432,-.576),l(-.365,-.393),l(-.693,.427),l(-.27,.016),l(-.232,-.38),l(-.59,-.814),l(-.379,-.407),l(-.47,-.364),l(-.266,-.098),l(-.25,.101),l(-1.042,.246),l(-.55,.003),l(.214,-.27),l(.833,-.88),l(1.805,-1.816),l(1.435,-1.363),l(1.633,-1.448),l(.348,-.242),l(1.754,-.744),l(.521,-.313),l(.161,-.467),l(.094,-1.638),l(-.517,-1.154),l(-.206,-.196),l(-.462,.017),l(-.957,.161),M(288.966,203.943),l(-.558,-.125),l(-.301,-.536),l(-.078,-.382),l(.16,-.197),l(-.094,-.636),l(.048,-.381),l(.208,-1.018),l(.176,-.099),l(.479,-.058),l(.879,.097),l(1.007,.11),l(.479,-.199),l(.368,.028),l(.479,.168),l(.479,.083),l(.319,.155),l(-.335,.538),l(-.193,.946),l(-.257,.494),l(-.289,.312),l(-.561,.326),l(-.464,.171),l(-.527,.015),l(-.783,.016),l(-.641,.171),
+N(732.92,214.323),l(-.164,-.24),l(-.225,-.197),l(-.379,-.126),l(-.416,.198),l(-.399,-.38),l(-.287,-.184),l(-.659,-.238),l(-.243,-.239),l(.156,-.255),l(.29,.027),l(.731,-.058),l(.538,.126),l(.743,.083),l(.523,-.058),l(.258,-.185),l(.232,-.509),l(.056,.099),l(.351,.395),l(.286,.184),l(.241,.014),l(.961,-.2),l(.366,-.227),l(.361,-.722),l(.241,-.212),l(.653,-.029),l(.263,-.128),l(.04,-.282),l(-.064,-.565),l(-.043,-.536),l(.495,.196),l(.404,.056),l(.324,-.354),l(.318,.578),l(.077,.353),l(-.196,.495),l(-.099,.184),l(-.509,.044),l(-.159,.226),l(.061,.17),l(.437,.479),l(-.308,.354),l(-.264,.113),l(-.742,-.083),l(-.416,.001),l(-.091,.269),l(-.408,.495),l(-.275,.156),l(-.973,.426),l(-.484,.143),l(-.798,.029),l(-.807,.115),M(713.795,220.696),l(.031,-3.438),l(-.046,-.805),l(-.431,-1.368),l(.44,-.822),l(-.169,-7.966),l(2.581,.802),l(.85,.337),l(1.04,.295),l(1.254,.378),l(.848,.507),l(.613,.323),l(.597,.084),l(.38,-.058),l(.26,.508),l(.274,.254),l(.635,.352),l(.687,.395),l(.779,.718),l(-.3,.947),l(.033,.226),l(.305,.226),l(.665,.111),l(1.887,.787),l(.354,.027),l(.72,.183),l(.181,.254),l(.413,.535),l(.211,.579),l(-.166,.113),l(-1.114,.073),l(-.563,.156),l(-.098,.155),l(.047,.339),l(.589,.987),l(.5,.521),l(1.464,1),l(.218,.847),l(.725,1.044),l(.288,.141),l(.304,-.015),l(.712,-.086),l(.338,.013),l(.087,.198),l(-.354,.551),l(.218,.212),l(.401,.141),l(.423,.041),l(.63,.168),l(.096,.127),l(-.031,.142),l(-.648,.213),l(.287,.24),l(1.064,.28),l(.538,.295),l(.235,.763),l(-.064,.226),l(-1.094,-.012),l(-.215,-.154),l(-.146,-.466),l(-.126,-.099),l(-1.011,-.111),l(-1.063,-.266),l(-.644,-.126),l(-.752,.016),l(-.774,-.026),l(-.573,-.211),l(-.494,-.352),l(-.223,-.522),l(-.24,-.268),l(-.726,-.31),l(-.472,-.338),l(-.135,-.197),l(-1.089,-1.608),l(-.613,-.817),l(-.454,-.056),l(-1.524,-.336),l(-.671,-.31),l(-.55,-.055),l(-.415,.185),l(-.394,.071),l(-.78,-.45),l(.282,.762),l(-.027,.212),l(-.249,.071),l(-.382,-.126),l(-.311,.1),l(.296,.395),l(-.116,.113),l(-1.037,.045),l(-1.125,-.182),l(-.478,.029),l(.237,.127),l(.24,.154),l(.642,.169),l(.662,.352),l(.404,.338),l(.219,.395),l(-.411,.199),l(-.739,.425),l(-.458,.213),l(-.668,-.097),l(-1.801,-.039),l(-1.219,-.092),
+N(726.605,297.247),l(-.479,-.229),l(-1.179,-.471),l(-.543,-.371),l(-.508,-.715),l(-.477,-.558),l(-.216,-.414),l(.264,-.044),l(.169,.1),l(.421,.171),l(.129,-.143),l(-.209,-.387),l(-.703,-.699),l(-.617,-.713),l(-.149,-.257),l(-.375,-.956),l(-.008,-.67),l(.177,-.044),l(1.004,.312),l(1.476,.354),l(1.089,.369),l(.797,-.03),l(.463,-.144),l(.382,-.115),l(.373,-.058),l(.684,.027),l(.306,-.301),l(.716,-.244),l(.475,.385),l(-.009,.1),l(.128,.8),l(-.009,.686),l(-.751,1.503),l(-.124,.758),l(-.245,.315),l(-.943,.26),l(-.553,.388),l(-.49,.689),l(-.189,.272),l(-.274,.072),M(716.883,224.344),l(.682,.394),l(.233,.509),l(.047,.649),l(.118,.678),l(.256,.197),l(.42,.013),l(.102,.24),l(-.45,.919),l(.715,.338),l(.175,.282),l(.147,.593),l(.08,1.3),l(.144,.621),l(.456,1.157),l(.293,.268),l(.422,.014),l(.328,-.312),l(.384,-.185),l(.32,.663),l(.363,.127),l(.563,.408),l(.385,.154),l(.144,.155),l(.002,.41),l(.083,.96),l(.275,.776),l(-.046,1.06),l(.279,.24),l(.93,1.325),l(.276,.706),l(.055,.777),l(-.209,.876),l(.403,.649),l(.275,.833),l(.204,.353),l(1.395,.803),l(.285,.154),l(.744,.111),l(.402,.649),l(.843,.535),l(.483,.169),l(1.141,.068),l(.117,.197),L(731,245.42),l(-.273,.565),l(.309,.424),l(.879,.479),l(.22,.564),l(.469,1.342),l(.211,.748),l(.112,.396),l(.252,.311),l(.771,.352),l(-.021,-.127),l(-.141,-.777),l(.913,.507),l(.567,.154),l(.184,.127),l(.136,.296),l(.106,1.752),l(.884,.762),l(.573,.323),l(.604,.154),l(.287,.296),l(.244,.579),l(.229,.424),l(.545,.168),l(.176,.297),l(.007,.269),l(.19,.536),l(.106,.113),l(.506,.126),l(.156,.112),l(.162,.354),l(.366,1.327),l(.026,.876),l(.013,.862),l(-.132,.41),l(-.181,.325),l(.778,1.271),l(.223,.48),l(.181,.833),l(.034,.749),l(-.293,.708),l(-.353,1.668),l(-.585,1.755),l(.137,.791),l(-.065,.806),l(-.306,.778),l(-.661,.977),l(-.203,.665),l(-.598,.821),l(-.45,.185),l(-.465,.1),l(-.423,.468),l(-.466,.68),l(-.328,1.527),l(-.477,.638),l(-.34,.495),l(.014,.65),l(-.208,.539),l(-.331,.312),l(-.601,.341),l(-.27,.326),l(-.3,1.021),l(-.169,1.049),l(-.079,.937),l(.021,.666),l(-.283,.64),l(-.322,.354),l(-.463,.3),l(-.754,.101),l(-1.158,.087),l(-.82,.03),l(-.527,.157),l(-.516,.299),l(-1.529,.94),l(-.443,.129),l(-.214,.284),l(-.346,.071),l(-.528,.059),l(-.286,-.014),l(.295,.368),l(.209,.27),l(-1.315,-.665),l(-.885,-.353),l(.003,-.469),l(-.073,-.156),l(-.56,-.467),l(-.628,-.368),l(-.421,-.014),l(-.485,.172),l(-.335,.242),l(.748,.467),l(-.97,.243),l(-.929,.428),l(-.953,.442),l(-.222,.028),l(-.604,-.226),l(-.886,-.438),l(-.67,-.226),l(-1.086,-.311),l(-.51,-.041),l(-.239,.156),l(-.044,.113),l(-.716,-.169),l(-.751,-.353),l(-.522,-.298),l(-.896,-.82),l(-.526,-.34),l(-.422,-.879),l(.09,-1.035),l(-.082,-.411),l(-.184,-.495),l(-.664,-.736),l(-.141,-.523),l(-.029,-.425),l(-.534,-.014),l(-.786,.398),l(-.597,.114),l(-.34,.058),l(-.178,-.07),l(-.167,-.17),l(.517,-.454),l(.233,-.567),l(.073,-.821),l(-.253,-.324),l(-.536,-.593),l(-.247,-.353),l(-.485,.735),l(-.443,1.431),l(-.19,.113),l(-.796,.002),l(-.199,.156),l(-.196,.015),l(-.255,.028),l(.198,-.396),l(.081,-.396),l(.079,-.1),l(.634,.041),l(.242,-.142),l(.126,-.255),l(-.105,-1.004),l(.454,-.835),l(.328,-.453),l(.091,-.396),l(.018,-.409),l(.151,-.128),l(.245,-.015),l(.218,-.354),l(-.052,-.227),l(-.323,-.494),l(-.338,-.494),l(-.107,.707),l(-.288,.255),l(-.518,.299),l(-.311,.467),l(-.086,.155),l(-.189,.467),l(-.281,.326),l(-.747,.242),l(-.735,.481),l(-.653,.567),l(-.36,.693),l(-.514,.808),l(-.41,-.339),l(-.38,-1.328),l(-.263,-.579),l(-.19,-.325),l(-.688,-.79),l(-.297,-.734),l(-.176,-.212),l(-.704,.072),l(-.235,-.099),l(-.139,-.24),l(-.085,-.269),l(.334,-.34),l(-.047,-.297),l(-.346,-.395),l(-.543,-.494),l(-.266,-.098),l(-.83,.157),l(-.486,-.07),l(-.95,-.549),l(-.274,-.014),l(-.438,.17),l(-.433,-.027),l(-.421,-.183),l(-.662,-.521),l(-.921,-.437),l(-.218,.001),l(-.723,.213),l(-1.282,.088),l(-.669,.001),l(-1.764,.061),l(-.611,.129),l(-.656,.213),l(-.989,.44),l(-.972,.256),l(-1.039,.257),l(-1.503,.088),l(-.794,-.013),l(-.383,.044),l(-.927,.284),l(-.993,.469),l(-.773,.397),l(-.538,.143),l(-.431,.085),l(-.361,.199),l(-.615,.693),l(-.774,1.02),l(-.588,.284),l(-.766,-.013),l(-.547,-.013),l(-.927,.143),l(-.4,.185),l(-.663,-.395),l(-.294,-.084),l(-.734,.016),l(-1.572,.173),l(-.938,.157),l(-.459,-.041),l(-.672,.044),l(-.398,.227),l(-.583,.793),l(-.344,.128),l(-.958,-.125),l(-.158,.057),l(-.57,.708),l(-.465,.368),l(-.919,.271),l(-.586,.086),l(-1.516,-.082),l(-.638,-.055),l(-.688,-.197),l(-.633,-.366),l(-.778,-.677),l(-.74,-.353),l(-.374,-.041),l(-.151,-.07),l(-.19,-1.229),l(.055,-.255),l(.489,.112),l(.45,-.086),l(.332,-.425),l(.197,-.467),l(.267,-1.357),l(-.043,-1.215),l(-.156,-.622),l(-.258,-.593),l(-1.117,-1.906),l(-.208,-.635),l(-.144,-.834),l(.027,-.989),l(-.16,-.692),l(-.467,-1.072),l(-.663,-.945),l(-.603,-.734),l(-.214,-.254),l(.128,-.904),l(-.215,-.536),l(-.733,-1.115),l(-.972,-1.018),l(-.273,-.583),l(.126,-.233),l(.188,.187),l(.152,.443),l(.183,.163),l(.235,.35),l(.327,.188),l(.354,.023),l(-.348,-1.144),l(-.437,-.396),l(-.226,-.326),l(.08,-.304),l(.748,.84),l(.495,.979),l(.477,.065),l(-.099,-.555),l(.289,-.039),l(.004,-.564),l(-.282,-.48),l(-1.03,-1.368),l(-.354,-.691),l(-.119,-.579),l(-.038,-.734),l(.355,-.595),l(.323,-.523),l(.21,-.664),l(-.083,-1.031),l(-.254,-.635),l(.033,-.368),l(.438,-.692),l(.109,-.325),l(.064,-.156),l(.271,.649),l(.011,.424),l(.105,.184),l(.35,.027),l(.171,-.113),l(.187,-.565),l(.141,-.48),l(.765,-.468),l(1.22,-.624),l(.484,-.326),l(.676,-.581),l(.585,-.467),l(.632,-.327),l(.79,-.114),l(.697,-.016),l(.7,-.002),l(.431,-.043),l(.352,-.185),l(.474,-.453),l(.494,-.128),l(.929,-.072),l(.279,-.143),l(.291,-.551),l(.158,-.1),l(.444,.027),l(.877,.224),l(.626,-.043),l(.911,-.299),l(1.084,-.469),l(.359,-.213),l(.716,-.665),l(.427,-.58),l(.29,-.622),l(.132,-.297),l(.41,-.369),l(.968,-.651),l(.079,-.17),l(-.067,-.409),l(-.242,-.805),l(-.016,-.495),l(1.063,-1.118),l(.387,-.692),l(.291,.169),l(.341,.437),l(.619,1.355),l(.262,.253),l(.177,-.579),l(.021,-.466),l(.436,.238),l(.272,.07),l(.189,-.607),l(-.06,-.142),l(-.563,-.238),l(-.175,-.24),l(.007,-.565),l(.044,-.112),l(.897,.04),l(.661,.253),l(.642,-.029),l(.334,-.029),l(.289,.074),l(-.699,-.455),l(-.431,-.141),l(.128,-.537),l(-.07,-.296),l(.135,-.509),l(.422,-.354),l(.165,-.07),l(.732,.394),l(.202,-.043),l(-.112,-.452),l(.11,-.48),l(.146,-.367),l(-.041,-.522),l(.358,-.171),l(.4,-.113),l(.813,.04),l(.529,-1.088),l(.371,-.298),l(.35,.169),l(.268,.451),l(.265,-.552),l(.222,-.227),l(.197,-.48),l(.695,.62),l(.513,.084),l(.293,.211),l(.331,.536),l(.632,.592),l(.122,.706),l(-.072,.594),l(.181,.197),l(.256,-.283),l(.462,-.679),l(.155,-.128),l(1.16,.082),l(.479,.155),l(.637,.492),l(.332,.141),l(.156,-.48),l(.302,-.297),l(.022,-.24),l(-.266,-.324),l(-.601,-.395),l(-.079,-.184),l(.008,-.24),l(.145,-.099),l(.604,-.538),l(.007,-.452),l(.191,-.213),l(.518,-.283),l(.268,-.241),l(.151,-.269),l(-.094,-.184),l(.003,-.296),l(.512,-.863),l(.121,-.057),l(.317,-.029),l(.397,-.029),l(.248,-.17),l(-.205,-.409),l(.377,-.396),l(.344,-.071),l(.793,.366),l(.616,-.072),l(1.291,-.088),l(.512,-.128),l(.232,-.17),l(.04,-.057),l(-.077,-.197),l(-.2,-.734),l(-.248,-.282),l(-.471,-.268),l(-.374,.086),l(-.244,-.141),l(.035,-.212),l(.367,-.143),l(.396,-.043),l(.617,.521),l(.255,.099),l(.34,-.1),l(.364,.31),l(.676,.465),l(.36,.154),l(1.297,.294),l(.591,.084),l(.413,-.143),l(.372,.014),l(.396,.606),l(.419,.112),l(.141,-.029),l(.562,-.438),l(.454,.027),l(.652,.38),l(.331,.479),l(.46,-.143),l(.122,-.791),l(.181,-.085),l(.455,.465),l(.337,.099),l(.152,.154),l(-.436,.411),l(-.126,.424),l(-.176,.212),l(-.011,.438),l(-.12,.255),l(-.513,.015),l(-.51,.228),l(-.396,.34),l(-.004,.551),l(.301,.353),l(-.187,.692),l(-.381,.58),l(-.559,.481),l(-.155,.48),l(.063,.17),l(.469,.437),l(1.038,.619),l(.81,.677),l(.508,.606),l(.246,.099),l(.349,-.114),l(.264,.027),l(.782,.352),l(.742,.465),l(.434,.451),l(.679,.535),l(.335,.127),l(.442,.027),l(.784,.182),l(.25,.184),l(.218,.621),l(.167,.169),l(.507,.31),l(.76,.423),l(.537,.154),l(.422,-.072),l(.414,-.17),l(.603,-.199),l(.208,-.156),l(.736,-1.344),l(.403,-1.131),l(.194,-1.314),l(.259,-.721),l(.43,-.679),l(-.131,-.424),l(-.409,-.621),l(.022,-.311),l(.236,-.637),l(.187,-.48),l(-.164,-.282),l(-.183,-.395),l(.088,-.692),l(.104,-1.004),l(.225,-.297),l(.329,-.156),l(.158,-.311),l(-.534,-.521),l(.033,-.198),l(.576,-.947),l(.312,-.934),l(.072,-.833),l(.191,-.241),l(.279,-.297),
+N(270.934,276.123),l(.054,-.338),l(-.194,-.577),l(.011,-.522),l(.24,-.495),l(.48,-.524),l(.118,-.325),l(-.168,-.986),l(-.049,-.847),l(.103,-.522),l(.595,-2.359),l(.065,-.452),l(.443,-.524),l(.55,-.003),l(1.042,-.246),l(.25,-.101),l(.266,.098),l(.47,.364),l(.379,.407),l(.59,.814),l(.232,.38),l(.27,-.016),l(.693,-.427),l(.365,.393),l(.432,.576),l(.617,.194),l(.55,.194),l(.999,.587),l(.474,.435),l(.853,1.109),l(.131,.197),l(.163,.027),l(.333,.379),l(-.017,.269),l(-.634,.766),l(-.103,.269),l(.258,.746),l(.101,.313),l(-.059,.053),l(-.803,1.103),l(-.625,.552),l(-.775,.454),l(-.441,.156),l(-.818,.1),l(-.874,-.337),l(-.551,.044),l(-.551,.114),l(-.64,.283),l(-.38,-.042),l(-.846,-.676),l(-.637,-.252),l(-.76,-.154),l(-.469,.128),l(-.507,.072),l(-.327,-.127),l(-.548,-.563),l(-.354,-.159),
+N(418.763,73.869),l(.391,-.499),l(.389,-.262),l(.283,.081),l(.663,-.062),l(.762,-.075),l(.324,-.137),l(.891,-.787),l(.979,-.2),l(.224,.025),l(.198,-.219),l(.175,.032),l(-.349,.531),l(.11,.106),l(.026,.481),l(-.288,.156),l(-.17,.368),l(-1.675,.069),l(-.376,-.106),l(-.428,.031),l(-.14,-.062),l(-.239,.081),l(-.275,.031),l(-.153,.417),l(-.249,.218),l(-.353,.118),l(-.08,.112),l(-.229,-.155),l(-.411,-.292),M(421.68,78.002),l(-1.839,.129),l(-.116,-.016),l(.064,-.404),l(-.19,-.638),l(-.174,.015),l(-.36,-.293),l(-.233,.184),l(-.398,-.172),l(.2,-.355),l(.434,-.293),l(-.007,-.181),l(-.445,-.541),l(.018,-.256),l(.131,-.498),l(.279,-.106),l(.318,.15),l(.495,.12),l(.43,-.574),l(.299,-.091),l(.296,.437),l(.391,-.046),l(.022,-.528),l(.107,-.363),l(1.032,-.017),l(.848,.089),l(.03,.544),l(.187,.301),l(1.138,.058),l(.14,.166),l(-.307,.604),l(-.565,.142),l(-.119,-.261),l(-.331,.031),l(-.263,.136),l(.121,.278),l(-.184,.414),l(-.312,.077),l(-.069,.244),l(-.635,.035),l(.157,.229),l(-.291,.094),l(-.191,.24),l(-.061,.285),l(.003,.21),l(-.215,.338),l(.166,.084),M(427.177,77.967),l(-.139,-.149),l(-.312,-.344),l(-.405,.031),l(-.665,-.059),l(-.123,-.329),l(-.285,-.66),l(.433,-.091),l(.603,-.467),l(.356,.495),l(.521,.179),l(.2,-.271),l(.078,-.586),l(.333,-.046),l(.459,.044),l(.056,.571),l(-.134,.36),l(-.144,.09),l(-.413,.286),l(.603,.299),l(-.285,.166),l(-.499,.39),l(-.238,.09),
+N(417.259,94.301),l(-.135,-.233),l(.216,-.701),l(-.091,-.076),l(.075,-.295),l(.321,-.372),l(.054,-.358),l(.054,-.213),l(.954,-.806),l(-.605,-.193),l(-.479,.014),l(-.456,-.09),l(-.095,-.186),l(-.233,-.007),l(-.072,.048),l(-.689,.062),l(-.045,-.145),l(-.395,.055),l(-.337,-.277),l(-.428,-.319),l(-.074,-.353),l(.248,-.144),l(.044,-.288),l(-.466,-.096),l(-.41,-.312),l(-.062,-.301),l(.422,-.376),l(-.038,-.468),l(-.282,-.365),l(-.344,-.177),l(.165,-.278),l(-.143,-.217),l(-.182,-.037),l(.08,-.097),l(.235,-.133),l(.236,-.133),l(-.193,-.121),l(.201,-.275),l(.095,-.148),l(-.152,-.292),l(-.082,-.265),l(-.376,-.182),l(.07,-.182),l(.341,-.078),l(.175,-.092),l(.378,.134),l(.664,-.151),l(.32,-.152),l(.128,-.376),l(.412,-.207),l(.003,-.328),l(-.16,-.17),l(-.188,.061),l(-.44,-.134),l(.029,-.184),l(.113,-.181),l(.571,.036),l(.084,-.401),l(.345,-.361),l(-.151,-.438),l(.066,-.147),l(-.465,-.192),l(.126,-.43),l(.285,-.181),l(.371,-.028),l(1.12,-.062),l(.293,-.012),l(.095,.16),l(.195,.271),l(-.155,.158),l(.324,.113),l(.148,-.068),l(.042,-.192),l(-.159,-.204),l(.259,.012),l(.437,.169),l(-.163,-.362),l(.247,-.419),l(.687,.113),l(.614,-.091),l(-.596,-.17),l(-.084,-.227),l(.282,-.102),l(-.252,-.114),l(-.12,-.147),l(.166,-.08),l(.068,-.136),l(-.675,.08),l(-.06,-.182),l(.664,-.125),l(.218,-.193),l(-.464,-.42),l(-.324,-.341),l(.045,-.28),l(.116,.016),l(1.839,-.129),l(.254,.13),l(.565,.341),l(.271,.297),l(-.02,.228),l(-.252,.175),l(.445,-.05),l(.171,.216),l(.157,-.078),l(.283,.021),l(.235,.156),l(.45,.073),l(.866,-.121),l(.077,.208),l(-.07,.149),l(-.057,.125),l(-.665,.295),l(.316,.193),l(.649,-.136),l(.113,.182),l(.457,-.006),l(.349,-.391),l(1.059,-.136),l(.602,-.234),l(.757,-.266),l(.249,.113),l(.396,-.17),l(.184,.182),l(.085,.159),l(.634,.29),l(.182,.074),l(.526,-.12),l(.156,.12),l(.059,.34),l(.036,.227),l(.154,.102),l(.354,.125),l(.372,-.022),l(.028,.13),l(.201,.025),l(.319,.835),l(-.219,.52),l(-.391,.147),l(-.051,.328),l(.391,.102),l(.683,.429),l(-.217,.395),l(.094,.18),l(.312,.146),l(-.021,.304),l(.131,.102),l(-.118,.292),l(-.214,.124),l(-.007,.191),l(.325,.27),l(-.114,.258),l(.468,.188),l(.281,.485),l(-.435,.698),l(-.142,.115),l(-.344,-.072),l(-.031,-.278),l(-.308,-.121),l(-.436,.072),l(.282,.218),l(-.254,.084),l(-.284,.097),l(-.524,.048),l(-.124,.169),l(-.735,.024),l(-.112,.217),l(-.176,-.072),l(-.358,.061),l(-.097,.229),l(-.382,.012),l(-.078,.181),l(-.442,0),l(-.422,.201),l(-.293,-.033),l(-.26,.181),l(-.243,.168),l(.037,.056),l(.258,.378),l(.413,.098),l(-.155,.25),l(-.08,.406),l(.159,.085),l(.036,.233),l(.244,.173),l(.478,.265),l(.188,-.072),l(.573,.515),l(.431,.17),l(.184,.201),l(.219,-.084),l(.165,.18),l(.207,.036),l(.447,.633),l(-.682,.26),l(-.437,-.151),l(-.132,.027),l(-.039,.337),l(-.162,.172),l(-.968,.295),l(-.364,.227),l(.538,.571),l(-.197,.295),l(.334,.014),l(.056,.158),l(-.098,.343),l(-.082,.055),l(-.441,-.178),l(.049,-.165),l(-.146,-.117),l(-.564,.062),l(-.195,-.138),l(-.433,.035),l(-.092,.178),l(-1.25,.035),l(-.125,.171),l(-.319,.014),l(-.044,.13),L(425.4,94.7),l(-.594,.021),l(-.059,-.144),l(-.093,-.145),l(-.493,-.089),l(-.262,.055),l(-.237,-.041),l(.032,.274),l(-.452,.343),l(-.215,0),l(.078,-.195),l(-.26,-.039),l(.011,-.165),l(-.194,-.048),l(-.104,-.137),l(-.249,-.007),l(-.096,-.11),l(-.164,.137),l(-.368,-.014),l(-.664,-.261),l(-.852,-.007),l(-.149,-.089),l(-.199,.014),l(-.017,-.151),l(-.709,.199),l(.179,.199),l(-.354,.021),l(-.278,-.11),l(-.567,.158),l(-.271,-.096),l(-.272,.117),l(-.271,-.089),M(432.012,80.473),l(-.171,-.038),l(-.088,-.049),l(-.447,.08),l(-.111,-.264),l(.002,-.213),l(.647,.281),l(.168,.203),
+N(450.734,91.05),l(-.831,-.33),l(-.424,-.101),l(-.104,-.216),l(-.703,-.186),l(-.129,-.13),l(-.561,.076),l(-.508,-.041),l(-.073,.137),l(-.373,.18),l(-.46,-.254),l(-.483,.046),l(-.168,-.056),l(-.558,.204),l(-.104,.177),l(-.149,.135),l(-.18,-.12),l(-.389,.083),l(-.003,-.204),l(.026,-.083),l(-.066,-.18),l(-.331,.025),l(-.073,-.169),l(-.194,-.24),l(-.261,.024),l(-.062,.112),l(-.193,-.016),l(-.183,.24),l(-.43,.048),l(-.03,-.228),l(-.285,-.041),l(-.105,-.331),l(-.382,-.096),l(-.188,-.208),l(.02,-.249),l(-.802,-.132),l(-.311,-.181),l(-.368,.161),l(-.293,-.013),l(-.013,-.221),l(.001,-.253),l(-.329,.084),l(.181,-.283),l(-.709,.005),l(-.258,-.121),l(-.509,-.193),l(-.286,-.024),l(-.003,.145),l(.282,.302),l(-.41,.12),l(-.22,.187),l(-.318,-.072),l(-.296,-.38),l(-.55,-.247),l(.224,-.211),l(.208,-.024),l(.099,-.121),l(-.199,-.181),l(-.257,-.024),l(-.061,.066),l(-.466,.066),l(.005,-.169),l(-.278,.037),l(-.132,-.181),l(-.568,-.054),l(-.201,-.025),l(-.363,-.163),l(-.093,-.26),l(-.211,-.091),l(-.361,.018),l(-.063,.084),l(.062,.073),l(-.024,.151),l(-.375,0),l(.435,-.698),l(-.281,-.485),l(-.468,-.188),l(.114,-.258),l(-.325,-.27),l(.007,-.191),l(.214,-.124),l(.118,-.292),l(-.131,-.102),l(.021,-.304),l(-.312,-.146),l(-.094,-.18),l(.217,-.395),l(-.683,-.429),l(-.391,-.102),l(.051,-.328),l(.391,-.147),l(.219,-.52),l(-.319,-.835),l(.34,.043),l(.23,.125),l(-.093,-.193),l(.156,-.153),l(-.019,-.147),l(-.166,-.13),l(-.021,-.129),l(-.012,-.075),l(.93,-.154),l(.431,-.051),l(.516,-.152),l(1.304,-.128),l(.48,-.158),l(.797,-.479),l(1.117,-.298),l(1.515,-.303),l(1.382,-.086),l(1.067,.417),l(-.882,-.294),l(-.054,.147),l(.256,.172),l(.132,.466),l(.355,.135),l(.648,.061),l(.645,-.11),l(1.063,-.409),l(.054,.004),l(-.978,.417),l(-.19,.11),l(-.004,.123),l(.218,.012),l(.286,-.123),l(.613,-.208),l(.543,-.253),l(.842,.006),l(2.246,.115),l(2.96,-.101),l(.641,-.021),l(.04,.014),l(.679,.243),l(.284,.487),l(.099,.186),l(.016,.029),l(.09,.171),l(.16,.302),l(.615,1.5),l(.172,.502),l(-.023,.236),l(-.263,.208),l(-.44,.03),l(-.571,.244),l(-.291,.328),l(-.128,.292),l(.289,.012),l(.421,.146),l(.149,.176),l(.218,.146),l(.013,.25),l(-.315,.752),l(.126,.137),l(.161,.175),l(-.074,.242),l(.816,.835),l(.316,.193),l(-.298,.048),l(-.085,.133),l(.328,.302),l(-.009,.314),l(-.255,.24),l(-.429,.013),l(-.286,.181),l(-.599,.398),l(-1.509,1.218),l(-.082,.306),l(.044,.552),l(.349,.383),l(-.653,-.018),M(431.844,80.27),l(.232,.024),l(.069,.208),l(-.134,-.029),l(-.168,-.203),M(432.739,80.361),l(-.03,.129),l(-.278,-.024),l(-.191,.03),l(-.046,-.208),l(.174,-.012),l(.266,0),l(.106,.085),
+N(416.488,81.945),l(.151,.438),l(-.345,.361),l(-.084,.401),l(-.571,-.036),l(-.113,.181),l(-.029,.184),l(.44,.134),l(.188,-.061),l(.16,.17),l(-.003,.328),l(-.412,.207),l(-.128,.376),l(-.32,.152),l(-.664,.151),l(-.378,-.134),l(-.175,.092),l(-.341,.078),l(-.07,.182),l(.376,.182),l(.082,.265),l(.152,.292),l(-.095,.148),l(-.201,.275),l(.193,.121),l(-.236,.133),l(-.235,.133),l(-.08,.097),l(.182,.037),l(.143,.217),l(-.165,.278),l(-.672,.024),l(-.001,-.338),l(.172,-.097),l(.11,-.423),l(-.754,-.375),l(-.535,.109),l(-.292,-.375),l(-.228,-.061),l(-.173,.121),l(-.313,-.242),l(-.267,.182),l(-.307,0),l(-.307,-.012),l(.025,.157),l(-.52,.034),l(-.407,-.042),l(-.477,-.098),l(-.07,-.162),l(-.496,-.264),l(.795,-.472),l(.858,-.621),l(.273,-.354),l(.563,-1.167),l(.173,-.104),l(.644,-.12),l(.367,.251),l(.136,.268),l(-.28,.203),l(-.228,-.056),l(.066,.496),l(-.191,.124),l(1.163,.225),l(.225,-.236),l(.406,-.113),l(.134,-.417),l(-.458,-.022),l(-.123,-.124),l(-.02,-.203),l(.236,-.158),l(-.171,-.023),l(-.558,-.067),l(.072,-.328),l(-.034,-.13),l(-.023,-.034),l(.128,-.283),l(.572,-.198),l(.709,-.238),l(.654,.03),l(1.089,-.151),l(.245,.275),l(.329,.045),l(.076,.181),l(.259,0),
+N(431.57,91.965),l(-.447,-.633),l(-.207,-.036),l(-.165,-.18),l(-.219,.084),L(430.349,91),l(-.431,-.17),l(-.573,-.515),l(-.188,.072),l(-.478,-.265),l(-.244,-.173),l(-.036,-.233),l(-.159,-.085),l(.08,-.406),l(.155,-.25),l(-.413,-.098),l(-.258,-.378),l(-.037,-.056),l(.243,-.168),l(.26,-.181),l(.293,.033),l(.422,-.201),l(.442,0),l(.078,-.181),l(.382,-.012),l(.097,-.229),l(.358,-.061),l(.176,.072),l(.112,-.217),l(.735,-.024),l(.124,-.169),l(.524,-.048),l(.284,-.097),l(.254,-.084),l(-.282,-.218),l(.436,-.072),l(.308,.121),l(.031,.278),l(.344,.072),l(.142,-.115),l(.375,0),l(.024,-.151),l(-.062,-.073),l(.063,-.084),l(.361,-.018),l(.211,.091),l(.093,.26),l(.363,.163),l(.201,.025),l(.568,.054),l(.132,.181),l(.278,-.037),l(-.005,.169),l(.466,-.066),l(.061,-.066),l(.257,.024),l(.199,.181),l(-.099,.121),l(-.208,.024),l(-.224,.211),l(.55,.247),l(.296,.38),l(.318,.072),l(.22,-.187),l(.41,-.12),l(-.282,-.302),l(.003,-.145),l(.286,.024),l(.509,.193),l(.258,.121),l(.709,-.005),l(-.181,.283),l(.329,-.084),l(-.001,.253),l(.013,.221),l(.293,.013),l(.368,-.161),l(.311,.181),l(.802,.132),l(-.02,.249),l(.188,.208),l(.382,.096),l(.105,.331),l(-.071,-.012),l(-.065,.066),l(-.066,.04),l(-.105,-.026),L(442,89.998),l(-.119,.013),l(-.065,.04),l(-.132,.066),l(-.053,.079),l(-.118,.092),l(-.119,.053),l(-.132,.079),l(-.105,.013),l(-.118,.013),l(-.053,.092),l(-.026,.092),l(-.026,.132),l(-.053,.079),l(-.053,.105),l(-.145,.066),l(-.105,.04),l(-.092,-.026),l(-.079,.079),l(-.04,.092),l(-.053,.079),l(-.039,0),l(-.105,.026),l(-.066,.026),l(-.079,.053),l(-.118,.053),l(-.132,0),l(-.145,.04),l(-.093,.026),l(-.065,-.026),l(-.065,-.026),l(-.093,0),l(-.065,.026),l(-.158,0),l(-.132,-.053),l(-.092,-.053),l(-.093,.026),l(-.171,.053),l(-.026,.04),l(-.146,.119),l(-.092,.066),l(-.014,.131),l(-.065,.105),l(-.039,.044),l(-.055,-.095),l(-.545,-.2),l(-1.332,.181),l(-1.019,-.227),l(-1.374,-.341),l(-.746,.773),l(-.598,.163),l(-.483,-.099),l(-.354,-.129),l(-.145,-.014),
+N(421.683,94.397),l(.368,.014),l(.164,-.137),l(.096,.11),l(.249,.007),l(.104,.137),l(.194,.048),l(-.011,.165),l(.26,.039),l(-.078,.195),l(.215,0),l(.452,-.343),l(-.032,-.274),l(.237,.041),l(.262,-.055),l(.493,.089),l(.093,.145),l(.059,.144),L(425.4,94.7),l(.377,-.103),l(.044,-.13),l(.319,-.014),l(.125,-.171),l(1.25,-.035),l(.092,-.178),l(.433,-.035),l(.195,.138),l(.564,-.062),l(.146,.117),l(-.049,.165),l(.441,.178),l(.082,-.055),l(.098,-.343),l(-.056,-.158),l(-.334,-.014),l(.197,-.295),l(-.538,-.571),l(.364,-.227),l(.968,-.295),l(.162,-.172),l(.039,-.337),l(.132,-.027),l(.437,.151),l(.682,-.26),l(.145,.014),l(.354,.129),l(.483,.099),l(.598,-.163),l(.746,-.773),l(1.374,.341),l(1.019,.227),l(1.332,-.181),l(.545,.2),l(.055,.095),l(.053,.093),l(-.097,.581),l(.155,.26),l(.761,.547),l(-.636,.291),l(-.019,.367),l(-.701,.054),l(-.164,-.134),l(-.325,0),l(-.223,.197),l(.452,.063),l(.136,.196),l(-.157,.206),l(-.409,.062),l(-.04,.375),l(.204,.188),l(-.154,.294),l(-.346,.299),l(-.693,.157),l(.082,.393),l(-.89,-.116),l(-.298,.196),l(-.85,-.08),l(-.566,.107),l(-.646,.5),l(-.287,-.152),l(-.612,.009),l(-.179,-.107),l(-1.04,-.065),l(-.478,-.112),l(-.894,-.082),l(-1.311,-.247),l(-.32,-.391),l(-.318,-.096),l(-.023,-.363),l(-.856,.227),l(-.301,-.103),l(-.445,.11),l(-.183,-.083),l(-.366,.096),l(-.329,.411),l(-.597,-.034),l(-.631,-.171),l(.029,-.171),l(-.215,-.117),l(-.579,.332),l(-.55,-.242),l(-.008,-.144),l(-.622,-.062),l(.09,-.192),l(-.214,-.288),l(.266,-.274),l(-.193,-.336),
+N(431.763,171.063),l(-.067,.354),l(.091,.72),l(.108,.508),l(.225,.168),l(.562,.11),l(.144,.183),l(.077,.353),l(-.089,1.116),l(-.146,.227),l(-.274,.171),l(-.885,.217),l(-.291,.256),l(-.664,1.275),l(-.503,1.203),l(-.243,1.004),l(-.354,.129),l(-.369,.03),l(-.129,.354),l(-.146,1.229),l(-.192,.312),l(-.385,.045),l(-.257,.284),l(-.417,.836),l(-.944,2.223),l(-.304,.624),l(-.352,.496),l(-.368,.355),l(-.239,.114),l(-.145,-.056),l(-.722,-.97),l(-.145,-.14),l(-1.104,-.05),l(-.272,.03),l(-1.31,1.265),l(-.941,.839),l(-.495,.526),l(.02,.974),l(-.189,.552),l(-.376,.686),l(-.188,-.119),l(-.224,-.042),l(-.176,-.127),l(-.145,.212),l(.144,.296),l(-.063,.127),l(-.353,.198),l(-.56,.03),l(-.977,.101),l(-.607,-.267),l(-.288,.043),l(-.271,.368),l(-.177,.113),l(-.432,-.07),l(-1.247,-.011),l(-.528,-.225),l(-.543,-.451),l(-.416,-.72),l(-.192,-.649),l(.048,-.254),l(.208,-.254),l(-.144,-.296),l(-.513,-.069),l(-.128,-.254),l(-.464,-.55),l(-.561,-.465),l(-.608,-.253),l(-.641,-.253),l(-.272,-.31),l(-.513,.072),l(-.24,.297),l(-.336,.071),l(-.881,.044),l(-.659,.03),l(-.006,-.234),l(.121,-1.188),l(-.217,-1.439),l(.09,-.989),l(.012,-.876),l(-.003,-.48),l(-.002,-.381),l(.237,-.397),l(.257,-.03),l(.433,-.13),l(.078,-.368),l(-.116,-.592),l(.095,-.34),l(.656,-.414),l(.223,-.298),l(.19,-.566),l(.316,-.962),l(-.388,-.718),l(-.164,-.762),l(.062,-.777),l(.092,-.961),l(.158,-.849),l(.353,-.482),l(.687,-1.614),l(.676,-.4),l(1.064,-.188),l(1.174,-.108),l(1.111,.121),l(.821,.277),l(1.095,1.223),l(.209,.098),l(.37,-.002),l(1.337,-.544),l(.467,-.116),l(.354,.083),l(1.173,.742),l(.965,.277),l(.934,-.005),l(.273,-.059),l(.629,-.399),l(.403,-.327),l(.774,-.287),l(.628,-.103),l(.709,-.047),l(.531,.04),l(.884,.221),l(.724,.193),l(.609,.208),l(.259,-.058),l(.761,-.697),l(.453,-.299),l(.437,-.2),l(.951,-.034),l(.173,.394),l(.575,.52),l(.351,.407),
+N(425.506,195.522),l(-1.965,-.017),l(-1.005,.007),l(.029,-.176),l(-.208,-.536),l(.271,-.989),l(-.159,-.72),l(-.191,-.522),l(-.399,-.649),l(.433,-.396),l(-.287,-.367),l(-.24,-.056),l(-.576,.058),l(-.559,-.268),l(-.176,-.324),l(-.063,-.537),l(-.111,-.211),l(-.527,-.14),l(-.101,-.064),l(.376,-.686),l(.189,-.552),l(-.02,-.974),l(.495,-.526),l(.941,-.839),l(1.31,-1.265),l(.272,-.03),l(1.104,.05),l(.145,.14),l(.722,.97),l(.145,.056),l(.239,-.114),l(.368,-.355),l(.352,-.496),l(.304,-.624),l(.944,-2.223),l(.417,-.836),l(.257,-.284),l(.385,-.045),l(.192,-.312),l(.146,-1.229),l(.129,-.354),l(.369,-.03),l(.354,-.129),l(.243,-1.004),l(.503,-1.203),l(.664,-1.275),l(.291,-.256),l(.885,-.217),l(.274,-.171),l(.146,-.227),l(.089,-1.116),l(-.077,-.353),l(-.144,-.183),l(-.562,-.11),l(-.225,-.168),l(-.108,-.508),l(-.091,-.72),l(.067,-.354),l(.627,.109),l(.208,.083),l(.923,1.238),l(.395,.887),l(.119,1.2),l(-.134,.651),l(.169,1.228),l(.205,.578),l(.381,.633),l(.208,.21),l(.047,.127),l(-.225,.143),l(-.674,.032),l(-1.187,-.191),l(-.481,-.082),l(-.24,.1),l(-.29,.312),l(-.323,.539),l(1.088,1.067),l(1.343,1.179),l(.638,1.07),l(.382,1.057),l(.208,.183),l(-.208,.114),l(-.354,.327),l(-.866,1.743),l(-.4,.511),l(-.528,.399),l(-.144,.198),l(-.064,.424),l(.112,.776),l(.273,1.185),l(.207,.592),l(.4,.661),l(.432,.605),l(.064,.791),l(.112,.324),l(1.217,1.236),l(.498,.802),l(.194,.804),l(.209,.451),l(-.159,.185),l(.1,.861),l(-.271,.086),l(-.863,-.292),l(-.864,-.334),l(-.576,-.194),l(-.56,-.124),l(-.479,-.04),l(-.271,-.055),l(-.878,.076),l(-.863,-.023),l(-.56,-.109),l(-1.022,-.149),l(-.831,-.038),l(-1.773,-.088),l(-.88,-.093),l(-.045,.495),
+N(551.793,147.278),l(-.788,-.111),l(-.458,-.253),l(-.379,-.367),l(-.248,-1.101),l(-.112,-.141),l(-.342,-.141),l(-.662,-.083),l(-.105,-.07),l(-.014,-.268),l(.116,-.466),l(-.178,-.451),l(-.418,-.38),l(-.294,-.013),l(-1.181,.412),l(-1.229,.087),l(-.81,.143),l(-.947,.073),l(-.415,-.083),l(-.263,-.226),l(-.135,-.197),l(-.909,.143),l(-.548,.382),l(-.856,.016),l(-1.264,-.011),l(-.691,.128),l(-.723,.115),l(-.541,.03),l(.182,-.954),l(.049,-.354),l(.31,-.792),l(.285,-.383),l(.794,-.47),l(.697,-.258),l(1,-.077),l(.209,-.072),l(.188,-.255),l(.036,-.974),l(-.186,-.281),l(-.652,-.053),l(-.185,-.394),l(-.111,-1.34),l(-.168,-.38),l(-.409,-.224),l(-1.144,-.388),l(-.695,-.391),l(-.353,-.464),l(-.71,-1.068),l(-.802,-1.083),l(.887,.32),l(.63,.194),l(1.069,.248),l(.854,.235),l(.541,.039),l(.742,.024),l(1.187,-.218),l(.349,-.002),l(1.005,.135),l(1.234,-.12),l(.964,-.175),l(1.183,-.19),l(1.066,-.274),l(.247,-.156),l(.069,-.184),l(.099,-.903),l(.232,-.876),l(.188,-.34),l(.412,-.369),l(.597,-.441),l(.283,-.072),l(.644,.039),l(.516,.082),l(.254,-.086),l(.321,-.693),l(.362,-.271),l(.559,-.243),l(.562,.025),l(1.001,.375),l(.237,-.086),l(.34,-.383),l(.021,-.084),l(.139,-1.214),l(.288,-.834),l(.224,-.424),l(.292,-.228),l(.416,-.115),l(.513,-.031),l(.315,-.115),l(.199,-.255),l(-.088,-.437),l(-.129,-.281),L(556.193,125),l(-.35,-.336),l(.355,-.129),l(.997,.122),l(.698,.039),l(.513,-.215),l(.289,-.255),l(-.033,-.31),l(-.223,-.478),l(.13,-.283),l(.4,-.341),l(.524,-.355),l(.324,-.426),l(-.198,-.477),l(.119,-.483),l(-.232,-.171),l(-.01,-.336),l(-.411,-.271),l(-.01,-.32),l(.464,-.413),l(.258,-.214),l(.246,.023),l(.559,-.395),l(.272,-.19),l(.53,-.292),l(1.148,-.152),l(1.345,-.012),l(.647,.144),l(.338,-.179),l(.332,.005),l(.455,-.297),l(.358,-.004),l(.148,-.142),l(.313,.14),l(.105,.112),l(.281,-.21),l(.296,.047),l(.554,.117),l(.004,.456),l(.282,-.128),l(.625,-.009),l(.373,.323),l(.213,.247),l(.007,.501),l(-.312,.516),l(.301,.07),l(.198,.218),l(.252,.281),l(.52,-.196),l(.239,0),l(.104,.199),l(.178,.09),l(.565,.436),l(1.337,.104),l(.305,.111),l(.147,.126),l(-.207,.084),l(-.688,.37),l(-.411,.232),l(-.155,.43),l(-.071,.479),l(-.234,.116),l(-.125,-.179),l(-.621,-.102),l(-.438,.132),l(-.271,.298),l(-.262,-.116),l(-.557,.265),l(-.928,-.149),l(-.568,-.138),l(-1.708,-.325),l(-.894,.265),l(-.38,.611),l(.09,.166),l(.336,0),l(.047,.314),l(-.202,.149),l(.101,.199),l(.598,-.017),l(-.002,.347),l(-.384,.099),l(-.139,.413),l(.389,.232),l(-.116,.479),l(-.215,.132),l(.089,.248),l(.606,.298),l(-.003,.532),l(.782,-.003),l(-.039,.43),l(.188,.248),l(.702,-.05),l(.668,.377),l(.012,.211),l(-.2,.255),l(-.504,.2),l(-.643,.196),l(-.517,.248),l(.032,.366),l(.188,.377),l(-.237,.977),l(-1.512,1.503),l(.261,.38),l(-.358,.281),l(-.609,.133),l(-.353,.467),l(-.509,1.216),l(-.478,.547),l(-1.193,.496),l(-.177,.364),l(-.277,.481),l(-.563,.61),l(-.076,.38),l(-.71,.259),l(-.734,-.011),l(-.895,.314),l(-.361,-.094),l(-.158,-.518),l(-.207,-.132),l(-.404,.083),l(-.535,.463),l(-.144,.446),l(-.979,.893),l(-.186,.543),l(-.079,.269),l(.116,.38),l(.541,.163),l(.504,.085),l(.425,.014),l(-.114,.689),l(-.154,.735),l(.412,.411),l(.33,.099),l(.537,-.099),l(.112,.441),l(.216,.507),l(.654,1.333),l(-.232,.149),l(.241,.463),l(-.317,.066),l(-.15,.248),l(-.55,.083),l(-.145,-.335),l(-.183,-.062),l(-.78,.215),l(-.2,.331),l(-.735,-.099),l(-.229,-.149),l(-.835,-.021),l(-.835,-.009),l(-.259,-.052),l(.015,.728),l(-.866,.017),l(-.296,.431),l(-.37,.036),
+N(606.155,150.953),l(-.037,-.466),l(-.627,-2.479),l(-.064,-.578),l(-.4,.044),l(-.281,.115),l(-.395,1.159),l(-.224,.354),l(-.529,-.448),l(-.249,-.267),l(-.23,-.281),l(-.001,-.381),l(-.009,-.522),l(.131,-.283),l(.651,-.356),l(.498,-.13),l(.938,-.767),l(.159,-.34),l(.012,-.79),l(-.057,-.127),l(-.111,-.098),l(-2.473,-.198),l(-.559,.003),l(-.916,.062),l(-.547,-.053),l(-.537,-.109),l(-.095,-.099),l(-.079,-.719),l(-.053,-.479),l(-.129,-.324),l(-.417,-.054),l(-.489,.06),l(-.372,-.266),l(-.339,-.266),l(-1.252,-.303),l(-.234,.171),l(-.555,.525),l(-.124,.283),l(.083,.155),l(.494,.237),l(1.224,.938),l(.126,.112),l(-.047,.155),l(-.382,.101),l(-.502,.13),l(-.4,.299),l(-.548,.61),l(.339,.323),l(1.042,.431),l(.193,.21),l(-.029,.269),l(-.505,.765),l(.04,.254),l(.352,.45),l(.325,1.409),l(.402,1.775),l(.147,.532),l(-.172,.322),l(.068,.183),l(-.321,.071),l(-.35,-.056),l(-.148,-.706),l(-.198,-.084),l(-.253,.354),l(-.171,.354),l(-.172,.057),l(-.115,-.099),l(-.28,-.592),l(-.152,-.169),l(-.412,.537),l(-.504,.298),l(-.992,.397),l(-.571,.213),l(-.264,.226),l(-.05,.113),l(.106,.579),l(.183,.409),l(-.336,.495),l(-.305,.332),l(-.013,.257),l(-.548,.415),l(-.593,.467),l(-.467,.185),l(-.432,.057),l(-.746,.206),l(-.591,.362),l(-.459,.58),l(-.551,.552),l(-.88,1.061),l(-.611,.552),l(-.673,.276),l(-.675,.829),l(-.676,.467),l(-.728,.368),l(-.452,.241),l(-.427,.312),l(-.192,.509),l(-.073,.466),l(-.341,.41),l(-.649,.298),l(-.428,.058),l(-.506,-.098),l(-.258,.269),l(-.366,.887),l(-.277,.23),l(-.505,-.253),l(-.614,.142),l(-.354,.283),l(-.304,.565),l(-.165,.48),l(-.005,.508),l(.166,1.539),l(.018,.805),l(-.208,.495),l(.227,.324),l(.315,.423),l(-.015,.508),l(-.199,.607),l(-.669,1.611),l(-.341,.834),l(-.13,.636),l(.047,.649),l(.21,1.764),l(-.081,.24),l(-.643,.001),l(-.433,-.013),l(-.186,.142),l(-.334,.961),l(-.324,.594),l(.025,.127),l(.493,.352),l(-.805,.327),l(-.306,.015),l(-.77,.284),l(-.295,.41),l(-.101,.692),l(-.157,.255),l(-.367,.283),l(-.526,.255),l(-.099,.057),l(-.066,.042),l(-.231,.156),l(-.145,0),l(-.174,-.056),l(-1.417,-1.451),l(-.092,-.395),l(-.276,-.522),l(-.34,-1.397),l(-.689,-1.792),l(-.94,-1.933),l(-.979,-1.508),l(-.554,-1.722),l(-.507,-1.792),l(-.738,-1.636),l(-.82,-1.42),l(-.424,-.737),l(-.598,-1.439),l(-.363,-1.157),l(-.767,-3.274),l(-.469,-2.695),l(-.157,-1.566),l(-.051,-.24),l(.232,-.565),l(.546,-.834),l(.007,-.311),l(-.404,-.281),l(-.367,-.437),l(-.113,-.635),l(-.108,-.917),l(.065,-.622),l(-.837,.03),l(-.19,.212),l(-.235,.424),l(.009,.183),l(.276,.254),l(.074,.183),l(-.073,.438),l(-.301,.438),l(-.503,.368),l(-.812,.369),l(-.504,.114),l(-.617,.255),l(-.377,.015),l(-.861,-.281),l(-.572,-.38),l(-1.018,-1),l(-1.391,-1.268),l(-.516,-.705),l(.267,-.043),l(1.062,.125),l(.615,-.086),l(.443,-.142),l(.461,-.283),l(.521,-.608),l(-.067,-.24),l(-.156,.071),l(-.587,.114),l(-.847,-.026),l(-.607,-.112),l(-.632,-.132),l(-.5,-.218),l(-.203,-.07),l(-.929,-.661),l(-.668,-.775),l(-.057,-.197),l(.37,-.036),l(.296,-.431),l(.866,-.017),l(-.015,-.728),l(.259,.052),l(.835,.009),l(.835,.021),l(.229,.149),l(.735,.099),l(.2,-.331),l(.78,-.215),l(.183,.062),l(.145,.335),l(.55,-.083),l(.15,-.248),l(.317,-.066),l(-.241,-.463),l(.232,-.149),l(-.654,-1.333),l(-.216,-.507),l(-.112,-.441),L(557,143.058),l(-.33,-.099),l(-.412,-.411),l(.154,-.735),l(.114,-.689),l(-.425,-.014),l(-.504,-.085),l(-.541,-.163),l(-.116,-.38),l(.079,-.269),l(.186,-.543),l(.979,-.893),l(.144,-.446),l(.535,-.463),l(.404,-.083),l(.207,.132),l(.158,.518),l(.361,.094),l(.895,-.314),l(.734,.011),l(.71,-.259),l(.076,-.38),l(.563,-.61),l(.277,-.481),l(.177,-.364),l(1.193,-.496),l(.478,-.547),l(.509,-1.216),l(.353,-.467),l(.609,-.133),l(.358,-.281),l(-.261,-.38),l(1.512,-1.503),l(.237,-.977),l(-.188,-.377),l(-.032,-.366),l(.517,-.248),l(.643,-.196),l(.504,-.2),l(.2,-.255),l(-.012,-.211),l(-.668,-.377),l(-.702,.05),l(-.188,-.248),l(.039,-.43),l(-.782,.003),l(.003,-.532),l(-.606,-.298),l(-.089,-.248),l(.215,-.132),l(.116,-.479),l(-.389,-.232),l(.139,-.413),l(.384,-.099),l(.002,-.347),l(-.598,.017),l(-.101,-.199),l(.202,-.149),l(-.047,-.314),l(-.336,0),l(-.09,-.166),l(.38,-.611),l(.894,-.265),l(1.708,.325),l(.568,.138),l(.928,.149),l(.557,-.265),l(.262,.116),l(.271,-.298),l(.438,-.132),l(.621,.102),l(.125,.179),l(.234,-.116),l(.071,-.479),l(.155,-.43),l(.411,-.232),l(.688,-.37),l(.207,-.084),l(.502,-.152),l(0,.515),l(.441,1.03),l(.221,.515),l(.81,.11),l(.441,.405),l(.221,.258),l(-.331,.221),l(-.184,.184),l(.073,.589),l(.037,.552),l(.294,.221),l(.718,.096),l(.092,.078),l(.044,.182),l(.68,.099),l(-.104,.414),l(.367,.694),l(-.578,.364),l(-.376,.281),l(-.368,.049),l(-.337,-.264),l(-.033,-.364),l(-.785,.198),l(.157,.694),l(.579,.595),l(-.104,.446),l(.272,.364),l(-.215,.215),l(.099,.43),l(.198,.066),l(.477,-.314),l(.383,.248),l(.772,.843),l(.363,-.116),l(1.078,.579),l(-.116,.364),l(.756,.248),l(.154,-.066),l(.859,.596),l(-1.07,.909),l(-.281,.116),l(.008,.364),l(-.221,.265),l(.04,.396),l(-.309,.397),l(-.218,.43),l(.039,.248),l(.63,.38),l(.466,-.083),l(.665,.479),l(.704,.149),l(.305,.529),l(1.242,.678),l(.231,-.166),l(1.027,.595),l(.538,-.066),l(.182,.397),l(.835,.166),l(.304,.198),l(.15,-.066),l(.087,-.215),l(.503,0),l(.482,.265),l(.582,-.347),l(.494,.298),l(.643,.066),l(.142,.231),l(-.101,.446),l(.663,.149),l(.286,.281),l(.618,.265),l(.584,-.281),l(.313,.066),l(-.034,.331),l(.312,.248),l(.379,-.231),l(.721,.148),l(.847,.364),l(.606,-.297),l(.268,.364),l(.399,.116),l(.357,-.132),l(.271,.083),l(.687,-.132),l(.336,.05),l(.311,-.694),l(-.429,-.827),l(.07,-.876),l(.318,-.761),l(-.037,-.022),l(.345,-.129),l(.471,-.102),l(.231,.069),l(.139,.183),l(-.052,.861),l(.212,.662),l(-.092,.113),l(.235,.493),l(.637,.18),l(.559,.081),l(.869,.214),l(.085,.021),l(.544,-.074),l(.531,-.313),l(.301,.055),l(.335,.125),l(1.238,.063),l(1.036,-.062),l(.624,-.06),l(.217,-.58),l(-.017,-.282),l(-.258,-.238),l(-.313,-.069),l(-.326,-.294),l(-.042,-.24),l(.07,-.156),l(.189,-.1),l(.784,-.033),l(.714,-.216),l(.397,-.27),l(1.123,-1.107),l(.543,-.37),l(.829,-.258),l(1.105,-.726),l(.546,-.299),l(.355,-.087),l(.286,.167),l(.975,.319),l(.377,-.044),l(1.377,-.84),l(.455,.392),l(.716,.715),l(.046,.38),l(-.354,.454),l(-.138,.269),l(.102,.056),l(.3,.055),l(.657,.081),l(.73,.179),l(.624,.081),l(-.018,.508),l(-.112,.24),l(-.596,.582),l(-.072,.283),l(.184,.718),l(-.295,.058),l(-.853,-.221),l(-.558,-.082),l(-.312,.129),l(-.719,.512),l(-1.446,.883),l(-.197,.354),l(.057,.761),l(-.136,.382),l(-.938,1.134),l(-.045,.212),l(.192,.408),l(0,.324),l(-1.148,2.25),l(-.17,.128),l(-.309,-.013),l(-.391,-.11),l(-.811,-.32),l(-.133,.283),l(.146,1.594),l(-.191,.354),l(-.401,.144),l(-.228,.185),l(.152,.93),l(-.015,.678),l(-.273,.368),l(-.25,.129),l(-.255,-.14),l(-.595,-.152),
+N(478.516,135.173),l(.052,-.292),l(-.049,-.169),l(-.197,-.107),l(.107,-.175),l(.292,-.919),l(-.015,-.818),l(.517,-1.09),l(.3,-.891),l(-.004,-.409),l(.133,-.283),l(.07,-.749),l(.033,-.847),l(.062,-.174),l(.026,-.278),l(-.065,-.411),l(.037,-.119),l(.102,-.063),l(1.902,1.034),l(.365,.167),l(.253,-.016),l(1.139,-.656),l(2.96,-1.541),l(.161,-.071),l(.87,1.632),l(.311,.69),l(.093,.056),l(-.46,.44),l(-.257,.171),l(-.97,.26),l(-2.586,.622),l(-.646,.229),l(1.146,1.32),l(.698,.885),l(-.765,.724),l(-.456,.37),l(-.24,.072),l(-1.249,.332),l(-.462,.61),l(-.975,.782),l(-2.079,-.299),l(-.154,-.017),
+N(456.028,151.46),l(-.021,1.003),l(.033,3.078),l(-.088,.17),l(-1.561,-.019),l(-.52,-.011),l(-.073,1.13),l(-1.981,-.963),l(-5.577,-2.792),l(-4.941,-2.372),l(-5.231,-2.554),l(-.41,.059),l(-1.818,.858),l(-1.519,.729),l(-.231,.157),l(-1.192,-.911),l(-.258,-.182),l(-1.008,-.333),l(-1.646,-.442),l(-.832,-.137),l(-.098,-.07),l(-.86,-1.506),l(-.178,-.168),l(-1.028,-.347),l(-.702,-.165),l(-.544,.201),l(-.244,-.154),l(-.562,-.873),l(-.249,-.917),l(-1.272,-1.702),l(.152,-.283),l(.249,-.128),l(.666,-.47),l(.086,-.17),l(.061,-.664),l(-.457,-1.156),l(.158,-.495),l(.16,-.622),l(-.101,-.748),l(.1,-.862),l(-.052,-.691),l(-.147,-.833),l(-.88,-1.605),l(.241,-.383),l(.204,-.156),l(.22,-.143),l(.864,-.598),l(.155,-.227),l(.147,-.537),l(-.274,-.973),l(.126,-.354),l(1.473,-1.138),l(.579,-.314),l(.802,-.428),l(.093,-.269),l(-.064,-.564),l(.093,-.981),l(1.436,.59),l(.995,.309),l(.521,.013),l(.863,-.129),l(.604,.027),l(1.552,.223),l(.614,.479),l(.794,.224),l(.486,-.001),l(.342,.197),l(.173,.226),l(.26,.819),l(.39,.564),l(.688,.591),l(.378,.126),l(.678,.14),l(1.031,.083),l(.447,.07),l(.973,.224),l(.639,.224),l(.552,.281),l(1.289,.788),l(.84,.464),l(.465,.013),l(.441,-.128),l(.758,-.411),l(.706,-.623),l(.3,-.523),l(0,-.254),l(-.276,-.621),l(-.112,-.579),l(.044,-.41),l(.237,-.537),l(.661,-.58),l(.333,-.198),l(.554,-.241),l(.644,-.298),l(1.376,-.413),l(1.205,.054),l(.728,.154),l(.844,.365),l(.188,.169),l(.043,.508),l(.281,.253),l(.301,.014),l(.945,.125),l(.712,.309),l(.45,.027),l(1.286,.04),l(.302,.197),l(.068,.381),l(.276,.296),l(-.099,.208),l(-.369,.228),l(-.21,.34),l(.354,1.283),l(-.231,.425),l(-.322,.553),l(-.056,.311),l(.185,.945),l(.388,.916),l(.042,.367),l(-.015,.988),l(-.019,3.869),l(-.016,1.468),l(-.008,2.048),l(-.001,.692),l(.045,2.81),l(-.021,1.342),l(.011,2.612),
+N(478.212,134.714),l(-.834,-1.746),l(-.796,-1.944),l(-.124,-.289),l(.109,-.066),l(.679,-.851),l(.219,-.438),l(.183,-.507),l(.171,-.566),l(.188,-.822),l(.116,.018),l(.137,-.093),l(.006,-.204),l(.028,-.315),l(.372,-.051),l(.151,.022),l(.07,.099),l(.355,-.07),l(.009,-.167),l(.067,-.193),l(.088,-.041),l(.07,.023),l(.183,.346),l(.201,.128),l(.021,.183),l(-.047,.122),l(.082,.085),l(-.102,.063),l(-.037,.119),l(.065,.411),l(-.026,.278),l(-.062,.174),l(-.033,.847),l(-.07,.749),l(-.133,.283),l(.004,.409),l(-.3,.891),l(-.517,1.09),l(.015,.818),l(-.292,.919),l(-.107,.175),l(-.067,.068),l(-.042,.042),
+N(495.751,163.817),l(-.03,-.184),l(-.112,-.537),l(-.508,-.945),l(-.73,-.987),l(-.438,-.493),l(-.846,-.69),l(-.51,-.875),l(-.814,-1.876),l(-.474,-.889),l(-.28,-.409),l(-.794,-.507),l(-1.271,-.689),l(-.527,-.634),l(-.8,-1.17),l(-.081,-.96),l(-.061,-.776),l(-.002,-.89),l(-.104,-.381),l(-.312,-.663),l(-.944,-1.65),l(-.357,-.494),l(-.758,-.62),l(-.459,-.225),l(-.499,-.126),l(-.308,-.282),l(-.483,-.578),l(.149,-.692),l(-.111,-.437),l(-.474,-.818),l(-.747,-1.072),l(-.793,-.902),l(-1.069,-1.494),l(-.525,-.931),l(-.352,-.479),l(-.722,-.761),l(-.524,-.056),l(-.248,0),l(.077,-.296),l(.193,-.283),l(.311,-1.314),l(.104,-.583),l(.154,.017),l(2.079,.299),l(.975,-.782),l(.462,-.61),l(1.249,-.332),l(.24,-.072),l(.456,-.37),l(.765,-.724),l(-.698,-.885),l(-1.146,-1.32),l(.646,-.229),l(2.586,-.622),l(.97,-.26),l(.257,-.171),l(.46,-.44),l(.093,.056),l(1.129,.459),l(.757,.222),l(2.034,.934),l(1.14,.473),l(2.44,1.101),l(.258,.196),l(.399,.633),l(.141,.07),l(.973,-.048),l(.135,.366),l(-.118,.396),l(.047,.818),l(.118,.253),l(.812,.277),l(1.557,.697),l(4.048,.132),l(1.657,.259),l(.408,.054),l(.334,.619),l(.185,.239),l(1.07,.05),l(.644,-.044),l(.043,.121),l(.277,.648),l(.365,.494),l(.178,.663),l(.052,.113),l(.615,-.029),l(.248,.126),l(-.204,.237),l(.194,.187),l(.184,.282),l(.234,.067),l(.234,.27),l(.886,.168),l(.423,.437),l(-.07,.28),l(-.235,.035),l(-.111,.25),l(.316,.381),l(-.188,.593),l(-.122,.198),l(.165,.268),l(.302,.666),l(.149,-.117),l(.372,.282),l(.105,.616),l(.422,.696),l(-.028,.423),l(.222,.268),l(.16,.197),l(.287,.084),l(.136,-.007),l(.336,.083),l(1.043,2.198),l(.548,1.154),l(.261,.902),l(3.362,.375),l(3.387,.446),l(.839,.108),l(.584,-.469),l(.152,-.057),l(.581,.914),l(.155,1.453),l(-5.346,2.982),l(-2.35,1.213),l(-1.691,.815),l(-.169,.085),l(-1.148,.346),l(-3.097,1.035),l(-4.618,1.566),l(-.484,.229),l(-.041,.127),l(-.383,.397),l(-1.907,2.271),l(-2.042,2.667),l(-1.302,-2.703),l(-1.211,-2.45),l(-.452,-.012),l(-.715,.047),l(-.446,-.125),l(-.671,-.151),l(-.216,.1),l(-.174,.185),l(-.11,.495),l(.041,.678),l(-.113,.565),l(-.692,.563),
+N(476.458,130.735),l(.124,.289),l(.796,1.944),l(.834,1.746),l(-.38,.381),l(-.479,1.145),l(-.334,1.413),l(-.171,.593),l(-.18,.156),l(-.407,-.07),l(-.448,-.521),l(-.782,-.676),l(-.386,-.494),l(-.338,-.988),l(-.521,-.45),l(-.289,-.621),l(-.17,-.479),l(-.198,-.353),l(-.466,.17),l(-.267,.523),l(.604,1.34),l(.131,.381),l(.634,.86),l(.933,1.042),l(.473,1.199),l(.526,.973),l(.277,.818),l(.391,.465),l(.912,1.735),l(1.072,1.904),l(.428,.705),l(.586,.549),l(.451,.352),l(.151,.183),l(-.241,.17),l(-.285,.1),l(-.043,.155),l(.238,1.087),l(.252,.467),l(.127,.238),l(.812,.591),l(.397,.168),l(.406,.521),l(.416,.38),l(.311,.56),l(-10.382,-.006),l(-2.138,-.001),l(-2.774,.002),l(-2.513,.015),l(-2.268,-.029),l(-1.664,.01),l(-1.241,.007),l(-1.614,-.019),l(-.914,.005),l(-.819,.089),l(-.011,-2.612),l(.021,-1.342),l(-.045,-2.81),l(.001,-.692),l(.008,-2.048),l(.016,-1.468),l(.019,-3.869),l(.015,-.988),l(-.042,-.367),l(-.388,-.916),l(-.185,-.945),l(.056,-.311),l(.322,-.553),l(.231,-.425),l(-.354,-1.283),l(.21,-.34),l(.369,-.228),l(.099,-.208),l(.337,.168),l(.553,-.015),l(.628,-.1),l(.786,-.001),l(1.513,.293),l(.587,.115),l(.779,.122),l(.721,.154),l(.348,.409),l(.4,0),l(.928,.083),l(.998,.394),l(.628,.069),l(.245,-.127),l(.72,-.538),l(.925,-.397),l(.837,-.186),l(.78,-.27),l(.375,-.072),l(.346,.056),l(.535,-.001),l(.723,.126),l(.202,.465),l(.596,.366),l(.518,-.156),l(.64,.267),l(.382,.027),l(.561,-.401),l(.241,.179),l(.277,.056),l(.674,.13),l(.338,-.062),l(.46,-.165),l(.51,-.308),
+N(580.625,132.873),l(.24,.43),l(.299,.05),l(.276,-.314),l(.134,-.513),l(.275,.066),l(.186,-.182),l(1.079,.199),l(.132,.612),l(.867,.264),l(.726,.595),l(.472,.215),l(.15,-.132),l(.454,.281),l(.657,.794),l(.158,-.166),l(.71,-.116),l(.289,.166),l(.178,.38),l(-.069,.281),l(1.451,.893),l(.333,-.248),l(.326,.017),l(-.175,.396),l(.014,.265),l(.935,.066),l(.365,-.066),l(.54,.496),l(.141,.463),l(.237,-.099),l(-.01,-.364),l(.685,.38),l(.271,-.083),l(.08,-.331),l(.407,0),l(.63,.281),l(.319,.364),l(.849,-.066),l(.341,.116),l(.339,-.281),l(.655,.159),l(.037,.022),l(-.318,.761),l(-.07,.876),l(.429,.827),l(-.311,.694),l(-.336,-.05),l(-.687,.132),l(-.271,-.083),l(-.357,.132),l(-.399,-.116),l(-.268,-.364),l(-.606,.297),l(-.847,-.364),l(-.721,-.148),l(-.379,.231),l(-.312,-.248),l(.034,-.331),l(-.313,-.066),l(-.584,.281),l(-.618,-.265),l(-.286,-.281),l(-.663,-.149),l(.101,-.446),l(-.142,-.231),l(-.643,-.066),l(-.494,-.298),l(-.582,.347),l(-.482,-.265),l(-.503,0),l(-.087,.215),l(-.15,.066),l(-.304,-.198),l(-.835,-.166),l(-.182,-.397),l(-.538,.066),l(-1.027,-.595),l(-.231,.166),l(-1.242,-.678),l(-.305,-.529),l(-.704,-.149),l(-.665,-.479),l(-.466,.083),l(-.63,-.38),l(-.039,-.248),l(.218,-.43),l(.309,-.397),l(-.04,-.396),l(.221,-.265),l(-.008,-.364),l(.281,-.116),l(1.07,-.909),
+N(374.125,167.166),l(-1.41,-.924),l(-.661,-.604),l(-.537,-.788),l(-.292,-.662),l(-.15,-.183),l(-.312,-.154),l(-.567,-.053),l(-.655,-.307),l(-.695,-.561),l(-.604,-.194),l(-.567,-.025),l(-1.209,.12),l(-1.821,.194),l(-.523,.417),l(.06,-.502),l(.563,-1.301),l(.188,-.819),l(.13,-1.13),l(-.162,-1.101),l(-.3,-.791),l(-.624,-.747),l(.267,-.283),l(.182,-.424),l(.067,-.975),l(-.065,-.537),l(-.174,-.353),l(-.808,-.817),l(-.297,-.112),l(-.393,.438),l(-.055,-.197),l(-.013,-.381),l(.08,-.689),l(.474,.013),l(5.055,.056),l(2.396,.014),l(.732,-.033),l(.212,.027),l(-.051,-1.102),l(-.164,-1.539),l(.01,-.707),l(.249,-.383),l(.575,-.427),l(.726,-.315),l(.809,-.287),l(.144,-.128),l(.099,-2.6),l(.07,-2.261),l(.047,-.509),l(.557,-.074),l(6.005,.022),l(.56,.011),l(.104,-.396),l(-.002,-.65),l(.03,-1.752),l(2.829,1.509),l(4.12,2.42),l(1.414,.91),l(-.523,.13),l(-3.231,.089),l(.049,.776),l(.908,7.962),l(.19,1.468),l(.178,1.736),l(.325,2.753),l(.202,2.386),l(.186,1.468),l(.724,.787),l(-.379,1.613),l(-6.457,.01),l(-1.953,.026),l(-.945,.344),l(-.387,.031),l(-.485,-.054),l(-.713,-.137),l(-.535,-.124),l(-.06,.212),l(.055,.296),l(-.107,.269),l(-.454,-.082),l(-.214,-.168),l(-.568,-.83),l(-.261,-.111),l(-.402,.073),l(-.252,.256),l(-.181,.552),l(-.018,.607),l(-.332,.284),
+N(476.114,191.139),l(-.563,.54),l(-.626,.314),l(-.367,.016),l(-.303,-.196),l(-.303,-.097),l(-.88,.132),l(-.881,.33),l(-.911,.048),l(-.942,-.234),l(-.495,-.011),l(-.464,.087),l(-.496,.229),l(-1.288,-1.32),l(-1.032,-.926),l(-.207,-.083),l(-.258,.157),l(-.436,.582),l(-.16,.1),l(-.684,-.631),l(-.384,-.012),l(-.529,.37),l(-.258,.242),l(-.352,.016),l(-.366,-.195),l(-.525,-.477),l(-.348,-.493),l(-.795,-.772),l(-.143,-.239),l(-.031,-.07),l(.083,-.679),l(-.157,-.352),l(-.558,-.477),l(-.814,-.165),l(-.367,-.224),l(-.285,-.436),l(-.059,-.72),l(-.206,-.366),l(-.207,-.168),l(-.717,-.434),l(-.558,-.378),l(-.445,-.351),l(-.173,-.395),l(.148,-.481),l(-.223,-.267),l(-.351,-.196),l(-.799,-.235),l(-.797,-.447),l(-.223,-.225),l(-.252,-.493),l(-.207,-.126),l(-.272,.001),l(-.802,.019),l(-.158,-.211),l(-.01,-.664),l(.416,-1.472),l(-.122,-.536),l(-.347,-.549),l(-1.342,-1.673),l(.15,-.425),l(-.026,-.367),l(-.266,-.465),l(-.444,-.407),l(-.155,-.295),l(-.137,-.522),l(-.221,-1.228),l(-.141,-.225),l(-.338,-.012),l(-.517,.088),l(-.219,-.352),l(.316,-.609),l(.542,-.596),l(.087,-.34),l(-.342,-.662),l(.053,-.24),l(.718,-.428),l(.149,-.212),l(-.131,-.677),l(.122,-.438),l(.583,-.809),l(.417,-1.245),l(.229,-.143),l(1.245,-.05),l(.839,.009),l(.04,-.283),l(-.031,-1.229),l(-.036,-1.002),l(.038,-.749),l(-.085,-2.5),l(.036,-.636),l(.016,-.946),l(.02,-1.045),l(.073,-1.13),l(.52,.011),l(1.561,.019),l(.088,-.17),l(-.033,-3.078),l(.021,-1.003),l(.819,-.089),l(.914,-.005),l(1.614,.019),l(1.241,-.007),l(1.664,-.01),l(2.268,.029),l(2.513,-.015),l(2.774,-.002),l(2.138,.001),l(10.382,.006),l(.229,.414),l(.499,1.115),l(.281,3.501),l(.319,1.637),l(.182,.211),l(.625,.394),l(.595,.366),l(.617,.507),l(.491,.197),l(.254,.223),l(-.238,.199),l(-.277,.327),l(-.306,.566),l(-.369,.242),l(-.511,.172),l(-.427,.116),l(-.153,.142),l(-.235,.496),l(-.348,.171),l(-.73,.033),l(-.204,.552),l(-.038,.452),l(-.202,.862),l(-.242,.722),l(-.541,1.302),l(-.068,.495),l(.092,.903),l(-.013,.679),l(-.001,.083),l(-.148,.947),l(-.398,1.231),l(-.214,1.061),l(-1.04,.331),l(-.414,.37),l(-.693,1.134),l(-.154,.34),l(-.191,1.088),l(-.141,1.074),l(-.197,.185),l(-.274,.044),l(-.431,-.096),l(-.259,.072),l(-.163,.114),l(-.187,1.103),l(-.115,.933),l(-.2,1.272),l(.039,.522),l(-.229,1.159),l(-.469,.299),l(-.288,-.012),l(-.928,-.122),l(-.321,.03),l(-.188,.806),l(-.054,.466),l(.094,.141),l(.479,.11),l(.734,.123),l(.334,.167),l(.805,.913),l(1.06,1.067),l(.751,1.464),l(.345,.732),l(.348,.421),l(.462,.28),l(.415,.097),l(.269,.309),l(.117,.988),l(-.034,.17),l(-.018,.141),l(-.079,-.028),l(-.464,.017),l(-1.009,.133),l(-.832,.005),l(-.671,-.052),l(-.291,.327),l(-.678,.795),
+N(518.402,163.079),l(-.282,.097),l(-.538,.27),l(-.656,.566),l(-.265,.297),l(-.166,.508),l(-.062,.41),l(-.41,.326),l(-1.418,.652),l(-2.27,.641),l(-1.285,.412),l(-.843,.312),l(-.356,.297),l(-.473,.622),l(-.436,.269),l(-.506,.114),l(-.593,-.069),l(-.521,.072),l(-.83,.439),l(-.65,.396),l(-.956,.397),l(-.752,.199),l(-1.16,.003),l(-.562,-.013),l(-.297,.128),l(-.386,.312),l(-.272,.297),l(-.45,.312),l(-.511,.241),l(-.389,.043),l(-.239,-.042),l(-.535,.411),l(-.839,.058),l(-.494,-.112),l(-.623,-.437),l(-.17,-.155),l(-.317,-.437),l(-.084,-.254),l(.18,-.721),l(-.081,-.635),l(-.312,-.507),l(-.341,-1.171),l(-.572,-1.919),l(-.072,-.438),l(.268,-.707),l(-.124,-.748),l(.692,-.563),l(.113,-.565),l(-.041,-.678),l(.11,-.495),l(.174,-.185),l(.216,-.1),l(.671,.151),l(.446,.125),l(.715,-.047),l(.452,.012),l(1.211,2.45),l(1.302,2.703),l(2.042,-2.667),l(1.907,-2.271),l(.383,-.397),l(.041,-.127),l(.484,-.229),l(4.618,-1.566),l(3.097,-1.035),l(1.148,-.346),l(.169,-.085),l(.092,.663),l(.226,.634),l(.604,.971),l(.933,1.364),l(.127,.253),l(-.006,.296),l(.483,.689),l(.241,.306),
+N(494.64,172.627),l(-.261,-.166),l(-.476,-.633),l(-.475,-.159),l(-.437,-.911),l(-1.267,-.792),l(-.277,-.594),l(-.673,-.673),l(-.594,-.119),l(-.871,-.554),l(-.555,.079),l(-.158,-.158),l(-.237,.04),l(-.277,-.198),l(-.356,.159),l(-.476,.079),l(-.277,-.436),l(-.158,.237),l(-.436,.198),l(-.792,.079),l(-.554,-.594),l(-.238,0),l(-.396,-.317),l(-.832,1.663),l(-.436,-.871),l(-.475,.079),l(-.277,.356),l(-.396,-.08),l(-.349,.041),l(.013,-.679),l(-.092,-.903),l(.068,-.495),l(.541,-1.302),l(.242,-.722),l(.202,-.862),l(.038,-.452),l(.204,-.552),l(.73,-.033),l(.348,-.171),l(.235,-.496),l(.153,-.142),l(.427,-.116),l(.511,-.172),l(.369,-.242),l(.306,-.566),l(.277,-.327),l(.238,-.199),l(.098,.129),l(.718,2.102),l(.442,1.623),l(.689,1.919),l(.618,.832),l(.205,-.212),l(-.072,-.479),l(.093,-.226),l(.31,.253),l(.4,.677),l(.384,.395),l(.534,-.043),l(.242,.014),l(1.338,1.282),l(.809,.916),l(.124,.099),l(.706,.055),l(.618,.874),l(.021,.24),l(-.025,.198),l(.118,.212),l(.507,.182),l(.915,.869),l(-.075,.094),l(-.529,.78),l(-.331,-.182),l(-.396,-.125),l(-.214,.114),l(-.055,.085),
+N(370.147,172.035),l(-2.301,-.043),l(-1.045,.006),l(-.505,.384),l(-.51,.187),l(-.74,-.024),l(-.819,.047),l(-.463,.139),l(-.009,-.003),l(-.278,-.226),l(-.169,-.409),l(.104,-.424),l(-.095,-.55),l(-.018,-.198),l(.001,-.046),l(1.695,.014),l(0,-.434),l(.155,0),l(.341,-.016),l(.186,-.077),l(.248,.062),l(.294,-.046),l(.124,-.093),l(.016,-.263),l(.077,-.078),l(.14,-.016),l(.155,.155),l(.232,.124),l(.356,.108),l(.046,.108),l(.139,.047),l(.217,-.031),l(.263,.108),l(.186,.17),l(.434,0),l(.186,-.108),l(.263,-.108),l(.279,0),l(.108,-.124),l(.016,-.124),l(-.155,-.217),l(-.202,-.077),l(-.201,.031),l(-.294,.093),l(-.108,.093),l(-.248,.062),l(-.279,-.186),l(-.031,-.186),l(-.186,-.108),l(-.17,-.015),l(-.186,.124),l(-.139,-.108),l(-.108,-.217),l(-.155,-.108),l(-.201,.031),l(-.17,-.062),l(-.387,.17),l(-.108,-.108),l(-.155,.046),l(-.202,.124),l(-.093,.294),l(-1.664,0),l(-.007,-.067),l(-.028,-.269),l(-.377,-.268),l(-.068,-.155),l(-.057,-.367),l(-.386,-.635),l(-.399,-.494),l(-.379,-.31),l(-.472,-.183),l(.54,-.34),l(.723,-.75),l(.588,-1.004),l(.334,-.82),l(.099,-.826),l(.523,-.417),l(1.821,-.194),l(1.209,-.12),l(.567,.025),l(.604,.194),l(.695,.561),l(.655,.307),l(.567,.053),l(.312,.154),l(.15,.183),l(.292,.662),l(.537,.788),l(.661,.604),l(1.41,.924),l(-.506,.399),l(-.057,.339),l(.251,1.1),l(.144,.663),l(.22,.479),l(.181,.197),l(.554,.322),l(.265,.337),l(.082,.833),l(-.004,.565),l(-.062,.142),l(-.146,-.042),l(-.963,.091),l(-.658,.074),l(-.725,-.081),l(-.503,-.209),l(-.795,-.32),l(-1.255,-.021),
+N(495.973,175.881),l(-.363,.807),l(.083,.409),l(.428,.732),l(.587,.844),l(.732,.801),l(.596,.547),l(.634,.321),l(.54,.209),l(4.26,1.443),l(1.447,.472),l(1.875,-.04),l(.236,.154),l(-4.087,4.205),l(-1.562,1.69),l(-.813,.909),l(-.8,.004),l(-1.693,-.046),l(-.626,.088),l(-.562,.215),l(-.388,.214),l(-.502,.497),l(-.294,.426),l(-.337,.115),l(-1.216,.078),l(-.305,.101),l(-.453,.511),l(-1.103,-.106),l(-.461,-.181),l(-.46,-.336),l(-.271,-.098),l(-.852,.358),l(-.675,.343),l(-.258,.199),l(-.71,.753),l(-.16,.114),l(-.847,-.094),l(-.67,-.193),l(-1.373,-.133),l(-.335,-.041),l(-2.353,-1.525),l(-.604,-.293),l(-.749,-.193),l(-1.054,-.149),l(-.319,-.069),l(.018,-.141),l(.034,-.17),l(-.117,-.988),l(-.269,-.309),l(-.415,-.097),l(-.462,-.28),l(-.348,-.421),l(-.345,-.732),l(-.751,-1.464),l(-1.06,-1.067),l(-.805,-.913),l(-.334,-.167),l(-.734,-.123),l(-.479,-.11),l(-.094,-.141),l(.054,-.466),l(.188,-.806),l(.321,-.03),l(.928,.122),l(.288,.012),l(.469,-.299),l(.229,-1.159),l(-.039,-.522),l(.2,-1.272),l(.115,-.933),l(.187,-1.103),l(.163,-.114),l(.259,-.072),l(.431,.096),l(.274,-.044),l(.197,-.185),l(.141,-1.074),l(.191,-1.088),l(.154,-.34),l(.693,-1.134),l(.414,-.37),l(1.04,-.331),l(.214,-1.061),l(.398,-1.231),l(.148,-.947),l(.001,-.083),l(.349,-.041),l(.396,.08),l(.277,-.356),l(.475,-.079),l(.436,.871),l(.832,-1.663),l(.396,.317),l(.238,0),l(.554,.594),l(.792,-.079),l(.436,-.198),l(.158,-.237),l(.277,.436),l(.476,-.079),l(.356,-.159),l(.277,.198),l(.237,-.04),l(.158,.158),l(.555,-.079),l(.871,.554),l(.594,.119),l(.673,.673),l(.277,.594),l(1.267,.792),l(.437,.911),l(.475,.159),l(.476,.633),l(.261,.166),l(-.594,.921),l(-.488,.61),l(-.105,.254),l(-.029,.396),l(.202,1.157),l(.5,-.074),l(.892,-.246),l(.4,.04),l(.556,.195),
+N(364.011,169.929),l(1.664,0),l(.093,-.294),l(.202,-.124),l(.155,-.046),l(.108,.108),l(.387,-.17),l(.17,.062),l(.201,-.031),l(.155,.108),l(.108,.217),l(.139,.108),l(.186,-.124),l(.17,.015),l(.186,.108),l(.031,.186),l(.279,.186),l(.248,-.062),l(.108,-.093),l(.294,-.093),l(.201,-.031),l(.202,.077),l(.155,.217),l(-.016,.124),l(-.108,.124),l(-.279,0),l(-.263,.108),l(-.186,.108),l(-.434,0),l(-.186,-.17),l(-.263,-.108),l(-.217,.031),l(-.139,-.047),l(-.046,-.108),l(-.356,-.108),l(-.232,-.124),l(-.155,-.155),l(-.14,.016),l(-.077,.078),l(-.016,.263),l(-.124,.093),l(-.294,.046),l(-.248,-.062),l(-.186,.077),l(-.341,.016),l(-.155,0),l(0,.434),l(-1.695,-.014),l(.019,-.477),l(.173,-.198),l(.434,-.058),l(.093,-.155),l(-.006,-.059),
+N(495.973,175.881),l(-.556,-.195),l(-.4,-.04),l(-.892,.246),l(-.5,.074),l(-.202,-1.157),l(.029,-.396),l(.105,-.254),l(.488,-.61),l(.594,-.921),l(.055,-.085),l(.214,-.114),l(.396,.125),l(.331,.182),l(.529,-.78),l(.075,-.094),l(.627,.596),l(.285,.465),l(.036,.282),l(-.118,.113),l(-.361,.185),l(-.438,.1),l(-.56,.312),l(-.566,.467),l(.253,.127),l(.645,-.058),l(.321,.013),l(.434,.124),l(-.114,.26),l(-.37,.468),l(-.34,.567),
+N(363.763,172.732),l(.463,-.139),l(.819,-.047),l(.74,.024),l(.51,-.187),l(.505,-.384),l(1.045,-.006),l(2.301,.043),l(-.111,.792),l(.115,.847),l(-.186,.312),l(-.333,.186),l(-.513,.031),l(-.401,.017),l(-.381,.186),l(-.789,.64),l(-.321,.372),l(-.047,-.126),l(-.192,0),l(-.501,-.14),l(-.165,-.254),l(.121,-.41),l(.33,-.438),l(.253,-.212),l(-.131,-.141),l(-.372,-.112),l(-.498,.015),l(-.415,.17),l(-.161,0),l(-.616,-.281),l(-.36,-.296),l(-.069,-.24),l(-.323,-.084),l(-.316,-.137),
+N(383.005,177.596),l(-.379,.397),l(-.264,.623),l(.214,.409),l(.695,.405),l(.197,.31),l(-.125,.283),l(-.332,.37),l(.309,.351),l(.648,.561),l(.051,.226),l(-.19,.143),l(-.304,-.012),l(-.548,-.223),l(-.304,.03),l(-.158,.199),l(-.03,.127),l(.296,.549),l(.179,.21),l(-.188,.354),l(-.602,.554),l(-.047,.099),l(-.339,-.224),l(-.337,-.097),l(-.143,.086),l(-.756,.922),l(-.321,-.026),l(-.404,-.322),l(-.277,-.323),l(.044,-.283),l(-.009,-.65),l(-.22,-.846),l(-.165,-.366),l(-.338,-.097),l(-.528,.046),l(-.367,.143),l(-.252,.242),l(-.193,.376),l(-.26,-.656),l(-.165,-1.369),l(-.252,-.761),l(-.475,-.619),l(-.456,-.421),l(-.42,-.224),l(-.466,-.04),l(-1.137,.148),l(-.594,-.039),l(-.238,.157),l(-.643,.866),l(-1.088,1.235),l(.051,-.392),l(-.312,-.55),l(-.764,-.775),l(-.122,-.649),l(-.84,-.366),l(-.908,-.563),l(-.277,-.296),l(.09,-.396),l(-.053,-.311),l(-.547,-.041),l(-.323,-.098),l(-.115,-.155),l(.059,-.311),l(-.038,-.1),l(.321,-.372),l(.789,-.64),l(.381,-.186),l(.401,-.017),l(.513,-.031),l(.333,-.186),l(.186,-.312),l(-.115,-.847),l(.111,-.792),l(1.255,.021),l(.795,.32),l(.503,.209),l(.725,.081),l(.658,-.074),l(.963,-.091),l(.146,.042),l(.113,.028),l(.18,.183),l(.882,.715),l(.536,.265),l(.252,-.256),l(.475,-.413),l(.338,.026),l(.356,.153),l(.565,.152),l(.43,-.243),l(.3,-.327),l(.684,-.428),l(.323,.055),l(.246,.281),l(.022,.339),l(.271,.832),l(.265,.451),l(.474,.478),l(.349,.718),l(.194,1.143),l(.559,.901),
+N(266.015,188.956),l(.103,.169),l(-.163,.326),l(-.592,.385),l(-1.74,.9),l(-.807,.23),l(-.557,.074),l(-.465,-.054),l(-.284,.115),l(-.232,1.117),l(-.348,.115),l(-.628,-.618),l(-.344,-.224),l(-1.149,.035),l(-.385,-.04),l(-.896,-.461),l(-.309,-.125),l(-.159,.029),l(-.041,.184),l(.616,.688),l(.391,.69),l(.302,1.524),l(.079,.55),l(.166,.239),l(.96,.051),l(.434,.125),l(.15,.253),l(-.265,.27),l(-.569,.272),l(-.652,.131),l(-.203,.199),l(-.259,.666),l(-.235,.213),l(-.652,.173),l(-.554,.286),l(-.74,.654),l(-.645,.739),l(-.271,.016),l(-.186,-.776),l(-.083,-.183),l(-.757,.697),l(-.414,.073),l(-.482,-.223),l(-.694,-.546),l(-.432,-.054),l(-.199,-.437),l(-.088,-.452),l(-.161,-.861),l(-.138,-.437),l(-.148,-.168),l(-.797,-1.182),l(-.51,-.491),l(.479,-.526),l(.731,-.612),l(-.121,-.282),l(-.486,-.647),l(-.256,-.437),l(-.447,-.789),l(-.162,-.804),l(-.048,-.367),l(-.035,-.438),l(-.026,-.254),l(.147,-.326),l(.379,-.511),l(.085,-1.004),l(.409,-.525),l(-.644,-.081),l(-1.99,.224),l(-.76,.174),l(-.522,.13),l(-.144,0),l(-.554,-.576),l(-.847,-.998),l(-.188,-.253),l(-.64,-.321),l(-.521,-.181),l(-1.167,.05),l(-1.163,.12),l(-.496,.017),l(-.397,-.252),l(-.429,-.548),l(-.401,-.309),l(-.099,-.353),l(.226,-1.132),l(-.103,-.395),l(-.855,-1.45),l(-.31,-.606),l(-.384,.017),l(-.234,.1),l(-.402,-.025),l(.709,-1.191),l(.241,-.722),l(.172,-.722),l(.99,-1.758),l(.381,-.059),l(.227,.027),l(.129,-.396),l(-.048,-.497),l(.056,-.288),l(.414,-.2),l(.534,-.156),l(.84,-.171),l(.128,.105),l(-.9,.151),l(-.731,.312),l(-.145,.212),l(.19,.607),l(.142,.407),l(.224,.126),l(-.043,.145),l(.153,.579),l(-.135,.367),l(-.327,.364),l(-.348,.824),l(-.137,.368),l(.253,.479),l(.288,.253),l(.25,.72),l(.341,.353),l(.523,-.114),l(.184,-.156),l(.419,-.255),l(.12,-.142),l(.066,-.523),l(-.167,-.649),l(-.21,-.282),l(-.438,-.804),l(-.136,-.135),l(-.118,-.395),l(-.247,-.18),l(.239,-.099),l(.095,-.251),l(-.204,-.144),l(1,-.379),l(1.085,-.327),l(.998,-.272),l(.086,-.225),l(.69,-.086),l(.143,-.008),l(-.042,-.157),l(-.055,-.198),l(-.125,-.036),l(-.039,-.108),l(-.128,-.072),l(-.226,.071),l(-.156,.027),l(-.229,-.012),l(-.315,-.55),l(.109,-.254),l(.337,-.213),l(.367,-.043),l(.09,.112),l(.14,.368),l(.186,.162),l(-.001,.148),l(.026,.193),l(.068,.09),l(.004,.198),l(.253,.258),l(.329,-.02),l(.699,.111),l(.455,.07),l(.593,.196),l(.323,.254),l(.393,.564),l(.156,.635),l(.358,.324),l(.359,.084),l(1.02,-.129),l(.928,-.059),l(.59,-.058),l(.799,-.059),l(.714,.125),l(.4,.479),l(.267,.169),l(.578,.253),l(.49,.14),l(1.094,.04),l(.382,-.057),l(.388,-.227),l(1.042,-.807),l(.47,-.185),l(.453,.042),l(.959,-.073),l(1.152,-.073),l(.919,.055),l(.248,.112),l(-.056,.141),l(-.294,.185),l(-.854,-.041),l(-.433,.015),l(-.083,.212),l(.059,.184),l(.593,.253),l(.609,.535),l(.195,.649),l(.246,-.523),l(.185,-.142),l(.415,.253),l(.483,.027),l(.374,.098),l(.258,.338),l(.918,.394),l(.464,.295),l(-.729,.496),l(-.161,.65),l(-.214,.226),l(-1.055,.417),l(.5,.064),l(.598,.098),l(.368,-.029),l(.33,-.142),l(.929,-.03),l(.725,.083),l(.84,.274),l(.095,.296),l(-.061,.41),l(-1.655,1.239),l(-.101,.255),l(.074,.212),l(.62,.604),l(.141,.282),l(-.308,.299),l(-.41,.144),l(-1.032,.19),l(-.061,.452),l(.008,.58),l(-.395,.539),l(-.071,.212),l(.324,.521),l(.732,.745),l(.503,.647),
+N(493.044,204.258),l(-1.223,-1.771),l(-.027,-.932),l(-.03,-1.43),l(-.042,-2.045),l(-.003,-1.017),l(0,-.438),l(.016,-.848),l(.004,-1.215),l(.002,-.508),l(1.649,-2.467),l(.453,-.511),l(.305,-.101),l(1.216,-.078),l(.337,-.115),l(.294,-.426),l(.502,-.497),l(.388,-.214),l(.562,-.215),l(.626,-.088),l(1.693,.046),l(.8,-.004),l(.813,-.909),l(1.562,-1.69),l(4.087,-4.205),l(-.236,-.154),l(-1.875,.04),l(-1.447,-.472),l(-4.26,-1.443),l(-.54,-.209),l(-.634,-.321),l(-.596,-.547),l(-.732,-.801),l(-.587,-.844),l(-.428,-.732),l(-.083,-.409),l(.363,-.807),l(.34,-.567),l(.37,-.468),l(.114,-.26),l(.154,.044),l(.935,1.142),l(.586,.62),l(.243,.381),l(.265,.211),l(.372,-.071),l(.417,-.001),l(.465,.027),l(.372,-.071),l(.572,-.27),l(.836,-.425),l(.585,-.157),l(.397,.098),l(.76,.267),l(.549,-.072),l(.56,-.326),l(.779,-.566),l(.247,-.127),l(.447,.041),l(.479,.098),l(.419,-.043),l(1.195,-.482),l(.288,.027),l(.682,.196),l(.74,-.03),l(.764,-.185),l(.964,-.327),l(.9,-.666),l(.47,-.382),l(.604,.154),l(.391,.211),l(.08,.014),l(.147,.268),l(-.414,.919),l(.021,.564),l(.132,.621),l(-.165,.452),l(-.375,.509),l(-.028,.678),l(-.047,.833),l(-.163,.509),l(-1.264,2.262),l(-.842,.792),l(-.122,.311),l(.102,.353),l(-.893,1.569),l(-.834,1.272),l(-.214,.947),l(-.351,.636),l(-.712,1.117),l(-.874,1.188),l(-1.159,1.498),l(-.384,.439),l(-2.274,2.504),l(-1.82,1.557),l(-2.164,1.121),l(-.593,.382),l(-1.28,1.09),l(-1.74,1.755),l(-.06,.061),l(-1.055,1.1),l(-1.235,1.569),l(-.615,.835),l(.1,.353),l(-.094,.276),
+N(264.768,176.039),l(-.128,.225),l(-.115,.067),l(-.029,.135),l(.039,.25),l(-.058,.086),l(.125,.376),l(-.039,.424),l(-.453,.154),l(-.135,-.01),l(-.144,.039),l(-.482,-.039),l(-.192,.039),l(-.087,-.048),l(-.356,0),l(-.02,-.058),l(.039,-.067),l(.202,-.029),l(.222,-.135),l(.019,-.087),l(.106,.02),l(.154,.01),l(.135,-.145),l(-.096,-.279),l(.048,-.125),l(.029,-.183),l(-.067,-.125),l(-.097,-.135),l(-.279,-.048),l(.116,-.096),l(.164,-.019),l(.231,-.029),l(.115,-.087),l(.385,.02),l(.106,-.039),l(.299,-.067),l(.244,.006),
+N(654.075,190.187),l(.206,-.125),l(.63,-.114),l(.656,-.938),l(.241,-.07),l(-.069,.268),l(.122,.087),l(.187,-.046),l(.11,.174),l(.148,.444),l(-.024,.111),l(-.013,.247),l(.197,.197),l(.025,.086),l(-1.234,.42),l(-.383,.271),l(-.309,-.271),l(-.111,-.259),l(-.234,.012),l(-.062,-.37),l(-.084,-.126),
+N(493.044,204.258),l(-.602,.389),l(-.557,.171),l(-.385,-.112),l(-.086,.777),l(-.282,.367),l(-.67,.115),l(-.394,.382),l(-.088,.48),l(.006,.353),l(-.356,.622),l(-.964,1.358),l(.092,.536),l(-.337,.65),l(-.25,.255),l(-.334,.1),l(-.084,.152),l(-1.067,-.807),l(-2.427,-1.752),l(-.07,-.239),l(.116,-.552),l(-.137,-.381),l(-3.553,-1.984),l(-4.663,-2.568),l(-1.448,.033),l(1.144,-2.479),l(.105,-.229),l(.656,-.835),l(.985,-.938),l(.477,-.525),l(.43,-.695),l(.143,-.566),l(-.048,-.664),l(-.223,-.606),l(-.224,-.352),l(-.732,-1.069),l(-.174,-.465),l(-.027,-.861),l(-.126,-.226),l(-.477,-.463),l(-.3,-.493),l(.678,-.795),l(.291,-.327),l(.671,.052),l(.832,-.005),l(1.009,-.133),l(.464,-.017),l(.079,.028),l(.319,.069),l(1.054,.149),l(.749,.193),l(.604,.293),l(2.353,1.525),l(.335,.041),l(1.373,.133),l(.67,.193),l(.847,.094),l(.16,-.114),l(.71,-.753),l(.258,-.199),l(.675,-.343),l(.852,-.358),l(.271,.098),l(.46,.336),l(.461,.181),l(1.103,.106),l(-1.649,2.467),l(-.002,.508),l(-.004,1.215),l(-.016,.848),l(0,.438),l(.003,1.017),l(.042,2.045),l(.03,1.43),l(.027,.932),l(1.223,1.771),
+N(466.196,203.275),l(.188,-.298),l(.076,-.27),l(-.057,-.748),l(.025,-.734),l(-.021,-.593),l(.107,-.507),l(.217,-1.02),l(.395,-.681),l(.255,-.284),l(1.241,-.996),l(1.195,-1.066),l(.191,-.453),l(-.111,-.31),l(-.271,-.182),l(-.479,-.04),l(-.191,-.027),l(-.128,-.253),l(.26,-1.88),l(.018,-.424),l(-.159,-.183),l(-.063,-.028),l(.496,-.229),l(.464,-.087),l(.495,.011),l(.942,.234),l(.911,-.048),l(.881,-.33),l(.88,-.132),l(.303,.097),l(.303,.196),l(.367,-.016),l(.626,-.314),l(.563,-.54),l(.3,.493),l(.477,.463),l(.126,.226),l(.027,.861),l(.174,.465),l(.732,1.069),l(.224,.352),l(.223,.606),l(.048,.664),l(-.143,.566),l(-.43,.695),l(-.477,.525),l(-.985,.938),l(-.656,.835),l(-.105,.229),l(-1.144,2.479),l(-4.659,0),l(-1.277,.05),l(-.319,.017),l(-.554,.398),l(-.458,.427),l(-.431,.045),l(-.546,-.223),l(-.064,-.042),
+N(713.621,206.298),l(.169,7.966),l(-.44,.822),l(.431,1.368),l(.046,.805),l(-.031,3.438),l(-.515,-.512),l(-.927,-.888),l(-.716,-.902),l(-.406,-.056),l(-.776,.101),l(-.739,.143),l(-.434,-.013),l(.091,-.382),l(.435,-.65),l(.006,-.283),l(-.561,-.521),l(-.565,-.775),l(.028,-.226),l(.442,.111),l(.236,-.042),l(.135,-.113),l(-.467,-.409),l(-.595,-.408),l(-.287,-.381),l(-.275,-.648),l(-1.053,-1.693),l(-.508,-.394),l(-.467,-.282),l(-.604,-.196),l(-1.983,-.603),l(-1.26,-.379),l(-.613,-.069),l(-.705,-.238),l(-.63,-.323),l(.072,-.34),l(-.098,-.268),l(-.193,-.028),l(-.617,.101),l(-.389,-.07),l(-.412,-.196),l(-.408,-.395),l(-.209,-.579),l(.133,-.494),l(-.155,-.226),l(-.187,.113),l(-.234,.396),l(-.122,.664),l(-.251,.608),l(-.334,.269),l(-.696,.354),l(-.155,-.169),l(-.331,-.677),l(.022,-.155),l(.384,-.27),l(-.152,-.424),l(-.173,-.239),l(-.564,-.395),l(-.707,-.394),l(-.338,-.056),l(-.059,-.212),l(.038,-.226),l(.413,-.044),l(.388,.084),l(.603,.239),l(.158,-.029),l(.368,-.34),l(.525,-.41),l(.146,.056),l(.3,.269),l(1.021,-.045),l(.139,-.128),l(.09,-.522),l(-.063,-.409),l(-.238,.028),l(-.345,.199),l(-.604,.071),l(-.656,-.041),l(-.766,.044),l(-1.026,-.082),l(-.411,-.31),l(-.135,-.197),l(-.148,-.664),l(-.202,-.338),l(-.42,-.155),l(-1.249,-.124),l(.265,-.297),l(.058,-.255),l(.004,-.593),l(.463,-.029),l(.92,-.411),l(.49,-.383),l(.444,-.283),l(.352,.027),l(.4,.069),l(1.494,.646),l(.515,.169),l(.913,.153),l(.382,.705),l(.138,.396),l(-.283,.749),l(-.067,.381),l(.221,.381),l(.115,.494),l(.115,.48),l(.215,.521),l(.186,.197),l(.197,.127),l(.226,-.65),l(.085,.113),l(.087,.141),l(.309,1.073),l(.169,.169),l(.234,.183),l(.294,.112),l(.354,.056),l(.58,-.198),l(.504,-.439),l(1.192,-1.853),l(.352,-.015),l(1.078,-.215),l(.378,-.142),l(.045,-.085),l(.014,-.509),l(.219,-.17),l(1.1,-.609),l(.335,-.043),l(1.732,.759),l(2.129,.941),l(1.54,.52),l(1.299,.404),M(691.208,208.707),l(-.388,-.069),l(-.693,-.38),l(-.852,-.647),l(-.295,-.141),l(-.414,.028),l(-.059,.1),l(.024,.452),l(-.206,.028),l(-1.014,-.407),l(-.258,-.353),l(-.582,.199),l(-.289,.269),l(-.326,.185),l(-.186,-.184),l(-.312,-.451),l(-.245,-.451),l(.246,-.198),l(.303,-.029),l(.274,.056),l(1.104,.04),l(.574,.31),l(.319,-.015),l(.544,-.326),l(.414,-.015),l(.534,.126),l(.857,.21),l(.499,.395),l(.293,.395),l(.179,.621),l(-.049,.254),M(682.045,208.699),l(-.419,-.056),l(-.715,-.493),l(-.232,-.451),l(.146,-.283),l(.603,-.1),l(.766,-.044),l(.246,.126),l(.256,.311),l(.313,.197),l(.108,.226),l(-.067,.226),l(-.125,.057),l(-.879,.285),M(707.635,219.095),l(-1.11,-.209),l(.589,-1.032),l(.56,-.708),l(.407,-.269),l(.427,-.072),l(.527,.338),l(.198,.24),l(-.11,.184),l(-.324,.637),l(-.256,.17),l(-.638,.693),l(-.27,.028),M(673.797,218.703),l(-.562,.257),l(.034,.233),l(-.886,.326),l(-.582,.274),l(-.339,-.041),l(-.453,.325),l(-.504,-.069),l(-.427,-.112),l(-.378,.255),l(-.3,.058),l(-.358,-.07),l(-.58,-.196),l(-1.046,-.04),l(-.316,.043),l(-.211,-.564),l(.027,-.24),l(.383,-.198),l(.672,-.199),l(.528,-.016),l(1.142,.407),l(.445,.324),l(.338,.013),l(.326,-.297),l(.464,-.016),l(.429,-.071),l(.414,.187),l(.467,-.116),l(-.072,-.222),l(.421,-.187),l(.404,-.233),l(.094,-.151),l(-.076,-.117),l(-.184,.023),l(.116,-.198),l(.16,.012),l(.22,.094),l(.177,.221),l(.013,.304),M(662.661,219.065),l(-.312,-.099),l(-.203,-.127),l(-.062,-.169),l(.03,-.212),l(.256,-.198),l(.315,-.036),l(.17,.092),l(.053,.212),l(.182,.098),l(.305,-.145),l(.34,.105),l(.104,.151),l(-.012,.451),l(.183,-.148),l(.163,-.304),l(.318,-.029),l(.229,.226),l(.021,.424),l(.181,-.036),l(.062,.104),l(-.025,.397),l(-.316,-.211),l(-.311,-.058),l(-.141,.058),l(.072,.155),l(-.852,.157),l(-.143,-.091),l(.097,-.268),l(-.085,-.059),l(-.308,.269),l(-.229,.256),l(-.296,-.046),l(-.63,.225),l(-.624,.199),l(-.357,-.051),l(-.31,.123),l(-.392,-.07),l(-.103,-.07),l(-.202,-.123),l(-.063,-.279),l(.143,-.261),l(-.08,-.253),l(.193,-.115),l(.23,-.113),l(.233,-.156),l(.224,.07),l(.61,.013),l(.4,.104),l(.089,.28),l(.291,.109),l(.294,.056),l(.189,-.259),l(.29,-.012),l(.051,-.187),l(-.263,-.15),M(656.294,219.602),l(-.393,-.282),l(-.855,-.449),l(-.118,-.269),l(.417,-.001),l(.514,-.185),l(.462,-.029),l(.925,.521),l(-.338,.17),l(-.232,.1),l(-.381,.425),M(631.053,200.125),l(-.061,.225),l(-.413,.439),l(-.204,.41),l(-.381,.354),l(.164,.353),l(.162,.169),l(.806,.493),l(.832,.055),l(.241,.112),l(.151,.381),l(.128,.763),l(-.007,.409),l(.267,.423),l(.212,.127),l(.544,.041),l(-.45,.933),l(.151,.212),l(.703,-.453),l(.824,.252),l(.177,.042),l(.265,.254),l(.144,.438),l(.698,.676),l(-.515,1.979),l(-.04,.452),l(.23,.946),l(-.021,.438),l(.021,.664),l(-.002,.268),l(-.149,1.06),l(-.087,.156),l(-.107,.07),l(-.367,-.253),l(-.381,-.522),l(-.261,-.084),l(-.262,.481),l(-.081,.268),l(-1.043,-.619),l(-.219,.086),l(.394,.747),l(-.163,.213),l(-.204,-.197),l(-1.343,-1.424),l(-.775,-.761),l(-1.011,-.859),l(-1.348,-.958),l(-.391,-.451),l(-.199,-.493),l(-.191,-.339),l(-1.003,-.633),l(-.697,-.677),l(-1.186,-1.509),l(-.074,-.353),l(.039,-.339),l(-.324,-.875),l(-.841,-1.467),l(-.667,-1.044),l(-.612,-.775),l(-.369,-.301),l(-.287,-.234),l(-.64,-.295),l(-.254,-.748),l(-.688,-1.806),l(.067,-.24),l(-.107,-.311),l(-.157,-.197),l(-.662,-.507),l(-.711,-.394),l(-.539,-.21),l(-.317,-.099),l(-.119,-.353),l(-.077,-.734),l(-.18,-.409),l(-.386,-.479),l(-.818,-.831),l(-.368,-.423),l(-.725,.128),l(-.613,-.676),l(-.646,-.606),l(-.593,-.69),l(-.562,-.945),l(-.229,-.635),l(-.032,-.367),l(.057,-.198),l(.149,-.113),l(.401,-.043),l(.364,.098),l(.25,.126),l(.632,.563),l(.361,.155),l(.922,.153),l(.335,.027),l(.548,-.1),l(.454,-.142),l(.4,-.015),l(.323,.31),l(.919,1.156),l(.513,.31),l(.058,.155),l(-.12,.537),l(1.066,.916),l(.749,.493),l(1.175,.689),l(.678,.323),l(.139,.169),l(.03,.593),l(-.02,.155),l(.573,.055),l(.745,.944),l(.612,.55),l(.271,-.015),l(.004,-.198),l(-.123,-.226),l(.069,-.24),l(.507,.21),l(.479,.804),l(.441,.38),l(.446,.056),l(.429,.197),l(.314,.366),l(.28,.734),l(.316,.437),l(.431,.268),l(.511,.126),l(.767,.083),l(.431,.154),l(.494,.38),l(.576,.606),l(-.019,.071),M(684.201,200.125),l(-.007,-.172),l(-.414,-1.058),l(.18,-.551),l(-.078,-.141),l(-.141,-.296),l(.036,-.325),l(.286,-.89),l(.514,-.82),l(.263,.367),l(.152,.353),l(-.054,.283),l(-.246,.396),l(-.361,.763),l(.061,.325),l(.19,.141),l(.097,-.141),l(.436,-.411),l(.135,-.522),l(.179,-.142),l(.806,-.412),l(.141,.141),l(-.052,.254),l(.104,.55),l(-.354,.212),l(-.467,.354),l(-.162,.311),l(.159,.099),l(.446,.126),l(.398,.211),l(-.016,.141),l(.159,.353),l(-.688,-.154),l(-.431,-.154),l(-.367,-.042),l(-.304,.156),l(-.08,.438),l(.049,.258),l(.131,.688),l(.341,.62),l(.405,.438),l(.196,.282),l(-.156,.212),l(-.26,-.211),l(-.664,-.648),l(-.55,-.733),l(-.002,-.396),l(-.011,-.251),M(637.361,207.144),l(-.863,-.394),l(-.377,-.239),l(-.205,-.367),l(-.045,-.367),l(-.156,-.395),l(-.507,-.395),l(-.291,-.099),l(-.446,.029),l(-.116,-.141),l(.271,-.65),l(.234,-.24),l(.509,.55),l(.148,-.467),l(.313,-.269),l(.072,.395),l(.312,.89),l(.648,.817),l(.698,.31),l(-.265,.184),l(-.118,.283),l(.183,.564),M(634.321,215.345),l(-.091,-.187),l(.316,-.023),l(.402,.093),l(.369,-.129),l(.068,-.524),l(.018,-.14),l(.309,.057),l(-.043,-.5),l(.222,-.235),l(.093,-.277),l(.202,.121),l(.631,.112),l(.474,-.047),l(.237,.443),l(.524,-.089),l(.158,-.297),l(.022,-.244),l(.259,.116),l(.618,.168),l(.411,.438),l(.338,-.046),l(.204,.271),l(.446,-.029),l(.453,-.185),l(.302,.211),l(.369,.522),l(.179,.521),l(.884,.041),l(.462,.188),l(.49,-.077),l(1.435,.124),l(.479,-.029),l(.34,-.17),l(.213,-.65),l(.271,-.269),l(.447,-.015),l(.223,.211),l(.289,.494),l(.633,.125),l(.53,.027),l(.774,.083),l(.796,.153),l(.289,.24),l(.293,.288),l(-.08,.445),l(.275,.466),l(.119,.099),l(.877,.352),l(.422,.069),l(.658,.013),l(.45,-.185),l(.415,-.015),l(.628,.238),l(.048,.197),l(-.255,.425),l(-.152,.494),l(.578,.776),l(-.499,-.211),l(-.802,-.196),l(-.599,-.253),l(-.891,-.309),l(-.528,.001),l(-.589,.256),l(-.348,.057),l(-.714,-.098),l(-1.454,-.138),l(-1.47,-.138),l(-.805,-.253),l(-.839,-.479),l(-1.099,-.336),l(-1.125,-.267),l(-.948,-.04),l(-.556,.298),l(-.445,.043),l(-.957,-.153),l(-.805,-.492),l(-.357,-.07),l(-1.606,-.066),l(-.363,-.155),l(.055,-.141),l(.448,-.468),l(-.402,-.267),l(-.551,-.099),l(-.506,-.14),l(-.307,-.027),l(-1.261,-.121),M(675.004,223.092),l(.249,-.494),l(.023,-.537),l(.113,-.312),l(.674,-.481),l(1.447,-.624),l(.662,-.454),l(.36,-.607),l(.466,-.157),l(1.578,-.102),l(.91,-.214),l(.541,-.044),l(.869,-.143),l(.118,.07),l(.099,.197),l(-.237,.212),l(-.36,.256),l(-1.609,.61),l(-1.369,.44),l(-.713,.256),l(-.606,.354),l(-1.09,.963),l(-.653,.481),l(-.439,.086),l(-.552,.228),l(-.48,.015),M(667.866,223.149),l(-.217,-.069),l(-.917,-.605),l(-.8,-.45),l(-.347,-.099),l(-.493,-.126),l(-.292,-.197),l(.108,-.212),l(.371,-.142),l(.992,-.03),l(.502,-.114),l(.35,.296),l(1.147,.746),l(.265,.381),l(-.125,.325),l(-.246,.24),l(-.299,.057),M(661.819,191.241),l(-.041,.09),l(.319,.691),l(-.23,.142),l(-.546,.043),l(-.579,.086),l(.198,.226),l(.115,.296),l(-.169,.226),l(.216,.211),l(.235,.112),l(.546,.832),l(.536,.747),l(.043,.198),l(-.338,.721),l(.075,.226),l(.406,.465),l(.743,.45),l(.6,.493),l(.551,.761),l(-.465,.17),l(-.75,-.026),l(-.797,-.238),l(-.337,.1),l(-.387,.467),l(-.354,.918),l(-.08,.476),l(-.046,.272),l(.132,.649),l(.116,.424),l(-.133,.848),l(-.256,0),l(-.466,-.154),l(-1.037,.963),l(-.433,.65),l(-.751,.608),l(.443,.381),l(.06,.396),l(.17,.296),l(-.685,.058),l(.452,.578),l(.009,.212),l(-.103,.227),l(-.547,.665),l(-.206,.396),l(-.127,.354),l(-.529,.594),l(-1.294,.61),l(-.607,.284),l(-.292,.198),l(-.194,-.311),l(.024,-.424),l(-.33,-.804),l(-.306,-.381),l(-.265,-.184),l(-.286,.029),l(-.503,.523),l(-.302,.029),l(-.328,-.508),l(-.313,-.197),l(-.437,-.112),l(-.387,-.451),l(-.342,-.154),l(-.35,.806),l(-.135,.198),l(-.381,.058),l(-.356,-.112),l(-.442,.128),l(-.318,.354),l(-.364,.071),l(-.059,-.551),l(.034,-.311),l(-.314,-1.03),l(-.336,.396),l(-1.42,.44),l(-.321,-.408),l(-.639,.015),l(-.281,.156),l(-.303,.029),l(-.058,-.649),l(-.022,-.65),l(-.267,-1.411),l(-.012,-.48),l(-.352,-.747),l(-.406,-.409),l(-.79,-.422),l(-.146,-.141),l(.555,-.354),l(-.531,-.38),l(-.258,-.296),l(.188,-.735),l(-.074,-.128),l(-.278,-.478),l(-.352,-.296),l(.065,-.466),l(-.125,-.593),l(.182,-.65),l(.133,-.353),l(.424,-.58),l(.303,-.806),l(.318,.028),l(.204,.11),l(.288,.792),l(.253,.295),l(1,.983),l(.304,.083),l(.446,.28),l(.928,-.416),l(.255,-.001),l(.526,.223),l(.543,.11),l(.399,-.172),l(.528,-.342),l(.403,-.525),l(.531,-.441),l(.479,-.074),l(.431,.11),l(.557,.251),l(.524,.223),l(.559,.152),l(.287,-.03),l(.467,-.356),l(.465,-.172),l(.864,-.175),l(.387,-.299),l(.928,-1.785),l(-.076,-.748),l(.218,-.34),l(.646,-.244),l(.22,-.383),l(-.106,-.988),l(.119,-.565),l(.381,-.638),l(.247,-.157),l(.464,-.017),l(.748,.081),l(.651,.081),l(.624,-.018),l(.446,.04),l(.753,.292),l(.182,.09),M(666.561,200.125),l(.012,-.049),l(.48,-1.188),l(.434,-.41),l(.289,-.142),l(.429,.338),l(.29,-.311),l(.162,-.325),l(.293,-.481),l(.496,-.058),l(.605,.14),l(.729,.535),l(.447,.027),l(.863,-.044),l(.478,.168),l(.749,.267),l(.577,-.227),l(1.853,.081),l(.72,-.128),l(.627,-.354),l(.211,-.283),l(-.156,-.268),l(.196,-.283),l(.388,-.241),l(.295,-.41),l(.289,-.057),l(.075,.24),l(-.073,.537),l(-.117,.311),l(-.081,.127),l(-.082,.127),l(-.969,1.259),l(-.416,.396),l(-.464,.1),l(-1.23,.229),l(-.495,-.069),l(-.591,-.422),l(-1.149,-.068),l(-1.151,.059),l(-.878,-.041),l(-1.039,.045),l(-.575,-.083),l(-.671,.029),l(-.415,.1),l(-.433,.368),l(-.259,.461),l(-.154,.274),l(-.187,.721),l(.068,.48),l(.263,.494),l(.194,.183),l(.403,.226),l(.259,.196),l(.221,.607),l(.179,.154),l(.226,.042),l(.815,.026),l(.249,-.269),l(.652,-.976),l(.385,.056),l(.307,.183),l(.496,.041),l(.363,-.227),l(.669,-.156),l(.62,-.143),l(.268,-.298),l(.271,-.057),l(.466,.196),l(.131,.212),l(-.083,.734),l(-.469,-.267),l(-.544,-.042),l(-.361,.298),l(-.389,.523),l(-.438,.425),l(-1.059,.439),l(-.214,.325),l(-.143,.029),l(-.241,-.042),l(-.468,-.126),l(-.03,.056),l(.025,.312),l(.212,.126),l(.676,.578),l(.467,.521),l(.854,1.24),l(-.097,.325),l(-.156,.679),l(.102,.409),l(.447,.535),l(.555,.438),l(.062,.226),l(-.045,.282),l(-.436,-.056),l(-.652,.059),l(-.412,.297),l(-.224,.692),l(-.498,-.026),l(-.461,-.183),l(-.107,-.17),l(.052,-.649),l(.204,-.58),l(-.978,-.845),l(-.417,-.31),l(-.174,-.269),l(.036,-.24),l(.284,-.396),l(.116,-.579),l(-.165,-.494),l(-.737,-.055),l(-.503,.213),l(-.494,.396),l(.16,.353),l(.143,.932),l(-.068,.509),l(-.236,1.145),l(.363,.903),l(-.01,.311),l(-.377,.636),l(-.019,.227),l(.275,.564),l(-.726,.171),l(-.513,.241),l(-.476,.071),l(-.245,-.324),l(-.16,-.522),l(.156,-.325),l(.181,-.466),l(.069,-.876),l(.06,-1.073),l(-.125,-.509),l(.029,-.339),l(-.213,-.395),l(-.311,-.127),l(-.391,.171),l(-.574,.029),l(.011,-.41),l(-.25,-1.284),l(.131,-.311),l(.491,-.524),l(.469,-.777),l(.161,-.48),l(-.089,-.918),l(-.006,-.254),l(.087,-.452),l(.339,-.721),l(.447,-.058),l(-.043,-.861),l(.254,-1.053),
+N(341.05,41.069),l(2.084,.272),l(.344,.361),l(-.869,.174),l(-.541,.139),l(-1.678,.106),l(-1.159,.037),l(-.689,.156),l(-.372,.224),l(-.308,.6),l(-.361,.376),l(1.05,.39),l(.971,.168),l(2.117,.064),l(.601,-.001),l(1.775,-.242),l(1.93,-.038),l(.866,.135),l(.933,.219),l(.417,.135),l(.284,-.018),l(1.001,-.002),l(1.277,.032),l(.615,.05),l(-1.277,.626),l(-1.583,.457),l(-1.976,.523),l(-.556,-.016),l(-.695,-.116),l(-.951,.671),l(-1.061,.503),l(-1.246,.452),l(-1.125,.296),l(-.211,.056),l(-2.212,.054),l(-.525,.134),l(-.502,.001),l(-.982,.201),l(-.665,.167),l(-.528,.051),l(-.946,-.413),l(-.375,.05),l(-.69,.913),l(-.958,.118),l(-.631,-.065),l(-.743,-.197),l(-.622,-.463),l(-.854,-.43),l(-.647,-.215),l(-.109,0),l(.008,.2),l(.707,1.043),l(-.192,.249),l(-.319,.017),l(-.69,.249),l(-.84,.249),l(-.573,.38),l(-1,.906),l(-.657,.657),l(-1.051,.851),l(-.776,.262),l(-1.034,.083),l(-1.023,-.275),l(-.148,.554),l(-.438,.569),l(-.783,.277),l(-.992,-.095),l(-.616,.05),l(-1.18,.439),l(.942,-1.723),l(-.121,.017),l(-.795,-.015),l(-1.055,-.177),l(.26,.423),l(-.026,.455),l(-.386,.407),l(-.794,.39),l(-1.16,.164),l(-.973,.002),l(-1.255,.083),l(.467,.403),l(.212,.403),l(-.09,.387),l(-.379,.097),l(-.321,-.063),l(-.47,.033),l(-1.792,-.157),l(.517,.32),l(.765,.462),l(.295,.351),l(-.01,.224),l(-.26,.176),l(-1.197,.034),l(-1.051,.129),l(.844,.413),l(.47,.126),l(.448,.222),l(.389,.333),l(-.554,.461),l(-.285,.111),l(-.599,-.094),l(-.478,.096),l(.345,.474),l(-.009,.127),L(308.501,60),l(-.486,-.125),l(-.583,-.062),l(.026,.158),l(.255,.457),l(-.101,.347),l(-.288,0),l(-.656,-.093),l(-.089,-.016),l(-.979,.112),l(-1.081,.018),l(.682,.487),l(1.108,.391),l(.331,.204),l(-.077,1.035),l(-.382,.938),l(-.427,.094),l(-.815,-.061),l(.489,.591),l(-.016,.498),l(.156,.233),l(-.068,.373),l(-.316,.062),l(-.495,-.03),l(-.771,.079),l(.762,.386),l(.427,.603),l(-.117,.447),l(-.287,.031),l(-.967,-.26),l(-1.052,-.508),l(-.498,.294),l(-.425,.602),l(-.635,-.599),l(.158,-.573),l(-.387,-.201),l(-1.124,-.184),l(-.577,-.309),l(.04,-.187),l(.253,-.249),l(.066,-.218),l(-.325,-.28),l(-.366,-.186),l(-.668,.359),l(-.276,.016),l(-.3,.141),l(-.444,-.046),l(-.98,.064),l(-.417,.017),l(-.571,.296),l(-.476,.28),l(-.426,-.403),l(-.104,-.357),l(-.222,-.217),l(-.513,-.233),l(-.817,-.232),l(-.772,-.389),l(-.517,-.781),l(.07,-.737),l(-.199,-.156),l(-.434,-.094),l(-.467,.048),l(-.97,-.266),l(-.108,-.094),l(-.138,-.236),l(.14,-.457),l(.459,-.395),l(.071,-.269),l(-.258,-.062),l(-.551,-.031),l(-.542,-.094),l(-.278,-.221),l(-.058,-.633),l(-.458,-.126),l(-.616,.049),l(-.589,-.57),l(.023,-.191),l(.198,-.254),l(.618,-.367),l(1.22,-.337),l(.405,-.304),l(.476,-.128),l(.051,-.383),l(-.277,-.287),l(-.473,.097),l(-.921,.082),l(-.493,.097),l(-.635,.416),l(-.538,.129),l(-.63,.304),l(-.339,-.318),l(.038,-.623),l(-.114,-.784),l(-.206,-.451),l(.015,-.355),l(-.243,-.323),l(-.504,.082),l(-.271,-.032),l(-.666,-.355),l(-.594,-.485),l(-.013,-.357),l(.842,-.538),l(.265,.019),l(-.556,-.189),l(-1.083,.064),l(-.103,-.284),l(.383,-.176),l(.677,-.03),l(.586,-.052),l(.456,-.087),l(.322,-.672),l(-1.208,-.047),l(-.572,.05),l(-.362,-.032),l(-.29,-.163),l(-.116,-.197),l(.223,-.28),l(.218,-.008),l(.18,-.16),l(.427,-.055),l(-.375,-.188),l(-.552,.073),l(-.22,-.248),l(.057,-.188),l(.073,-.132),l(.259,0),l(.309,-.099),l(.827,-.25),l(1.218,.081),l(.854,.163),l(.776,.032),l(.378,.131),l(.927,.146),l(1.027,.097),l(-.031,-.363),l(.299,-.545),l(-.298,-.182),l(-1.02,-.263),l(-1.356,-.312),l(-.903,-.164),l(-1.592,-.33),l(-.354,-.116),l(.336,-.35),l(.788,-.001),l(1.462,.363),l(1.034,.048),l(.463,-.067),l(.114,-.067),l(.088,-.6),l(.088,-.301),l(.595,-.034),l(.528,.116),l(.227,-.101),l(-.027,-.351),l(-.195,-.184),l(-.891,-.317),l(.162,-.437),l(.528,-.455),l(-.258,-.286),l(-1.21,-.167),l(-1.154,.002),l(-1.178,-.286),l(-1.649,-.49),l(-.78,-.101),l(-.903,-.05),l(-.76,-.34),l(-.811,-.477),l(.156,-.035),l(.323,-.155),l(.605,-.001),l(.572,-.019),l(2.085,.305),l(.716,.033),l(1.249,.306),l(1.451,.458),l(.729,.169),l(.056,-.307),l(-.311,-.426),l(-.86,-.546),l(-.172,-.446),l(-.603,-.446),l(-.485,-.051),l(-.677,-.24),l(.361,-.277),l(.542,-.139),L(285.644,41),l(-.704,-.241),l(-1.101,-.015),l(-.625,-.086),l(-1.132,-.327),l(-.88,.608),l(-.324,.156),l(-.274,.294),l(-.875,.243),l(-1.402,-.066),l(-1.031,-.343),l(-.306,-.242),l(-.027,-.294),l(.438,-.313),l(.293,-.645),l(-.152,-1.259),l(.582,-.054),l(.691,.192),l(.372,-.124),l(.151,-.334),l(-.383,-.369),l(-.933,-.545),l(-.452,-.141),l(-.946,-.796),l(-.895,-.925),l(-1.105,-1.289),l(-.578,-.485),l(-1.855,-.379),l(-.667,-.255),l(-.291,-.202),l(-.052,-.701),l(-.904,-.406),l(-.962,-.109),l(-1.589,-.165),l(-1.928,-.425),l(-1.903,-.333),l(-2.133,-.183),l(-.997,-.054),l(-1.632,-.035),l(-.785,.189),l(-1.043,.096),l(-.806,.188),l(-1.419,.152),l(-1.228,-.166),l(-1.46,-.296),l(.319,.747),l(-.051,.093),l(-1.051,-.017),l(-1.294,-.184),l(-3.168,-.611),l(1.538,-.566),l(.463,-.114),l(-.092,-.226),l(-.423,-.169),l(-1.067,-.017),l(-2.21,-.015),l(-.812,-.074),l(-.629,-.018),l(-1.238,-.434),l(-.87,-.208),l(.587,-.306),l(1.257,-.041),l(3.036,.147),l(2.025,.034),l(1.343,.017),l(2.117,-.157),l(1.055,-.212),l(.292,-.096),l(.054,-.345),l(-.627,-.287),l(-.82,-.21),l(-1.217,.156),l(-1.11,.252),l(-1.31,.021),l(-1.138,-.113),l(-.753,.078),l(-.879,.098),l(-.68,-.056),l(-.857,-.19),l(-.664,-.365),l(-.816,-.191),l(-.662,-.057),l(-.726,.059),l(-.486,-.076),l(-1.416,-.481),l(-.044,-.35),l(.36,-.45),l(.81,-.119),l(1.235,-.1),l(1.517,-.14),l(2.074,-.161),l(1.29,-.081),l(.951,-.396),l(1.089,-.259),l(.843,-.081),l(2.478,-.005),l(1.101,-.101),l(1.942,.036),l(.402,-.139),l(.31,-.199),l(.609,-.16),l(.202,-.658),l(.276,-.501),l(.116,-.101),l(-.89,-.228),l(-1.947,-.039),l(-1.155,.194),l(-.959,-.125),l(-1.243,-.383),l(.595,-.781),l(1.38,-.332),l(2.845,-.359),l(1.407,-.225),l(1.962,-.249),l(2.112,-.162),l(1.163,.087),l(1.213,-.07),l(1.319,-.07),l(.345,-.181),l(.011,-.226),l(-.357,-.753),l(-.022,-.208),l(.522,-.14),l(1.886,-.05),l(1.526,.205),l(2.141,.41),l(1.296,.226),l(.802,.181),l(.823,-.275),l(-1.657,-.525),l(-.697,-.509),l(.167,-.047),l(2.2,-.122),l(1.166,-.12),l(1.854,-.216),l(2.52,-.195),l(.73,.069),l(1.064,.116),l(.232,1.738),l(.913,-.162),l(.539,-.322),l(.432,-1),l(1.003,.021),l(2.004,.323),l(1.858,.414),l(1.529,.25),l(.205,-.3),l(-.644,-.3),l(-.816,-.537),l(-.894,-.4),l(.295,-.287),l(.742,.022),l(1.758,.02),l(1.136,.212),l(2.754,.373),l(1.284,.279),l(2.109,.322),l(1.878,.274),l(1.872,.204),l(.8,-.209),l(.816,-1.483),l(-.326,-.191),l(-1.292,-.334),l(-1.176,-.533),l(.708,-.247),l(2.404,-.005),l(2.962,-.328),l(1.329,-.077),l(1.527,.17),l(2.221,.488),l(1.567,.167),l(2.005,.142),l(.3,-.761),l(-.3,-.472),l(2.646,-.206),l(2.021,-.08),l(2.589,.095),l(1.989,.146),l(1.886,-.18),l(2.367,-.207),l(2.043,-.005),l(1.859,.223),l(1.825,-.055),l(1.315,.072),l(.619,.099),l(.55,-.102),l(1.946,.146),l(1.707,.046),l(1.673,.096),l(2.438,.761),l(1.368,.241),l(1.345,-.076),l(1.118,.168),l(2.594,.237),l(.445,.408),l(-.304,.12),l(-.492,.192),l(-1.683,.146),l(-2.303,.124),l(-1.152,.121),l(-1.233,.05),l(-1.469,-.068),l(-2.831,-.064),l(-2.22,-.066),l(-1.389,.168),l(-1.614,.027),l(-1.933,.027),l(-1.16,.026),l(-1.485,.168),l(-.444,.118),l(-1.322,.213),l(-.335,.464),l(.743,.251),l(2.551,-.281),l(1.367,-.072),l(3.912,.038),l(2.223,-.12),l(2.331,-.005),l(.997,-.025),l(.93,.067),l(1.77,.434),l(.671,.09),l(1.087,-.186),l(1.663,-.21),l(1.536,-.281),l(1.964,-.144),l(.59,.462),l(-.566,.482),l(-2.316,.639),l(-.973,.338),l(-1.281,.734),l(.12,.307),l(.319,.152),l(.796,-.089),l(.477,-.044),l(1.616,-.553),l(1.766,-.537),l(1.413,-.385),l(1.706,-.32),l(.775,-.207),l(1.662,-.163),l(1.618,.111),l(1.391,.065),l(1.497,-.3),l(.703,-.324),l(1.129,-.234),l(2.148,-.004),l(1.672,.112),l(1.097,.044),l(1.197,.136),l(1.135,.228),l(1.107,.112),l(.316,.25),l(-.181,.273),l(-1.97,.252),l(-1.491,.138),l(-1.245,.494),l(-.557,.289),l(-1.604,.355),l(-1.57,.548),l(-1.063,.089),l(-.918,-.042),l(-1.592,.047),l(-2.213,-.039),l(-1.491,.198),l(-.731,.217),l(-.495,.535),l(.166,.322),l(1.949,-.305),l(1.581,-.046),l(1.856,.101),l(.003,.42),l(-.743,.241),l(-2.388,.124),l(-.463,.14),l(-.213,.199),l(-.156,.595),l(-.471,.71),l(-.678,.158),l(-1.06,-.077),l(-.742,.041),l(-.837,.9),l(-.987,1.087),l(-.15,.347),l(.454,.307),l(.403,.095),l(.602,-.481),l(.743,-.368),l(.856,-.041),l(2.345,.266),l(.353,.096),l(.262,.288),l(-.059,.211),l(-1.234,-.074),l(-.673,-.018),l(-.512,.097),l(-.136,.191),l(.29,.286),l(1.756,.188),l(.557,.132),l(1.802,-.137),l(.526,.208),l(.214,.323),l(-.049,.436),l(-.256,.133),l(-1.835,-.186),l(-1.653,-.054),l(-.781,-.074),l(-1.295,.078),l(-1.382,.475),l(-.823,-.13),l(-.49,-.15),l(-1.06,.04),l(-.283,.377),l(1.393,.599),l(1.187,.222),l(1.298,.128),l(1.665,.072),l(.696,.148),l(.551,.482),l(.272,.444),l(.014,.554),l(-.434,.405),l(-.384,.074),l(-1.292,-.181),l(-.82,-.109),l(-.372,.111),l(.023,.55),l(.118,.236),l(.426,.162),l(.618,.089),l(.723,.215),l(.914,.142),l(.752,.16),l(.383,.376),l(-.338,.233),l(-.832,.145),l(-.647,.126),l(-1.747,-.032),l(-1.176,-.087),l(-1.624,-.086),l(-.592,.448),l(.551,.195),l(1.396,.051),l(1.052,.158),l(.724,.248),l(.088,.319),l(-.035,.549),l(-.13,-.005),l(-1.092,-.045),l(-1.247,.108),l(-.596,.266),l(-1.246,.02),l(-1.225,-.139),l(-1.497,-.404),l(-.922,-.478),l(-.373,-.07),l(-1.094,.286),L(345,36.811),l(-1.084,.09),l(-.589,.178),l(-1.451,-.033),l(-.913,-.087),l(-.969,.143),l(-.395,.125),l(-.174,.283),l(.006,.141),l(.354,.527),l(.71,.245),l(1.284,.05),l(1.515,.26),l(1.567,-.056),l(1.323,.54),l(.758,.226),l(.482,.226),l(1.196,.329),l(1.252,.38),l(.376,.276),l(.483,.898),l(.892,-.208),l(.278,-.139),l(.397,.207),l(.298,.43),l(.071,.344),l(.198,1.164),l(-.169,.205),l(-.371,.12),l(-.541,-.101),l(-.546,-.119),l(-.917,.002),l(-1.041,.036),l(-1.488,-.27),l(-.637,-.409),l(-.415,-.634),l(-.354,-.274),l(-1.17,-.566),l(-.84,-.292),l(-.748,-.137),l(-1.095,-.084),l(-.521,.14),l(-.962,.105),M(351.365,40.026),l(-1.527,-.537),l(-.96,-.225),l(-.712,-.156),l(-.159,-.069),l(-.314,-.419),l(1.483,-.038),l(.893,.139),l(1.064,.26),l(.819,.296),l(.162,.488),l(-.215,.209),l(-.533,.053),M(281.574,46.135),l(-.568,-.133),l(-.707,-.318),l(-.801,-.183),l(-.197,-.101),l(-.25,-.218),l(-.08,-.844),l(.287,-.34),l(.368,-.018),l(.646,.135),l(1.157,.066),l(1.287,.27),l(.748,.269),l(.595,.1),l(.777,.217),l(.603,.335),l(-.144,.202),l(-.112,.034),l(-.543,.051),l(-.774,.035),l(-.77,.186),l(-1.009,.153),l(-.511,.102),
+N(105.98,81.688),l(-.952,-.826),l(-.198,-.342),l(-.024,-.476),l(.095,-.104),l(.408,.044),l(.312,-.045),l(.781,.177),l(.658,-.076),l(.28,.119),l(.138,.163),l(-.234,.224),l(-.173,.565),l(-.028,.312),l(-.581,.075),l(-.483,.19),M(125.24,92.375),l(-1.312,-.288),l(-1.345,-.434),l(-.218,-.174),l(.061,-.189),l(.376,-.466),l(-1.023,.002),l(-.413,.248),l(-.299,-.072),l(-.416,-.188),l(.166,-.452),l(-.487,-.334),l(-.269,-.014),l(-.735,-.086),l(-.226,-.262),l(.317,-.292),l(-.976,-.524),l(-.556,.118),l(-.386,-.102),l(-.852,-.511),l(-1.277,-.863),l(-.219,-.235),l(.02,-.117),l(.962,-.12),l(.337,.043),l(1.979,.598),l(.981,.204),l(1.772,.202),l(.385,.263),l(.618,.526),l(.426,.642),l(.433,.422),l(.362,.189),l(1.587,.536),l(.316,.203),l(.48,.756),l(.116,.407),l(-.279,.349),l(-.407,.016),M(271.379,92.089),l(-1.202,-.23),l(.641,-.743),l(.358,-.161),l(.279,.058),l(.292,0),l(.355,-.263),l(-.697,-.653),l(.079,-.219),L(272,89.003),l(1.121,-1.35),l(1.454,-1.31),l(.725,-.442),l(.496,-.192),l(1.315,-.194),l(.198,.073),l(.11,.221),l(-.299,.221),l(-.582,.03),l(-.242,.133),l(.349,.44),l(-.755,.78),l(-1.226,1.438),l(-.271,.526),l(.113,.291),l(.11,0),l(.428,-.176),l(.483,-.555),l(.458,-.191),l(1.115,.305),l(-.896,.687),l(.261,.203),l(.229,.072),l(1.423,.565),l(.758,-.03),l(.325,-.408),l(.309,-.059),l(.718,.057),l(.826,.202),l(.616,.231),l(-.297,.292),l(-.373,.233),l(-.708,.467),l(.339,.333),l(.477,.362),l(.26,.014),l(.417,-.161),l(.464,-.132),l(.278,.116),l(.02,.16),l(-.254,.262),l(-.404,.248),l(-.892,.104),L(280.84,93),l(.273,.362),l(.124,.405),l(.28,.231),l(.183,-.203),l(.309,-.262),l(.527,.159),l(-.099,.449),l(.149,.275),l(.716,.028),l(.085,-.015),l(.015,.203),l(-.168,.304),l(-.25,.652),l(-.34,.651),l(-.222,-.072),l(-.71,-.128),l(-.301,-.144),l(-.042,-.651),l(-.601,.406),l(-.374,.015),l(-.095,-.274),l(.497,-.652),l(.011,-.333),l(-.421,-.478),l(-.279,-.072),l(-.388,.392),l(-.423,.291),l(-.365,.146),l(-.435,.204),l(-.552,.536),l(-.496,.334),l(-.881,-.042),l(-.222,-.217),l(.165,-.145),l(1.229,-.408),l(.466,-.522),l(.632,-.363),l(-.699,-.129),l(-.601,-.057),l(-.322,.464),l(-.412,.015),l(-.13,-.159),l(.04,-.493),l(-.757,.016),l(-.148,.29),l(-.41,.218),l(-1.052,.045),l(-.709,-.057),l(-1.139,-.186),l(-1.012,-.085),l(-1.355,.061),l(-1.014,.147),l(-.145,-.188),l(-.215,-.463),l(.187,-.175),l(.561,-.334),l(.734,-.408),l(.502,-.161),l(.636,-.335),M(265.435,98.655),l(-.469,-.057),l(-.497,-.273),l(-.356,-.562),l(.062,-.635),l(.742,-.738),l(.932,-1.043),l(.816,.432),l(-.375,.435),l(-.112,.462),l(-.233,.333),l(-.262,.116),l(-.58,.319),l(-.244,.448),l(.522,.244),l(.168,-.029),l(.279,-.26),l(.42,-.362),l(.617,-.319),l(.309,.057),l(.495,.461),l(-.177,.347),l(-.246,.159),l(-1.134,.42),l(-.682,.044),M(211.34,59.677),l(-.68,-.046),l(.068,-.872),l(-.375,-.333),l(-.958,.161),l(-2.375,.29),l(.107,-.461),l(.56,-.303),l(1.644,-.561),l(-.302,-.478),l(-.102,-.415),l(.106,-.417),l(.398,-.835),l(.434,-.566),l(.254,-.648),l(.331,-.471),l(1.11,.566),l(-.312,.518),l(.791,.386),l(.527,.047),l(.402,-.469),l(.67,.112),l(.806,.289),l(.917,.514),l(.582,.255),l(2.168,.492),l(.442,.271),l(.176,.255),l(-.09,.925),l(.539,.047),l(.57,-.065),l(.934,.046),l(.701,.142),l(1.019,.427),l(-.419,.096),l(-.269,.127),l(-.46,.271),l(-.949,-.046),l(-.623,-.125),l(-1.328,-.125),l(-.438,-.126),L(217.259,58),l(-.528,-.301),l(-1.017,-.237),l(-.528,.017),l(-.203,.271),l(.174,.588),l(-.126,.096),l(-1.314,.161),l(-.673,.493),l(-.588,.302),l(-1.116,.287),M(200.125,19.1),l(-.862,-.015),l(-1.085,-.195),l(-.308,-.664),l(.819,-.304),l(.77,-.072),l(.666,-.024),l(3.475,-.125),l(1.263,-.12),l(1.374,-.026),l(1.714,.324),l(.397,-.094),l(.397,-.377),l(1.303,-.287),l(1.759,-.099),l(1.975,.209),l(.746,-.001),l(2.562,.137),l(2.621,.324),l(1.424,.09),l(1.461,.161),l(.448,-.165),l(-1.433,-.42),l(-1.67,-.352),l(-.816,-.429),l(.293,-.242),l(1.361,-.148),l(1.101,-.246),l(1.431,-.101),l(2.382,-.201),l(1.666,.119),l(1.944,.191),l(1.009,.265),l(1.19,.456),l(.354,.047),l(.273,-.362),l(-.959,-.508),l(-.828,-.292),l(.499,-.248),l(1.45,.121),l(1.832,.168),l(1.653,.07),l(1.639,.46),l(.378,.023),l(.062,-.195),l(-.301,-.539),l(1.781,-.004),l(1.408,.046),l(.832,.269),l(.831,.34),l(.618,-.001),l(-.044,-.268),l(-.331,-.467),l(1.075,-.077),l(3.691,.386),l(2.726,.288),l(1.937,-.077),l(2.987,.018),l(.967,.047),l(.757,.12),l(.126,0),l(1.419,.094),l(1.089,.191),l(.744,.095),l(1.685,.044),l(1.357,.357),l(-.385,.358),l(-1.237,.121),l(-1.206,.356),l(-1.849,.191),l(-.978,-.045),l(-2.191,-.159),l(-2.284,.005),l(-.776,.142),l(-1.915,.168),l(-.597,.465),l(.75,.366),l(.761,.044),l(1.03,-.048),l(1.705,-.279),l(.79,.021),l(.808,.434),l(-.168,.114),l(-1.246,.139),l(-1.38,.207),l(-1.174,.295),l(-2.098,.518),l(-1.316,.224),l(-1.19,.355),l(-.924,.286),l(-2.252,.005),l(.65,.906),l(-.449,.193),l(-2.297,.455),l(-.768,-.019),l(-1.587,-.037),l(-1.462,-.218),l(-2.386,-.164),l(-.66,.33),l(2.591,.695),l(-.662,.141),l(-.967,-.038),l(-1.297,.022),l(-1.068,.022),l(-2.58,-.214),l(-2.009,.063),l(-.134,.66),l(1.257,-.105),l(1.065,.018),l(2.312,.292),l(.557,.157),l(.12,.67),l(-.33,.197),l(-1.031,.12),l(-.515,.705),l(-1.073,.021),l(-.448,-.058),l(-.402,.176),l(.297,.253),l(.759,.25),l(-.328,.136),l(-1.615,.08),l(-.867,-.037),l(-1.71,-.171),l(-.422,.078),l(.41,.791),l(-.08,.231),l(-.649,.289),l(-.767,.155),l(-1.52,-.112),l(-2.039,-.111),l(-1.43,-.227),l(-1.008,.079),l(-1.219,.5),l(1.031,.112),l(.368,.057),l(2.154,.11),l(1.759,.13),l(1.534,.168),l(2.001,.034),l(.66,.34),l(.045,.359),l(-.907,.398),l(-2.685,.268),l(-.927,.115),l(-1.054,.227),l(-1.115,.077),l(-.467,-.28),l(-.797,-.638),l(-.56,.039),l(-.631,.001),l(-1.453,-.318),l(-.001,.17),l(.331,.508),l(-1.477,-.016),l(-1.5,-.129),l(-.875,-.319),l(-1.033,-.471),l(-.388,.058),l(.527,.717),l(-.24,.17),l(-.821,.133),l(-1.72,-.109),l(-2.276,-.033),l(-.972,-.073),l(-1.382,-.394),l(-.642,-.131),l(-.282,.453),l(-.619,.152),l(-1.843,-.316),l(.161,-.586),l(.219,-.228),l(1.525,-.117),l(.61,-.249),l(.961,-.173),l(1.179,.036),l(.499,-.172),l(-1.073,-.4),l(-1.043,-.651),l(.052,-.154),l(.479,-.117),l(1.316,.036),l(1.743,.093),l(.888,.21),l(1.108,.517),l(1.35,.323),l(1.085,.093),l(1.667,-.022),l(.829,-.136),l(.086,-.268),l(.514,-.304),l(-3.019,.001),l(-1.025,-.171),l(-.156,-.85),l(.211,-.154),l(-1.74,-.153),l(-1.963,-.152),l(-.274,0),l(-.631,.114),l(.204,-.758),l(1.159,-.551),l(1.104,-.16),l(1.837,-.003),l(1.164,.037),l(1.37,.076),l(2.023,.311),l(1.342,.115),l(.486,-.158),l(1.132,-.041),l(-3.399,-.802),l(-1.742,-.313),l(-3.555,-1.27),l(-.406,.242),l(-1.398,-.878),l(.025,-.258),l(.313,-.108),l(1.747,.104),l(1.905,-.004),l(2.019,.06),l(1.6,.382),l(2.535,.784),l(1.448,-.043),l(.833,.095),l(-1.387,-.555),l(-2.015,-.317),l(1.208,-.743),l(1.456,-.329),l(1.731,-.025),l(1.529,-.222),l(2.042,-.07),l(1.157,-.112),l(1.414,-.051),l(-1.778,-.479),l(-1.425,-.153),l(-2.501,.027),l(-1.243,.248),l(-1.305,.158),l(-1.425,.202),l(-1.447,.047),l(-.586,.067),l(-1.532,-.438),l(-.214,.111),l(-.543,.156),l(-2.16,-.018),l(-1.58,.365),l(.311,-.828),l(.98,-.292),l(.007,-.202),l(-.606,-.247),l(-1.375,-.156),l(-1.39,.003),l(-4.189,.505),l(-2.031,.672),l(-.408,-.11),l(-.569,-.251),l(.395,-.133),l(.678,-.023),l(-.117,-.316),l(-.698,-.398),l(-1.216,-.056),l(-.216,-.003),M(200.125,20.844),l(.899,-.096),l(.832,.196),l(.339,.5),l(.511,.495),l(.427,.063),l(1.141,.041),l(-.081,-.236),l(.056,-.411),l(.438,-.109),l(.718,.194),l(.718,.322),l(.374,.3),l(-.066,.171),l(.056,.826),l(.764,.442),l(.953,-.017),l(1.276,-.074),l(1.646,.504),l(-1.123,-.264),l(-1.528,.34),l(-1.599,.221),l(-.83,.377),l(-.287,.197),l(-.265,.315),l(-.448,.021),l(-1.493,-.41),l(-.656,.335),l(.465,.43),l(-.029,.235),l(-.412,.196),l(-.392,.04),l(-1.086,-.31),l(-.944,-.311),l(-.26,.645),l(-.117,.068),l(-.083,.049),l(-.888,.041),l(-1.74,-.094),l(-1.458,-.153),l(-.888,-.154),l(-.494,.021),l(-3.115,-1.31),l(-.191,-.276),l(1.971,-.241),l(3.32,.093),l(.889,.097),l(1.573,.1),l(-2.485,-.693),l(-3.019,-.213),l(-1.103,.122),l(-1.43,-.017),l(-.597,.18),l(-1.008,.022),l(-.606,-.198),l(-1.066,-.517),l(-1.425,-.479),l(-.341,-.355),l(1.971,.124),l(2.278,-.175),l(-1.255,-.249),l(-.756,-.351),l(.38,-.305),l(.729,-.132),l(.769,-.023),l(.921,.042),l(.156,-.219),l(-1.799,-.793),l(1.053,-.114),l(1.213,-.182),l(1.13,.087),l(.584,-.046),l(.145,-.18),l(-.514,-.475),l(1.362,.134),l(.941,.066),l(.83,.202),l(1.589,.869),l(.653,.264),l(.772,.24),l(.674,-.001),l(.36,-.039),M(179.067,27.216),l(-1.156,-.056),l(-.604,-.173),l(-.926,-.638),l(-.621,-.193),l(-3.102,-.091),l(-1.487,.081),l(-.622,.001),l(-1.444,-.056),l(-.767,-.154),l(-1.019,-.37),l(-.161,-.234),l(.335,-.138),l(.802,-.001),l(1.687,.232),l(.867,-.021),l(-.031,-.235),l(-.252,-.275),l(-1.344,-.49),l(-.579,-.098),l(-1.075,-.077),l(-1.392,-.196),l(.065,-.397),l(2.246,-.124),l(2.392,.155),l(.77,.376),l(.999,.453),l(1.979,.193),l(2.189,.114),l(1.178,.233),l(.604,.254),l(1.123,.721),l(.581,.446),l(.168,.426),l(-.481,.194),l(-.919,.137),M(185.907,26.758),l(-1.078,-.037),L(184,26.529),l(-1.029,-.484),l(-1.144,-.76),l(-.03,-.216),l(.239,-.099),l(2.296,-.044),l(1.816,.311),l(3.101,.542),l(-.047,.351),l(-.254,.331),l(-.436,.04),l(-1.563,.177),l(-1.043,.08),M(156.886,26.865),l(-1.573,.646),l(-.558,.27),l(-1.85,.042),l(-1.019,.079),l(-1.898,-.15),l(-.577,-.114),l(-.302,-.423),l(.334,-.291),l(1.365,-.177),l(.899,.056),l(2.351,-.102),l(.496,0),l(2.331,.163),M(132.902,31.305),l(-.53,-.186),l(-.95,-.466),l(-.424,-.112),l(-.33,.057),l(-.56,.207),l(-1.269,.059),l(-.786,-.279),l(-.283,-.319),l(.23,-.264),l(1.13,-.097),l(.503,-.133),l(.771,-.134),l(.977,-.399),l(.848,-.211),l(.726,-.172),l(.548,-.344),l(1.083,-.231),l(1.277,-.079),l(2.532,-.158),l(1.68,.016),l(.888,-.29),l(1.038,-.079),l(1.503,.438),l(-.756,.097),l(-.852,.231),l(-.22,.268),l(.12,.266),l(.469,.474),l(-.777,.001),l(-.912,.115),l(-.918,.662),l(-1,-.017),l(-.867,-.981),l(-.694,-.15),l(-.379,.02),l(-.229,.285),l(-.588,.342),l(-.63,.623),l(-.595,.151),l(-.284,.375),l(-.705,.356),l(-.787,.058),M(191.827,30.313),l(-1.266,-.054),l(-2.278,-.165),l(-.426,.058),l(-.332,-.094),l(-.896,-.489),l(-1.185,-.414),l(.192,-.229),l(2.433,-.042),l(1.542,.263),l(1.472,.054),l(.171,0),l(.89,.358),l(-.179,.246),l(.123,.32),l(-.263,.188),M(144.688,31.739),l(-2.222,-.395),l(-.325,-.674),l(.503,-.057),l(.595,-.17),l(.945,-.096),l(.953,-.133),l(1.279,-.059),l(.522,.187),l(.65,.374),l(.659,.186),l(1.55,-.209),l(.617,.149),l(1.624,.762),l(1.016,.351),l(.897,.036),l(.96,-.058),l(1.418,.09),l(.591,-.02),l(1.116,-.169),l(.092,-.297),l(-.557,-.559),l(-.941,-.391),l(-1.347,-.354),l(.96,-.322),l(.524,-.379),l(.569,-.152),l(1.097,-.116),l(.507,.17),l(.773,.678),l(-.017,.413),l(.518,.654),l(.565,.111),l(.9,.036),l(1.805,.406),l(-.334,-.465),l(.151,-.28),l(.409,-.076),l(1.495,.24),l(.932,.39),l(-.292,.409),l(.039,.5),l(-.358,.461),l(-.573,.277),l(-.755,.111),l(-.782,.001),l(-1.682,.095),l(-1.156,-.071),l(-1.757,-.18),l(-.622,-.017),l(-1.129,.277),l(-1.132,.202),l(-.76,.182),l(-.977,.254),l(-1.625,.292),l(-1.338,.2),L(149.23,34.5),l(-.748,-.07),l(-1.445,-.286),l(-.276,-.378),l(.648,-.128),l(1.219,-.038),l(.738,-.146),l(.852,-.075),l(1.166,-.057),l(.622,.017),l(1.09,-.149),l(.483,-.553),l(-2.768,-.087),l(-.925,-.054),l(-1.564,.28),l(-1.625,.168),l(-1.292,.04),l(-.795,.093),l(-1.681,-.347),l(-.479,.167),l(-.92,.075),l(-.979,-.127),l(-.854,-.33),l(.023,-.111),l(.863,-.427),l(1.098,-.058),l(2.047,-.022),l(.96,-.159),M(178.479,33.234),l(-.984,-.219),l(-.193,-.294),l(.764,-.389),l(.433,-.112),l(.088,-.167),l(-.447,-.333),l(-1.161,-.054),l(-2.13,.227),l(-.939,.076),l(-.331,.019),l(-.854,-.276),l(.039,-.335),l(.739,-.02),l(.542,-.244),l(.587,-.057),l(-.466,-.598),l(.176,-.245),l(.132,-.226),l(.49,.018),l(.859,.224),l(1.942,.746),l(.426,.186),l(.46,-.094),l(-.101,-.243),l(-.959,-.486),l(-.371,-.131),l(-.407,-.357),l(.436,-.095),l(.956,-.059),l(.713,.131),l(1.033,.262),l(.572,.168),l(.27,.018),l(.162,-.452),l(.478,-.133),l(.73,.112),l(.717,.168),l(.327,.168),l(.367,.75),l(-.034,.616),l(-.247,.242),l(-.831,.335),l(-.017,.352),l(.35,.625),l(-.361,.147),l(-1.648,-.089),l(-.862,.112),l(-1.446,.003),M(200.125,30.572),l(-.895,.045),l(-.853,.17),l(-.37,.467),l(1.133,.054),l(.984,-.038),l(.046,-.001),l(.847,.11),l(.463,.129),l(.498,.463),l(.727,.424),l(.621,.091),l(.213,-.074),l(.043,-.314),l(.286,-.056),l(1.075,-.002),l(.883,-.187),l(.766,.11),l(.835,.239),l(.665,.257),l(.976,.053),l(.775,-.463),l(1.393,-.281),l(1.704,-.114),l(1.951,-.246),l(1.533,.053),l(2.59,.014),l(.381,.037),l(.79,.314),l(.911,.239),l(1.418,.146),l(.653,.128),l(.21,.037),l(.361,.166),l(.181,.257),l(-.4,.148),l(-1.833,.407),l(-.135,.255),l(.469,.666),l(-2.486,.076),l(-.592,.02),l(-.651,.091),l(-.768,-.053),l(-.846,-.16),l(-.405,-.125),l(-.306,-.667),l(-.833,-.218),l(-.366,.129),l(.072,.723),l(-.536,.127),l(-.747,-.053),l(-.91,.109),l(-.728,-.017),l(-.495,.001),l(-1.342,-.213),l(-.593,-.197),l(-.495,-.017),l(-.209,.433),l(-1.801,.111),l(-.831,.074),l(-1.453,-.069),l(-.404,-.251),l(-.144,-.686),l(-1.237,.129),l(-.389,.181),l(-.326,.325),l(-.955,.2),l(-1.011,-.034),l(-.112,-.027),l(-.704,-.169),l(-1.186,-.575),l(-.675,.489),l(-1.131,-.07),l(-.666,-.688),l(-.442,-.717),l(.587,-.481),l(.019,-.371),l(-.292,-.316),l(-1.249,-.651),l(-.617,-.299),l(-.047,-.338),l(.636,-.133),l(1.226,-.078),l(2.472,-.023),l(.763,.093),l(1.118,.261),l(.188,.04),l(.872,.184),l(-.613,.189),l(-.259,.013),M(128.19,41.985),l(-.926,-.016),l(-1.059,-.102),l(-.362,-.466),l(-.549,-.467),l(-.432,-.259),l(-1.123,-.363),l(-1.36,-.067),l(-.951,-.138),l(-.469,-.19),l(-.168,-.174),l(.537,-.106),l(.589,-.298),l(.481,-.211),l(.08,-.386),l(-.437,-.809),l(.552,-.001),l(.468,-.177),l(.307,-.372),l(1.104,-.533),l(.526,-.588),l(-.121,-.32),l(-.271,-.16),l(-1.229,-.677),l(-.375,-.448),l(.869,-.001),l(.823,-.056),l(1.455,.051),l(.97,.016),l(1.515,-.092),l(1.284,-.146),l(1.242,-.074),l(.495,.125),l(3.242,.801),l(.918,.088),l(.708,-.055),l(1.316,-.127),l(1.223,.016),l(.771,.07),l(1.35,.373),l(2.389,.815),l(-.242,.143),l(-.432,.036),l(-.26,.072),l(-1.609,.322),l(-1.073,.144),l(-1.829,.428),l(-1.069,.319),l(-1.604,.725),l(-1.025,.563),l(-.549,.089),l(-.974,.124),l(.066,.924),l(-.271,.504),l(-.662,.278),l(-1.215,.124),l(-1.213,-.067),l(-.521,.485),l(-.898,.312),M(190.483,39.666),l(-1.146,-.208),l(-.146,-.524),l(-.941,-.806),l(-.207,-.582),l(.058,-.389),l(.27,-.657),l(.377,-.321),l(1.256,.033),l(-.089,-.16),l(-.416,-.266),l(-.185,-.286),l(.211,-.09),l(.234,-.072),l(2.154,-.058),l(1.215,.087),l(1.464,.248),l(1.282,.051),l(1.316,-.146),l(1.051,.016),l(.694,.105),l(.639,.213),l(-.007,.089),l(-.224,.179),l(-.824,.428),l(-.874,.746),l(-1.513,.92),l(-1.386,.073),l(-2.379,-.154),l(-1.269,.055),l(1.392,.717),l(-.188,.315),l(-.855,.369),l(-.964,.072),M(181.204,41.523),l(-.491,-.085),l(-1.101,-.552),l(-.952,-.641),l(-1.014,-.468),l(-.978,-.225),l(-1.438,-.12),l(-.55,-.174),l(-2.255,-1.066),l(.866,-.654),l(.653,.14),l(1.032,.474),l(1.063,.227),l(.46,.052),l(.615,-.283),l(.908,-.619),l(.415,-.036),l(.018,-.212),l(-1.062,-.565),l(-1.068,-.424),l(-.177,-.231),l(.132,-.107),l(1.683,.086),l(.711,-.215),l(.42,0),l(.996,.39),l(.56,.035),l(.58,-.055),l(.435,-.25),l(1.232,-.127),l(1.354,.069),l(.912,.23),l(-.324,.268),l(-.58,.125),l(-.323,.338),l(-1.55,.375),l(-.392,.16),l(-.069,.194),l(.253,.247),l(.506,.105),l(.692,-.089),l(1.08,.174),l(.868,.245),l(.391,.017),l(.564,.262),l(.186,.438),l(-.681,.352),l(-.156,.35),l(-.271,.68),l(-.457,.366),l(-.508,.14),l(-.658,.019),l(-.582,-.103),l(-.773,-.346),l(-.653,-.103),l(.013,.208),l(1.054,.553),l(-.817,.399),l(-.77,.036),M(243.524,60.394),l(-.234,-.208),l(-1.199,-.235),l(-.673,-.331),l(-.154,-.269),l(.346,-.064),l(.616,-.461),l(-1.378,-.521),l(-1.132,-.125),l(-.76,-.349),l(-.929,-.731),l(-.035,-.511),l(-1.115,-.062),l(-1.311,-.366),l(-.675,-.031),l(.284,.767),l(-.155,.096),l(-.409,-.015),l(-1.704,-.332),l(-.309,.033),l(-.325,.304),l(-.441,.288),l(-1.312,.082),l(-1.349,-.173),l(-1.343,-.189),l(-.813,-.254),l(-.052,-.319),l(.196,-.4),l(.382,-.354),l(1.066,-.163),l(.192,-.178),l(-.128,-.516),l(.206,-.033),l(1.357,.11),l(1.408,.175),l(.517,.144),l(.962,.626),l(.051,-.386),l(-.154,-.193),l(.077,-.194),l(.585,-.033),l(.977,-.099),l(.652,-.163),l(.649,-.114),l(.515,.063),l(.785,.031),l(.166,-.275),l(-1.138,-.825),l(-.773,-.356),l(-.119,-.228),l(.167,-.163),l(.586,-.066),l(.72,-.246),l(1.409,-.591),l(.361,-.541),l(.771,-.46),l(.493,-.379),l(-.109,-.593),l(-.899,-.841),l(-.407,-.496),l(-.541,-.364),l(-.414,.001),l(-1.258,-.33),l(-1.041,-.481),l(-.244,-.467),l(-.527,-.384),l(-.442,.202),l(-.551,.202),l(-.825,-.015),l(-.293,.117),l(-.62,.018),l(-1.255,.169),l(-.214,-.667),l(1.032,-.052),l(1.23,-.103),l(.163,-.269),l(-1.604,-.618),l(-1.552,-.67),l(-.879,-.015),l(-.567,-.185),l(-.169,-.542),l(-.677,-.339),l(-.45,-.05),l(-.918,-.306),l(-.687,-.341),l(-.385,-.119),l(-.611,.155),l(-.81,-.187),l(-1.177,-.238),l(-.489,-.085),l(-.379,.138),l(.529,.307),l(.453,.05),l(2.838,.712),l(.438,.271),l(.069,.306),l(-.505,.221),l(-.669,.069),l(-.541,-.033),l(-.757,-.049),l(-.818,-.252),l(-1.153,-.27),l(-.667,-.066),l(-.323,.17),l(.044,.204),l(.426,.236),l(.259,.438),l(-1.703,-.553),l(-.47,-.05),l(-.396,.119),l(-.63,.153),l(-.767,-.218),l(-.693,-.117),l(-.859,.12),l(-1.474,-.184),l(-1.995,-.167),l(-1.321,.037),l(-1.146,-.032),l(-.862,-.186),l(-.003,-.597),l(-.363,-.153),l(-.904,-.049),l(-.396,.342),l(-.623,.086),l(-1.214,-.049),l(-1.076,-.168),l(-1.303,-.477),l(-.415,-.376),l(.123,-.275),l(.868,-.07),l(1.131,.067),l(1.212,.101),l(.879,-.019),l(.312,-.19),l(-.934,-.463),l(-.8,-.275),l(-.905,-.102),l(-1.106,-.119),l(-.752,.036),l(-.539,-.017),l(-1.249,-.223),l(.114,-.416),l(.292,-.557),l(.34,-.14),l(.646,-.054),l(.081,-.227),l(-1.082,-.4),l(-.044,-.175),l(.449,-.79),l(1.197,-.919),l(.565,-.284),l(.918,-.321),l(.74,-.374),l(.423,-.037),l(.37,-.178),l(.698,-.001),l(.481,-.125),l(.71,-.09),l(1.436,-.109),l(1.348,.033),l(.857,.194),l(-.92,.393),l(-.815,.48),l(-1.394,.639),l(-.43,.529),l(.169,.369),l(1.256,.541),l(-.444,.298),l(-.076,.402),l(.257,.313),l(.862,.554),l(1.559,.621),l(-.096,.121),l(-1.272,.331),l(-.072,.31),l(.959,.033),l(1.504,.101),l(.654,-.639),l(-.103,-.415),l(-.343,-.277),l(-.724,-.103),l(-.422,-.138),l(-.884,-.538),l(.101,-.157),l(.506,-.245),l(.473,-.193),l(1.001,.12),l(.837,-.071),l(-1.204,-.47),l(-.703,-.034),l(-.793,-.279),l(-.056,-.193),l(.053,-.545),l(.886,-.319),l(1.207,.086),l(1.509,-.056),l(-.939,-.281),l(-1.233,-.351),l(.793,-.303),l(1.288,-.198),l(1.044,-.126),l(1.688,-.323),l(1.114,.016),l(.642,.052),l(.833,.141),l(.782,.478),l(1.536,.97),l(.058,.141),l(-.583,.687),l(-.709,.632),l(.038,.733),l(.364,.086),l(.65,.033),l(1.088,-.315),l(.284,-.455),l(.595,-.088),l(.791,.034),l(.454,.174),l(-.006,.262),l(.16,.47),l(.875,.189),l(.196,-.122),l(-.204,-.854),l(.218,-.123),l(.456,-.474),l(1.038,-.265),l(.98,-.054),l(.748,.034),l(.98,.174),l(1.172,.138),l(1.151,-.09),l(.688,.139),l(.327,.262),l(.621,.331),l(.574,.191),L(235.438,40),l(0,.191),l(-.531,.088),l(-.484,.279),l(-.818,.262),l(-.148,.225),l(.45,.259),l(.427,.068),l(.897,-.417),l(.652,-.174),l(.502,.051),l(.476,.242),l(.365,.466),l(.516,.413),l(.342,-.242),l(1.304,-.798),l(1.935,.256),l(.915,.361),l(-.051,.069),l(-.638,.346),l(-.708,.517),l(1.167,-.054),l(.455,-.173),l(1.078,-.105),l(.033,.704),l(.797,.324),l(.523,-.069),l(.831,-.207),l(1.316,-.088),l(.816,.221),l(.566,.273),l(-.162,.154),l(-.461,.223),l(-1.87,.43),l(-.238,.272),l(.523,.253),l(.456,-.068),l(.747,-.171),l(1.235,-.122),l(.406,-.29),l(.361,-.103),l(.479,.067),l(.51,.187),l(.544,.339),l(.636,.522),l(-1.019,.002),l(-1.2,.053),l(-.424,.135),l(.059,.269),l(.372,.134),l(1.333,.065),l(.938,.183),l(.543,.217),l(.233,.301),l(-.37,.034),l(-.748,.001),l(-1.011,-.082),l(-.875,-.216),l(-.824,-.065),l(-.316,.185),l(1.23,.583),l(-.216,.201),l(-1.552,.12),l(.245,.283),l(.437,.166),l(.551,.032),l(1.331,.364),l(1.312,.347),l(.247,.182),l(.039,.282),l(.351,.38),l(.75,-.217),l(.536,.049),l(1.413,.295),l(.298,-.067),l(.649,-.15),l(.61,.032),l(.752,.379),l(.862,.477),l(.376,.346),l(-.685,.1),l(-.801,.117),l(-.027,.444),l(.795,-.001),l(1.405,-.052),l(.51,-.132),l(.895,.048),l(-.386,.559),l(.918,.179),l(.514,-.001),l(.943,-.379),l(.685,.343),l(1.089,.407),l(.194,.098),l(-.275,.229),l(-.254,.099),l(-.103,.326),l(-.819,.05),l(-.718,-.21),l(-.247,-.048),l(-.794,.213),l(.968,.454),l(.279,.162),l(.057,.276),l(-1.057,.197),l(-.356,.228),l(-.312,.292),l(-.372,-.113),l(-.819,-.583),l(-.29,1.103),l(.354,.903),l(-.419,.065),l(-.677,-.257),l(-.751,-.176),l(-.205,-.177),l(-.018,-.243),l(-.315,-.274),l(-.93,.276),l(-.743,-.613),l(.051,-.292),l(.27,-.374),l(-.304,-.129),l(-.224,-.016),l(-.992,-.08),l(-.718,-.292),l(-1.17,-.617),l(-.769,-.292),l(-.762,-.048),l(-.452,.23),l(-.645,.083),L(250,52.592),l(.281,.179),l(1.05,.682),l(-.321,.114),l(-.686,.05),l(-.359,-.259),L(249.277,53),l(-.646,-.21),l(.275,.488),l(.859,.972),l(.604,.015),l(.587,.08),l(.5,.581),l(.612,.805),l(.513,.432),l(.615,-.321),l(.285,.047),l(.592,.399),l(.585,.271),l(1.38,.396),l(-.634,.113),l(-.213,.208),l(.254,.19),l(.568,.286),l(.962,.444),l(.324,.237),l(.242,.682),l(-.112,.428),l(-1.302,-1.155),l(-.554,-.237),l(-.027,.238),l(.118,.27),l(1.055,1.281),l(-.01,.3),l(-.926,-.125),l(.053,.205),l(.432,.409),l(.378,.519),l(-.563,-.172),l(-.615,-.313),l(-.889,-.693),l(-.145,-.031),l(-.719,.064),l(-.91,-.188),l(-1.44,-.662),l(-.319,-.285),l(-1.062,-.665),l(.187,.777),l(-1.22,-.473),l(-.567,-.158),l(-.872,-.03),l(.095,.222),l(.799,.696),l(.853,.426),l(1.842,.645),l(1.296,.644),l(.774,.549),l(.442,.486),l(.429,.689),l(-1.833,-.341),l(-1.524,-.421),l(-1.251,-.28),l(-1.444,-.107),l(-1.092,-.25),l(-.898,-.644),l(-1.146,-.14),l(-.638,-.204),l(-.635,-.141),l(-.058,.145),M(146.194,38.698),l(.818,-.037),l(.78,-.125),l(1.138,-.548),l(.895,-.019),l(1.723,.243),l(.939,.262),l(-.188,.877),l(.515,-.071),l(.66,-.019),l(.792,-.229),l(.599,-.141),l(.758,.016),l(.334,-.071),l(-.989,-.965),l(.156,-.036),l(1.38,.138),l(1.208,.245),l(.675,.245),l(.259,.245),l(.194,.508),l(.965,1.063),l(.638,.346),l(1.045,-.315),l(.14,-.261),l(-1.243,-1.361),l(-.439,-1.321),l(.228,-.354),l(1.91,.262),l(1.775,.156),l(2.031,.719),l(.36,.175),l(.3,.316),l(.16,.701),l(.511,.645),l(.352,.26),l(.856,.606),l(.048,.19),l(-.178,.243),l(-.333,.605),l(.179,.31),l(.224,.12),l(1.4,.649),l(.509,.171),l(1.151,.254),l(1.513,.1),l(2.056,.576),l(1.012,.39),l(.364,.793),l(-.168,.101),l(-1.071,-.082),l(-.811,-.234),l(-.945,-.234),l(-.551,.169),l(-.665,.204),l(-1.021,.036),l(-.256,.118),l(.208,.689),l(1.087,-.069),l(.614,-.152),l(.676,-.119),l(.876,.536),l(-.01,.235),l(-.526,.151),l(-.517,.252),l(-.583,.102),l(-1.417,.12),l(-1.049,-.015),l(-1.194,-.082),l(-1.594,-.248),l(-2.278,-.499),l(-.553,-.217),l(-.436,-.335),l(-.482,-.033),l(-.581,.102),l(-.402,.37),l(-1.114,.505),l(-1.055,.019),l(-1.411,.103),l(-1.253,.42),l(-2.753,.356),l(-1.42,.019),l(-1.205,.086),l(-1.984,-.063),l(-.483,.101),l(-.916,-.015),l(-1,-.282),l(-.061,-.468),l(.198,-.101),l(.002,-.302),l(-.395,-.2),l(-.462,-.1),l(-3.146,-.112),l(-1.258,-.115),l(-.864,-.167),l(-.801,-.2),l(-.753,-.504),l(-1.274,-.554),l(.303,-.069),l(.531,-.222),l(1.572,-.054),l(.603,-.188),l(.558,.016),l(.91,-.019),l(.904,-.087),l(1.716,.031),l(.935,-.002),l(2.14,.047),l(1.09,-.002),l(1.711,-.038),l(.415,-.154),l(-.681,-.221),l(-2.312,-.492),l(-1.942,-.202),l(-4.059,-.061),l(-1.569,-.014),l(-1.694,.055),l(-.955,.053),l(-.604,.001),l(-1.651,-.529),l(.011,-.207),l(.28,-.069),l(.823,-.053),l(1.315,-.209),l(.996,.032),l(1.78,-.141),l(.931,-.105),l(.5,-.277),l(-.392,-.346),l(-2.023,.073),l(-1.578,.159),l(-.393,-.051),l(-.554,-.189),l(-.677,-.346),l(-.65,-.19),l(-.692,.054),l(-.709,-.242),l(-.039,-.279),l(1.304,-.981),l(2.62,-.848),l(.909,-.143),l(.373,-.177),l(1.297,-.267),l(1.324,-.162),l(.701,-.267),l(1.113,-.091),l(1.026,.246),l(-.07,.212),l(-.548,.354),l(-.021,.81),M(251.273,99.526),l(-.188,.153),l(-.16,-.291),l(.192,-.077),l(-.02,-.256),l(.143,-.069),l(-.042,-.154),l(-.224,0),l(-.606,-.231),l(.077,-.229),l(-.31,-2.819),l(-.174,-.274),l(-.488,-.288),l(-.771,-.025),l(-.41,.176),l(-.381,-.085),l(-.505,-.36),l(-.273,-.085),l(-.632,.526),l(-.514,.626),l(-1.139,2.22),l(-1.139,1.45),l(-1.161,-.124),l(-.402,.06),l(-.363,.435),l(-.174,.375),l(-1.093,-.095),l(-1.855,-.004),l(-2.508,-.029),l(-1.76,.009),l(-.968,.523),l(-.534,.305),l(-1.754,.814),l(-.545,.164),l(-.146,.434),l(-.163,.512),l(-.44,.275),l(-1.156,.197),l(-1.305,-.138),l(-1.123,-.01),l(-.93,.091),l(-.47,.203),l(-.162,.375),l(.018,.319),l(.16,.471),l(.047,.362),l(-.875,.427),l(-1.464,.452),l(-.944,.163),l(-.919,.062),l(-.88,.262),l(-.939,.478),l(-.925,.506),l(-.524,.117),l(-.573,-.068),l(-.497,-.169),l(-.371,-.427),l(-.012,-.33),l(.044,-.218),l(.707,-.525),l(.414,-.294),l(.264,-.433),l(.294,-.544),l(.377,-.576),l(.028,-.746),l(-.054,-.545),l(-.876,-3.16),l(-2.529,-1.05),l(-.26,-.33),l(.11,-.318),l(-.307,-.235),l(-.916,-.181),l(-.184,-.294),l(-.178,-.135),l(-.628,.024),l(-.46,-.465),l(-.101,-.429),l(-2.15,-1.061),l(-3.975,-1.576),l(-.977,-.386),l(-.797,-.227),l(-.805,.189),l(-1.469,.592),l(-.707,-.074),l(-.542,.049),l(-.196,-.144),l(-.156,-.115),l(-.474,-.041),l(-.855,.083),l(-.197,-.116),l(-.028,-.282),l(-.373,.075),l(-.412,.191),l(-.219,.06),l(-.573,.141),l(-.506,-.098),l(-.064,-.185),l(-.469,-.086),l(-.241,-.271),l(-.502,-.013),l(-.16,.247),l(-.338,-.48),l(-.271,.012),l(-.02,-.185),l(-1.425,-.208),l(-.518,.076),l(-.833,-.451),l(-.468,-.46),l(-.279,-.371),l(-.896,-.748),l(-.501,.036),l(.131,.347),l(.387,.588),l(-.68,-.003),l(-2.687,.029),l(-2.798,-.029),l(-1.348,.007),l(-2.105,-.003),l(-2.915,.016),l(-2.781,-.029),l(-2.131,.012),l(-2.935,-.014),l(-.601,.003),l(-4.84,-.018),l(-3.617,.004),l(-.875,.005),l(-3.821,-.023),l(-1.089,.035),l(-4.13,-.021),l(-.74,-.011),l(-5.117,.028),l(-1.687,-.006),l(-2.87,.001),l(-3.938,-.008),l(-4.588,.025),l(-1.335,-.022),l(-2.579,-.001),l(-.194,-.013),l(-.187,-.151),l(-.509,-.305),l(-.071,-.437),l(.074,-.346),l(-.708,.25),l(-.373,-.029),l(-.331,-.305),l(-.162,-.496),l(-.125,-.189),l(-.385,.088),l(-.23,.205),l(-.483,.059),l(-.721,-.495),l(-.119,-.425),l(-.201,-.821),l(-1.051,.104),l(-1.01,-.277),l(-.487,-.087),l(-.173,-.087),l(-.143,-.396),l(-.438,-.352),l(-.591,.222),l(-1.236,.046),l(-.461,-.117),l(-.383,-.249),l(-.106,-.25),l(.257,-.648),l(.458,-.222),l(-.227,-.294),l(-1.24,-.086),l(.617,-.518),l(.398,-.281),l(.547,-.149),l(.605,-.508),l(-.874,.006),l(-.621,.149),l(-.362,-.043),L(116,83.422),l(-.039,-.978),l(-.789,.002),l(-1.015,-1.066),l(.132,-.238),l(.034,-.53),l(-.547,.056),l(-.83,.492),l(-1.266,-.934),l(-.384,-.521),l(-.204,-.402),l(-.068,-.432),l(.419,-.404),l(.161,-.254),l(.436,-.3),l(-.358,-.689),l(-.393,-.777),l(.163,-.788),l(-.402,-.255),l(-2.025,-.763),l(-.98,-.314),l(-.189,-.029),l(-.512,-.393),l(-1.67,-1.882),l(-1.769,-1.768),l(-.814,-.58),l(-2.048,-1.175),l(-.35,-.322),l(-.371,-.492),l(-.316,-.199),l(-.832,-.073),l(-.495,.126),l(-.731,.498),l(-1.225,.67),l(-.848,.205),l(-.238,.325),l(-.945,-.673),l(-2.162,-1.318),l(-.348,-.292),l(-.173,-.387),l(-.332,-.388),l(-.739,-.059),l(-2.424,.122),l(-.84,-.074),l(-.196,-.279),l(-.089,-1.046),l(-.026,-2.167),l(.043,-4.334),l(.026,-2.183),l(-.129,-2.796),l(-.052,-2.335),l(-.039,-2.259),l(.003,-2.855),l(-.102,-.483),l(.71,.024),l(.9,-.086),l(.964,.116),l(2.012,.451),l(1.601,.518),l(1.214,.266),l(1.04,.115),l(.731,.032),l(1.619,.164),l(.888,.232),l(.429,.149),l(.254,-.034),l(-.452,-.601),l(-.357,-.2),l(-.345,-.15),l(-.064,-.419),l(1.344,-.423),l(.745,.066),l(.578,-.068),l(.15,-.102),l(1.736,.148),l(.771,-.001),l(1.125,-.373),l(.309,-.186),l(.442,0),l(.656,-.221),l(.759,-.069),l(.866,-.086),l(.734,-.086),l(.469,-.239),l(.392,-.188),l(.771,-.104),l(1.045,-.002),l(.872,.123),l(-.445,.404),l(-.352,.119),l(-1.101,.137),l(-1.092,.373),l(-1.244,.171),l(-1.22,.271),l(-.699,.522),l(-1.767,.255),l(-.681,.487),l(.846,.266),l(1.441,.748),l(-.219,-.55),l(.168,-.351),l(1.196,-.253),l(.39,-.235),l(.726,-.421),l(1.727,-.053),l(.96,-.372),l(1.158,-.389),l(2.066,-.173),l(.643,-.338),l(.921,-.272),l(.821,-.189),l(.476,-.239),l(-.178,-.272),l(-.702,-.392),l(-.655,-.444),l(.899,.101),l(.764,.272),l(.701,.306),l(.412,.324),l(.376,.476),l(.449,.523),l(.393,.235),l(1.246,.486),l(.186,.067),l(1.154,.216),l(.394,-.018),l(.199,-.151),l(-.511,-.639),l(.07,-.27),l(.548,-.035),l(.334,-.136),l(.627,-.103),l(.383,.354),l(.059,.421),l(-.205,.287),l(.833,.133),l(.938,-.069),l(1.136,-.457),l(.536,-.49),l(.479,-.069),l(1.131,.015),l(1.536,.267),l(1.745,.435),l(1.396,.334),l(2.095,.349),l(1.024,.216),l(.619,.066),l(1.572,.282),l(1.121,.065),l(1.144,.148),l(1.096,.032),l(1.4,-.086),l(.899,.099),l(1.008,.282),l(.982,.349),l(.434,.249),l(.191,.333),l(-.524,.134),l(-.935,-.032),l(-.566,.051),l(-.849,.135),l(-.354,.714),l(3.323,.358),l(1.726,.079),l(1.749,.014),l(.868,-.068),l(.738,-.051),l(.94,-.167),l(.895,-.118),l(.938,-.101),l(.886,.032),l(1.432,.477),l(1.452,.179),l(.42,.115),l(1.225,.443),l(-.013,.312),l(-.504,.083),l(-.35,.247),l(.305,.147),l(1.823,.979),l(-.162,-.392),l(-.024,-.312),l(.456,-.05),l(.617,-.132),l(-.062,-.181),l(-.972,-.656),l(-.128,-.198),l(-.145,-.445),l(.121,-.745),l(.35,-.034),l(1.944,-.136),l(.928,-.151),l(.207,-.299),l(.459,-.217),l(.613,-.035),l(1.098,.281),l(1.528,.279),l(.968,.064),l(.969,-.102),l(.612,.414),l(.248,.082),l(.962,.213),l(1.211,.13),l(.678,.081),l(1.146,-.002),l(.879,-.2),l(1.755,-.02),l(1.876,.029),l(1.07,-.052),l(1.18,-.267),l(.959,.478),l(.95,.296),l(.522,-.018),l(.243,-.314),l(-.017,-.513),l(-.666,-.231),l(-.732,-.131),l(-1.377,-.064),l(.089,-.449),l(1.193,-.085),l(.575,.065),l(.804,.214),l(.871,.198),l(.858,.048),l(.498,.198),l(.088,.183),l(-.095,.132),l(-.287,.86),l(.179,.51),l(.304,.164),l(.177,.065),l(.792,.097),l(.951,.311),l(-.071,-.559),l(-.466,-.989),l(.137,-.48),l(.258,-.266),l(.712,.015),l(.811,-.035),l(1.229,-.85),l(.492,-.051),l(.479,-.001),l(.517,-.151),l(.033,-.133),l(-.15,-.367),l(-.375,-.35),l(-.307,.001),l(-.81,.185),l(-.988,-.082),l(.535,-.52),l(.806,-.069),l(.435,-.168),l(.572,-.001),l(.739,.4),l(.464,.167),l(.065,-.268),l(-.081,-.956),l(-.744,.069),l(-.897,-.032),l(-.68,-.116),l(-.859,-.318),l(-.725,.085),l(-1.245,-.183),l(-.861,-.234),l(-.956,-.218),l(-.657,-.338),l(-.092,-.136),l(-.022,-.324),l(.33,-.137),l(.842,-.463),l(-.486,-.221),l(-1.188,-.375),l(.09,-.207),l(.58,-.604),l(.593,-.294),l(.387,-.035),l(1.032,.257),l(.139,-.035),l(.173,-.346),l(-.709,-.362),l(-.201,-.277),l(.23,-.035),l(.551,-.331),l(.367,-.035),l(1.841,-.021),l(.559,.086),l(.728,.189),l(1.26,.449),l(.432,.328),l(.195,.38),l(-.246,.603),l(1.261,.53),l(.809,.495),l(1.134,.493),l(-.377,.341),l(-.985,.036),l(-.474,.273),l(-.416,.557),l(.471,.067),l(1.071,.233),l(.805,.049),l(.387,-.136),l(.597,-.001),l(1.477,.351),l(-.335,.353),l(-.563,.219),l(.092,.151),l(.796,.467),l(.358,.601),l(.025,.833),l(.303,-.063),l(.021,-.004),l(.411,-.067),l(.608,-.367),l(.655,-1.137),l(.668,-.42),l(.523,.016),l(.731,.284),l(1.064,.55),l(.473,.383),l(.209,.45),l(-.159,.433),l(-.336,.034),l(-.796,-.098),l(-.202,.299),l(-.043,.415),l(.35,.396),l(1.146,.659),l(.61,.493),l(.463,.279),l(.595,-.166),l(.896,-.167),l(.369,-.132),l(.208,-.66),l(.764,-.398),l(.599,-.416),l(.249,-.664),l(.363,-.75),l(.237,-.184),l(1.394,.081),l(.329,-.067),l(.134,-.518),l(-.985,-.333),l(-.918,-.35),l(.088,-.891),l(.595,-.271),l(.787,.032),l(.42,-.068),l(.571,.016),l(3.459,.616),l(1.325,.669),l(.506,-.001),l(.553,-.068),l(.454,.201),l(.244,1.036),l(-.474,.268),l(-.431,.101),l(-.243,-.05),l(-.718,-.532),l(-.263,0),l(-.799,.269),l(.123,.316),l(.309,.515),l(.699,.729),l(.855,.528),l(1.108,.576),l(.024,.313),l(-.478,.642),l(-.439,.181),l(-1.407,.772),l(-.674,.083),l(-1.123,.509),l(-.763,-.276),l(-1.654,-.962),l(-.586,-.262),l(-.497,-.048),l(-.684,.281),l(1.364,.521),l(1.483,.896),l(-.708,.067),l(-.691,-.081),l(-1.288,.084),l(-.375,-.129),l(-.596,-.62),l(-1.147,-.014),l(-1.857,.118),l(-.253,.229),l(.614,.244),l(1.311,.421),l(-.159,.195),l(-.611,.327),l(-2.045,1.106),l(-.657,.179),l(-.527,.001),l(-.859,-.241),l(-.816,-.484),l(-.225,-.081),l(-1.189,-.225),l(-.736,-.259),l(-.598,-.112),l(-.947,.014),l(-.289,.004),l(-1.214,.174),l(1.503,.278),l(1.136,.21),l(1.751,.774),l(1.629,.433),l(1.233,.126),l(1.02,.031),l(-.618,1.091),l(-1.237,.705),l(-.856,.432),l(-.728,.161),l(-.829,.049),l(-.928,-.126),l(-1.062,-.38),l(-.048,.351),l(-.025,.287),l(.321,.572),l(-.02,.159),l(-.741,.031),l(-.058,.002),l(-1.365,-.108),l(-1.649,-.41),l(-.884,-.078),l(-2.962,-.322),l(2.146,.864),l(1.576,.156),l(1.367,.267),l(.562,.205),l(.33,.268),l(-.011,.19),l(-.642,.333),l(-1.106,.207),l(-1.429,-.076),l(-.511,-.062),l(-.367,.269),l(1.254,.423),l(-.469,.426),l(-1.06,.316),l(-1.454,.662),l(-.421,.252),l(.218,.704),l(-.313,.235),l(-.909,.205),l(-.31,.282),l(-.529,.64),l(-.276,.296),l(-.241,.669),l(-.274,.543),l(-.323,.666),l(.056,.416),l(-.161,.554),l(.123,.875),l(.136,.536),l(.598,.366),l(.25,.015),l(.257,.091),l(.664,.014),l(1.164,-.094),l(.276,.045),l(.367,.29),l(.413,.763),l(.813,1.157),l(.22,.668),l(-.132,.91),l(.673,.014),l(1.874,-.428),l(1.261,-.033),l(.723,.074),l(.535,.157),l(1.062,.311),l(2.129,.435),l(1.896,.903),l(.993,.933),l(3.5,.67),l(.644,.225),l(.982,.403),l(.986,.253),l(.553,.104),l(.702,-.091),l(.453,.044),l(.828,-.077),l(1.245,.163),l(1.407,.207),l(.401,.194),l(-.297,.702),l(-.142,.85),l(.154,.283),l(.307,.342),l(.07,.416),l(-.115,1.025),l(-.309,.593),l(.022,.208),l(.604,.266),l(.481,.339),l(.264,.354),l(.046,.488),l(-.076,.354),l(.97,.116),l(.963,.47),l(.676,.588),l(.392,.588),l(.078,.162),l(.64,.014),l(.726,.41),l(.907,.601),l(-.349,-.66),l(-.22,-.279),l(.134,-.338),l(.573,-.414),l(.365,.176),l(.381,.456),l(.262,.353),l(.165,-.354),l(.107,-.545),l(-.215,-.456),l(.541,-.532),l(.139,-.546),l(-.183,-.517),l(-.337,-.458),l(-.261,-.754),l(-.004,-.548),l(-.205,-.593),l(-.218,-.43),l(.615,-.016),l(-.097,-.476),l(-.296,-.252),l(-.657,-.163),l(-.375,-.282),l(-.326,-.923),l(1.252,-.271),l(.872,-.241),l(.625,-.271),l(1.758,-.949),l(.629,-.302),l(1.043,-.935),l(.434,-.544),l(.237,-.665),l(.054,-.529),l(-.257,-1.045),l(-.246,-.531),l(-.239,-.319),l(-.938,-.729),l(-.467,-.274),l(-1.105,-.532),l(-.363,-.122),l(-.453,-.274),l(-.151,-.046),l(-.293,-.351),l(.08,-.107),l(.868,-.522),l(.553,-.875),l(.293,-.416),l(.25,-.092),l(.447,-.017),l(.295,-.277),l(-.106,-.523),l(-.18,-.355),l(-.316,-.402),l(-.048,-.202),l(.258,-.357),l(.005,-.264),l(-1.751,-.105),l(1.084,-.92),l(.503,-.704),l(.007,-.125),l(-.316,-.203),l(-.609,-.265),l(-.244,-.266),l(-.043,-.533),l(.305,-.425),l(.554,-.315),l(.57,-.19),l(.827,.062),l(1.781,.374),l(1.097,.234),l(.753,.077),l(1.44,.013),l(1.08,-.144),l(.86,-.222),l(.21,-.047),l(.179,-.063),l(.589,.078),l(.991,.407),l(.254,.125),l(.754,.454),l(.918,.375),l(.796,.437),l(-.294,.391),l(.406,.233),l(1.698,.496),l(1.958,.354),l(.725,-.033),l(.368,-.203),l(.339,.295),l(-.013,.404),l(-.577,.343),l(-.123,.45),l(.438,1.327),l(.136,.722),l(.23,.414),l(-.049,.353),l(-.248,.169),l(-.445,-.014),l(-.347,-.015),l(-.138,.674),l(.375,.274),l(1.137,-.415),l(.366,-.047),l(.781,-.047),l(.286,.015),l(.677,.32),l(.378,.351),l(.004,.259),l(-.081,.123),l(.277,.32),l(.516,-.184),l(.306,-.046),l(1.173,-.079),l(.636,-.184),l(.436,-.383),l(.333,-.551),l(.326,.015),l(.194,.122),l(.693,.717),l(.042,-.062),l(.108,-.764),l(.317,-.583),l(.475,-.262),l(.539,-.385),l(-.651,-.505),l(.008,-.308),l(.272,-.139),l(.98,-.094),l(.193,-.139),l(.512,-.665),l(.667,.37),l(.607,.599),l(.785,.506),l(.596,.797),l(1.045,.764),l(.264,.352),l(-.344,.291),l(.095,.335),l(.573,-.031),l(.365,.777),l(.182,.183),l(.324,.121),l(.743,.136),l(.281,.258),l(.133,.38),l(-.379,.092),l(-.416,.168),l(.411,.318),l(.397,.227),l(.77,.196),l(.279,.227),l(.034,.424),l(-.056,.076),l(-.409,.106),l(-.676,-.029),l(-.745,-.12),l(-.316,.061),l(.091,.166),l(.273,.181),l(.189,.241),l(.333,.513),l(.411,.226),l(.634,.029),l(.462,.18),l(.838,.496),l(.899,.435),l(.246,.33),l(-.035,.195),l(-.447,.781),l(.508,.059),l(.663,-.166),l(.786,-.077),l(.79,.164),l(.574,.194),l(1.162,.49),l(.981,.132),l(1.517,.295),l(-.184,.253),l(-.718,.21),l(-.736,.21),l(-.663,.046),l(-.834,.24),l(-.583,.402),l(-.65,.225),l(-1.032,.061),l(-.286,.075),l(-.324,.268),l(.029,.371),l(-.271,.535),l(1.175,-.343),l(.542,-.09),l(.649,-.105),l(1.201,-.774),l(1.251,-.478),l(1.146,-.106),l(.662,.237),l(.35,.341),l(-.398,.446),l(.036,.119),l(.307,.296),l(.616,-.224),l(.455,-.164),l(.655,.192),l(1.051,.487),l(.226,.251),l(.022,.178),l(-.299,.43),l(-.05,.355),l(-.406,.444),l(1.001,.929),l(-.365,.37),l(-.795,.282),l(-1.078,.621),l(-.662,.281),l(-1.097,.046),l(-.823,.119),l(-1.548,.077),l(-.433,.413),l(-.916,.795),l(-.686,.427),l(-.612,.294),l(-.938,.222),l(-1.494,.172),l(-1.845,.127),l(-1.452,-.07),l(-2.031,-.084),l(-.355,.03),l(-1.073,.075),l(-1.058,-.012),l(-1.873,-.099),l(-.917,-.027),l(-1.758,.106),l(-.547,.206),l(-.523,.294),l(-.537,.585),l(-.205,.554),l(-.287,.335),l(-.591,.19),l(-1.07,.104),l(-.537,.147),l(-1.098,.555),l(-.774,.54),l(-.794,.612),l(-.325,.363),l(-.33,.233),l(-.868,.843),l(-.485,.566),l(-.418,.276),l(-.46,.58),l(-.518,.968),l(.749,-.737),l(.375,-.131),l(.688,-.479),l(1.059,-.944),l(1.097,-.785),l(2.028,-.948),l(1.245,-.395),l(1.797,-.512),l(1.065,-.235),l(1.03,-.235),l(1.473,-.148),l(.922,.056),l(.895,.289),l(.509,.29),l(.136,.189),l(.144,.464),l(-.125,.218),l(-.326,.219),l(-1.059,.292),l(-.753,.452),l(-.581,.044),l(-.845,-.23),l(-.726,.045),l(-.645,.19),l(.279,.08),l(1.13,.229),l(.17,.122),l(.256,.444),l(.074,.095),l(1.299,-.485),l(-.028,.216),l(.479,-.148),l(.372,.162),l(-.36,.229),l(-.231,.256),l(.112,.27),l(-.163,.014),l(-.074,.229),l(-.91,.444),l(1.216,.013),l(.077,.188),l(-.187,.282),l(.091,.43),l(.118,-.081),l(.239,.134),l(-.063,.134),l(.048,.202),l(.351,.457),l(.009,.147),l(.824,.054),l(.154,.094),l(.04,-.067),l(.727,.147),l(-.315,.134),l(-.373,-.013),l(-.047,.134),l(.525,.147),l(.211,.241),l(.569,-.081),l(.135,.134),l(.212,-.014),l(.134,.174),l(.418,-.04),l(-.075,-.107),l(.843,.067),l(.241,.107),l(-.207,.201),l(.242,-.107),l(.26,.027),l(.245,-.013),l(.696,-.362),l(.303,-.081),l(.104,.362),l(.377,.161),l(.538,-.121),l(.488,.416),l(-.405,.254),l(.089,.107),l(.825,.027),l(.164,.174),l(-.521,.121),l(-.161,-.121),l(-.3,.134),l(.118,.094),l(-.515,0),l(-.23,-.04),l(.109,.161),l(-.45,.04),l(.056,.107),l(-.443,.014),l(-.128,.147),l(-.45,.04),l(-.368,.253),l(-.09,-.106),l(-.706,.28),l(-.046,.053),l(-.529,.133),l(-.119,-.267),l(-.274,.106),l(-.163,.267),l(-.188,-.187),l(-.068,.253),l(-.218,.08),l(-.094,.187),l(-.513,0),l(-.081,-.08),l(-.169,-.053),l(.032,-.347),l(-.242,.36),l(-.202,.12),l(-.131,-.253),l(-.354,.027),l(.043,.24),l(-.233,.04),l(.312,.08),l(.033,.213),l(-.103,.12),l(-.174,-.067),l(-.768,.453),l(.127,.16),l(-.235,.12),l(-.194,.053),l(.015,.213),l(-.161,-.12),l(.083,.173),l(-.217,.08),l(-.14,-.107),l(.096,.253),l(-.222,.066),l(-.146,-.08),l(-.148,0),l(-.064,.133),l(-.156,-.106),l(-.243,.227),l(-.086,.292),l(-.201,-.226),l(-.344,.133),l(-.154,-.187),l(-.349,-.479),l(-.138,.24),l(-.419,-.866),l(.456,-.773),l(.284,-.16),l(.035,-.12),l(-.35,.12),l(-.357,.267),l(-.076,-.106),l(.924,-.507),l(.125,.146),l(.195,-.093),l(-.258,-.107),l(1.103,-.52),l(1.109,-.562),l(.658,-.361),l(.336,.094),l(-.067,.428),l(.179,-.054),l(.258,.281),l(-.044,-.201),l(-.017,-.174),l(.632,-.214),l(.73,-.134),l(.192,.067),l(.202,-.081),l(-.152,-.094),l(-.653,-.053),l(-.595,.053),l(-.42,-.053),l(-.804,-.014),l(-.306,.027),l(-.251,.081),l(-.246,.094),l(.033,-.214),l(1.128,-.563),l(.054,-.201),l(.252,-.08),l(-.052,-.174),l(-.523,.281),l(.097,-.134),l(-.502,-.51),l(.309,.443),l(-.36,.482),l(-.328,.013),l(-1.974,.817),l(-.284,.08),l(-.362,-.201),l(-.227,-.067),l(.23,.201),l(-.788,.401),l(-.219,-.174),l(-1.019,-.054),l(-.124,.147),l(-.38,-.241),M(186.193,47.833),l(-.713,-.032),l(-.922,-.181),l(-.882,-.065),l(-1.25,-.314),l(-.973,-.182),l(-.604,-.049),l(-1.083,-.199),l(.43,-.335),l(1.542,-.405),l(.385,-.186),l(.115,-.673),l(.305,-.236),l(.831,-.069),l(.743,.184),l(1.436,.603),l(1.287,.4),l(.074,.285),l(.315,.284),l(1.094,.516),l(-.288,.117),l(-1.263,.486),l(-.578,.051),M(231.09,50.646),l(-1.319,-.03),l(-.449,-.147),l(-.232,-.247),l(-.173,-.478),l(.3,-.43),l(.708,-.664),l(.662,-.267),l(1.359,-.168),l(.911,.197),l(.79,.314),l(-.021,.464),l(-.039,.727),l(-.362,.265),l(-1.025,.348),l(-1.108,.117),
+N(444.972,79.145),l(.47,-.218),l(.307,-.093),l(-.294,-.024),l(-.419,.061),l(-.15,-.135),l(-.125,.184),l(-.108,-.012),l(.066,-.491),l(.177,-.218),l(.41,.009),l(1.489,.062),l(.417,.014),l(.339,-.075),l(.121,-.253),l(-.175,-.288),l(.246,-.05),l(-.068,-.122),l(-.068,-.123),l(.353,-.096),l(.12,-.034),l(.051,.154),l(.086,.052),l(.24,0),l(.223,.12),l(.257,.069),l(.514,.068),l(.086,.103),l(.223,-.051),l(.445,0),l(.257,0),l(.223,-.017),l(.086,.137),l(.103,.103),l(.188,.034),l(.171,.069),l(.018,.137),l(.052,.12),l(-.224,.12),l(-.068,.154),l(-.068,.206),l(.018,.171),l(.034,.137),l(.029,.038),l(-2.96,.101),l(-2.246,-.115),l(-.842,-.006),M(717.633,81.109),l(.42,.443),l(.429,.62),l(.183,.457),l(.01,.767),l(-.244,.442),l(-.197,.78),l(-.002,.764),l(.29,.777),l(.592,.849),l(.65,1.446),l(.899,1.614),l(1.115,1.679),l(-1.26,-.677),l(-.832,-.39),l(-.99,-.056),l(-.268,.088),l(-.396,.204),l(-.462,1.045),l(-.266,1.101),l(-.082,.579),l(.277,.982),l(.183,.216),l(.659,.908),l(.54,.201),l(.463,.648),l(-.314,1.246),l(-.664,-1.258),l(-.866,-.301),l(-.224,.029),l(-.415,.303),l(-.311,.534),l(-.643,.907),l(-.422,-.5),l(-.19,-.929),l(.637,-1.146),l(-.395,-.884),l(.175,-.454),l(.502,-.63),l(-.131,-.723),l(-.196,-.376),l(-.27,-.55),l(-.062,-.235),l(.403,-.302),l(.284,-.915),l(.075,-.784),l(.005,-1.326),l(.15,-1.302),l(-.09,-.732),l(-.213,-.469),l(-.83,-.85),l(-.1,-.897),l(.114,-.192),l(.359,-.722),l(.065,-.738),l(-.336,-.457),l(.172,-.237),l(.374,-.03),l(.62,-.031),l(1.023,-.534),M(471.158,84.281),l(-.002,-.142),l(-.165,-.066),l(-.082,-.115),l(-.164,-.082),l(.033,-.099),l(-.033,-.23),l(-.033,-.164),l(.082,-.099),l(-.147,-.131),l(-.099,-.148),l(.132,-.066),l(0,-.165),l(-.296,-.164),l(-.279,-.263),l(-.017,-.164),l(.099,-.131),l(.131,-.165),l(.362,-.017),l(.328,.049),l(.197,.132),l(.51,.016),l(.525,-.099),l(.444,-.247),l(.049,-.065),l(.148,-.083),l(.296,0),l(.065,-.164),l(-.033,-.131),l(-.279,-.066),l(-.296,-.148),l(-.099,-.181),l(.082,-.017),l(.066,-.049),l(.032,-.065),l(-.263,-.066),l(-.361,-.099),l(-.378,-.066),l(-.361,.066),l(-.182,-.066),l(.066,-.181),l(.099,-.197),l(-.066,-.148),l(-.164,-.099),l(-.279,-.082),l(-.23,-.066),l(-.443,-.213),l(-.115,-.23),l(-.164,-.263),l(-.214,-.017),l(-.017,-.099),l(.066,-.131),l(.099,-.115),l(-.132,-.033),l(-.181,.049),l(-.082,-.115),l(-.132,-.181),l(-.345,-.049),l(.049,-.147),l(.033,-.165),l(.099,-.049),l(.115,-.082),l(0,-.083),l(.114,0),l(.066,-.131),l(-.05,-.164),l(-.147,-.099),l(-.197,-.247),l(.131,-.165),l(.033,-.164),l(0,-.083),l(.065,-.115),l(-.049,-.115),l(-.147,.033),l(-.165,-.033),l(-.147,-.099),l(-.099,-.099),l(-.279,-.099),l(-.132,-.131),l(-.542,-.115),l(-.247,.049),l(-.099,-.049),l(-.131,-.049),l(-.23,.083),l(-.147,.099),l(-.165,0),l(-.279,.016),l(-.214,.197),l(-.197,0),l(-.164,-.148),l(-.065,-.148),l(.017,-.099),l(.164,-.099),l(0,-.115),l(-.147,-.017),l(-.296,-.065),l(-.312,-.049),l(-.361,.049),l(-.214,.065),l(-.197,.033),l(-.082,-.148),l(-.132,-.148),l(-.312,-.033),l(-.181,-.016),l(-.197,.131),l(-.229,-.066),l(-.165,-.147),l(.061,-.042),l(.015,-.117),l(.044,-.087),l(-.088,-.233),l(.015,-.189),l(-.131,-.117),l(.059,-.087),l(-.16,-.043),l(-.146,-.102),l(-.029,-.16),l(-.131,-.058),l(-.116,-.102),l(.043,-.073),l(.059,-.087),l(-.073,-.044),l(-.087,-.014),l(-.131,-.073),l(-.146,.015),l(-.204,.059),l(.044,-.102),l(.102,-.073),l(.073,-.087),l(-.029,-.117),l(.072,-.131),l(-.131,-.087),l(.103,-.029),l(.087,-.015),l(.102,-.073),l(.015,-.087),l(.029,-.116),l(.015,-.087),l(-.204,-.058),l(-.087,-.073),l(-.204,-.087),l(-.232,-.073),l(0,-.117),l(.015,-.116),l(-.37,.004),l(-.081,-.106),l(.116,-.058),L(461.402,72),l(.029,-.117),l(.131,0),l(.087,-.116),l(.059,-.102),l(.16,-.058),l(.262,-.043),l(.175,-.073),l(-.059,-.059),l(-.175,-.043),l(-.043,-.146),l(-.015,-.087),l(0,-.073),l(-.088,-.073),l(-.203,-.087),l(-.175,-.233),l(0,-.175),l(.175,-.131),l(-.029,-.16),l(-.073,-.189),l(-.131,-.437),l(-.029,-.16),l(.088,-.16),l(.204,-.131),l(.319,-.131),l(.219,-.204),l(.175,-.277),l(.058,-.131),l(.088,-.043),l(.116,0),l(.189,0),l(.175,-.044),l(.043,-.174),l(-.16,-.131),l(-.145,-.053),l(-.089,-.13),l(-.17,-.038),l(.1,-.253),l(.339,-.038),l(.153,.165),l(.229,.063),l(.188,-.088),l(-.094,-.139),l(.301,-.154),l(.485,.199),l(.296,-.062),l(.312,-.338),l(.311,-.185),l(.75,.106),l(.781,.275),l(.439,0),l(.363,-.154),l(-.386,-.399),l(-.59,-.323),l(-.393,-.03),l(-1.204,.08),l(-.616,-.091),l(-.271,-.108),l(-.299,-.309),l(.258,-.434),l(-.065,-.201),l(-.199,.044),l(.174,-.285),l(1.946,-1.145),l(1.983,-1.195),l(1.385,-.758),l(.591,-.536),l(.43,-.536),l(.105,-.409),l(-.161,-.346),l(-.436,-.392),l(-.703,-.265),l(-1.357,-.499),l(-.439,-.33),l(.327,-.191),l(.542,-.415),l(.057,-.254),l(-.151,-.253),l(-1.286,-1.395),l(-.37,-.509),l(.029,-.37),l(.187,-.403),l(.44,-.535),l(.196,-.356),l(-.772,-1.195),l(-1.402,-1.394),l(.328,-.296),l(1.303,-.777),l(.421,-.364),l(-.543,-.392),l(-.964,-.506),l(-.872,-.194),l(-.563,-.212),l(-.116,-.529),l(.258,-.465),l(.024,-.283),l(.689,-.303),l(1.013,-.672),l(1.023,-.49),l(.77,-.121),l(.824,-.021),l(.514,-.204),l(.404,-.288),l(.617,-.051),l(1.002,-.254),l(.643,-.237),l(.01,.151),l(.255,.386),l(.358,.284),l(.543,.2),l(.919,.082),l(.602,.1),l(.078,.602),l(.695,-.319),l(.421,.049),l(1.083,.048),l(.875,.015),l(.522,.032),l(1.116,-.002),l(1.293,.281),l(2.728,.512),l(.984,.364),l(1.595,.86),l(.583,.214),l(1.48,.246),l(1.296,.212),l(2.018,.623),l(.328,.279),l(-.051,.444),l(.147,.295),l(.426,.294),l(.104,.294),l(-.24,.344),l(-.69,.491),l(-1.092,.54),l(-.816,.262),l(-1.75,.36),l(-.907,.083),l(-1.631,-.013),l(-1.391,-.192),l(-2.038,-.175),l(-1.63,-.192),l(-1.342,-.339),l(-2.256,-.485),l(-1.114,-.112),l(-.476,-.048),l(-.621,-.473),l(-.371,-.163),l(-.771,-.13),l(-.943,.117),l(.307,.163),l(.149,.065),l(.73,.538),l(.482,.146),l(1.109,.601),l(.832,.291),l(.921,.161),l(.634,.242),l(.405,.453),l(-.002,.405),l(-.276,.291),l(-.684,.195),l(.086,.113),l(.208,.531),l(.771,.943),l(.093,.494),l(.155,.207),l(.438,.174),l(1.203,.078),l(.872,.125),l(.499,.619),l(.401,.095),l(1.26,.077),l(.575,.126),l(.364,.079),l(.402,-.128),l(.785,-.097),l(.243,-.302),l(-.001,-.318),l(-.387,-.397),l(-.471,-.079),l(-.455,.096),l(-.447,-.031),l(-.589,-.206),l(-.952,-.795),l(.701,-.674),l(.484,-.001),l(1.116,.479),l(1.441,.333),l(2.09,.427),l(.952,.078),l(.834,-.146),l(.723,.174),l(.261,-.224),l(.05,-.415),l(-.214,-.239),l(-.858,-.656),l(-.348,-.628),l(.285,-.323),l(.19,-.049),l(1.432,-.423),l(1.495,-.359),l(.599,-.244),l(1.133,-.717),l(.172,-.049),l(.462,.064),l(1.829,.29),l(1.41,.533),l(.341,-.001),l(.052,-.065),l(.154,-.503),l(.581,-.767),l(-.048,-.653),l(-.317,-.408),l(-.847,-.163),l(-.3,-.229),l(1.139,-1.005),l(.101,-.247),l(-.205,-.594),l(-.771,-.512),l(.069,-.315),l(.353,-.051),l(1.458,.23),l(2.025,-.12),l(.631,.132),l(.664,.611),l(.616,.445),l(.433,.461),l(-1.045,.051),l(-1.559,.085),l(-.822,.215),l(-.492,.51),l(.191,.18),l(.952,.293),l(.732,.555),l(.804,.194),l(.723,.097),l(1.268,-.133),l(1.33,-.084),l(.301,-.164),l(.257,-.491),l(.291,-.591),l(.284,-.412),l(1.232,-.2),l(1.223,-.414),l(.988,-.216),l(1.924,-.483),l(1.429,-.251),l(1.537,-.318),l(.921,-.3),l(.205,.464),l(.278,.083),l(.571,-.117),l(.487,-.266),l(.148,-.465),l(.386,-.167),l(.718,-.135),l(.859,.065),l(-.18,.399),l(-.058,.597),l(-.858,.084),l(-.178,.149),l(.002,.215),l(.687,.197),l(.507,-.083),l(1.169,-.167),l(.436,-.001),l(.161,.198),l(.23,.049),l(.278,-.133),l(.264,-.216),l(.29,-.431),l(.464,-.183),l(.861,-.118),l(1.049,-.068),l(.768,.032),l(1.075,.23),l(.755,-.018),l(.36,-.083),l(.963,-.467),l(1,-.285),l(.803,-.052),l(.952,.182),l(.326,.166),l(-.631,.45),l(.129,.232),l(.217,.099),l(.632,.131),l(.579,-.018),l(.288,-.232),l(.074,-.398),l(.342,-.084),l(.962,.065),l(.543,-.184),l(.395,-.316),l(.115,-.417),l(-1.37,-1.033),l(.405,-.168),l(.66,-.37),l(.403,-.068),l(.609,.016),l(2.171,.063),l(1.272,.199),l(1.241,.149),l(1.135,.199),l(2.111,.515),l(1.071,.098),l(1.712,.414),l(1.02,.248),l(1.305,.53),l(1.455,.611),l(.864,.379),l(.376,.049),l(.229,-.1),l(1.145,-1.047),l(.236,-.3),l(-.927,.035),l(-.4,-.049),l(-.564,-.232),l(-.365,-.433),l(.027,-.652),l(-.727,-.283),l(-1.987,-.147),l(-.19,-.268),l(.064,-.168),l(.305,-.303),l(.693,-.255),l(.236,-.153),l(.085,-.187),l(-.052,-.833),l(-.251,-.238),l(-1.135,-.066),l(-.232,-.29),l(.328,-.532),l(.359,-.241),l(.391,-.035),l(1.482,-.416),l(1.098,-.485),l(.521,-.416),l(.581,-.608),l(.544,-1.22),l(.637,-.421),l(.374,.069),l(1.562,.155),l(1.613,-.125),l(1.605,-.091),l(.695,.069),l(1.066,-.055),l(.574,.122),l(.309,.279),l(-.018,.332),l(-.423,.836),l(-.348,.348),l(-1.334,.833),l(-.223,.345),l(.752,.342),l(.931,.667),l(.277,.342),l(.21,.818),l(-.174,.222),l(-.575,.375),l(.254,1.179),l(-.058,1.305),l(.263,.583),l(.45,.381),l(1.027,.264),l(.19,.166),l(-.001,.133),l(-.485,.481),l(-.417,.826),l(-.333,.33),l(-.784,.462),l(-1.232,.625),l(-.63,.198),l(-.55,.263),l(.321,.522),l(-.433,.115),L(558,52.195),l(-1.599,-.372),l(-.731,-.08),l(-.97,.034),l(-.601,.115),l(.195,.31),l(.583,.276),l(.738,.21),l(1.569,.208),l(1.133,.079),l(.613,-.05),l(1.188,.144),l(.922,-.034),l(.472,-.358),l(.303,-.358),l(1.352,-.328),l(1.166,-.492),l(.268,-.278),l(.386,-.606),l(.818,-.313),l(.864,-.626),l(.064,-.362),l(-.225,-.561),l(-.609,-.545),l(.244,-.548),l(.237,-.1),l(.677,-.151),l(1.38,-.152),l(1.757,-.003),l(.74,.231),l(.842,.463),l(.151,.778),l(-.34,1.023),l(.302,.279),l(.92,.212),l(1.298,.047),l(.864,-.149),l(.129,-.296),l(-.514,-.18),l(-.797,-.18),l(-.571,.034),l(-.457,-.098),l(.068,-.379),l(1.03,-.382),l(.065,-.249),l(-.218,-.148),l(-.166,-.331),l(-.441,-.763),l(-.511,-.266),l(-.836,-.098),l(-1.093,-.231),l(-.801,-.116),l(-1.288,-.165),l(-.91,.186),l(-.638,.101),l(-1.297,-.181),l(-.896,.019),l(-.015,-.267),l(-.564,-1.071),l(.305,-.657),l(.736,-.697),l(.282,-.46),l(-.134,-.221),l(-1.092,-1.042),l(-.949,-.514),l(-.12,-.189),l(.833,-.554),l(1.213,-.106),l(.998,-.262),l(.744,-.348),l(.172,-.226),l(.169,-.644),l(-.13,-.663),l(.23,.069),l(.64,.051),l(.466,.086),l(.108,.471),l(-.186,.54),l(-.636,.608),l(-.167,.554),l(.14,.448),l(.373,.274),l(.485,.274),l(1.384,.134),l(1.574,.169),l(1.632,.083),l(.819,.409),l(.321,.017),l(.799,-.036),l(-.527,-.89),l(-.521,-.274),l(-1.893,-.1),l(-.931,-.067),l(-.576,-.154),l(-.609,-.448),l(.275,-.329),l(1.374,-.054),l(.444,.172),l(1.145,.084),l(.747,-.157),l(-.09,-.728),l(.408,-.088),l(.84,-.105),l(1.278,-.02),l(1.067,.207),l(1.413,.379),l(1.088,.535),l(1.326,.343),l(.547,.085),l(1.822,.014),l(.727,-.174),l(.138,.345),l(-.781,.38),l(-.696,.259),l(-.248,.771),l(-.129,.972),l(.333,.136),l(.68,-.785),l(.387,-.292),l(.285,.051),l(.604,.528),l(-.088,.749),l(.743,-.205),l(.681,-.273),l(-.044,-.306),l(-.191,-.119),l(-.147,-.358),l(-.748,-.821),l(.188,-.223),l(.686,-.759),l(-.797,-.448),l(-.772,-.258),l(-.93,-.241),l(-.257,-.382),l(-.655,-.051),l(-.979,-.242),l(-1.34,-.207),l(-.307,-.296),l(.062,-.577),l(-.096,-.386),l(-.811,-.667),l(.081,-.247),l(.266,-.16),l(.484,-.125),l(2.31,-.11),l(2.54,-.022),l(2.125,-.128),l(1.421,-.162),l(.475,.317),l(.382,.052),l(.844,-.267),l(1.056,-.286),l(1.413,-.109),l(.589,.194),l(-.957,.338),l(-.451,.407),l(1.737,-.233),l(.521,-.107),l(.955,-.374),l(.27,-.284),l(-.334,-.444),l(-.326,-.177),l(-.925,-.266),l(-.365,-.303),l(-.002,-.232),l(.324,-.539),l(1.176,-.397),l(.966,-.22),l(3.028,-.903),l(.889,-.094),l(.248,-.036),l(.522,-.076),l(1.899,-.096),l(1.663,-.114),l(2.302,-.244),l(2.048,-.263),l(1.595,-.43),l(.855,-.243),l(1.763,.034),l(1.065,-.002),l(.383,.185),l(-.351,.409),l(1.504,.108),l(1.018,-.039),l(1.261,-.188),l(1.345,-.225),l(.95,-.039),l(.982,.166),l(.687,.073),l(.693,-.206),l(.12,-.335),l(-.133,-.167),l(.466,-.337),l(.942,-.077),l(.939,.036),l(1.243,-.377),l(-.618,-.506),l(.122,-.34),l(1.165,-.438),l(1.554,-.383),l(2.23,-.406),l(1.229,-.077),l(.993,.056),l(1.486,-.003),l(.86,.265),l(.045,.266),l(-1.528,.401),l(-.66,.342),l(.488,.15),l(1.83,-.117),l(1.588,.148),l(2.039,-.079),l(.177,.113),l(-.375,.283),l(-1.187,.453),l(-.296,.3),l(1.971,-.004),l(.833,-.02),l(.234,.093),l(1.052,-.545),l(1.366,-.002),l(1.771,-.097),l(.631,.13),l(1.35,-.021),l(1.954,.165),l(1.4,.259),l(1.181,.427),l(.52,.445),l(.726,-.001),l(.854,-.076),l(.422,.5),l(-1.354,.832),l(.241,.128),l(.896,.365),l(-2.329,.859),l(-1.035,.235),l(-1.166,.11),l(-3.404,1.061),l(-3.018,.965),l(-.793,.285),l(-2.388,.375),l(-2.35,.586),l(-2.065,1.126),l(.715,.017),l(1.081,-.247),l(.922,-.458),l(1.663,-.161),l(1.231,-.02),l(2.101,-.268),l(1.879,-.286),l(.879,-.107),l(1.004,-.284),l(-.094,-.389),l(-.492,-.123),l(-.034,-.071),l(.281,-.249),l(.581,-.214),l(.873,.211),l(.603,.389),l(.621,.052),l(.593,.193),l(.737,.052),l(.853,-.055),l(1.155,-.268),l(.499,.07),l(.192,.3),l(.009,.512),l(.522,.404),l(1.422,-.778),l(1.66,-.021),l(1.506,-.145),l(2.354,.014),l(1.919,.155),l(.854,.034),l(1.204,.033),l(-.271,.74),l(.354,.333),l(2.043,.154),l(.848,.121),l(.698,.069),l(1.035,.103),l(2.49,-.145),l(1.209,-.02),l(1.42,.348),l(1.405,-.932),l(-.161,-.352),l(-.038,-.229),l(-.034,-.105),l(1.806,-.48),l(.521,-.019),l(.802,.104),l(1.148,.298),l(.851,.281),l(1.711,.032),l(1.354,-.073),l(1.384,.033),l(1.323,.431),l(.409,.181),l(.058,.386),l(-.52,.088),l(-.268,.036),l(-1.905,.406),l(-2.438,.737),l(-.233,.227),l(.253,.069),l(1.033,.067),l(.957,.016),l(.659,.155),l(.659,.293),l(1.014,.396),l(.583,.172),l(.78,.481),l(1.27,.805),l(1.814,.801),l(1.351,.305),l(.612,-.018),l(.795,-.394),l(.843,-.72),l(1.093,-1.051),l(.601,-.329),l(.29,.017),l(.236,.465),l(.772,.308),l(1.346,.29),l(1.105,.135),l(.848,-.087),l(1.973,-.468),l(.778,-.07),l(.813,.067),l(1.196,.239),l(1.921,.734),l(.315,-.052),l(.186,-.069),l(.491,-.258),l(.221,-.258),l(-.137,-.051),l(.013,-.189),l(.726,-.312),l(.509,-.018),l(.5,.257),l(.575,.188),l(1.302,.032),l(.181,-.5),l(-.194,-.466),l(.15,-.363),l(.093,-.521),l(-1.131,.159),l(-.643,.001),l(-.179,-.104),l(.442,-.296),l(.318,-.087),l(.986,-.089),l(1.021,-.02),l(.832,-.141),l(1.566,-.648),l(.254,0),l(1.76,.241),l(1.561,.137),l(2.036,.188),l(.997,.068),l(.654,.103),l(2.307,.065),l(-1.732,.628),l(.865,.051),l(1.011,-.089),l(.335,.138),l(-.305,.381),l(-.926,.192),l(-.846,.261),l(-.177,.293),l(.664,.033),l(.52,-.122),l(.916,-.14),l(.978,-.33),l(1.62,-.799),l(2.766,.012),l(1.196,.067),l(.903,.172),l(.946,.137),l(.205,.19),l(.221,.104),l(-2.247,.59),l(.559,.137),l(1.674,.289),l(2.174,.202),l(.946,.204),l(.801,.375),l(.367,.427),l(.564,.357),l(.522,.152),l(1.459,-.037),l(1.364,-.105),l(1.138,-.139),l(2.518,-.329),l(2.208,-.107),l(3.008,.131),l(1.515,.134),l(.734,.118),l(1.168,.424),l(.655,.169),l(.525,.338),l(.361,.39),l(-.123,.491),l(-.286,.521),l(.509,.25),l(.764,.065),l(.835,.015),l(.643,.083),l(-.017,.685),l(.419,.416),l(.686,-.168),l(.545,-.435),l(1.211,-.387),l(.348,-.067),l(.35,.049),l(1.696,-.02),l(1.521,-.288),l(.736,.032),l(.588,.434),l(.707,.116),l(1.541,.014),l(2.176,.062),l(.869,-.118),l(1.378,-.504),l(.406,.2),l(.93,.533),l(.396,.216),l(1.095,.265),l(.875,.332),l(.282,.398),l(.612,.148),l(1.556,-.136),l(1.653,-.319),l(.16,-.25),l(-.248,-.333),l(-.805,-.833),l(-.833,-.115),l(.4,-.336),l(.479,-.571),l(1.89,.098),l(1.214,.082),l(1.135,.065),l(1.221,.166),l(.222,.318),l(1.396,-.153),l(2.084,-.054),l(2.304,.013),l(1.292,.148),l(.786,.199),l(1.185,.199),l(1.391,.098),l(.751,.182),l(1.302,.332),l(.747,.065),l(.703,.182),l(1.145,.505),l(0,2.126),l(0,2.222),l(0,2.222),l(0,1.292),l(0,.157),l(0,.576),l(0,.219),l(-1.083,.371),l(-.651,.03),l(-.645,.37),l(-.56,.065),l(-1.044,.065),l(-.355,-.079),l(-.928,-.052),l(-.118,-.343),l(-.271,-.211),l(-.501,.027),l(.241,-.185),l(-.938,.324),l(-.846,.02),l(-.337,-.211),l(-.478,-.079),l(.424,.501),l(-.569,.29),l(.32,.103),l(.942,.205),l(.634,-.36),l(.395,.041),l(.335,.079),l(0,.477),l(.248,.206),l(.76,.269),l(1.059,-.228),l(-.439,.322),l(.741,-.243),l(.065,.336),l(.247,.206),l(.187,.363),l(.068,.189),l(-.722,.522),l(.593,-.064),l(.349,.172),l(.473,.503),l(.501,.157),l(.145,.251),l(-.162,.456),l(.792,-.111),l(-.125,.393),l(.023,.25),l(-.43,.299),l(-.691,.205),l(-.635,-.046),l(-.448,-.14),l(-1.243,-.154),l(-.889,-.077),l(-.347,-.14),l(.123,-.267),l(-.493,-.046),l(-.304,.032),l(-.559,.55),l(-.069,.11),l(-3.06,.913),l(-1.155,.174),l(-.245,0),l(-.43,.203),l(-.219,.188),l(-.719,.22),l(-.991,.033),l(-.308,.11),l(-.48,.405),l(-.462,.203),l(-.946,.033),l(-.854,.622),l(-.24,.279),l(-1.67,.452),l(-.392,.449),l(-1.229,.25),l(-.406,.14),l(-.151,.293),l(.01,.292),l(-.473,.292),l(-.406,.016),l(-.586,-.306),l(-.183,-.262),l(-.169,-.37),l(-.67,-.308),l(-1.074,-.044),l(-1.021,.048),l(-1.159,.172),l(-1.301,.188),l(-.523,.217),l(-1.333,.756),l(-.536,.277),l(-.184,-.138),l(.575,-1.293),l(-.55,.094),l(-.392,-.097),l(-.811,.531),l(-.67,.186),l(-.401,.155),l(-.114,.506),l(-.66,.154),l(-.317,-.168),l(-.253,-.49),l(-.483,-.261),l(-1.024,.636),l(.261,-.204),l(-.557,.062),l(-.283,.092),l(-.628,.522),l(-.141,.261),l(.126,.229),l(.344,.152),l(-.932,.521),l(-.182,.199),l(.342,.167),l(-.647,.352),l(-.88,.55),l(-.626,.503),l(-.298,.35),l(-.01,.531),l(.421,.317),l(.477,.09),l(1.382,-.048),l(.562,.166),l(.11,.167),l(-.436,.394),l(-.752,.455),l(-.181,.302),l(.224,.512),l(.292,.452),l(.786,.089),l(.165,.391),l(-.014,.616),l(-.349,.361),l(-.528,.061),l(-.481,-.209),l(-.017,-.21),l(.388,-.527),l(-.444,-.014),l(-.454,.242),l(-1.014,.843),l(-.56,.675),l(-.237,.599),l(.321,.672),l(.647,.311),l(.154,.237),l(-.294,.387),l(-.688,.313),l(-.956,.031),l(-.664,-.088),l(-.344,.001),l(-.619,.179),l(-.837,.476),l(-.214,.149),l(-.525,.504),l(-.137,.341),l(.111,.281),l(.492,.398),l(.038,.221),l(-.056,.133),l(-.679,.238),l(-.604,.016),L(753.44,82.4),l(-.727,.296),l(-.065,.251),l(.067,.28),l(-.161,.854),l(-.293,.412),l(-.8,.78),l(-1.53,.971),l(-.854,.5),l(-.285,.103),l(-.295,-.614),l(-.198,-.821),l(-.25,-.69),l(-.064,-.794),l(-.351,-.75),l(-.305,-.383),l(-.214,-.915),l(-.514,-1.36),l(-.008,-.578),l(-.154,-.563),l(-.017,-.327),l(-.105,-.193),l(-.262,-.817),l(-.026,-.792),l(.116,-.808),l(.271,-1.396),l(.167,-.226),l(1.185,-.86),l(.716,-.424),l(.57,-.695),l(.14,-.227),l(-.085,-.318),l(-.139,-.166),l(1.632,-.367),l(1.001,-.305),l(.811,-.32),l(1.729,-.884),l(.641,-.412),l(.431,-.428),l(.14,-.335),l(1.784,-.889),l(.872,-.445),l(1.535,-.861),l(.368,-.293),l(.26,-.433),l(1.252,-.435),l(2.106,-.514),l(.257,-.434),l(.773,-.528),l(.086,-.233),l(-.568,-.216),l(.814,-.904),l(-.036,-.483),l(.183,-.391),l(.598,-.204),l(1.729,-.082),l(.513,-.063),l(-.485,-.328),l(-2.065,-.215),l(-.71,.095),l(-1.062,.174),l(-.777,.189),l(.042,.328),l(-.664,.923),l(.125,.202),l(-.04,.14),l(-.662,.11),l(-.479,.11),l(-1.555,.718),l(-1.979,1.042),l(-1.169,.342),l(-.249,-.062),l(.156,-.325),l(.352,-.465),l(-.933,-.076),l(-.16,-.263),l(.252,-.451),l(.442,-.467),l(.207,-.328),l(-.069,-.202),l(-.339,-.031),l(-1.136,.454),l(-.496,.032),l(-.277,-.358),l(-.589,-.17),l(-1.606,.144),l(-1.312,.111),l(-.956,.08),l(-.606,.157),l(-.894,.359),l(-.093,.436),l(.082,.186),l(-1.262,.53),l(-.408,.233),l(.149,.495),l(-1.294,.357),l(-1.019,.434),l(-.84,.479),l(-.496,.461),l(-.332,.46),l(.004,.383),l(.527,.213),l(1.269,.043),l(.278,.275),l(.062,.122),l(-1.152,.139),l(-1.028,.262),l(-1.045,-.059),l(-.698,-.136),l(-.382,.031),l(-.311,.107),l(-.721,.398),l(-.695,-.35),l(-1.112,.383),l(-.747,.139),l(-.487,-.09),l(-.284,-.137),l(.108,-.29),l(.748,-.124),l(.868,-.124),l(.164,-.046),l(-.741,-.64),L(736.444,68),l(-1.06,.017),l(-.854,.155),l(-.353,-.061),l(-.868,-.458),l(-.775,-.029),l(-.745,.047),l(-.704,.246),l(.042,.398),l(-.26,.229),l(-.477,.215),l(-.695,-.243),l(-.408,-.122),l(-1.26,.063),l(-.784,.093),l(-.651,-.075),l(-.887,-.136),l(-.563,.078),l(-.067,.122),l(-.147,.474),l(-.677,.017),l(-.311,-.137),l(-.038,-.382),l(-.203,-.259),l(-1.241,.094),l(-1.014,-.059),l(-1.257,.033),l(-1.158,.063),l(-.836,-.029),l(-.18,.016),l(-1.085,.292),l(-.964,.444),l(-.74,.474),l(-.536,.504),l(-.789,.245),l(-.904,.336),l(-.194,.152),l(-1.047,1.17),l(-1.634,.684),l(-.949,.471),l(-1.157,.711),l(-1.653,1.253),l(-.828,.572),l(-1.573,.873),l(-.893,.376),l(-1.889,.871),l(-.632,.388),l(-.203,.298),l(.018,.357),l(.428,.281),l(.485,.043),l(.918,.013),l(1.046,-.15),l(.656,.043),l(-.329,1.261),l(.016,.415),l(.303,.103),l(.63,-.09),l(.601,-.371),l(.761,.117),l(-.127,.148),L(705.293,81),l(-.112,.222),l(.373,.073),l(1.645,-.018),l(.566,-.238),l(.39,-.519),l(.017,-.638),l(.763,.014),l(.647,-.001),l(.726,.014),l(.951,.265),l(.658,.354),l(.486,.591),l(.847,.575),l(.426,.176),l(.506,.324),l(-.07,.148),l(-.581,.355),l(.453,.221),l(.13,.309),l(-.336,.723),l(.491,.117),l(.215,.235),l(-.291,.515),l(-.348,.397),l(-.532,.559),l(-.724,1.364),l(-.181,.688),l(.057,.219),l(.24,.701),l(-.188,.917),l(-.098,.741),l(-.403,1.408),l(-.146,.493),l(-1.928,1.538),l(-.371,.435),l(-.217,.65),l(-.587,.42),l(-.741,.579),l(-.241,.361),l(-.574,.981),l(-.587,.606),l(-.941,.778),l(-1.784,1.512),l(-.464,.474),l(-.235,.458),l(-.323,.33),l(-.758,.388),l(-.618,.416),l(-.574,.702),l(-.431,.458),l(-.875,.673),l(-.955,.487),l(-1.838,.475),l(-.798,.244),l(-.278,-.427),l(-.519,-.085),l(-.243,.043),l(-.337,-.185),l(-.337,-.513),l(-.663,.272),l(-.464,.101),l(.424,-.586),l(-.624,.173),l(-.506,.486),l(-.649,.543),l(-1.326,1.001),l(-.072,.049),l(-.167,-.393),l(-.298,-.439),l(.111,-.058),l(1.252,-.462),l(.511,-.43),l(.156,-.329),l(-.112,-.299),l(.097,-.128),l(.025,-.385),l(.006,-.613),l(-.062,-.656),l(-.332,-.897),l(.048,-.557),l(1.664,-.982),l(.396,.041),l(.685,.24),l(.679,.225),l(.547,.098),l(.47,-.347),l(.551,-.69),l(.329,-.432),l(.627,-1.08),l(.538,-1.066),l(.278,-.893),l(.291,-.707),l(.66,-.393),l(.566,-.407),l(-.017,-.504),l(-.116,-.389),l(-.064,-.259),l(-.246,-.114),l(-.902,.034),l(-1.181,.208),l(-1.357,.31),l(-.953,.308),l(-.604,.22),l(-1.657,.052),l(-.649,.018),l(-.68,.033),l(-.261,-.446),l(-.44,-1.283),l(-.297,-.866),l(-.205,-.144),l(-2.659,-.839),l(-1.523,-.253),l(-1.247,-.341),l(-.507,-.2),l(-.436,-.389),l(-.927,-1.903),l(-.94,-1.588),l(-1.087,-2.384),l(-.742,-.952),l(-.763,-.467),l(-.539,-.026),l(-1.386,.125),l(-.683,-.188),l(-1.037,-.481),l(-1.148,-.215),l(-.917,.049),l(-1.203,.109),l(-.836,.123),l(-1.854,.143),l(-.602,.136),l(-.478,.165),l(-1.193,.787),l(-.375,.282),l(-.119,.25),l(.822,-.078),l(.558,.026),l(.465,.306),l(.107,.249),l(-.167,.794),l(-1.371,.608),l(-.599,.545),l(-.667,.779),l(-.416,.543),l(-.422,.426),l(-.103,.249),l(.062,.146),l(.35,.348),l(.056,.306),l(-.123,.233),l(-.779,.339),l(-2.44,.752),l(-.438,.089),l(-.343,.016),l(-1.126,-.574),l(-.452,-.172),l(-.046,-.018),l(-.431,-.168),l(-.622,.018),l(-1.228,.297),l(-.86,-.169),l(-.34,-.129),l(-.751,-.506),l(-.74,-.156),l(-.609,.047),l(-.333,.002),l(-1.165,.487),l(-.755,.498),l(-.447,.394),l(-.604,.264),l(-.526,.163),l(-1.147,.136),l(-.867,.106),l(-.532,.075),l(-1.018,.063),l(-1.602,.11),l(-.739,-.039),l(-.984,-.082),l(-.905,-.241),l(-1.318,-.254),l(-.812,-.373),l(-1.132,-.313),l(-.623,-.331),l(-1.333,-.75),l(-.769,-.229),l(-1.423,-.022),l(-1.172,-.037),l(-.796,.077),l(-2.48,.538),l(-.673,-.113),l(-1.643,-.531),l(-.421,-.333),l(-.408,-.451),l(-.182,-.481),l(-.004,-.541),l(-.145,-.204),l(-.767,-.143),l(-.989,-.317),l(-.702,-.231),l(-1.748,-.328),l(-1.036,-.185),l(-1.028,-.098),l(-.84,-.201),l(-1.269,.96),l(-.905,.839),l(-.098,.293),l(.409,.86),l(.396,.304),l(.116,.204),l(-.163,.526),l(-.744,.572),l(-.31,.162),l(-.755,.28),l(-.562,.018),l(-.576,-.186),l(-.312,-.114),l(-.875,-.068),l(-.85,.004),l(-.719,-.083),l(-1.458,.008),l(-.699,-.113),l(-.393,-.406),l(-.694,-.755),l(-.831,-.083),l(-1.842,-.122),l(-.932,-.156),l(-.953,-.097),l(-.84,.18),l(-1.512,.476),l(-1.143,.341),l(-.787,.398),l(-.971,.692),l(-.017,.012),l(-.727,.381),l(-.603,.148),l(-1.387,.08),l(-.599,.207),l(-.799,.425),l(-.154,.044),l(-.244,.074),l(-.569,.003),l(-.228,.014),l(-.064,-.145),l(-.589,0),l(-.294,-.478),l(-.441,-.331),l(.073,-.331),l(-.625,.184),l(-.478,.368),l(-.993,-.074),l(-.882,-.073),l(-.662,-.699),l(-.588,-.552),l(-.956,-.147),l(-.331,-.625),l(-.772,-.588),l(-.698,-.441),l(-.993,.037),l(-.771,.221),l(-.993,.221),l(-.992,0),l(-.589,0),l(-.184,-.184),l(-.258,-.257),l(-.478,0),l(0,-.368),l(-.367,-.331),l(-.92,0),l(-.367,.515),l(-.331,.257),l(-.515,.257),l(-1.104,-1.434),l(-.846,-.882),l(-1.69,-2.133),l(-1.066,-1.029),l(-1.287,-.772),l(-.809,-.294),l(-1.104,-.588),l(.11,-.368),l(.515,-.11),l(0,-.441),l(-.809,.074),l(-.515,.22),l(-.772,.221),l(-.956,.515),l(-1.103,.257),l(-.772,.441),l(-.294,.294),l(-.552,-.184),l(-.441,-.037),l(-.771,.073),l(-.441,.11),l(-.331,-.184),l(.331,-.441),l(.441,-.184),l(.146,-.294),l(-.367,0),l(-.441,.221),l(-.478,-.11),l(-.405,-.294),l(-.478,-.037),l(-.184,.147),l(-.147,.147),l(-.367,-.221),l(-.295,-.368),l(-.294,-.11),l(-.331,.221),l(-.367,-.074),l(-.368,.147),l(-.44,-.11),l(-.295,.147),l(-.478,-.074),l(-.184,-.257),l(.33,-.037),l(-.073,-.331),l(.147,-.257),l(.11,-.331),l(-.515,-.22),l(-.147,-.221),l(.037,-.331),l(-.368,-.404),l(-.882,.037),l(-.625,.11),l(-.772,-.257),l(-.515,-.11),l(-.919,-.147),l(-.735,.037),l(-.11,.221),l(-.589,.184),l(-.515,.037),l(0,.294),l(-.367,.368),l(-.625,.074),l(-1.876,.073),l(-2.021,.405),l(-1.177,.037),l(-.625,.331),l(-.221,.331),l(-.331,-.073),l(-.588,.073),l(-1.545,.11),l(-.735,.11),l(-1.029,.037),l(-1.396,.405),l(-.368,.184),l(-.772,0),l(-.515,0),L(537.304,80),l(-.33,.074),l(-.185,.515),l(.074,.441),l(.294,.221),l(-.294,.074),l(0,.331),l(1.065,.11),l(.956,.294),l(-.11,.257),l(-.515,.073),l(-1.103,-.147),l(-.698,.184),l(-.662,.515),l(.146,.257),l(.441,.478),l(-.331,.294),l(-.588,.147),l(-.735,.368),l(-.467,.067),l(.164,.274),l(.239,0),l(.377,.137),l(-.068,.171),l(.377,.137),l(.651,.069),l(.274,.308),l(1.165,.171),l(.24,.24),l(-.138,.686),l(-.137,.309),l(-1.577,.411),l(-.959,-.034),l(-.343,-.343),l(-.24,0),l(-.171,.309),l(-.651,.343),l(-.411,-.171),l(-.754,-.137),l(-.926,-.309),l(-.274,-.548),l(-.754,-.103),l(-1.062,.103),l(-.137,.412),l(-.617,.068),l(-.651,-.411),l(-.65,-.035),l(-.823,-.068),l(-.514,.377),l(-.377,.343),l(-.274,.274),l(-.686,.171),l(-.411,-.24),l(-.686,-.137),l(-.582,-.548),l(-.72,-.068),l(.034,.24),l(.205,.48),l(-.239,.274),l(-.274,-.137),l(-.068,-.583),l(-.411,-.274),l(-.789,-.343),l(-.582,-.206),l(0,-.343),l(-.96,-.171),l(-.617,.069),l(-.788,-.035),l(-.411,-.514),l(-.411,-.069),l(-.617,.24),l(-.273,.137),l(-.651,.137),l(-.309,-.274),l(-.479,0),l(-.651,-.069),l(-.515,.309),l(-.548,.343),l(-.788,.377),l(-.549,.068),l(-.514,.171),l(-.309,.309),l(-.172,.24),L(509.58,87.5),l(-.479,.206),l(.068,.445),l(.171,.411),l(-.068,.446),l(-.411,.24),l(-.651,0),l(-.514,-.411),l(-.48,-.548),l(-.514,-.24),l(-.411,.069),l(-.103,.308),l(-.343,.549),l(-.823,.137),l(-.205,1.303),l(.343,.171),l(.239,.274),l(-.239,.206),l(-.446,.274),l(-.65,1.165),l(1.37,.343),l(.138,.377),l(-.068,.309),l(.514,.514),l(.103,-.343),l(.583,.206),l(.343,-.034),l(.514,.034),l(.515,.445),l(.479,.206),l(.343,.514),l(.96,1.131),l(-.138,.103),l(-.445,-.103),l(-.309,-.103),l(-.343,.103),l(.068,.308),l(.857,.377),l(.616,.19),l(-.167,.2),l(-.399,.28),l(-.38,.12),l(-.12,0),l(0,.14),l(0,.22),l(-.14,.08),l(-.3,-.2),l(-.34,.2),l(-.399,.26),l(-.64,.12),l(-.319,.08),l(-.26,-.08),l(-.181,-.08),l(-.1,.04),l(-.06,.16),l(.12,.26),l(-.221,.2),l(-.18,.3),l(-.18,.319),l(-.319,.42),l(-.18,.28),l(-.32,.16),l(-.34,.24),l(-.14,.32),l(.08,.2),l(.34,.2),l(.319,.04),l(.18,.3),l(.24,.04),l(.239,.34),l(.28,.419),l(-.06,.38),l(-.101,.2),l(.061,.16),l(.1,-.2),l(.1,-.34),l(.12,-.22),l(.16,-.02),l(-.141,.439),l(-.22,.36),l(.061,.4),l(.12,.1),l(-.16,.2),l(-.04,.4),l(.38,.24),l(.119,.1),l(.12,.52),l(.28,.06),l(.359,.42),l(.2,.28),l(.439,.419),l(.18,.36),l(.359,.06),l(.047,.146),l(-.292,.449),l(-.496,.284),l(-.283,.094),l(-.308,.331),l(-.165,.213),l(-.379,.047),l(-.449,-.142),l(-.591,-.094),l(0,-.308),l(-.283,-.284),l(-.118,0),l(-.095,-.118),l(-.473,-.284),l(-.142,-.189),H(504.5,0),l(-.213,.047),L(504.264,107),l(-.229,.023),l(-.126,-.189),l(-.236,-.071),l(-.236,.023),l(-.284,-.047),l(-.26,-.094),l(-.284,-.166),l(-.354,-.284),l(.118,-.307),l(.118,-.189),l(-.118,-.142),l(-.354,-.024),l(-.378,0),l(-.213,-.166),l(-.189,-.118),l(-.212,0),l(-.143,-.094),l(-.236,-.118),l(-.118,0),l(-.095,.071),l(-.142,.166),l(-.188,-.142),l(-.261,-.071),l(-.354,0),l(-.213,.071),l(-.094,.095),l(-.166,.166),l(-.283,0),l(-.261,.118),l(-.212,-.071),l(-.261,-.118),l(.048,-.118),l(.142,-.118),l(-.308,-.119),l(-.236,-.118),l(-.354,-.071),l(-.52,-.118),l(-.284,-.213),l(-.095,-.142),l(-.354,-.166),l(-.283,.047),l(-.189,0),l(-.401,-.166),l(-.544,0),l(-.426,.095),l(-.307,0),l(-.355,-.047),l(-.307,-.071),l(-.261,-.095),l(-.212,-.166),l(-.213,0),l(-.331,0),l(-.189,-.047),l(-.188,-.094),l(-.284,-.142),l(-.283,-.095),l(-.449,-.023),l(-.402,-.023),l(-.07,-.047),l(-.284,-.047),l(-.26,.166),l(-.112,.309),l(-1.421,-1.012),l(-1.188,-.842),l(-.817,-.385),l(-.62,-.084),l(-.373,-.157),l(-.509,-.5),l(-.236,-.057),l(-.338,.159),l(-.329,-.042),l(-.347,-.515),l(-.795,-.674),l(.595,-.188),l(.519,-.001),l(.445,-.073),l(.1,-.519),l(.359,-.476),L(485,97.85),l(.526,-.03),l(.516,-.131),l(-.432,-.532),l(-.654,-.273),l(-.474,-.36),l(.243,-.116),l(.367,-.03),l(.82,-.117),l(.715,-.348),l(1.244,-.436),l(-.196,-.375),l(-.076,-.058),l(-.799,.088),l(-1.312,.175),l(.012,-.126),l(.021,-.112),l(0,-.224),l(.09,-.514),l(.224,-.089),l(.357,-.022),l(.38,-.134),l(.223,-.179),l(.022,-.179),l(.269,0),l(.736,-.045),l(.805,.157),l(.335,-.134),l(0,-.156),l(.156,-.291),l(.156,-.491),l(-.066,-.067),l(-.09,-.201),l(-.045,-.179),l(-.044,-.134),l(-.179,-.067),l(-.156,-.067),l(.044,-.224),l(.045,-.179),l(.246,0),l(.312,0),l(.134,-.156),l(-.29,-.044),l(-.269,-.089),l(-.223,-.246),l(.312,-.044),l(.357,-.201),l(.156,-.067),l(.201,-.089),l(.045,-.224),l(-.09,-.179),l(-.111,-.089),l(.022,-.179),l(.089,-.111),l(-.156,-.089),l(-.201,.089),l(-.134,.044),l(-.269,0),l(-.357,-.156),l(-.111,-.224),l(-.469,-.022),l(-.291,-.089),l(-.201,-.179),l(-.357,.067),l(-.268,-.112),l(-.469,-.112),l(-.425,-.067),l(-.29,-.268),l(-.224,.067),l(-.045,.157),l(-.29,.134),l(-.224,-.112),l(-.179,-.179),l(-.402,-.044),l(-.022,-.134),l(-.201,-.179),l(0,-.134),l(-.268,-.179),l(-.111,-.156),l(-.357,.067),l(-.536,.134),l(-.269,0),l(-.312,.112),l(-.425,.112),l(-.179,-.156),l(-.179,-.022),l(-.201,.067),l(-.469,-.291),l(-.268,-.067),l(-.47,.067),l(-.268,.179),l(-.291,-.29),l(-.179,-.089),l(-.089,-.224),l(.089,-.179),l(-.089,-.246),l(-.224,-.268),l(0,-.357),l(-.402,0),l(0,-.312),l(-.38,-.022),l(-.514,.067),l(-.156,-.112),l(-.647,0),l(-.269,-.29),l(-.111,-.357),l(-.134,-.291),l(.312,-.134),l(.312,.022),l(0,-.268),l(-.312,-.156),l(-.246,-.156),l(-.134,-.201),l(-.246,-.335),l(-.312,-.134),l(-.201,-.268),l(-.514,.134),l(-.692,-.112),l(-.67,.223),l(-.536,.022),l(-.536,-.246),l(-.134,.268),l(-.179,.291),l(-.313,.156),l(-.469,-.022),l(-.357,-.089),M(527.156,37.071),l(-.59,-.14),l(-.955,-.21),l(-1.128,-.139),l(-.739,.054),l(-.959,.037),l(-.732,.143),l(-.411,-.105),l(-1.025,-.476),l(.737,-.303),l(1.21,-.429),l(.654,-.09),l(1.549,-.002),l(.135,-.357),l(-.728,-.338),l(.351,-.269),l(.419,-.144),l(.676,-.02),l(.852,-.181),l(-.25,-.161),l(-.526,-.233),l(1.539,-.895),l(.513,-.129),l(.226,.073),l(.892,.017),l(.981,-.535),l(.863,-.333),l(1.02,-.261),l(.975,-.15),l(1.305,-.113),l(1.274,.053),l(.738,-.15),l(.786,-.615),l(.273,.018),l(.873,-.132),l(1.722,.276),l(.471,-.038),l(1.93,-.321),l(.958,-.039),l(2.184,-.247),l(1.864,-.116),l(.771,-.564),l(.376,-.152),l(2.511,-.137),l(1.965,-.079),l(.471,.131),l(.442,.225),l(.154,.357),l(-.812,.47),l(-.541,.169),l(-1.346,.319),l(-2.609,.433),l(-4.329,.49),l(-2.187,.281),l(-2.122,.299),l(-1.842,.316),l(-2.102,.242),l(-.941,.203),l(-.288,.274),l(.644,.216),l(-.422,.217),l(-.943,.361),l(-.527,.037),l(-2.047,-.068),l(-.432,.18),l(-.119,.233),l(.621,.249),l(-.331,.233),l(-1.206,.448),l(-.402,-.142),l(-.752,-.087),l(-.592,.304),l(.877,.283),l(.052,.319),l(-1.094,.657),l(-.822,.284),M(517.491,38.443),l(1.041,-.37),l(.512,-.299),l(.428,-.212),l(1.426,-.021),l(1.316,-.249),l(.987,-.02),l(1.412,-.091),l(.551,.069),l(.988,.227),l(-.063,.176),l(-.463,.528),l(-.302,.158),l(-.697,.071),l(-.443,.228),l(-.233,.385),l(.006,.818),l(.445,1.039),l(.957,.826),l(.505,.308),l(.775,.307),l(1.162,.392),l(-.028,.282),l(-2.62,-.089),l(-.844,.053),l(-.917,.326),l(-.596,.086),l(-.676,-.494),l(-.382,-.034),l(-1.091,.088),l(-.673,-.102),l(-.031,-.359),l(1.347,-.362),l(.073,-.24),l(-.102,-.017),l(-.944,-.273),l(-1.442,-.411),l(-1.519,-.17),l(-.33,.156),l(-.624,.122),l(-.681,-.033),l(-.625,-.396),l(-.114,-.415),l(.229,-.312),l(.39,-.209),l(.344,-.036),l(.318,.104),l(.65,.016),l(.518,-.192),l(1.121,-.768),l(.243,-.35),l(-.322,0),l(-.981,-.243),M(.125,56.089),l(0,-.562),l(0,-.576),l(0,-.157),l(0,-1.292),V(0,51.28),l(0,-2.222),l(0,-2.12),l(2.917,.61),l(1.693,.598),l(.933,.181),l(3.819,.99),l(1.059,.395),l(.204,.149),l(.074,.214),l(.445,.429),l(.406,.789),l(-.209,.428),l(1.034,.8),l(.982,.26),l(-.02,-.18),l(.297,-.148),l(-.051,-.196),l(-.638,-.392),l(.016,-.542),l(.077,-.296),l(1.026,-.183),l(.984,.278),l(.573,.098),l(.767,.064),l(1.003,-.117),l(.933,.13),l(.93,.425),l(.694,.359),l(1.676,.684),l(.32,.081),l(.584,.179),l(.43,.211),l(.09,.13),l(-.343,.033),l(-1.026,-.096),l(-.364,.034),l(-.808,.798),l(-1.539,-.468),l(.138,.178),l(.438,.227),l(.465,.324),l(-1.177,-.111),l(-1.008,.05),l(-1.202,-.387),l(-.708,-.096),l(.135,.129),l(.289,.259),l(.084,0),l(.561,.259),l(.205,.307),l(.131,.453),l(-.056,.339),l(-.814,.05),l(-.805,.065),l(-.189,.161),l(.5,.865),l(-.115,.272),l(-1.04,-.078),l(-.397,.081),l(-1.193,-.174),l(-.264,-.352),l(-1.795,-.51),l(-.253,.273),L(9.85,55.79),l(-.276,-.161),l(-.265,-.403),l(.174,-.178),l(-.321,-.42),l(-.87,-.339),l(-.565,-.063),l(-.762,.034),l(-.858,.229),l(-1.343,.084),L(3.57,54.443),l(.059,-.325),l(-.155,-.325),l(-.618,-.487),L(1.958,53.43),l(-.45,.409),l(-.655,1.228),l(-.166,.715),l(-.562,.307),
+N(449.401,22.792),l(-1.596,-.014),l(-2.019,-.016),l(-1.739,.063),l(-.764,.061),l(-1.972,-.316),l(.812,-.456),l(.826,-.172),l(.735,-.453),l(1.148,-.588),l(1.354,.691),l(.998,.105),l(1.116,-.088),l(.9,.084),l(.704,.341),l(.865,-.323),l(.53,-.454),l(.868,-.306),l(-.311,.823),l(.086,.32),l(.851,-.001),l(.991,-.495),l(1.061,-.261),l(.803,.128),l(.559,.472),l(.705,.041),l(2.007,-.111),l(1.543,.189),l(.551,.376),l(-.507,.201),l(-2.004,.622),l(-1.623,.38),l(-1.069,.062),l(-.976,.14),l(-1.324,.366),l(-6.271,-.097),l(-.033,-.377),l(1.492,-.26),l(.702,-.677),M(430.027,22.752),l(.068,.697),l(.252,.119),l(1.694,.155),l(.221,-.377),l(.13,-.418),l(.573,-.141),l(.523,-.041),l(.949,.477),l(1.192,.771),l(.798,.235),l(.568,-.218),l(-.222,-.296),l(-.46,-.356),l(-.327,-.477),l(-.04,-.22),l(.91,-.407),l(1.001,.103),l(.485,.18),l(1.278,.018),l(.586,.179),l(-.08,.419),l(-.169,.298),l(.104,.159),l(.549,.118),l(.743,-.338),l(.44,-.1),l(.662,.396),l(.678,.335),l(.785,.156),l(.948,.117),l(1.672,.429),l(.498,.234),l(-1.305,.277),l(-1.981,.218),l(-.696,.293),l(-.731,1.144),l(-.885,.885),l(-1.243,.117),l(-.766,.535),l(-.455,.589),l(-.029,.378),l(-.786,.209),l(-.556,-.018),l(-1.593,-.355),l(-1.883,-.507),l(-1.365,-.568),l(.651,-.364),l(1.565,-.041),l(1.788,-.137),l(.944,-.386),l(-.652,-.249),l(-1.822,.139),l(-1.566,.118),l(-1.694,.042),l(-.502,-.519),l(.959,-.06),l(1.371,-.215),l(2.149,-.314),l(1.547,-.45),l(-2.525,-.405),l(-.881,-.292),l(-.589,.138),l(-1.036,.646),l(-1.069,.293),l(-.562,.059),l(-1.236,-.172),l(-.338,-.174),l(-1.05,-.368),l(-.807,-.233),l(-.698,-.41),l(1.698,-.396),l(-.817,-.571),l(-1.359,.319),l(-.467,-.078),l(-.924,-.751),l(.812,-.36),l(.516,-.021),l(1.075,-.122),l(1.017,.038),l(.577,-.061),l(1.188,-.042),M(425.42,68.82),l(-.148,-.21),l(-.629,.132),l(-.134,-.026),l(-.249,-.237),l(-.239,-.343),l(.188,-.158),l(-.143,-.291),l(-.361,.185),l(-.062,.29),l(.113,.237),l(-.147,.105),l(-.339,.316),l(-.086,.185),l(-.521,.105),l(-.533,-.131),l(-.781,.342),l(.057,.131),l(-.502,.289),l(-.498,.263),l(-1.658,.813),L(418.697,71),l(-.274,.052),l(-.271,0),l(-2.111,.209),l(-.188,-.236),l(-.33,-.131),l(-.183,.209),L(414.976,71),l(.384,-.184),l(-.935,-.236),l(-.794,-.341),l(-.574,-.052),l(-.479,-.578),l(.292,-.368),l(-.126,-.21),l(.34,.026),l(.085,.316),l(.284,-.21),l(.667,.263),l(-.244,-.197),l(.127,-.145),l(.5,-.092),l(-.479,.026),l(-.245,.105),l(-.263,-.184),l(-.111,-.132),l(.579,-.276),l(.455,-.185),l(-.482,.066),l(-.317,-.132),l(.441,-.237),l(.083,-.237),l(-.661,.475),l(-.036,-.264),l(-.265,-.171),l(.005,.211),l(.076,.171),l(-.419,.158),l(-.41,0),l(.014,-.277),l(-.15,.264),l(-.235,-.079),l(-.2,-.448),l(.658,-.449),l(.08,.436),l(.068,-.317),l(.438,.158),l(.211,-.092),l(-.166,-.106),l(.674,-.079),l(.479,-.251),l(-.611,.159),l(-.48,0),l(-.335,-.159),l(.196,-.132),l(.387,-.146),l(.196,-.471),l(-.821,-.014),l(-.546,.094),l(-.406,-.309),l(.368,-.14),l(.643,-.404),l(-.212,-.186),l(-.445,.063),l(-.399,-.062),l(-.211,-.217),l(.284,-.482),l(.619,-.265),l(-.595,-.248),l(-.225,-.374),l(.272,-.188),l(-.089,-.687),l(.106,-.094),l(.594,-.063),l(.392,-.045),l(.455,.044),l(.082,-.11),l(-.255,-.134),l(-.425,-.118),l(-.228,-.17),l(.098,-.188),l(.211,-.125),l(.575,-.064),l(.511,-.346),l(.567,.109),l(.498,-.111),l(.179,-.55),l(.835,.093),l(.668,.125),l(.571,-.252),l(-.989,-.234),l(-.266,-.314),l(.236,-.143),l(1.151,.014),l(.851,-.08),l(.538,.219),l(.06,-.473),l(.477,-.27),l(.297,-.333),l(.78,-.175),l(.438,.189),l(.138,.079),l(.5,-.476),l(.869,-.413),l(.084,-.429),l(.437,-.398),l(1.497,-.735),l(.335,-.192),l(.235,-.048),l(.481,.175),l(.335,-.001),l(.319,-.224),l(-.225,-.223),l(.141,-.128),l(.488,-.224),l(.457,-.305),l(.481,-.483),l(.245,.064),l(.676,-.017),l(-.067,-.612),l(-.471,-.112),l(.434,-.405),l(.511,-.648),l(.841,.063),l(.047,-.341),l(.096,-.228),l(.954,-.116),l(-.396,-.357),l(-.327,-.097),l(-.193,-.146),l(.164,-.245),l(.313,-.246),l(.464,.048),l(.888,-.067),l(-.543,-.522),l(.249,-.082),l(.435,-.034),l(.707,-.263),l(.592,-.067),l(.308,-.208),l(-.358,-.064),l(-.105,-.187),l(.289,-.1),l(.616,-.33),l(.557,.032),l(.351,.098),l(.434,-.264),l(.369,-.031),l(.035,-.176),l(-.421,-.321),l(.627,-.232),l(.146,-.275),l(.336,.01),l(.359,.297),l(.397,.082),l(.526,-.381),l(-.281,-.656),l(.438,.065),l(.698,-.058),l(.207,-.174),l(-.604,-.315),l(.411,-.224),l(.816,-.251),l(.093,-.257),l(.261,-.194),l(.73,-.135),l(.074,.067),l(.274,-.051),l(.102,-.067),l(.492,-.67),l(.521,.25),l(.96,-.153),l(.411,.133),l(.265,.1),l(.646,.065),l(.536,-.419),l(.747,-.84),l(.286,-.085),l(.16,.168),l(-.178,.286),l(-.182,.587),l(.791,-.454),l(.403,-.572),l(.819,-.085),l(.688,-.439),l(.437,.117),l(.665,.353),l(.567,-.643),l(.318,-.272),l(.976,.1),l(1.019,.506),l(.197,-.152),l(.479,-.595),l(.709,-.444),l(.283,-.052),l(.562,.067),l(.338,-.308),l(.469,-.291),l(.619,-.189),l(1.2,-.173),l(.984,.015),l(-1.337,.755),l(-.24,.273),l(-.107,.646),l(.42,.084),l(.691,-.579),l(1.53,-.941),l(.764,-.275),l(.028,.257),l(-.004,.905),l(.704,-.172),l(.438,-.239),l(.855,-.874),l(.959,-.104),l(.586,-.001),l(.216,.154),l(-.383,.257),l(-.335,.257),l(.074,.239),l(-.319,.41),l(.921,.118),l(.221,-.443),l(.902,-.651),l(.421,.017),l(1.682,.561),l(.667,.135),l(.935,.015),l(.649,.237),l(.1,.272),l(-1.216,.393),l(-1.148,.036),l(-2.233,-.047),l(.193,.084),l(.585,.304),l(1.058,.284),l(.383,.302),l(.728,-.052),l(.679,-.102),l(.831,.032),l(.708,.25),l(-.404,.288),l(-.514,.204),l(-.824,.021),l(-.77,.121),l(-1.023,.49),l(-1.013,.672),l(-.689,.303),l(-.001,-.2),l(.096,-.367),l(.874,-.923),l(-.044,-.268),l(-.88,-.348),l(-.672,-.114),l(-1.125,-.431),l(-.556,.003),l(-.555,.07),l(-2.004,.095),l(-.865,.374),l(-.567,.422),l(-.26,.437),l(-.079,.501),l(-.188,.5),l(-1.25,.472),l(-.582,.368),l(-.31,-.148),l(-1.288,-.492),l(-1.657,.225),l(-1.411,-.042),l(-.536,-.13),l(-.861,-.595),l(-.994,-.612),l(-.486,-.082),l(-.355,.103),l(-1.012,.656),l(-.114,-.063),l(-.41,-.031),l(-.865,.038),l(-.281,1.066),l(-.164,.449),l(-.271,.25),l(-.323,-.015),l(-.67,-.129),l(-.972,-.144),l(-1.731,-.389),l(-.168,.183),l(-.021,.663),l(-.083,.199),l(-.318,.299),l(-.695,.004),l(-.871,-.095),l(-.279,-.015),l(-.465,.167),l(-1.484,1.176),l(.05,.213),l(.171,.507),l(-.188,.345),l(-.615,.346),l(-1.325,.919),l(-.687,.442),l(-.981,.021),l(-.121,.244),l(-.06,.971),l(-.32,.598),l(-.383,.469),l(-.574,.499),l(-.495,.545),l(.339,.125),l(.381,.269),l(.252,.587),l(-.17,.176),l(-.44,.177),l(-.733,.036),l(-.932,-.027),l(-.618,.114),l(-.613,.257),l(-.617,.479),l(-.389,.492),l(-.077,.664),l(-.349,1.093),l(.65,.729),l(-.335,1.171),l(.582,.39),l(.715,.186),l(.297,.243),l(-.432,.67),l(-.941,.16),l(.571,.735),l(.26,.427),l(-.249,.346),l(-.029,.532),l(-.769,.384),l(-.414,.013),l(-.117,.423),l(-.506,.224),l(.22,.831),l(-.324,.737),l(-.41,.013),l(-.15,-.342),l(-.293,-.132),
+N(464.349,47.431),l(-.024,.283),l(-.258,.465),l(.116,.529),l(.563,.212),l(.872,.194),l(.964,.506),l(.543,.392),l(-.421,.364),l(-1.303,.777),l(-.328,.296),l(1.402,1.394),l(.772,1.195),l(-.196,.356),l(-.44,.535),l(-.187,.403),l(-.029,.37),l(.37,.509),l(1.286,1.395),l(.151,.253),l(-.057,.254),l(-.542,.415),l(-.327,.191),l(.439,.33),l(1.357,.499),l(.703,.265),l(.436,.392),l(.161,.346),l(-.105,.409),l(-.43,.536),l(-.591,.536),l(-1.385,.758),l(-1.983,1.195),l(-1.946,1.145),l(-.174,.285),l(-.935,.206),l(-1.195,.188),l(-.149,.181),l(-.506,-.217),l(-.518,.146),l(-.052,.134),l(-.688,-.07),l(-.193,-.108),l(.057,-.387),l(-.241,.527),l(-.268,.14),l(-.633,.047),l(-.328,.03),l(-.1,.267),l(-.589,-.326),l(-.29,.275),l(-.676,.064),l(-.34,.178),l(-.052,-.127),l(-.504,.108),l(-.504,.108),l(-.211,.266),l(-.311,-.152),l(-.672,.126),l(-.04,-.114),l(-.658,.215),l(-.547,.013),l(-.482,.025),l(-.487,-.253),l(-.223,-.274),l(.273,-.34),l(-.846,.017),l(-.517,.177),l(.065,-.382),l(-.446,.076),l(-.644,-.271),l(-.409,-.061),l(-.415,-.231),l(-.26,-.403),l(-.036,-.714),l(.158,-.374),l(.05,-.436),l(.09,-.234),l(-.347,-.483),l(-.431,-.375),l(.3,-.658),l(-.02,-.392),l(-.305,-.204),l(-.37,-.093),l(.062,-.299),l(.295,-.331),l(.637,-.285),l(.144,-.189),l(-.113,-.331),l(.382,-.143),l(.633,.125),l(.274,.063),l(.483,-.222),l(.303,-.427),l(.104,-.459),l(.207,-.27),l(.301,.316),l(.27,0),l(1.678,-1.114),l(1.142,-.654),l(.835,-.576),l(1.026,-.401),l(.874,.03),l(.06,-.304),l(-.13,-.144),l(-.357,-.16),l(.119,-.371),l(.146,-.387),l(-.329,-.274),l(-1.139,-.095),l(-.836,-.451),l(-.594,-.024),l(-.113,-.234),l(-.327,-.307),l(-.208,-.535),l(.5,-.8),l(-.028,-.392),l(-.405,-.685),l(-.507,-.637),l(.004,-.526),l(.062,-.413),l(-.77,-.558),l(-.508,-.229),l(-1.583,-.207),l(-1.085,-.292),l(-1.286,-.658),l(-.616,-.463),l(-.146,-.033),l(1.012,-.656),l(.355,-.103),l(.486,.082),l(.994,.612),l(.861,.595),l(.536,.13),l(1.411,.042),l(1.657,-.225),l(1.288,.492),l(.31,.148),l(.582,-.368),l(1.25,-.472),l(.188,-.5),l(.079,-.501),l(.26,-.437),l(.567,-.422),l(.865,-.374),l(2.004,-.095),l(.555,-.07),l(.556,-.003),l(1.125,.431),l(.672,.114),l(.88,.348),l(.044,.268),l(-.874,.923),l(-.096,.367),l(.001,.2),
+N(453.795,53.873),l(-.23,-.004),l(-.975,.164),l(-.447,.098),l(-.902,-.387),l(-.339,-.178),l(-.347,.114),l(-.641,.374),l(-.542,.599),l(-.309,.146),l(-.658,.018),l(-.545,.355),l(.325,.241),l(.146,.192),l(-.355,.273),l(-.907,.401),l(.317,.271),l(.385,.159),l(.33,.302),l(-.749,.367),l(-.405,.43),l(-.368,.461),l(-1.591,.669),l(-.699,.286),l(-.456,-.205),l(-.326,.08),l(-.538,.539),l(-.646,.144),l(-.663,.348),l(-.217,.284),l(-.191,.142),l(-.746,.033),l(-.221,-.031),l(.151,.535),l(-.484,.425),L(439,61.33),l(.216,.533),l(.243,.25),l(-.244,.955),l(-.498,.063),l(-.217,.204),l(.189,.757),l(-.009,.544),l(.381,.444),l(-.287,.175),l(.926,.082),l(.225,.187),l(.499,-.082),l(.652,.594),l(.428,.314),l(.86,.163),l(.198,.406),l(.32,.139),l(.014,.335),l(-.391,0),l(-.508,.323),l(-.861,.3),l(-.492,.162),l(-.521,-.012),l(-.146,-.115),l(-.805,-.115),l(-.66,-.173),l(-.634,-.069),l(-.137,.104),l(-.446,-.115),l(-.257,.3),l(.819,-.069),l(.497,.265),l(.591,.046),l(.205,.208),l(.481,.069),l(.021,-.127),l(.616,.069),l(.258,-.196),l(.297,.011),l(.481,-.104),l(.226,.081),l(.026,-.15),l(.164,0),l(.214,.15),l(-.029,.081),l(-.722,.023),l(.219,.288),l(-.792,.265),l(-.168,.288),l(-.386,.08),l(-.089,-.092),l(.042,-.161),l(-.014,-.276),l(-.258,.023),l(-.091,.46),l(-.501,.333),l(-.248,.058),l(-.36,-.069),l(-.005,.218),l(-1.418,.035),l(.156,.458),l(.513,.258),l(.066,.609),l(-.109,.33),l(-.281,.051),l(-.308,-.064),l(.038,.429),l(.29,.081),l(-.126,.268),l(.24,.228),l(-.365,.364),l(-.222,.455),l(-.041,.56),l(-.766,1.043),l(-.58,.71),l(-.165,-.062),l(-.442,-.236),l(-.614,.193),l(-1.262,-.089),l(-.106,.311),l(-.252,-.083),l(-.518,.264),l(-.295,.517),l(.356,.336),l(-.376,.374),l(-.48,-.129),l(-.173,-.037),l(-1.158,.269),l(-1.11,-.116),l(-.001,-.142),l(.19,-.078),l(-.062,-.181),l(.281,-.297),l(-.638,-.53),l(-.413,-.479),l(-.22,-.272),l(.529,-.116),l(-.082,-.312),l(.421,.077),l(.147,-.245),l(-.19,-.234),l(-.285,.013),l(-.292,-.377),l(-.527,-.221),l(-.63,-.99),l(-.286,0),l(.011,-.408),l(-.256,-.364),l(-.348,-.298),l(.221,-.484),l(.206,-.341),l(-.418,-.154),l(-.405,.102),l(-.055,-.288),l(-.412,.051),l(-.18,-1.207),l(-.225,-.131),l(.311,-.355),l(.293,.132),l(.15,.342),l(.41,-.013),l(.324,-.737),l(-.22,-.831),l(.506,-.224),l(.117,-.423),l(.414,-.013),l(.769,-.384),l(.029,-.532),l(.249,-.346),l(-.26,-.427),l(-.571,-.735),l(.941,-.16),l(.432,-.67),l(-.297,-.243),l(-.715,-.186),l(-.582,-.39),l(.335,-1.171),l(-.65,-.729),l(.349,-1.093),l(.077,-.664),l(.389,-.492),l(.617,-.479),l(.613,-.257),l(.618,-.114),l(.932,.027),l(.733,-.036),l(.44,-.177),l(.17,-.176),l(-.252,-.587),l(-.381,-.269),l(-.339,-.125),l(.495,-.545),l(.574,-.499),l(.383,-.469),l(.32,-.598),l(.06,-.971),l(.121,-.244),l(.981,-.021),l(.687,-.442),l(1.325,-.919),l(.615,-.346),l(.188,-.345),l(-.171,-.507),l(-.05,-.213),l(1.484,-1.176),l(.465,-.167),l(.279,.015),l(.871,.095),l(.695,-.004),l(.318,-.299),l(.083,-.199),l(.021,-.663),l(.168,-.183),l(1.731,.389),l(.972,.144),l(.67,.129),l(.323,.015),l(.271,-.25),l(.164,-.449),l(.281,-1.066),l(.865,-.038),l(.41,.031),l(.114,.063),l(.146,.033),l(.616,.463),l(1.286,.658),l(1.085,.292),l(1.583,.207),l(.508,.229),l(.77,.558),l(-.062,.413),l(-.004,.526),l(.507,.637),l(.405,.685),l(.028,.392),l(-.5,.8),l(.208,.535),l(.327,.307),l(.113,.234),
+N(238.107,361.753),l(.515,-.688),l(.859,0),l(1.202,-.515),l(-.171,-.858),l(-3.091,.344),l(-2.061,.515),l(-1.545,-.344),l(-.515,-.858),l(1.374,-.515),l(1.202,-.172),l(3.091,-.172),l(1.374,-.515),l(-.172,-1.03),l(.859,-.516),l(0,-1.374),l(-1.326,-1.054),l(.982,-.491),l(1.202,-.344),l(1.545,-.172),l(.858,.344),l(.858,.858),l(1.03,1.374),l(1.374,1.202),l(1.03,1.373),l(-.515,2.061),l(-1.545,.516),l(-1.545,.858),l(-3.434,.172),l(-3.435,0),M(172.686,360.379),l(3.091,-.687),l(3.262,0),l(5.495,0),l(2.919,1.202),l(-2.748,.687),l(-3.759,-.337),l(-5.169,-.35),l(-3.091,-.516),M(65.13,371.085),l(1.194,-.265),l(1.393,.133),l(.796,.464),l(-1.99,0),l(-1.393,-.332),M(277.944,379.954),l(.515,-1.202),l(2.404,-1.03),l(2.748,-.172),l(2.061,-.171),l(1.545,-.859),l(.343,-1.545),l(1.374,-.687),l(3.091,-.688),l(4.464,0),l(2.404,0),l(3.434,.688),l(.687,1.889),l(0,1.202),l(-2.061,1.201),l(-11.848,1.03),l(-11.161,.344),M(36.004,376.434),l(1.202,-.858),l(2.061,-.343),l(4.121,.515),l(4.293,1.374),l(-.887,.482),l(-2.719,.204),l(-4.293,-.515),l(-3.777,-.859),M(777.843,385.46),l(3.823,.391),l(.899,.029),l(.322,.234),l(1.202,.294),l(2.329,.088),l(2.126,-.003),l(5.218,.329),l(3.046,.348),l(1.144,-.059),l(.762,.029),l(1.411,.37),l(0,2.175),l(0,2.223),l(0,2.222),l(0,2.223),l(0,2.222),l(0,1.551),l(-.041,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.182,0),l(-.041,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.223,0),l(-2.182,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.223,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),l(-2.222,0),H(9.014,0),H(6.792,0),H(4.569,0),H(2.347,0),H(.125,0),l(0,-1.544),l(0,-2.222),l(0,-2.223),l(0,-2.222),l(0,-2.223),l(0,-2.223),l(3.941,.297),l(10.131,0),l(7.898,.516),l(6.868,.172),l(8.586,.858),l(6.353,.515),l(8.757,.172),l(4.808,-.172),l(6.525,-.172),l(2.404,.344),l(3.606,-.858),l(16.312,.344),l(4.638,-.013),l(1.143,-.467),l(-14.366,-.551),l(-9.616,-.688),l(-2.232,0),l(-3.091,-.172),l(-.858,-.171),l(-1.545,-.344),l(-.498,-.455),l(.155,-1.434),l(.687,-.858),l(1.889,-.688),l(-3.263,-.687),l(-2.232,-.344),l(-.953,-.503),l(1.589,-.521),l(-2.891,-.6),l(-3.074,-.208),l(-.104,-.261),l(2.857,-.312),l(2.748,0),l(6.525,.343),l(3.434,0),l(2.576,.344),l(4.636,-1.202),l(2.404,-.687),l(-2.748,-1.03),l(-3.778,-.858),l(-4.391,-.405),l(-2.649,-.625),l(-3.262,-.172),l(-2.919,0),l(-2.919,-.858),l(2.576,-.516),l(1.28,-.342),l(-1.28,-.517),l(-2.919,.516),H(52.66,0),l(-1.717,-.344),L(49.054,373),l(.343,-1.202),l(1.956,-.07),l(1.65,-.273),l(4.98,0),l(4.626,.493),l(3.272,.709),l(1.374,.172),l(4.465,-.858),l(4.089,.243),l(0,-.729),l(.066,-.597),l(-2.255,-.73),l(-2.93,-.075),l(-2.576,-.344),l(2.404,-.687),l(4.121,.171),l(1.717,-.343),l(3.091,-.516),l(3.09,-.343),l(5.667,-.688),l(4.465,-.343),l(3.949,-.516),l(4.464,-.515),l(2.748,.343),l(5.667,0),l(4.464,.258),l(4.121,-.515),l(7.898,.343),l(7.555,-.687),l(3.091,.172),l(1.545,-.688),l(1.545,.516),l(5.323,-.172),l(.121,-.87),l(1.758,-.293),l(1.433,.325),l(.586,.554),l(-.423,.813),l(2.364,.329),l(1.38,-.264),l(-.006,-.938),l(1.438,-.267),l(1.48,.267),l(.212,1.036),l(-1.009,.423),l(.521,.781),l(3.024,-.351),l(1.889,.343),l(3.434,.172),l(2.576,-.687),l(3.778,.086),l(4.868,.33),l(2.344,.013),l(1.449,.109),l(.693,-.53),l(-.611,-.285),l(-2.202,-.122),l(1.305,-.285),l(.041,-.408),l(-.367,-.245),l(-1.386,.123),l(-.693,.04),l(-.856,-.979),l(-2.178,-.337),l(-.676,-.193),l(-.182,-.665),l(4.056,.462),l(3.874,-.245),l(-1.224,-.489),l(-6.035,-.163),l(-.774,-.082),l(-.653,-.489),l(0,-.815),l(2.301,.105),l(.839,.67),l(5.301,-.204),l(7.253,.736),l(2.404,-.172),l(3.262,-.172),l(4.464,.172),l(3.263,.172),l(2.061,-.516),l(.687,-.687),l(1.202,0),l(.344,1.03),l(2.576,.343),l(2.404,-.343),l(.858,.515),l(3.435,.688),l(3.777,.343),l(2.061,.172),l(1.03,-.515),l(.687,-1.202),l(2.747,-.172),l(1.03,.515),l(1.717,.688),l(3.091,-.172),l(3.434,.258),l(4.121,-.344),l(4.979,-.516),l(5.495,-.858),l(3.091,-.515),l(1.202,-.688),l(0,-1.373),l(-1.374,-1.202),l(-.859,-1.545),l(-1.202,-.688),l(-.344,-1.03),l(1.202,-1.03),l(1.717,-.343),l(.858,-1.202),l(-.343,-.858),l(-.172,-1.03),l(-1.202,-.516),l(.344,-1.545),l(1.889,-.172),l(2.404,-1.374),l(1.545,-.515),l(.859,-.859),l(1.03,-.687),l(2.919,-1.202),l(3.606,-.515),l(2.404,-1.202),l(2.404,-.172),l(2.232,-1.03),l(1.545,-.343),l(.343,1.03),l(-1.374,.515),l(-1.03,.344),l(-1.202,.515),l(-.858,0),l(-1.202,0),l(-2.919,1.202),l(-1.03,.687),l(-1.717,1.374),l(-.172,1.202),l(-.687,.687),l(-1.374,-.344),l(-1.03,0),l(-1.202,.516),l(-1.202,.687),l(-1.03,.688),l(-.687,1.201),l(.515,.688),l(.687,.687),l(1.374,.344),l(1.545,0),l(.858,.515),l(.687,1.202),l(1.545,1.546),l(.687,.858),l(1.03,.687),l(.687,1.374),l(.858,1.373),l(.344,1.546),l(-.344,.858),l(-.858,1.717),l(-2.919,1.889),l(-1.202,.172),l(-1.03,.858),l(-1.717,1.03),l(-3.263,.344),l(-4.979,.858),l(-2.404,.344),l(-2.919,.687),l(-7.377,-.141),l(-4.556,-.316),l(-.773,-.401),l(-1.717,-.344),l(-1.717,-.343),l(-1.374,0),l(-.859,.515),l(.515,.858),l(2.061,.688),l(4.121,1.202),l(4.995,.04),l(1.202,.759),l(-3.278,.574),l(-5.667,-.343),l(-4.979,-.516),l(-3.097,-.285),l(-2.151,.253),l(.823,.696),l(1.164,.538),l(3.262,.172),l(2.232,0),l(1.374,.343),l(-.249,.402),l(-.782,.113),l(-2.232,.515),l(-5.151,-.171),l(-1.374,-.172),l(-2.232,-1.202),l(-2.404,0),l(.128,.917),l(2.62,1.144),l(1.03,.172),l(1.202,-.172),l(1.374,.344),l(2.404,0),l(4.98,-.516),l(3.09,.687),l(.385,.431),l(-.041,.6),l(-2.061,.172),l(-3.263,.172),l(-2.608,-.185),l(3.811,.871),l(3.656,-.238),l(1.324,.41),l(2.576,.687),l(6.869,.859),l(8.585,.858),l(10.646,1.373),l(6.525,.516),l(2.061,.858),l(.687,1.03),l(3.091,-.344),l(5.323,-1.545),l(6.525,-.687),l(2.455,-.066),l(6.474,-.105),l(9.788,-.344),l(1.889,.344),l(2.576,-1.202),l(8.414,-1.03),l(11.333,-.172),l(8.929,-.858),l(1.202,-.858),l(-1.202,-.516),l(-.271,-1.07),l(-1.184,-.338),l(-5.071,.035),l(-2.232,.172),l(-4.808,-.344),l(-3.091,0),l(0,-1.202),l(3.263,-1.545),l(3.949,-1.202),l(2.404,-.172),l(4.121,-1.03),l(9.444,-1.202),l(5.323,-.858),l(6.525,0),l(4.979,-.516),l(2.747,-2.061),l(6.039,-1.541),l(-1.23,-.52),l(-2.576,.516),l(-2.061,-.344),l(1.545,-1.03),l(1.545,-.343),l(2.48,-.249),l(.696,-.742),l(3.85,-.742),l(1.577,-.418),l(.603,-.557),l(-1.716,-.881),l(-.093,-.604),l(1.252,-.231),l(.464,.742),l(1.017,-.097),l(2.061,-.858),l(1.03,-.343),l(.858,.171),l(1.203,1.544),l(2.403,-.342),l(.242,-.91),l(.96,-.807),l(1.889,-.516),l(1.374,.516),l(-1.162,.574),l(-.139,.604),l(3.189,-.319),l(4.808,.258),l(3.263,-.172),l(1.03,.858),l(1.545,-.344),l(1.717,-.515),l(5.839,-.858),l(7.212,-1.03),l(4.292,-.858),l(2.061,0),l(2.061,1.373),l(1.718,.344),l(1.889,-.344),l(1.545,-.858),l(7.556,-.344),l(3.434,-.171),l(4.293,.171),l(6.697,.945),l(2.575,0),l(4.293,-.516),l(6.01,-.687),l(5.151,-.688),l(2.404,-.515),l(2.231,-.344),l(.615,-.959),l(1.148,-.835),l(1.671,-.095),l(.938,.965),l(1.294,.409),l(1.732,1.052),l(1.009,.139),l(1.009,-.661),l(1.322,-.174),l(.209,.522),l(-.835,.312),l(.661,.244),l(.8,.278),l(.383,-.383),l(.313,-.383),l(.312,.209),l(-.174,.348),l(0,.521),l(.592,-.174),l(1.913,-.557),l(.418,-1.704),l(5.102,-1.137),l(1.374,-.687),l(3.605,-.172),l(1.363,-.646),l(2.758,-.126),l(.21,-.27),l(-.165,-.297),l(.692,-.23),l(1.221,.165),l(.197,.593),l(.66,.231),l(2.165,-.536),l(1.265,-.223),l(-.726,-.297),l(-.561,-.264),l(.099,-.362),l(1.451,-.1),l(1.562,.215),l(.647,.28),l(.692,-.132),l(-.066,-.33),l(-.527,-.33),l(0,-.561),l(.297,-.23),l(.846,-.242),l(4.292,-.858),l(2.92,-.172),l(3.058,.115),l(2.296,1.076),l(1.316,.023),l(.741,.144),l(.023,.383),l(-.908,.096),l(-.168,.454),l(1.723,.216),l(4.892,.646),l(5.571,.453),l(1.546,.172),l(1.717,-.172),l(7.556,.688),l(5.323,0),l(.687,.687),l(.2,1.075),l(-.73,1.232),l(-.672,.439),l(-.425,1.113),l(-.73,.319),l(-.905,-.402),l(-.83,.402),l(-.73,.959),l(1.507,.457),l(.594,.045),l(.959,-.593),l(.411,.365),l(-.867,1.05),l(-1.215,.062),l(-1.717,1.374),l(0,.858),l(1.889,.688),l(2.919,0),l(1.718,-.859),l(1.889,-1.545),l(1.717,-1.717),l(1.374,-.688),l(4.121,-1.03),l(2.231,-.687),l(3.263,-.344),l(2.061,-1.03),l(1.03,-1.03),l(3.435,-1.03),l(2.403,-.687),l(2.061,-.687),l(2.061,-.172),l(6.182,-.687),l(3.778,.171),l(1.204,-.542),l(.169,-.659),l(.54,-.759),l(.49,-.101),l(.471,.776),l(.305,.775),l(4.892,-.35),l(5.838,0),l(4.979,-.172),l(3.091,.344),l(2.112,-.214),l(1.328,.085),l(1.018,.594),l(1.188,-.764),l(2.714,-1.046),l(1.866,-.226),l(.664,-.028),l(.594,-.028),l(.777,-.057),l(1.512,.311),l(1.166,-.172),l(3.606,.687),l(3.777,.344),l(1.03,0),l(1.064,.573),l(.745,.088),l(2.149,-.088),l(1.271,-.263),l(1.315,-.438),l(-.192,-.216),l(.28,-.53),l(1.447,-.131),l(.921,-.088),l(.786,.062),l(2.195,-.501),l(2.097,.501),l(.688,.687),l(.373,.435),l(1.842,-.131),l(.921,-.044),l(.985,.255),l(1.889,.688),l(2.919,.515),l(2.919,-.343),l(4.121,-.258),l(2.232,-.344),l(2.404,0),l(3.521,.315),l(.702,-.755),l(2.158,-.162),l(.863,1.133),l(4.909,.323),l(.917,-1.133),l(1.889,-.593),l(5.988,.013),l(.756,-.283),l(1.996,.108),l(-.432,-1.403),l(.054,-.809),l(1.232,-.36),l(.872,1.277),l(-.647,1.079),l(.805,.219),l(2.81,.482),l(5.262,.376),l(5.494,.344),l(2.278,.583),l(1.283,.14),l(1.396,-.167),l(2.204,.446),l(1.961,-.167),l(.719,.278),l(-.435,.431),l(-.151,.351),l(.293,.123),l(2.081,.331),l(1.078,.484),l(2.706,-.134),l(.377,.595),l(1.038,.227),l(4.808,.515),l(-.123,.536),l(.567,.236),l(2.695,-.095),l(3.214,.181),l(-.329,-.984),l(.71,-.095),l(.804,.426),l(.331,.709),l(1.135,.284),l(2.672,.519),l(2.576,-.343),l(4.017,.999),l(1.626,.495),l(1.672,.871),l(1.626,.023),l(.504,.187),l(.532,-.021),l(.754,-.047),l(.777,.047),l(.896,.589),l(.541,.118),l(.542,.07),l(.142,-.259),l(.471,0),l(1.484,-.048),l(1.416,.237),l(5.951,.535),l(.729,.516),l(1.733,.323),l(2.979,.944),l(.43,-.335),l(.551,.191),l(.454,.67),l(-.741,.215),l(-1.124,.167),l(-.216,.359),l(.168,.263),l(.55,-.048),l(-.024,.67),l(-.43,-.048),l(-.096,.287),l(-.312,.071),l(-.598,.622),l(-.526,.12),l(-.55,.287),l(-.168,.669),l(-1.603,.096),l(-1.339,-.239),l(-1.794,.359),l(-2.153,.425),l(-2.629,.764),l(1.271,1.103),l(-1.907,.212),l(-1.23,-.255),l(-.763,.212),l(-.043,.637),l(-2.374,.169),l(.136,.514),l(.924,.632),l(-.127,.763),l(-.382,.085),l(-.466,.467),l(.551,.466),l(.085,.764),l(-.764,.424),l(.637,.254),l(.763,0),l(.764,.255),l(.339,.509),l(.17,.721),l(1.284,-.187),l(.836,.907),l(2.035,.297),l(.339,.339),l(2.672,.552),l(-4.113,0),l(-2.799,.138),l(-2.332,.541),l(-1.823,-.085),l(-.806,.212),l(-1.611,.339),l(-1.326,-.32),l(-.546,.426),l(1.116,.529),l(-.503,.447),l(-.669,.195),l(-1.117,.753),l(-2.623,.642),l(.475,.391),l(2.205,-.111),l(.53,0),l(.809,.307),l(.168,.363),l(.499,.18),l(.422,.183),l(.111,.894),l(.209,.502),l(3.195,.279),l(2.874,.948),l(3.662,.801),l(5.151,1.202),l(1.456,.062),l(1.015,.17),l(-.146,.234),l(-1.67,.264),l(-.47,.264),l(1.173,.088),l(2.198,-.293),l(1.988,.166),
+E(0,0)
+};
+
+#undef N
+#undef M
+#undef L
+#undef l
+#undef E
diff --git a/test/xcb-huge-image-shm.c b/test/xcb-huge-image-shm.c
new file mode 100644
index 000000000..269d7f0d4
--- /dev/null
+++ b/test/xcb-huge-image-shm.c
@@ -0,0 +1,67 @@
+/*
+ * Copyright © 2011 Uli Schlachter
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Uli Schlachter <psychon@znc.in>
+ */
+
+#include "cairo-test.h"
+
+#define WIDTH 3000
+#define HEIGHT 3000
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_surface_t *surface;
+ cairo_surface_t *image;
+ cairo_t *cr2;
+
+ /* We use a similar surface to have way smaller ref images */
+ surface = cairo_surface_create_similar (cairo_get_target (cr),
+ CAIRO_CONTENT_COLOR_ALPHA,
+ WIDTH, HEIGHT);
+
+ /* First we have to defeat xcb's deferred clear */
+ cr2 = cairo_create (surface);
+ cairo_test_paint_checkered (cr2);
+ cairo_destroy (cr2);
+
+ /* Now we try to map this to an image. This will try to use shared memory
+ * but fail the allocation, because of the huge surface. */
+ image = cairo_surface_map_to_image (surface, NULL);
+ cairo_surface_unmap_image (surface, image);
+
+ /* Finally we make sure that errors aren't lost. */
+ cairo_set_source_surface (cr, surface, 0, 0);
+ cairo_paint (cr);
+ cairo_surface_destroy (surface);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (xcb_huge_image_shm,
+ "Force a failed shm allocation when receiving an image",
+ "xcb", /* keywords */
+ NULL, /* requirements */
+ 2, 2,
+ NULL, draw)
diff --git a/test/xcb-huge-subimage.c b/test/xcb-huge-subimage.c
new file mode 100644
index 000000000..fc8e278c6
--- /dev/null
+++ b/test/xcb-huge-subimage.c
@@ -0,0 +1,81 @@
+/*
+ * Copyright © 2012 Uli Schlachter
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Uli Schlachter <psychon@znc.in>
+ */
+
+#include "cairo-test.h"
+
+#define WIDTH 6000
+#define HEIGHT 6000
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_surface_t *surface;
+ cairo_surface_t *image;
+ cairo_surface_t *subimage;
+ cairo_rectangle_int_t extents;
+ cairo_t *cr2;
+
+ extents.x = extents.y = 10;
+ extents.width = WIDTH - 20;
+ extents.height = HEIGHT - 20;
+
+ /* We use a similar surface to have way smaller ref images */
+ surface = cairo_surface_create_similar (cairo_get_target (cr),
+ CAIRO_CONTENT_COLOR_ALPHA,
+ WIDTH, HEIGHT);
+
+ /* First we have to defeat xcb's deferred clear */
+ cr2 = cairo_create (surface);
+ cairo_test_paint_checkered (cr2);
+ cairo_destroy (cr2);
+
+ /* Get us an image surface with a non-natural stride */
+ image = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
+ WIDTH, HEIGHT);
+ subimage = cairo_surface_map_to_image (image, &extents);
+
+ /* Paint the subimage to the similar surface and trigger the big upload */
+ cr2 = cairo_create (surface);
+ cairo_set_source_surface (cr2, subimage, 0, 0);
+ cairo_paint (cr2);
+ cairo_destroy (cr2);
+
+ /* Finally we make sure that errors aren't lost. */
+ cairo_surface_unmap_image (image, subimage);
+ cairo_set_source_surface (cr, surface, 0, 0);
+ cairo_paint (cr);
+ cairo_surface_destroy (image);
+ cairo_surface_destroy (surface);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (xcb_huge_subimage,
+ "Test if the maximum request size is honored",
+ "xcb", /* keywords */
+ NULL, /* requirements */
+ 2, 2,
+ NULL, draw)
diff --git a/test/xcb-snapshot-assert.c b/test/xcb-snapshot-assert.c
new file mode 100644
index 000000000..b578f8c7e
--- /dev/null
+++ b/test/xcb-snapshot-assert.c
@@ -0,0 +1,75 @@
+/*
+ * Copyright © 2011 Uli Schlachter
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Uli Schlachter <psychon@znc.in>
+ */
+
+#include "cairo-test.h"
+#include "cairo.h"
+
+static cairo_surface_t *
+create_image (int width, int height)
+{
+ cairo_surface_t *surface;
+ cairo_t *cr;
+
+ surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
+ /* Paint something random to the image */
+ cr = cairo_create (surface);
+ cairo_surface_destroy (surface);
+
+ cairo_set_source_rgb (cr, 0, 1, 1);
+ cairo_paint (cr);
+
+ surface = cairo_surface_reference (cairo_get_target (cr));
+ cairo_destroy (cr);
+
+ return surface;
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_surface_t *image;
+
+ /* Image has to have same geometry as xcb surface to be added as a snapshot */
+ image = create_image (width, height);
+ cairo_set_source_surface (cr, image, 0, 0);
+ cairo_surface_destroy (image);
+
+ /* This attaches the tested xcb surface as a snapshot */
+ cairo_paint (cr);
+
+ /* Now cairo is modifying a snapshot which fails an
+ * assert in _cairo_surface_begin_modification */
+ cairo_paint (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (xcb_snapshot_assert,
+ "Test a wrong _cairo_surface_attach_snapshot call",
+ "xcb", /* keywords */
+ NULL, /* requirements */
+ 2, 2,
+ NULL, draw)
diff --git a/test/xcb-stress-cache.c b/test/xcb-stress-cache.c
new file mode 100644
index 000000000..3e3d0a289
--- /dev/null
+++ b/test/xcb-stress-cache.c
@@ -0,0 +1,118 @@
+/*
+ * Copyright © 2011 Uli Schlachter
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Uli Schlachter <psychon@znc.in>
+ */
+
+#include "cairo-test.h"
+
+#define WIDTH 512
+#define HEIGHT 512
+
+/* This is a random pick. This results in 512 (width) * 512 (height) *
+ * 2 (surfaces per run) * 4 (ARGB32) * ITERATIONS = 200 MiB of image data. */
+#define ITERATIONS 100
+
+/* This tries to trigger a bug in the xcb backend where a Picture is freed to
+ * early. It goes something like this:
+ *
+ * - _composite_mask calls _cairo_xcb_picture_for_pattern to get a xcb_picture_t
+ * for the source.
+ * - _cairo_xcb_picture_for_pattern calls _cairo_xcb_surface_picture which calls
+ * _cairo_xcb_screen_store_surface_picture which adds the picture to a cache.
+ * - _cairo_xcb_surface_picture also attached the picture as a snapshot to
+ * the source surface using cairo_surface_finish as detach_func.
+ * - _composite_mask calls _cairo_xcb_picture_for_pattern to get a xcb_picture_t
+ * for the mask.
+ * - The resulting picture surface is added to the cache again, but the cache is
+ * already full, so a random cache entry is picked and removed.
+ * - The surface that was added before is picked and gets fed to
+ * _surface_cache_entry_destroy.
+ * - This calls _cairo_surface_detach_snapshot which causes the
+ * detach_func from above to be called, so the surface is finished and the
+ * associated picture is FreePicture'd.
+ * - _composite_mask now uses a Picture that was already freed.
+ *
+ * So this depends on the screen's surface cache to be full which is why we do
+ * all this looping.
+ */
+
+static cairo_surface_t *
+create_image (void)
+{
+ cairo_surface_t *surface;
+ cairo_t *cr;
+
+ surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, WIDTH, HEIGHT);
+ /* Paint something random to the image */
+ cr = cairo_create (surface);
+ cairo_paint (cr);
+ cairo_set_source_rgb (cr, 0, 1, 1);
+ cairo_rectangle (cr, 0, 0, WIDTH/2.0, HEIGHT/2.0);
+ cairo_fill (cr);
+ cairo_set_source_rgb (cr, 1, 0, 1);
+ cairo_rectangle (cr, WIDTH/2.0, HEIGHT/2.0, WIDTH/2.0, HEIGHT/2.0);
+ cairo_fill (cr);
+ cairo_destroy (cr);
+
+ return surface;
+}
+
+static cairo_surface_t *
+dirty_cache (cairo_t *cr)
+{
+ cairo_surface_t *surface;
+
+ /* Set a source surface... */
+ surface = create_image ();
+ cairo_set_source_surface (cr, surface, 0, 0);
+ cairo_surface_destroy (surface);
+ /* ...and create a mask surface, so that we can hit the early FreePicture */
+ surface = create_image ();
+ cairo_mask_surface (cr, surface, 0, 0);
+
+ return surface;
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ int i;
+ cairo_surface_t *array[ITERATIONS];
+
+ /* We have to keep the associated cairo_surface_t alive so that they aren't
+ * removed from the cache */
+ for (i = 0; i < ITERATIONS; i++)
+ array[i] = dirty_cache (cr);
+ for (i = 0; i < ITERATIONS; i++)
+ cairo_surface_destroy (array[i]);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (xcb_stress_cache,
+ "Stress test for a image surface cache in cairo-xcb",
+ "xcb, stress", /* keywords */
+ NULL, /* requirements */
+ 2, 2,
+ NULL, draw)
diff --git a/test/xcb-surface-source.c b/test/xcb-surface-source.c
new file mode 100644
index 000000000..d2c7a1362
--- /dev/null
+++ b/test/xcb-surface-source.c
@@ -0,0 +1,149 @@
+/*
+ * Copyright © 2009 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Chris Wilson not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Chris Wilson makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+#if CAIRO_HAS_XCB_SURFACE
+#include <cairo-xcb.h>
+#endif
+
+#include "surface-source.c"
+
+#if CAIRO_HAS_XCB_SURFACE
+static cairo_user_data_key_t closure_key;
+
+struct closure {
+ cairo_device_t *device;
+ xcb_connection_t *connection;
+ xcb_pixmap_t pixmap;
+};
+
+static void
+cleanup (void *data)
+{
+ struct closure *arg = data;
+
+ cairo_device_finish (arg->device);
+ cairo_device_destroy (arg->device);
+
+ xcb_free_pixmap (arg->connection, arg->pixmap);
+ xcb_disconnect (arg->connection);
+
+ free (arg);
+}
+
+static xcb_render_pictforminfo_t *
+find_depth (xcb_connection_t *connection, int depth, void **formats_out)
+{
+ xcb_render_query_pict_formats_reply_t *formats;
+ xcb_render_query_pict_formats_cookie_t cookie;
+ xcb_render_pictforminfo_iterator_t i;
+
+ cookie = xcb_render_query_pict_formats (connection);
+ xcb_flush (connection);
+
+ formats = xcb_render_query_pict_formats_reply (connection, cookie, 0);
+ if (formats == NULL)
+ return NULL;
+
+ for (i = xcb_render_query_pict_formats_formats_iterator (formats);
+ i.rem;
+ xcb_render_pictforminfo_next (&i))
+ {
+ if (XCB_RENDER_PICT_TYPE_DIRECT != i.data->type)
+ continue;
+
+ if (depth != i.data->depth)
+ continue;
+
+ *formats_out = formats;
+ return i.data;
+ }
+
+ free (formats);
+ return NULL;
+}
+#endif
+
+static cairo_surface_t *
+create_source_surface (int size)
+{
+#if CAIRO_HAS_XCB_SURFACE
+ xcb_connection_t *connection;
+ xcb_render_pictforminfo_t *render_format;
+ struct closure *data;
+ cairo_surface_t *surface;
+ xcb_screen_t *root;
+ xcb_void_cookie_t cookie;
+ void *formats;
+
+ connection = xcb_connect (NULL, NULL);
+ if (connection == NULL)
+ return NULL;
+
+ data = xmalloc (sizeof (struct closure));
+ data->connection = connection;
+
+ render_format = find_depth (connection, 32, &formats);
+ if (render_format == NULL) {
+ xcb_disconnect (connection);
+ free (data);
+ return NULL;
+ }
+
+ root = xcb_setup_roots_iterator (xcb_get_setup (connection)).data;
+
+ data->pixmap = xcb_generate_id (connection);
+ cookie = xcb_create_pixmap_checked (connection, 32,
+ data->pixmap, root->root, size, size);
+ /* slow, but sure */
+ if (xcb_request_check (connection, cookie) != NULL) {
+ free (formats);
+ xcb_disconnect (connection);
+ free (data);
+ return NULL;
+ }
+
+ surface = cairo_xcb_surface_create_with_xrender_format (connection,
+ root,
+ data->pixmap,
+ render_format,
+ size, size);
+ free (formats);
+
+ data->device = cairo_device_reference (cairo_surface_get_device (surface));
+ cairo_surface_set_user_data (surface, &closure_key, data, cleanup);
+
+ return surface;
+#else
+ return NULL;
+#endif
+}
+
+CAIRO_TEST (xcb_surface_source,
+ "Test using a XCB surface as the source",
+ "source", /* keywords */
+ NULL, /* requirements */
+ SIZE, SIZE,
+ preamble, draw)
diff --git a/test/xcomposite-projection.c b/test/xcomposite-projection.c
new file mode 100644
index 000000000..39686cf99
--- /dev/null
+++ b/test/xcomposite-projection.c
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2009 Benjamin Otte
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Benjamin Otte <otte@gnome.org>
+ */
+
+#include "cairo-test.h"
+
+/*
+ * Exercise a bug in the projection of a rotated trapezoid mask.
+ * I used CAIRO_ANTIALIAS_NONE and a single-color source in the test to get
+ * rid of aliasing issues in the output images. This makes some issues
+ * slightly less visible, but still fails for all of them. If you want to
+ * get a clearer view:
+ * #define ANTIALIAS CAIRO_ANTIALIAS_DEFAULT
+ */
+
+#define ANTIALIAS CAIRO_ANTIALIAS_NONE
+
+static const char png_filename[] = "romedalen.png";
+
+static cairo_pattern_t *
+get_source (const cairo_test_context_t *ctx,
+ int *width, int *height)
+{
+ cairo_surface_t *surface;
+ cairo_pattern_t *pattern;
+
+ if (ANTIALIAS == CAIRO_ANTIALIAS_NONE) {
+ cairo_t *cr;
+
+ surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, 256, 192);
+ cr = cairo_create (surface);
+
+ cairo_set_source_rgb (cr, 0.75, 0.25, 0.25);
+ cairo_paint (cr);
+
+ pattern = cairo_pattern_create_for_surface (cairo_get_target (cr));
+ cairo_destroy (cr);
+ } else {
+ surface = cairo_test_create_surface_from_png (ctx, png_filename);
+ pattern = cairo_pattern_create_for_surface (surface);
+ }
+
+ *width = cairo_image_surface_get_width (surface);
+ *height = cairo_image_surface_get_height (surface);
+ cairo_surface_destroy (surface);
+
+ return pattern;
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_pattern_t *image;
+ int img_width, img_height;
+
+ image = get_source (cairo_test_get_context (cr),
+ &img_width, &img_height);
+
+ /* we don't want to debug antialiasing artifacts */
+ cairo_set_antialias (cr, ANTIALIAS);
+
+ /* dark grey background */
+ cairo_set_source_rgb (cr, 0.25, 0.25, 0.25);
+ cairo_paint (cr);
+
+ /* magic transform */
+ cairo_translate (cr, 10, -40);
+ cairo_rotate (cr, -0.05);
+
+ /* place the image on our surface */
+ cairo_set_source (cr, image);
+
+ /* paint the image */
+ cairo_rectangle (cr, 0, 0, img_width, img_height);
+ cairo_fill (cr);
+
+ cairo_pattern_destroy (image);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (xcomposite_projection,
+ "Test a bug with XRenderComposite reference computation when projecting the first trapezoid onto 16.16 space",
+ "xlib", /* keywords */
+ "target=raster", /* requirements */
+ 300, 150,
+ NULL, draw)
diff --git a/test/xlib-expose-event.c b/test/xlib-expose-event.c
new file mode 100644
index 000000000..1de23e01e
--- /dev/null
+++ b/test/xlib-expose-event.c
@@ -0,0 +1,196 @@
+/*
+ * Copyright © 2008 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Chris Wilson not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Chris Wilson makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+/* This test tries to emulate the behaviour of most toolkits; it tries
+ * to simulate typical usage of a single surface with multiple exposures.
+ *
+ * The first goal of the test is to reproduce the XSetClipMask(NULL) bug
+ * reintroduced in 1.6.2 (but was originally fixed in 40558cb15). As I've
+ * made the same mistake again, it is worth adding a regression test...
+ */
+
+#include "cairo-test.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "cairo.h"
+
+#include "buffer-diff.h"
+
+#define SIZE 160
+#define NLOOPS 10
+
+static const char *png_filename = "romedalen.png";
+
+static void
+draw_mask (cairo_t *cr)
+{
+ cairo_surface_t *surface;
+ cairo_t *cr2;
+
+ surface = cairo_surface_create_similar (cairo_get_group_target (cr),
+ CAIRO_CONTENT_ALPHA,
+ 50, 50);
+ cr2 = cairo_create (surface);
+ cairo_surface_destroy (surface);
+
+ cairo_rectangle (cr2,
+ 0, 0,
+ 40, 40);
+ cairo_rectangle (cr2,
+ 10, 10,
+ 40, 40);
+ cairo_clip (cr2);
+
+ cairo_move_to (cr2, 0, 25);
+ cairo_line_to (cr2, 50, 25);
+ cairo_move_to (cr2, 25, 0);
+ cairo_line_to (cr2, 25, 50);
+ cairo_set_source_rgb (cr2, 1, 1, 1);
+ cairo_stroke (cr2);
+
+ cairo_set_source_rgb (cr, 1, 0, 0);
+ cairo_mask_surface (cr, cairo_get_target (cr2), 50, 50);
+ cairo_destroy (cr2);
+}
+
+static cairo_surface_t *
+clone_similar_surface (cairo_surface_t * target, cairo_surface_t *surface)
+{
+ cairo_t *cr;
+ cairo_surface_t *similar;
+
+ similar = cairo_surface_create_similar (target,
+ cairo_surface_get_content (surface),
+ cairo_image_surface_get_width (surface),
+ cairo_image_surface_get_height (surface));
+
+ cr = cairo_create (similar);
+ cairo_surface_destroy (similar);
+
+ cairo_set_source_surface (cr, surface, 0, 0);
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_paint (cr);
+
+ similar = cairo_surface_reference (cairo_get_target (cr));
+ cairo_destroy (cr);
+
+ return similar;
+}
+
+static void
+draw_image (const cairo_test_context_t *ctx,
+ cairo_t *cr,
+ cairo_surface_t *image)
+{
+ cairo_set_source_surface (cr, image, 0, 0);
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_paint (cr);
+}
+
+static void
+draw (const cairo_test_context_t *ctx,
+ cairo_t *cr,
+ cairo_surface_t *image,
+ cairo_rectangle_t *region,
+ int n_regions)
+{
+ cairo_save (cr);
+ if (region != NULL) {
+ int i;
+ for (i = 0; i < n_regions; i++) {
+ cairo_rectangle (cr,
+ region[i].x, region[i].y,
+ region[i].width, region[i].height);
+ }
+ cairo_clip (cr);
+ }
+ cairo_push_group (cr);
+ draw_image (ctx, cr, image);
+ draw_mask (cr);
+ cairo_pop_group_to_source (cr);
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_paint (cr);
+ cairo_restore (cr);
+}
+
+static cairo_test_status_t
+draw_func (cairo_t *cr, int width, int height)
+{
+ cairo_rectangle_t region[4];
+ const cairo_test_context_t *ctx;
+ cairo_surface_t *source, *image;
+ int i, j;
+
+ ctx = cairo_test_get_context (cr);
+
+ source = cairo_test_create_surface_from_png (ctx, png_filename);
+ image = clone_similar_surface (cairo_get_group_target (cr), source);
+ cairo_surface_destroy (source);
+
+ cairo_push_group_with_content (cr, CAIRO_CONTENT_COLOR);
+ draw (ctx, cr, image, NULL, 0);
+ for (i = 0; i < NLOOPS; i++) {
+ for (j = 0; j < NLOOPS; j++) {
+ region[0].x = i * SIZE / NLOOPS;
+ region[0].y = i * SIZE / NLOOPS;
+ region[0].width = SIZE / 4;
+ region[0].height = SIZE / 4;
+
+ region[1].x = j * SIZE / NLOOPS;
+ region[1].y = j * SIZE / NLOOPS;
+ region[1].width = SIZE / 4;
+ region[1].height = SIZE / 4;
+
+ region[2].x = i * SIZE / NLOOPS;
+ region[2].y = j * SIZE / NLOOPS;
+ region[2].width = SIZE / 4;
+ region[2].height = SIZE / 4;
+
+ region[3].x = j * SIZE / NLOOPS;
+ region[3].y = i * SIZE / NLOOPS;
+ region[3].width = SIZE / 4;
+ region[3].height = SIZE / 4;
+
+ draw (ctx, cr, image, region, 4);
+ }
+ }
+
+ cairo_pop_group_to_source (cr);
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_paint (cr);
+
+ cairo_surface_destroy (image);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (xlib_expose_event,
+ "Emulate a typical expose event",
+ "xlib", /* keywords */
+ NULL, /* requirements */
+ SIZE, SIZE,
+ NULL, draw_func)
diff --git a/test/xlib-surface-source.c b/test/xlib-surface-source.c
new file mode 100644
index 000000000..7d2ed71c0
--- /dev/null
+++ b/test/xlib-surface-source.c
@@ -0,0 +1,100 @@
+/*
+ * Copyright © 2008 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Chris Wilson not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Chris Wilson makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+#include <cairo-xlib.h>
+#if CAIRO_HAS_XLIB_XRENDER_SURFACE
+#include <cairo-xlib-xrender.h>
+#endif
+
+#include "surface-source.c"
+
+static cairo_user_data_key_t closure_key;
+
+struct closure {
+ cairo_device_t *device;
+ Display *dpy;
+ Pixmap pix;
+};
+
+static void
+cleanup (void *data)
+{
+ struct closure *arg = data;
+
+ cairo_device_finish (arg->device);
+ cairo_device_destroy (arg->device);
+
+ XFreePixmap (arg->dpy, arg->pix);
+ XCloseDisplay (arg->dpy);
+
+ free (arg);
+}
+
+static cairo_surface_t *
+create_source_surface (int size)
+{
+#if CAIRO_HAS_XLIB_XRENDER_SURFACE
+ XRenderPictFormat *xrender_format;
+ struct closure *data;
+ cairo_surface_t *surface;
+
+ data = xmalloc (sizeof (struct closure));
+
+ data->dpy = XOpenDisplay (NULL);
+ if (!data->dpy) {
+ return NULL;
+ }
+
+ xrender_format = XRenderFindStandardFormat (data->dpy, PictStandardARGB32);
+
+ data->pix = XCreatePixmap (data->dpy, DefaultRootWindow (data->dpy),
+ size, size, xrender_format->depth);
+
+ surface = cairo_xlib_surface_create_with_xrender_format (data->dpy,
+ data->pix,
+ DefaultScreenOfDisplay (data->dpy),
+ xrender_format,
+ size, size);
+ data->device = cairo_device_reference (cairo_surface_get_device (surface));
+ if (cairo_surface_set_user_data (surface, &closure_key, data, cleanup)) {
+ cairo_surface_finish (surface);
+ cairo_surface_destroy (surface);
+ cleanup (data);
+ return NULL;
+ }
+
+ return surface;
+#else
+ return NULL;
+#endif
+}
+
+CAIRO_TEST (xlib_surface_source,
+ "Test using a Xlib surface as the source",
+ "source", /* keywords */
+ NULL, /* requirements */
+ SIZE, SIZE,
+ preamble, draw)
diff --git a/test/xlib-surface.c b/test/xlib-surface.c
new file mode 100644
index 000000000..137b28232
--- /dev/null
+++ b/test/xlib-surface.c
@@ -0,0 +1,353 @@
+/*
+ * Copyright © 2005 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+#include "cairo-test.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "cairo.h"
+#include "cairo-xlib.h"
+
+#include "cairo-boilerplate-xlib.h"
+
+#include "buffer-diff.h"
+
+#define SIZE 100
+#define OFFSCREEN_OFFSET 50
+
+cairo_bool_t result = 0;
+
+#if CAIRO_HAS_XLIB_XRENDER_SURFACE
+
+#include "cairo-xlib-xrender.h"
+
+/* Vladimir Vukicevic reported that surfaces were being created with
+ * mismatching Visuals and XRenderPictFormats.
+ */
+static cairo_bool_t
+surface_compare_visual_and_format (cairo_surface_t *surface)
+{
+ Display *dpy;
+ Visual *visual;
+ XRenderPictFormat *format;
+
+ dpy = cairo_xlib_surface_get_display (surface);
+
+ visual = cairo_xlib_surface_get_visual (surface);
+ if (visual == NULL)
+ return TRUE;
+
+ format = cairo_xlib_surface_get_xrender_format (surface);
+ if (format == NULL)
+ return TRUE;
+
+ return format == XRenderFindVisualFormat (dpy, visual);
+
+}
+#else
+
+static cairo_bool_t
+surface_compare_visual_and_format (cairo_surface_t *surface)
+{
+ return TRUE;
+}
+
+#endif
+
+static cairo_bool_t
+check_similar_visual_and_format (cairo_surface_t *surface)
+{
+ cairo_surface_t *similar;
+ cairo_bool_t ret;
+
+ similar = cairo_surface_create_similar (surface,
+ CAIRO_CONTENT_COLOR_ALPHA,
+ 1, 1);
+ if (cairo_surface_status (similar))
+ return FALSE;
+
+ ret = surface_compare_visual_and_format (similar);
+
+ cairo_surface_destroy (similar);
+
+ return ret;
+}
+
+
+static void
+draw_pattern (cairo_surface_t *surface)
+{
+ cairo_t *cr = cairo_create (surface);
+ int i;
+
+ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */
+ cairo_paint (cr);
+
+ cairo_set_source_rgba (cr, 0, 0.0, 0.0, 0.50); /* half-alpha-black */
+
+ for (i = 1; i <= 3; i++) {
+ int inset = SIZE / 8 * i;
+
+ cairo_rectangle (cr,
+ inset, inset,
+ SIZE - 2 * inset, SIZE - 2 * inset);
+ cairo_fill (cr);
+ }
+
+ cairo_destroy (cr);
+}
+
+static void
+erase_pattern (cairo_surface_t *surface)
+{
+ cairo_t *cr = cairo_create (surface);
+
+ cairo_set_source_rgb (cr, 0.0, 0.0, 0.0); /* black */
+ cairo_paint (cr);
+
+ cairo_destroy (cr);
+}
+
+static cairo_test_status_t
+do_test (const cairo_test_context_t *ctx,
+ Display *dpy,
+ unsigned char *reference_data,
+ unsigned char *test_data,
+ unsigned char *diff_data,
+ cairo_bool_t use_pixmap,
+ cairo_bool_t set_size,
+ cairo_bool_t offscreen)
+{
+ cairo_surface_t *surface;
+ cairo_surface_t *test_surface;
+ cairo_t *test_cr;
+ buffer_diff_result_t result;
+ Drawable drawable;
+ int screen = DefaultScreen (dpy);
+
+ if (use_pixmap && offscreen)
+ return CAIRO_TEST_SUCCESS;
+
+ if (use_pixmap) {
+ drawable = XCreatePixmap (dpy, DefaultRootWindow (dpy),
+ SIZE, SIZE, DefaultDepth (dpy, screen));
+ } else {
+ XSetWindowAttributes xwa;
+ int x, y;
+
+ xwa.override_redirect = True;
+
+ if (offscreen) {
+ x = - OFFSCREEN_OFFSET;
+ y = - OFFSCREEN_OFFSET;
+ } else {
+ x = 0;
+ y = 0;
+ }
+
+ drawable = XCreateWindow (dpy, DefaultRootWindow (dpy),
+ x, y, SIZE, SIZE, 0,
+ DefaultDepth (dpy, screen), InputOutput,
+ DefaultVisual (dpy, screen),
+ CWOverrideRedirect, &xwa);
+ XMapWindow (dpy, drawable);
+ }
+
+ surface = cairo_xlib_surface_create (dpy,
+ drawable,
+ DefaultVisual (dpy, screen),
+ SIZE, SIZE);
+
+ if (! surface_compare_visual_and_format (surface))
+ return CAIRO_TEST_FAILURE;
+
+ if (set_size) {
+ cairo_xlib_surface_set_size (surface, SIZE, SIZE);
+
+ if (cairo_xlib_surface_get_width (surface) != SIZE ||
+ cairo_xlib_surface_get_height (surface) != SIZE)
+ return CAIRO_TEST_FAILURE;
+ }
+
+ if (! check_similar_visual_and_format (surface))
+ return CAIRO_TEST_FAILURE;
+
+ draw_pattern (surface);
+
+ test_surface = cairo_image_surface_create_for_data (test_data,
+ CAIRO_FORMAT_RGB24,
+ SIZE, SIZE,
+ SIZE * 4);
+
+ test_cr = cairo_create (test_surface);
+ cairo_set_source_surface (test_cr, surface, 0, 0);
+ cairo_paint (test_cr);
+
+ cairo_destroy (test_cr);
+ cairo_surface_destroy (test_surface);
+
+ /* We erase the surface to black in case we get the same
+ * memory back again for the pixmap case.
+ */
+ erase_pattern (surface);
+ cairo_surface_destroy (surface);
+
+ if (use_pixmap)
+ XFreePixmap (dpy, drawable);
+ else
+ XDestroyWindow (dpy, drawable);
+
+ if (offscreen) {
+ size_t offset = 4 * (SIZE * OFFSCREEN_OFFSET + OFFSCREEN_OFFSET);
+
+ buffer_diff_noalpha (reference_data + offset,
+ test_data + offset,
+ diff_data + offset,
+ SIZE - OFFSCREEN_OFFSET,
+ SIZE - OFFSCREEN_OFFSET,
+ 4 * SIZE,
+ &result);
+ } else {
+ buffer_diff_noalpha (reference_data,
+ test_data,
+ diff_data,
+ SIZE,
+ SIZE,
+ 4 * SIZE,
+ &result);
+ }
+
+ cairo_test_log (ctx, "xlib-surface: %s, %s, %s: %s\n",
+ set_size ? " size" : "no-size",
+ use_pixmap ? "pixmap" : "window",
+ use_pixmap ? " " : (offscreen ? ", offscreen" : ", onscreen"),
+ image_diff_is_failure (&result, 0) ? "FAIL" : "PASS");
+
+ if (image_diff_is_failure (&result, 0))
+ return CAIRO_TEST_FAILURE;
+ else
+ return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_bool_t
+check_visual (Display *dpy)
+{
+ Visual *visual = DefaultVisual (dpy, DefaultScreen (dpy));
+
+ if ((visual->red_mask == 0xff0000 &&
+ visual->green_mask == 0x00ff00 &&
+ visual->blue_mask == 0x0000ff) ||
+ (visual->red_mask == 0x0000ff &&
+ visual->green_mask == 0x00ff00 &&
+ visual->blue_mask == 0xff0000))
+ return 1;
+ else
+ return 0;
+}
+
+#undef xcalloc
+static void *
+xcalloc (const cairo_test_context_t *ctx, size_t a, size_t b)
+{
+ void *ptr = calloc (a, b);
+ if (ptr == NULL) {
+ cairo_test_log (ctx, "xlib-surface: unable to allocate memory, skipping\n");
+ abort ();
+ }
+ return ptr;
+}
+
+static cairo_test_status_t
+preamble (cairo_test_context_t *ctx)
+{
+ Display *dpy;
+ unsigned char *reference_data;
+ unsigned char *test_data;
+ unsigned char *diff_data;
+ cairo_surface_t *reference_surface;
+ cairo_bool_t use_pixmap;
+ cairo_bool_t set_size;
+ cairo_bool_t offscreen;
+ cairo_test_status_t status, result = CAIRO_TEST_UNTESTED;
+ int stride;
+
+ if (! cairo_test_is_target_enabled (ctx, "xlib"))
+ goto CLEANUP_TEST;
+
+ dpy = XOpenDisplay (NULL);
+ if (!dpy) {
+ cairo_test_log (ctx, "xlib-surface: Cannot open display, skipping\n");
+ goto CLEANUP_TEST;
+ }
+
+ if (!check_visual (dpy)) {
+ cairo_test_log (ctx, "xlib-surface: default visual is not RGB24 or BGR24, skipping\n");
+ goto CLEANUP_DISPLAY;
+ }
+
+ stride = cairo_format_stride_for_width (CAIRO_FORMAT_RGB24, SIZE);
+
+ reference_data = xcalloc (ctx, SIZE, stride);
+ test_data = xcalloc (ctx, SIZE, stride);
+ diff_data = xcalloc (ctx, SIZE, stride);
+
+ reference_surface = cairo_image_surface_create_for_data (reference_data,
+ CAIRO_FORMAT_RGB24,
+ SIZE, SIZE,
+ stride);
+
+ draw_pattern (reference_surface);
+ cairo_surface_destroy (reference_surface);
+
+ result = CAIRO_TEST_SUCCESS;
+
+ for (set_size = 0; set_size <= 1; set_size++)
+ for (use_pixmap = 0; use_pixmap <= 1; use_pixmap++)
+ for (offscreen = 0; offscreen <= 1; offscreen++) {
+ status = do_test (ctx, dpy,
+ reference_data, test_data, diff_data,
+ use_pixmap, set_size, offscreen);
+ if (status)
+ result = status;
+ }
+
+ free (reference_data);
+ free (test_data);
+ free (diff_data);
+
+ CLEANUP_DISPLAY:
+ XCloseDisplay (dpy);
+
+ CLEANUP_TEST:
+ return result;
+}
+
+CAIRO_TEST (xlib_surface,
+ "Check creating surfaces for various XWindows",
+ "xlib", /* keywords */
+ NULL, /* requirements */
+ 0, 0,
+ preamble, NULL)
diff --git a/test/zero-alpha.c b/test/zero-alpha.c
new file mode 100644
index 000000000..0105cc8e6
--- /dev/null
+++ b/test/zero-alpha.c
@@ -0,0 +1,95 @@
+/*
+ * Copyright © 2006 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+#include "cairo-test.h"
+
+#define SIZE 3
+#define REPS 10
+
+/* History:
+ *
+ * 2006-06-13 Paul Giblock reports a "Stange alpha channel problem" on
+ * the cairo mailing list.
+ *
+ * 2006-06-13 Carl Worth writes this test in an attempt to reproduce
+ * the problem. The test first fills in a 3x3 rectangle with red, then
+ * starts pounding on that center pixel with various forms of
+ * zero-alpha rendering to see if its value can ever be made to
+ * change.
+ *
+ * 2006-06-13 Paul Giblock reports that this only happens with the
+ * xlib backend, and then only on some systems.
+ */
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ int i;
+ cairo_surface_t *surface;
+ uint32_t zero = 0;
+
+ /* First paint background red. */
+ cairo_set_source_rgb (cr, 1.0, 0.0, 0.0); /* red */
+ cairo_paint (cr);
+
+ /* Then we paint zero-alpha in several ways (always REPS times): */
+
+ /* 1. fill a rectangle with a zero-alpha solid source. */
+ cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 0.0); /* transparent */
+ cairo_rectangle (cr, 1.0, 1.0, 1.0, 1.0);
+ for (i=0; i < REPS; i++)
+ cairo_fill_preserve (cr);
+ cairo_new_path (cr);
+
+ /* 2. paint with a zero-alpha image surface source. */
+ surface = cairo_image_surface_create_for_data ((unsigned char *) &zero,
+ CAIRO_FORMAT_ARGB32, 1, 1, 4);
+ cairo_set_source_surface (cr, surface, 1, 1);
+ for (i=0; i < REPS; i++)
+ cairo_paint (cr);
+
+ /* 3. clip to rectangle then paint with zero-alpha solid source. */
+ cairo_rectangle (cr, 1.0, 1.0, 1.0, 1.0);
+ cairo_clip (cr);
+ cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 0.0); /* transparent */
+ for (i=0; i < REPS; i++)
+ cairo_paint (cr);
+
+ /* 4. With the clip still there, paint our image surface. */
+ cairo_set_source_surface (cr, surface, 1, 1);
+ for (i=0; i < REPS; i++)
+ cairo_paint (cr);
+
+ cairo_surface_finish (surface); /* zero will go out of scope */
+ cairo_surface_destroy (surface);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (zero_alpha,
+ "Testing that drawing with zero alpha has no effect",
+ "alpha", /* keywords */
+ NULL, /* requirements */
+ SIZE, SIZE,
+ NULL, draw)
diff --git a/test/zero-mask.c b/test/zero-mask.c
new file mode 100644
index 000000000..3d2f34d0e
--- /dev/null
+++ b/test/zero-mask.c
@@ -0,0 +1,198 @@
+/*
+ * Copyright © 2010 Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Benjamin Otte <otte@gnome.org>
+ */
+
+#include "cairo-test.h"
+
+#define RECT 10
+#define SPACE 5
+
+static void
+paint_with_alpha (cairo_t *cr)
+{
+ cairo_paint_with_alpha (cr, 0.0);
+}
+
+static void
+mask_with_solid (cairo_t *cr)
+{
+ cairo_pattern_t *pattern = cairo_pattern_create_rgba (1, 0, 0, 0);
+
+ cairo_mask (cr, pattern);
+
+ cairo_pattern_destroy (pattern);
+}
+
+static void
+mask_with_empty_gradient (cairo_t *cr)
+{
+ cairo_pattern_t *pattern = cairo_pattern_create_linear (1, 2, 3, 4);
+
+ cairo_mask (cr, pattern);
+
+ cairo_pattern_destroy (pattern);
+}
+
+static void
+mask_with_gradient (cairo_t *cr)
+{
+ cairo_pattern_t *pattern = cairo_pattern_create_radial (1, 2, 3, 4, 5, 6);
+
+ cairo_pattern_add_color_stop_rgba (pattern, 0, 1, 0, 0, 0);
+ cairo_pattern_add_color_stop_rgba (pattern, 0, 0, 0, 1, 0);
+
+ cairo_mask (cr, pattern);
+
+ cairo_pattern_destroy (pattern);
+}
+
+static void
+mask_with_surface (cairo_t *cr)
+{
+ cairo_surface_t *surface = cairo_surface_create_similar (cairo_get_target (cr),
+ CAIRO_CONTENT_COLOR_ALPHA,
+ RECT,
+ RECT);
+
+ cairo_mask_surface (cr, surface, 0, 0);
+
+ cairo_surface_destroy (surface);
+}
+
+static void
+mask_with_alpha_surface (cairo_t *cr)
+{
+ cairo_surface_t *surface = cairo_surface_create_similar (cairo_get_target (cr),
+ CAIRO_CONTENT_ALPHA,
+ RECT / 2,
+ RECT / 2);
+ cairo_pattern_t *pattern = cairo_pattern_create_for_surface (surface);
+ cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REFLECT);
+
+ cairo_mask (cr, pattern);
+
+ cairo_pattern_destroy (pattern);
+ cairo_surface_destroy (surface);
+}
+
+static void
+mask_with_nonclear_surface (cairo_t *cr)
+{
+ static unsigned char data[8 * 4] = { 0, };
+ cairo_surface_t *surface = cairo_image_surface_create_for_data (data,
+ CAIRO_FORMAT_A1,
+ 16, 8, 4);
+
+ cairo_mask_surface (cr, surface, 0, 0);
+
+ cairo_surface_destroy (surface);
+}
+
+static void
+mask_with_0x0_surface (cairo_t *cr)
+{
+ cairo_surface_t *surface = cairo_surface_create_similar (cairo_get_target (cr),
+ CAIRO_CONTENT_COLOR_ALPHA,
+ 0, 0);
+
+ cairo_mask_surface (cr, surface, 0, 0);
+
+ cairo_surface_destroy (surface);
+}
+
+static void
+mask_with_extend_none (cairo_t *cr)
+{
+ cairo_surface_t *surface = cairo_surface_create_similar (cairo_get_target (cr),
+ CAIRO_CONTENT_COLOR_ALPHA,
+ RECT,
+ RECT);
+
+ cairo_mask_surface (cr, surface, 2 * RECT, 2 * RECT);
+
+ cairo_surface_destroy (surface);
+}
+
+typedef void (* mask_func_t) (cairo_t *);
+
+static mask_func_t mask_funcs[] = {
+ paint_with_alpha,
+ mask_with_solid,
+ mask_with_empty_gradient,
+ mask_with_gradient,
+ mask_with_surface,
+ mask_with_alpha_surface,
+ mask_with_nonclear_surface,
+ mask_with_0x0_surface,
+ mask_with_extend_none
+};
+
+static cairo_operator_t operators[] = {
+ CAIRO_OPERATOR_CLEAR,
+ CAIRO_OPERATOR_SOURCE,
+ CAIRO_OPERATOR_OVER,
+ CAIRO_OPERATOR_IN,
+ CAIRO_OPERATOR_DEST_ATOP,
+ CAIRO_OPERATOR_SATURATE,
+ CAIRO_OPERATOR_MULTIPLY
+};
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ unsigned int i, op;
+
+ /* 565-compatible gray background */
+ cairo_set_source_rgb (cr, 0.51613, 0.55555, 0.51613);
+ cairo_paint (cr);
+
+ cairo_set_source_rgb (cr, 0.0, 1.0, 0.0); /* green */
+ /* mask with zero-alpha in several ways */
+
+ cairo_translate (cr, SPACE, SPACE);
+
+ for (op = 0; op < ARRAY_LENGTH (operators); op++) {
+ cairo_set_operator (cr, operators[op]);
+
+ for (i = 0; i < ARRAY_LENGTH (mask_funcs); i++) {
+ cairo_save (cr);
+ cairo_translate (cr, i * (RECT + SPACE), op * (RECT + SPACE));
+ cairo_rectangle (cr, 0, 0, RECT, RECT);
+ cairo_clip (cr);
+ mask_funcs[i] (cr);
+ cairo_restore (cr);
+ }
+ }
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (zero_mask,
+ "Testing that masking with zero alpha works",
+ "alpha, mask", /* keywords */
+ NULL, /* requirements */
+ SPACE + (RECT + SPACE) * ARRAY_LENGTH (mask_funcs),
+ SPACE + (RECT + SPACE) * ARRAY_LENGTH (operators),
+ NULL, draw)
diff --git a/util/.gitignore b/util/.gitignore
index 9a28da1b9..9a28da1b9 100755..100644
--- a/util/.gitignore
+++ b/util/.gitignore
diff --git a/util/COPYING b/util/COPYING
index ea44bb6f5..ea44bb6f5 100755..100644
--- a/util/COPYING
+++ b/util/COPYING
diff --git a/util/Makefile.am b/util/Makefile.am
index ee8cf87f3..82d0a804c 100755..100644
--- a/util/Makefile.am
+++ b/util/Makefile.am
@@ -11,9 +11,11 @@ SUBDIRS += cairo-script
endif
if CAIRO_HAS_TRACE
+SUBDIRS += cairo-trace
if CAIRO_HAS_DLSYM
if CAIRO_HAS_SCRIPT_SURFACE
if CAIRO_HAS_TEE_SURFACE
+SUBDIRS += cairo-fdr
endif
endif
endif
@@ -23,6 +25,7 @@ if BUILD_SPHINX
if CAIRO_HAS_DLSYM
if CAIRO_HAS_SCRIPT_SURFACE
if CAIRO_HAS_TEE_SURFACE
+SUBDIRS += cairo-sphinx
endif
endif
endif
diff --git a/util/README b/util/README
index 39560a8c3..39560a8c3 100755..100644
--- a/util/README
+++ b/util/README
diff --git a/util/backtrace-symbols.c b/util/backtrace-symbols.c
new file mode 100644
index 000000000..045ad7805
--- /dev/null
+++ b/util/backtrace-symbols.c
@@ -0,0 +1,377 @@
+/*
+ A hacky replacement for backtrace_symbols in glibc
+
+ backtrace_symbols in glibc looks up symbols using dladdr which is limited in
+ the symbols that it sees. libbacktracesymbols opens the executable and shared
+ libraries using libbfd and will look up backtrace information using the symbol
+ table and the dwarf line information.
+
+ It may make more sense for this program to use libelf instead of libbfd.
+ However, I have not investigated that yet.
+
+ Derived from addr2line.c from GNU Binutils by Jeff Muizelaar
+
+ Copyright 2007 Jeff Muizelaar
+*/
+
+/* addr2line.c -- convert addresses to line number and function name
+ Copyright 1997, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ Contributed by Ulrich Lauther <Ulrich.Lauther@mchp.siemens.de>
+
+ This file was part of GNU Binutils.
+
+ 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 2, 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, write to the Free Software
+ Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. */
+
+#define fatal(a, b) exit(1)
+#define bfd_fatal(a) exit(1)
+#define bfd_nonfatal(a) exit(1)
+#define list_matching_formats(a) exit(1)
+
+/* 2 characters for each byte, plus 1 each for 0, x, and NULL */
+#define PTRSTR_LEN (sizeof(void *) * 2 + 3)
+#define true 1
+#define false 0
+
+#define _GNU_SOURCE
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <execinfo.h>
+#include <bfd.h>
+#include <libiberty.h>
+#include <dlfcn.h>
+#include <link.h>
+#if 0
+
+void (*dbfd_init)(void);
+bfd_vma (*dbfd_scan_vma)(const char *string, const char **end, int base);
+bfd* (*dbfd_openr)(const char *filename, const char *target);
+bfd_boolean (*dbfd_check_format)(bfd *abfd, bfd_format format);
+bfd_boolean (*dbfd_check_format_matches)(bfd *abfd, bfd_format format, char ***matching);
+bfd_boolean (*dbfd_close)(bfd *abfd);
+bfd_boolean (*dbfd_map_over_sections)(bfd *abfd, void (*func)(bfd *abfd, asection *sect, void *obj),
+ void *obj);
+#define bfd_init dbfd_init
+
+static void load_funcs(void)
+{
+ void * handle = dlopen("libbfd.so", RTLD_NOW);
+ dbfd_init = dlsym(handle, "bfd_init");
+ dbfd_scan_vma = dlsym(handle, "bfd_scan_vma");
+ dbfd_openr = dlsym(handle, "bfd_openr");
+ dbfd_check_format = dlsym(handle, "bfd_check_format");
+ dbfd_check_format_matches = dlsym(handle, "bfd_check_format_matches");
+ dbfd_close = dlsym(handle, "bfd_close");
+ dbfd_map_over_sections = dlsym(handle, "bfd_map_over_sections");
+}
+
+#endif
+
+
+static asymbol **syms; /* Symbol table. */
+
+/* 150 isn't special; it's just an arbitrary non-ASCII char value. */
+#define OPTION_DEMANGLER (150)
+
+static void slurp_symtab(bfd * abfd);
+static void find_address_in_section(bfd *abfd, asection *section, void *data);
+
+/* Read in the symbol table. */
+
+static void slurp_symtab(bfd * abfd)
+{
+ long symcount;
+ unsigned int size;
+
+ if ((bfd_get_file_flags(abfd) & HAS_SYMS) == 0)
+ return;
+
+ symcount = bfd_read_minisymbols(abfd, false, (PTR) & syms, &size);
+ if (symcount == 0)
+ symcount = bfd_read_minisymbols(abfd, true /* dynamic */ ,
+ (PTR) & syms, &size);
+
+ if (symcount < 0)
+ bfd_fatal(bfd_get_filename(abfd));
+}
+
+/* These global variables are used to pass information between
+ translate_addresses and find_address_in_section. */
+
+static bfd_vma pc;
+static const char *filename;
+static const char *functionname;
+static unsigned int line;
+static int found;
+
+/* Look for an address in a section. This is called via
+ bfd_map_over_sections. */
+
+static void find_address_in_section(bfd *abfd, asection *section, void *data __attribute__ ((__unused__)) )
+{
+ bfd_vma vma;
+ bfd_size_type size;
+
+ if (found)
+ return;
+
+ if ((bfd_get_section_flags(abfd, section) & SEC_ALLOC) == 0)
+ return;
+
+ vma = bfd_get_section_vma(abfd, section);
+ if (pc < vma)
+ return;
+
+ size = bfd_section_size(abfd, section);
+ if (pc >= vma + size)
+ return;
+
+ found = bfd_find_nearest_line(abfd, section, syms, pc - vma,
+ &filename, &functionname, &line);
+}
+
+/* Read hexadecimal addresses from stdin, translate into
+ file_name:line_number and optionally function name. */
+#if 0
+static void translate_addresses(bfd * abfd, char (*addr)[PTRSTR_LEN], int naddr)
+{
+ while (naddr) {
+ pc = bfd_scan_vma(addr[naddr-1], NULL, 16);
+
+ found = false;
+ bfd_map_over_sections(abfd, find_address_in_section,
+ (PTR) NULL);
+
+ if (!found) {
+ printf("[%s] \?\?() \?\?:0\n",addr[naddr-1]);
+ } else {
+ const char *name;
+
+ name = functionname;
+ if (name == NULL || *name == '\0')
+ name = "??";
+ if (filename != NULL) {
+ char *h;
+
+ h = strrchr(filename, '/');
+ if (h != NULL)
+ filename = h + 1;
+ }
+
+ printf("\t%s:%u\t", filename ? filename : "??",
+ line);
+
+ printf("%s()\n", name);
+
+ }
+
+ /* fflush() is essential for using this command as a server
+ child process that reads addresses from a pipe and responds
+ with line number information, processing one address at a
+ time. */
+ fflush(stdout);
+ naddr--;
+ }
+}
+#endif
+
+static char** translate_addresses_buf(bfd * abfd, bfd_vma *addr, int naddr)
+{
+ int naddr_orig = naddr;
+ char b;
+ int total = 0;
+ enum { Count, Print } state;
+ char *buf = &b;
+ int len = 0;
+ char **ret_buf = NULL;
+ /* iterate over the formating twice.
+ * the first time we count how much space we need
+ * the second time we do the actual printing */
+ for (state=Count; state<=Print; state++) {
+ if (state == Print) {
+ ret_buf = malloc(total + sizeof(char*)*naddr);
+ buf = (char*)(ret_buf + naddr);
+ len = total;
+ }
+ while (naddr) {
+ if (state == Print)
+ ret_buf[naddr-1] = buf;
+ pc = addr[naddr-1];
+
+ found = false;
+ bfd_map_over_sections(abfd, find_address_in_section,
+ (PTR) NULL);
+
+ if (!found) {
+ total += snprintf(buf, len, "[0x%llx] \?\?() \?\?:0",(long long unsigned int) addr[naddr-1]) + 1;
+ } else {
+ const char *name;
+
+ name = functionname;
+ if (name == NULL || *name == '\0')
+ name = "??";
+ if (filename != NULL) {
+ char *h;
+
+ h = strrchr(filename, '/');
+ if (h != NULL)
+ filename = h + 1;
+ }
+ total += snprintf(buf, len, "%s:%u\t%s()", filename ? filename : "??",
+ line, name) + 1;
+
+ }
+ if (state == Print) {
+ /* set buf just past the end of string */
+ buf = buf + total + 1;
+ }
+ naddr--;
+ }
+ naddr = naddr_orig;
+ }
+ return ret_buf;
+}
+/* Process a file. */
+
+static char **process_file(const char *file_name, bfd_vma *addr, int naddr)
+{
+ bfd *abfd;
+ char **matching;
+ char **ret_buf;
+
+ abfd = bfd_openr(file_name, NULL);
+
+ if (abfd == NULL)
+ bfd_fatal(file_name);
+
+ if (bfd_check_format(abfd, bfd_archive))
+ fatal("%s: can not get addresses from archive", file_name);
+
+ if (!bfd_check_format_matches(abfd, bfd_object, &matching)) {
+ bfd_nonfatal(bfd_get_filename(abfd));
+ if (bfd_get_error() ==
+ bfd_error_file_ambiguously_recognized) {
+ list_matching_formats(matching);
+ free(matching);
+ }
+ xexit(1);
+ }
+
+ slurp_symtab(abfd);
+
+ ret_buf = translate_addresses_buf(abfd, addr, naddr);
+
+ free (syms);
+ syms = NULL;
+
+ bfd_close(abfd);
+ return ret_buf;
+}
+
+#define MAX_DEPTH 16
+
+struct file_match {
+ const char *file;
+ void *address;
+ void *base;
+ void *hdr;
+};
+
+static int find_matching_file(struct dl_phdr_info *info,
+ size_t size, void *data)
+{
+ struct file_match *match = data;
+ /* This code is modeled from Gfind_proc_info-lsb.c:callback() from libunwind */
+ long n;
+ const ElfW(Phdr) *phdr;
+ ElfW(Addr) load_base = info->dlpi_addr;
+ phdr = info->dlpi_phdr;
+ for (n = info->dlpi_phnum; --n >= 0; phdr++) {
+ if (phdr->p_type == PT_LOAD) {
+ ElfW(Addr) vaddr = phdr->p_vaddr + load_base;
+ if (match->address >= vaddr && match->address < vaddr + phdr->p_memsz) {
+ /* we found a match */
+ match->file = info->dlpi_name;
+ match->base = info->dlpi_addr;
+ }
+ }
+ }
+ return 0;
+}
+
+char **backtrace_symbols(void *const *buffer, int size)
+{
+ int stack_depth = size - 1;
+ int x,y;
+ /* discard calling function */
+ int total = 0;
+
+ char ***locations;
+ char **final;
+ char *f_strings;
+
+ locations = malloc(sizeof(char**) * (stack_depth+1));
+
+ bfd_init();
+ for(x=stack_depth, y=0; x>=0; x--, y++){
+ struct file_match match = { .address = buffer[x] };
+ char **ret_buf;
+ bfd_vma addr;
+ dl_iterate_phdr(find_matching_file, &match);
+ addr = buffer[x] - match.base;
+ if (match.file && strlen(match.file))
+ ret_buf = process_file(match.file, &addr, 1);
+ else
+ ret_buf = process_file("/proc/self/exe", &addr, 1);
+ locations[x] = ret_buf;
+ total += strlen(ret_buf[0]) + 1;
+ }
+
+ /* allocate the array of char* we are going to return and extra space for
+ * all of the strings */
+ final = malloc(total + (stack_depth + 1) * sizeof(char*));
+ /* get a pointer to the extra space */
+ f_strings = (char*)(final + stack_depth + 1);
+
+ /* fill in all of strings and pointers */
+ for(x=stack_depth; x>=0; x--){
+ strcpy(f_strings, locations[x][0]);
+ free(locations[x]);
+ final[x] = f_strings;
+ f_strings += strlen(f_strings) + 1;
+ }
+
+ free(locations);
+
+ return final;
+}
+
+void
+backtrace_symbols_fd(void *const *buffer, int size, int fd)
+{
+ int j;
+ char **strings;
+
+ strings = backtrace_symbols(buffer, size);
+ if (strings == NULL) {
+ perror("backtrace_symbols");
+ exit(EXIT_FAILURE);
+ }
+
+ for (j = 0; j < size; j++)
+ printf("%s\n", strings[j]);
+
+ free(strings);
+}
diff --git a/util/cairo-fdr/Makefile.am b/util/cairo-fdr/Makefile.am
new file mode 100644
index 000000000..34215a659
--- /dev/null
+++ b/util/cairo-fdr/Makefile.am
@@ -0,0 +1,15 @@
+cairolibdir = $(libdir)/cairo
+
+#bin_SCRIPTS = cairo-fdr
+cairolib_LTLIBRARIES = cairo-fdr.la
+
+AM_CPPFLAGS = -I$(top_srcdir)/src \
+ -I$(top_builddir)/src
+
+cairo_fdr_la_SOURCES = fdr.c
+cairo_fdr_la_CPPFLAGS = $(AM_CPPFLAGS)
+cairo_fdr_la_CFLAGS = $(CAIRO_CFLAGS)
+cairo_fdr_la_LDFLAGS = -module -no-undefined
+if CAIRO_HAS_DL
+cairo_fdr_la_LIBADD = -ldl
+endif
diff --git a/util/cairo-fdr/fdr.c b/util/cairo-fdr/fdr.c
new file mode 100644
index 000000000..08d9c0113
--- /dev/null
+++ b/util/cairo-fdr/fdr.c
@@ -0,0 +1,331 @@
+/* cairo-fdr - a 'flight data recorder', a black box, for cairo
+ *
+ * Copyright © 2009 Chris Wilson
+ *
+ * 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/>.
+ */
+
+#define _GNU_SOURCE
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <cairo.h>
+#include <cairo-script.h>
+#include <cairo-tee.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <signal.h>
+
+#include <dlfcn.h>
+
+static void *_dlhandle = RTLD_NEXT;
+#define DLCALL(name, args...) ({ \
+ static typeof (&name) name##_real; \
+ if (name##_real == NULL) { \
+ name##_real = dlsym (_dlhandle, #name); \
+ if (name##_real == NULL && _dlhandle == RTLD_NEXT) { \
+ _dlhandle = dlopen ("libcairo.so", RTLD_LAZY); \
+ name##_real = dlsym (_dlhandle, #name); \
+ assert (name##_real != NULL); \
+ } \
+ } \
+ (*name##_real) (args); \
+})
+
+#define RINGBUFFER_SIZE 16
+static cairo_surface_t *fdr_ringbuffer[RINGBUFFER_SIZE];
+static int fdr_position;
+static int fdr_dump;
+
+static const cairo_user_data_key_t fdr_key;
+
+static void
+fdr_replay_to_script (cairo_surface_t *recording, cairo_device_t *ctx)
+{
+ if (recording != NULL) {
+ DLCALL (cairo_script_write_comment, ctx, "--- fdr ---", -1);
+ DLCALL (cairo_script_from_recording_surface, ctx, recording);
+ }
+}
+
+static void
+fdr_dump_ringbuffer (void)
+{
+ cairo_device_t *ctx;
+ int n;
+
+ ctx = DLCALL (cairo_script_create, "/tmp/fdr.trace");
+
+ for (n = fdr_position; n < RINGBUFFER_SIZE; n++)
+ fdr_replay_to_script (fdr_ringbuffer[n], ctx);
+
+ for (n = 0; n < fdr_position; n++)
+ fdr_replay_to_script (fdr_ringbuffer[n], ctx);
+
+ DLCALL (cairo_device_destroy, ctx);
+}
+
+static void
+fdr_sighandler (int sig)
+{
+ fdr_dump = 1;
+}
+
+static void
+fdr_urgent_sighandler (int sig)
+{
+ fdr_dump_ringbuffer ();
+}
+
+static void
+fdr_atexit (void)
+{
+ if (fdr_dump)
+ fdr_dump_ringbuffer ();
+}
+
+static void
+fdr_pending_signals (void)
+{
+ static int initialized;
+
+ if (! initialized) {
+ initialized = 1;
+
+ signal (SIGUSR1, fdr_sighandler);
+
+ signal (SIGSEGV, fdr_urgent_sighandler);
+ signal (SIGABRT, fdr_urgent_sighandler);
+ atexit (fdr_atexit);
+ }
+
+ if (fdr_dump) {
+ fdr_dump_ringbuffer ();
+ fdr_dump = 0;
+ }
+}
+
+static void
+fdr_get_extents (cairo_surface_t *surface,
+ cairo_rectangle_t *extents)
+{
+ cairo_t *cr;
+
+ cr = DLCALL (cairo_create, surface);
+ DLCALL (cairo_clip_extents, cr,
+ &extents->x, &extents->y, &extents->width, &extents->height);
+ DLCALL (cairo_destroy, cr);
+
+ extents->width -= extents->x;
+ extents->height -= extents->y;
+}
+
+static void
+fdr_surface_destroy (void *surface)
+{
+ DLCALL (cairo_surface_destroy, surface);
+}
+
+static void
+fdr_surface_reference (void *surface)
+{
+ DLCALL (cairo_surface_reference, surface);
+}
+
+static cairo_surface_t *
+fdr_surface_get_tee (cairo_surface_t *surface)
+{
+ return DLCALL (cairo_surface_get_user_data, surface, &fdr_key);
+}
+
+static cairo_surface_t *
+fdr_tee_surface_index (cairo_surface_t *surface, int index)
+{
+ return DLCALL (cairo_tee_surface_index, surface, index);
+}
+
+cairo_t *
+cairo_create (cairo_surface_t *surface)
+{
+ cairo_surface_t *record, *tee;
+
+ fdr_pending_signals ();
+
+ tee = fdr_surface_get_tee (surface);
+ if (tee == NULL) {
+ cairo_rectangle_t extents;
+ cairo_content_t content;
+
+ fdr_get_extents (surface, &extents);
+ content = DLCALL (cairo_surface_get_content, surface);
+
+ tee = DLCALL (cairo_tee_surface_create, surface);
+ record = DLCALL (cairo_recording_surface_create, content, &extents);
+ DLCALL (cairo_tee_surface_add, tee, record);
+
+ DLCALL (cairo_surface_set_user_data, surface,
+ &fdr_key, tee, fdr_surface_destroy);
+ } else {
+ int n;
+
+ record = fdr_tee_surface_index (tee, 1);
+
+ /* update the position of the recording surface in the ringbuffer */
+ for (n = 0; n < RINGBUFFER_SIZE; n++) {
+ if (record == fdr_ringbuffer[n]) {
+ fdr_ringbuffer[n] = NULL;
+ break;
+ }
+ }
+ }
+
+ fdr_surface_destroy (fdr_ringbuffer[fdr_position]);
+ fdr_ringbuffer[fdr_position] = record;
+ fdr_position = (fdr_position + 1) % RINGBUFFER_SIZE;
+
+ return DLCALL (cairo_create, tee);
+}
+
+static void
+fdr_remove_tee (cairo_surface_t *surface)
+{
+ fdr_surface_reference (surface);
+ DLCALL (cairo_surface_set_user_data, surface, &fdr_key, NULL, NULL);
+ fdr_surface_destroy (surface);
+}
+
+void
+cairo_destroy (cairo_t *cr)
+{
+ cairo_surface_t *tee;
+
+ tee = DLCALL (cairo_get_target, cr);
+ DLCALL (cairo_destroy, cr);
+
+ if (DLCALL (cairo_surface_get_reference_count, tee) == 1)
+ fdr_remove_tee (fdr_tee_surface_index (tee, 0));
+}
+
+void
+cairo_pattern_destroy (cairo_pattern_t *pattern)
+{
+ if (DLCALL (cairo_pattern_get_type, pattern) == CAIRO_PATTERN_TYPE_SURFACE) {
+ cairo_surface_t *surface;
+
+ if (DLCALL (cairo_pattern_get_surface, pattern, &surface) == CAIRO_STATUS_SUCCESS &&
+ DLCALL (cairo_surface_get_type, surface) == CAIRO_SURFACE_TYPE_TEE &&
+ DLCALL (cairo_surface_get_reference_count, surface) == 2)
+ {
+ fdr_remove_tee (fdr_tee_surface_index (surface, 0));
+ }
+ }
+
+ DLCALL (cairo_pattern_destroy, pattern);
+}
+
+cairo_surface_t *
+cairo_get_target (cairo_t *cr)
+{
+ cairo_surface_t *tee;
+
+ tee = DLCALL (cairo_get_target, cr);
+ return fdr_tee_surface_index (tee, 0);
+}
+
+cairo_surface_t *
+cairo_get_group_target (cairo_t *cr)
+{
+ cairo_surface_t *tee;
+
+ tee = DLCALL (cairo_get_group_target, cr);
+ return fdr_tee_surface_index (tee, 0);
+}
+
+cairo_pattern_t *
+cairo_pattern_create_for_surface (cairo_surface_t *surface)
+{
+ cairo_surface_t *tee;
+
+ tee = fdr_surface_get_tee (surface);
+ if (tee != NULL)
+ surface = tee;
+
+ return DLCALL (cairo_pattern_create_for_surface, surface);
+}
+
+cairo_status_t
+cairo_pattern_get_surface (cairo_pattern_t *pattern,
+ cairo_surface_t **surface)
+{
+ cairo_status_t status;
+ cairo_surface_t *tee;
+
+ status = DLCALL (cairo_pattern_get_surface, pattern, surface);
+ if (status != CAIRO_STATUS_SUCCESS)
+ return status;
+
+ tee = fdr_surface_get_tee (*surface);
+ if (tee != NULL)
+ *surface = tee;
+
+ return CAIRO_STATUS_SUCCESS;
+}
+
+void
+cairo_set_source_surface (cairo_t *cr,
+ cairo_surface_t *surface,
+ double x, double y)
+{
+ cairo_surface_t *tee;
+
+ tee = fdr_surface_get_tee (surface);
+ if (tee != NULL)
+ surface = tee;
+
+ DLCALL (cairo_set_source_surface, cr, surface, x, y);
+}
+
+cairo_surface_t *
+cairo_surface_create_similar (cairo_surface_t *surface,
+ cairo_content_t content,
+ int width, int height)
+{
+ cairo_surface_t *tee;
+
+ tee = fdr_surface_get_tee (surface);
+ if (tee != NULL)
+ surface = tee;
+
+ return DLCALL (cairo_surface_create_similar,
+ surface, content, width, height);
+}
+
+cairo_surface_t *
+cairo_surface_create_for_rectangle (cairo_surface_t *surface,
+ double x,
+ double y,
+ double width,
+ double height)
+{
+ cairo_surface_t *tee;
+
+ tee = fdr_surface_get_tee (surface);
+ if (tee != NULL)
+ surface = tee;
+
+ return DLCALL (cairo_surface_create_for_rectangle,
+ surface, x, y, width, height);
+}
diff --git a/util/cairo-gobject/Makefile.am b/util/cairo-gobject/Makefile.am
index 22c1a278a..22c1a278a 100755..100644
--- a/util/cairo-gobject/Makefile.am
+++ b/util/cairo-gobject/Makefile.am
diff --git a/util/cairo-gobject/cairo-gobject-enums.c b/util/cairo-gobject/cairo-gobject-enums.c
index 0a7c95d29..0a7c95d29 100755..100644
--- a/util/cairo-gobject/cairo-gobject-enums.c
+++ b/util/cairo-gobject/cairo-gobject-enums.c
diff --git a/util/cairo-gobject/cairo-gobject-structs.c b/util/cairo-gobject/cairo-gobject-structs.c
index 05e3ece80..4bbf11baa 100755..100644
--- a/util/cairo-gobject/cairo-gobject-structs.c
+++ b/util/cairo-gobject/cairo-gobject-structs.c
@@ -78,10 +78,12 @@ cairo_gobject_cairo_ ## name ## _copy (gpointer src) \
return g_memdup (src, sizeof (cairo_ ## name ## _t)); \
}
+COPY_FUNC (matrix)
+CAIRO_DEFINE_BOXED ("CairoMatrix", cairo_gobject_matrix,
+ cairo_gobject_cairo_matrix_copy, g_free);
COPY_FUNC (rectangle)
CAIRO_DEFINE_BOXED ("CairoRectangle", cairo_gobject_rectangle,
cairo_gobject_cairo_rectangle_copy, g_free);
COPY_FUNC (rectangle_int)
CAIRO_DEFINE_BOXED ("CairoRectangleInt", cairo_gobject_rectangle_int,
cairo_gobject_cairo_rectangle_int_copy, g_free);
-
diff --git a/util/cairo-gobject/cairo-gobject.h b/util/cairo-gobject/cairo-gobject.h
index e82cbc0d1..459074e83 100755..100644
--- a/util/cairo-gobject/cairo-gobject.h
+++ b/util/cairo-gobject/cairo-gobject.h
@@ -55,6 +55,10 @@ cairo_gobject_context_get_type (void);
cairo_public GType
cairo_gobject_device_get_type (void);
+#define CAIRO_GOBJECT_TYPE_MATRIX cairo_gobject_matrix_get_type ()
+cairo_public GType
+cairo_gobject_matrix_get_type (void);
+
#define CAIRO_GOBJECT_TYPE_PATTERN cairo_gobject_pattern_get_type ()
cairo_public GType
cairo_gobject_pattern_get_type (void);
diff --git a/util/cairo-missing/Makefile.am b/util/cairo-missing/Makefile.am
index 907861026..907861026 100755..100644
--- a/util/cairo-missing/Makefile.am
+++ b/util/cairo-missing/Makefile.am
diff --git a/util/cairo-missing/Makefile.sources b/util/cairo-missing/Makefile.sources
index 1a306314a..1a306314a 100755..100644
--- a/util/cairo-missing/Makefile.sources
+++ b/util/cairo-missing/Makefile.sources
diff --git a/util/cairo-missing/Makefile.win32 b/util/cairo-missing/Makefile.win32
index c2c5bc01e..c2c5bc01e 100755..100644
--- a/util/cairo-missing/Makefile.win32
+++ b/util/cairo-missing/Makefile.win32
diff --git a/util/cairo-missing/cairo-missing.h b/util/cairo-missing/cairo-missing.h
index 7e4f0a37d..741b498a8 100755..100644
--- a/util/cairo-missing/cairo-missing.h
+++ b/util/cairo-missing/cairo-missing.h
@@ -41,7 +41,7 @@
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
-#ifndef _SSIZE_T_DEFINED
+#if !defined(_SSIZE_T_DEFINED) && !defined(_SSIZE_T_)
typedef SSIZE_T ssize_t;
#endif
#endif
diff --git a/util/cairo-missing/getline.c b/util/cairo-missing/getline.c
index 8585cfdc2..8585cfdc2 100755..100644
--- a/util/cairo-missing/getline.c
+++ b/util/cairo-missing/getline.c
diff --git a/util/cairo-missing/strndup.c b/util/cairo-missing/strndup.c
index 280ea3017..280ea3017 100755..100644
--- a/util/cairo-missing/strndup.c
+++ b/util/cairo-missing/strndup.c
diff --git a/util/cairo-script/.gitignore b/util/cairo-script/.gitignore
index 8ecaee3e5..8ecaee3e5 100755..100644
--- a/util/cairo-script/.gitignore
+++ b/util/cairo-script/.gitignore
diff --git a/util/cairo-script/COPYING b/util/cairo-script/COPYING
index 66ad7840f..66ad7840f 100755..100644
--- a/util/cairo-script/COPYING
+++ b/util/cairo-script/COPYING
diff --git a/util/cairo-script/Makefile.am b/util/cairo-script/Makefile.am
index d5c2998ac..d5c2998ac 100755..100644
--- a/util/cairo-script/Makefile.am
+++ b/util/cairo-script/Makefile.am
diff --git a/util/cairo-script/Makefile.sources b/util/cairo-script/Makefile.sources
index fd73a17cf..fd73a17cf 100755..100644
--- a/util/cairo-script/Makefile.sources
+++ b/util/cairo-script/Makefile.sources
diff --git a/util/cairo-script/Makefile.win32 b/util/cairo-script/Makefile.win32
index 0aef981c1..0aef981c1 100755..100644
--- a/util/cairo-script/Makefile.win32
+++ b/util/cairo-script/Makefile.win32
diff --git a/util/cairo-script/cairo-script-file.c b/util/cairo-script/cairo-script-file.c
index 85d292c47..0274a3e7c 100755..100644
--- a/util/cairo-script/cairo-script-file.c
+++ b/util/cairo-script/cairo-script-file.c
@@ -176,21 +176,21 @@ csi_file_new_from_string (csi_t *ctx,
status = _csi_error (CAIRO_STATUS_NO_MEMORY);
break;
-#if HAVE_ZLIB
case ZLIB:
+#if HAVE_ZLIB
if (uncompress ((Bytef *) tmp_str->string, &len,
(Bytef *) src->string, src->len) != Z_OK)
+#endif
status = _csi_error (CAIRO_STATUS_NO_MEMORY);
break;
-#endif
-#if HAVE_LZO
case LZO:
+#if HAVE_LZO
if (lzo2a_decompress ((lzo_bytep) src->string, src->len,
(lzo_bytep) tmp_str->string, &len,
NULL))
+#endif
status = _csi_error (CAIRO_STATUS_NO_MEMORY);
break;
-#endif
}
if (_csi_unlikely (status)) {
csi_string_free (ctx, tmp_str);
@@ -1063,7 +1063,6 @@ _csi_file_as_string (csi_t *ctx,
unsigned int allocated;
csi_status_t status;
- len = 0;
allocated = 16384;
bytes = _csi_alloc (ctx, allocated);
if (bytes == NULL)
diff --git a/util/cairo-script/cairo-script-hash.c b/util/cairo-script/cairo-script-hash.c
index 0a230e8d7..0a230e8d7 100755..100644
--- a/util/cairo-script/cairo-script-hash.c
+++ b/util/cairo-script/cairo-script-hash.c
diff --git a/util/cairo-script/cairo-script-interpreter.c b/util/cairo-script/cairo-script-interpreter.c
index bdd525542..50170fc29 100755..100644
--- a/util/cairo-script/cairo-script-interpreter.c
+++ b/util/cairo-script/cairo-script-interpreter.c
@@ -634,7 +634,7 @@ cairo_script_interpreter_finish (csi_t *ctx)
if (! ctx->finished) {
_csi_finish (ctx);
ctx->finished = 1;
- } else if (status == CAIRO_STATUS_SUCCESS) {
+ } else if (status == CSI_STATUS_SUCCESS) {
status = ctx->status = CSI_STATUS_INTERPRETER_FINISHED;
}
diff --git a/util/cairo-script/cairo-script-interpreter.h b/util/cairo-script/cairo-script-interpreter.h
index 27fb98661..27fb98661 100755..100644
--- a/util/cairo-script/cairo-script-interpreter.h
+++ b/util/cairo-script/cairo-script-interpreter.h
diff --git a/util/cairo-script/cairo-script-objects.c b/util/cairo-script/cairo-script-objects.c
index a625489b1..a625489b1 100755..100644
--- a/util/cairo-script/cairo-script-objects.c
+++ b/util/cairo-script/cairo-script-objects.c
diff --git a/util/cairo-script/cairo-script-operators.c b/util/cairo-script/cairo-script-operators.c
index b14579c4a..d7cd203f5 100755..100644
--- a/util/cairo-script/cairo-script-operators.c
+++ b/util/cairo-script/cairo-script-operators.c
@@ -1769,28 +1769,28 @@ inflate_string (csi_t *ctx, csi_string_t *src)
free (bytes);
return NULL;
-#if HAVE_ZLIB
case ZLIB:
+#if HAVE_ZLIB
if (uncompress ((Bytef *) bytes, &len,
(Bytef *) src->string, src->len) != Z_OK)
+#endif
{
_csi_free (ctx, bytes);
return NULL;
}
break;
-#endif
-#if HAVE_LZO
case LZO:
+#if HAVE_LZO
if (lzo2a_decompress ((Bytef *) src->string, src->len,
(Bytef *) bytes, &len,
NULL))
+#endif
{
_csi_free (ctx, bytes);
return NULL;
}
break;
-#endif
}
bytes[len] = '\0';
@@ -1949,6 +1949,18 @@ _ft_create_for_pattern (csi_t *ctx,
}
pattern = FcNameParse (bytes);
+ if (!pattern)
+ {
+ /* Fontconfig's representation of charset changed mid 2014;
+ * We used to record charset before that. Remove everything
+ * after charset if that's present, and try again. */
+ char *s = strstr ((char *) bytes, ":charset=");
+ if (s)
+ {
+ *s = '\0';
+ pattern = FcNameParse (bytes);
+ }
+ }
if (bytes != tmpl.bytes)
_csi_free (ctx, bytes);
@@ -2983,22 +2995,22 @@ err_decompress:
cairo_surface_destroy (image);
return _csi_error (CSI_STATUS_READ_ERROR);
-#if HAVE_ZLIB
case ZLIB:
+#if HAVE_ZLIB
if (uncompress ((Bytef *) data, &out,
(Bytef *) s->string, s->len) != Z_OK)
+#endif
goto err_decompress;
break;
-#endif
-#if HAVE_LZO
case LZO:
+#if HAVE_LZO
if (lzo2a_decompress ((Bytef *) s->string, s->len,
(Bytef *) data, &out,
NULL))
+#endif
goto err_decompress;
break;
-#endif
}
}
else
@@ -4866,6 +4878,30 @@ _set_device_offset (csi_t *ctx)
}
static csi_status_t
+_set_device_scale (csi_t *ctx)
+{
+ csi_status_t status;
+ cairo_surface_t *surface;
+ double x, y;
+
+ check (3);
+
+ status = _csi_ostack_get_number (ctx, 0, &y);
+ if (_csi_unlikely (status))
+ return status;
+ status = _csi_ostack_get_number (ctx, 1, &x);
+ if (_csi_unlikely (status))
+ return status;
+ status = _csi_ostack_get_surface (ctx, 2, &surface);
+ if (_csi_unlikely (status))
+ return status;
+
+ cairo_surface_set_device_scale (surface, x, y);
+ pop (2);
+ return CSI_STATUS_SUCCESS;
+}
+
+static csi_status_t
_set_extend (csi_t *ctx)
{
csi_status_t status;
@@ -6146,6 +6182,29 @@ _surface (csi_t *ctx)
}
}
+ status = csi_name_new_static (ctx, &key, "device-scale");
+ if (_csi_unlikely (status)) {
+ cairo_surface_destroy (surface);
+ return status;
+ }
+ if (csi_dictionary_has (dict, key.datum.name)) {
+ status = csi_dictionary_get (ctx, dict, key.datum.name, &obj);
+ if (_csi_unlikely (status))
+ return status;
+
+ if (csi_object_get_type (&obj) == CSI_OBJECT_TYPE_ARRAY) {
+ csi_array_t *array = obj.datum.array;
+
+ if (array->stack.len == 2) {
+ cairo_surface_set_device_scale (surface,
+ csi_number_get_value
+ (&array->stack.objects[0]),
+ csi_number_get_value
+ (&array->stack.objects[1]));
+ }
+ }
+ }
+
obj.type = CSI_OBJECT_TYPE_SURFACE;
obj.datum.surface = surface;
pop (1);
@@ -6582,6 +6641,7 @@ _defs[] = {
{ "set-antialias", _set_antialias },
{ "set-dash", _set_dash },
{ "set-device-offset", _set_device_offset },
+ { "set-device-scale", _set_device_scale },
{ "set-extend", _set_extend },
{ "set-fallback-resolution", _set_fallback_resolution },
{ "set-fill-rule", _set_fill_rule },
diff --git a/util/cairo-script/cairo-script-private.h b/util/cairo-script/cairo-script-private.h
index 6bf41b4e5..6bf41b4e5 100755..100644
--- a/util/cairo-script/cairo-script-private.h
+++ b/util/cairo-script/cairo-script-private.h
diff --git a/util/cairo-script/cairo-script-scanner.c b/util/cairo-script/cairo-script-scanner.c
index b9d445bb3..b9d445bb3 100755..100644
--- a/util/cairo-script/cairo-script-scanner.c
+++ b/util/cairo-script/cairo-script-scanner.c
diff --git a/util/cairo-script/cairo-script-stack.c b/util/cairo-script/cairo-script-stack.c
index b1d146c52..b1d146c52 100755..100644
--- a/util/cairo-script/cairo-script-stack.c
+++ b/util/cairo-script/cairo-script-stack.c
diff --git a/util/cairo-script/csi-bind.c b/util/cairo-script/csi-bind.c
index 91b58fb95..91b58fb95 100755..100644
--- a/util/cairo-script/csi-bind.c
+++ b/util/cairo-script/csi-bind.c
diff --git a/util/cairo-script/csi-exec.c b/util/cairo-script/csi-exec.c
index d30b1c9c8..d30b1c9c8 100755..100644
--- a/util/cairo-script/csi-exec.c
+++ b/util/cairo-script/csi-exec.c
diff --git a/util/cairo-script/csi-replay.c b/util/cairo-script/csi-replay.c
index 67fed3b33..67fed3b33 100755..100644
--- a/util/cairo-script/csi-replay.c
+++ b/util/cairo-script/csi-replay.c
diff --git a/util/cairo-script/csi-trace.c b/util/cairo-script/csi-trace.c
index c57a56b18..a0466a35b 100755..100644
--- a/util/cairo-script/csi-trace.c
+++ b/util/cairo-script/csi-trace.c
@@ -2,6 +2,7 @@
#include <cairo-script-interpreter.h>
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include <libgen.h>
@@ -22,11 +23,18 @@ main (int argc, char **argv)
.surface_create = _script_surface_create,
};
int i;
+ char buf[4096];
csi = cairo_script_interpreter_create ();
for (i = 1; i < argc; i++) {
- char buf[4096];
+ if (strcmp (argv[i], "--version")) {
+ printf ("%s: version %s\n", argv[0], __DATE__);
+ exit (0);
+ } else if (strcmp (argv[i], "--help")) {
+ printf ("usage: %s < in > out\n", argv[0]);
+ exit (0);
+ }
snprintf (buf, sizeof (buf), "%s.trace", basename (argv[i]));
cairo_device_destroy (hooks.closure);
diff --git a/util/cairo-script/examples/Makefile.am b/util/cairo-script/examples/Makefile.am
index a87f02d9a..a87f02d9a 100755..100644
--- a/util/cairo-script/examples/Makefile.am
+++ b/util/cairo-script/examples/Makefile.am
diff --git a/util/cairo-script/examples/dragon.cs b/util/cairo-script/examples/dragon.cs
index 1060ca699..1060ca699 100755..100644
--- a/util/cairo-script/examples/dragon.cs
+++ b/util/cairo-script/examples/dragon.cs
diff --git a/util/cairo-script/examples/hilbert.cs b/util/cairo-script/examples/hilbert.cs
index 4278bf74c..4278bf74c 100755..100644
--- a/util/cairo-script/examples/hilbert.cs
+++ b/util/cairo-script/examples/hilbert.cs
diff --git a/util/cairo-script/examples/infinichess.cs b/util/cairo-script/examples/infinichess.cs
index f82b10278..f82b10278 100755..100644
--- a/util/cairo-script/examples/infinichess.cs
+++ b/util/cairo-script/examples/infinichess.cs
diff --git a/util/cairo-script/examples/interference.cs b/util/cairo-script/examples/interference.cs
index 6d2ee2200..6d2ee2200 100755..100644
--- a/util/cairo-script/examples/interference.cs
+++ b/util/cairo-script/examples/interference.cs
diff --git a/util/cairo-script/examples/pythagoras-tree.cs b/util/cairo-script/examples/pythagoras-tree.cs
index 96b4b39bc..96b4b39bc 100755..100644
--- a/util/cairo-script/examples/pythagoras-tree.cs
+++ b/util/cairo-script/examples/pythagoras-tree.cs
diff --git a/util/cairo-script/examples/sierpinski.cs b/util/cairo-script/examples/sierpinski.cs
index 6f959083b..6f959083b 100755..100644
--- a/util/cairo-script/examples/sierpinski.cs
+++ b/util/cairo-script/examples/sierpinski.cs
diff --git a/util/cairo-script/examples/wedgeAnnulus_crop_ybRings.cs b/util/cairo-script/examples/wedgeAnnulus_crop_ybRings.cs
index 5aeb97f6e..5aeb97f6e 100755..100644
--- a/util/cairo-script/examples/wedgeAnnulus_crop_ybRings.cs
+++ b/util/cairo-script/examples/wedgeAnnulus_crop_ybRings.cs
diff --git a/util/cairo-script/examples/world-map.cs b/util/cairo-script/examples/world-map.cs
index 54d9a8f31..54d9a8f31 100755..100644
--- a/util/cairo-script/examples/world-map.cs
+++ b/util/cairo-script/examples/world-map.cs
diff --git a/util/cairo-script/examples/zrusin.cs b/util/cairo-script/examples/zrusin.cs
index 8efc24bbe..8efc24bbe 100755..100644
--- a/util/cairo-script/examples/zrusin.cs
+++ b/util/cairo-script/examples/zrusin.cs
diff --git a/util/cairo-sphinx/.gitignore b/util/cairo-sphinx/.gitignore
new file mode 100644
index 000000000..56ecd5de8
--- /dev/null
+++ b/util/cairo-sphinx/.gitignore
@@ -0,0 +1 @@
+cairo-sphinx
diff --git a/util/cairo-sphinx/Makefile.am b/util/cairo-sphinx/Makefile.am
new file mode 100644
index 000000000..10bc10c27
--- /dev/null
+++ b/util/cairo-sphinx/Makefile.am
@@ -0,0 +1,43 @@
+cairolibdir = $(libdir)/cairo
+
+cairolib_LTLIBRARIES = cairo-sphinx.la
+bin_PROGRAMS = cairo-sphinx
+
+AM_CPPFLAGS = -I$(top_srcdir)/src \
+ -I$(top_builddir)/src \
+ -I$(top_srcdir)/boilerplate \
+ -I$(top_srcdir)/util/cairo-script
+
+cairo_sphinx_la_SOURCES = fdr.c
+cairo_sphinx_la_CPPFLAGS = $(AM_CPPFLAGS)
+cairo_sphinx_la_CFLAGS = $(CAIRO_CFLAGS)
+cairo_sphinx_la_LDFLAGS = -module -no-undefined
+if CAIRO_HAS_DL
+cairo_sphinx_la_LIBADD = -ldl
+endif
+
+cairo_sphinx_SOURCES = sphinx.c
+cairo_sphinx_CPPFLAGS = $(AM_CPPFLAGS) -DLIBDIR="\"$(cairolibdir)\""
+cairo_sphinx_CFLAGS = $(CAIRO_CFLAGS) $(real_pthread_CFLAGS) $(glib_CFLAGS)
+cairo_sphinx_LDADD = \
+ $(real_pthread_LIBS) \
+ $(top_builddir)/util/cairo-script/libcairo-script-interpreter.la \
+ $(top_builddir)/boilerplate/libcairoboilerplate.la \
+ $(top_builddir)/src/libcairo.la \
+ $(glib_LIBS) \
+ $(CAIRO_LDADD) \
+ $(shm_LIBS)
+cairo_sphinx_DEPENDENCIES = \
+ $(top_builddir)/util/cairo-script/libcairo-script-interpreter.la \
+ $(top_builddir)/boilerplate/libcairoboilerplate.la \
+ $(top_builddir)/src/libcairo.la
+
+# Install rules to rebuild the libraries and add explicit dependencies
+$(top_builddir)/boilerplate/libcairoboilerplate.la: $(top_builddir)/src/libcairo.la
+ cd $(top_builddir)/boilerplate && $(MAKE) $(AM_MAKEFLAGS) libcairoboilerplate.la
+
+$(top_builddir)/src/libcairo.la:
+ cd $(top_builddir)/src && $(MAKE) $(AM_MAKEFLAGS) libcairo.la
+
+$(top_builddir)/util/cairo-script/libcairo-script-interpreter.la: $(top_builddir)/src/libcairo.la
+ cd $(top_builddir)/util/cairo-script && $(MAKE) $(AM_MAKEFLAGS) libcairo-script-interpreter.la
diff --git a/util/cairo-sphinx/fdr.c b/util/cairo-sphinx/fdr.c
new file mode 100644
index 000000000..aeda89bcd
--- /dev/null
+++ b/util/cairo-sphinx/fdr.c
@@ -0,0 +1,261 @@
+/* cairo-fdr - a 'flight data recorder', a black box, for cairo
+ *
+ * Copyright © 2009 Chris Wilson
+ *
+ * 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/>.
+ */
+
+#define _GNU_SOURCE
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <cairo.h>
+#include <cairo-script.h>
+#include <cairo-tee.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <assert.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <dlfcn.h>
+
+static void *_dlhandle = RTLD_NEXT;
+#define DLCALL(name, args...) ({ \
+ static typeof (&name) name##_real; \
+ if (name##_real == NULL) { \
+ name##_real = dlsym (_dlhandle, #name); \
+ if (name##_real == NULL && _dlhandle == RTLD_NEXT) { \
+ _dlhandle = dlopen ("libcairo.so", RTLD_LAZY); \
+ name##_real = dlsym (_dlhandle, #name); \
+ assert (name##_real != NULL); \
+ } \
+ } \
+ (*name##_real) (args); \
+})
+
+static cairo_device_t *fdr_context;
+static const cairo_user_data_key_t fdr_key;
+
+static void
+fdr_get_extents (cairo_surface_t *surface,
+ cairo_rectangle_t *extents)
+{
+ cairo_t *cr;
+
+ cr = DLCALL (cairo_create, surface);
+ DLCALL (cairo_clip_extents, cr,
+ &extents->x, &extents->y, &extents->width, &extents->height);
+ DLCALL (cairo_destroy, cr);
+
+ extents->width -= extents->x;
+ extents->height -= extents->y;
+}
+
+static void
+fdr_surface_destroy (void *surface)
+{
+ DLCALL (cairo_surface_destroy, surface);
+}
+
+static void
+fdr_surface_reference (void *surface)
+{
+ DLCALL (cairo_surface_reference, surface);
+}
+
+static cairo_surface_t *
+fdr_surface_get_tee (cairo_surface_t *surface)
+{
+ return DLCALL (cairo_surface_get_user_data, surface, &fdr_key);
+}
+
+static cairo_surface_t *
+fdr_tee_surface_index (cairo_surface_t *surface, int index)
+{
+ return DLCALL (cairo_tee_surface_index, surface, index);
+}
+
+static cairo_status_t
+fdr_write (void *closure, const unsigned char *data, unsigned int len)
+{
+ int fd = (int) (intptr_t) closure;
+ while (len) {
+ int ret = write (fd, data, len);
+ if (ret < 0) {
+ switch (errno) {
+ case EAGAIN:
+ case EINTR:
+ continue;
+ default:
+ return CAIRO_STATUS_WRITE_ERROR;
+ }
+ } else if (ret == 0) {
+ return CAIRO_STATUS_WRITE_ERROR;
+ } else {
+ data += ret;
+ len -= ret;
+ }
+ }
+ return CAIRO_STATUS_SUCCESS;
+}
+
+cairo_t *
+cairo_create (cairo_surface_t *surface)
+{
+ cairo_surface_t *tee;
+
+ tee = fdr_surface_get_tee (surface);
+ if (tee == NULL) {
+ cairo_surface_t *script;
+ cairo_rectangle_t extents;
+ cairo_content_t content;
+
+ if (fdr_context == NULL) {
+ const char *env = getenv ("CAIRO_SPHINX_FD");
+ int fd = env ? atoi (env) : 1;
+ fdr_context = DLCALL (cairo_script_create_for_stream,
+ fdr_write, (void *) (intptr_t) fd);
+ }
+
+ fdr_get_extents (surface, &extents);
+ content = DLCALL (cairo_surface_get_content, surface);
+
+ tee = DLCALL (cairo_tee_surface_create, surface);
+ script = DLCALL (cairo_script_surface_create,
+ fdr_context, content, extents.width, extents.height);
+ DLCALL (cairo_tee_surface_add, tee, script);
+
+ DLCALL (cairo_surface_set_user_data, surface,
+ &fdr_key, tee, fdr_surface_destroy);
+ }
+
+ return DLCALL (cairo_create, tee);
+}
+
+static void
+fdr_remove_tee (cairo_surface_t *surface)
+{
+ fdr_surface_reference (surface);
+ DLCALL (cairo_surface_set_user_data, surface, &fdr_key, NULL, NULL);
+ fdr_surface_destroy (surface);
+}
+
+void
+cairo_destroy (cairo_t *cr)
+{
+ cairo_surface_t *tee;
+
+ tee = DLCALL (cairo_get_target, cr);
+ DLCALL (cairo_destroy, cr);
+
+ if (DLCALL (cairo_surface_get_reference_count, tee) == 1)
+ fdr_remove_tee (fdr_tee_surface_index (tee, 0));
+}
+
+void
+cairo_pattern_destroy (cairo_pattern_t *pattern)
+{
+ if (DLCALL (cairo_pattern_get_type, pattern) == CAIRO_PATTERN_TYPE_SURFACE) {
+ cairo_surface_t *surface;
+
+ if (DLCALL (cairo_pattern_get_surface, pattern, &surface) == CAIRO_STATUS_SUCCESS &&
+ DLCALL (cairo_surface_get_type, surface) == CAIRO_SURFACE_TYPE_TEE &&
+ DLCALL (cairo_surface_get_reference_count, surface) == 2)
+ {
+ fdr_remove_tee (fdr_tee_surface_index (surface, 0));
+ }
+ }
+
+ DLCALL (cairo_pattern_destroy, pattern);
+}
+
+cairo_surface_t *
+cairo_get_target (cairo_t *cr)
+{
+ cairo_surface_t *tee;
+
+ tee = DLCALL (cairo_get_target, cr);
+ return fdr_tee_surface_index (tee, 0);
+}
+
+cairo_surface_t *
+cairo_get_group_target (cairo_t *cr)
+{
+ cairo_surface_t *tee;
+
+ tee = DLCALL (cairo_get_group_target, cr);
+ return fdr_tee_surface_index (tee, 0);
+}
+
+cairo_pattern_t *
+cairo_pattern_create_for_surface (cairo_surface_t *surface)
+{
+ cairo_surface_t *tee;
+
+ tee = fdr_surface_get_tee (surface);
+ if (tee != NULL)
+ surface = tee;
+
+ return DLCALL (cairo_pattern_create_for_surface, surface);
+}
+
+cairo_status_t
+cairo_pattern_get_surface (cairo_pattern_t *pattern,
+ cairo_surface_t **surface)
+{
+ cairo_status_t status;
+ cairo_surface_t *tee;
+
+ status = DLCALL (cairo_pattern_get_surface, pattern, surface);
+ if (status != CAIRO_STATUS_SUCCESS)
+ return status;
+
+ tee = fdr_surface_get_tee (*surface);
+ if (tee != NULL)
+ *surface = tee;
+
+ return CAIRO_STATUS_SUCCESS;
+}
+
+void
+cairo_set_source_surface (cairo_t *cr,
+ cairo_surface_t *surface,
+ double x, double y)
+{
+ cairo_surface_t *tee;
+
+ tee = fdr_surface_get_tee (surface);
+ if (tee != NULL)
+ surface = tee;
+
+ DLCALL (cairo_set_source_surface, cr, surface, x, y);
+}
+
+cairo_surface_t *
+cairo_surface_create_similar (cairo_surface_t *surface,
+ cairo_content_t content,
+ int width, int height)
+{
+ cairo_surface_t *tee;
+
+ tee = fdr_surface_get_tee (surface);
+ if (tee != NULL)
+ surface = tee;
+
+ return DLCALL (cairo_surface_create_similar,
+ surface, content, width, height);
+}
diff --git a/util/cairo-sphinx/sphinx.c b/util/cairo-sphinx/sphinx.c
new file mode 100644
index 000000000..238d40064
--- /dev/null
+++ b/util/cairo-sphinx/sphinx.c
@@ -0,0 +1,1545 @@
+/*
+ * The intention for sphinx is for detection of rendering errors inside
+ * applications by simultaneously rendering on to the target device and on
+ * an image surface and comparing the two. If it found a discrepancy, it
+ * would then dump the trace that reproduces the error. (Then apply
+ * delta-debugging to reduce that down to a minimal trace.)
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <sys/socket.h>
+#include <sys/poll.h>
+#include <sys/un.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <errno.h>
+#include <assert.h>
+#include <pthread.h>
+
+#include <cairo.h>
+#include <cairo-script.h>
+#include <cairo-script-interpreter.h>
+#include <cairo-boilerplate.h>
+
+#include <glib.h> /* for checksumming */
+
+#ifndef CAIRO_HAS_REAL_PTHREAD
+# error "cairo-sphinx needs real pthreads"
+#endif
+
+#ifndef MAP_NORESERVE
+#define MAP_NORESERVE 0
+#endif
+
+#define DATA_SIZE (256 << 20)
+#define SHM_PATH_XXX "/shmem-cairo-sphinx"
+
+struct client {
+ int sk;
+ const cairo_boilerplate_target_t *target;
+ cairo_surface_t *surface;
+ void *base;
+
+ cairo_script_interpreter_t *csi;
+ struct context_closure {
+ struct context_closure *next;
+ unsigned long id;
+ cairo_t *context;
+ cairo_surface_t *surface;
+ cairo_surface_t *original;
+ } *contexts;
+
+ unsigned long context_id;
+};
+
+struct surface_tag {
+ long width, height;
+};
+static const cairo_user_data_key_t surface_tag;
+
+static int
+client_socket (const char *socket_path);
+
+static int
+writen (int fd, const void *ptr, int len)
+{
+#if 1
+ const uint8_t *data = ptr;
+ while (len) {
+ int ret = write (fd, data, len);
+ if (ret < 0) {
+ switch (errno) {
+ case EAGAIN:
+ case EINTR:
+ continue;
+ default:
+ return FALSE;
+ }
+ } else if (ret == 0) {
+ return FALSE;
+ } else {
+ data += ret;
+ len -= ret;
+ }
+ }
+ return TRUE;
+#else
+ int ret = send (fd, ptr, len, 0);
+ return ret == len;
+#endif
+}
+
+static int
+readn (int fd, void *ptr, int len)
+{
+#if 0
+ uint8_t *data = ptr;
+ while (len) {
+ int ret = read (fd, data, len);
+ if (ret < 0) {
+ switch (errno) {
+ case EAGAIN:
+ case EINTR:
+ continue;
+ default:
+ return FALSE;
+ }
+ } else if (ret == 0) {
+ return FALSE;
+ } else {
+ data += ret;
+ len -= ret;
+ }
+ }
+ return TRUE;
+#else
+ int ret = recv (fd, ptr, len, MSG_WAITALL);
+ return ret == len;
+#endif
+}
+static int
+open_devnull_to_fd (int want_fd, int flags)
+{
+ int error;
+ int got_fd;
+
+ close (want_fd);
+
+ got_fd = open("/dev/null", flags | O_CREAT, 0700);
+ if (got_fd == -1)
+ return -1;
+
+ error = dup2 (got_fd, want_fd);
+ close (got_fd);
+
+ return error;
+}
+
+static int
+daemonize (void)
+{
+ void (*oldhup) (int);
+
+ /* Let the parent go. */
+ switch (fork ()) {
+ case -1: return -1;
+ case 0: break;
+ default: _exit (0);
+ }
+
+ /* Become session leader. */
+ if (setsid () == -1)
+ return -1;
+
+ /* Refork to yield session leadership. */
+ oldhup = signal (SIGHUP, SIG_IGN);
+ switch (fork ()) {
+ case -1: return -1;
+ case 0: break;
+ default: _exit (0);
+ }
+ signal (SIGHUP, oldhup);
+
+ /* Establish stdio. */
+ if (open_devnull_to_fd (0, O_RDONLY) == -1)
+ return -1;
+ if (open_devnull_to_fd (1, O_WRONLY | O_APPEND) == -1)
+ return -1;
+ if (dup2 (1, 2) == -1)
+ return -1;
+
+ return 0;
+}
+
+static int
+server_socket (const char *socket_path)
+{
+ long flags;
+ struct sockaddr_un addr;
+ int sk;
+
+ unlink (socket_path);
+
+ sk = socket (PF_UNIX, SOCK_STREAM, 0);
+ if (sk == -1)
+ return -1;
+
+ memset (&addr, 0, sizeof (addr));
+ addr.sun_family = AF_UNIX;
+ strcpy (addr.sun_path, socket_path);
+ if (bind (sk, (struct sockaddr *) &addr, sizeof (addr)) == -1) {
+ close (sk);
+ return -1;
+ }
+
+ flags = fcntl (sk, F_GETFL);
+ if (flags == -1 || fcntl (sk, F_SETFL, flags | O_NONBLOCK) == -1) {
+ close (sk);
+ return -1;
+ }
+
+ if (listen (sk, 5) == -1) {
+ close (sk);
+ return -1;
+ }
+
+ return sk;
+}
+
+static int
+readline (int fd, char *line, int max)
+{
+ int len = 0;
+ do {
+ int ret = read (fd, &line[len], 1);
+ if (ret <= 0)
+ return -1;
+ } while (line[len] != '\n' && ++len < max);
+ line[len] = '\0';
+ return len;
+}
+
+struct clients {
+ int count, size;
+ int complete;
+
+ cairo_surface_t *recording;
+ unsigned long serial;
+
+ struct client_info {
+ int sk;
+ int trace;
+ unsigned long image_serial;
+ cairo_surface_t *image;
+ char *name;
+ char *target;
+ char *reference;
+
+ uint8_t *out_buf;
+ int out_len;
+ int out_size;
+ } *clients;
+ const char *shm_path;
+ unsigned long offset;
+ uint8_t *base;
+};
+
+static void *
+clients_shm (const char *shm_path)
+{
+ void *base;
+ int fd;
+
+ shm_unlink (shm_path);
+ fd = shm_open (shm_path, O_RDWR | O_EXCL | O_CREAT, 0777);
+ if (fd == -1)
+ return MAP_FAILED;
+
+ if (ftruncate (fd, DATA_SIZE) == -1) {
+ close (fd);
+ return MAP_FAILED;
+ }
+
+ base = mmap (NULL, DATA_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+ close (fd);
+
+ return base;
+}
+
+static int
+clients_init (struct clients *clients)
+{
+ clients->count = 0;
+ clients->complete = 0;
+ clients->size = 4;
+ clients->clients = xmalloc (clients->size * sizeof (struct client_info));
+
+ clients->shm_path = SHM_PATH_XXX;
+ clients->base = clients_shm (clients->shm_path);
+ if (clients->base == MAP_FAILED)
+ return -1;
+ clients->offset = 0;
+
+ clients->recording = NULL;
+ clients->serial = 0;
+
+ return 0;
+}
+
+static void
+clients_add_command (struct clients *clients, int fd, char *info)
+{
+ struct client_info *c;
+ char buf[1024];
+ int len;
+ char *str;
+
+ if (clients->count == clients->size) {
+ clients->size *= 2;
+ clients->clients = xrealloc (clients->clients,
+ clients->size * sizeof (struct client_info));
+ }
+
+ c = &clients->clients[clients->count++];
+ c->sk = fd;
+ c->trace = -1;
+ c->image_serial = 0;
+ c->image = NULL;
+ c->name = c->target = c->reference = NULL;
+
+ c->out_size = 8192;
+ c->out_buf = xmalloc (c->out_size);
+ c->out_len = 0;
+
+ str = strstr (info, "name=");
+ if (str != NULL) {
+ char *sp = strchr (str + 5, ' ');
+ int len;
+ if (sp)
+ len = sp - str - 5;
+ else
+ len = strlen (str + 5);
+ c->name = xmalloc (len + 1);
+ memcpy (c->name, str + 5, len);
+ c->name[len] = '\0';
+ }
+
+ str = strstr (info, "target=");
+ if (str != NULL) {
+ char *sp = strchr (str + 7, ' ');
+ int len;
+ if (sp)
+ len = sp - str - 7;
+ else
+ len = strlen (str + 7);
+ c->target = xmalloc (len + 1);
+ memcpy (c->target, str + 7, len);
+ c->target[len] = '\0';
+ }
+
+ str = strstr (info, "reference=");
+ if (str != NULL) {
+ char *sp = strchr (str + 10, ' ');
+ int len;
+ if (sp)
+ len = sp - str - 10;
+ else
+ len = strlen (str + 10);
+ c->reference = xmalloc (len + 1);
+ memcpy (c->reference, str + 10, len);
+ c->reference[len] = '\0';
+ }
+
+ len = sprintf (buf, "%s\n", clients->shm_path);
+ writen (fd, buf, len);
+}
+
+static void
+clients_add_trace (struct clients *clients, int fd, char *info)
+{
+ char *str, *sp;
+ char *name;
+ int i;
+
+ str = strstr (info, "name=");
+ assert (str != NULL);
+ sp = strchr (str + 5, ' ');
+ if (sp)
+ i = sp - str - 5;
+ else
+ i = strlen (str + 5);
+
+ name = xmalloc (i + 1);
+ memcpy (name, str + 5, i);
+ name[i] = '\0';
+
+ for (i = 0; i < clients->count; i++) {
+ struct client_info *c = &clients->clients[i];
+ if (strcmp (name, c->name) == 0) {
+ c->trace = fd;
+ break;
+ }
+ }
+
+ free (name);
+}
+
+static int
+clients_image (struct clients *clients, int fd, char *info)
+{
+ struct client_info *c = NULL;
+ int format, width, height, stride, size;
+ int i;
+
+ for (i = 0; i < clients->count; i++) {
+ if (clients->clients[i].sk == fd) {
+ c = &clients->clients[i];
+ break;
+ }
+ }
+
+ if (c == NULL)
+ return 0;
+
+ if (sscanf (info, "%lu %d %d %d %d",
+ &c->image_serial, &format, &width, &height, &stride) != 5)
+ {
+ return 0;
+ }
+
+ size = height * stride;
+ size = (size + 4095) & -4096;
+ assert (clients->offset + size <= DATA_SIZE);
+
+ c->image =
+ cairo_image_surface_create_for_data (clients->base + clients->offset,
+ format, width, height, stride);
+
+ if (! writen (fd, &clients->offset, sizeof (clients->offset)))
+ return 0;
+
+ clients->offset += size;
+
+ return 1;
+}
+
+static int
+u8_cmp (const void *A, const void *B)
+{
+ const uint8_t *a = A, *b = B;
+ return (int) *a - (int) *b;
+}
+
+static uint8_t
+median (uint8_t *values, int count)
+{
+ /* XXX could use a fast median here if we cared */
+ qsort (values, count, 1, u8_cmp);
+ return values[count/2];
+}
+
+static uint32_t
+get_pixel32 (int x, int y, const uint8_t *data, int stride)
+{
+ return ((uint32_t *)(data + y * stride))[x];
+}
+
+static uint8_t
+get_median_32 (int x, int y, int channel,
+ const uint8_t *data, int width, int height, int stride)
+{
+ uint8_t neighbourhood[25];
+ int cnt = 0;
+ int xx, yy;
+
+ for (yy = y - 2; yy <= y + 2; yy++) {
+ if (yy < 0)
+ continue;
+ if (yy >= height)
+ continue;
+
+ for (xx = x - 2; xx <= x + 2; xx++) {
+ if (xx < 0)
+ continue;
+ if (xx >= width)
+ continue;
+
+ neighbourhood[cnt++] = (get_pixel32 (xx, yy, data, stride) >> (channel*8)) & 0xff;
+ }
+ }
+
+ return median (neighbourhood, cnt);
+}
+
+static uint8_t
+get_pixel8 (int x, int y, const uint8_t *data, int stride)
+{
+ return data[y * stride + x];
+}
+
+static uint8_t
+get_median_8 (int x, int y, const uint8_t *data, int width, int height, int stride)
+{
+ uint8_t neighbourhood[25];
+ int cnt = 0;
+ int xx, yy;
+
+ for (yy = y - 2; yy <= y + 2; yy++) {
+ if (yy < 0)
+ continue;
+ if (yy >= height)
+ continue;
+
+ for (xx = x - 2; xx <= x + 2; xx++) {
+ if (xx < 0)
+ continue;
+ if (xx >= width)
+ continue;
+
+ neighbourhood[cnt++] = get_pixel8 (xx, yy, data, stride);
+ }
+ }
+
+ return median (neighbourhood, cnt);
+}
+
+static cairo_bool_t
+compare_images (cairo_surface_t *a,
+ cairo_surface_t *b)
+{
+ int width, height, stride;
+ const uint8_t *aa, *bb;
+ int x, y;
+
+ if (cairo_surface_status (a) || cairo_surface_status (b))
+ return FALSE;
+
+ if (cairo_surface_get_type (a) != cairo_surface_get_type (b))
+ return FALSE;
+
+ if (cairo_image_surface_get_format (a) != cairo_image_surface_get_format (b))
+ return FALSE;
+
+ if (cairo_image_surface_get_width (a) != cairo_image_surface_get_width (b))
+ return FALSE;
+
+ if (cairo_image_surface_get_height (a) != cairo_image_surface_get_height (b))
+ return FALSE;
+
+ if (cairo_image_surface_get_stride (a) != cairo_image_surface_get_stride (b))
+ return FALSE;
+
+
+ width = cairo_image_surface_get_width (a);
+ height = cairo_image_surface_get_height (a);
+ stride = cairo_image_surface_get_stride (a);
+
+ aa = cairo_image_surface_get_data (a);
+ bb = cairo_image_surface_get_data (b);
+ switch (cairo_image_surface_get_format (a)) {
+ case CAIRO_FORMAT_ARGB32:
+ for (y = 0; y < height; y++) {
+ const uint32_t *ua = (uint32_t *) aa;
+ const uint32_t *ub = (uint32_t *) bb;
+ for (x = 0; x < width; x++) {
+ if (ua[x] != ub[x]) {
+ int channel;
+
+ for (channel = 0; channel < 4; channel++) {
+ unsigned va, vb, diff;
+
+ va = (ua[x] >> (channel*8)) & 0xff;
+ vb = (ub[x] >> (channel*8)) & 0xff;
+ diff = abs (va - vb);
+ if (diff > 1) {
+ va = get_median_32 (x, y, channel, aa, width, height, stride);
+ vb = get_median_32 (x, y, channel, bb, width, height, stride);
+ diff = abs (va - vb);
+ if (diff > 1)
+ return FALSE;
+ }
+ }
+ }
+ }
+ aa += stride;
+ bb += stride;
+ }
+ break;
+
+ case CAIRO_FORMAT_RGB24:
+ for (y = 0; y < height; y++) {
+ const uint32_t *ua = (uint32_t *) aa;
+ const uint32_t *ub = (uint32_t *) bb;
+ for (x = 0; x < width; x++) {
+ if ((ua[x] & 0x00ffffff) != (ub[x] & 0x00ffffff)) {
+ int channel;
+
+ for (channel = 0; channel < 3; channel++) {
+ unsigned va, vb, diff;
+
+ va = (ua[x] >> (channel*8)) & 0xff;
+ vb = (ub[x] >> (channel*8)) & 0xff;
+ diff = abs (va - vb);
+ if (diff > 1) {
+ va = get_median_32 (x, y, channel, aa, width, height, stride);
+ vb = get_median_32 (x, y, channel, bb, width, height, stride);
+ diff = abs (va - vb);
+ if (diff > 1)
+ return FALSE;
+ }
+ }
+ }
+ }
+ aa += stride;
+ bb += stride;
+ }
+ break;
+
+ case CAIRO_FORMAT_A8:
+ for (y = 0; y < height; y++) {
+ for (x = 0; x < width; x++) {
+ if (aa[x] != bb[x]) {
+ unsigned diff = abs (aa[x] - bb[x]);
+ if (diff > 1) {
+ uint8_t va, vb;
+
+ va = get_median_8 (x, y, aa, width, height, stride);
+ vb = get_median_8 (x, y, bb, width, height, stride);
+ diff = abs (va - vb);
+ if (diff > 1)
+ return FALSE;
+ }
+
+ }
+ }
+ aa += stride;
+ bb += stride;
+ }
+ break;
+
+ case CAIRO_FORMAT_A1:
+ width /= 8;
+ for (y = 0; y < height; y++) {
+ if (memcmp (aa, bb, width))
+ return FALSE;
+ aa += stride;
+ bb += stride;
+ }
+ break;
+
+ case CAIRO_FORMAT_INVALID:
+ case CAIRO_FORMAT_RGB16_565: /* XXX */
+ break;
+ }
+
+ return TRUE;
+}
+
+static int
+check_images (struct clients *clients)
+{
+ int i, j;
+
+ for (i = 0; i < clients->count; i++) {
+ struct client_info *c = &clients->clients[i];
+
+ if (c->reference == NULL)
+ continue;
+
+ for (j = 0; j < clients->count; j++) {
+ struct client_info *ref = &clients->clients[j];
+
+ if (strcmp (c->reference, ref->name))
+ continue;
+
+ if (! compare_images (c->image, ref->image))
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+static gchar *
+checksum (const char *filename)
+{
+ gchar *str = NULL;
+ gchar *data;
+ gsize len;
+
+ if (g_file_get_contents (filename, &data, &len, NULL)) {
+ str = g_compute_checksum_for_data (G_CHECKSUM_SHA1, (guchar *) data, len);
+ g_free (data);
+ }
+
+ return str;
+}
+
+static void
+write_trace (struct clients *clients)
+{
+ cairo_device_t *ctx;
+ gchar *csum;
+ char buf[4096];
+ int i;
+
+ mkdir ("output", 0777);
+
+ ctx = cairo_script_create ("output/cairo-sphinx.trace");
+ cairo_script_from_recording_surface (ctx, clients->recording);
+ cairo_device_destroy (ctx);
+
+ csum = checksum ("output/cairo-sphinx.trace");
+
+ sprintf (buf, "output/%s.trace", csum);
+ if (! g_file_test (buf, G_FILE_TEST_EXISTS)) {
+ rename ("output/cairo-sphinx.trace", buf);
+
+ sprintf (buf, "output/%s.recording.png", csum);
+ cairo_surface_write_to_png (clients->recording, buf);
+
+ for (i = 0; i < clients->count; i++) {
+ struct client_info *c = &clients->clients[i];
+ if (c->image != NULL) {
+ sprintf (buf, "output/%s.%s.png", csum, c->name);
+ cairo_surface_write_to_png (c->image, buf);
+ }
+ }
+ }
+}
+
+static void
+clients_complete (struct clients *clients, int fd)
+{
+ int i;
+
+ for (i = 0; i < clients->count; i++) {
+ if (clients->clients[i].sk == fd) {
+ break;
+ }
+ }
+ if (i == clients->count)
+ return;
+
+ if (++clients->complete != clients->count)
+ return;
+
+ clients->offset = 0;
+ clients->complete = 0;
+
+ if (! check_images (clients))
+ write_trace (clients);
+
+ /* ack */
+ for (i = 0; i < clients->count; i++) {
+ struct client_info *c = &clients->clients[i];
+
+ cairo_surface_destroy (c->image);
+ c->image = NULL;
+
+ if (! writen (c->sk, &clients->serial, sizeof (clients->serial)))
+ continue;
+
+ c->image_serial = 0;
+ }
+
+ clients->recording = NULL;
+ clients->serial = 0;
+}
+
+static void
+clients_recording (struct clients *clients, int fd, char *info)
+{
+ sscanf (info, "%p %lu", &clients->recording, &clients->serial);
+ clients_complete (clients, fd);
+}
+
+static void
+clients_remove (struct clients *clients, int fd)
+{
+ int i, j;
+
+ for (i = 0; i < clients->count; i++) {
+ struct client_info *c = &clients->clients[i];
+ if (c->sk == fd) {
+ free (c->out_buf);
+ break;
+ }
+ }
+
+ for (j = i++; i < clients->count; i++)
+ clients->clients[j] = clients->clients[i];
+
+ clients->count = j;
+}
+
+static void
+clients_send_trace (struct clients *clients,
+ const char * const line, const int len)
+{
+ int i;
+
+ for (i = 0; i < clients->count; i++) {
+ struct client_info *c = &clients->clients[i];
+ int ret, rem = len;
+
+ if (c->trace == -1)
+ continue;
+
+ if (c->out_len) {
+ ret = write (c->trace, c->out_buf, c->out_len);
+ if (ret > 0) {
+ c->out_len -= ret;
+ if (c->out_len)
+ memmove (c->out_buf, c->out_buf + ret, c->out_len);
+ }
+ }
+
+ if (! c->out_len) {
+ ret = write (c->trace, line, rem);
+ if (ret > 0)
+ rem -= ret;
+ }
+
+ if (rem) {
+ if (c->out_len + rem > c->out_size) {
+ c->out_size *= 2;
+ c->out_buf = xrealloc (c->out_buf, c->out_size);
+ }
+
+ memcpy (c->out_buf + c->out_len, line, rem);
+ c->out_len += rem;
+ }
+ }
+}
+
+static void
+clients_fini (struct clients *clients)
+{
+ shm_unlink (clients->shm_path);
+ munmap (clients->base, DATA_SIZE);
+ free (clients->clients);
+}
+
+static int
+nonblocking (int fd)
+{
+ long flags;
+
+ flags = fcntl (fd, F_GETFL);
+ if (flags == -1)
+ return -1;
+
+ return fcntl (fd, F_SETFL, flags | O_NONBLOCK);
+}
+
+static void *
+request_image (struct client *c,
+ struct context_closure *closure,
+ cairo_format_t format,
+ int width, int height, int stride)
+{
+ char buf[1024];
+ unsigned long offset = -1;
+ int len;
+
+ assert (format != CAIRO_FORMAT_INVALID);
+
+ len = sprintf (buf, ".image %lu %d %d %d %d\n",
+ closure->id, format, width, height, stride);
+ writen (c->sk, buf, len);
+
+ readn (c->sk, &offset, sizeof (offset));
+ if (offset == (unsigned long) -1)
+ return NULL;
+
+ return (uint8_t *) c->base + offset;
+}
+
+static cairo_format_t
+format_for_content (cairo_content_t content)
+{
+ switch (content) {
+ case CAIRO_CONTENT_ALPHA:
+ return CAIRO_FORMAT_A8;
+ case CAIRO_CONTENT_COLOR:
+ return CAIRO_FORMAT_RGB24;
+ default:
+ case CAIRO_CONTENT_COLOR_ALPHA:
+ return CAIRO_FORMAT_ARGB32;
+ }
+}
+
+static void
+get_surface_size (cairo_surface_t *surface,
+ int *width, int *height,
+ cairo_format_t *format)
+{
+ if (cairo_surface_get_type (surface) == CAIRO_SURFACE_TYPE_IMAGE) {
+ *width = cairo_image_surface_get_width (surface);
+ *height = cairo_image_surface_get_height (surface);
+ *format = cairo_image_surface_get_format (surface);
+ } else {
+ struct surface_tag *tag;
+
+ tag = cairo_surface_get_user_data (surface, &surface_tag);
+ if (tag != NULL) {
+ *width = tag->width;
+ *height = tag->height;
+ } else {
+ double x0, x1, y0, y1;
+ cairo_t *cr;
+
+ /* presumably created using cairo_surface_create_similar() */
+ cr = cairo_create (surface);
+ cairo_clip_extents (cr, &x0, &y0, &x1, &y1);
+ cairo_destroy (cr);
+
+ tag = xmalloc (sizeof (*tag));
+ *width = tag->width = ceil (x1 - x0);
+ *height = tag->height = ceil (y1 - y0);
+
+ if (cairo_surface_set_user_data (surface, &surface_tag, tag, free))
+ exit (-1);
+ }
+ }
+}
+
+
+static void
+send_surface (struct client *c,
+ struct context_closure *closure)
+{
+ cairo_surface_t *source = closure->surface;
+ cairo_surface_t *image;
+ cairo_format_t format = CAIRO_FORMAT_INVALID;
+ cairo_t *cr;
+ int width, height, stride;
+ void *data;
+ unsigned long serial;
+
+ get_surface_size (source, &width, &height, &format);
+ if (format == CAIRO_FORMAT_INVALID)
+ format = format_for_content (cairo_surface_get_content (source));
+
+ stride = cairo_format_stride_for_width (format, width);
+
+ data = request_image (c, closure, format, width, height, stride);
+ if (data == NULL)
+ exit (-1);
+
+ image = cairo_image_surface_create_for_data (data,
+ format,
+ width, height,
+ stride);
+ cr = cairo_create (image);
+ cairo_surface_destroy (image);
+
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_set_source_surface (cr, source, 0, 0);
+ cairo_paint (cr);
+ cairo_destroy (cr);
+
+ /* signal completion */
+ writen (c->sk, ".complete\n", strlen (".complete\n"));
+
+ /* wait for image check */
+ serial = 0;
+ readn (c->sk, &serial, sizeof (serial));
+ if (serial != closure->id)
+ exit (-1);
+}
+
+static void
+send_recording (struct client *c,
+ struct context_closure *closure)
+{
+ cairo_surface_t *source = closure->surface;
+ char buf[1024];
+ int len;
+ unsigned long serial;
+
+ assert (cairo_surface_get_type (source) == CAIRO_SURFACE_TYPE_RECORDING);
+ len = sprintf (buf, ".recording %p %lu\n", source, closure->id);
+ writen (c->sk, buf, len);
+
+ /* wait for image check */
+
+ serial = 0;
+ readn (c->sk, &serial, sizeof (serial));
+ if (serial != closure->id)
+ exit (-1);
+}
+
+static cairo_surface_t *
+_surface_create (void *closure,
+ cairo_content_t content,
+ double width, double height,
+ long uid)
+{
+ struct client *c = closure;
+ cairo_surface_t *surface;
+
+ surface = cairo_surface_create_similar (c->surface,
+ content, width, height);
+ if (cairo_surface_get_type (surface) != CAIRO_SURFACE_TYPE_IMAGE) {
+ struct surface_tag *tag;
+
+ tag = xmalloc (sizeof (*tag));
+ tag->width = width;
+ tag->height = height;
+ if (cairo_surface_set_user_data (surface, &surface_tag, tag, free))
+ exit (-1);
+ }
+
+ return surface;
+}
+
+static cairo_t *
+_context_create (void *closure, cairo_surface_t *surface)
+{
+ struct client *c = closure;
+ struct context_closure *l;
+ cairo_bool_t foreign = FALSE;
+
+ l = xmalloc (sizeof (*l));
+ l->next = c->contexts;
+ l->surface = surface;
+ l->original = cairo_surface_reference (surface);
+ l->id = ++c->context_id;
+ if (l->id == 0)
+ l->id = ++c->context_id;
+ c->contexts = l;
+
+ /* record everything, including writes to images */
+ if (c->target == NULL) {
+ if (cairo_surface_get_type (surface) != CAIRO_SURFACE_TYPE_RECORDING) {
+ cairo_format_t format;
+ int width, height;
+
+ get_surface_size (surface, &width, &height, &format);
+ l->surface = cairo_surface_create_similar (c->surface,
+ cairo_surface_get_content (surface),
+ width, height);
+ foreign = TRUE;
+ }
+ }
+
+ l->context = cairo_create (l->surface);
+ if (foreign) {
+ cairo_set_source_surface (l->context, surface, 0, 0);
+ cairo_paint (l->context);
+ }
+
+ return l->context;
+}
+
+static void
+_context_destroy (void *closure, void *ptr)
+{
+ struct client *c = closure;
+ struct context_closure *l, **prev = &c->contexts;
+
+ while ((l = *prev) != NULL) {
+ if (l->context == ptr) {
+ if (cairo_surface_status (l->surface) == CAIRO_STATUS_SUCCESS) {
+ if (c->target == NULL)
+ send_recording (c, l);
+ else
+ send_surface (c, l);
+ } else {
+ exit (-1);
+ }
+
+ cairo_surface_destroy (l->original);
+ *prev = l->next;
+ free (l);
+ return;
+ }
+ prev = &l->next;
+ }
+}
+
+static void *
+recorder (void *arg)
+{
+ struct client client;
+ const cairo_script_interpreter_hooks_t hooks = {
+ .closure = &client,
+ .surface_create = _surface_create,
+ .context_create = _context_create,
+ .context_destroy = _context_destroy,
+ };
+ char *buf;
+ int buf_size;
+ int len = 0, ret;
+ struct pollfd pfd;
+
+ client.target = NULL;
+ client.sk = client_socket ("/tmp/cairo-sphinx");
+ if (client.sk < 0)
+ return NULL;
+
+ buf_size = 65536;
+ buf = xmalloc (buf_size);
+
+ len = sprintf (buf, "client-command target=recording name=.recorder\n");
+ if (! writen (client.sk, buf, len))
+ return NULL;
+
+ /* drain the shm_path */
+ len = readline (client.sk, buf, buf_size);
+
+ pfd.fd = client_socket ("/tmp/cairo-sphinx");
+ if (pfd.fd < 0)
+ return NULL;
+
+ len = sprintf (buf, "client-trace name=.recorder\n");
+ if (! writen (pfd.fd, buf, len))
+ return NULL;
+
+ client.surface = cairo_recording_surface_create (CAIRO_CONTENT_COLOR_ALPHA,
+ NULL);
+
+ client.context_id = 0;
+ client.csi = cairo_script_interpreter_create ();
+ cairo_script_interpreter_install_hooks (client.csi, &hooks);
+
+ nonblocking (pfd.fd);
+ pfd.events = POLLIN;
+ len = 0;
+ while (poll (&pfd, 1, -1) > 0) {
+ while ((ret = read (pfd.fd, buf + len, buf_size - len)) > 0) {
+ int end;
+
+ if (ret == buf_size - len) {
+ buf_size *= 2;
+ buf = xrealloc (buf, buf_size);
+ }
+ len += ret;
+
+ for (end = len; end > 0 && buf[--end] != '\n'; )
+ ;
+ if (end > 0) {
+ buf[end] = '\0';
+ cairo_script_interpreter_feed_string (client.csi, buf, end);
+
+ len -= end + 1;
+ if (len)
+ memmove (buf, buf + end + 1, len);
+ }
+ }
+ if (ret == 0)
+ break;
+ if (! (errno == EAGAIN || errno == EINTR))
+ break;
+ }
+
+ cairo_script_interpreter_finish (client.csi);
+ cairo_script_interpreter_destroy (client.csi);
+
+ cairo_surface_destroy (client.surface);
+ return NULL;
+}
+
+static int
+do_server (const char *path)
+{
+ pthread_t thread;
+ struct clients clients;
+ char line[4096];
+ struct pollfd *pfd;
+ int num_pfd, size_pfd;
+ int n, cnt, ret = 1;
+ int sk, source = -1;
+ int waiter = -1, waiter_count = 0;
+ int len;
+
+ signal (SIGPIPE, SIG_IGN);
+
+ if (clients_init (&clients) < 0) {
+ fprintf (stderr, "Failed to initialise clients structure\n");
+ return -1;
+ }
+
+ sk = server_socket (path);
+ if (sk < 0) {
+ fprintf (stderr, "Failed to create server socket\n");
+ return 1;
+ }
+
+ if (daemonize () < 0)
+ return 1;
+
+ if (pthread_create (&thread, NULL, recorder, NULL) < 0) {
+ fprintf (stderr, "Failed to create spawn recording thread\n");
+ return 1;
+ }
+
+ size_pfd = 4;
+ pfd = xmalloc (sizeof (*pfd) * size_pfd);
+ pfd[0].fd = sk;
+ pfd[0].events = POLLIN;
+ num_pfd = 1;
+
+ while ((cnt = poll (pfd, num_pfd, -1)) > 0) {
+ int have_source;
+
+ if (pfd[0].revents) {
+ while ((sk = accept (pfd[0].fd, NULL, NULL)) != -1) {
+ len = readline (sk, line, sizeof (line));
+ if (strcmp (line, "source") == 0) {
+
+ if (source != -1)
+ exit (1);
+
+ source = sk;
+ if (nonblocking (sk) < 0) {
+ close (sk);
+ continue;
+ }
+ } else if (strncmp (line, "client-command", 14) == 0) {
+ if (source == -1)
+ clients_add_command (&clients, sk, line);
+ } else if (strncmp (line, "client-trace", 12) == 0) {
+ if (source == -1) {
+ clients_add_trace (&clients, sk, line);
+ if (nonblocking (sk) < 0) {
+ close (sk);
+ continue;
+ }
+
+ if (clients.count == waiter_count) {
+ for (n = 1; n < num_pfd; n++) {
+ if (pfd[n].fd == waiter) {
+ pfd[n].fd = -1;
+ break;
+ }
+ }
+ close (waiter);
+ waiter_count = -1;
+ }
+ }
+ } else if (strncmp (line, "wait", 4) == 0) {
+ int count = atoi (line + 5) + 1;
+ if (clients.count == count) {
+ close (sk);
+ continue;
+ } else {
+ waiter = sk;
+ waiter_count = count;
+ }
+ }
+
+ if (num_pfd == size_pfd) {
+ size_pfd *= 2;
+ pfd = xrealloc (pfd, sizeof (*pfd) * size_pfd);
+ }
+
+ pfd[num_pfd].fd = sk;
+ pfd[num_pfd].events = POLLIN;
+ pfd[num_pfd].revents = 0;
+ num_pfd++;
+ }
+ cnt--;
+ }
+
+ have_source = 0;
+ for (n = 1; cnt && n < num_pfd; n++) {
+ if (! pfd[n].revents)
+ continue;
+ cnt--;
+
+ if (pfd[n].fd == -1)
+ continue;
+
+ if (source == pfd[n].fd) {
+ have_source = n;
+ } else {
+ len = readline (pfd[n].fd, line, sizeof (line));
+ if (len < 0) {
+ clients_remove (&clients, pfd[n].fd);
+ close (pfd[n].fd);
+ pfd[n].fd = -1;
+ continue;
+ }
+
+ if (strncmp (line, ".image", 6) == 0) {
+ if (! clients_image (&clients, pfd[n].fd, line + 7)) {
+ clients_remove (&clients, pfd[n].fd);
+ close (pfd[n].fd);
+ pfd[n].fd = -1;
+ continue;
+ }
+ } else if (strncmp (line, ".complete", 9) == 0) {
+ clients_complete (&clients, pfd[n].fd);
+ } else if (strncmp (line, ".recording", 10) == 0) {
+ clients_recording (&clients, pfd[n].fd, line + 6);
+ } else {
+ printf ("do_command (%s)\n", line);
+ }
+ }
+ }
+
+ if (have_source) {
+ do {
+ len = read (source, line, sizeof (line));
+ if (len > 0) {
+ clients_send_trace (&clients, line, len);
+ } else if (len == 0) {
+ close (source);
+ pfd[have_source].fd = source = -1;
+ goto done;
+ } else
+ break;
+ } while (1);
+ }
+
+ for (n = cnt = 1; n < num_pfd; n++) {
+ if (pfd[n].fd != -1) {
+ if (cnt != n)
+ pfd[cnt] = pfd[n];
+ cnt++;
+ }
+ }
+ num_pfd = cnt;
+ }
+
+done:
+ ret = 0;
+ for (n = 0; n < num_pfd; n++) {
+ if (pfd[n].fd != -1)
+ close (pfd[n].fd);
+ }
+ free (pfd);
+ clients_fini (&clients);
+
+ return ret;
+}
+
+static void *
+client_shm (const char *shm_path)
+{
+ void *base;
+ int fd;
+
+ fd = shm_open (shm_path, O_RDWR, 0);
+ if (fd == -1)
+ return MAP_FAILED;
+
+ base = mmap (NULL, DATA_SIZE,
+ PROT_READ | PROT_WRITE,
+ MAP_SHARED | MAP_NORESERVE,
+ fd, 0);
+ close (fd);
+
+ return base;
+}
+
+static int
+client_socket (const char *socket_path)
+{
+ struct sockaddr_un addr;
+ int sk;
+
+ sk = socket (PF_UNIX, SOCK_STREAM, 0);
+ if (sk == -1)
+ return -1;
+
+ memset (&addr, 0, sizeof (addr));
+ addr.sun_family = AF_UNIX;
+ strcpy (addr.sun_path, socket_path);
+
+ if (connect (sk, (struct sockaddr *) &addr, sizeof (addr)) == -1)
+ return -1;
+
+ return sk;
+}
+
+static int
+do_client (int fd,
+ const char *target,
+ const char *name,
+ const char *reference,
+ cairo_content_t content)
+{
+ struct client client;
+ const cairo_script_interpreter_hooks_t hooks = {
+ .closure = &client,
+ .surface_create = _surface_create,
+ .context_create = _context_create,
+ .context_destroy = _context_destroy,
+ };
+ void *closure;
+ char *buf;
+ int buf_size;
+ int len = 0, ret;
+ struct pollfd pfd;
+
+ client.sk = fd;
+ client.target = cairo_boilerplate_get_target_by_name (target, content);
+ client.context_id = 0;
+
+ client.surface = client.target->create_surface (NULL, content, 1, 1, 1, 1,
+ CAIRO_BOILERPLATE_MODE_TEST,
+ &closure);
+ if (client.surface == NULL) {
+ fprintf (stderr, "Failed to create target surface: %s.\n",
+ client.target->name);
+ return 1;
+ }
+
+ buf_size = 65536;
+ buf = xmalloc (buf_size);
+
+ if (reference != NULL) {
+ len = sprintf (buf,
+ "client-command name=%s target=%s reference=%s\n",
+ name, target, reference);
+ } else {
+ len = sprintf (buf,
+ "client-command name=%s target=%s\n",
+ name, target);
+ }
+ if (! writen (fd, buf, len))
+ return 1;
+
+ len = readline (fd, buf, buf_size);
+ client.base = client_shm (buf);
+ if (client.base == MAP_FAILED) {
+ fprintf (stderr, "Failed to map shared memory segment '%s'.\n", buf);
+ return 1;
+ }
+
+ if (daemonize () < 0)
+ return 1;
+
+ pfd.fd = client_socket ("/tmp/cairo-sphinx");
+ if (pfd.fd < 0)
+ return 1;
+
+ len = sprintf (buf, "client-trace name=%s\n", name);
+ if (! writen (pfd.fd, buf, len))
+ return 1;
+
+ client.csi = cairo_script_interpreter_create ();
+ cairo_script_interpreter_install_hooks (client.csi, &hooks);
+
+ nonblocking (pfd.fd);
+ pfd.events = POLLIN;
+ len = 0;
+ while (poll (&pfd, 1, -1) > 0) {
+ while ((ret = read (pfd.fd, buf + len, buf_size - len)) > 0) {
+ int end;
+
+ if (ret == buf_size - len) {
+ buf_size *= 2;
+ buf = xrealloc (buf, buf_size);
+ }
+ len += ret;
+
+ for (end = len; end > 0 && buf[--end] != '\n'; )
+ ;
+ if (end > 0) {
+ buf[end] = '\0';
+ cairo_script_interpreter_feed_string (client.csi, buf, end);
+
+ len -= end + 1;
+ if (len)
+ memmove (buf, buf + end + 1, len);
+ }
+ }
+ if (ret == 0)
+ break;
+ if (! (errno == EAGAIN || errno == EINTR))
+ break;
+ }
+
+ cairo_script_interpreter_finish (client.csi);
+ cairo_script_interpreter_destroy (client.csi);
+
+ cairo_surface_destroy (client.surface);
+ close (fd);
+
+ return 0;
+}
+
+static int
+do_exec (int fd, char **argv)
+{
+ char buf[4096];
+
+ if (*argv == NULL)
+ return 0;
+
+ snprintf (buf, sizeof (buf), "%s/cairo-trace.so", LIBDIR);
+ setenv ("LD_PRELOAD", buf, 1);
+
+ snprintf (buf, sizeof (buf), "0");
+ setenv ("CAIRO_TRACE_LINE_INFO", buf, 1);
+
+ snprintf (buf, sizeof (buf), "%d", fd);
+ setenv ("CAIRO_TRACE_FD", buf, 1);
+ putenv (buf);
+
+ return execvp (argv[0], argv);
+}
+
+static int
+do_wait (int fd)
+{
+ char buf;
+ int ret = read (fd, &buf, 1);
+ return ret != 0;
+}
+
+int
+main (int argc, char **argv)
+{
+ char buf[4096];
+ int len;
+ int fd;
+
+ if (argc == 1)
+ return do_server ("/tmp/cairo-sphinx");
+
+ fd = client_socket ("/tmp/cairo-sphinx");
+ if (fd < 0)
+ return 1;
+
+ if (strcmp (argv[1], "client") == 0) {
+ return do_client (fd, argv[2], argv[3], argv[4],
+ CAIRO_CONTENT_COLOR_ALPHA);
+ }
+
+ if (strcmp (argv[1], "wait") == 0) {
+ len = snprintf (buf, sizeof (buf), "wait %s\n", argv[2]);
+ if (! writen (fd, buf, len))
+ return 1;
+
+ return do_wait (fd);
+ }
+
+ if (strcmp (argv[1], "exec") == 0) {
+ len = snprintf (buf, sizeof (buf), "source\n");
+ if (! writen (fd, buf, len))
+ return 1;
+
+ return do_exec (fd, argv+2);
+ }
+
+ if (strcmp (argv[1], "replay") == 0) {
+ len = snprintf (buf, sizeof (buf), "replay %s\n", argv[2]);
+ return ! writen (fd, buf, len);
+ }
+
+ return 0;
+}
diff --git a/util/cairo-trace/.gitignore b/util/cairo-trace/.gitignore
new file mode 100644
index 000000000..b5f866669
--- /dev/null
+++ b/util/cairo-trace/.gitignore
@@ -0,0 +1 @@
+cairo-trace
diff --git a/util/cairo-trace/COPYING b/util/cairo-trace/COPYING
new file mode 100644
index 000000000..37aeee076
--- /dev/null
+++ b/util/cairo-trace/COPYING
@@ -0,0 +1,5 @@
+Cairo is free software.
+
+cairo-trace is released under the terms of the GNU General Public License
+(GPL) version 3. Please see COPYING-GPL-3 for the precise terms and
+conditions.
diff --git a/util/cairo-trace/COPYING-GPL-3 b/util/cairo-trace/COPYING-GPL-3
new file mode 100644
index 000000000..94a9ed024
--- /dev/null
+++ b/util/cairo-trace/COPYING-GPL-3
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ 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/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ <program> Copyright (C) <year> <name of author>
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
diff --git a/util/cairo-trace/Makefile.am b/util/cairo-trace/Makefile.am
new file mode 100644
index 000000000..3278abe42
--- /dev/null
+++ b/util/cairo-trace/Makefile.am
@@ -0,0 +1,40 @@
+cairolibdir = $(libdir)/cairo
+cairooutdir = $(localstatedir)/lib/cairo-trace
+
+bin_SCRIPTS = cairo-trace
+cairolib_LTLIBRARIES = libcairo-trace.la
+
+AM_CPPFLAGS = -I$(top_srcdir)/src \
+ -I$(top_builddir)/src
+
+libcairo_trace_la_SOURCES = trace.c
+libcairo_trace_la_CPPFLAGS = -DCAIRO_TRACE_OUTDIR="\"$(cairooutdir)\"" \
+ $(AM_CPPFLAGS)
+libcairo_trace_la_CFLAGS = $(CAIRO_CFLAGS) $(real_pthread_CFLAGS)
+libcairo_trace_la_LDFLAGS = -no-undefined
+
+libcairo_trace_la_LIBADD = $(real_pthread_LIBS) -lz
+if CAIRO_HAS_DL
+libcairo_trace_la_LIBADD += -ldl
+endif
+
+if CAIRO_HAS_SYMBOL_LOOKUP
+libcairo_trace_la_SOURCES += \
+ lookup-symbol.c \
+ lookup-symbol.h
+libcairo_trace_la_LIBADD += $(BFD_LIBS)
+endif
+
+
+system-install: install
+ -mkdir -p $(cairooutdir)
+ -chmod 01777 $(cairooutdir)
+ grep -sq $(cairolibdir)/libcairo-trace.so /etc/ld.so.preload || echo $(cairolibdir)/libcairo-trace.so >> /etc/ld.so.preload
+
+system-uninstall: uninstall
+ sed -e '/libcairo-trace.so/d' < /etc/ld.so.preload > /tmp/ld.so.preload && mv /tmp/ld.so.preload /etc/ld.so.preload;
+
+EXTRA_DIST = \
+ COPYING \
+ COPYING-GPL-3 \
+ cairo-trace.in
diff --git a/util/cairo-trace/cairo-trace.in b/util/cairo-trace/cairo-trace.in
new file mode 100644
index 000000000..ece90d3eb
--- /dev/null
+++ b/util/cairo-trace/cairo-trace.in
@@ -0,0 +1,136 @@
+#!/bin/sh
+
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+
+nofile=
+flush=
+nocallers=
+nomarkdirty=
+compress=
+
+usage() {
+cat << EOF
+usage: cairo-trace [--no-file] command
+cairo-trace will generate a log of all calls made by command to
+cairo. This log will be stored in a file in the local directory
+called command.pid.trace.
+Whatever else happens is driven by its argument:
+ --flush - Flush the output trace after every call.
+ --no-file - Disable the creation of an output file. Outputs to the
+ terminal instead.
+ --no-callers - Do not lookup the caller address/symbol/line whilst tracing.
+ --mark-dirty - Record image data for cairo_mark_dirty() [default]
+ --no-mark-dirty - Do not record image data for cairo_mark_dirty()
+ --compress - Compress the output with LZMA
+ --profile - Combine --no-callers and --no-mark-dirty and --compress
+
+Environment variables understood by cairo-trace:
+ CAIRO_TRACE_FLUSH - flush the output after every function call.
+ CAIRO_TRACE_LINE_INFO - emit line information for most function calls.
+EOF
+exit
+}
+
+skip=1
+while test $skip -eq 1; do
+ skip=0
+ case $1 in
+ --flush)
+ skip=1
+ flush=1
+ ;;
+ --no-file)
+ skip=1
+ nofile=1
+ ;;
+ --no-callers)
+ skip=1
+ nocallers=1
+ ;;
+ --mark-dirty)
+ skip=1
+ nomarkdirty=
+ ;;
+ --no-mark-dirty)
+ skip=1
+ nomarkdirty=1
+ ;;
+ --compress)
+ skip=1
+ compress=1
+ nofile=1
+ ;;
+ --profile)
+ skip=1
+ compress=1
+ nomarkdirty=1
+ nocallers=1
+ nofile=1
+ ;;
+ --version)
+ echo "cairo-trace, version @CAIRO_VERSION_MAJOR@.@CAIRO_VERSION_MINOR@.@CAIRO_VERSION_MICRO@."
+ exit
+ ;;
+ --help)
+ usage
+ ;;
+ esac
+ if test $skip -eq 1; then
+ shift
+ fi
+done
+
+if test $# -eq 0; then
+ usage
+fi
+
+CAIRO_TRACE_PROG_NAME="$1"
+export CAIRO_TRACE_PROG_NAME
+
+if test "x$CAIRO_TRACE_SO" = "x"; then
+ CAIRO_TRACE_SO=""
+ for lib in @libdir@/cairo/libcairo-trace.@SHLIB_EXT@ @libdir@/cairo/libcairo-trace.@SHLIB_EXT@* @libdir@/cairo/libcairo-trace.*.@SHLIB_EXT@ ; do
+ if test -h "$lib" -o -f "$lib"; then
+ CAIRO_TRACE_SO="$lib"
+ break
+ fi
+ done
+fi
+if test "x$CAIRO_TRACE_SO" = "x"; then
+ echo "Could not find the cairo-trace shared library in @libdir@/cairo/." >&2
+ echo "Set the CAIRO_TRACE_SO environment variable to the full path of the library." >&2
+ exit 15
+fi
+
+LD_PRELOAD="$CAIRO_TRACE_SO"
+DYLD_INSERT_LIBRARIES="$CAIRO_TRACE_SO"
+DYLD_FORCE_FLAT_NAMESPACE=1
+export LD_PRELOAD
+export DYLD_INSERT_LIBRARIES
+export DYLD_FORCE_FLAT_NAMESPACE
+
+if test -n "$nocallers"; then
+ CAIRO_TRACE_LINE_INFO=0
+ export CAIRO_TRACE_LINE_INFO
+fi
+
+if test -n "$nomarkdirty"; then
+ CAIRO_TRACE_MARK_DIRTY=0
+ export CAIRO_TRACE_MARK_DIRTY
+fi
+
+if test -n "$flush"; then
+ CAIRO_TRACE_FLUSH=1
+ export CAIRO_TRACE_FLUSH
+fi
+
+if test -z "$nofile"; then
+ CAIRO_TRACE_OUTDIR=`pwd` "$@"
+elif test -n "$compress"; then
+ name=`basename $1`
+ echo Generating compressed trace file $name.$$.lzma
+ CAIRO_TRACE_FD=3 "$@" 3>&1 >/dev/null | lzma -cz9 > $name.$$.lzma
+else
+ CAIRO_TRACE_FD=3 "$@" 3>&1 >/dev/null
+fi
diff --git a/util/cairo-trace/lookup-symbol.c b/util/cairo-trace/lookup-symbol.c
new file mode 100644
index 000000000..f9665b36f
--- /dev/null
+++ b/util/cairo-trace/lookup-symbol.c
@@ -0,0 +1,331 @@
+/* cairo-trace - a utility to record and replay calls to the Cairo library.
+ *
+ * Copyright © 2008 Chris Wilson
+ *
+ * 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/>.
+ */
+
+/*
+ * A less hacky utility to lookup the debug strings for a particular
+ * .text address.
+ * Derived from backtrace-symbols.c in cairo by Chris Wilson.
+ */
+
+/*
+ A hacky replacement for backtrace_symbols in glibc
+
+ backtrace_symbols in glibc looks up symbols using dladdr which is limited
+ in the symbols that it sees. libbacktracesymbols opens the executable and
+ shared libraries using libbfd and will look up backtrace information using
+ the symbol table and the dwarf line information.
+
+ It may make more sense for this program to use libelf instead of libbfd.
+ However, I have not investigated that yet.
+
+ Derived from addr2line.c from GNU Binutils by Jeff Muizelaar
+
+ Copyright 2007 Jeff Muizelaar
+ */
+
+/* addr2line.c -- convert addresses to line number and function name
+ Copyright 1997, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ Contributed by Ulrich Lauther <Ulrich.Lauther@mchp.siemens.de>
+
+ This file was part of GNU Binutils.
+ */
+
+#define _GNU_SOURCE
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#define true 1
+#define false 0
+
+#include "lookup-symbol.h"
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <link.h>
+#include <string.h>
+#include <pthread.h>
+
+#if HAVE_BFD
+#include <bfd.h>
+#include <libiberty.h>
+
+struct symtab {
+ bfd *bfd;
+ asymbol **syms;
+};
+
+struct symbol {
+ int found;
+ bfd_vma pc;
+ struct symtab *symtab;
+ const char *filename;
+ const char *functionname;
+ unsigned int line;
+};
+
+
+static void
+_symtab_fini (struct symtab *symtab)
+{
+ free (symtab->syms);
+ if (symtab->bfd != NULL)
+ bfd_close (symtab->bfd);
+}
+
+/* Read in the symbol table. */
+static int
+_symtab_init (struct symtab *symtab, const char *filename)
+{
+ char **matching;
+ long symcount;
+ unsigned int size;
+
+ symtab->bfd = NULL;
+ symtab->syms = NULL;
+
+ symtab->bfd = bfd_openr (filename, NULL);
+ if (symtab->bfd == NULL)
+ goto BAIL;
+
+ if (bfd_check_format (symtab->bfd, bfd_archive))
+ goto BAIL;
+
+ if (! bfd_check_format_matches (symtab->bfd, bfd_object, &matching))
+ goto BAIL;
+
+ symcount = bfd_read_minisymbols (symtab->bfd, false, (PTR) &symtab->syms, &size);
+ if (symcount == 0) {
+ symcount = bfd_read_minisymbols (symtab->bfd, true /* dynamic */ ,
+ (PTR) &symtab->syms, &size);
+ }
+ if (symcount < 0)
+ goto BAIL;
+
+ if ((bfd_get_file_flags (symtab->bfd) & HAS_SYMS) == 0)
+ goto BAIL;
+
+ return 1;
+
+BAIL:
+ _symtab_fini (symtab);
+ return 0;
+}
+
+/* Look for an address in a section.
+ * This is called via bfd_map_over_sections.
+ */
+static void
+find_address_in_section (bfd *abfd,
+ asection *section,
+ void *data)
+{
+ bfd_vma vma;
+ bfd_size_type size;
+ struct symbol *symbol = data;
+ struct symtab *symtab = symbol->symtab;
+
+ if (symbol->found)
+ return;
+
+ if ((bfd_get_section_flags (symtab->bfd, section) & SEC_ALLOC) == 0)
+ return;
+
+ vma = bfd_get_section_vma (symtab->bfd, section);
+ if (symbol->pc < vma)
+ return;
+
+ size = bfd_section_size (symtab->bfd, section);
+ if (symbol->pc >= vma + size)
+ return;
+
+ symbol->found = bfd_find_nearest_line (symtab->bfd, section,
+ symtab->syms,
+ symbol->pc - vma,
+ &symbol->filename,
+ &symbol->functionname,
+ &symbol->line);
+}
+
+static void
+_symbol_fini (struct symbol *symbol)
+{
+}
+
+static void
+_symbol_init (struct symbol *symbol, struct symtab *symtab, bfd_vma addr)
+{
+ symbol->found = false;
+ symbol->symtab = symtab;
+ symbol->pc = addr;
+}
+
+static void
+_symbol_print (struct symbol *symbol, char *buf, int buflen, const char *filename)
+{
+ const char *name, *h;
+ char path[1024];
+
+ if (! symbol->found)
+ return;
+
+ name = symbol->functionname;
+ if (name == NULL || *name == '\0')
+ name = "??";
+
+ if (symbol->filename != NULL)
+ filename = symbol->filename;
+ if (strcmp (filename, "/proc/self/exe") == 0) {
+ int len = readlink ("/proc/self/exe", path, sizeof (path) - 1);
+ if (len != -1) {
+ path[len] = '\0';
+ filename = path;
+ }
+ }
+ h = strrchr (filename, '/');
+ if (h != NULL)
+ filename = h + 1;
+
+ if (symbol->line) {
+ snprintf (buf, buflen, "%s() [%s:%u]",
+ name, filename, symbol->line);
+ } else {
+ snprintf (buf, buflen, "%s() [%s]", name, filename);
+ }
+}
+#endif
+
+struct file_match {
+ const char *file;
+ ElfW(Addr) address;
+ ElfW(Addr) base;
+ void *hdr;
+};
+
+static int
+find_matching_file (struct dl_phdr_info *info, size_t size, void *data)
+{
+ struct file_match *match = data;
+ /* This code is modeled from Gfind_proc_info-lsb.c:callback() from libunwind */
+ long n;
+ const ElfW(Phdr) *phdr;
+ ElfW(Addr) load_base = info->dlpi_addr;
+
+ phdr = info->dlpi_phdr;
+ for (n = info->dlpi_phnum; --n >= 0; phdr++) {
+ if (phdr->p_type == PT_LOAD) {
+ ElfW(Addr) vaddr = phdr->p_vaddr + load_base;
+ if (match->address >= vaddr &&
+ match->address < vaddr + phdr->p_memsz)
+ {
+ /* we found a match */
+ match->file = info->dlpi_name;
+ match->base = info->dlpi_addr;
+ return 1;
+ }
+ }
+ }
+
+ return 0;
+}
+
+struct symbol_cache_entry {
+ const void *ptr;
+ struct symbol_cache_entry *hash_prev, *hash_next;
+ char name[0];
+};
+
+static struct symbol_cache_entry *symbol_cache_hash[13477];
+static pthread_mutex_t symbol_cache_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+char *
+lookup_symbol (char *buf, int buflen, const void *ptr)
+{
+ struct file_match match;
+#if HAVE_BFD
+ struct symtab symtab;
+ struct symbol symbol;
+#endif
+ struct symbol_cache_entry *cache;
+ int bucket;
+ int len;
+
+ bucket = (unsigned long) ptr % (sizeof (symbol_cache_hash) / sizeof (symbol_cache_hash[0]));
+ pthread_mutex_lock (&symbol_cache_mutex);
+ for (cache = symbol_cache_hash[bucket];
+ cache != NULL;
+ cache = cache->hash_next)
+ {
+ if (cache->ptr == ptr) {
+ if (cache->hash_prev != NULL) {
+ cache->hash_prev->hash_next = cache->hash_next;
+ if (cache->hash_next != NULL)
+ cache->hash_next->hash_prev = cache->hash_prev;
+ cache->hash_prev = NULL;
+ cache->hash_next = symbol_cache_hash[bucket];
+ symbol_cache_hash[bucket]->hash_prev = cache;
+ symbol_cache_hash[bucket] = cache;
+ }
+
+ pthread_mutex_unlock (&symbol_cache_mutex);
+ return cache->name;
+ }
+ }
+ pthread_mutex_unlock (&symbol_cache_mutex);
+
+ match.file = NULL;
+ match.address = (ElfW(Addr)) ptr;
+ dl_iterate_phdr (find_matching_file, &match);
+
+ snprintf (buf, buflen, "0x%llx",
+ (long long unsigned int) match.address);
+
+ if (match.file == NULL || *match.file == '\0')
+ match.file = "/proc/self/exe";
+
+#if HAVE_BFD
+ if (_symtab_init (&symtab, match.file)) {
+ _symbol_init (&symbol, &symtab, match.address - match.base);
+ bfd_map_over_sections (symtab.bfd, find_address_in_section, &symbol);
+ if (symbol.found)
+ _symbol_print (&symbol, buf, buflen, match.file);
+ _symbol_fini (&symbol);
+
+ _symtab_fini (&symtab);
+ }
+#endif
+
+ len = strlen (buf);
+ cache = malloc (sizeof (struct symbol_cache_entry) + len + 1);
+ if (cache != NULL) {
+ cache->ptr = ptr;
+ memcpy (cache->name, buf, len + 1);
+
+ pthread_mutex_lock (&symbol_cache_mutex);
+ cache->hash_prev = NULL;
+ cache->hash_next = symbol_cache_hash[bucket];
+ if (symbol_cache_hash[bucket] != NULL)
+ symbol_cache_hash[bucket]->hash_prev = cache;
+ symbol_cache_hash[bucket] = cache;
+ pthread_mutex_unlock (&symbol_cache_mutex);
+ }
+
+ return buf;
+}
diff --git a/util/cairo-trace/lookup-symbol.h b/util/cairo-trace/lookup-symbol.h
new file mode 100644
index 000000000..83817edc6
--- /dev/null
+++ b/util/cairo-trace/lookup-symbol.h
@@ -0,0 +1,24 @@
+/* cairo-trace - a utility to record and replay calls to the Cairo library.
+ *
+ * Copyright © 2008 Chris Wilson
+ *
+ * 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/>.
+ */
+
+#ifndef LOOKUP_SYMBOLS_H
+
+char *
+lookup_symbol (char *buf, int len, const void *ptr);
+
+#endif /*LOOKUP_SYMBOLS_H */
diff --git a/util/cairo-trace/trace.c b/util/cairo-trace/trace.c
new file mode 100644
index 000000000..d5d76689c
--- /dev/null
+++ b/util/cairo-trace/trace.c
@@ -0,0 +1,5581 @@
+/* cairo-trace - a utility to record and replay calls to the Cairo library.
+ *
+ * Copyright © 2008 Chris Wilson
+ *
+ * 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/>.
+ */
+
+#define _GNU_SOURCE
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+/* 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__)
+# define SIZEOF_VOID_P SIZEOF_VOID__
+#endif
+
+#include <dlfcn.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <errno.h>
+#include <pthread.h>
+#include <zlib.h>
+#include <math.h>
+#include <locale.h> /* for locale independent %f printing */
+#include <ctype.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <stdarg.h>
+
+#include <cairo.h>
+#if CAIRO_HAS_FT_FONT
+# include <cairo-ft.h>
+#endif
+
+#ifndef TRUE
+#define TRUE 1
+#define FALSE 0
+#endif
+
+#ifndef CAIRO_TRACE_OUTDIR
+#define CAIRO_TRACE_OUTDIR "."
+#endif
+
+#define DEBUG_STACK 0
+
+#if HAVE_BYTESWAP_H
+# include <byteswap.h>
+#endif
+#ifndef bswap_16
+# define bswap_16(p) \
+ (((((uint16_t)(p)) & 0x00ff) << 8) | \
+ (((uint16_t)(p)) >> 8))
+#endif
+#ifndef bswap_32
+# define bswap_32(p) \
+ (((((uint32_t)(p)) & 0x000000ff) << 24) | \
+ ((((uint32_t)(p)) & 0x0000ff00) << 8) | \
+ ((((uint32_t)(p)) & 0x00ff0000) >> 8) | \
+ ((((uint32_t)(p))) >> 24))
+#endif
+
+#if WORDS_BIGENDIAN
+#define le16(x) bswap_16 (x)
+#define le32(x) bswap_32 (x)
+#define be16(x) x
+#define be32(x) x
+#define to_be32(x) x
+#else
+#define le16(x) x
+#define le32(x) x
+#define be16(x) bswap_16 (x)
+#define be32(x) bswap_32 (x)
+#define to_be32(x) bswap_32 (x)
+#endif
+
+#if CAIRO_HAS_SYMBOL_LOOKUP
+#include "lookup-symbol.h"
+#endif
+
+/* Reverse the bits in a byte with 7 operations (no 64-bit):
+ * Devised by Sean Anderson, July 13, 2001.
+ * Source: http://graphics.stanford.edu/~seander/bithacks.html#ReverseByteWith32Bits
+ */
+#define CAIRO_BITSWAP8(c) ((((c) * 0x0802LU & 0x22110LU) | ((c) * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16)
+
+#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4)
+#define CAIRO_PRINTF_FORMAT(fmt_index, va_index) \
+ __attribute__((__format__(__printf__, fmt_index, va_index)))
+#else
+#define CAIRO_PRINTF_FORMAT(fmt_index, va_index)
+#endif
+
+/* XXX implement manual vprintf so that the user can control precision of
+ * printed numbers.
+ */
+
+static void *_dlhandle = RTLD_NEXT;
+#define DLCALL(name, args...) ({ \
+ static typeof (&name) name##_real; \
+ if (name##_real == NULL) { \
+ name##_real = (typeof (&name))(dlsym (_dlhandle, #name)); \
+ if (name##_real == NULL && _dlhandle == RTLD_NEXT) { \
+ _dlhandle = dlopen ("libcairo." SHARED_LIB_EXT, RTLD_LAZY); \
+ name##_real = (typeof (&name))(dlsym (_dlhandle, #name)); \
+ assert (name##_real != NULL); \
+ } \
+ } \
+ (*name##_real) (args); \
+})
+
+#ifndef ARRAY_LENGTH
+#define ARRAY_LENGTH(__array) ((int) (sizeof (__array) / sizeof (__array[0])))
+#endif
+
+#if SIZEOF_VOID_P == 4
+#define PTR_SHIFT 2
+#elif SIZEOF_VOID_P == 8
+#define PTR_SHIFT 3
+#else
+#error Unexpected pointer size
+#endif
+#define BUCKET(b, ptr) (((unsigned long) (ptr) >> PTR_SHIFT) % ARRAY_LENGTH (b))
+
+#if defined(__GNUC__) && (__GNUC__ > 2) && defined(__OPTIMIZE__)
+#define _BOOLEAN_EXPR(expr) \
+ __extension__ ({ \
+ int _boolean_var_; \
+ if (expr) \
+ _boolean_var_ = 1; \
+ else \
+ _boolean_var_ = 0; \
+ _boolean_var_; \
+})
+#define LIKELY(expr) (__builtin_expect (_BOOLEAN_EXPR(expr), 1))
+#define UNLIKELY(expr) (__builtin_expect (_BOOLEAN_EXPR(expr), 0))
+#else
+#define LIKELY(expr) (expr)
+#define UNLIKELY(expr) (expr)
+#endif
+
+typedef struct _object Object;
+typedef struct _type Type;
+
+struct _object {
+ const void *addr;
+ Type *type;
+ unsigned long int token;
+ int width, height;
+ cairo_bool_t foreign;
+ cairo_bool_t defined;
+ cairo_bool_t unknown;
+ int operand;
+ void *data;
+ void (*destroy)(void *);
+ Object *next, *prev;
+};
+
+struct _type {
+ const char *name;
+
+ enum operand_type {
+ NONE,
+ SURFACE,
+ CONTEXT,
+ FONT_FACE,
+ PATTERN,
+ SCALED_FONT,
+ _N_OP_TYPES
+ } op_type;
+ const char *op_code;
+
+ pthread_mutex_t mutex;
+ struct _bitmap {
+ unsigned long int min;
+ unsigned long int count;
+ unsigned int map[64];
+ struct _bitmap *next;
+ } map;
+ Object *objects[607];
+ Type *next;
+};
+
+static struct _type_table {
+ pthread_mutex_t mutex;
+ Type *op_types[_N_OP_TYPES];
+} Types;
+
+static FILE *logfile;
+static cairo_bool_t _flush;
+static cairo_bool_t _error;
+static cairo_bool_t _line_info;
+static cairo_bool_t _mark_dirty;
+static const cairo_user_data_key_t destroy_key;
+static pthread_once_t once_control = PTHREAD_ONCE_INIT;
+static pthread_key_t counter_key;
+
+static void _init_trace (void);
+
+#define INIT_TRACE_ONCE() pthread_once (&once_control, _init_trace)
+
+#if __GNUC__ >= 3 && defined(__ELF__) && !defined(__sun)
+# define _enter_trace() INIT_TRACE_ONCE ()
+# define _exit_trace() do { } while (0)
+# define _should_trace() 1
+# define USE_ENTER_EXIT 0
+#else
+static void _enter_trace (void);
+static void _exit_trace (void);
+static cairo_bool_t _should_trace (void);
+# define USE_ENTER_EXIT 1
+#endif
+
+#if HAVE_BUILTIN_RETURN_ADDRESS && CAIRO_HAS_SYMBOL_LOOKUP
+#define _emit_line_info() do { \
+ if (_line_info && _write_lock ()) { \
+ void *addr = __builtin_return_address(0); \
+ char caller[1024]; \
+ _trace_printf ("%% %s() called by %s\n", __FUNCTION__, \
+ lookup_symbol (caller, sizeof (caller), addr)); \
+ _write_unlock (); \
+ } \
+} while (0)
+#else
+#define _emit_line_info()
+#endif
+
+static void
+_type_release_token (Type *t, unsigned long int token)
+{
+ struct _bitmap *b, **prev = NULL;
+
+ b = &t->map;
+ while (b != NULL) {
+ if (token < b->min + sizeof (b->map) * CHAR_BIT) {
+ unsigned int bit, elem;
+
+ token -= b->min;
+ elem = token / (sizeof (b->map[0]) * CHAR_BIT);
+ bit = token % (sizeof (b->map[0]) * CHAR_BIT);
+ b->map[elem] &= ~(1 << bit);
+ if (! --b->count && prev) {
+ *prev = b->next;
+ free (b);
+ }
+ return;
+ }
+ prev = &b->next;
+ b = b->next;
+ }
+}
+
+static unsigned long int
+_type_next_token (Type *t)
+{
+ struct _bitmap *b, *bb, **prev = NULL;
+ unsigned long int min = 0;
+
+ b = &t->map;
+ while (b != NULL) {
+ if (b->min != min)
+ break;
+
+ if (b->count < sizeof (b->map) * CHAR_BIT) {
+ unsigned int n, m, bit;
+ for (n = 0; n < ARRAY_LENGTH (b->map); n++) {
+ if (b->map[n] == (unsigned int) -1)
+ continue;
+
+ for (m=0, bit=1; m<sizeof (b->map[0])*CHAR_BIT; m++, bit<<=1) {
+ if ((b->map[n] & bit) == 0) {
+ b->map[n] |= bit;
+ b->count++;
+ return n * sizeof (b->map[0])*CHAR_BIT + m + b->min;
+ }
+ }
+ }
+ }
+ min += sizeof (b->map) * CHAR_BIT;
+
+ prev = &b->next;
+ b = b->next;
+ }
+
+ bb = malloc (sizeof (struct _bitmap));
+ *prev = bb;
+ bb->next = b;
+ bb->min = min;
+ bb->count = 1;
+ bb->map[0] = 0x1;
+ memset (bb->map + 1, 0, sizeof (bb->map) - sizeof (bb->map[0]));
+
+ return min;
+}
+
+static void
+_object_destroy (Object *obj)
+{
+ int bucket;
+
+ pthread_mutex_lock (&obj->type->mutex);
+ bucket = BUCKET (obj->type->objects, obj->addr);
+ _type_release_token (obj->type, obj->token);
+
+ if (obj->prev != NULL)
+ obj->prev->next = obj->next;
+ else
+ obj->type->objects[bucket] = obj->next;
+
+ if (obj->next != NULL)
+ obj->next->prev = obj->prev;
+ pthread_mutex_unlock (&obj->type->mutex);
+
+ if (obj->data != NULL && obj->destroy != NULL)
+ obj->destroy (obj->data);
+
+ free (obj);
+}
+
+static void
+_type_create (const char *typename,
+ enum operand_type op_type,
+ const char *op_code)
+{
+ Type *t;
+
+ pthread_mutex_lock (&Types.mutex);
+
+ t = malloc (sizeof (Type));
+ t->name = typename;
+ t->op_type = op_type;
+ t->op_code = op_code;
+
+ pthread_mutex_init (&t->mutex, NULL);
+
+ t->map.min = 0;
+ t->map.count = 0;
+ memset (t->map.map, 0, sizeof (t->map.map));
+ t->map.next = NULL;
+
+ memset (t->objects, 0, sizeof (t->objects));
+
+ t->next = NULL;
+
+ Types.op_types[op_type] = t;
+ pthread_mutex_unlock (&Types.mutex);
+}
+
+static Type *
+_get_type (enum operand_type type)
+{
+ return Types.op_types[type];
+}
+
+static void
+_type_destroy (Type *t)
+{
+ int n;
+ struct _bitmap *b;
+
+ for (n = 0; n < ARRAY_LENGTH (t->objects); n++) {
+ Object *obj = t->objects[n];
+ while (obj != NULL) {
+ Object *next = obj->next;
+ _object_destroy (obj);
+ obj = next;
+ }
+ }
+
+ b = t->map.next;
+ while (b != NULL) {
+ struct _bitmap *next = b->next;
+ free (b);
+ b = next;
+ }
+
+ pthread_mutex_destroy (&t->mutex);
+ free (t);
+}
+
+static Object *
+_type_get_object (Type *type, const void *ptr)
+{
+ Object *obj;
+ int bucket = BUCKET (type->objects, ptr);
+
+ for (obj = type->objects[bucket]; obj != NULL; obj = obj->next) {
+ if (obj->addr == ptr) {
+ if (obj->prev != NULL) { /* mru */
+ obj->prev->next = obj->next;
+ if (obj->next != NULL)
+ obj->next->prev = obj->prev;
+ obj->prev = NULL;
+ type->objects[bucket]->prev = obj;
+ obj->next = type->objects[bucket];
+ type->objects[bucket] = obj;
+ }
+ return obj;
+ }
+ }
+
+ return NULL;
+}
+
+static Object *
+_object_create (Type *type, const void *ptr)
+{
+ Object *obj;
+ int bucket = BUCKET (type->objects, ptr);
+
+ obj = malloc (sizeof (Object));
+ obj->unknown = TRUE;
+ obj->defined = FALSE;
+ obj->foreign = FALSE;
+ obj->operand = -1;
+ obj->type = type;
+ obj->addr = ptr;
+ obj->token = _type_next_token (type);
+ obj->data = NULL;
+ obj->destroy = NULL;
+ obj->prev = NULL;
+ obj->next = type->objects[bucket];
+ if (type->objects[bucket] != NULL)
+ type->objects[bucket]->prev = obj;
+ type->objects[bucket] = obj;
+
+ return obj;
+}
+
+#if USE_ENTER_EXIT
+static int *
+_get_counter (void)
+{
+ int *counter = pthread_getspecific (counter_key);
+ if (counter == NULL) {
+ counter = calloc(1, sizeof(int));
+ pthread_setspecific (counter_key, counter);
+ }
+ return counter;
+}
+
+static void
+_enter_trace (void)
+{
+ INIT_TRACE_ONCE ();
+ _get_counter ()[0]++;
+}
+
+static void
+_exit_trace (void)
+{
+ _get_counter ()[0]--;
+}
+
+static cairo_bool_t
+_should_trace (void)
+{
+ return _get_counter ()[0] <= 1;
+}
+#endif /* USE_ENTER_EXIT */
+
+static void
+_init_trace (void)
+{
+ pthread_mutex_init (&Types.mutex, NULL);
+ pthread_key_create (&counter_key, free);
+
+ _type_create ("unclassed", NONE, "");
+ _type_create ("cairo_t", CONTEXT, "c");
+ _type_create ("cairo_font_face_t", FONT_FACE, "f");
+ _type_create ("cairo_pattern_t", PATTERN, "p");
+ _type_create ("cairo_scaled_font_t", SCALED_FONT, "sf");
+ _type_create ("cairo_surface_t", SURFACE, "s");
+}
+
+static void
+_close_trace (void)
+{
+ if (logfile != NULL) {
+ fclose (logfile);
+ logfile = NULL;
+ }
+}
+
+static void __attribute__ ((destructor))
+_fini_trace (void)
+{
+ int n;
+
+ _close_trace ();
+
+ for (n = 0; n < ARRAY_LENGTH (Types.op_types); n++) {
+ if (Types.op_types[n]) {
+ _type_destroy (Types.op_types[n]);
+ Types.op_types[n] = NULL;
+ }
+ }
+
+ pthread_mutex_destroy (&Types.mutex);
+}
+
+/* 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
+ *
+ * The code in the patch is copyright Red Hat, Inc under the LGPL.
+ */
+#define SIGNIFICANT_DIGITS_AFTER_DECIMAL 6
+static void
+_trace_dtostr (char *buffer, size_t size, double d)
+{
+ struct lconv *locale_data;
+ const char *decimal_point;
+ int decimal_point_len;
+ char *p;
+ int decimal_len;
+ int num_zeros, decimal_digits;
+
+ /* Omit the minus sign from negative zero. */
+ if (d == 0.0)
+ d = 0.0;
+
+ locale_data = localeconv ();
+ decimal_point = locale_data->decimal_point;
+ decimal_point_len = strlen (decimal_point);
+
+ /* Using "%f" to print numbers less than 0.1 will result in
+ * reduced precision due to the default 6 digits after the
+ * decimal point.
+ *
+ * For numbers is < 0.1, we print with maximum precision and count
+ * the number of zeros between the decimal point and the first
+ * significant digit. We then print the number again with the
+ * number of decimal places that gives us the required number of
+ * significant digits. This ensures the number is correctly
+ * rounded.
+ */
+ if (fabs (d) >= 0.1) {
+ snprintf (buffer, size, "%f", d);
+ } else {
+ snprintf (buffer, size, "%.18f", d);
+ p = buffer;
+
+ if (*p == '+' || *p == '-')
+ p++;
+
+ while (isdigit (*p))
+ p++;
+
+ if (strncmp (p, decimal_point, decimal_point_len) == 0)
+ p += decimal_point_len;
+
+ num_zeros = 0;
+ while (*p++ == '0')
+ num_zeros++;
+
+ decimal_digits = num_zeros + SIGNIFICANT_DIGITS_AFTER_DECIMAL;
+
+ if (decimal_digits < 18)
+ snprintf (buffer, size, "%.*f", decimal_digits, d);
+ }
+ p = buffer;
+
+ if (*p == '+' || *p == '-')
+ p++;
+
+ while (isdigit (*p))
+ p++;
+
+ if (strncmp (p, decimal_point, decimal_point_len) == 0) {
+ *p = '.';
+ decimal_len = strlen (p + decimal_point_len);
+ memmove (p + 1, p + decimal_point_len, decimal_len);
+ p[1 + decimal_len] = 0;
+
+ /* Remove trailing zeros and decimal point if possible. */
+ for (p = p + decimal_len; *p == '0'; p--)
+ *p = 0;
+
+ if (*p == '.') {
+ *p = 0;
+ p--;
+ }
+ }
+}
+
+enum {
+ LENGTH_MODIFIER_LONG = 0x100
+};
+
+/* Here's a limited reimplementation of printf. The reason for doing
+ * this is primarily to special case handling of doubles. We want
+ * locale independent formatting of doubles and we want to trim
+ * trailing zeros. This is handled by dtostr() above, and the code
+ * below handles everything else by calling snprintf() to do the
+ * formatting. This functionality is only for internal use and we
+ * only implement the formats we actually use.
+ */
+static void CAIRO_PRINTF_FORMAT(1, 0)
+_trace_vprintf (const char *fmt, va_list ap)
+{
+#define SINGLE_FMT_BUFFER_SIZE 32
+ char buffer[512], single_fmt[SINGLE_FMT_BUFFER_SIZE];
+ int single_fmt_length;
+ char *p;
+ const char *f, *start;
+ int length_modifier, width;
+ cairo_bool_t var_width;
+ int ret_ignored;
+
+ assert (_should_trace ());
+
+ f = fmt;
+ p = buffer;
+ while (*f != '\0') {
+ if (*f != '%') {
+ *p++ = *f++;
+ continue;
+ }
+
+ start = f;
+ f++;
+
+ if (*f == '0')
+ f++;
+
+ var_width = 0;
+ if (*f == '*') {
+ var_width = 1;
+ f++;
+ }
+
+ while (isdigit (*f))
+ f++;
+
+ length_modifier = 0;
+ if (*f == 'l') {
+ length_modifier = LENGTH_MODIFIER_LONG;
+ f++;
+ }
+
+ /* The only format strings exist in the cairo implementation
+ * itself. So there's an internal consistency problem if any
+ * of them is larger than our format buffer size. */
+ single_fmt_length = f - start + 1;
+
+ /* Reuse the format string for this conversion. */
+ memcpy (single_fmt, start, single_fmt_length);
+ single_fmt[single_fmt_length] = '\0';
+
+ /* Flush contents of buffer before snprintf()'ing into it. */
+ ret_ignored = fwrite (buffer, 1, p-buffer, logfile);
+
+ /* We group signed and unsigned together in this switch, the
+ * only thing that matters here is the size of the arguments,
+ * since we're just passing the data through to sprintf(). */
+ switch (*f | length_modifier) {
+ case '%':
+ buffer[0] = *f;
+ buffer[1] = 0;
+ break;
+ case 'd':
+ case 'u':
+ case 'o':
+ case 'x':
+ case 'X':
+ if (var_width) {
+ width = va_arg (ap, int);
+ snprintf (buffer, sizeof buffer,
+ single_fmt, width, va_arg (ap, int));
+ } else {
+ snprintf (buffer, sizeof buffer, single_fmt, va_arg (ap, int));
+ }
+ break;
+ case 'd' | LENGTH_MODIFIER_LONG:
+ case 'u' | LENGTH_MODIFIER_LONG:
+ case 'o' | LENGTH_MODIFIER_LONG:
+ case 'x' | LENGTH_MODIFIER_LONG:
+ case 'X' | LENGTH_MODIFIER_LONG:
+ if (var_width) {
+ width = va_arg (ap, int);
+ snprintf (buffer, sizeof buffer,
+ single_fmt, width, va_arg (ap, long int));
+ } else {
+ snprintf (buffer, sizeof buffer,
+ single_fmt, va_arg (ap, long int));
+ }
+ break;
+ case 's':
+ snprintf (buffer, sizeof buffer,
+ single_fmt, va_arg (ap, const char *));
+ break;
+ case 'f':
+ case 'g':
+ _trace_dtostr (buffer, sizeof buffer, va_arg (ap, double));
+ break;
+ case 'c':
+ buffer[0] = va_arg (ap, int);
+ buffer[1] = 0;
+ break;
+ default:
+ break;
+ }
+ p = buffer + strlen (buffer);
+ f++;
+ }
+
+ ret_ignored = fwrite (buffer, 1, p-buffer, logfile);
+ (void)ret_ignored;
+}
+
+static void CAIRO_PRINTF_FORMAT(1, 2)
+_trace_printf (const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start (ap, fmt);
+ _trace_vprintf (fmt, ap);
+ va_end (ap);
+}
+
+static void
+get_prog_name (char *buf, int length)
+{
+ char *slash;
+ FILE *file;
+
+ memset (buf, 0, length);
+ if (length == 0)
+ return;
+
+ file = fopen ("/proc/self/cmdline", "rb");
+ if (file != NULL) {
+ slash = fgets (buf, length, file);
+ fclose (file);
+
+ if (slash == NULL)
+ return;
+ } else {
+ char const *name = getenv ("CAIRO_TRACE_PROG_NAME");
+ if (name != NULL) {
+ strncpy (buf, name, length-1);
+ }
+ }
+
+ slash = strrchr (buf, '/');
+ if (slash != NULL) {
+ size_t len = strlen (slash+1);
+ memmove (buf, slash+1, len+1);
+ }
+}
+
+static void
+_emit_header (void)
+{
+ char name[4096] = "";
+
+ get_prog_name (name, sizeof (name));
+
+ _trace_printf ("%%!CairoScript - %s\n", name);
+}
+
+static cairo_bool_t
+_init_logfile (void)
+{
+ static cairo_bool_t initialized;
+ char buf[4096];
+ const char *filename;
+ const char *env;
+
+ if (initialized)
+ return logfile != NULL;
+
+ initialized = TRUE;
+
+ env = getenv ("CAIRO_TRACE_FLUSH");
+ if (env != NULL)
+ _flush = atoi (env);
+
+ _line_info = TRUE;
+ env = getenv ("CAIRO_TRACE_LINE_INFO");
+ if (env != NULL)
+ _line_info = atoi (env);
+
+ _mark_dirty = TRUE;
+ env = getenv ("CAIRO_TRACE_MARK_DIRTY");
+ if (env != NULL)
+ _mark_dirty = atoi (env);
+
+ filename = getenv ("CAIRO_TRACE_FD");
+ if (filename != NULL) {
+ int fd = atoi (filename);
+ if (fd == -1)
+ return FALSE;
+
+ logfile = fdopen (fd, "w");
+ if (logfile == NULL) {
+ fprintf (stderr, "Failed to open trace file descriptor '%s': %s\n",
+ filename, strerror (errno));
+ return FALSE;
+ }
+
+ setenv ("CAIRO_TRACE_FD", "-1", 1);
+ goto done;
+ }
+
+ filename = getenv ("CAIRO_TRACE_OUTFILE_EXACT");
+ if (filename == NULL) {
+ char name[4096] = "";
+
+ filename = getenv ("CAIRO_TRACE_OUTDIR");
+ if (filename == NULL)
+ filename = CAIRO_TRACE_OUTDIR;
+
+ get_prog_name (name, sizeof (name));
+ if (*name == '\0')
+ strcpy (name, "cairo-trace.dat");
+
+ snprintf (buf, sizeof (buf), "%s/%s.%d.trace",
+ filename, name, getpid());
+
+ filename = buf;
+ } else {
+ setenv ("CAIRO_TRACE_FD", "-1", 1);
+ }
+
+ logfile = fopen (filename, "wb");
+ if (logfile == NULL) {
+ fprintf (stderr, "Failed to open trace file '%s': %s\n",
+ filename, strerror (errno));
+ return FALSE;
+ }
+
+ fprintf (stderr, "cairo-trace: Recording cairo trace data to %s\n",
+ filename);
+
+done:
+ atexit (_close_trace);
+ _emit_header ();
+ return TRUE;
+}
+
+static cairo_bool_t
+_write_lock (void)
+{
+ if (_error)
+ return FALSE;
+
+ if (! _should_trace ())
+ return FALSE;
+
+ if (! _init_logfile ())
+ return FALSE;
+
+#if HAVE_FLOCKFILE && HAVE_FUNLOCKFILE
+ flockfile (logfile);
+#endif
+ return TRUE;
+}
+
+static void
+_write_unlock (void)
+{
+ if (logfile == NULL)
+ return;
+
+#if HAVE_FLOCKFILE && HAVE_FUNLOCKFILE
+ funlockfile (logfile);
+#endif
+
+ if (_flush)
+ fflush (logfile);
+}
+
+
+static Object *
+_type_object_create (enum operand_type op_type, const void *ptr)
+{
+ Type *type;
+ Object *obj;
+
+ type = _get_type (op_type);
+
+ pthread_mutex_lock (&type->mutex);
+ obj = _object_create (type, ptr);
+ pthread_mutex_unlock (&type->mutex);
+
+ return obj;
+}
+
+static Object *
+_get_object (enum operand_type op_type, const void *ptr)
+{
+ Type *type;
+ Object *obj;
+
+ type = _get_type (op_type);
+ pthread_mutex_lock (&type->mutex);
+ obj = _type_get_object (type, ptr);
+ pthread_mutex_unlock (&type->mutex);
+
+ return obj;
+}
+
+static Object *current_object[2048]; /* XXX limit operand stack */
+static int current_stack_depth;
+
+static void
+dump_stack(const char *func)
+{
+#if DEBUG_STACK
+ int n;
+
+ _trace_printf ("%% %s: stack[%d] = [", func, current_stack_depth);
+ fflush (logfile);
+ for (n = 0; n < current_stack_depth; n++) {
+ Object *obj = current_object[n];
+ assert(obj && obj->type);
+ _trace_printf (" %s%s%ld",
+ obj->defined ? "" : "*",
+ obj->type->op_code, obj->token);
+ fflush (logfile);
+ }
+ _trace_printf (" ]\n");
+ fflush (logfile);
+#endif
+}
+
+static void
+ensure_operands (int num_operands)
+{
+ if (current_stack_depth < num_operands) {
+ int n;
+
+ fprintf (stderr, "Operand stack underflow!\n");
+ for (n = 0; n < current_stack_depth; n++) {
+ Object *obj = current_object[n];
+
+ fprintf (stderr, " [%3d] = %s%ld\n",
+ n, obj->type->op_code, obj->token);
+ }
+
+ abort ();
+ }
+}
+
+static void
+_consume_operand (bool discard)
+{
+ Object *obj;
+
+ ensure_operands (1);
+ obj = current_object[--current_stack_depth];
+ if (!discard && ! obj->defined) {
+ _trace_printf ("dup /%s%ld exch def\n",
+ obj->type->op_code,
+ obj->token);
+ obj->defined = TRUE;
+ }
+ obj->operand = -1;
+}
+
+static void
+_exch_operands (void)
+{
+ Object *tmp;
+
+ ensure_operands (2);
+ tmp = current_object[current_stack_depth-1];
+ tmp->operand--;
+ current_object[current_stack_depth-1] = current_object[current_stack_depth-2];
+ current_object[current_stack_depth-2] = tmp;
+ tmp = current_object[current_stack_depth-1];
+ tmp->operand++;
+}
+
+static cairo_bool_t
+_pop_operands_to_depth (int depth)
+{
+ if (depth < 0)
+ return FALSE;
+
+ assert(current_stack_depth >= depth);
+ if (current_stack_depth == depth)
+ return TRUE;
+
+ while (current_stack_depth > depth + 1) {
+ Object *c_obj;
+
+ ensure_operands (1);
+ c_obj = current_object[--current_stack_depth];
+
+ assert(c_obj);
+ assert(c_obj->type);
+
+ if (! c_obj->defined) {
+ current_stack_depth++;
+ return FALSE;
+ }
+
+ _trace_printf ("pop %% %s%ld\n",
+ c_obj->type->op_code, c_obj->token);
+ c_obj->operand = -1;
+ }
+
+ _exch_operands ();
+ _trace_printf ("exch\n");
+
+ dump_stack(__func__);
+ return TRUE;
+}
+
+static cairo_bool_t
+_pop_operands_to_object (Object *obj)
+{
+ if (!obj)
+ return FALSE;
+
+ if (obj->operand == -1)
+ return FALSE;
+
+ if (obj->operand == current_stack_depth - 1)
+ return TRUE;
+
+ if (obj->operand == current_stack_depth - 2) {
+ _exch_operands ();
+ _trace_printf ("exch ");
+ return TRUE;
+ }
+
+ return _pop_operands_to_depth (obj->operand + 1);
+}
+
+static cairo_bool_t
+_pop_operands_to (enum operand_type t, const void *ptr)
+{
+ return _pop_operands_to_object (_get_object (t, ptr));
+}
+
+static cairo_bool_t
+_is_current_object (Object *obj, int depth)
+{
+ if (current_stack_depth <= depth)
+ return FALSE;
+ return current_object[current_stack_depth-depth-1] == obj;
+}
+
+static cairo_bool_t
+_is_current (enum operand_type type, const void *ptr, int depth)
+{
+ return _is_current_object (_get_object (type, ptr), depth);
+}
+
+static void
+_push_object(Object *obj)
+{
+ assert(obj->operand == -1);
+
+ if (current_stack_depth == ARRAY_LENGTH (current_object)) {
+ int n;
+
+ fprintf (stderr, "Operand stack overflow!\n");
+ for (n = 0; n < current_stack_depth; n++) {
+ obj = current_object[n];
+
+ fprintf (stderr, " [%3d] = %s%ld\n",
+ n, obj->type->op_code, obj->token);
+ }
+
+ abort ();
+ }
+
+ obj->operand = current_stack_depth;
+ current_object[current_stack_depth++] = obj;
+}
+
+static void
+_push_operand (enum operand_type t, const void *ptr)
+{
+ _push_object(_get_object(t, ptr));
+}
+
+static void
+_object_remove (Object *obj)
+{
+ if (obj->operand != -1) {
+ ensure_operands (1);
+ if (obj->operand == current_stack_depth - 1) {
+ _trace_printf ("pop %% %s%ld destroyed\n",
+ obj->type->op_code, obj->token);
+ } else if (obj->operand == current_stack_depth - 2) {
+ _exch_operands ();
+ _trace_printf ("exch pop %% %s%ld destroyed\n",
+ obj->type->op_code, obj->token);
+ } else {
+ int n;
+
+ _trace_printf ("%d -1 roll pop %% %s%ld destroyed\n",
+ current_stack_depth - obj->operand,
+ obj->type->op_code, obj->token);
+
+ for (n = obj->operand; n < current_stack_depth - 1; n++) {
+ current_object[n] = current_object[n+1];
+ current_object[n]->operand = n;
+ }
+ }
+ obj->operand = -1;
+
+ current_stack_depth--;
+ dump_stack(__func__);
+ }
+}
+
+static void
+_object_undef (void *ptr)
+{
+ Object *obj = ptr;
+
+ if (_write_lock ()) {
+ _object_remove (obj);
+
+ if (obj->defined) {
+ _trace_printf ("/%s%ld undef\n",
+ obj->type->op_code, obj->token);
+ }
+
+ _write_unlock ();
+ }
+
+ _object_destroy (obj);
+}
+
+static long
+_create_context_id (cairo_t *cr)
+{
+ Object *obj;
+
+ obj = _get_object (CONTEXT, cr);
+ if (obj == NULL) {
+ obj = _type_object_create (CONTEXT, cr);
+ DLCALL (cairo_set_user_data,
+ cr, &destroy_key, obj, _object_undef);
+ }
+
+ return obj->token;
+}
+
+static long
+_get_id (enum operand_type op_type, const void *ptr)
+{
+ Object *obj;
+
+ obj = _get_object (op_type, ptr);
+ if (obj == NULL) {
+ if (logfile != NULL) {
+ _trace_printf ("%% Unknown object of type %s, trace is incomplete.",
+ _get_type (op_type)->name);
+ }
+ _error = TRUE;
+ return -1;
+ }
+
+ return obj->token;
+}
+
+static cairo_bool_t
+_has_id (enum operand_type op_type, const void *ptr)
+{
+ return _get_object (op_type, ptr) != NULL;
+}
+
+static long
+_create_font_face_id (cairo_font_face_t *font_face)
+{
+ Object *obj;
+
+ obj = _get_object (FONT_FACE, font_face);
+ if (obj == NULL) {
+ obj = _type_object_create (FONT_FACE, font_face);
+ DLCALL (cairo_font_face_set_user_data,
+ font_face, &destroy_key, obj, _object_undef);
+ }
+
+ return obj->token;
+}
+
+static long
+_get_font_face_id (cairo_font_face_t *font_face)
+{
+ return _get_id (FONT_FACE, font_face);
+}
+
+static void
+_emit_font_face_id (cairo_font_face_t *font_face)
+{
+ Object *obj = _get_object (FONT_FACE, font_face);
+ if (obj == NULL) {
+ _trace_printf ("null ");
+ } else {
+ if (obj->defined) {
+ _trace_printf ("f%ld ", obj->token);
+ } else {
+ _trace_printf ("%d index ", current_stack_depth - obj->operand - 1);
+ }
+ }
+}
+
+static cairo_bool_t
+_has_pattern_id (cairo_pattern_t *pattern)
+{
+ return _has_id (PATTERN, pattern);
+}
+
+static long
+_create_pattern_id (cairo_pattern_t *pattern)
+{
+ Object *obj;
+
+ obj = _get_object (PATTERN, pattern);
+ if (obj == NULL) {
+ obj = _type_object_create (PATTERN, pattern);
+ DLCALL (cairo_pattern_set_user_data,
+ pattern, &destroy_key, obj, _object_undef);
+ }
+
+ return obj->token;
+}
+
+static void
+_emit_pattern_id (cairo_pattern_t *pattern)
+{
+ Object *obj = _get_object (PATTERN, pattern);
+ if (obj == NULL) {
+ _trace_printf ("null ");
+ } else {
+ if (obj->defined) {
+ _trace_printf ("p%ld ", obj->token);
+ } else {
+ _trace_printf ("%d index ",
+ current_stack_depth - obj->operand - 1);
+ }
+ }
+}
+
+static void
+_emit_scaled_font_id (const cairo_scaled_font_t *scaled_font)
+{
+ Object *obj = _get_object (SCALED_FONT, scaled_font);
+ if (obj == NULL) {
+ _trace_printf ("null ");
+ } else {
+ if (obj->defined) {
+ _trace_printf ("sf%ld ", obj->token);
+ } else {
+ _trace_printf ("%d index ",
+ current_stack_depth - obj->operand - 1);
+ }
+ }
+}
+
+static long
+_create_scaled_font_id (cairo_scaled_font_t *font)
+{
+ Object *obj;
+
+ assert(_get_object (SCALED_FONT, font) == NULL);
+ obj = _type_object_create (SCALED_FONT, font);
+ DLCALL (cairo_scaled_font_set_user_data,
+ font, &destroy_key, obj, _object_undef);
+
+ return obj->token;
+}
+
+static cairo_bool_t
+_has_scaled_font_id (const cairo_scaled_font_t *font)
+{
+ return _has_id (SCALED_FONT, font);
+}
+
+static Object *
+_create_surface (cairo_surface_t *surface)
+{
+ Object *obj;
+
+ obj = _get_object (SURFACE, surface);
+ if (obj == NULL) {
+ obj = _type_object_create (SURFACE, surface);
+ DLCALL (cairo_surface_set_user_data,
+ surface, &destroy_key, obj, _object_undef);
+ }
+
+ return obj;
+}
+
+static long
+_get_surface_id (cairo_surface_t *surface)
+{
+ return _get_id (SURFACE, surface);
+}
+
+static cairo_bool_t
+_matrix_is_identity (const cairo_matrix_t *m)
+{
+ return m->xx == 1. && m->yx == 0. &&
+ m->xy == 0. && m->yy == 1. &&
+ m->x0 == 0. && m->y0 == 0.;
+}
+
+#define BUFFER_SIZE 16384
+struct _data_stream {
+ z_stream zlib_stream;
+ unsigned char zin_buf[BUFFER_SIZE];
+ unsigned char zout_buf[BUFFER_SIZE];
+ unsigned char four_tuple[4];
+ int base85_pending;
+};
+
+static void
+_write_zlib_data_start (struct _data_stream *stream)
+{
+ stream->zlib_stream.zalloc = Z_NULL;
+ stream->zlib_stream.zfree = Z_NULL;
+ stream->zlib_stream.opaque = Z_NULL;
+
+ deflateInit (&stream->zlib_stream, Z_DEFAULT_COMPRESSION);
+
+ stream->zlib_stream.next_in = stream->zin_buf;
+ stream->zlib_stream.avail_in = 0;
+ stream->zlib_stream.next_out = stream->zout_buf;
+ stream->zlib_stream.avail_out = BUFFER_SIZE;
+}
+
+static void
+_write_base85_data_start (struct _data_stream *stream)
+{
+ stream->base85_pending = 0;
+}
+
+static cairo_bool_t
+_expand_four_tuple_to_five (unsigned char four_tuple[4],
+ unsigned char five_tuple[5])
+{
+ uint32_t value;
+ int digit, i;
+ cairo_bool_t all_zero = TRUE;
+
+ value = four_tuple[0] << 24 |
+ four_tuple[1] << 16 |
+ four_tuple[2] << 8 |
+ four_tuple[3] << 0;
+ for (i = 0; i < 5; i++) {
+ digit = value % 85;
+ if (digit != 0 && all_zero)
+ all_zero = FALSE;
+ five_tuple[4-i] = digit + 33;
+ value = value / 85;
+ }
+
+ return all_zero;
+}
+
+static void
+_write_base85_data (struct _data_stream *stream,
+ const unsigned char *data,
+ unsigned long length)
+{
+ unsigned char five_tuple[5];
+ int ret;
+
+ assert (_should_trace ());
+
+ while (length--) {
+ stream->four_tuple[stream->base85_pending++] = *data++;
+ if (stream->base85_pending == 4) {
+ if (_expand_four_tuple_to_five (stream->four_tuple, five_tuple))
+ ret = fwrite ("z", 1, 1, logfile);
+ else
+ ret = fwrite (five_tuple, 5, 1, logfile);
+ (void)ret;
+ stream->base85_pending = 0;
+ }
+ }
+}
+
+static void
+_write_zlib_data (struct _data_stream *stream, cairo_bool_t flush)
+{
+ cairo_bool_t finished;
+
+ do {
+ int ret = deflate (&stream->zlib_stream, flush ? Z_FINISH : Z_NO_FLUSH);
+ if (flush || stream->zlib_stream.avail_out == 0) {
+ _write_base85_data (stream,
+ stream->zout_buf,
+ BUFFER_SIZE - stream->zlib_stream.avail_out);
+ stream->zlib_stream.next_out = stream->zout_buf;
+ stream->zlib_stream.avail_out = BUFFER_SIZE;
+ }
+
+ finished = TRUE;
+ if (stream->zlib_stream.avail_in != 0)
+ finished = FALSE;
+ if (flush && ret != Z_STREAM_END)
+ finished = FALSE;
+ } while (! finished);
+
+ stream->zlib_stream.next_in = stream->zin_buf;
+}
+
+static void
+_write_data_start (struct _data_stream *stream, uint32_t len)
+{
+ _write_zlib_data_start (stream);
+ _write_base85_data_start (stream);
+
+ _trace_printf ("<|");
+ len = to_be32 (len);
+ _write_base85_data (stream, (unsigned char *) &len, sizeof (len));
+}
+
+static void
+_write_data (struct _data_stream *stream,
+ const void *data,
+ unsigned int length)
+{
+ unsigned int count;
+ const unsigned char *p = data;
+
+ while (length) {
+ count = length;
+ if (count > BUFFER_SIZE - stream->zlib_stream.avail_in)
+ count = BUFFER_SIZE - stream->zlib_stream.avail_in;
+ memcpy (stream->zin_buf + stream->zlib_stream.avail_in, p, count);
+ p += count;
+ stream->zlib_stream.avail_in += count;
+ length -= count;
+
+ if (stream->zlib_stream.avail_in == BUFFER_SIZE)
+ _write_zlib_data (stream, FALSE);
+ }
+}
+
+static void
+_write_zlib_data_end (struct _data_stream *stream)
+{
+ _write_zlib_data (stream, TRUE);
+ deflateEnd (&stream->zlib_stream);
+
+}
+
+static void
+_write_base85_data_end (struct _data_stream *stream)
+{
+ unsigned char five_tuple[5];
+ int ret;
+
+ assert (_should_trace ());
+
+ if (stream->base85_pending) {
+ memset (stream->four_tuple + stream->base85_pending,
+ 0, 4 - stream->base85_pending);
+ _expand_four_tuple_to_five (stream->four_tuple, five_tuple);
+ ret = fwrite (five_tuple, stream->base85_pending+1, 1, logfile);
+ (void) ret;
+ }
+}
+
+static void
+_write_data_end (struct _data_stream *stream)
+{
+ _write_zlib_data_end (stream);
+ _write_base85_data_end (stream);
+
+ _trace_printf ("~>");
+}
+
+static void
+_emit_data (const void *data, unsigned int length)
+{
+ struct _data_stream stream;
+
+ _write_data_start (&stream, length);
+ _write_data (&stream, data, length);
+ _write_data_end (&stream);
+}
+
+static const char *
+_format_to_string (cairo_format_t format)
+{
+#define f(name) case CAIRO_FORMAT_ ## name: return #name
+ switch (format) {
+ f(INVALID);
+ f(ARGB32);
+ f(RGB30);
+ f(RGB24);
+ f(RGB16_565);
+ f(A8);
+ f(A1);
+ }
+#undef f
+ return "UNKNOWN_FORMAT";
+}
+
+static const char *
+_format_to_content_string (cairo_format_t format)
+{
+ switch (format) {
+ case CAIRO_FORMAT_INVALID:
+ return "INVALID";
+ case CAIRO_FORMAT_ARGB32:
+ return "COLOR_ALPHA";
+ case CAIRO_FORMAT_RGB30:
+ case CAIRO_FORMAT_RGB24:
+ case CAIRO_FORMAT_RGB16_565:
+ return "COLOR";
+ case CAIRO_FORMAT_A8:
+ case CAIRO_FORMAT_A1:
+ return "ALPHA";
+ }
+ return "UNKNOWN";
+}
+
+static const char *
+_status_to_string (cairo_status_t status)
+{
+#define f(name) case CAIRO_STATUS_ ## name: return "STATUS_" #name
+ switch (status) {
+ f(SUCCESS);
+ f(NO_MEMORY);
+ f(INVALID_RESTORE);
+ f(INVALID_POP_GROUP);
+ f(NO_CURRENT_POINT);
+ f(INVALID_MATRIX);
+ f(INVALID_STATUS);
+ f(NULL_POINTER);
+ f(INVALID_STRING);
+ f(INVALID_PATH_DATA);
+ f(READ_ERROR);
+ f(WRITE_ERROR);
+ f(SURFACE_FINISHED);
+ f(SURFACE_TYPE_MISMATCH);
+ f(PATTERN_TYPE_MISMATCH);
+ f(INVALID_CONTENT);
+ f(INVALID_FORMAT);
+ f(INVALID_VISUAL);
+ f(FILE_NOT_FOUND);
+ f(INVALID_DASH);
+ f(INVALID_DSC_COMMENT);
+ f(INVALID_INDEX);
+ f(CLIP_NOT_REPRESENTABLE);
+ f(TEMP_FILE_ERROR);
+ f(INVALID_STRIDE);
+ f(FONT_TYPE_MISMATCH);
+ f(USER_FONT_IMMUTABLE);
+ f(USER_FONT_ERROR);
+ f(NEGATIVE_COUNT);
+ f(INVALID_CLUSTERS);
+ f(INVALID_SLANT);
+ f(INVALID_WEIGHT);
+ f(INVALID_SIZE);
+ f(USER_FONT_NOT_IMPLEMENTED);
+ f(DEVICE_TYPE_MISMATCH);
+ f(DEVICE_ERROR);
+ f(INVALID_MESH_CONSTRUCTION);
+ f(DEVICE_FINISHED);
+ f(JBIG2_GLOBAL_MISSING);
+ case CAIRO_STATUS_LAST_STATUS:
+ break;
+ }
+ return "UNKNOWN_STATUS";
+#undef f
+}
+
+static void CAIRO_PRINTF_FORMAT(2, 3)
+_emit_image (cairo_surface_t *image,
+ const char *info,
+ ...)
+{
+ int stride, row, width, height;
+ uint32_t len;
+ cairo_format_t format;
+ uint8_t row_stack[BUFFER_SIZE];
+ uint8_t *rowdata;
+ uint8_t *data;
+ struct _data_stream stream;
+ cairo_status_t status;
+
+ status = DLCALL (cairo_surface_status, image);
+ if (status) {
+ _trace_printf ("<< /status //%s >> image",
+ _status_to_string (status));
+ return;
+ }
+
+ width = DLCALL (cairo_image_surface_get_width, image);
+ height = DLCALL (cairo_image_surface_get_height, image);
+ stride = DLCALL (cairo_image_surface_get_stride, image);
+ format = DLCALL (cairo_image_surface_get_format, image);
+ data = DLCALL (cairo_image_surface_get_data, image);
+
+ _trace_printf ("dict\n"
+ " /width %d set\n"
+ " /height %d set\n"
+ " /format //%s set\n",
+ width, height,
+ _format_to_string (format));
+ if (info != NULL) {
+ va_list ap;
+
+ va_start (ap, info);
+ _trace_vprintf (info, ap);
+ va_end (ap);
+ }
+
+ if (DLCALL (cairo_version) >= CAIRO_VERSION_ENCODE (1, 9, 0)) {
+ const char *mime_types[] = {
+ CAIRO_MIME_TYPE_JPEG,
+ CAIRO_MIME_TYPE_JP2,
+ CAIRO_MIME_TYPE_PNG,
+ NULL
+ }, **mime_type;
+
+ for (mime_type = mime_types; *mime_type; mime_type++) {
+ const unsigned char *mime_data;
+ unsigned long mime_length;
+
+ DLCALL (cairo_surface_get_mime_data,
+ image, *mime_type, &mime_data, &mime_length);
+ if (mime_data != NULL) {
+ _trace_printf (" /mime-type (%s) set\n"
+ " /source <~",
+ *mime_type);
+ _write_base85_data_start (&stream);
+ _write_base85_data (&stream, mime_data, mime_length);
+ _write_base85_data_end (&stream);
+ _trace_printf ("~> set\n"
+ " image");
+ return;
+ }
+ }
+ }
+
+ switch (format) {
+ case CAIRO_FORMAT_A1: len = (width + 7)/8; break;
+ case CAIRO_FORMAT_A8: len = width; break;
+ case CAIRO_FORMAT_RGB16_565: len = 2*width; break;
+ case CAIRO_FORMAT_RGB24: len = 3*width; break;
+ default:
+ case CAIRO_FORMAT_RGB30:
+ case CAIRO_FORMAT_INVALID:
+ case CAIRO_FORMAT_ARGB32: len = 4*width; break;
+ }
+
+ _trace_printf (" /source ");
+ _write_data_start (&stream, len * height);
+
+#ifdef WORDS_BIGENDIAN
+ switch (format) {
+ case CAIRO_FORMAT_A1:
+ for (row = height; row--; ) {
+ _write_data (&stream, data, (width+7)/8);
+ data += stride;
+ }
+ break;
+ case CAIRO_FORMAT_A8:
+ for (row = height; row--; ) {
+ _write_data (&stream, data, width);
+ data += stride;
+ }
+ break;
+ case CAIRO_FORMAT_RGB16_565:
+ for (row = height; row--; ) {
+ _write_data (&stream, data, 2*width);
+ data += stride;
+ }
+ break;
+ case CAIRO_FORMAT_RGB24:
+ for (row = height; row--; ) {
+ int col;
+ rowdata = data;
+ for (col = width; col--; ) {
+ _write_data (&stream, rowdata, 3);
+ rowdata+=4;
+ }
+ data += stride;
+ }
+ break;
+ case CAIRO_FORMAT_RGB30:
+ case CAIRO_FORMAT_ARGB32:
+ for (row = height; row--; ) {
+ _write_data (&stream, data, 4*width);
+ data += stride;
+ }
+ break;
+ case CAIRO_FORMAT_INVALID:
+ default:
+ break;
+ }
+#else
+ if (stride > ARRAY_LENGTH (row_stack)) {
+ rowdata = malloc (stride);
+ if (rowdata == NULL)
+ goto BAIL;
+ } else
+ rowdata = row_stack;
+
+ switch (format) {
+ case CAIRO_FORMAT_A1:
+ for (row = height; row--; ) {
+ int col;
+ for (col = 0; col < (width + 7)/8; col++)
+ rowdata[col] = CAIRO_BITSWAP8 (data[col]);
+ _write_data (&stream, rowdata, (width+7)/8);
+ data += stride;
+ }
+ break;
+ case CAIRO_FORMAT_A8:
+ for (row = height; row--; ) {
+ _write_data (&stream, rowdata, width);
+ data += stride;
+ }
+ break;
+ case CAIRO_FORMAT_RGB16_565: /* XXX endianness */
+ for (row = height; row--; ) {
+ uint16_t *src = (uint16_t *) data;
+ uint16_t *dst = (uint16_t *)rowdata;
+ int col;
+ for (col = 0; col < width; col++)
+ dst[col] = bswap_16 (src[col]);
+ _write_data (&stream, rowdata, 2*width);
+ data += stride;
+ }
+ break;
+ case CAIRO_FORMAT_RGB24:
+ for (row = height; row--; ) {
+ uint8_t *src = data;
+ int col;
+ for (col = 0; col < width; col++) {
+ rowdata[3*col+2] = *src++;
+ rowdata[3*col+1] = *src++;
+ rowdata[3*col+0] = *src++;
+ src++;
+ }
+ _write_data (&stream, rowdata, 3*width);
+ data += stride;
+ }
+ break;
+ case CAIRO_FORMAT_RGB30:
+ case CAIRO_FORMAT_ARGB32:
+ for (row = height; row--; ) {
+ uint32_t *src = (uint32_t *) data;
+ uint32_t *dst = (uint32_t *) rowdata;
+ int col;
+ for (col = 0; col < width; col++)
+ dst[col] = bswap_32 (src[col]);
+ _write_data (&stream, rowdata, 4*width);
+ data += stride;
+ }
+ break;
+ case CAIRO_FORMAT_INVALID:
+ default:
+ break;
+ }
+ if (rowdata != row_stack)
+ free (rowdata);
+
+BAIL:
+ _write_data_end (&stream);
+#endif
+ _trace_printf (" set\n image");
+}
+
+static void
+_encode_string_literal (char *out, int max,
+ const char *utf8, int len)
+{
+ char c;
+ const char *end;
+
+ *out++ = '(';
+ max--;
+
+ if (utf8 == NULL)
+ goto DONE;
+
+ if (len < 0)
+ len = strlen (utf8);
+ end = utf8 + len;
+
+ while (utf8 < end) {
+ if (max < 5)
+ break;
+
+ switch ((c = *utf8++)) {
+ case '\n':
+ *out++ = '\\';
+ *out++ = 'n';
+ max -= 2;
+ break;
+ case '\r':
+ *out++ = '\\';
+ *out++ = 'r';
+ max -= 2;
+ case '\t':
+ *out++ = '\\';
+ *out++ = 't';
+ max -= 2;
+ break;
+ case '\b':
+ *out++ = '\\';
+ *out++ = 'b';
+ max -= 2;
+ break;
+ case '\f':
+ *out++ = '\\';
+ *out++ = 'f';
+ max -= 2;
+ break;
+ case '\\':
+ case '(':
+ case ')':
+ *out++ = '\\';
+ *out++ = c;
+ max -= 2;
+ break;
+ default:
+ if (isprint (c) || isspace (c)) {
+ *out++ = c;
+ } else {
+ int octal = 0;
+ while (c) {
+ octal *= 10;
+ octal += c&7;
+ c /= 8;
+ }
+ octal = snprintf (out, max, "\\%03d", octal);
+ out += octal;
+ max -= octal;
+ }
+ break;
+ }
+ }
+DONE:
+ *out++ = ')';
+ *out = '\0';
+}
+
+static void
+to_octal (int value, char *buf, size_t size)
+{
+ do {
+ buf[--size] = '0' + (value & 7);
+ value >>= 3;
+ } while (size);
+}
+
+static void
+_emit_string_literal (const char *utf8, int len)
+{
+ char c;
+ const char *end;
+
+ if (utf8 == NULL) {
+ _trace_printf ("()");
+ return;
+ }
+
+ if (len < 0)
+ len = strlen (utf8);
+ end = utf8 + len;
+
+ _trace_printf ("(");
+ while (utf8 < end) {
+ switch ((c = *utf8++)) {
+ case '\n':
+ c = 'n';
+ goto ESCAPED_CHAR;
+ case '\r':
+ c = 'r';
+ goto ESCAPED_CHAR;
+ case '\t':
+ c = 't';
+ goto ESCAPED_CHAR;
+ case '\b':
+ c = 'b';
+ goto ESCAPED_CHAR;
+ case '\f':
+ c = 'f';
+ goto ESCAPED_CHAR;
+ case '\\':
+ case '(':
+ case ')':
+ESCAPED_CHAR:
+ _trace_printf ("\\%c", c);
+ break;
+ default:
+ if (isprint (c) || isspace (c)) {
+ _trace_printf ("%c", c);
+ } else {
+ char buf[4] = { '\\' };
+ int ret_ignored;
+
+ to_octal (c, buf+1, 3);
+ ret_ignored = fwrite (buf, 4, 1, logfile);
+ (void)ret_ignored;
+ }
+ break;
+ }
+ }
+ _trace_printf (")");
+}
+
+static void
+_emit_current (Object *obj)
+{
+ if (obj != NULL && ! _pop_operands_to_object (obj)) {
+ if (obj->operand != -1) {
+ int n;
+
+ _trace_printf ("%d -1 roll %% %s%ld\n",
+ current_stack_depth - obj->operand,
+ obj->type->op_code, obj->token);
+
+ for (n = obj->operand; n < current_stack_depth - 1; n++) {
+ current_object[n] = current_object[n+1];
+ current_object[n]->operand = n;
+ }
+ obj->operand = -1;
+ current_stack_depth--;
+ } else {
+ assert(obj->defined);
+ _trace_printf ("%s%ld\n", obj->type->op_code, obj->token);
+ }
+
+ _push_object (obj);
+ dump_stack(__func__);
+ }
+}
+
+static void
+_emit_context (cairo_t *cr)
+{
+ _emit_current (_get_object (CONTEXT, cr));
+}
+
+static void
+_emit_pattern (cairo_pattern_t *pattern)
+{
+ _emit_current (_get_object (PATTERN, pattern));
+}
+
+static void
+_emit_surface (cairo_surface_t *surface)
+{
+ _emit_current (_get_object (SURFACE, surface));
+}
+
+static void CAIRO_PRINTF_FORMAT(2, 3)
+_emit_cairo_op (cairo_t *cr, const char *fmt, ...)
+{
+ va_list ap;
+
+ if (cr == NULL || ! _write_lock ())
+ return;
+
+ _emit_context (cr);
+
+ va_start (ap, fmt);
+ _trace_vprintf ( fmt, ap);
+ va_end (ap);
+
+ _write_unlock ();
+}
+
+cairo_t *
+cairo_create (cairo_surface_t *target)
+{
+ cairo_t *ret;
+ long surface_id;
+ long context_id;
+
+ _enter_trace ();
+
+ ret = DLCALL (cairo_create, target);
+ context_id = _create_context_id (ret);
+
+ _emit_line_info ();
+ if (target != NULL && _write_lock ()) {
+ surface_id = _get_surface_id (target);
+ if (surface_id != -1) {
+ _get_object (SURFACE, target)->foreign = FALSE;
+
+ /* we presume that we will continue to use the context */
+ if (_pop_operands_to (SURFACE, target)){
+ _consume_operand (false);
+ } else {
+ _trace_printf ("s%ld ", surface_id);
+ }
+ _trace_printf ("context %% c%ld\n", context_id);
+ _push_operand (CONTEXT, ret);
+ dump_stack(__func__);
+ }
+ _write_unlock ();
+ }
+
+ _exit_trace ();
+ return ret;
+}
+
+void
+cairo_save (cairo_t *cr)
+{
+ _enter_trace ();
+ _emit_line_info ();
+ _emit_cairo_op (cr, "save\n");
+ DLCALL (cairo_save, cr);
+ _exit_trace ();
+}
+
+void
+cairo_restore (cairo_t *cr)
+{
+ _enter_trace ();
+ _emit_line_info ();
+ _emit_cairo_op (cr, "restore\n");
+ DLCALL (cairo_restore, cr);
+ _exit_trace ();
+}
+
+void
+cairo_push_group (cairo_t *cr)
+{
+ _enter_trace ();
+ _emit_line_info ();
+ _emit_cairo_op (cr, "//COLOR_ALPHA push-group\n");
+ DLCALL (cairo_push_group, cr);
+ _exit_trace ();
+}
+
+static const char *
+_content_to_string (cairo_content_t content)
+{
+ switch (content) {
+ case CAIRO_CONTENT_ALPHA: return "ALPHA";
+ case CAIRO_CONTENT_COLOR: return "COLOR";
+ default:
+ case CAIRO_CONTENT_COLOR_ALPHA: return "COLOR_ALPHA";
+ }
+}
+
+void
+cairo_push_group_with_content (cairo_t *cr, cairo_content_t content)
+{
+ _enter_trace ();
+ _emit_line_info ();
+ _emit_cairo_op (cr, "//%s push-group\n", _content_to_string (content));
+ DLCALL (cairo_push_group_with_content, cr, content);
+ _exit_trace ();
+}
+
+cairo_pattern_t *
+cairo_pop_group (cairo_t *cr)
+{
+ cairo_pattern_t *ret;
+
+ _enter_trace ();
+
+ ret = DLCALL (cairo_pop_group, cr);
+
+ _emit_line_info ();
+ _emit_cairo_op (cr, "pop-group %% p%ld\n", _create_pattern_id (ret));
+ _push_operand (PATTERN, ret);
+ dump_stack(__func__);
+
+ _exit_trace ();
+ return ret;
+}
+
+void
+cairo_pop_group_to_source (cairo_t *cr)
+{
+ _enter_trace ();
+ _emit_line_info ();
+ _emit_cairo_op (cr, "pop-group set-source\n");
+ DLCALL (cairo_pop_group_to_source, cr);
+ _exit_trace ();
+}
+
+static const char *
+_operator_to_string (cairo_operator_t op)
+{
+#define f(name) case CAIRO_OPERATOR_ ## name: return #name
+ switch (op) {
+ f(OVER);
+ f(SOURCE);
+ f(CLEAR);
+ f(IN);
+ f(OUT);
+ f(ATOP);
+ f(DEST);
+ f(DEST_OVER);
+ f(DEST_IN);
+ f(DEST_OUT);
+ f(DEST_ATOP);
+ f(XOR);
+ f(ADD);
+ f(SATURATE);
+ f(MULTIPLY);
+ f(SCREEN);
+ f(OVERLAY);
+ f(DARKEN);
+ f(LIGHTEN);
+ case CAIRO_OPERATOR_COLOR_DODGE: return "DODGE";
+ case CAIRO_OPERATOR_COLOR_BURN: return "BURN";
+ f(HARD_LIGHT);
+ f(SOFT_LIGHT);
+ f(DIFFERENCE);
+ f(EXCLUSION);
+ f(HSL_HUE);
+ f(HSL_SATURATION);
+ f(HSL_COLOR);
+ f(HSL_LUMINOSITY);
+ }
+#undef f
+ return "UNKNOWN_OPERATOR";
+}
+
+void
+cairo_set_operator (cairo_t *cr, cairo_operator_t op)
+{
+ _enter_trace ();
+ _emit_line_info ();
+ _emit_cairo_op (cr, "//%s set-operator\n", _operator_to_string (op));
+ DLCALL (cairo_set_operator, cr, op);
+ _exit_trace ();
+}
+
+void
+cairo_set_source_rgb (cairo_t *cr, double red, double green, double blue)
+{
+ _enter_trace ();
+ _emit_line_info ();
+ _emit_cairo_op (cr, "%g %g %g set-source-rgb\n", red, green, blue);
+ DLCALL (cairo_set_source_rgb, cr, red, green, blue);
+ _exit_trace ();
+}
+
+void
+cairo_set_source_rgba (cairo_t *cr, double red, double green, double blue, double alpha)
+{
+ _enter_trace ();
+ _emit_line_info ();
+ _emit_cairo_op (cr, "%g %g %g %g set-source-rgba\n",
+ red, green, blue, alpha);
+ DLCALL (cairo_set_source_rgba, cr, red, green, blue, alpha);
+ _exit_trace ();
+}
+
+static void
+_emit_source_image (cairo_surface_t *surface)
+{
+ Object *obj;
+ cairo_surface_t *image;
+ cairo_t *cr;
+
+ obj = _get_object (SURFACE, surface);
+ if (obj == NULL)
+ return;
+
+ image = DLCALL (cairo_image_surface_create,
+ CAIRO_FORMAT_ARGB32,
+ obj->width,
+ obj->height);
+ cr = DLCALL (cairo_create, image);
+ DLCALL (cairo_set_source_surface, cr, surface, 0, 0);
+ DLCALL (cairo_paint, cr);
+ DLCALL (cairo_destroy, cr);
+
+ _emit_image (image, NULL);
+ _trace_printf (" set-source-image ");
+ DLCALL (cairo_surface_destroy, image);
+
+ obj->foreign = FALSE;
+}
+
+static void
+_emit_source_image_rectangle (cairo_surface_t *surface,
+ int x, int y,
+ int width, int height)
+{
+ Object *obj;
+ cairo_surface_t *image;
+ cairo_t *cr;
+
+ obj = _get_object (SURFACE, surface);
+ if (obj == NULL)
+ return;
+
+ if (obj->foreign) {
+ _emit_source_image (surface);
+ return;
+ }
+
+ image = DLCALL (cairo_image_surface_create,
+ CAIRO_FORMAT_ARGB32,
+ width,
+ height);
+ cr = DLCALL (cairo_create, image);
+ DLCALL (cairo_set_source_surface, cr, surface, x, y);
+ DLCALL (cairo_paint, cr);
+ DLCALL (cairo_destroy, cr);
+
+ _emit_image (image, NULL);
+ _trace_printf (" %d %d set-device-offset set-source-image ",
+ x, y);
+ DLCALL (cairo_surface_destroy, image);
+}
+
+void
+cairo_set_source_surface (cairo_t *cr, cairo_surface_t *surface, double x, double y)
+{
+ _enter_trace ();
+ _emit_line_info ();
+ if (cr != NULL && surface != NULL && _write_lock ()) {
+ Object *obj = _get_object (SURFACE, surface);
+
+ if (_is_current (SURFACE, surface, 0) &&
+ _is_current (CONTEXT, cr, 1))
+ {
+ _consume_operand (false);
+ }
+ else if (_is_current (SURFACE, surface, 1) &&
+ _is_current (CONTEXT, cr, 0) &&
+ obj->defined)
+ {
+ _trace_printf ("exch ");
+ _exch_operands ();
+ _consume_operand (false);
+ } else if (obj->defined) {
+ _emit_context (cr);
+ _trace_printf ("s%ld ", obj->token);
+ } else {
+ _emit_context (cr);
+ _trace_printf ("%d index ",
+ current_stack_depth - obj->operand - 1);
+ }
+
+ if (obj->foreign)
+ _emit_source_image (surface);
+
+ _trace_printf ("pattern");
+ if (x != 0. || y != 0.)
+ _trace_printf (" %g %g translate", -x, -y);
+
+ _trace_printf (" set-source\n");
+ _write_unlock ();
+ }
+
+ DLCALL (cairo_set_source_surface, cr, surface, x, y);
+ _exit_trace ();
+}
+
+void
+cairo_set_source (cairo_t *cr, cairo_pattern_t *source)
+{
+ _enter_trace ();
+ _emit_line_info ();
+ if (cr != NULL && source != NULL && _write_lock ()) {
+ Object *obj = _get_object (PATTERN, source);
+ cairo_bool_t need_context_and_pattern = TRUE;
+
+ if (_is_current (PATTERN, source, 0) &&
+ _is_current (CONTEXT, cr, 1))
+ {
+ if (obj->defined) {
+ _consume_operand (false);
+ } else {
+ _trace_printf ("exch 1 index ");
+ _exch_operands ();
+ }
+ need_context_and_pattern = FALSE;
+ }
+ else if (_is_current (PATTERN, source, 1) &&
+ _is_current (CONTEXT, cr, 0))
+ {
+ if (obj->defined) {
+ _trace_printf ("exch ");
+ _exch_operands ();
+ _consume_operand (false);
+ need_context_and_pattern = FALSE;
+ }
+ }
+
+ if (need_context_and_pattern) {
+ _emit_context (cr);
+ _emit_pattern_id (source);
+ }
+
+ _trace_printf ("set-source %% p%ld\n", obj->token);
+ _write_unlock ();
+ }
+
+ DLCALL (cairo_set_source, cr, source);
+ _exit_trace ();
+}
+
+cairo_pattern_t *
+cairo_get_source (cairo_t *cr)
+{
+ cairo_pattern_t *ret;
+
+ _enter_trace ();
+
+ ret = DLCALL (cairo_get_source, cr);
+
+ if (! _has_pattern_id (ret)) {
+ _emit_cairo_op (cr, "/source get /p%ld exch def\n",
+ _create_pattern_id (ret));
+ _get_object (PATTERN, ret)->defined = TRUE;
+ }
+
+ _exit_trace ();
+ return ret;
+}
+
+void
+cairo_set_tolerance (cairo_t *cr, double tolerance)
+{
+ _enter_trace ();
+ _emit_line_info ();
+ _emit_cairo_op (cr, "%g set-tolerance\n", tolerance);
+ DLCALL (cairo_set_tolerance, cr, tolerance);
+ _exit_trace ();
+}
+
+static const char *
+_antialias_to_string (cairo_antialias_t antialias)
+{
+#define f(name) case CAIRO_ANTIALIAS_ ## name: return "ANTIALIAS_" #name
+ switch (antialias) {
+ f(DEFAULT);
+
+ f(NONE);
+ f(GRAY);
+ f(SUBPIXEL);
+
+ f(FAST);
+ f(GOOD);
+ f(BEST);
+ };
+#undef f
+ return "UNKNOWN_ANTIALIAS";
+}
+
+void
+cairo_set_antialias (cairo_t *cr, cairo_antialias_t antialias)
+{
+ _enter_trace ();
+ _emit_line_info ();
+ _emit_cairo_op (cr,
+ "//%s set-antialias\n", _antialias_to_string (antialias));
+ DLCALL (cairo_set_antialias, cr, antialias);
+ _exit_trace ();
+}
+
+static const char *
+_fill_rule_to_string (cairo_fill_rule_t rule)
+{
+#define f(name) case CAIRO_FILL_RULE_ ## name: return #name
+ switch (rule) {
+ f(WINDING);
+ f(EVEN_ODD);
+ };
+#undef f
+ return "UNKNOWN_FILL_RULE";
+}
+
+void
+cairo_set_fill_rule (cairo_t *cr, cairo_fill_rule_t fill_rule)
+{
+ _enter_trace ();
+ _emit_line_info ();
+ _emit_cairo_op (cr,
+ "//%s set-fill-rule\n", _fill_rule_to_string (fill_rule));
+ DLCALL (cairo_set_fill_rule, cr, fill_rule);
+ _exit_trace ();
+}
+
+void
+cairo_set_line_width (cairo_t *cr, double width)
+{
+ _enter_trace ();
+ _emit_line_info ();
+ _emit_cairo_op (cr, "%g set-line-width\n", width);
+ DLCALL (cairo_set_line_width, cr, width);
+ _exit_trace ();
+}
+
+static const char *
+_line_cap_to_string (cairo_line_cap_t line_cap)
+{
+#define f(name) case CAIRO_LINE_CAP_ ## name: return "LINE_CAP_" #name
+ switch (line_cap) {
+ f(BUTT);
+ f(ROUND);
+ f(SQUARE);
+ };
+#undef f
+ return "UNKNOWN_LINE_CAP";
+}
+
+void
+cairo_set_line_cap (cairo_t *cr, cairo_line_cap_t line_cap)
+{
+ _enter_trace ();
+ _emit_line_info ();
+ _emit_cairo_op (cr, "//%s set-line-cap\n", _line_cap_to_string (line_cap));
+ DLCALL (cairo_set_line_cap, cr, line_cap);
+ _exit_trace ();
+}
+
+static const char *
+_line_join_to_string (cairo_line_join_t line_join)
+{
+#define f(name) case CAIRO_LINE_JOIN_ ## name: return "LINE_JOIN_" #name
+ switch (line_join) {
+ f(MITER);
+ f(ROUND);
+ f(BEVEL);
+ };
+#undef f
+ return "UNKNOWN_LINE_JOIN";
+}
+
+void
+cairo_set_line_join (cairo_t *cr, cairo_line_join_t line_join)
+{
+ _enter_trace ();
+ _emit_line_info ();
+ _emit_cairo_op (cr,
+ "//%s set-line-join\n", _line_join_to_string (line_join));
+ DLCALL (cairo_set_line_join, cr, line_join);
+ _exit_trace ();
+}
+
+void
+cairo_set_dash (cairo_t *cr, const double *dashes, int num_dashes, double offset)
+{
+ _enter_trace ();
+ _emit_line_info ();
+ if (cr != NULL && _write_lock ()) {
+ int n;
+
+ _emit_context (cr);
+
+ _trace_printf ("[");
+ for (n = 0; n < num_dashes; n++) {
+ if (n != 0)
+ _trace_printf (" ");
+ _trace_printf ("%g", dashes[n]);
+ }
+ _trace_printf ("] %g set-dash\n", offset);
+
+ _write_unlock ();
+ }
+
+ DLCALL (cairo_set_dash, cr, dashes, num_dashes, offset);
+ _exit_trace ();
+}
+
+void
+cairo_set_miter_limit (cairo_t *cr, double limit)
+{
+ _enter_trace ();
+ _emit_line_info ();
+ _emit_cairo_op (cr, "%g set-miter-limit\n", limit);
+ DLCALL (cairo_set_miter_limit, cr, limit);
+ _exit_trace ();
+}
+
+void
+cairo_translate (cairo_t *cr, double tx, double ty)
+{
+ _enter_trace ();
+ _emit_line_info ();
+ _emit_cairo_op (cr, "%g %g translate\n", tx, ty);
+ DLCALL (cairo_translate, cr, tx, ty);
+ _exit_trace ();
+}
+
+void
+cairo_scale (cairo_t *cr, double sx, double sy)
+{
+ _enter_trace ();
+ _emit_line_info ();
+ _emit_cairo_op (cr, "%g %g scale\n", sx, sy);
+ DLCALL (cairo_scale, cr, sx, sy);
+ _exit_trace ();
+}
+
+void
+cairo_rotate (cairo_t *cr, double angle)
+{
+ _enter_trace ();
+ _emit_line_info ();
+ _emit_cairo_op (cr, "%g rotate\n", angle);
+ DLCALL (cairo_rotate, cr, angle);
+ _exit_trace ();
+}
+
+void
+cairo_transform (cairo_t *cr, const cairo_matrix_t *matrix)
+{
+ _enter_trace ();
+ _emit_line_info ();
+ _emit_cairo_op (cr, "%g %g %g %g %g %g matrix transform\n",
+ matrix->xx, matrix->yx,
+ matrix->xy, matrix->yy,
+ matrix->x0, matrix->y0);
+ DLCALL (cairo_transform, cr, matrix);
+ _exit_trace ();
+}
+
+void
+cairo_set_matrix (cairo_t *cr, const cairo_matrix_t *matrix)
+{
+ _enter_trace ();
+ _emit_line_info ();
+ if (_matrix_is_identity (matrix)) {
+ _emit_cairo_op (cr, "identity set-matrix\n");
+ } else {
+ _emit_cairo_op (cr, "%g %g %g %g %g %g matrix set-matrix\n",
+ matrix->xx, matrix->yx,
+ matrix->xy, matrix->yy,
+ matrix->x0, matrix->y0);
+ }
+ DLCALL (cairo_set_matrix, cr, matrix);
+ _exit_trace ();
+}
+
+cairo_surface_t *
+cairo_get_target (cairo_t *cr)
+{
+ cairo_surface_t *ret;
+
+ _enter_trace ();
+
+ ret = DLCALL (cairo_get_target, cr);
+ if (cr != NULL) {
+ Object *obj = _create_surface (ret);
+
+ if (! obj->defined) {
+ _emit_cairo_op (cr,
+ "/target get /s%ld exch def\n",
+ obj->token);
+ obj->defined = TRUE;
+ }
+ }
+
+ _exit_trace ();
+ return ret;
+}
+
+cairo_surface_t *
+cairo_get_group_target (cairo_t *cr)
+{
+ cairo_surface_t *ret;
+
+ _enter_trace ();
+
+ ret = DLCALL (cairo_get_group_target, cr);
+ if (cr != NULL) {
+ Object *obj = _create_surface (ret);
+
+ if (! obj->defined) {
+ _emit_cairo_op (cr,
+ "/group-target get /s%ld exch def\n",
+ obj->token);
+ obj->defined = TRUE;
+ }
+ }
+
+ _exit_trace ();
+ return ret;
+}
+
+void
+cairo_identity_matrix (cairo_t *cr)
+{
+ _enter_trace ();
+ _emit_line_info ();
+ _emit_cairo_op (cr, "identity set-matrix\n");
+ DLCALL (cairo_identity_matrix, cr);
+ _exit_trace ();
+}
+
+void
+cairo_new_path (cairo_t *cr)
+{
+ _enter_trace ();
+ _emit_line_info ();
+ _emit_cairo_op (cr, "n ");
+ DLCALL (cairo_new_path, cr);
+ _exit_trace ();
+}
+
+void
+cairo_move_to (cairo_t *cr, double x, double y)
+{
+ _enter_trace ();
+ _emit_cairo_op (cr, "%g %g m ", x, y);
+ DLCALL (cairo_move_to, cr, x, y);
+ _exit_trace ();
+}
+
+void
+cairo_new_sub_path (cairo_t *cr)
+{
+ _enter_trace ();
+ _emit_cairo_op (cr, "N ");
+ DLCALL (cairo_new_sub_path, cr);
+ _exit_trace ();
+}
+
+void
+cairo_line_to (cairo_t *cr, double x, double y)
+{
+ _enter_trace ();
+ _emit_cairo_op (cr, "%g %g l ", x, y);
+ DLCALL (cairo_line_to, cr, x, y);
+ _exit_trace ();
+}
+
+void
+cairo_curve_to (cairo_t *cr, double x1, double y1, double x2, double y2, double x3, double y3)
+{
+ _enter_trace ();
+ _emit_cairo_op (cr, "%g %g %g %g %g %g c ", x1, y1, x2, y2, x3, y3);
+ DLCALL (cairo_curve_to, cr, x1, y1, x2, y2, x3, y3);
+ _exit_trace ();
+}
+
+void
+cairo_arc (cairo_t *cr, double xc, double yc, double radius, double angle1, double angle2)
+{
+ _enter_trace ();
+ _emit_cairo_op (cr, "%g %g %g %g %g arc\n", xc, yc, radius, angle1, angle2);
+ DLCALL (cairo_arc, cr, xc, yc, radius, angle1, angle2);
+ _exit_trace ();
+}
+
+void
+cairo_arc_negative (cairo_t *cr, double xc, double yc, double radius, double angle1, double angle2)
+{
+ _enter_trace ();
+ _emit_cairo_op (cr, "%g %g %g %g %g arc-\n",
+ xc, yc, radius, angle1, angle2);
+ DLCALL (cairo_arc_negative, cr, xc, yc, radius, angle1, angle2);
+ _exit_trace ();
+}
+
+void
+cairo_rel_move_to (cairo_t *cr, double dx, double dy)
+{
+ _enter_trace ();
+ _emit_cairo_op (cr, "%g %g M ", dx, dy);
+ DLCALL (cairo_rel_move_to, cr, dx, dy);
+ _exit_trace ();
+}
+
+void
+cairo_rel_line_to (cairo_t *cr, double dx, double dy)
+{
+ _enter_trace ();
+ _emit_cairo_op (cr, "%g %g L ", dx, dy);
+ DLCALL (cairo_rel_line_to, cr, dx, dy);
+ _exit_trace ();
+}
+
+void
+cairo_rel_curve_to (cairo_t *cr, double dx1, double dy1, double dx2, double dy2, double dx3, double dy3)
+{
+ _enter_trace ();
+ _emit_cairo_op (cr, "%g %g %g %g %g %g C ",
+ dx1, dy1, dx2, dy2, dx3, dy3);
+ DLCALL (cairo_rel_curve_to, cr, dx1, dy1, dx2, dy2, dx3, dy3);
+ _exit_trace ();
+}
+
+void
+cairo_rectangle (cairo_t *cr, double x, double y, double width, double height)
+{
+ _enter_trace ();
+ _emit_cairo_op (cr, "%g %g %g %g rectangle\n", x, y, width, height);
+ DLCALL (cairo_rectangle, cr, x, y, width, height);
+ _exit_trace ();
+}
+
+void
+cairo_close_path (cairo_t *cr)
+{
+ _enter_trace ();
+ _emit_cairo_op (cr, "h\n");
+ DLCALL (cairo_close_path, cr);
+ _exit_trace ();
+}
+
+void
+cairo_paint (cairo_t *cr)
+{
+ _enter_trace ();
+ _emit_line_info ();
+ _emit_cairo_op (cr, "paint\n");
+ DLCALL (cairo_paint, cr);
+ _exit_trace ();
+}
+
+void
+cairo_paint_with_alpha (cairo_t *cr, double alpha)
+{
+ _enter_trace ();
+ _emit_line_info ();
+ _emit_cairo_op (cr, "%g paint-with-alpha\n", alpha);
+ DLCALL (cairo_paint_with_alpha, cr, alpha);
+ _exit_trace ();
+}
+
+void
+cairo_mask (cairo_t *cr, cairo_pattern_t *pattern)
+{
+ _enter_trace ();
+ _emit_line_info ();
+ if (cr != NULL && pattern != NULL && _write_lock ()) {
+ Object *obj = _get_object (PATTERN, pattern);
+ cairo_bool_t need_context_and_pattern = TRUE;
+
+ if (_is_current (PATTERN, pattern, 0) &&
+ _is_current (CONTEXT, cr, 1))
+ {
+ if (obj->defined) {
+ _consume_operand (false);
+ need_context_and_pattern = FALSE;
+ }
+ }
+ else if (_is_current (PATTERN, pattern, 1) &&
+ _is_current (CONTEXT, cr, 0))
+ {
+ if (obj->defined) {
+ _trace_printf ("exch ");
+ _exch_operands ();
+ _consume_operand (false);
+ need_context_and_pattern = FALSE;
+ }
+ }
+
+ if (need_context_and_pattern) {
+ _emit_context (cr);
+ _emit_pattern_id (pattern);
+ }
+
+ _trace_printf (" mask\n");
+ _write_unlock ();
+ }
+ DLCALL (cairo_mask, cr, pattern);
+ _exit_trace ();
+}
+
+void
+cairo_mask_surface (cairo_t *cr, cairo_surface_t *surface, double x, double y)
+{
+ _enter_trace ();
+ _emit_line_info ();
+ if (cr != NULL && surface != NULL && _write_lock ()) {
+ Object *obj = _get_object (SURFACE, surface);
+ if (_is_current (SURFACE, surface, 0) &&
+ _is_current (CONTEXT, cr, 1))
+ {
+ _consume_operand (false);
+ }
+ else if (_is_current (SURFACE, surface, 1) &&
+ _is_current (CONTEXT, cr, 0))
+ {
+ _trace_printf ("exch ");
+ _exch_operands ();
+ _consume_operand (false);
+ } else if (obj->defined){
+ _emit_context (cr);
+ _trace_printf ("s%ld ", obj->token);
+ } else {
+ _emit_context (cr);
+ _trace_printf ("%d index ",
+ current_stack_depth - obj->operand - 1);
+ }
+ _trace_printf ("pattern");
+
+ if (x != 0. || y != 0.)
+ _trace_printf (" %g %g translate", -x, -y);
+
+ _trace_printf (" mask\n");
+ _write_unlock ();
+ }
+
+ DLCALL (cairo_mask_surface, cr, surface, x, y);
+ _exit_trace ();
+}
+
+void
+cairo_stroke (cairo_t *cr)
+{
+ _enter_trace ();
+ _emit_line_info ();
+ _emit_cairo_op (cr, "stroke\n");
+ DLCALL (cairo_stroke, cr);
+ _exit_trace ();
+}
+
+void
+cairo_stroke_preserve (cairo_t *cr)
+{
+ _enter_trace ();
+ _emit_line_info ();
+ _emit_cairo_op (cr, "stroke+\n");
+ DLCALL (cairo_stroke_preserve, cr);
+ _exit_trace ();
+}
+
+void
+cairo_fill (cairo_t *cr)
+{
+ _enter_trace ();
+ _emit_line_info ();
+ _emit_cairo_op (cr, "fill\n");
+ DLCALL (cairo_fill, cr);
+ _exit_trace ();
+}
+
+void
+cairo_fill_preserve (cairo_t *cr)
+{
+ _enter_trace ();
+ _emit_line_info ();
+ _emit_cairo_op (cr, "fill+\n");
+ DLCALL (cairo_fill_preserve, cr);
+ _exit_trace ();
+}
+
+void
+cairo_copy_page (cairo_t *cr)
+{
+ _enter_trace ();
+ _emit_line_info ();
+ _emit_cairo_op (cr, "copy-page\n");
+ DLCALL (cairo_copy_page, cr);
+ _exit_trace ();
+}
+
+void
+cairo_show_page (cairo_t *cr)
+{
+ _enter_trace ();
+ _emit_line_info ();
+ _emit_cairo_op (cr, "show-page\n");
+ DLCALL (cairo_show_page, cr);
+ _exit_trace ();
+}
+
+void
+cairo_clip (cairo_t *cr)
+{
+ _enter_trace ();
+ _emit_line_info ();
+ _emit_cairo_op (cr, "clip\n");
+ DLCALL (cairo_clip, cr);
+ _exit_trace ();
+}
+
+void
+cairo_clip_preserve (cairo_t *cr)
+{
+ _enter_trace ();
+ _emit_line_info ();
+ _emit_cairo_op (cr, "clip+\n");
+ DLCALL (cairo_clip_preserve, cr);
+ _exit_trace ();
+}
+
+void
+cairo_reset_clip (cairo_t *cr)
+{
+ _enter_trace ();
+ _emit_line_info ();
+ _emit_cairo_op (cr, "reset-clip\n");
+ DLCALL (cairo_reset_clip, cr);
+ _exit_trace ();
+}
+
+
+static const char *
+_slant_to_string (cairo_font_slant_t font_slant)
+{
+#define f(name) case CAIRO_FONT_SLANT_ ## name: return "SLANT_" #name
+ switch (font_slant) {
+ f(NORMAL);
+ f(ITALIC);
+ f(OBLIQUE);
+ };
+#undef f
+ return "UNKNOWN_SLANT";
+}
+
+static const char *
+_weight_to_string (cairo_font_weight_t font_weight)
+{
+#define f(name) case CAIRO_FONT_WEIGHT_ ## name: return "WEIGHT_" #name
+ switch (font_weight) {
+ f(NORMAL);
+ f(BOLD);
+ };
+#undef f
+ return "UNKNOWN_WEIGHT";
+}
+
+void
+cairo_select_font_face (cairo_t *cr, const char *family, cairo_font_slant_t slant, cairo_font_weight_t weight)
+{
+ _enter_trace ();
+ _emit_line_info ();
+ if (cr != NULL && _write_lock ()) {
+ _emit_context (cr);
+ _emit_string_literal (family, -1);
+ _trace_printf (" //%s //%s select-font-face\n",
+ _slant_to_string (slant),
+ _weight_to_string (weight));
+ _write_unlock ();
+ }
+ DLCALL (cairo_select_font_face, cr, family, slant, weight);
+ _exit_trace ();
+}
+
+cairo_font_face_t *
+cairo_get_font_face (cairo_t *cr)
+{
+ cairo_font_face_t *ret;
+ long font_face_id;
+
+ _enter_trace ();
+
+ ret = DLCALL (cairo_get_font_face, cr);
+ font_face_id = _create_font_face_id (ret);
+
+ _emit_cairo_op (cr, "/font-face get %% f%ld\n", font_face_id);
+ _push_operand (FONT_FACE, ret);
+ dump_stack(__func__);
+
+ _exit_trace ();
+ return ret;
+}
+
+void
+cairo_set_font_face (cairo_t *cr, cairo_font_face_t *font_face)
+{
+ _enter_trace ();
+ _emit_line_info ();
+ if (cr != NULL && font_face != NULL && _write_lock ()) {
+ if (_is_current (FONT_FACE, font_face, 0) &&
+ _is_current (CONTEXT, cr, 1))
+ {
+ _consume_operand (false);
+ }
+ else if (_is_current (FONT_FACE, font_face, 1) &&
+ _is_current (CONTEXT, cr, 0))
+ {
+ _trace_printf ("exch ");
+ _exch_operands ();
+ _consume_operand (false);
+ }
+ else
+ {
+ _emit_context (cr);
+ _emit_font_face_id (font_face);
+ }
+
+ _trace_printf ("set-font-face\n");
+ _write_unlock ();
+ }
+
+ DLCALL (cairo_set_font_face, cr, font_face);
+ _exit_trace ();
+}
+
+void
+cairo_set_font_size (cairo_t *cr, double size)
+{
+ _enter_trace ();
+ _emit_line_info ();
+ _emit_cairo_op (cr, "%g set-font-size\n", size);
+ DLCALL (cairo_set_font_size, cr, size);
+ _exit_trace ();
+}
+
+void
+cairo_set_font_matrix (cairo_t *cr, const cairo_matrix_t *matrix)
+{
+ _enter_trace ();
+ _emit_line_info ();
+ _emit_cairo_op (cr, "%g %g %g %g %g %g matrix set-font-matrix\n",
+ matrix->xx, matrix->yx,
+ matrix->xy, matrix->yy,
+ matrix->x0, matrix->y0);
+ DLCALL (cairo_set_font_matrix, cr, matrix);
+ _exit_trace ();
+}
+
+static const char *
+_subpixel_order_to_string (cairo_subpixel_order_t subpixel_order)
+{
+#define f(name) case CAIRO_SUBPIXEL_ORDER_ ## name: return "SUBPIXEL_ORDER_" #name
+ switch (subpixel_order) {
+ f(DEFAULT);
+ f(RGB);
+ f(BGR);
+ f(VRGB);
+ f(VBGR);
+ };
+#undef f
+ return "UNKNOWN_SUBPIXEL_ORDER";
+}
+
+static const char *
+_hint_style_to_string (cairo_hint_style_t hint_style)
+{
+#define f(name) case CAIRO_HINT_STYLE_ ## name: return "HINT_STYLE_" #name
+ switch (hint_style) {
+ f(DEFAULT);
+ f(NONE);
+ f(SLIGHT);
+ f(MEDIUM);
+ f(FULL);
+ };
+#undef f
+ return "UNKNOWN_HINT_STYLE";
+}
+
+static const char *
+_hint_metrics_to_string (cairo_hint_metrics_t hint_metrics)
+{
+#define f(name) case CAIRO_HINT_METRICS_ ## name: return "HINT_METRICS_" #name
+ switch (hint_metrics) {
+ f(DEFAULT);
+ f(OFF);
+ f(ON);
+ };
+#undef f
+ return "UNKNOWN_HINT_METRICS";
+}
+
+static void
+_emit_font_options (const cairo_font_options_t *options)
+{
+ cairo_antialias_t antialias;
+ cairo_subpixel_order_t subpixel_order;
+ cairo_hint_style_t hint_style;
+ cairo_hint_metrics_t hint_metrics;
+
+ _trace_printf ("<<");
+
+ antialias = DLCALL (cairo_font_options_get_antialias, options);
+ if (antialias != CAIRO_ANTIALIAS_DEFAULT) {
+ _trace_printf (" /antialias //%s",
+ _antialias_to_string (antialias));
+ }
+
+ subpixel_order = DLCALL (cairo_font_options_get_subpixel_order, options);
+ if (subpixel_order != CAIRO_SUBPIXEL_ORDER_DEFAULT) {
+ _trace_printf (" /subpixel-order //%s",
+ _subpixel_order_to_string (subpixel_order));
+ }
+
+ hint_style = DLCALL (cairo_font_options_get_hint_style, options);
+ if (hint_style != CAIRO_HINT_STYLE_DEFAULT) {
+ _trace_printf (" /hint-style //%s",
+ _hint_style_to_string (hint_style));
+ }
+
+ hint_metrics = DLCALL (cairo_font_options_get_hint_metrics, options);
+ if (hint_metrics != CAIRO_HINT_METRICS_DEFAULT) {
+ _trace_printf (" /hint-metrics //%s",
+ _hint_metrics_to_string (hint_metrics));
+ }
+
+ _trace_printf (" >>");
+}
+
+void
+cairo_set_font_options (cairo_t *cr, const cairo_font_options_t *options)
+{
+ _enter_trace ();
+ _emit_line_info ();
+ if (cr != NULL && options != NULL && _write_lock ()) {
+ _emit_context (cr);
+ _emit_font_options (options);
+ _trace_printf (" set-font-options\n");
+ _write_unlock ();
+ }
+
+ DLCALL (cairo_set_font_options, cr, options);
+ _exit_trace ();
+}
+
+cairo_scaled_font_t *
+cairo_get_scaled_font (cairo_t *cr)
+{
+ cairo_scaled_font_t *ret;
+
+ _enter_trace ();
+
+ ret = DLCALL (cairo_get_scaled_font, cr);
+
+ if (cr != NULL && ! _has_scaled_font_id (ret)) {
+ _emit_cairo_op (cr, "/scaled-font get /sf%ld exch def\n",
+ _create_scaled_font_id (ret));
+ _get_object (SCALED_FONT, ret)->defined = TRUE;
+ }
+
+ _exit_trace ();
+ return ret;
+}
+
+void
+cairo_set_scaled_font (cairo_t *cr, const cairo_scaled_font_t *scaled_font)
+{
+ _enter_trace ();
+ _emit_line_info ();
+ if (cr != NULL && scaled_font != NULL && _write_lock ()) {
+ Object *obj = _get_object (SCALED_FONT, scaled_font);
+ cairo_bool_t need_context_and_font = TRUE;
+
+ if (_is_current (SCALED_FONT, scaled_font, 0) &&
+ _is_current (CONTEXT, cr, 1))
+ {
+ if (obj->defined) {
+ _consume_operand (false);
+ } else {
+ _trace_printf ("exch 1 index ");
+ _exch_operands ();
+ }
+ need_context_and_font = FALSE;
+ }
+ else if (_is_current (SCALED_FONT, scaled_font, 1) &&
+ _is_current (CONTEXT, cr, 0))
+ {
+ if (obj->defined) {
+ _trace_printf ("exch ");
+ _exch_operands ();
+ _consume_operand (false);
+ need_context_and_font = FALSE;
+ }
+ }
+
+ if (need_context_and_font) {
+ _emit_context (cr);
+ _emit_scaled_font_id (scaled_font);
+ }
+
+ _trace_printf ("set-scaled-font\n");
+
+ _write_unlock ();
+ }
+ DLCALL (cairo_set_scaled_font, cr, scaled_font);
+ _exit_trace ();
+}
+
+static void
+_emit_matrix (const cairo_matrix_t *m)
+{
+ if (_matrix_is_identity(m))
+ {
+ _trace_printf ("identity");
+ }
+ else
+ {
+ _trace_printf ("%g %g %g %g %g %g matrix",
+ m->xx, m->yx,
+ m->xy, m->yy,
+ m->x0, m->y0);
+ }
+}
+
+cairo_scaled_font_t *
+cairo_scaled_font_create (cairo_font_face_t *font_face,
+ const cairo_matrix_t *font_matrix,
+ const cairo_matrix_t *ctm,
+ const cairo_font_options_t *options)
+{
+ cairo_scaled_font_t *ret;
+
+ _enter_trace ();
+
+ ret = DLCALL (cairo_scaled_font_create, font_face, font_matrix, ctm, options);
+ if (_has_scaled_font_id (ret))
+ goto out;
+
+ _emit_line_info ();
+ if (font_face != NULL &&
+ font_matrix != NULL &&
+ ctm != NULL &&
+ options != NULL
+ && _write_lock ())
+ {
+ Object *obj;
+
+ obj = _type_object_create (SCALED_FONT, ret);
+ DLCALL (cairo_scaled_font_set_user_data,
+ ret, &destroy_key, obj, _object_undef);
+
+ if (_pop_operands_to (FONT_FACE, font_face))
+ _consume_operand (false);
+ else
+ _trace_printf ("f%ld ", _get_font_face_id (font_face));
+
+ _emit_matrix (font_matrix);
+ _trace_printf (" ");
+
+ _emit_matrix (ctm);
+ _trace_printf (" ");
+
+ _emit_font_options (options);
+
+ _trace_printf (" scaled-font /sf%ld exch def\n",
+ obj->token);
+ obj->defined = TRUE;
+
+ _write_unlock ();
+ }
+
+out:
+ _exit_trace ();
+ return ret;
+}
+
+void
+cairo_show_text (cairo_t *cr, const char *utf8)
+{
+ _enter_trace ();
+ _emit_line_info ();
+ if (cr != NULL && _write_lock ()) {
+ _emit_context (cr);
+ _emit_string_literal (utf8, -1);
+ _trace_printf (" show-text\n");
+ _write_unlock ();
+ }
+ DLCALL (cairo_show_text, cr, utf8);
+ _exit_trace ();
+}
+
+static void
+_glyph_advance (cairo_scaled_font_t *font,
+ const cairo_glyph_t *glyph,
+ double *x, double *y)
+{
+ cairo_text_extents_t extents;
+
+ DLCALL (cairo_scaled_font_glyph_extents, font, glyph, 1, &extents);
+ *x += extents.x_advance;
+ *y += extents.y_advance;
+}
+
+#define TOLERANCE 1e-5
+static void
+_emit_glyphs (cairo_scaled_font_t *font,
+ const cairo_glyph_t *glyphs,
+ int num_glyphs)
+{
+ double x,y;
+ int n;
+
+ if (num_glyphs == 0) {
+ _trace_printf ("[]");
+ return;
+ }
+
+ for (n = 0; n < num_glyphs; n++) {
+ if (glyphs[n].index > 255)
+ break;
+ }
+
+ x = glyphs->x;
+ y = glyphs->y;
+ if (n < num_glyphs) { /* need full glyph range */
+ cairo_bool_t first;
+
+ _trace_printf ("[%g %g [", x, y);
+ first = TRUE;
+ while (num_glyphs--) {
+ if (fabs (glyphs->x - x) > TOLERANCE ||
+ fabs (glyphs->y - y) > TOLERANCE)
+ {
+ x = glyphs->x;
+ y = glyphs->y;
+ _trace_printf ("] %g %g [", x, y);
+ first = TRUE;
+ }
+
+ if (! first)
+ _trace_printf (" ");
+ _trace_printf ("%lu", glyphs->index);
+ first = FALSE;
+
+ _glyph_advance (font, glyphs, &x, &y);
+ glyphs++;
+ }
+ _trace_printf ("]]");
+ } else {
+ struct _data_stream stream;
+
+ if (num_glyphs == 1) {
+ _trace_printf ("[%g %g <%02lx>]", x, y, glyphs->index);
+ } else {
+ _trace_printf ("[%g %g <~", x, y);
+ _write_base85_data_start (&stream);
+ while (num_glyphs--) {
+ unsigned char c;
+
+ if (fabs (glyphs->x - x) > TOLERANCE ||
+ fabs (glyphs->y - y) > TOLERANCE)
+ {
+ x = glyphs->x;
+ y = glyphs->y;
+ _write_base85_data_end (&stream);
+ _trace_printf ("~> %g %g <~", x, y);
+ _write_base85_data_start (&stream);
+ }
+
+ c = glyphs->index;
+ _write_base85_data (&stream, &c, 1);
+
+ _glyph_advance (font, glyphs, &x, &y);
+ glyphs++;
+ }
+ _write_base85_data_end (&stream);
+ _trace_printf ("~>]");
+ }
+ }
+}
+
+void
+cairo_show_glyphs (cairo_t *cr, const cairo_glyph_t *glyphs, int num_glyphs)
+{
+ _enter_trace ();
+ _emit_line_info ();
+ if (cr != NULL && glyphs != NULL && _write_lock ()) {
+ cairo_scaled_font_t *font;
+
+ _emit_context (cr);
+ font = DLCALL (cairo_get_scaled_font, cr);
+
+ _emit_glyphs (font, glyphs, num_glyphs);
+ _trace_printf (" show-glyphs\n");
+ _write_unlock ();
+ }
+
+ DLCALL (cairo_show_glyphs, cr, glyphs, num_glyphs);
+ _exit_trace ();
+}
+
+static const char *
+_direction_to_string (cairo_bool_t backward)
+{
+ const char *names[] = {
+ "FORWARD",
+ "BACKWARD"
+ };
+ return names[!!backward];
+}
+
+void
+cairo_show_text_glyphs (cairo_t *cr,
+ const char *utf8,
+ int utf8_len,
+ const cairo_glyph_t *glyphs,
+ int num_glyphs,
+ const cairo_text_cluster_t *clusters,
+ int num_clusters,
+ cairo_text_cluster_flags_t backward)
+{
+ cairo_scaled_font_t *font;
+
+ _enter_trace ();
+
+ font = DLCALL (cairo_get_scaled_font, cr);
+
+ _emit_line_info ();
+ if (cr != NULL && glyphs != NULL && clusters != NULL && _write_lock ()) {
+ int n;
+
+ _emit_context (cr);
+
+ _emit_string_literal (utf8, utf8_len);
+
+ _emit_glyphs (font, glyphs, num_glyphs);
+ _trace_printf (" [");
+ for (n = 0; n < num_clusters; n++) {
+ _trace_printf (" %d %d",
+ clusters[n].num_bytes,
+ clusters[n].num_glyphs);
+ }
+ _trace_printf (" ] //%s show-text-glyphs\n",
+ _direction_to_string (backward));
+
+ _write_unlock ();
+ }
+
+ DLCALL (cairo_show_text_glyphs, cr,
+ utf8, utf8_len,
+ glyphs, num_glyphs,
+ clusters, num_clusters,
+ backward);
+ _exit_trace ();
+}
+
+void
+cairo_text_path (cairo_t *cr, const char *utf8)
+{
+ _enter_trace ();
+ _emit_line_info ();
+ if (cr != NULL && _write_lock ()) {
+ _emit_context (cr);
+ _emit_string_literal (utf8, -1);
+ _trace_printf (" text-path\n");
+ _write_unlock ();
+ }
+ DLCALL (cairo_text_path, cr, utf8);
+ _exit_trace ();
+}
+
+void
+cairo_glyph_path (cairo_t *cr, const cairo_glyph_t *glyphs, int num_glyphs)
+{
+ cairo_scaled_font_t *font;
+
+ _enter_trace ();
+
+ font = DLCALL (cairo_get_scaled_font, cr);
+
+ _emit_line_info ();
+ if (cr != NULL && glyphs != NULL && _write_lock ()) {
+ _emit_context (cr);
+ _emit_glyphs (font, glyphs, num_glyphs);
+ _trace_printf (" glyph-path\n");
+
+ _write_unlock ();
+ }
+
+ DLCALL (cairo_glyph_path, cr, glyphs, num_glyphs);
+ _exit_trace ();
+}
+
+void
+cairo_append_path (cairo_t *cr, const cairo_path_t *path)
+{
+ /* XXX no support for named paths, so manually reconstruct */
+ int i;
+ cairo_path_data_t *p;
+
+ _enter_trace ();
+
+ _emit_line_info ();
+ if (cr == NULL || path == NULL) {
+ DLCALL (cairo_append_path, cr, path);
+ _exit_trace ();
+ return;
+ }
+
+ for (i=0; i < path->num_data; i += path->data[i].header.length) {
+ p = &path->data[i];
+ switch (p->header.type) {
+ case CAIRO_PATH_MOVE_TO:
+ if (p->header.length >= 2)
+ cairo_move_to (cr, p[1].point.x, p[1].point.y);
+ break;
+ case CAIRO_PATH_LINE_TO:
+ if (p->header.length >= 2)
+ cairo_line_to (cr, p[1].point.x, p[1].point.y);
+ break;
+ case CAIRO_PATH_CURVE_TO:
+ if (p->header.length >= 4)
+ cairo_curve_to (cr,
+ p[1].point.x, p[1].point.y,
+ p[2].point.x, p[2].point.y,
+ p[3].point.x, p[3].point.y);
+ break;
+ case CAIRO_PATH_CLOSE_PATH:
+ if (p->header.length >= 1)
+ cairo_close_path (cr);
+ break;
+ default:
+ break;
+ }
+ }
+ _exit_trace ();
+}
+
+cairo_surface_t *
+cairo_image_surface_create (cairo_format_t format, int width, int height)
+{
+ cairo_surface_t *ret;
+
+ _enter_trace ();
+
+ ret = DLCALL (cairo_image_surface_create, format, width, height);
+
+ _emit_line_info ();
+ if (_write_lock ()) {
+ Object *obj = _create_surface (ret);
+ const char *format_str = _format_to_string (format);
+ const char *content_str = _format_to_content_string (format);
+
+ _trace_printf ("dict\n"
+ " /width %d set\n"
+ " /height %d set\n"
+ " /format //%s set\n"
+ " /content //%s set\n"
+ " image dup /s%ld exch def\n",
+ width, height, format_str, content_str, obj->token);
+ obj->width = width;
+ obj->height = height;
+ obj->defined = TRUE;
+ _push_object (obj);
+ dump_stack(__func__);
+ _write_unlock ();
+ }
+
+ _exit_trace ();
+ return ret;
+}
+
+cairo_surface_t *
+cairo_image_surface_create_for_data (unsigned char *data, cairo_format_t format, int width, int height, int stride)
+{
+ cairo_surface_t *ret;
+
+ _enter_trace ();
+
+ ret = DLCALL (cairo_image_surface_create_for_data, data, format, width, height, stride);
+
+ _emit_line_info ();
+ if (_write_lock ()) {
+ Object *obj = _create_surface (ret);
+
+ /* cairo_image_surface_create_for_data() is both used to supply
+ * foreign pixel data to cairo and in order to read pixels back.
+ * Defer grabbing the pixel contents until we have to, but only for
+ * "large" images, for small images the overhead of embedding pixels
+ * is negligible.
+ *
+ * Choose 32x32 as that captures most icons which thanks to GdkPixbuf
+ * are frequently reloaded.
+ */
+ if (width * height < 32*32) {
+ _emit_image (ret, NULL);
+ _trace_printf (" dup /s%ld exch def\n",
+ obj->token);
+ } else {
+ _trace_printf ("dict\n"
+ " /width %d set\n"
+ " /height %d set\n"
+ " /format //%s set\n"
+ " image dup /s%ld exch def\n",
+ width, height,
+ _format_to_string (format),
+ obj->token);
+
+ obj->foreign = TRUE;
+ }
+
+ obj->width = width;
+ obj->height = height;
+ obj->defined = TRUE;
+ _push_object (obj);
+ dump_stack(__func__);
+ _write_unlock ();
+ }
+
+ _exit_trace ();
+ return ret;
+}
+
+unsigned char *
+cairo_image_surface_get_data (cairo_surface_t *surface)
+{
+ unsigned char *ptr;
+
+ /* Just leave some breadcrumbs */
+ _enter_trace ();
+ _emit_line_info ();
+ if (surface != NULL && _write_lock ()) {
+ _trace_printf ("%% s%ld get-data\n", _get_surface_id (surface));
+ _write_unlock ();
+ }
+ ptr = DLCALL (cairo_image_surface_get_data, surface);
+ _exit_trace ();
+
+ return ptr;
+}
+
+cairo_pattern_t *
+cairo_pattern_create_raster_source (void *data, cairo_content_t content, int width, int height)
+{
+ cairo_pattern_t *ret;
+
+ _enter_trace ();
+
+ ret = DLCALL (cairo_pattern_create_raster_source, data, content, width, height);
+
+ _emit_line_info ();
+ if (_write_lock ()) {
+ long pattern_id = _create_pattern_id (ret);
+ cairo_format_t format;
+ cairo_surface_t *image;
+ cairo_t *cr;
+
+ /* Impossible to accurately record the interaction with this custom
+ * pattern so just suck all the data into an image upfront */
+ switch (content) {
+ case CAIRO_CONTENT_ALPHA: format = CAIRO_FORMAT_A8; break;
+ case CAIRO_CONTENT_COLOR: format = CAIRO_FORMAT_RGB24; break;
+ default:
+ case CAIRO_CONTENT_COLOR_ALPHA: format = CAIRO_FORMAT_ARGB32; break;
+ }
+
+ _trace_printf ("%% raster-source\n");
+
+ image = DLCALL (cairo_image_surface_create, format, width, height);
+ cr = DLCALL (cairo_create, image);
+ DLCALL (cairo_set_source, cr, ret);
+ DLCALL (cairo_paint, cr);
+ DLCALL (cairo_destroy, cr);
+
+ _emit_image (image, NULL);
+ DLCALL (cairo_surface_destroy, image);
+ _trace_printf (" pattern dup /s%ld exch def\n",
+ pattern_id);
+
+ _push_operand (PATTERN, ret);
+ _get_object (PATTERN, ret)->defined = TRUE;
+ dump_stack(__func__);
+ _write_unlock ();
+ }
+
+ _exit_trace ();
+ return ret;
+}
+
+cairo_surface_t *
+cairo_surface_create_similar (cairo_surface_t *other,
+ cairo_content_t content,
+ int width, int height)
+{
+ cairo_surface_t *ret;
+
+ _enter_trace ();
+
+ ret = DLCALL (cairo_surface_create_similar, other, content, width, height);
+
+ _emit_line_info ();
+ if (other != NULL && _write_lock ()) {
+ Object *other_obj = _get_object(SURFACE, other);
+ Object *new_obj = _create_surface (ret);
+
+ if (other_obj->operand != -1) {
+ if (current_stack_depth == other_obj->operand + 1)
+ _trace_printf ("dup ");
+ else
+ _trace_printf ("%d index ",
+ current_stack_depth - other_obj->operand - 1);
+ } else {
+ assert(other_obj->defined);
+ _trace_printf ("s%ld ", other_obj->token);
+ }
+
+ _trace_printf ("%d %d //%s similar dup /s%ld exch def\n",
+ width, height,
+ _content_to_string (content),
+ new_obj->token);
+
+ new_obj->width = width;
+ new_obj->height = height;
+ new_obj->defined = TRUE;
+
+ _push_object (new_obj);
+ dump_stack(__func__);
+ _write_unlock ();
+ }
+
+ _exit_trace ();
+ return ret;
+}
+
+cairo_surface_t *
+cairo_surface_create_similar_image (cairo_surface_t *other,
+ cairo_format_t format,
+ int width, int height)
+{
+ cairo_surface_t *ret;
+
+ _enter_trace ();
+
+ ret = DLCALL (cairo_surface_create_similar_image,
+ other, format, width, height);
+
+ _emit_line_info ();
+ if (other != NULL && _write_lock ()) {
+ Object *other_obj = _get_object(SURFACE, other);
+ Object *new_obj = _create_surface (ret);
+
+ if (other_obj->defined)
+ _trace_printf ("s%ld ", other_obj->token);
+ else if (current_stack_depth == other_obj->operand + 1)
+ _trace_printf ("dup ");
+ else
+ _trace_printf ("%d index ",
+ current_stack_depth - other_obj->operand - 1);
+ _trace_printf ("//%s %d %d similar-image %% s%ld\n",
+ _format_to_string (format),
+ width, height,
+ new_obj->token);
+ new_obj->width = width;
+ new_obj->height = height;
+
+ _push_object (new_obj);
+ dump_stack(__func__);
+ _write_unlock ();
+ }
+
+ _exit_trace ();
+ return ret;
+}
+
+cairo_surface_t *
+cairo_surface_map_to_image (cairo_surface_t *surface,
+ const cairo_rectangle_int_t *extents)
+{
+ cairo_surface_t *ret;
+
+ _enter_trace ();
+
+ ret = DLCALL (cairo_surface_map_to_image, surface, extents);
+
+ _emit_line_info ();
+ if (_write_lock ()) {
+ Object *obj = _create_surface (ret);
+
+ _emit_surface (surface);
+ if (extents) {
+ _trace_printf ("[%d %d %d %d] map-to-image %% s%ld\n",
+ extents->x, extents->y,
+ extents->width, extents->height,
+ obj->token);
+ obj->width = extents->width;
+ obj->height = extents->height;
+ } else {
+ _trace_printf ("[ ] map-to-image %% s%ld\n", obj->token);
+ }
+
+ _push_object (obj);
+ dump_stack(__func__);
+ _write_unlock ();
+ }
+
+ _exit_trace ();
+ return ret;
+}
+
+void
+cairo_surface_unmap_image (cairo_surface_t *surface,
+ cairo_surface_t *image)
+{
+ _enter_trace ();
+
+ _emit_line_info ();
+ if (_write_lock ()) {
+ Object *s = _get_object (SURFACE, surface);
+ Object *i = _get_object (SURFACE, image);
+ if (!(s->operand == current_stack_depth - 2 &&
+ i->operand == current_stack_depth - 1)) {
+ if (i->operand != s->operand + 1 || ! _pop_operands_to_depth (i->operand + 1)) {
+ _emit_surface (surface);
+ _emit_surface (image);
+ }
+ }
+ _trace_printf ("unmap-image\n");
+ _consume_operand (true);
+ _write_unlock ();
+ }
+
+ DLCALL (cairo_surface_unmap_image, surface, image);
+
+ _exit_trace ();
+}
+
+cairo_surface_t *
+cairo_surface_create_for_rectangle (cairo_surface_t *target,
+ double x, double y,
+ double width, double height)
+{
+ cairo_surface_t *ret;
+
+ _enter_trace ();
+
+ ret = DLCALL (cairo_surface_create_for_rectangle, target, x, y, width, height);
+
+ _emit_line_info ();
+ if (target != NULL && _write_lock ()) {
+ Object *target_obj = _get_object (SURFACE, target);
+ Object *child_obj = _create_surface (ret);
+
+ if (target_obj->defined)
+ _trace_printf ("s%ld ", target_obj->token);
+ else if (current_stack_depth == target_obj->operand + 1)
+ _trace_printf ("dup ");
+ else
+ _trace_printf ("%d index ", current_stack_depth - target_obj->operand - 1);
+ _trace_printf ("%f %f %f %f subsurface %% s%ld\n",
+ x, y, width, height,
+ child_obj->token);
+
+ _push_object (child_obj);
+ dump_stack(__func__);
+ _write_unlock ();
+ }
+
+ _exit_trace ();
+ return ret;
+}
+
+static void CAIRO_PRINTF_FORMAT(2, 3)
+_emit_surface_op (cairo_surface_t *surface, const char *fmt, ...)
+{
+ va_list ap;
+
+ if (surface == NULL || ! _write_lock ())
+ return;
+
+ _emit_surface (surface);
+
+ va_start (ap, fmt);
+ _trace_vprintf ( fmt, ap);
+ va_end (ap);
+
+ _write_unlock ();
+}
+
+void
+cairo_surface_finish (cairo_surface_t *surface)
+{
+ _enter_trace ();
+ _emit_line_info ();
+ DLCALL (cairo_surface_finish, surface);
+ _exit_trace ();
+}
+
+void
+cairo_surface_flush (cairo_surface_t *surface)
+{
+ _enter_trace ();
+ _emit_line_info ();
+ if (surface != NULL && _write_lock ()) {
+ _trace_printf ("%% s%ld flush\n", _get_surface_id (surface));
+ _write_unlock ();
+ }
+ DLCALL (cairo_surface_flush, surface);
+ _exit_trace ();
+}
+
+void
+cairo_surface_mark_dirty (cairo_surface_t *surface)
+{
+ _enter_trace ();
+ _emit_line_info ();
+
+ /* Call cairo before emitting the trace since _emit_surface() might cause
+ * snapshots to be creates while mark_dirty assert()s that there are none.
+ */
+ DLCALL (cairo_surface_mark_dirty, surface);
+
+ if (surface != NULL && _write_lock ()) {
+ if (_mark_dirty) {
+ _emit_surface (surface);
+ _trace_printf ("%% mark-dirty\n");
+ _emit_source_image (surface);
+ } else
+ _trace_printf ("%% s%ld mark-dirty\n", _get_surface_id (surface));
+ _write_unlock ();
+ }
+ _exit_trace ();
+}
+
+void
+cairo_surface_mark_dirty_rectangle (cairo_surface_t *surface,
+ int x, int y, int width, int height)
+{
+ _enter_trace ();
+
+ /* Call cairo before emitting the trace since _emit_surface() might cause
+ * snapshots to be creates while mark_dirty assert()s that there are none.
+ */
+ DLCALL (cairo_surface_mark_dirty_rectangle, surface, x, y, width, height);
+
+ _emit_line_info ();
+ if (surface != NULL && _write_lock ()) {
+ if (_mark_dirty) {
+ _emit_surface (surface);
+ _trace_printf ("%% %d %d %d %d mark-dirty-rectangle\n",
+ x, y, width, height);
+ _emit_source_image_rectangle (surface, x,y, width, height);
+ } else
+ _trace_printf ("%% s%ld %d %d %d %d mark-dirty-rectangle\n",
+ _get_surface_id (surface), x, y, width, height);
+ _write_unlock ();
+ }
+ _exit_trace ();
+}
+
+void
+cairo_surface_set_device_offset (cairo_surface_t *surface, double x_offset, double y_offset)
+{
+ _enter_trace ();
+ _emit_line_info ();
+ _emit_surface_op (surface, "%g %g set-device-offset\n",
+ x_offset, y_offset);
+ DLCALL (cairo_surface_set_device_offset, surface, x_offset, y_offset);
+ _exit_trace ();
+}
+
+void
+cairo_surface_set_device_scale (cairo_surface_t *surface, double x_offset, double y_offset)
+{
+ _enter_trace ();
+ _emit_line_info ();
+ _emit_surface_op (surface, "%g %g set-device-scale\n",
+ x_offset, y_offset);
+ DLCALL (cairo_surface_set_device_scale, surface, x_offset, y_offset);
+ _exit_trace ();
+}
+
+
+void
+cairo_surface_set_fallback_resolution (cairo_surface_t *surface, double x_pixels_per_inch, double y_pixels_per_inch)
+{
+ _enter_trace ();
+ _emit_line_info ();
+ _emit_surface_op (surface, "%g %g set-fallback-resolution\n",
+ x_pixels_per_inch, y_pixels_per_inch);
+ DLCALL (cairo_surface_set_fallback_resolution, surface, x_pixels_per_inch, y_pixels_per_inch);
+ _exit_trace ();
+}
+
+void
+cairo_surface_copy_page (cairo_surface_t *surface)
+{
+ _enter_trace ();
+ _emit_line_info ();
+ _emit_surface_op (surface, "copy-page\n");
+ DLCALL (cairo_surface_copy_page, surface);
+ _exit_trace ();
+}
+
+void
+cairo_surface_show_page (cairo_surface_t *surface)
+{
+ _enter_trace ();
+ _emit_line_info ();
+ _emit_surface_op (surface, "show-page\n");
+ DLCALL (cairo_surface_show_page, surface);
+ _exit_trace ();
+}
+
+cairo_status_t
+cairo_surface_set_mime_data (cairo_surface_t *surface,
+ const char *mime_type,
+ const unsigned char *data,
+ unsigned long length,
+ cairo_destroy_func_t destroy,
+ void *closure)
+{
+ cairo_status_t ret;
+ _enter_trace ();
+ _emit_line_info ();
+ if (surface != NULL && _write_lock ()) {
+ _emit_surface (surface);
+ _emit_string_literal (mime_type, -1);
+ _trace_printf (" ");
+ _emit_data (data, length);
+ _trace_printf (" /deflate filter set-mime-data\n");
+
+ _write_unlock ();
+ }
+
+ ret = DLCALL (cairo_surface_set_mime_data,
+ surface,
+ mime_type,
+ data, length,
+ destroy,
+ closure);
+ _exit_trace ();
+ return ret;
+}
+
+#if CAIRO_HAS_PNG_FUNCTIONS
+cairo_status_t
+cairo_surface_write_to_png (cairo_surface_t *surface, const char *filename)
+{
+ cairo_status_t ret;
+ _enter_trace ();
+ _emit_line_info ();
+ if (surface != NULL && _write_lock ()) {
+ _trace_printf ("%% s%ld ", _get_surface_id (surface));
+ _emit_string_literal (filename, -1);
+ _trace_printf (" write-to-png pop\n");
+ _write_unlock ();
+ }
+ ret = DLCALL (cairo_surface_write_to_png, surface, filename);
+ _exit_trace ();
+ return ret;
+}
+
+cairo_status_t
+cairo_surface_write_to_png_stream (cairo_surface_t *surface,
+ cairo_write_func_t write_func,
+ void *data)
+{
+ cairo_status_t ret;
+ _enter_trace ();
+ _emit_line_info ();
+ if (surface != NULL && _write_lock ()) {
+ char symbol[1024];
+
+ _trace_printf ("%% s%ld ", _get_surface_id (surface));
+#if CAIRO_HAS_SYMBOL_LOOKUP
+ lookup_symbol (symbol, sizeof (symbol), write_func);
+#else
+ symbol[0] = '\0';
+#endif
+ _emit_string_literal (symbol, -1);
+ _trace_printf (" write-to-png-stream pop\n");
+ _write_unlock ();
+ }
+ ret = DLCALL (cairo_surface_write_to_png_stream,
+ surface, write_func, data);
+ _exit_trace ();
+ return ret;
+}
+#endif
+
+static void CAIRO_PRINTF_FORMAT(2, 3)
+_emit_pattern_op (cairo_pattern_t *pattern, const char *fmt, ...)
+{
+ va_list ap;
+
+ if (pattern == NULL || ! _write_lock ())
+ return;
+
+ _emit_pattern (pattern);
+
+ va_start (ap, fmt);
+ _trace_vprintf (fmt, ap);
+ va_end (ap);
+
+ _write_unlock ();
+}
+
+cairo_pattern_t *
+cairo_pattern_create_rgb (double red, double green, double blue)
+{
+ cairo_pattern_t *ret;
+ long pattern_id;
+
+ _enter_trace ();
+
+ ret = DLCALL (cairo_pattern_create_rgb, red, green, blue);
+ pattern_id = _create_pattern_id (ret);
+
+ _emit_line_info ();
+ if (_write_lock ()) {
+ _trace_printf ("/p%ld %g %g %g rgb def\n",
+ pattern_id, red, green, blue);
+ _get_object (PATTERN, ret)->defined = TRUE;
+ _write_unlock ();
+ }
+
+ _exit_trace ();
+ return ret;
+}
+
+cairo_pattern_t *
+cairo_pattern_create_rgba (double red, double green, double blue, double alpha)
+{
+ cairo_pattern_t *ret;
+ long pattern_id;
+
+ _enter_trace ();
+
+ ret = DLCALL (cairo_pattern_create_rgba, red, green, blue, alpha);
+ pattern_id = _create_pattern_id (ret);
+
+ _emit_line_info ();
+ if (_write_lock ()) {
+ _trace_printf ("/p%ld %g %g %g %g rgba def\n",
+ pattern_id, red, green, blue, alpha);
+ _get_object (PATTERN, ret)->defined = TRUE;
+ _write_unlock ();
+ }
+
+ _exit_trace ();
+ return ret;
+}
+
+cairo_pattern_t *
+cairo_pattern_create_for_surface (cairo_surface_t *surface)
+{
+ cairo_pattern_t *ret;
+ long pattern_id;
+ long surface_id;
+
+ _enter_trace ();
+
+ ret = DLCALL (cairo_pattern_create_for_surface, surface);
+ pattern_id = _create_pattern_id (ret);
+
+ _emit_line_info ();
+ if (surface != NULL && _write_lock ()) {
+ surface_id = _get_surface_id (surface);
+
+ if (_pop_operands_to (SURFACE, surface)) {
+ _consume_operand (false);
+ } else {
+ _trace_printf ("s%ld ", surface_id);
+ }
+
+ if (_get_object (SURFACE, surface)->foreign)
+ _emit_source_image (surface);
+
+ _trace_printf ("pattern %% p%ld\n", pattern_id);
+ _push_operand (PATTERN, ret);
+ dump_stack(__func__);
+ _write_unlock ();
+ }
+
+ _exit_trace ();
+ return ret;
+}
+
+cairo_pattern_t *
+cairo_pattern_create_linear (double x0, double y0, double x1, double y1)
+{
+ cairo_pattern_t *ret;
+ long pattern_id;
+
+ _enter_trace ();
+
+ ret = DLCALL (cairo_pattern_create_linear, x0, y0, x1, y1);
+ pattern_id = _create_pattern_id (ret);
+
+ _emit_line_info ();
+ if (_write_lock ()) {
+ _trace_printf ("%g %g %g %g linear %% p%ld\n",
+ x0, y0, x1, y1, pattern_id);
+ _push_operand (PATTERN, ret);
+ dump_stack(__func__);
+ _write_unlock ();
+ }
+
+ _exit_trace ();
+ return ret;
+}
+
+cairo_pattern_t *
+cairo_pattern_create_radial (double cx0, double cy0, double radius0, double cx1, double cy1, double radius1)
+{
+ cairo_pattern_t *ret;
+ long pattern_id;
+
+ _enter_trace ();
+
+ ret = DLCALL (cairo_pattern_create_radial,
+ cx0, cy0, radius0,
+ cx1, cy1, radius1);
+ pattern_id = _create_pattern_id (ret);
+
+ _emit_line_info ();
+ if (_write_lock ()) {
+ _trace_printf ("%g %g %g %g %g %g radial %% p%ld\n",
+ cx0, cy0, radius0, cx1, cy1, radius1,
+ pattern_id);
+ _push_operand (PATTERN, ret);
+ dump_stack(__func__);
+ _write_unlock ();
+ }
+
+ _exit_trace ();
+ return ret;
+}
+
+void
+cairo_pattern_add_color_stop_rgb (cairo_pattern_t *pattern, double offset, double red, double green, double blue)
+{
+ _enter_trace ();
+ _emit_line_info ();
+ _emit_pattern_op (pattern,
+ "%g %g %g %g 1 add-color-stop\n",
+ offset, red, green, blue);
+ DLCALL (cairo_pattern_add_color_stop_rgb, pattern, offset, red, green, blue);
+ _exit_trace ();
+}
+
+void
+cairo_pattern_add_color_stop_rgba (cairo_pattern_t *pattern, double offset, double red, double green, double blue, double alpha)
+{
+ _enter_trace ();
+ _emit_line_info ();
+ _emit_pattern_op (pattern,
+ "%g %g %g %g %g add-color-stop\n",
+ offset, red, green, blue, alpha);
+ DLCALL (cairo_pattern_add_color_stop_rgba, pattern, offset, red, green, blue, alpha);
+ _exit_trace ();
+}
+
+void
+cairo_pattern_set_matrix (cairo_pattern_t *pattern, const cairo_matrix_t *matrix)
+{
+ _enter_trace ();
+ _emit_line_info ();
+ if (_matrix_is_identity (matrix)) {
+ _emit_pattern_op (pattern, "identity set-matrix\n");
+ } else {
+ _emit_pattern_op (pattern,
+ "%g %g %g %g %g %g matrix set-matrix\n",
+ matrix->xx, matrix->yx,
+ matrix->xy, matrix->yy,
+ matrix->x0, matrix->y0);
+ }
+ DLCALL (cairo_pattern_set_matrix, pattern, matrix);
+ _exit_trace ();
+}
+
+static const char *
+_filter_to_string (cairo_filter_t filter)
+{
+#define f(name) case CAIRO_FILTER_ ## name: return "FILTER_" #name
+ switch (filter) {
+ f(FAST);
+ f(GOOD);
+ f(BEST);
+ f(NEAREST);
+ f(BILINEAR);
+ f(GAUSSIAN);
+ };
+#undef f
+ return "UNKNOWN_FILTER";
+}
+
+void
+cairo_pattern_set_filter (cairo_pattern_t *pattern, cairo_filter_t filter)
+{
+ _enter_trace ();
+ _emit_line_info ();
+ _emit_pattern_op (pattern, "//%s set-filter\n", _filter_to_string (filter));
+ DLCALL (cairo_pattern_set_filter, pattern, filter);
+ _exit_trace ();
+}
+
+static const char *
+_extend_to_string (cairo_extend_t extend)
+{
+#define f(name) case CAIRO_EXTEND_ ## name: return "EXTEND_" #name
+ switch (extend) {
+ f(NONE);
+ f(REPEAT);
+ f(REFLECT);
+ f(PAD);
+ };
+#undef f
+ return "UNKNOWN_EXTEND";
+}
+
+void
+cairo_pattern_set_extend (cairo_pattern_t *pattern, cairo_extend_t extend)
+{
+ _enter_trace ();
+ _emit_line_info ();
+ _emit_pattern_op (pattern, "//%s set-extend\n", _extend_to_string (extend));
+ DLCALL (cairo_pattern_set_extend, pattern, extend);
+ _exit_trace ();
+}
+
+#if CAIRO_HAS_FT_FONT
+#if CAIRO_HAS_FC_FONT
+cairo_font_face_t *
+cairo_ft_font_face_create_for_pattern (FcPattern *pattern)
+{
+ cairo_font_face_t *ret;
+ long font_face_id;
+
+ _enter_trace ();
+
+ ret = DLCALL (cairo_ft_font_face_create_for_pattern, pattern);
+ font_face_id = _create_font_face_id (ret);
+
+ _emit_line_info ();
+ if (pattern != NULL && _write_lock ()) {
+ Object *obj;
+
+ obj = _get_object (FONT_FACE, ret);
+ if (obj->unknown) {
+ FcPattern *copy;
+ FcChar8 *unparsed;
+
+ copy = DLCALL (FcPatternDuplicate, pattern);
+ if (copy)
+ {
+ DLCALL (FcPatternDel, copy, FC_LANG);
+ DLCALL (FcPatternDel, copy, FC_CHARSET);
+ DLCALL (FcPatternDel, copy, FC_CAPABILITY);
+ }
+ else
+ copy = pattern;
+
+ unparsed = DLCALL (FcNameUnparse, copy);
+ _trace_printf ("dict\n"
+ " /type 42 set\n"
+ " /pattern ");
+ _emit_string_literal ((char *) unparsed, -1);
+ _trace_printf (" set\n"
+ " font %% f%ld\n",
+ font_face_id);
+ obj->unknown = FALSE;
+ _push_operand (FONT_FACE, ret);
+ dump_stack(__func__);
+
+ if (copy != pattern)
+ DLCALL (FcPatternDestroy, copy);
+ free (unparsed);
+ }
+ _write_unlock ();
+ }
+
+ _exit_trace ();
+ return ret;
+}
+#endif /* CAIRO_HAS_FC_FONT*/
+
+typedef struct _ft_face_data {
+ unsigned long index;
+ unsigned long size;
+ void *data;
+} FtFaceData;
+
+static void
+_ft_face_data_destroy (void *arg)
+{
+ FtFaceData *data = arg;
+ free (data->data);
+ free (data);
+}
+
+cairo_font_face_t *
+cairo_ft_font_face_create_for_ft_face (FT_Face face, int load_flags)
+{
+ cairo_font_face_t *ret;
+ Object *obj;
+ FtFaceData *data;
+ long font_face_id;
+
+ _enter_trace ();
+
+ ret = DLCALL (cairo_ft_font_face_create_for_ft_face, face, load_flags);
+ font_face_id = _create_font_face_id (ret);
+
+ if (face == NULL) {
+ _exit_trace ();
+ return ret;
+ }
+
+ obj = _get_object (NONE, face);
+ data = obj->data;
+ if (data == NULL) {
+ _exit_trace ();
+ return ret;
+ }
+
+ _emit_line_info ();
+ if (_write_lock ()) {
+ obj = _get_object (FONT_FACE, ret);
+ if (obj->operand != -1)
+ _object_remove (obj);
+
+ _trace_printf ("<< /type 42 /source ");
+ _emit_data (data->data, data->size);
+ _trace_printf (" /index %lu /flags %d >> font %% f%ld\n",
+ data->index, load_flags, font_face_id);
+ _push_operand (FONT_FACE, ret);
+ dump_stack(__func__);
+ _write_unlock ();
+ }
+
+ _exit_trace ();
+ return ret;
+}
+
+static cairo_bool_t
+_ft_read_file (FtFaceData *data, const char *path)
+{
+ char buf[8192];
+ FILE *file;
+
+ file = fopen (path, "rb");
+ if (file != NULL) {
+ size_t ret;
+ unsigned long int allocated = sizeof (buf);
+ data->data = malloc (allocated);
+ do {
+ ret = fread (buf, 1, sizeof (buf), file);
+ if (ret == 0)
+ break;
+ memcpy ((char *) data->data + data->size, buf, ret);
+ data->size += ret;
+ if (ret != sizeof (buf))
+ break;
+
+ if (data->size == allocated) {
+ allocated *= 2;
+ data->data = realloc (data->data, allocated);
+ }
+ } while (TRUE);
+ fclose (file);
+ }
+
+ return file != NULL;
+}
+
+FT_Error
+FT_New_Face (FT_Library library, const char *pathname, FT_Long index, FT_Face *face)
+{
+ FT_Error ret;
+
+ _enter_trace ();
+
+ ret = DLCALL (FT_New_Face, library, pathname, index, face);
+ if (ret == 0) {
+ Object *obj = _type_object_create (NONE, *face);
+ FtFaceData *data = malloc (sizeof (FtFaceData));
+ data->index = index;
+ data->size = 0;
+ data->data = NULL;
+ _ft_read_file (data, pathname);
+ obj->data = data;
+ obj->destroy = _ft_face_data_destroy;
+ }
+
+ _exit_trace ();
+ return ret;
+}
+
+FT_Error
+FT_New_Memory_Face (FT_Library library, const FT_Byte *mem, FT_Long size, FT_Long index, FT_Face *face)
+{
+ FT_Error ret;
+
+ _enter_trace ();
+
+ ret = DLCALL (FT_New_Memory_Face, library, mem, size, index, face);
+ if (ret == 0) {
+ Object *obj = _type_object_create (NONE, *face);
+ FtFaceData *data = malloc (sizeof (FtFaceData));
+ data->index = index;
+ data->size = size;
+ data->data = malloc (size);
+ memcpy (data->data, mem, size);
+ obj->data = data;
+ obj->destroy = _ft_face_data_destroy;
+ }
+
+ _exit_trace ();
+ return ret;
+}
+
+/* XXX
+ * FT_New_Memory_Face() and FT_New_Face() appear to wrap FT_Open_Face() so we
+ * get a redundant call to FT_Open_Face() from those paths (no PLT hiding
+ * within FT, naughty library!) but we do not intercept a direct call to
+ * FT_Open_Face(). So far this has not caused any issues, but it will one
+ * day...
+ */
+FT_Error
+FT_Open_Face (FT_Library library, const FT_Open_Args *args, FT_Long index, FT_Face *face)
+{
+ FT_Error ret;
+
+ _enter_trace ();
+
+ ret = DLCALL (FT_Open_Face, library, args, index, face);
+ if (ret == 0) {
+ Object *obj = _get_object (NONE, *face);
+ if (obj == NULL) {
+ FtFaceData *data;
+
+ data = malloc (sizeof (FtFaceData));
+ data->index = index;
+ if (args->flags & FT_OPEN_MEMORY) {
+ data->size = args->memory_size;
+ data->data = malloc (args->memory_size);
+ memcpy (data->data, args->memory_base, args->memory_size);
+ } else if (args->flags & FT_OPEN_STREAM) {
+ fprintf (stderr, "FT_Open_Face (stream, %ld) = %p\n",
+ index, *face);
+ abort ();
+ } else if (args->flags & FT_OPEN_PATHNAME) {
+ data->size = 0;
+ data->data = NULL;
+ _ft_read_file (data, args->pathname);
+ }
+
+ obj = _type_object_create (NONE, *face);
+ obj->data = data;
+ obj->destroy = _ft_face_data_destroy;
+ }
+ }
+
+ _exit_trace ();
+ return ret;
+}
+
+FT_Error
+FT_Done_Face (FT_Face face)
+{
+ FT_Error ret;
+ _enter_trace ();
+
+ _object_destroy (_get_object (NONE, face));
+
+ ret = DLCALL (FT_Done_Face, face);
+ _exit_trace ();
+ return ret;
+}
+#endif
+
+static void
+_surface_object_set_size (cairo_surface_t *surface, int width, int height)
+{
+ Object *obj;
+
+ obj = _get_object (SURFACE, surface);
+ obj->width = width;
+ obj->height = height;
+}
+
+static void
+_surface_object_set_size_from_surface (cairo_surface_t *surface)
+{
+ _surface_object_set_size (surface,
+ DLCALL (cairo_image_surface_get_width, surface),
+ DLCALL (cairo_image_surface_get_height, surface));
+}
+
+#if CAIRO_HAS_PS_SURFACE
+#include<cairo-ps.h>
+
+cairo_surface_t *
+cairo_ps_surface_create (const char *filename, double width_in_points, double height_in_points)
+{
+ cairo_surface_t *ret;
+
+ _enter_trace ();
+
+ ret = DLCALL (cairo_ps_surface_create, filename, width_in_points, height_in_points);
+
+ _emit_line_info ();
+ if (_write_lock ()) {
+ Object *obj = _create_surface (ret);
+
+ _trace_printf ("dict\n"
+ " /type /PS set\n"
+ " /filename ");
+ _emit_string_literal (filename, -1);
+ _trace_printf (" set\n"
+ " /width %g set\n"
+ " /height %g set\n"
+ " surface %% s%ld\n",
+ width_in_points,
+ height_in_points,
+ obj->token);
+ obj->width = width_in_points;
+ obj->height = height_in_points;
+ _push_object (obj);
+ dump_stack(__func__);
+ _write_unlock ();
+ }
+
+ _exit_trace ();
+ return ret;
+}
+
+cairo_surface_t *
+cairo_ps_surface_create_for_stream (cairo_write_func_t write_func, void *closure, double width_in_points, double height_in_points)
+{
+ cairo_surface_t *ret;
+
+ _enter_trace ();
+
+ ret = DLCALL (cairo_ps_surface_create_for_stream, write_func, closure, width_in_points, height_in_points);
+
+ _emit_line_info ();
+ if (_write_lock ()) {
+ Object *obj = _create_surface (ret);
+
+ _trace_printf ("dict\n"
+ " /type /PS set\n"
+ " /width %g set\n"
+ " /height %g set\n"
+ " surface %% s%ld\n",
+ width_in_points,
+ height_in_points,
+ obj->token);
+ obj->width = width_in_points;
+ obj->height = height_in_points;
+ _push_object (obj);
+ dump_stack(__func__);
+ _write_unlock ();
+ }
+
+ _exit_trace ();
+ return ret;
+}
+
+void
+cairo_ps_surface_set_size (cairo_surface_t *surface, double width_in_points, double height_in_points)
+{
+ _enter_trace ();
+ _emit_line_info ();
+ DLCALL (cairo_ps_surface_set_size, surface, width_in_points, height_in_points);
+ _exit_trace ();
+}
+
+#endif
+
+#if CAIRO_HAS_PDF_SURFACE
+#include <cairo-pdf.h>
+
+cairo_surface_t *
+cairo_pdf_surface_create (const char *filename, double width_in_points, double height_in_points)
+{
+ cairo_surface_t *ret;
+
+ _enter_trace ();
+
+ ret = DLCALL (cairo_pdf_surface_create, filename, width_in_points, height_in_points);
+
+ _emit_line_info ();
+ if (_write_lock ()) {
+ Object *obj = _create_surface (ret);
+
+ _trace_printf ("dict\n"
+ " /type /PDF set\n"
+ " /filename ");
+ _emit_string_literal (filename, -1);
+ _trace_printf (" set\n"
+ " /width %g set\n"
+ " /height %g set\n"
+ " surface %% s%ld\n",
+ width_in_points,
+ height_in_points,
+ obj->token);
+ obj->width = width_in_points;
+ obj->height = height_in_points;
+ _push_object (obj);
+ dump_stack(__func__);
+ _write_unlock ();
+ }
+
+ _exit_trace ();
+ return ret;
+}
+
+cairo_surface_t *
+cairo_pdf_surface_create_for_stream (cairo_write_func_t write_func, void *closure, double width_in_points, double height_in_points)
+{
+ cairo_surface_t *ret;
+
+ _enter_trace ();
+
+ ret = DLCALL (cairo_pdf_surface_create_for_stream, write_func, closure, width_in_points, height_in_points);
+
+ _emit_line_info ();
+ if (_write_lock ()) {
+ Object *obj = _create_surface (ret);
+
+ _trace_printf ("dict\n"
+ " /type /PDF set\n"
+ " /width %g set\n"
+ " /height %g set\n"
+ " surface %% s%ld\n",
+ width_in_points,
+ height_in_points,
+ obj->token);
+ obj->width = width_in_points;
+ obj->height = height_in_points;
+ _push_object (obj);
+ dump_stack(__func__);
+ _write_unlock ();
+ }
+ _exit_trace ();
+ return ret;
+}
+
+void
+cairo_pdf_surface_set_size (cairo_surface_t *surface, double width_in_points, double height_in_points)
+{
+ _enter_trace ();
+ _emit_line_info ();
+ DLCALL (cairo_pdf_surface_set_size, surface, width_in_points, height_in_points);
+ _exit_trace ();
+}
+#endif
+
+#if CAIRO_HAS_SVG_SURFACE
+#include <cairo-svg.h>
+
+cairo_surface_t *
+cairo_svg_surface_create (const char *filename, double width, double height)
+{
+ cairo_surface_t *ret;
+
+ _enter_trace ();
+
+ ret = DLCALL (cairo_svg_surface_create, filename, width, height);
+
+ _emit_line_info ();
+ if (_write_lock ()) {
+ Object *obj = _create_surface (ret);
+
+ _trace_printf ("dict\n"
+ " /type /SVG set\n"
+ " /filename ");
+ _emit_string_literal (filename, -1);
+ _trace_printf (" set\n"
+ " /width %g set\n"
+ " /height %g set\n"
+ " surface %% s%ld\n",
+ width,
+ height,
+ obj->token);
+ obj->width = width;
+ obj->height = height;
+ _push_object (obj);
+ dump_stack(__func__);
+ _write_unlock ();
+ }
+
+ _exit_trace ();
+ return ret;
+}
+
+cairo_surface_t *
+cairo_svg_surface_create_for_stream (cairo_write_func_t write_func, void *closure, double width, double height)
+{
+ cairo_surface_t *ret;
+
+ _enter_trace ();
+
+ ret = DLCALL (cairo_svg_surface_create_for_stream, write_func, closure, width, height);
+
+ _emit_line_info ();
+ if (_write_lock ()) {
+ Object *obj = _create_surface (ret);
+
+ _trace_printf ("dict\n"
+ " /type /SVG set\n"
+ " /width %g set\n"
+ " /height %g set\n"
+ " surface %% s%ld\n",
+ width,
+ height,
+ obj->token);
+ obj->width = width;
+ obj->height = height;
+ _push_object (obj);
+ dump_stack(__func__);
+ _write_unlock ();
+ }
+
+ _exit_trace ();
+ return ret;
+}
+
+#endif
+
+#if CAIRO_HAS_PNG_FUNCTIONS
+cairo_surface_t *
+cairo_image_surface_create_from_png (const char *filename)
+{
+ cairo_surface_t *ret;
+
+ _enter_trace ();
+
+ ret = DLCALL (cairo_image_surface_create_from_png, filename);
+
+ _emit_line_info ();
+ if (_write_lock ()) {
+ Object *obj = _create_surface (ret);
+ char filename_string[4096];
+
+ _encode_string_literal (filename_string, sizeof (filename_string),
+ filename, -1);
+ _emit_image (ret, " /filename %s set\n", filename_string);
+ _trace_printf (" dup /s%ld exch def\n", obj->token);
+ _surface_object_set_size_from_surface (ret);
+ obj->defined = TRUE;
+ _push_object (obj);
+ dump_stack(__func__);
+ _write_unlock ();
+ }
+
+ _exit_trace ();
+ return ret;
+}
+
+cairo_surface_t *
+cairo_image_surface_create_from_png_stream (cairo_read_func_t read_func, void *closure)
+{
+ cairo_surface_t *ret;
+
+ _enter_trace ();
+
+ ret = DLCALL (cairo_image_surface_create_from_png_stream, read_func, closure);
+
+ _emit_line_info ();
+ if (_write_lock ()) {
+ Object *obj = _create_surface (ret);
+
+ _emit_image (ret, NULL);
+ _trace_printf (" dup /s%ld exch def\n",
+ obj->token);
+
+ _surface_object_set_size_from_surface (ret);
+ obj->defined = TRUE;
+ _push_object (obj);
+ dump_stack(__func__);
+ _write_unlock ();
+ }
+
+ _exit_trace ();
+ return ret;
+}
+#endif
+
+static const char *
+_content_from_surface (cairo_surface_t *surface)
+{
+ return _content_to_string (DLCALL (cairo_surface_get_content, surface));
+}
+
+#if CAIRO_HAS_TEE_SURFACE
+#include <cairo-tee.h>
+
+cairo_surface_t *
+cairo_tee_surface_create (cairo_surface_t *master)
+{
+ cairo_surface_t *ret;
+
+ _enter_trace ();
+
+ ret = DLCALL (cairo_tee_surface_create, master);
+
+ _emit_line_info ();
+ if (_write_lock ()) {
+ Object *obj = _create_surface (ret);
+
+ _trace_printf ("dict\n"
+ " /type /tee set\n"
+ " /master s%ld set\n"
+ " surface dup /s%ld exch def\n",
+ _get_object (SURFACE, master)->token,
+ obj->token);
+ obj->defined = TRUE;
+ _push_object (obj);
+ dump_stack(__func__);
+ _write_unlock ();
+ }
+
+ _exit_trace ();
+ return ret;
+}
+
+#endif
+
+#if CAIRO_HAS_XLIB_SURFACE
+#include <cairo-xlib.h>
+
+cairo_surface_t *
+cairo_xlib_surface_create (Display *dpy,
+ Drawable drawable,
+ Visual *visual,
+ int width, int height)
+{
+ cairo_surface_t *ret;
+
+ _enter_trace ();
+
+ ret = DLCALL (cairo_xlib_surface_create,
+ dpy, drawable, visual, width, height);
+
+ _emit_line_info ();
+ if (_write_lock ()) {
+ Object *obj = _create_surface (ret);
+
+ _trace_printf ("dict\n"
+ " /type /xlib set\n"
+ " /drawable 16!%lx set\n"
+ " /content //%s set\n"
+ " /width %d set\n"
+ " /height %d set\n"
+ " surface dup /s%ld exch def\n",
+ drawable,
+ _content_from_surface (ret),
+ width, height,
+ obj->token);
+ obj->defined = TRUE;
+ obj->width = width;
+ obj->height = height;
+ obj->foreign = TRUE;
+ _push_object (obj);
+ dump_stack(__func__);
+ _write_unlock ();
+ }
+
+ _exit_trace ();
+ return ret;
+}
+
+cairo_surface_t *
+cairo_xlib_surface_create_for_bitmap (Display *dpy,
+ Pixmap bitmap,
+ Screen *screen,
+ int width, int height)
+{
+ cairo_surface_t *ret;
+
+ _enter_trace ();
+
+ ret = DLCALL (cairo_xlib_surface_create_for_bitmap,
+ dpy, bitmap, screen, width, height);
+
+ _emit_line_info ();
+ if (_write_lock ()) {
+ Object *obj = _create_surface (ret);
+
+ _trace_printf ("dict\n"
+ " /type /xlib set\n"
+ " /drawable 16!%lx set\n"
+ " /content //%s set\n"
+ " /width %d set\n"
+ " /height %d set\n"
+ " /depth 1 set\n"
+ " surface dup /s%ld exch def\n",
+ bitmap,
+ _content_from_surface (ret),
+ width, height,
+ obj->token);
+ obj->defined = TRUE;
+ obj->width = width;
+ obj->height = height;
+ obj->foreign = TRUE;
+ _push_object (obj);
+ dump_stack(__func__);
+ _write_unlock ();
+ }
+
+ _exit_trace ();
+ return ret;
+}
+
+#if CAIRO_HAS_XLIB_XRENDER_SURFACE
+#include <cairo-xlib-xrender.h>
+cairo_surface_t *
+cairo_xlib_surface_create_with_xrender_format (Display *dpy,
+ Drawable drawable,
+ Screen *screen,
+ XRenderPictFormat *format,
+ int width, int height)
+{
+ cairo_surface_t *ret;
+
+ _enter_trace ();
+
+ ret = DLCALL (cairo_xlib_surface_create_with_xrender_format,
+ dpy, drawable, screen, format, width, height);
+
+ _emit_line_info ();
+ if (_write_lock ()) {
+ Object *obj = _create_surface (ret);
+
+ _trace_printf ("dict\n"
+ " /type /xrender set\n"
+ " /drawable 16!%lx set\n"
+ " /content //%s set\n"
+ " /width %d set\n"
+ " /height %d set\n"
+ " /depth %d set\n"
+ " surface dup /s%ld exch def\n",
+ drawable,
+ _content_from_surface (ret),
+ width, height,
+ format->depth,
+ obj->token);
+ obj->defined = TRUE;
+ obj->width = width;
+ obj->height = height;
+ obj->foreign = TRUE;
+ _push_object (obj);
+ dump_stack(__func__);
+ _write_unlock ();
+ }
+
+ _exit_trace ();
+ return ret;
+}
+#endif
+#endif
+
+#if CAIRO_HAS_SCRIPT_SURFACE
+#include <cairo-script.h>
+cairo_surface_t *
+cairo_script_surface_create (cairo_device_t *device,
+ cairo_content_t content,
+ double width,
+ double height)
+{
+ cairo_surface_t *ret;
+
+ _enter_trace ();
+
+ ret = DLCALL (cairo_script_surface_create, device, content, width, height);
+
+ _emit_line_info ();
+ if (_write_lock ()) {
+ Object *obj = _create_surface (ret);
+
+ _trace_printf ("dict\n"
+ " /type /script set\n"
+ " /content %s set\n"
+ " /width %g set\n"
+ " /height %g set\n"
+ " surface dup /s%ld exch def\n",
+ _content_to_string (content),
+ width, height,
+ obj->token);
+ obj->width = width;
+ obj->height = height;
+ obj->defined = TRUE;
+ _push_object (obj);
+ dump_stack(__func__);
+ _write_unlock ();
+ }
+
+ _exit_trace ();
+ return ret;
+}
+
+cairo_surface_t *
+cairo_script_surface_create_for_target (cairo_device_t *device,
+ cairo_surface_t *target)
+{
+ cairo_surface_t *ret;
+
+ _enter_trace ();
+
+ ret = DLCALL (cairo_script_surface_create_for_target, device, target);
+
+ _emit_line_info ();
+ if (_write_lock ()) {
+ Object *obj = _create_surface (ret);
+
+ _trace_printf ("dict\n"
+ " /type /script set\n"
+ " surface dup /s%ld exch def\n",
+ obj->token);
+ obj->defined = TRUE;
+ _push_object (obj);
+ dump_stack(__func__);
+ _write_unlock ();
+ }
+
+ _exit_trace ();
+ return ret;
+}
+#endif
+
+#if CAIRO_HAS_TEST_SURFACES
+#include <test-paginated-surface.h>
+cairo_surface_t *
+_cairo_test_paginated_surface_create (cairo_surface_t *surface)
+{
+ cairo_surface_t *ret;
+
+ _enter_trace ();
+
+ ret = DLCALL (_cairo_test_paginated_surface_create, surface);
+
+ _emit_line_info ();
+ if (_write_lock ()) {
+ Object *obj = _create_surface (ret);
+
+ /* XXX store initial data? */
+ _trace_printf ("dict\n"
+ " /type /test-paginated set\n"
+ " /target s%ld set\n"
+ " surface dup /s%ld exch def\n",
+ _get_surface_id (surface),
+ obj->token);
+ _push_object (obj);
+ dump_stack(__func__);
+ _write_unlock ();
+ }
+
+ _exit_trace ();
+ return ret;
+}
+
+#include <test-compositor-surface.h>
+
+cairo_surface_t *
+_cairo_test_fallback_compositor_surface_create (cairo_content_t content, int width, int height)
+{
+ cairo_surface_t *ret;
+
+ _enter_trace ();
+
+ ret = DLCALL (_cairo_test_fallback_compositor_surface_create, content, width, height);
+
+ _emit_line_info ();
+ if (_write_lock ()) {
+ Object *obj = _create_surface (ret);
+
+ _trace_printf ("dict\n"
+ " /type /test-fallback-compositor set\n"
+ " /content //%s set\n"
+ " /width %d set\n"
+ " /height %d set\n"
+ " surface dup /s%ld exch def\n",
+ _content_to_string (content),
+ width, height,
+ obj->token);
+ obj->defined = TRUE;
+ _push_object (obj);
+ dump_stack(__func__);
+ _write_unlock ();
+ }
+
+ _exit_trace ();
+ return ret;
+}
+
+cairo_surface_t *
+_cairo_test_mask_compositor_surface_create (cairo_content_t content, int width, int height)
+{
+ cairo_surface_t *ret;
+
+ _enter_trace ();
+
+ ret = DLCALL (_cairo_test_mask_compositor_surface_create, content, width, height);
+
+ _emit_line_info ();
+ if (_write_lock ()) {
+ Object *obj = _create_surface (ret);
+
+ _trace_printf ("dict\n"
+ " /type /test-mask-compositor set\n"
+ " /content //%s set\n"
+ " /width %d set\n"
+ " /height %d set\n"
+ " surface dup /s%ld exch def\n",
+ _content_to_string (content),
+ width, height,
+ obj->token);
+ obj->defined = TRUE;
+ _push_object (obj);
+ dump_stack(__func__);
+ _write_unlock ();
+ }
+
+ _exit_trace ();
+ return ret;
+}
+
+cairo_surface_t *
+_cairo_test_spans_compositor_surface_create (cairo_content_t content, int width, int height)
+{
+ cairo_surface_t *ret;
+
+ _enter_trace ();
+
+ ret = DLCALL (_cairo_test_spans_compositor_surface_create, content, width, height);
+
+ _emit_line_info ();
+ if (_write_lock ()) {
+ Object *obj = _create_surface (ret);
+
+ _trace_printf ("dict\n"
+ " /type /test-spans-compositor set\n"
+ " /content //%s set\n"
+ " /width %d set\n"
+ " /height %d set\n"
+ " surface dup /s%ld exch def\n",
+ _content_to_string (content),
+ width, height,
+ obj->token);
+ obj->defined = TRUE;
+ _push_object (obj);
+ dump_stack(__func__);
+ _write_unlock ();
+ }
+
+ _exit_trace ();
+ return ret;
+}
+
+cairo_surface_t *
+_cairo_test_traps_compositor_surface_create (cairo_content_t content, int width, int height)
+{
+ cairo_surface_t *ret;
+
+ _enter_trace ();
+
+ ret = DLCALL (_cairo_test_traps_compositor_surface_create, content, width, height);
+
+ _emit_line_info ();
+ if (_write_lock ()) {
+ Object *obj = _create_surface (ret);
+
+ _trace_printf ("dict\n"
+ " /type /test-traps-compositor set\n"
+ " /content //%s set\n"
+ " /width %d set\n"
+ " /height %d set\n"
+ " surface dup /s%ld exch def\n",
+ _content_to_string (content),
+ width, height,
+ obj->token);
+ obj->defined = TRUE;
+ _push_object (obj);
+ dump_stack(__func__);
+ _write_unlock ();
+ }
+
+ _exit_trace ();
+ return ret;
+}
+
+#endif
+
+cairo_surface_t *
+cairo_recording_surface_create (cairo_content_t content,
+ const cairo_rectangle_t *extents)
+{
+ cairo_surface_t *ret;
+
+ _enter_trace ();
+
+ ret = DLCALL (cairo_recording_surface_create, content, extents);
+
+ _emit_line_info ();
+ if (_write_lock ()) {
+ Object *obj = _create_surface (ret);
+
+ if (extents) {
+ _trace_printf ("//%s [ %f %f %f %f ] record dup /s%ld exch def\n",
+ _content_to_string (content),
+ extents->x, extents->y,
+ extents->width, extents->height,
+ obj->token);
+ obj->width = extents->width;
+ obj->height = extents->height;
+ } else {
+ _trace_printf ("//%s [ ] record dup /s%ld exch def\n",
+ _content_to_string (content),
+ obj->token);
+ }
+ obj->defined = TRUE;
+ _push_object (obj);
+ dump_stack(__func__);
+ _write_unlock ();
+ }
+
+ _exit_trace ();
+ return ret;
+}
+
+#if CAIRO_HAS_VG_SURFACE
+#include <cairo-vg.h>
+cairo_surface_t *
+cairo_vg_surface_create (cairo_vg_context_t *context,
+ cairo_content_t content,
+ int width, int height)
+{
+ cairo_surface_t *ret;
+
+ _enter_trace ();
+
+ ret = DLCALL (cairo_vg_surface_create, context, content, width, height);
+
+ _emit_line_info ();
+ if (_write_lock ()) {
+ Object *obj = _create_surface (ret);
+
+ _trace_printf ("dict\n"
+ " /type /vg set\n"
+ " /content //%s set\n"
+ " /width %d set\n"
+ " /height %d set\n"
+ " surface dup /s%ld exch def\n",
+ _content_to_string (content),
+ width, height,
+ obj->token);
+ obj->width = width;
+ obj->height = height;
+ obj->defined = TRUE;
+ _push_object (obj);
+ dump_stack(__func__);
+ _write_unlock ();
+ }
+
+ _exit_trace ();
+ return ret;
+}
+
+cairo_surface_t *
+cairo_vg_surface_create_for_image (cairo_vg_context_t *context,
+ VGImage image,
+ VGImageFormat format,
+ int width, int height)
+{
+ cairo_surface_t *ret;
+
+ _enter_trace ();
+
+ ret = DLCALL (cairo_vg_surface_create_for_image,
+ context, image, format, width, height);
+
+ _emit_line_info ();
+ if (_write_lock ()) {
+ Object *obj = _create_surface (ret);
+ cairo_content_t content;
+
+ content = DLCALL (cairo_surface_get_content, ret);
+ _trace_printf ("dict\n"
+ " /type /vg set\n"
+ " /content //%s set\n"
+ " /width %d set\n"
+ " /height %d set\n"
+ " surface dup /s%ld exch def\n",
+ _content_to_string (content),
+ width, height,
+ obj->token);
+ obj->width = width;
+ obj->height = height;
+ obj->defined = TRUE;
+ _push_object (obj);
+ dump_stack(__func__);
+ _write_unlock ();
+ }
+
+ _exit_trace ();
+ return ret;
+}
+#endif
+
+#if CAIRO_HAS_GL_SURFACE || CAIRO_HAS_GLESV2_SURFACE
+#include <cairo-gl.h>
+cairo_surface_t *
+cairo_gl_surface_create (cairo_device_t *abstract_device,
+ cairo_content_t content,
+ int width,
+ int height)
+{
+ cairo_surface_t *ret;
+
+ _enter_trace ();
+
+ ret = DLCALL (cairo_gl_surface_create, abstract_device, content, width, height);
+
+ _emit_line_info ();
+ if (_write_lock ()) {
+ Object *obj = _create_surface (ret);
+
+ _trace_printf ("dict\n"
+ " /type /gl set\n"
+ " /content //%s set\n"
+ " /width %d set\n"
+ " /height %d set\n"
+ " surface dup /s%ld exch def\n",
+ _content_to_string (content),
+ width, height,
+ obj->token);
+ obj->width = width;
+ obj->height = height;
+ obj->defined = TRUE;
+ _push_object (obj);
+ dump_stack(__func__);
+ _write_unlock ();
+ }
+
+ _exit_trace ();
+ return ret;
+}
+
+cairo_surface_t *
+cairo_gl_surface_create_for_texture (cairo_device_t *abstract_device,
+ cairo_content_t content,
+ unsigned int tex,
+ int width,
+ int height)
+{
+ cairo_surface_t *ret;
+
+ _enter_trace ();
+
+ ret = DLCALL (cairo_gl_surface_create_for_texture, abstract_device, content, tex, width, height);
+
+ _emit_line_info ();
+ if (_write_lock ()) {
+ Object *obj = _create_surface (ret);
+
+ _trace_printf ("dict\n"
+ " /type /gl set\n"
+ " /content //%s set\n"
+ " /width %d set\n"
+ " /height %d set\n"
+ " surface dup /s%ld exch def\n",
+ _content_to_string (content),
+ width, height,
+ obj->token);
+ obj->width = width;
+ obj->height = height;
+ obj->defined = TRUE;
+ _push_object (obj);
+ dump_stack(__func__);
+ _write_unlock ();
+ }
+
+ _exit_trace ();
+ return ret;
+}
+
+#if CAIRO_HAS_GLX_FUNCTIONS
+cairo_surface_t *
+cairo_gl_surface_create_for_window (cairo_device_t *device,
+ Window win,
+ int width, int height)
+{
+ cairo_surface_t *ret;
+
+ _enter_trace ();
+
+ ret = DLCALL (cairo_gl_surface_create_for_window, device, win, width, height);
+
+ _emit_line_info ();
+ if (_write_lock ()) {
+ Object *obj = _create_surface (ret);
+
+ _trace_printf ("dict\n"
+ " /type /gl set\n"
+ " /width %d set\n"
+ " /height %d set\n"
+ " surface dup /s%ld exch def\n",
+ width, height,
+ obj->token);
+ obj->width = width;
+ obj->height = height;
+ obj->defined = TRUE;
+ _push_object (obj);
+ dump_stack(__func__);
+ _write_unlock ();
+ }
+
+ _exit_trace ();
+ return ret;
+}
+#endif
+
+#if CAIRO_HAS_WGL_FUNCTIONS
+cairo_surface_t *
+cairo_gl_surface_create_for_dc (cairo_device_t *device,
+ HDC dc,
+ int width,
+ int height)
+{
+ cairo_surface_t *ret;
+
+ _enter_trace ();
+
+ ret = DLCALL (cairo_gl_surface_create_for_dc, device, dc, width, height);
+
+ _emit_line_info ();
+ if (_write_lock ()) {
+ Object *obj = _create_surface (ret);
+
+ _trace_printf ("dict\n"
+ " /type /gl set\n"
+ " /width %d set\n"
+ " /height %d set\n"
+ " surface dup /s%ld exch def\n",
+ width, height,
+ obj->token);
+ obj->width = width;
+ obj->height = height;
+ obj->defined = TRUE;
+ _push_object (obj);
+ dump_stack(__func__);
+ _write_unlock ();
+ }
+
+ _exit_trace ();
+ return ret;
+}
+#endif
+
+#if CAIRO_HAS_EGL_FUNCTIONS
+cairo_surface_t *
+cairo_gl_surface_create_for_egl (cairo_device_t *device,
+ EGLSurface egl,
+ int width,
+ int height)
+{
+ cairo_surface_t *ret;
+
+ _enter_trace ();
+
+ ret = DLCALL (cairo_gl_surface_create_for_egl, device, egl, width, height);
+
+ _emit_line_info ();
+ if (_write_lock ()) {
+ Object *obj = _create_surface (ret);
+
+ _trace_printf ("dict\n"
+ " /type /gl set\n"
+ " /width %d set\n"
+ " /height %d set\n"
+ " surface dup /s%ld exch def\n",
+ width, height,
+ obj->token);
+ obj->width = width;
+ obj->height = height;
+ obj->defined = TRUE;
+ _push_object (obj);
+ dump_stack(__func__);
+ _write_unlock ();
+ }
+
+ _exit_trace ();
+ return ret;
+}
+#endif
+#endif
diff --git a/util/cairo.modules b/util/cairo.modules
index 71a3922fd..71a3922fd 100755..100644
--- a/util/cairo.modules
+++ b/util/cairo.modules
diff --git a/util/font-view.c b/util/font-view.c
index 07d9e2e9d..07d9e2e9d 100755..100644
--- a/util/font-view.c
+++ b/util/font-view.c
diff --git a/util/malloc-stats.c b/util/malloc-stats.c
index da91656dd..55ed51cad 100755..100644
--- a/util/malloc-stats.c
+++ b/util/malloc-stats.c
@@ -60,8 +60,9 @@ static struct alloc_stats_t total_allocations;
static struct func_stat_t *func_stats[31627];
static int func_stats_num;
-#define ARRAY_SIZE(A) (sizeof (A)/sizeof (A[0]))
-
+#ifndef ARRAY_LENGTH
+#define ARRAY_LENGTH(__array) ((int) (sizeof (__array) / sizeof (__array[0])))
+#endif
static void
alloc_stats_add (struct alloc_stats_t *stats, int is_realloc, size_t size)
{
@@ -147,7 +148,7 @@ func_stats_add (const void *caller, int is_realloc, size_t size)
alloc_stats_add (&total_allocations, is_realloc, size);
- i = ((uintptr_t) caller ^ 1215497) % ARRAY_SIZE (func_stats);
+ i = ((uintptr_t) caller ^ 1215497) % ARRAY_LENGTH (func_stats);
for (elt = func_stats[i]; elt != NULL; elt = elt->next) {
if (elt->addr == caller)
break;
@@ -328,7 +329,7 @@ malloc_stats (void)
return;
j = 0;
- for (i = 0; i < ARRAY_SIZE (func_stats); i++) {
+ for (i = 0; i < ARRAY_LENGTH (func_stats); i++) {
struct func_stat_t *elt;
for (elt = func_stats[i]; elt != NULL; elt = elt->next)
sorted_func_stats[j++] = *elt;
diff --git a/util/show-contour.c b/util/show-contour.c
index f3fa1babf..f3fa1babf 100755..100644
--- a/util/show-contour.c
+++ b/util/show-contour.c
diff --git a/util/show-edges.c b/util/show-edges.c
index a85ad5f7e..a85ad5f7e 100755..100644
--- a/util/show-edges.c
+++ b/util/show-edges.c
diff --git a/util/show-events.c b/util/show-events.c
index 8bff3efc4..8bff3efc4 100755..100644
--- a/util/show-events.c
+++ b/util/show-events.c
diff --git a/util/show-polygon.c b/util/show-polygon.c
index 35c0014d1..35c0014d1 100755..100644
--- a/util/show-polygon.c
+++ b/util/show-polygon.c
diff --git a/util/show-traps.c b/util/show-traps.c
index f46c8b009..f46c8b009 100755..100644
--- a/util/show-traps.c
+++ b/util/show-traps.c
diff --git a/util/trace-to-xml.c b/util/trace-to-xml.c
index a0f03ccff..a0f03ccff 100755..100644
--- a/util/trace-to-xml.c
+++ b/util/trace-to-xml.c
diff --git a/util/xml-to-trace.c b/util/xml-to-trace.c
index 13b7e5706..13b7e5706 100755..100644
--- a/util/xml-to-trace.c
+++ b/util/xml-to-trace.c