summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSøren Sandmann Pedersen <sandmann@redhat.com>2009-02-17 06:30:49 -0500
committerSøren Sandmann Pedersen <sandmann@redhat.com>2009-02-17 06:30:49 -0500
commitf37ebaa8f3089c4fa5f08bf16f8b52064006c64d (patch)
tree0774a1f052abfe6cad85f2328c1446a2f576a4fd
parentf8ce71d1f519bfad103f019312d536a9a605372b (diff)
parent2760d558e65696657882f2219218aa71032ac5bc (diff)
Merge branch 'damage' of git+ssh://sandmann@freedesktop.org/home/sandmann/cairo-damage into damagedamage
Conflicts: src/cairo.c
-rw-r--r--build/Makefile.am.changelog2
-rw-r--r--build/configure.ac.system2
-rw-r--r--configure.ac5
-rw-r--r--perf/Makefile.am9
-rwxr-xr-xperf/cairo-perf-diff2
-rw-r--r--perf/cairo-perf.c6
-rw-r--r--perf/cairo-perf.h2
-rw-r--r--perf/intersections.c97
-rw-r--r--perf/spiral.c200
-rw-r--r--src/Makefile.sources3
-rw-r--r--src/cairo-analysis-surface.c32
-rw-r--r--src/cairo-array.c10
-rw-r--r--src/cairo-base85-stream.c2
-rw-r--r--src/cairo-bentley-ottmann.c13
-rw-r--r--src/cairo-beos-surface.cpp2
-rw-r--r--src/cairo-cache.c10
-rw-r--r--src/cairo-cff-subset.c274
-rw-r--r--src/cairo-clip.c171
-rw-r--r--src/cairo-deflate-stream.c2
-rw-r--r--src/cairo-directfb-surface.c5
-rw-r--r--src/cairo-font-face.c20
-rw-r--r--src/cairo-ft-font.c69
-rw-r--r--src/cairo-glitz-surface.c478
-rw-r--r--src/cairo-gstate-private.h3
-rw-r--r--src/cairo-gstate.c156
-rw-r--r--src/cairo-hash.c6
-rw-r--r--src/cairo-hull.c2
-rw-r--r--src/cairo-image-surface.c297
-rw-r--r--src/cairo-lzw.c8
-rw-r--r--src/cairo-matrix.c4
-rw-r--r--src/cairo-meta-surface.c68
-rw-r--r--src/cairo-misc.c26
-rw-r--r--src/cairo-os2-surface.c2
-rw-r--r--src/cairo-output-stream.c16
-rw-r--r--src/cairo-paginated-surface.c42
-rw-r--r--src/cairo-path-fill.c8
-rw-r--r--src/cairo-path-fixed-private.h14
-rw-r--r--src/cairo-path-fixed.c152
-rw-r--r--src/cairo-path-stroke.c60
-rw-r--r--src/cairo-path.c14
-rw-r--r--src/cairo-pattern.c70
-rw-r--r--src/cairo-pdf-operators.c66
-rw-r--r--src/cairo-pdf-surface.c370
-rw-r--r--src/cairo-pen.c14
-rw-r--r--src/cairo-png.c43
-rw-r--r--src/cairo-polygon.c2
-rw-r--r--src/cairo-ps-surface.c140
-rw-r--r--src/cairo-quartz-image-surface.c2
-rw-r--r--src/cairo-quartz-surface.c65
-rw-r--r--src/cairo-rectangle.c21
-rw-r--r--src/cairo-region-private.h5
-rw-r--r--src/cairo-region.c13
-rw-r--r--src/cairo-scaled-font-subsets.c58
-rw-r--r--src/cairo-scaled-font.c101
-rw-r--r--src/cairo-script-surface.c176
-rw-r--r--src/cairo-sdl-surface.c8
-rw-r--r--src/cairo-skiplist.c18
-rw-r--r--src/cairo-spans-private.h144
-rw-r--r--src/cairo-spans.c395
-rw-r--r--src/cairo-stroke-style.c2
-rw-r--r--src/cairo-surface-fallback.c170
-rw-r--r--src/cairo-surface.c117
-rw-r--r--src/cairo-svg-surface.c102
-rw-r--r--src/cairo-tor-scan-converter.c2003
-rw-r--r--src/cairo-traps.c16
-rw-r--r--src/cairo-truetype-subset.c128
-rw-r--r--src/cairo-type1-fallback.c59
-rw-r--r--src/cairo-type1-subset.c68
-rw-r--r--src/cairo-type3-glyph-surface.c14
-rw-r--r--src/cairo-types-private.h24
-rw-r--r--src/cairo-user-font.c20
-rw-r--r--src/cairo-win32-printing-surface.c2
-rw-r--r--src/cairo-win32-surface.c9
-rw-r--r--src/cairo-xcb-surface.c2
-rw-r--r--src/cairo-xlib-display.c4
-rw-r--r--src/cairo-xlib-screen.c6
-rw-r--r--src/cairo-xlib-surface.c119
-rw-r--r--src/cairo-xlib-visual.c2
-rw-r--r--src/cairo.c145
-rw-r--r--src/cairoint.h62
-rwxr-xr-xsrc/check-doc-syntax.sh2
-rw-r--r--src/test-fallback-surface.c4
-rw-r--r--src/test-meta-surface.c4
-rw-r--r--src/test-paginated-surface.c4
-rw-r--r--test/Makefile.am19
-rw-r--r--test/cairo-test-runner.c4
-rw-r--r--test/caps-joins-curve.c111
-rw-r--r--test/caps-joins-curve.ps.ref.pngbin0 -> 3728 bytes
-rw-r--r--test/caps-joins-curve.ref.pngbin0 -> 5132 bytes
-rw-r--r--test/caps-joins.c40
-rw-r--r--test/caps-joins.ps.ref.pngbin0 -> 2282 bytes
-rw-r--r--test/caps-joins.ps2.ref.pngbin1459 -> 0 bytes
-rw-r--r--test/caps-joins.ps3.ref.pngbin1459 -> 0 bytes
-rw-r--r--test/caps-joins.ref.pngbin1488 -> 2380 bytes
-rw-r--r--test/caps.c87
-rw-r--r--test/caps.ps.ref.pngbin0 -> 1466 bytes
-rw-r--r--test/caps.ref.pngbin0 -> 1601 bytes
-rw-r--r--test/clip-fill-rule.pdf.argb32.ref.pngbin0 -> 509 bytes
-rw-r--r--test/clip-fill-rule.rgb24.ref.pngbin380 -> 390 bytes
-rw-r--r--test/clip-fill-rule.test-fallback.rgb24.ref.pngbin0 -> 361 bytes
-rw-r--r--test/clip-fill-rule.test-paginated.rgb24.ref.pngbin0 -> 361 bytes
-rw-r--r--test/clip-fill-rule.xlib.rgb24.ref.pngbin0 -> 380 bytes
-rw-r--r--test/clip-nesting.pdf.argb32.ref.pngbin0 -> 850 bytes
-rw-r--r--test/clip-nesting.rgb24.ref.pngbin955 -> 963 bytes
-rw-r--r--test/clip-nesting.test-fallback.rgb24.ref.pngbin0 -> 936 bytes
-rw-r--r--test/clip-nesting.test-paginated.rgb24.ref.pngbin0 -> 936 bytes
-rw-r--r--test/clip-nesting.xlib.rgb24.ref.pngbin0 -> 955 bytes
-rw-r--r--test/clip-operator.pdf.argb32.ref.pngbin12125 -> 11604 bytes
-rw-r--r--test/clip-operator.pdf.rgb24.ref.pngbin7367 -> 6882 bytes
-rw-r--r--test/clip-operator.ps2.rgb24.ref.pngbin3624 -> 3736 bytes
-rw-r--r--test/clip-operator.ps3.argb32.ref.pngbin0 -> 7576 bytes
-rw-r--r--test/clip-operator.ps3.rgb24.ref.pngbin3624 -> 3736 bytes
-rw-r--r--test/clip-operator.ref.pngbin8271 -> 8210 bytes
-rw-r--r--test/clip-operator.rgb24.ref.pngbin3258 -> 3279 bytes
-rw-r--r--test/clip-operator.test-fallback.argb32.ref.pngbin0 -> 8252 bytes
-rw-r--r--test/clip-operator.test-fallback.rgb24.ref.pngbin0 -> 3241 bytes
-rw-r--r--test/clip-operator.test-paginated.argb32.ref.pngbin0 -> 8247 bytes
-rw-r--r--test/clip-operator.xlib-fallback.rgb24.ref.pngbin0 -> 3254 bytes
-rw-r--r--test/clip-operator.xlib.ref.pngbin0 -> 8271 bytes
-rw-r--r--test/clip-operator.xlib.rgb24.ref.pngbin0 -> 3258 bytes
-rw-r--r--test/clip-twice.pdf.argb32.ref.pngbin0 -> 1498 bytes
-rw-r--r--test/clip-twice.ref.pngbin1362 -> 1342 bytes
-rw-r--r--test/clip-twice.rgb24.ref.pngbin1198 -> 1203 bytes
-rw-r--r--test/clip-twice.test-fallback.argb32.ref.pngbin0 -> 1343 bytes
-rw-r--r--test/clip-twice.test-fallback.rgb24.ref.pngbin0 -> 1179 bytes
-rw-r--r--test/clip-twice.test-paginated.argb32.ref.pngbin0 -> 1361 bytes
-rw-r--r--test/clip-twice.test-paginated.rgb24.ref.pngbin0 -> 1199 bytes
-rw-r--r--test/clip-twice.xlib.ref.pngbin0 -> 1362 bytes
-rw-r--r--test/clip-twice.xlib.rgb24.ref.pngbin0 -> 1198 bytes
-rw-r--r--test/clipped-group.pdf.argb32.ref.pngbin0 -> 298 bytes
-rw-r--r--test/clipped-group.pdf.rgb24.ref.pngbin0 -> 298 bytes
-rw-r--r--test/dash-curve.ref.pngbin39642 -> 39696 bytes
-rw-r--r--test/degenerate-arc.ref.pngbin616 -> 544 bytes
-rw-r--r--test/degenerate-arc.test-fallback.argb32.ref.pngbin0 -> 547 bytes
-rw-r--r--test/degenerate-arc.test-fallback.rgb24.ref.pngbin0 -> 547 bytes
-rw-r--r--test/degenerate-arc.xlib.ref.pngbin0 -> 616 bytes
-rw-r--r--test/device-offset-fractional.pdf.argb32.ref.pngbin0 -> 275 bytes
-rw-r--r--test/device-offset-fractional.pdf.rgb24.ref.pngbin0 -> 275 bytes
-rw-r--r--test/device-offset-positive.c1
-rw-r--r--test/fill-alpha-pattern.pdf.argb32.ref.pngbin3887 -> 3750 bytes
-rw-r--r--test/fill-alpha-pattern.pdf.rgb24.ref.pngbin3840 -> 3758 bytes
-rw-r--r--test/fill-alpha-pattern.ps3.argb32.ref.pngbin0 -> 4070 bytes
-rw-r--r--test/fill-alpha-pattern.ps3.rgb24.ref.pngbin0 -> 4473 bytes
-rw-r--r--test/fill-alpha-pattern.ref.pngbin3653 -> 3374 bytes
-rw-r--r--test/fill-alpha-pattern.test-fallback.argb32.ref.pngbin0 -> 3379 bytes
-rw-r--r--test/fill-alpha-pattern.test-fallback.rgb24.ref.pngbin0 -> 3379 bytes
-rw-r--r--test/fill-alpha-pattern.xlib.ref.pngbin0 -> 3653 bytes
-rw-r--r--test/fill-alpha.ref.pngbin2989 -> 2728 bytes
-rw-r--r--test/fill-alpha.test-fallback.argb32.ref.pngbin0 -> 2824 bytes
-rw-r--r--test/fill-alpha.test-fallback.rgb24.ref.pngbin0 -> 2824 bytes
-rw-r--r--test/fill-alpha.xlib.ref.pngbin0 -> 2989 bytes
-rw-r--r--test/fill-degenerate-sort-order.ref.pngbin2397 -> 2406 bytes
-rw-r--r--test/fill-degenerate-sort-order.rgb24.ref.pngbin2060 -> 2052 bytes
-rw-r--r--test/fill-degenerate-sort-order.test-fallback.argb32.ref.pngbin0 -> 2378 bytes
-rw-r--r--test/fill-degenerate-sort-order.test-fallback.rgb24.ref.pngbin0 -> 2041 bytes
-rw-r--r--test/fill-degenerate-sort-order.xlib.ref.pngbin0 -> 2397 bytes
-rw-r--r--test/fill-degenerate-sort-order.xlib.rgb24.ref.pngbin0 -> 2060 bytes
-rw-r--r--test/fill-missed-stop.pdf.argb32.ref.pngbin0 -> 452 bytes
-rw-r--r--test/fill-rule.ref.pngbin1979 -> 2061 bytes
-rw-r--r--test/fill-rule.rgb24.ref.pngbin1722 -> 1780 bytes
-rw-r--r--test/fill-rule.test-fallback.argb32.ref.pngbin0 -> 1979 bytes
-rw-r--r--test/fill-rule.test-fallback.rgb24.ref.pngbin0 -> 1703 bytes
-rw-r--r--test/fill-rule.xlib.ref.pngbin0 -> 1979 bytes
-rw-r--r--test/fill-rule.xlib.rgb24.ref.pngbin0 -> 1722 bytes
-rw-r--r--test/filter-nearest-offset.pdf.argb32.ref.pngbin0 -> 4295 bytes
-rw-r--r--test/filter-nearest-offset.pdf.rgb24.ref.pngbin0 -> 4295 bytes
-rw-r--r--test/filter-nearest-transformed.pdf.argb32.ref.pngbin0 -> 488 bytes
-rw-r--r--test/filter-nearest-transformed.pdf.rgb24.ref.pngbin0 -> 488 bytes
-rw-r--r--test/finer-grained-fallbacks.ps2.argb32.ref.pngbin0 -> 1173 bytes
-rw-r--r--test/finer-grained-fallbacks.ps2.rgb24.ref.pngbin1096 -> 1154 bytes
-rw-r--r--test/finer-grained-fallbacks.ps3.argb32.ref.pngbin0 -> 1173 bytes
-rw-r--r--test/finer-grained-fallbacks.ps3.rgb24.ref.pngbin1096 -> 1154 bytes
-rw-r--r--test/finer-grained-fallbacks.ref.pngbin1111 -> 1069 bytes
-rw-r--r--test/finer-grained-fallbacks.rgb24.ref.pngbin1114 -> 839 bytes
-rw-r--r--test/finer-grained-fallbacks.test-fallback.argb32.ref.pngbin0 -> 1111 bytes
-rw-r--r--test/finer-grained-fallbacks.test-fallback.rgb24.ref.pngbin0 -> 854 bytes
-rw-r--r--test/finer-grained-fallbacks.xlib.ref.pngbin0 -> 1111 bytes
-rw-r--r--test/finer-grained-fallbacks.xlib.rgb24.ref.pngbin0 -> 1114 bytes
-rw-r--r--test/font-matrix-translation.svg11.argb32.ref.pngbin0 -> 857 bytes
-rw-r--r--test/font-matrix-translation.svg11.rgb24.ref.pngbin0 -> 857 bytes
-rw-r--r--test/font-matrix-translation.svg12.argb32.ref.pngbin0 -> 857 bytes
-rw-r--r--test/font-matrix-translation.svg12.rgb24.ref.pngbin0 -> 857 bytes
-rw-r--r--test/ft-show-glyphs-table.svg11.argb32.ref.pngbin0 -> 9953 bytes
-rw-r--r--test/ft-show-glyphs-table.svg11.rgb24.ref.pngbin0 -> 9953 bytes
-rw-r--r--test/ft-show-glyphs-table.svg12.argb32.ref.pngbin0 -> 9953 bytes
-rw-r--r--test/ft-show-glyphs-table.svg12.rgb24.ref.pngbin0 -> 9953 bytes
-rw-r--r--test/ft-text-vertical-layout-type1.pdf.argb32.ref.pngbin0 -> 3632 bytes
-rw-r--r--test/ft-text-vertical-layout-type1.pdf.rgb24.ref.pngbin0 -> 3632 bytes
-rw-r--r--test/ft-text-vertical-layout-type1.ref.pngbin3980 -> 3643 bytes
-rw-r--r--test/ft-text-vertical-layout-type1.svg11.argb32.ref.pngbin0 -> 3614 bytes
-rw-r--r--test/ft-text-vertical-layout-type1.svg11.rgb24.ref.pngbin0 -> 3614 bytes
-rw-r--r--test/ft-text-vertical-layout-type1.svg12.argb32.ref.pngbin0 -> 3614 bytes
-rw-r--r--test/ft-text-vertical-layout-type1.svg12.rgb24.ref.pngbin0 -> 3614 bytes
-rw-r--r--test/ft-text-vertical-layout-type1.test-fallback.argb32.ref.pngbin0 -> 3639 bytes
-rw-r--r--test/ft-text-vertical-layout-type1.test-fallback.rgb24.ref.pngbin0 -> 3639 bytes
-rw-r--r--test/ft-text-vertical-layout-type1.xlib.ref.pngbin0 -> 3980 bytes
-rw-r--r--test/ft-text-vertical-layout-type3.pdf.argb32.ref.pngbin0 -> 3642 bytes
-rw-r--r--test/ft-text-vertical-layout-type3.pdf.rgb24.ref.pngbin0 -> 3642 bytes
-rw-r--r--test/ft-text-vertical-layout-type3.ref.pngbin3934 -> 3609 bytes
-rw-r--r--test/ft-text-vertical-layout-type3.svg11.argb32.ref.pngbin0 -> 3640 bytes
-rw-r--r--test/ft-text-vertical-layout-type3.svg11.rgb24.ref.pngbin0 -> 3640 bytes
-rw-r--r--test/ft-text-vertical-layout-type3.svg12.argb32.ref.pngbin0 -> 3640 bytes
-rw-r--r--test/ft-text-vertical-layout-type3.svg12.rgb24.ref.pngbin0 -> 3640 bytes
-rw-r--r--test/ft-text-vertical-layout-type3.test-fallback.argb32.ref.pngbin0 -> 3605 bytes
-rw-r--r--test/ft-text-vertical-layout-type3.test-fallback.rgb24.ref.pngbin0 -> 3605 bytes
-rw-r--r--test/ft-text-vertical-layout-type3.xlib.ref.pngbin0 -> 3934 bytes
-rw-r--r--test/glitz-surface-source.c96
-rw-r--r--test/glitz-surface-source.ps2.ref.pngbin0 -> 376 bytes
-rw-r--r--test/glitz-surface-source.ps3.ref.pngbin0 -> 376 bytes
-rw-r--r--test/huge-pattern.pdf.argb32.ref.pngbin0 -> 2430 bytes
-rw-r--r--test/linear-gradient.pdf.argb32.ref.pngbin0 -> 1112 bytes
-rw-r--r--test/linear-gradient.pdf.rgb24.ref.pngbin0 -> 1112 bytes
-rw-r--r--test/linear-gradient.ref.pngbin1021 -> 983 bytes
-rw-r--r--test/linear-gradient.svg11.argb32.ref.pngbin0 -> 988 bytes
-rw-r--r--test/linear-gradient.svg11.rgb24.ref.pngbin0 -> 988 bytes
-rw-r--r--test/linear-gradient.svg12.argb32.ref.pngbin0 -> 988 bytes
-rw-r--r--test/linear-gradient.svg12.rgb24.ref.pngbin0 -> 988 bytes
-rw-r--r--test/linear-gradient.test-fallback.argb32.ref.pngbin0 -> 923 bytes
-rw-r--r--test/linear-gradient.test-fallback.rgb24.ref.pngbin0 -> 923 bytes
-rw-r--r--test/linear-gradient.xlib.ref.pngbin0 -> 1021 bytes
-rw-r--r--test/mask-alpha.ref.pngbin640 -> 643 bytes
-rw-r--r--test/mask-alpha.svg11.argb32.ref.pngbin615 -> 642 bytes
-rw-r--r--test/mask-alpha.svg11.rgb24.ref.pngbin0 -> 592 bytes
-rw-r--r--test/mask-alpha.svg12.argb32.ref.pngbin615 -> 642 bytes
-rw-r--r--test/mask-alpha.svg12.rgb24.ref.pngbin0 -> 592 bytes
-rw-r--r--test/mask-alpha.test-fallback.argb32.ref.pngbin0 -> 627 bytes
-rw-r--r--test/mask-alpha.xlib.ref.pngbin0 -> 640 bytes
-rw-r--r--test/mask-alpha.xlib.rgb24.ref.pngbin0 -> 599 bytes
-rw-r--r--test/mask.pdf.argb32.ref.pngbin8881 -> 9903 bytes
-rw-r--r--test/mask.pdf.rgb24.ref.pngbin8267 -> 8735 bytes
-rw-r--r--test/mask.ref.pngbin8476 -> 8581 bytes
-rw-r--r--test/mask.rgb24.ref.pngbin7041 -> 7216 bytes
-rw-r--r--test/mask.svg11.argb32.ref.pngbin8527 -> 8682 bytes
-rw-r--r--test/mask.svg11.rgb24.ref.pngbin7935 -> 7203 bytes
-rw-r--r--test/mask.svg12.argb32.ref.pngbin8527 -> 8682 bytes
-rw-r--r--test/mask.svg12.rgb24.ref.pngbin7935 -> 7203 bytes
-rw-r--r--test/mask.test-fallback.argb32.ref.pngbin0 -> 8457 bytes
-rw-r--r--test/mask.test-fallback.rgb24.ref.pngbin0 -> 7058 bytes
-rw-r--r--test/mask.xlib-fallback.rgb24.ref.pngbin0 -> 7216 bytes
-rw-r--r--test/mask.xlib.ref.pngbin0 -> 8476 bytes
-rw-r--r--test/mask.xlib.rgb24.ref.pngbin0 -> 7041 bytes
-rw-r--r--test/meta-surface-pattern.pdf.argb32.ref.pngbin0 -> 4011 bytes
-rw-r--r--test/meta-surface-pattern.pdf.rgb24.ref.pngbin4009 -> 3910 bytes
-rw-r--r--test/meta-surface-pattern.svg11.argb32.ref.pngbin3924 -> 3924 bytes
-rw-r--r--test/meta-surface-pattern.svg11.rgb24.ref.pngbin4593 -> 3914 bytes
-rw-r--r--test/meta-surface-pattern.svg12.argb32.ref.pngbin3924 -> 3924 bytes
-rw-r--r--test/meta-surface-pattern.svg12.rgb24.ref.pngbin4593 -> 3914 bytes
-rw-r--r--test/operator-clear.pdf.argb32.ref.pngbin1614 -> 1607 bytes
-rw-r--r--test/operator-clear.ps2.argb32.ref.pngbin0 -> 1156 bytes
-rw-r--r--test/operator-clear.ps3.argb32.ref.pngbin0 -> 1156 bytes
-rw-r--r--test/operator-source.pdf.argb32.ref.pngbin5149 -> 5112 bytes
-rw-r--r--test/operator-source.pdf.rgb24.ref.pngbin4354 -> 4186 bytes
-rw-r--r--test/operator-source.ref.pngbin4420 -> 4425 bytes
-rw-r--r--test/operator-source.rgb24.ref.pngbin3201 -> 3231 bytes
-rw-r--r--test/operator-source.test-fallback.argb32.ref.pngbin0 -> 4401 bytes
-rw-r--r--test/operator-source.test-fallback.rgb24.ref.pngbin0 -> 3200 bytes
-rw-r--r--test/operator-source.xlib-fallback.rgb24.ref.pngbin0 -> 3193 bytes
-rw-r--r--test/operator-source.xlib.ref.pngbin0 -> 4420 bytes
-rw-r--r--test/operator-source.xlib.rgb24.ref.pngbin0 -> 3201 bytes
-rw-r--r--test/over-above-source.ps2.argb32.ref.pngbin636 -> 558 bytes
-rw-r--r--test/over-above-source.ps3.argb32.ref.pngbin636 -> 558 bytes
-rw-r--r--test/over-above-source.ref.pngbin538 -> 560 bytes
-rw-r--r--test/over-above-source.rgb24.ref.pngbin461 -> 466 bytes
-rw-r--r--test/over-above-source.test-fallback.argb32.ref.pngbin0 -> 533 bytes
-rw-r--r--test/over-above-source.test-fallback.rgb24.ref.pngbin0 -> 450 bytes
-rw-r--r--test/over-above-source.xlib.ref.pngbin0 -> 538 bytes
-rw-r--r--test/over-above-source.xlib.rgb24.ref.pngbin0 -> 461 bytes
-rw-r--r--test/over-around-source.pdf.argb32.ref.pngbin0 -> 585 bytes
-rw-r--r--test/over-around-source.ps2.argb32.ref.pngbin632 -> 522 bytes
-rw-r--r--test/over-around-source.ps3.argb32.ref.pngbin632 -> 522 bytes
-rw-r--r--test/over-around-source.ref.pngbin614 -> 645 bytes
-rw-r--r--test/over-around-source.test-fallback.argb32.ref.pngbin0 -> 610 bytes
-rw-r--r--test/over-around-source.xlib.ref.pngbin0 -> 614 bytes
-rw-r--r--test/over-around-source.xlib.rgb24.ref.pngbin0 -> 503 bytes
-rw-r--r--test/over-below-source.pdf.argb32.ref.pngbin0 -> 464 bytes
-rw-r--r--test/over-between-source.ps2.argb32.ref.pngbin678 -> 551 bytes
-rw-r--r--test/over-between-source.ps3.argb32.ref.pngbin678 -> 551 bytes
-rw-r--r--test/over-between-source.ref.pngbin575 -> 612 bytes
-rw-r--r--test/over-between-source.test-fallback.argb32.ref.pngbin0 -> 578 bytes
-rw-r--r--test/over-between-source.xlib.ref.pngbin0 -> 575 bytes
-rw-r--r--test/over-between-source.xlib.rgb24.ref.pngbin0 -> 473 bytes
-rw-r--r--test/push-group.pdf.argb32.ref.pngbin0 -> 2722 bytes
-rw-r--r--test/push-group.pdf.rgb24.ref.pngbin2714 -> 2740 bytes
-rw-r--r--test/push-group.ref.pngbin3126 -> 3060 bytes
-rw-r--r--test/push-group.rgb24.ref.pngbin2961 -> 2912 bytes
-rw-r--r--test/push-group.svg11.argb32.ref.pngbin2935 -> 3034 bytes
-rw-r--r--test/push-group.svg12.argb32.ref.pngbin2935 -> 3034 bytes
-rw-r--r--test/push-group.test-fallback.argb32.ref.pngbin0 -> 3107 bytes
-rw-r--r--test/push-group.test-fallback.rgb24.ref.pngbin0 -> 2942 bytes
-rw-r--r--test/push-group.xlib-fallback.rgb24.ref.pngbin0 -> 2912 bytes
-rw-r--r--test/push-group.xlib.ref.pngbin0 -> 3126 bytes
-rw-r--r--test/push-group.xlib.rgb24.ref.pngbin0 -> 2961 bytes
-rw-r--r--test/quartz-surface-source.c42
-rw-r--r--test/quartz-surface-source.ps2.ref.pngbin0 -> 376 bytes
-rw-r--r--test/quartz-surface-source.ps3.ref.pngbin0 -> 376 bytes
-rw-r--r--test/quartz-surface-source.ref.pngbin0 -> 332 bytes
-rw-r--r--test/radial-gradient.pdf.argb32.ref.pngbin0 -> 79601 bytes
-rw-r--r--test/radial-gradient.pdf.rgb24.ref.pngbin0 -> 79601 bytes
-rw-r--r--test/random-intersections.ref.pngbin148722 -> 133462 bytes
-rw-r--r--test/random-intersections.test-fallback.argb32.ref.pngbin0 -> 132312 bytes
-rw-r--r--test/random-intersections.test-fallback.rgb24.ref.pngbin0 -> 132312 bytes
-rw-r--r--test/random-intersections.xlib.ref.pngbin0 -> 148722 bytes
-rw-r--r--test/rotate-image-surface-paint.pdf.argb32.ref.pngbin209 -> 215 bytes
-rw-r--r--test/rotate-image-surface-paint.pdf.rgb24.ref.pngbin207 -> 215 bytes
-rw-r--r--test/smask-fill.pdf.argb32.ref.pngbin0 -> 1909 bytes
-rw-r--r--test/smask-fill.pdf.rgb24.ref.pngbin0 -> 1909 bytes
-rw-r--r--test/smask-fill.ref.pngbin1223 -> 1156 bytes
-rw-r--r--test/smask-fill.svg11.argb32.ref.pngbin0 -> 1128 bytes
-rw-r--r--test/smask-fill.svg11.rgb24.ref.pngbin0 -> 1128 bytes
-rw-r--r--test/smask-fill.svg12.argb32.ref.pngbin0 -> 1128 bytes
-rw-r--r--test/smask-fill.svg12.rgb24.ref.pngbin0 -> 1128 bytes
-rw-r--r--test/smask-fill.test-fallback.argb32.ref.pngbin0 -> 1148 bytes
-rw-r--r--test/smask-fill.test-fallback.rgb24.ref.pngbin0 -> 1148 bytes
-rw-r--r--test/smask-fill.xlib-fallback.ref.pngbin0 -> 1156 bytes
-rw-r--r--test/smask-fill.xlib.ref.pngbin0 -> 1223 bytes
-rw-r--r--test/smask-image-mask.pdf.argb32.ref.pngbin0 -> 1651 bytes
-rw-r--r--test/smask-image-mask.pdf.rgb24.ref.pngbin0 -> 1651 bytes
-rw-r--r--test/smask-mask.pdf.argb32.ref.pngbin0 -> 4398 bytes
-rw-r--r--test/smask-mask.pdf.rgb24.ref.pngbin0 -> 4398 bytes
-rw-r--r--test/smask-paint.pdf.argb32.ref.pngbin0 -> 4496 bytes
-rw-r--r--test/smask-paint.pdf.rgb24.ref.pngbin0 -> 4496 bytes
-rw-r--r--test/smask-stroke.pdf.argb32.ref.pngbin0 -> 1417 bytes
-rw-r--r--test/smask-stroke.pdf.rgb24.ref.pngbin0 -> 1417 bytes
-rw-r--r--test/smask-text.svg11.argb32.ref.pngbin0 -> 1791 bytes
-rw-r--r--test/smask-text.svg11.rgb24.ref.pngbin0 -> 1791 bytes
-rw-r--r--test/smask-text.svg12.argb32.ref.pngbin0 -> 1791 bytes
-rw-r--r--test/smask-text.svg12.rgb24.ref.pngbin0 -> 1791 bytes
-rw-r--r--test/smask.pdf.argb32.ref.pngbin0 -> 4496 bytes
-rw-r--r--test/smask.pdf.rgb24.ref.pngbin0 -> 4496 bytes
-rw-r--r--test/surface-pattern-scale-down.pdf.argb32.ref.pngbin2386 -> 1532 bytes
-rw-r--r--test/surface-pattern-scale-down.pdf.rgb24.ref.pngbin2386 -> 1532 bytes
-rw-r--r--test/surface-pattern-scale-up.pdf.argb32.ref.pngbin4247 -> 3834 bytes
-rw-r--r--test/surface-pattern-scale-up.pdf.rgb24.ref.pngbin4247 -> 3834 bytes
-rw-r--r--test/surface-pattern.pdf.argb32.ref.pngbin0 -> 14808 bytes
-rw-r--r--test/surface-pattern.pdf.rgb24.ref.pngbin0 -> 14808 bytes
-rw-r--r--test/text-pattern.pdf.argb32.ref.pngbin1823 -> 2151 bytes
-rw-r--r--test/text-pattern.svg11.argb32.ref.pngbin1733 -> 1743 bytes
-rw-r--r--test/text-pattern.svg12.argb32.ref.pngbin1733 -> 1743 bytes
-rw-r--r--test/text-rotate.svg11.argb32.ref.pngbin0 -> 16942 bytes
-rw-r--r--test/text-rotate.svg11.rgb24.ref.pngbin0 -> 16942 bytes
-rw-r--r--test/text-rotate.svg12.argb32.ref.pngbin0 -> 16942 bytes
-rw-r--r--test/text-rotate.svg12.rgb24.ref.pngbin0 -> 16942 bytes
-rw-r--r--test/text-transform.svg11.argb32.ref.pngbin0 -> 5677 bytes
-rw-r--r--test/text-transform.svg11.rgb24.ref.pngbin0 -> 5677 bytes
-rw-r--r--test/text-transform.svg12.argb32.ref.pngbin0 -> 5677 bytes
-rw-r--r--test/text-transform.svg12.rgb24.ref.pngbin0 -> 5677 bytes
-rw-r--r--test/trap-clip.pdf.argb32.ref.pngbin5809 -> 6720 bytes
-rw-r--r--test/trap-clip.pdf.rgb24.ref.pngbin5768 -> 6621 bytes
-rw-r--r--test/trap-clip.ps2.argb32.ref.pngbin5690 -> 4849 bytes
-rw-r--r--test/trap-clip.ref.pngbin5772 -> 5829 bytes
-rw-r--r--test/trap-clip.rgb24.ref.pngbin5365 -> 5457 bytes
-rw-r--r--test/trap-clip.test-fallback.argb32.ref.pngbin0 -> 5753 bytes
-rw-r--r--test/trap-clip.test-fallback.rgb24.ref.pngbin0 -> 5379 bytes
-rw-r--r--test/trap-clip.test-paginated.argb32.ref.pngbin0 -> 5865 bytes
-rw-r--r--test/trap-clip.xlib.ref.pngbin0 -> 5772 bytes
-rw-r--r--test/trap-clip.xlib.rgb24.ref.pngbin0 -> 5365 bytes
-rw-r--r--test/twin.svg11.argb32.ref.pngbin0 -> 1797 bytes
-rw-r--r--test/twin.svg11.rgb24.ref.pngbin0 -> 1797 bytes
-rw-r--r--test/twin.svg12.argb32.ref.pngbin0 -> 1797 bytes
-rw-r--r--test/twin.svg12.rgb24.ref.pngbin0 -> 1797 bytes
-rw-r--r--test/unbounded-operator.pdf.argb32.ref.pngbin0 -> 2713 bytes
-rw-r--r--test/unbounded-operator.ps2.argb32.ref.pngbin0 -> 2713 bytes
-rw-r--r--test/unbounded-operator.ps3.argb32.ref.pngbin0 -> 2713 bytes
-rw-r--r--test/unbounded-operator.rgb24.ref.pngbin1315 -> 1341 bytes
-rw-r--r--test/unbounded-operator.test-fallback.rgb24.ref.pngbin0 -> 1306 bytes
-rw-r--r--test/unbounded-operator.xlib.rgb24.ref.pngbin0 -> 1315 bytes
-rw-r--r--test/user-font-proxy.pdf.argb32.ref.pngbin0 -> 16937 bytes
-rw-r--r--test/user-font-proxy.pdf.rgb24.ref.pngbin0 -> 16937 bytes
-rw-r--r--test/user-font-proxy.ref.pngbin18121 -> 16937 bytes
-rw-r--r--test/user-font-proxy.svg11.argb32.ref.pngbin0 -> 16836 bytes
-rw-r--r--test/user-font-proxy.svg11.rgb24.ref.pngbin0 -> 16836 bytes
-rw-r--r--test/user-font-proxy.svg12.argb32.ref.pngbin0 -> 16836 bytes
-rw-r--r--test/user-font-proxy.svg12.rgb24.ref.pngbin0 -> 16836 bytes
-rw-r--r--test/user-font-proxy.test-fallback.argb32.ref.pngbin0 -> 16835 bytes
-rw-r--r--test/user-font-proxy.test-fallback.rgb24.ref.pngbin0 -> 16835 bytes
-rw-r--r--test/user-font-proxy.xlib.ref.pngbin0 -> 18121 bytes
-rw-r--r--test/user-font.ref.pngbin6183 -> 6082 bytes
-rw-r--r--test/user-font.svg11.argb32.ref.pngbin0 -> 6411 bytes
-rw-r--r--test/user-font.svg11.rgb24.ref.pngbin0 -> 6411 bytes
-rw-r--r--test/user-font.svg12.argb32.ref.pngbin0 -> 6411 bytes
-rw-r--r--test/user-font.svg12.rgb24.ref.pngbin0 -> 6411 bytes
-rw-r--r--test/user-font.test-fallback.argb32.ref.pngbin0 -> 5601 bytes
-rw-r--r--test/user-font.test-fallback.rgb24.ref.pngbin0 -> 5601 bytes
-rw-r--r--test/user-font.xlib.ref.pngbin0 -> 6183 bytes
-rw-r--r--util/cairo-script/Makefile.am4
-rw-r--r--util/cairo-script/cairo-script-file.c5
-rw-r--r--util/cairo-script/cairo-script-operators.c2
-rw-r--r--util/cairo-script/csi-replay.c8
388 files changed, 5720 insertions, 1792 deletions
diff --git a/build/Makefile.am.changelog b/build/Makefile.am.changelog
index b9fbdcf3..888f4e79 100644
--- a/build/Makefile.am.changelog
+++ b/build/Makefile.am.changelog
@@ -71,7 +71,7 @@ $(srcdir)/ChangeLog.cache-% $(srcdir)/ChangeLog.pre-%:
test "x$$from" = xinitial || from=$$from.0; \
spec=$$from..$$to; \
fi; \
- $(srcdir)/build/missing --run git-log --stat "$$spec") > $@.tmp \
+ $(top_srcdir)/build/missing --run git-log --stat "$$spec") > $@.tmp \
&& mv -f $@.tmp $@ \
|| ($(RM) $@.tmp; \
echo Failed to generate $@, your $@ may be outdated >&2); \
diff --git a/build/configure.ac.system b/build/configure.ac.system
index d06b7989..4544a54f 100644
--- a/build/configure.ac.system
+++ b/build/configure.ac.system
@@ -69,7 +69,7 @@ AC_CHECK_HEADER(fenv.h,
dnl check for misc headers and functions
AC_CHECK_HEADERS([libgen.h byteswap.h signal.h setjmp.h])
-AC_CHECK_FUNCS([vasnprintf link ctime_r drand48 flockfile])
+AC_CHECK_FUNCS([vasnprintf link ctime_r drand48 flockfile ffs])
dnl check for win32 headers (this detects mingw as well)
AC_CHECK_HEADERS([windows.h], have_windows=yes, have_windows=no)
diff --git a/configure.ac b/configure.ac
index 7384ccc4..47a3ac60 100644
--- a/configure.ac
+++ b/configure.ac
@@ -29,7 +29,10 @@ AC_CACHE_SAVE
dnl ===========================================================================
AC_CHECK_LIB(z, compress,
- [AC_CHECK_HEADER(zlib.h, [have_libz=yes],
+ [AC_CHECK_HEADER(zlib.h, [
+ have_libz=yes
+ AC_DEFINE(HAVE_ZLIB, 1, [Define to 1 if you have zlib available])
+ ],
[have_libz="no (requires zlib http://www.gzip.org/zlib/)"])],
[have_libz="no (requires zlib http://www.gzip.org/zlib/)"])
diff --git a/perf/Makefile.am b/perf/Makefile.am
index 737e96a4..5dcc0ab3 100644
--- a/perf/Makefile.am
+++ b/perf/Makefile.am
@@ -43,7 +43,9 @@ cairo_perf_SOURCES = \
zrusin-another.h \
long-dashed-lines.c \
dragon.c \
- pythagoras-tree.c
+ pythagoras-tree.c \
+ intersections.c \
+ spiral.c
if CAIRO_HAS_WIN32_SURFACE
cairo_perf_SOURCES += cairo-perf-win32.c
@@ -54,6 +56,11 @@ else
cairo_perf_SOURCES += cairo-perf-posix.c
endif
endif
+cairo_perf_LDADD = $(LDADD)
+
+if CAIRO_HAS_SDL_SURFACE
+cairo_perf_LDADD += $(sdl_LIBS)
+endif
libcairoperf_la_SOURCES = \
cairo-perf-report.c \
diff --git a/perf/cairo-perf-diff b/perf/cairo-perf-diff
index 50cd1f2c..718cdc57 100755
--- a/perf/cairo-perf-diff
+++ b/perf/cairo-perf-diff
@@ -89,7 +89,7 @@ fi
git_setup() {
SUBDIRECTORY_OK='Yes'
- . git-sh-setup
+ . "$(git --exec-path)/git-sh-setup"
CAIRO_DIR=`dirname $GIT_DIR`
if [ "$CAIRO_DIR" = "." ]; then
CAIRO_DIR=`pwd`
diff --git a/perf/cairo-perf.c b/perf/cairo-perf.c
index d5f69201..6bb48f13 100644
--- a/perf/cairo-perf.c
+++ b/perf/cairo-perf.c
@@ -33,6 +33,10 @@
#include "cairo-boilerplate-getopt.h"
+#if CAIRO_HAS_SDL_SURFACE
+#include <SDL_main.h>
+#endif
+
/* For basename */
#ifdef HAVE_LIBGEN_H
#include <libgen.h>
@@ -461,5 +465,7 @@ const cairo_perf_case_t perf_cases[] = {
{ twin, 800, 800},
{ dragon, 1024, 1024 },
{ pythagoras_tree, 768, 768 },
+ { intersections, 512, 512 },
+ { spiral, 512, 512 },
{ NULL }
};
diff --git a/perf/cairo-perf.h b/perf/cairo-perf.h
index d18be033..3affcb82 100644
--- a/perf/cairo-perf.h
+++ b/perf/cairo-perf.h
@@ -175,5 +175,7 @@ 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);
#endif
diff --git a/perf/intersections.c b/perf/intersections.c
new file mode 100644
index 00000000..5e410366
--- /dev/null
+++ b/perf/intersections.c
@@ -0,0 +1,97 @@
+/* -*- 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_perf_ticks_t
+draw_random (cairo_t *cr, cairo_fill_rule_t fill_rule, int width, int height)
+{
+ int i;
+ double x[NUM_SEGMENTS];
+ double y[NUM_SEGMENTS];
+
+ 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_perf_timer_start (); {
+
+ 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_fill (cr);
+ }
+ cairo_perf_timer_stop ();
+
+ cairo_restore (cr);
+
+ return cairo_perf_timer_elapsed ();
+}
+
+static cairo_perf_ticks_t
+random_eo (cairo_t *cr, int width, int height)
+{
+ return draw_random (cr, CAIRO_FILL_RULE_EVEN_ODD, width, height);
+}
+
+static cairo_perf_ticks_t
+random_nz (cairo_t *cr, int width, int height)
+{
+ return draw_random (cr, CAIRO_FILL_RULE_WINDING, width, height);
+}
+
+void
+intersections (cairo_perf_t *perf, cairo_t *cr, int width, int height)
+{
+ cairo_perf_run (perf, "intersections-nz-fill", random_nz);
+ cairo_perf_run (perf, "intersections-eo-fill", random_eo);
+}
diff --git a/perf/spiral.c b/perf/spiral.c
new file mode 100644
index 00000000..f26d0a2b
--- /dev/null
+++ b/perf/spiral.c
@@ -0,0 +1,200 @@
+/* -*- 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 <assert.h>
+#include "cairo-perf.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_perf_ticks_t
+draw_spiral (cairo_t *cr,
+ cairo_fill_rule_t fill_rule,
+ align_t align,
+ close_t close,
+ int width, int height)
+{
+ 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_perf_timer_start (); {
+
+ 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_fill (cr);
+ }
+ cairo_perf_timer_stop ();
+
+ cairo_restore (cr);
+
+ return cairo_perf_timer_elapsed ();
+}
+
+static cairo_perf_ticks_t
+draw_spiral_eo_pa_re (cairo_t *cr, int width, int height)
+{
+ return draw_spiral (cr,
+ CAIRO_FILL_RULE_EVEN_ODD,
+ PIXALIGN,
+ RECTCLOSE,
+ width, height);
+}
+
+static cairo_perf_ticks_t
+draw_spiral_nz_pa_re (cairo_t *cr, int width, int height)
+{
+ return draw_spiral (cr,
+ CAIRO_FILL_RULE_WINDING,
+ PIXALIGN,
+ RECTCLOSE,
+ width, height);
+}
+
+static cairo_perf_ticks_t
+draw_spiral_eo_na_re (cairo_t *cr, int width, int height)
+{
+ return draw_spiral (cr,
+ CAIRO_FILL_RULE_EVEN_ODD,
+ NONALIGN,
+ RECTCLOSE,
+ width, height);
+}
+
+static cairo_perf_ticks_t
+draw_spiral_nz_na_re (cairo_t *cr, int width, int height)
+{
+ return draw_spiral (cr,
+ CAIRO_FILL_RULE_WINDING,
+ NONALIGN,
+ RECTCLOSE,
+ width, height);
+}
+
+static cairo_perf_ticks_t
+draw_spiral_eo_pa_di (cairo_t *cr, int width, int height)
+{
+ return draw_spiral (cr,
+ CAIRO_FILL_RULE_EVEN_ODD,
+ PIXALIGN,
+ DIAGCLOSE,
+ width, height);
+}
+
+static cairo_perf_ticks_t
+draw_spiral_nz_pa_di (cairo_t *cr, int width, int height)
+{
+ return draw_spiral (cr,
+ CAIRO_FILL_RULE_WINDING,
+ PIXALIGN,
+ DIAGCLOSE,
+ width, height);
+}
+
+static cairo_perf_ticks_t
+draw_spiral_eo_na_di (cairo_t *cr, int width, int height)
+{
+ return draw_spiral (cr,
+ CAIRO_FILL_RULE_EVEN_ODD,
+ NONALIGN,
+ DIAGCLOSE,
+ width, height);
+}
+
+static cairo_perf_ticks_t
+draw_spiral_nz_na_di (cairo_t *cr, int width, int height)
+{
+ return draw_spiral (cr,
+ CAIRO_FILL_RULE_WINDING,
+ NONALIGN,
+ DIAGCLOSE,
+ width, height);
+}
+
+void
+spiral (cairo_perf_t *perf, cairo_t *cr, int width, int height)
+{
+ cairo_perf_run (perf, "spiral-diag-nonalign-evenodd-fill", draw_spiral_eo_na_di);
+ cairo_perf_run (perf, "spiral-diag-nonalign-nonzero-fill", draw_spiral_nz_na_di);
+ cairo_perf_run (perf, "spiral-diag-pixalign-evenodd-fill", draw_spiral_eo_pa_di);
+ cairo_perf_run (perf, "spiral-diag-pixalign-nonzero-fill", draw_spiral_nz_pa_di);
+ cairo_perf_run (perf, "spiral-rect-nonalign-evenodd-fill", draw_spiral_eo_na_re);
+ cairo_perf_run (perf, "spiral-rect-nonalign-nonzero-fill", draw_spiral_nz_na_re);
+ cairo_perf_run (perf, "spiral-rect-pixalign-evenodd-fill", draw_spiral_eo_pa_re);
+ cairo_perf_run (perf, "spiral-rect-pixalign-nonzero-fill", draw_spiral_nz_pa_re);
+}
diff --git a/src/Makefile.sources b/src/Makefile.sources
index 5d643dcb..5f387f43 100644
--- a/src/Makefile.sources
+++ b/src/Makefile.sources
@@ -81,6 +81,7 @@ cairo_private = \
cairo-region-private.h \
cairo-scaled-font-private.h \
cairo-skiplist-private.h \
+ cairo-spans-private.h \
cairo-surface-fallback-private.h \
cairo-surface-private.h \
cairo-types-private.h \
@@ -132,10 +133,12 @@ cairo_sources = \
cairo-scaled-font.c \
cairo-skiplist.c \
cairo-slope.c \
+ cairo-spans.c \
cairo-spline.c \
cairo-stroke-style.c \
cairo-surface.c \
cairo-surface-fallback.c \
+ cairo-tor-scan-converter.c \
cairo-system.c \
cairo-traps.c \
cairo-unicode.c \
diff --git a/src/cairo-analysis-surface.c b/src/cairo-analysis-surface.c
index 3109deed..50005c21 100644
--- a/src/cairo-analysis-surface.c
+++ b/src/cairo-analysis-surface.c
@@ -337,7 +337,7 @@ _cairo_analysis_surface_paint (void *abstract_surface,
cairo_rectangle_int_t source_extents;
status = _cairo_pattern_get_extents (source, &source_extents);
- if (status)
+ if (unlikely (status))
return status;
is_empty = _cairo_rectangle_intersect (&extents, &source_extents);
@@ -407,7 +407,7 @@ _cairo_analysis_surface_mask (void *abstract_surface,
cairo_rectangle_int_t source_extents;
status = _cairo_pattern_get_extents (source, &source_extents);
- if (status)
+ if (unlikely (status))
return status;
is_empty = _cairo_rectangle_intersect (&extents, &source_extents);
@@ -417,7 +417,7 @@ _cairo_analysis_surface_mask (void *abstract_surface,
cairo_rectangle_int_t mask_extents;
status = _cairo_pattern_get_extents (mask, &mask_extents);
- if (status)
+ if (unlikely (status))
return status;
is_empty = _cairo_rectangle_intersect (&extents, &mask_extents);
@@ -469,7 +469,7 @@ _cairo_analysis_surface_stroke (void *abstract_surface,
cairo_rectangle_int_t source_extents;
status = _cairo_pattern_get_extents (source, &source_extents);
- if (status)
+ if (unlikely (status))
return status;
is_empty = _cairo_rectangle_intersect (&extents, &source_extents);
@@ -489,7 +489,7 @@ _cairo_analysis_surface_stroke (void *abstract_surface,
ctm, ctm_inverse,
tolerance,
&traps);
- if (status) {
+ if (unlikely (status)) {
_cairo_traps_fini (&traps);
return status;
}
@@ -541,7 +541,7 @@ _cairo_analysis_surface_fill (void *abstract_surface,
cairo_rectangle_int_t source_extents;
status = _cairo_pattern_get_extents (source, &source_extents);
- if (status)
+ if (unlikely (status))
return status;
is_empty = _cairo_rectangle_intersect (&extents, &source_extents);
@@ -560,7 +560,7 @@ _cairo_analysis_surface_fill (void *abstract_surface,
fill_rule,
tolerance,
&traps);
- if (status) {
+ if (unlikely (status)) {
_cairo_traps_fini (&traps);
return status;
}
@@ -622,7 +622,7 @@ _cairo_analysis_surface_show_glyphs (void *abstract_surface,
cairo_rectangle_int_t source_extents;
status = _cairo_pattern_get_extents (source, &source_extents);
- if (status)
+ if (unlikely (status))
return status;
is_empty = _cairo_rectangle_intersect (&extents, &source_extents);
@@ -635,7 +635,7 @@ _cairo_analysis_surface_show_glyphs (void *abstract_surface,
glyphs,
num_glyphs,
&glyph_extents);
- if (status)
+ if (unlikely (status))
return status;
is_empty = _cairo_rectangle_intersect (&extents, &glyph_extents);
@@ -708,7 +708,7 @@ _cairo_analysis_surface_show_text_glyphs (void *abstract_surface,
cairo_rectangle_int_t source_extents;
status = _cairo_pattern_get_extents (source, &source_extents);
- if (status)
+ if (unlikely (status))
return status;
is_empty = _cairo_rectangle_intersect (&extents, &source_extents);
@@ -721,7 +721,7 @@ _cairo_analysis_surface_show_text_glyphs (void *abstract_surface,
glyphs,
num_glyphs,
&glyph_extents);
- if (status)
+ if (unlikely (status))
return status;
is_empty = _cairo_rectangle_intersect (&extents, &glyph_extents);
@@ -746,6 +746,8 @@ static const cairo_surface_backend_t cairo_analysis_surface_backend = {
NULL, /* composite */
NULL, /* fill_rectangles */
NULL, /* composite_trapezoids */
+ NULL, /* create_span_renderer */
+ NULL, /* check_span_renderer */
NULL, /* copy_page */
NULL, /* show_page */
NULL, /* set_clip_region */
@@ -780,11 +782,11 @@ _cairo_analysis_surface_create (cairo_surface_t *target,
cairo_status_t status;
status = target->status;
- if (status)
+ if (unlikely (status))
return _cairo_surface_create_in_error (status);
surface = malloc (sizeof (cairo_analysis_surface_t));
- if (surface == NULL)
+ if (unlikely (surface == NULL))
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
/* I believe the content type here is truly arbitrary. I'm quite
@@ -961,6 +963,8 @@ static const cairo_surface_backend_t cairo_null_surface_backend = {
NULL, /* composite */
NULL, /* fill_rectangles */
NULL, /* composite_trapezoids */
+ NULL, /* create_span_renderer */
+ NULL, /* check_span_renderer */
NULL, /* copy_page */
NULL, /* show_page */
(_set_clip_region_func) _return_success, /* set_clip_region */
@@ -992,7 +996,7 @@ _cairo_null_surface_create (cairo_content_t content)
cairo_surface_t *surface;
surface = malloc (sizeof (cairo_surface_t));
- if (surface == NULL) {
+ if (unlikely (surface == NULL)) {
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
}
diff --git a/src/cairo-array.c b/src/cairo-array.c
index f38cfe3e..9c084b9e 100644
--- a/src/cairo-array.c
+++ b/src/cairo-array.c
@@ -138,7 +138,7 @@ _cairo_array_grow_by (cairo_array_t *array, unsigned int additional)
if (array->elements == NULL) {
array->elements = malloc (sizeof (char *));
- if (array->elements == NULL)
+ if (unlikely (array->elements == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
*array->elements = NULL;
@@ -148,7 +148,7 @@ _cairo_array_grow_by (cairo_array_t *array, unsigned int additional)
new_elements = _cairo_realloc_ab (*array->elements,
array->size, array->element_size);
- if (new_elements == NULL) {
+ if (unlikely (new_elements == NULL)) {
array->size = old_size;
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
@@ -279,7 +279,7 @@ _cairo_array_append_multiple (cairo_array_t *array,
assert (! array->is_snapshot);
status = _cairo_array_allocate (array, num_elements, &dest);
- if (status)
+ if (unlikely (status))
return status;
memcpy (dest, elements, num_elements * array->element_size);
@@ -310,7 +310,7 @@ _cairo_array_allocate (cairo_array_t *array,
assert (! array->is_snapshot);
status = _cairo_array_grow_by (array, num_elements);
- if (status)
+ if (unlikely (status))
return status;
assert (array->num_elements + num_elements <= array->size);
@@ -489,7 +489,7 @@ _cairo_user_data_array_set_data (cairo_user_data_array_t *array,
}
status = _cairo_array_append (array, &new_slot);
- if (status)
+ if (unlikely (status))
return status;
return CAIRO_STATUS_SUCCESS;
diff --git a/src/cairo-base85-stream.c b/src/cairo-base85-stream.c
index 4d5a4652..9d42ef48 100644
--- a/src/cairo-base85-stream.c
+++ b/src/cairo-base85-stream.c
@@ -117,7 +117,7 @@ _cairo_base85_stream_create (cairo_output_stream_t *output)
return _cairo_output_stream_create_in_error (output->status);
stream = malloc (sizeof (cairo_base85_stream_t));
- if (stream == NULL) {
+ if (unlikely (stream == NULL)) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return (cairo_output_stream_t *) &_cairo_output_stream_nil;
}
diff --git a/src/cairo-bentley-ottmann.c b/src/cairo-bentley-ottmann.c
index eca28d5b..cd150218 100644
--- a/src/cairo-bentley-ottmann.c
+++ b/src/cairo-bentley-ottmann.c
@@ -979,7 +979,7 @@ _cairo_bo_event_queue_init (cairo_bo_event_queue_t *event_queue,
sizeof (cairo_bo_event_t) +
sizeof (cairo_bo_event_t *),
sizeof (cairo_bo_event_t *));
- if (events == NULL)
+ if (unlikely (events == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
sorted_event_ptrs = (cairo_bo_event_t **) (events + num_events);
@@ -1079,8 +1079,8 @@ _cairo_bo_sweep_line_insert (cairo_bo_sweep_line_t *sweep_line,
cairo_bo_edge_t **prev_of_next, **next_of_prev;
sweep_line_elt = _cairo_skip_list_insert (&sweep_line->active_edges, &edge,
- 1 /* unique inserts*/);
- if (sweep_line_elt == NULL)
+ 1 /* unique inserts*/);
+ if (unlikely (sweep_line_elt == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
next_elt = sweep_line_elt->elt.next[0];
@@ -1659,11 +1659,10 @@ _cairo_bentley_ottmann_tessellate_polygon (cairo_traps_t *traps,
has_limits = _cairo_traps_get_limit (traps, &limit);
- if (polygon->num_edges < ARRAY_LENGTH (stack_edges)) {
- edges = stack_edges;
- } else {
+ edges = stack_edges;
+ if (polygon->num_edges > ARRAY_LENGTH (stack_edges)) {
edges = _cairo_malloc_ab (polygon->num_edges, sizeof (cairo_bo_edge_t));
- if (edges == NULL)
+ if (unlikely (edges == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
diff --git a/src/cairo-beos-surface.cpp b/src/cairo-beos-surface.cpp
index ec4aff03..e527272e 100644
--- a/src/cairo-beos-surface.cpp
+++ b/src/cairo-beos-surface.cpp
@@ -895,6 +895,8 @@ static const struct _cairo_surface_backend cairo_beos_surface_backend = {
_cairo_beos_surface_composite, /* composite */
_cairo_beos_surface_fill_rectangles,
NULL, /* composite_trapezoids */
+ NULL, /* create_span_renderer */
+ NULL, /* check_span_renderer */
NULL, /* copy_page */
NULL, /* show_page */
_cairo_beos_surface_set_clip_region,
diff --git a/src/cairo-cache.c b/src/cairo-cache.c
index f5caba4b..07c8b71f 100644
--- a/src/cairo-cache.c
+++ b/src/cairo-cache.c
@@ -53,7 +53,7 @@ _cairo_cache_init (cairo_cache_t *cache,
unsigned long max_size)
{
cache->hash_table = _cairo_hash_table_create (keys_equal);
- if (cache->hash_table == NULL)
+ if (unlikely (cache->hash_table == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
cache->entry_destroy = entry_destroy;
@@ -125,13 +125,13 @@ _cairo_cache_create (cairo_cache_keys_equal_func_t keys_equal,
cairo_cache_t *cache;
cache = malloc (sizeof (cairo_cache_t));
- if (cache == NULL) {
+ if (unlikely (cache == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
return NULL;
}
status = _cairo_cache_init (cache, keys_equal, entry_destroy, max_size);
- if (status) {
+ if (unlikely (status)) {
free (cache);
return NULL;
}
@@ -240,7 +240,7 @@ _cairo_cache_remove_random (cairo_cache_t *cache)
cairo_cache_entry_t *entry;
entry = _cairo_hash_table_random_entry (cache->hash_table, NULL);
- if (entry == NULL)
+ if (unlikely (entry == NULL))
return FALSE;
_cairo_cache_remove (cache, entry);
@@ -293,7 +293,7 @@ _cairo_cache_insert (cairo_cache_t *cache,
status = _cairo_hash_table_insert (cache->hash_table,
(cairo_hash_entry_t *) entry);
- if (status)
+ if (unlikely (status))
return status;
cache->size += entry->size;
diff --git a/src/cairo-cff-subset.c b/src/cairo-cff-subset.c
index 45be5d1c..75e1ab51 100644
--- a/src/cairo-cff-subset.c
+++ b/src/cairo-cff-subset.c
@@ -298,7 +298,7 @@ cff_index_read (cairo_array_t *index, unsigned char **ptr, unsigned char *end_pt
element.is_copy = FALSE;
element.data = data + start;
status = _cairo_array_append (index, &element);
- if (status)
+ if (unlikely (status))
return status;
start = end;
}
@@ -324,7 +324,7 @@ cff_index_write (cairo_array_t *index, cairo_array_t *output)
num_elem = _cairo_array_num_elements (index);
count = cpu_to_be16 ((uint16_t) num_elem);
status = _cairo_array_append_multiple (output, &count, 2);
- if (status)
+ if (unlikely (status))
return status;
if (num_elem == 0)
@@ -347,13 +347,13 @@ cff_index_write (cairo_array_t *index, cairo_array_t *output)
buf[0] = (unsigned char) offset_size;
status = _cairo_array_append (output, buf);
- if (status)
+ if (unlikely (status))
return status;
offset = 1;
encode_index_offset (buf, offset_size, offset);
status = _cairo_array_append_multiple (output, buf, offset_size);
- if (status)
+ if (unlikely (status))
return status;
for (i = 0; i < num_elem; i++) {
@@ -361,7 +361,7 @@ cff_index_write (cairo_array_t *index, cairo_array_t *output)
offset += element->length;
encode_index_offset (buf, offset_size, offset);
status = _cairo_array_append_multiple (output, buf, offset_size);
- if (status)
+ if (unlikely (status))
return status;
}
@@ -370,7 +370,7 @@ cff_index_write (cairo_array_t *index, cairo_array_t *output)
status = _cairo_array_append_multiple (output,
element->data,
element->length);
- if (status)
+ if (unlikely (status))
return status;
}
return CAIRO_STATUS_SUCCESS;
@@ -399,13 +399,13 @@ cff_index_append_copy (cairo_array_t *index,
element.length = length;
element.is_copy = TRUE;
element.data = malloc (element.length);
- if (element.data == NULL)
+ if (unlikely (element.data == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
memcpy (element.data, object, element.length);
status = _cairo_array_append (index, &element);
- if (status) {
+ if (unlikely (status)) {
free (element.data);
return status;
}
@@ -440,8 +440,8 @@ static cairo_status_t
cff_dict_init (cairo_hash_table_t **dict)
{
*dict = _cairo_hash_table_create (_cairo_cff_dict_equal);
- if (*dict == NULL)
- return CAIRO_STATUS_NO_MEMORY;
+ if (unlikely (*dict == NULL))
+ return _cairo_error (CAIRO_STATUS_NO_MEMORY);
return CAIRO_STATUS_SUCCESS;
}
@@ -462,12 +462,12 @@ cff_dict_create_operator (int operator,
cff_dict_operator_t *op;
op = malloc (sizeof (cff_dict_operator_t));
- if (op == NULL)
+ if (unlikely (op == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
_cairo_dict_init_key (op, operator);
op->operand = malloc (size);
- if (op->operand == NULL) {
+ if (unlikely (op->operand == NULL)) {
free (op);
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
@@ -496,7 +496,7 @@ cff_dict_read (cairo_hash_table_t *dict, unsigned char *p, int dict_size)
size = operand_length (p);
if (size != 0) {
status = _cairo_array_append_multiple (&operands, p, size);
- if (status)
+ if (unlikely (status))
goto fail;
p += size;
@@ -506,11 +506,11 @@ cff_dict_read (cairo_hash_table_t *dict, unsigned char *p, int dict_size)
_cairo_array_index (&operands, 0),
_cairo_array_num_elements (&operands),
&op);
- if (status)
+ if (unlikely (status))
goto fail;
status = _cairo_hash_table_insert (dict, &op->base);
- if (status)
+ if (unlikely (status))
goto fail;
_cairo_array_truncate (&operands, 0);
@@ -568,7 +568,7 @@ cff_dict_set_operands (cairo_hash_table_t *dict,
if (op != NULL) {
free (op->operand);
op->operand = malloc (size);
- if (op->operand == NULL)
+ if (unlikely (op->operand == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
memcpy (op->operand, operand, size);
@@ -577,11 +577,11 @@ cff_dict_set_operands (cairo_hash_table_t *dict,
else
{
status = cff_dict_create_operator (operator, operand, size, &op);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_hash_table_insert (dict, &op->base);
- if (status)
+ if (unlikely (status))
return status;
}
@@ -724,7 +724,7 @@ cairo_cff_font_read_private_dict (cairo_cff_font_t *font,
unsigned char *p;
status = cff_dict_read (private_dict, ptr, size);
- if (status)
+ if (unlikely (status))
return status;
operand = cff_dict_get_operands (private_dict, LOCAL_SUB_OP, &i);
@@ -732,13 +732,13 @@ cairo_cff_font_read_private_dict (cairo_cff_font_t *font,
decode_integer (operand, &offset);
p = ptr + offset;
status = cff_index_read (local_sub_index, &p, font->data_end);
- if (status)
+ if (unlikely (status))
return status;
/* Use maximum sized encoding to reserve space for later modification. */
end_buf = encode_integer_max (buf, 0);
status = cff_dict_set_operands (private_dict, LOCAL_SUB_OP, buf, end_buf - buf);
- if (status)
+ if (unlikely (status))
return status;
}
@@ -751,7 +751,7 @@ cairo_cff_font_read_fdselect (cairo_cff_font_t *font, unsigned char *p)
int type, num_ranges, first, last, fd, i, j;
font->fdselect = calloc (font->num_glyphs, sizeof (int));
- if (font->fdselect == NULL)
+ if (unlikely (font->fdselect == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
type = *p++;
@@ -793,37 +793,37 @@ cairo_cff_font_read_cid_fontdict (cairo_cff_font_t *font, unsigned char *ptr)
cff_index_init (&index);
status = cff_index_read (&index, &ptr, font->data_end);
- if (status)
+ if (unlikely (status))
goto fail;
font->num_fontdicts = _cairo_array_num_elements (&index);
font->fd_dict = calloc (sizeof (cairo_hash_table_t *), font->num_fontdicts);
- if (font->fd_dict == NULL) {
+ if (unlikely (font->fd_dict == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail;
}
font->fd_private_dict = calloc (sizeof (cairo_hash_table_t *), font->num_fontdicts);
- if (font->fd_private_dict == NULL) {
+ if (unlikely (font->fd_private_dict == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail;
}
font->fd_local_sub_index = calloc (sizeof (cairo_array_t), font->num_fontdicts);
- if (font->fd_local_sub_index == NULL) {
+ if (unlikely (font->fd_local_sub_index == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail;
}
for (i = 0; i < font->num_fontdicts; i++) {
status = cff_dict_init (&font->fd_dict[i]);
- if (status)
+ if (unlikely (status))
goto fail;
element = _cairo_array_index (&index, i);
status = cff_dict_read (font->fd_dict[i], element->data, element->length);
- if (status)
+ if (unlikely (status))
goto fail;
operand = cff_dict_get_operands (font->fd_dict[i], PRIVATE_OP, &size);
@@ -834,7 +834,7 @@ cairo_cff_font_read_cid_fontdict (cairo_cff_font_t *font, unsigned char *ptr)
operand = decode_integer (operand, &size);
decode_integer (operand, &offset);
status = cff_dict_init (&font->fd_private_dict[i]);
- if (status)
+ if (unlikely (status))
goto fail;
cff_index_init (&font->fd_local_sub_index[i]);
@@ -843,7 +843,7 @@ cairo_cff_font_read_cid_fontdict (cairo_cff_font_t *font, unsigned char *ptr)
&font->fd_local_sub_index[i],
font->data + offset,
size);
- if (status)
+ if (unlikely (status))
goto fail;
/* Set integer operand to max value to use max size encoding to reserve
@@ -851,7 +851,7 @@ cairo_cff_font_read_cid_fontdict (cairo_cff_font_t *font, unsigned char *ptr)
end_buf = encode_integer_max (buf, 0);
end_buf = encode_integer_max (end_buf, 0);
status = cff_dict_set_operands (font->fd_dict[i], PRIVATE_OP, buf, end_buf - buf);
- if (status)
+ if (unlikely (status))
goto fail;
}
@@ -878,12 +878,12 @@ cairo_cff_font_read_top_dict (cairo_cff_font_t *font)
cff_index_init (&index);
status = cff_index_read (&index, &font->current_ptr, font->data_end);
- if (status)
+ if (unlikely (status))
goto fail;
element = _cairo_array_index (&index, 0);
status = cff_dict_read (font->top_dict, element->data, element->length);
- if (status)
+ if (unlikely (status))
goto fail;
if (cff_dict_get_operands (font->top_dict, ROS_OP, &size) != NULL)
@@ -895,7 +895,7 @@ cairo_cff_font_read_top_dict (cairo_cff_font_t *font)
decode_integer (operand, &offset);
p = font->data + offset;
status = cff_index_read (&font->charstrings_index, &p, font->data_end);
- if (status)
+ if (unlikely (status))
goto fail;
font->num_glyphs = _cairo_array_num_elements (&font->charstrings_index);
@@ -903,13 +903,13 @@ cairo_cff_font_read_top_dict (cairo_cff_font_t *font)
operand = cff_dict_get_operands (font->top_dict, FDSELECT_OP, &size);
decode_integer (operand, &offset);
status = cairo_cff_font_read_fdselect (font, font->data + offset);
- if (status)
+ if (unlikely (status))
goto fail;
operand = cff_dict_get_operands (font->top_dict, FDARRAY_OP, &size);
decode_integer (operand, &offset);
status = cairo_cff_font_read_cid_fontdict (font, font->data + offset);
- if (status)
+ if (unlikely (status))
goto fail;
} else {
operand = cff_dict_get_operands (font->top_dict, PRIVATE_OP, &size);
@@ -920,7 +920,7 @@ cairo_cff_font_read_top_dict (cairo_cff_font_t *font)
&font->local_sub_index,
font->data + offset,
size);
- if (status)
+ if (unlikely (status))
goto fail;
}
@@ -928,22 +928,22 @@ cairo_cff_font_read_top_dict (cairo_cff_font_t *font)
end_buf = encode_integer_max (buf, 0);
status = cff_dict_set_operands (font->top_dict,
CHARSTRINGS_OP, buf, end_buf - buf);
- if (status)
+ if (unlikely (status))
goto fail;
status = cff_dict_set_operands (font->top_dict,
FDSELECT_OP, buf, end_buf - buf);
- if (status)
+ if (unlikely (status))
goto fail;
status = cff_dict_set_operands (font->top_dict,
FDARRAY_OP, buf, end_buf - buf);
- if (status)
+ if (unlikely (status))
goto fail;
status = cff_dict_set_operands (font->top_dict,
CHARSET_OP, buf, end_buf - buf);
- if (status)
+ if (unlikely (status))
goto fail;
cff_dict_remove (font->top_dict, ENCODING_OP);
@@ -991,7 +991,7 @@ cairo_cff_font_read_font (cairo_cff_font_t *font)
for (i = 0; i < ARRAY_LENGTH (font_read_funcs); i++) {
status = font_read_funcs[i] (font);
- if (status)
+ if (unlikely (status))
return status;
}
@@ -1012,26 +1012,26 @@ cairo_cff_font_set_ros_strings (cairo_cff_font_t *font)
status = cff_index_append_copy (&font->strings_subset_index,
(unsigned char *)registry,
strlen(registry));
- if (status)
+ if (unlikely (status))
return status;
sid2 = NUM_STD_STRINGS + _cairo_array_num_elements (&font->strings_subset_index);
status = cff_index_append_copy (&font->strings_subset_index,
(unsigned char *)ordering,
strlen(ordering));
- if (status)
+ if (unlikely (status))
return status;
p = encode_integer (buf, sid1);
p = encode_integer (p, sid2);
p = encode_integer (p, 0);
status = cff_dict_set_operands (font->top_dict, ROS_OP, buf, p - buf);
- if (status)
+ if (unlikely (status))
return status;
p = encode_integer (buf, font->scaled_font_subset->num_glyphs);
status = cff_dict_set_operands (font->top_dict, CIDCOUNT_OP, buf, p - buf);
- if (status)
+ if (unlikely (status))
return status;
return CAIRO_STATUS_SUCCESS;
@@ -1060,12 +1060,12 @@ cairo_cff_font_subset_dict_string(cairo_cff_font_t *font,
element = _cairo_array_index (&font->strings_index, sid - NUM_STD_STRINGS);
sid = NUM_STD_STRINGS + _cairo_array_num_elements (&font->strings_subset_index);
status = cff_index_append (&font->strings_subset_index, element->data, element->length);
- if (status)
+ if (unlikely (status))
return status;
p = encode_integer (buf, sid);
status = cff_dict_set_operands (dict, operator, buf, p - buf);
- if (status)
+ if (unlikely (status))
return status;
return CAIRO_STATUS_SUCCESS;
@@ -1092,7 +1092,7 @@ cairo_cff_font_subset_dict_strings (cairo_cff_font_t *font,
for (i = 0; i < ARRAY_LENGTH (dict_strings); i++) {
status = cairo_cff_font_subset_dict_string (font, dict, dict_strings[i]);
- if (status)
+ if (unlikely (status))
return status;
}
@@ -1112,7 +1112,7 @@ cairo_cff_font_subset_charstrings (cairo_cff_font_t *font)
status = cff_index_append (&font->charstrings_subset_index,
element->data,
element->length);
- if (status)
+ if (unlikely (status))
return status;
}
@@ -1128,19 +1128,19 @@ cairo_cff_font_subset_fontdict (cairo_cff_font_t *font)
font->fdselect_subset = calloc (font->scaled_font_subset->num_glyphs,
sizeof (int));
- if (font->fdselect_subset == NULL)
+ if (unlikely (font->fdselect_subset == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
font->fd_subset_map = calloc (font->num_fontdicts, sizeof (int));
- if (font->fd_subset_map == NULL)
+ if (unlikely (font->fd_subset_map == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
font->private_dict_offset = calloc (font->num_fontdicts, sizeof (int));
- if (font->private_dict_offset == NULL)
+ if (unlikely (font->private_dict_offset == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
reverse_map = calloc (font->num_fontdicts, sizeof (int));
- if (reverse_map == NULL)
+ if (unlikely (reverse_map == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
for (i = 0; i < font->num_fontdicts; i++)
@@ -1170,7 +1170,7 @@ cairo_cff_font_create_cid_fontdict (cairo_cff_font_t *font)
font->num_fontdicts = 1;
font->fd_dict = malloc (sizeof (cairo_hash_table_t *));
- if (font->fd_dict == NULL)
+ if (unlikely (font->fd_dict == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
if (cff_dict_init (&font->fd_dict[0])) {
@@ -1181,11 +1181,11 @@ cairo_cff_font_create_cid_fontdict (cairo_cff_font_t *font)
}
font->fd_subset_map = malloc (sizeof (int));
- if (font->fd_subset_map == NULL)
+ if (unlikely (font->fd_subset_map == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
font->private_dict_offset = malloc (sizeof (int));
- if (font->private_dict_offset == NULL)
+ if (unlikely (font->private_dict_offset == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
font->fd_subset_map[0] = 0;
@@ -1196,7 +1196,7 @@ cairo_cff_font_create_cid_fontdict (cairo_cff_font_t *font)
end_buf = encode_integer_max (buf, 0);
end_buf = encode_integer_max (end_buf, 0);
status = cff_dict_set_operands (font->fd_dict[0], PRIVATE_OP, buf, end_buf - buf);
- if (status)
+ if (unlikely (status))
return status;
return CAIRO_STATUS_SUCCESS;
@@ -1209,17 +1209,17 @@ cairo_cff_font_subset_strings (cairo_cff_font_t *font)
unsigned int i;
status = cairo_cff_font_subset_dict_strings (font, font->top_dict);
- if (status)
+ if (unlikely (status))
return status;
if (font->is_cid) {
for (i = 0; i < font->num_subset_fontdicts; i++) {
status = cairo_cff_font_subset_dict_strings (font, font->fd_dict[font->fd_subset_map[i]]);
- if (status)
+ if (unlikely (status))
return status;
status = cairo_cff_font_subset_dict_strings (font, font->fd_private_dict[font->fd_subset_map[i]]);
- if (status)
+ if (unlikely (status))
return status;
}
} else {
@@ -1235,22 +1235,22 @@ cairo_cff_font_subset_font (cairo_cff_font_t *font)
cairo_status_t status;
status = cairo_cff_font_set_ros_strings (font);
- if (status)
+ if (unlikely (status))
return status;
status = cairo_cff_font_subset_charstrings (font);
- if (status)
+ if (unlikely (status))
return status;
if (font->is_cid)
status = cairo_cff_font_subset_fontdict (font);
else
status = cairo_cff_font_create_cid_fontdict (font);
- if (status)
+ if (unlikely (status))
return status;
status = cairo_cff_font_subset_strings (font);
- if (status)
+ if (unlikely (status))
return status;
return status;
@@ -1298,11 +1298,11 @@ cairo_cff_font_write_name (cairo_cff_font_t *font)
status = cff_index_append_copy (&index,
(unsigned char *) font->subset_font_name,
strlen(font->subset_font_name));
- if (status)
+ if (unlikely (status))
goto FAIL;
status = cff_index_write (&index, &font->output);
- if (status)
+ if (unlikely (status))
goto FAIL;
FAIL:
@@ -1326,27 +1326,27 @@ cairo_cff_font_write_top_dict (cairo_cff_font_t *font)
count = cpu_to_be16 (1);
status = _cairo_array_append_multiple (&font->output, &count, 2);
- if (status)
+ if (unlikely (status))
return status;
buf[0] = offset_size;
status = _cairo_array_append (&font->output, buf);
- if (status)
+ if (unlikely (status))
return status;
encode_index_offset (buf, offset_size, 1);
status = _cairo_array_append_multiple (&font->output, buf, offset_size);
- if (status)
+ if (unlikely (status))
return status;
/* Reserve space for last element of offset array and update after
* dict is written */
offset_index = _cairo_array_num_elements (&font->output);
status = _cairo_array_append_multiple (&font->output, buf, offset_size);
- if (status)
+ if (unlikely (status))
return status;
dict_start = _cairo_array_num_elements (&font->output);
status = cff_dict_write (font->top_dict, &font->output);
- if (status)
+ if (unlikely (status))
return status;
dict_size = _cairo_array_num_elements (&font->output) - dict_start;
@@ -1381,13 +1381,13 @@ cairo_cff_font_write_fdselect (cairo_cff_font_t *font)
if (font->is_cid) {
data = 0;
status = _cairo_array_append (&font->output, &data);
- if (status)
+ if (unlikely (status))
return status;
for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) {
data = font->fdselect_subset[i];
status = _cairo_array_append (&font->output, &data);
- if (status)
+ if (unlikely (status))
return status;
}
} else {
@@ -1395,7 +1395,7 @@ cairo_cff_font_write_fdselect (cairo_cff_font_t *font)
uint16_t word;
status = _cairo_array_grow_by (&font->output, 9);
- if (status)
+ if (unlikely (status))
return status;
byte = 3;
@@ -1431,7 +1431,7 @@ cairo_cff_font_write_charset (cairo_cff_font_t *font)
cairo_cff_font_set_topdict_operator_to_cur_pos (font, CHARSET_OP);
status = _cairo_array_grow_by (&font->output, 5);
- if (status)
+ if (unlikely (status))
return status;
byte = 2;
@@ -1470,22 +1470,22 @@ cairo_cff_font_write_cid_fontdict (cairo_cff_font_t *font)
cairo_cff_font_set_topdict_operator_to_cur_pos (font, FDARRAY_OP);
count = cpu_to_be16 (font->num_subset_fontdicts);
status = _cairo_array_append_multiple (&font->output, &count, sizeof (uint16_t));
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_array_append (&font->output, &offset_size);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_array_allocate (&font->output,
(font->num_subset_fontdicts + 1)*offset_size,
(void **) &offset_array);
- if (status)
+ if (unlikely (status))
return status;
offset_base = _cairo_array_num_elements (&font->output) - 1;
*offset_array++ = cpu_to_be32(1);
for (i = 0; i < font->num_subset_fontdicts; i++) {
status = cff_dict_write (font->fd_dict[font->fd_subset_map[i]],
&font->output);
- if (status)
+ if (unlikely (status))
return status;
*offset_array++ = cpu_to_be32(_cairo_array_num_elements (&font->output) - offset_base);
}
@@ -1509,7 +1509,7 @@ cairo_cff_font_write_private_dict (cairo_cff_font_t *font,
/* Write private dict and update offset and size in top dict */
font->private_dict_offset[dict_num] = _cairo_array_num_elements (&font->output);
status = cff_dict_write (private_dict, &font->output);
- if (status)
+ if (unlikely (status))
return status;
size = _cairo_array_num_elements (&font->output) - font->private_dict_offset[dict_num];
@@ -1548,7 +1548,7 @@ cairo_cff_font_write_local_sub (cairo_cff_font_t *font,
p = _cairo_array_index (&font->output, offset);
memcpy (p, buf, buf_end - buf);
status = cff_index_write (local_sub_index, &font->output);
- if (status)
+ if (unlikely (status))
return status;
}
@@ -1569,7 +1569,7 @@ cairo_cff_font_write_cid_private_dict_and_local_sub (cairo_cff_font_t *font)
i,
font->fd_dict[font->fd_subset_map[i]],
font->fd_private_dict[font->fd_subset_map[i]]);
- if (status)
+ if (unlikely (status))
return status;
}
@@ -1579,7 +1579,7 @@ cairo_cff_font_write_cid_private_dict_and_local_sub (cairo_cff_font_t *font)
i,
font->fd_private_dict[font->fd_subset_map[i]],
&font->fd_local_sub_index[font->fd_subset_map[i]]);
- if (status)
+ if (unlikely (status))
return status;
}
} else {
@@ -1587,14 +1587,14 @@ cairo_cff_font_write_cid_private_dict_and_local_sub (cairo_cff_font_t *font)
0,
font->fd_dict[0],
font->private_dict);
- if (status)
+ if (unlikely (status))
return status;
status = cairo_cff_font_write_local_sub (font,
0,
font->private_dict,
&font->local_sub_index);
- if (status)
+ if (unlikely (status))
return status;
}
@@ -1625,7 +1625,7 @@ cairo_cff_font_write_subset (cairo_cff_font_t *font)
for (i = 0; i < ARRAY_LENGTH (font_write_funcs); i++) {
status = font_write_funcs[i] (font);
- if (status)
+ if (unlikely (status))
return status;
}
@@ -1640,15 +1640,15 @@ cairo_cff_font_generate (cairo_cff_font_t *font,
cairo_int_status_t status;
status = cairo_cff_font_read_font (font);
- if (status)
+ if (unlikely (status))
return status;
status = cairo_cff_font_subset_font (font);
- if (status)
+ if (unlikely (status))
return status;
status = cairo_cff_font_write_subset (font);
- if (status)
+ if (unlikely (status))
return status;
*data = _cairo_array_index (&font->output, 0);
@@ -1674,7 +1674,7 @@ 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_hhea, 0,
(unsigned char*) &hhea, &size);
- if (status)
+ if (unlikely (status))
return status;
num_hmetrics = be16_to_cpu (hhea.num_hmetrics);
@@ -1687,7 +1687,7 @@ cairo_cff_font_create_set_widths (cairo_cff_font_t *font)
TT_TAG_hmtx,
glyph_index * long_entry_size,
buf, &short_entry_size);
- if (status)
+ if (unlikely (status))
return status;
}
else
@@ -1696,7 +1696,7 @@ cairo_cff_font_create_set_widths (cairo_cff_font_t *font)
TT_TAG_hmtx,
(num_hmetrics - 1) * long_entry_size,
buf, &short_entry_size);
- if (status)
+ if (unlikely (status))
return status;
}
font->widths[i] = be16_to_cpu (*((int16_t*)buf));
@@ -1727,47 +1727,47 @@ _cairo_cff_font_create (cairo_scaled_font_subset_t *scaled_font_subset,
data_length = 0;
status = backend->load_truetype_table( scaled_font_subset->scaled_font,
TT_TAG_CFF, 0, NULL, &data_length);
- if (status)
+ if (unlikely (status))
return status;
size = sizeof (tt_head_t);
status = backend->load_truetype_table (scaled_font_subset->scaled_font,
TT_TAG_head, 0,
(unsigned char *) &head, &size);
- if (status)
+ if (unlikely (status))
return status;
size = sizeof (tt_hhea_t);
status = backend->load_truetype_table (scaled_font_subset->scaled_font,
TT_TAG_hhea, 0,
(unsigned char *) &hhea, &size);
- if (status)
+ if (unlikely (status))
return status;
size = 0;
status = backend->load_truetype_table (scaled_font_subset->scaled_font,
TT_TAG_hmtx, 0, NULL, &size);
- if (status)
+ if (unlikely (status))
return status;
size = 0;
status = backend->load_truetype_table (scaled_font_subset->scaled_font,
TT_TAG_name, 0, NULL, &size);
- if (status)
+ if (unlikely (status))
return status;
name = malloc (size);
- if (name == NULL)
+ if (unlikely (name == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
status = backend->load_truetype_table (scaled_font_subset->scaled_font,
TT_TAG_name, 0,
(unsigned char *) name, &size);
- if (status)
+ if (unlikely (status))
goto fail1;
font = malloc (sizeof (cairo_cff_font_t));
- if (font == NULL) {
+ if (unlikely (font == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail1;
}
@@ -1777,11 +1777,11 @@ _cairo_cff_font_create (cairo_scaled_font_subset_t *scaled_font_subset,
_cairo_array_init (&font->output, sizeof (char));
status = _cairo_array_grow_by (&font->output, 4096);
- if (status)
+ if (unlikely (status))
goto fail2;
font->subset_font_name = strdup (subset_name);
- if (font->subset_font_name == NULL) {
+ if (unlikely (font->subset_font_name == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail2;
}
@@ -1817,7 +1817,7 @@ _cairo_cff_font_create (cairo_scaled_font_subset_t *scaled_font_subset,
if (font->font_name == NULL) {
font->font_name = malloc (30);
- if (font->font_name == NULL) {
+ if (unlikely (font->font_name == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail3;
}
@@ -1834,35 +1834,35 @@ _cairo_cff_font_create (cairo_scaled_font_subset_t *scaled_font_subset,
font->font_name[i] = '\0';
font->widths = calloc (font->scaled_font_subset->num_glyphs, sizeof (int));
- if (font->widths == NULL) {
+ if (unlikely (font->widths == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail4;
}
status = cairo_cff_font_create_set_widths (font);
- if (status)
+ if (unlikely (status))
goto fail5;
font->data_length = data_length;
font->data = malloc (data_length);
- if (font->data == NULL) {
+ if (unlikely (font->data == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail5;
}
status = font->backend->load_truetype_table ( font->scaled_font_subset->scaled_font,
TT_TAG_CFF, 0, font->data,
&font->data_length);
- if (status)
+ if (unlikely (status))
goto fail6;
font->data_end = font->data + font->data_length;
status = cff_dict_init (&font->top_dict);
- if (status)
+ if (unlikely (status))
goto fail6;
status = cff_dict_init (&font->private_dict);
- if (status)
+ if (unlikely (status))
goto fail7;
cff_index_init (&font->strings_index);
@@ -1971,21 +1971,21 @@ _cairo_cff_subset_init (cairo_cff_subset_t *cff_subset,
unsigned int i;
status = _cairo_cff_font_create (font_subset, &font, subset_name);
- if (status)
+ if (unlikely (status))
return status;
status = cairo_cff_font_generate (font, &data, &length);
- if (status)
+ if (unlikely (status))
goto fail1;
cff_subset->base_font = strdup (font->font_name);
- if (cff_subset->base_font == NULL) {
+ if (unlikely (cff_subset->base_font == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail1;
}
cff_subset->widths = calloc (sizeof (int), font->scaled_font_subset->num_glyphs);
- if (cff_subset->widths == NULL) {
+ if (unlikely (cff_subset->widths == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail2;
}
@@ -2000,7 +2000,7 @@ _cairo_cff_subset_init (cairo_cff_subset_t *cff_subset,
cff_subset->descent = font->descent;
cff_subset->data = malloc (length);
- if (cff_subset->data == NULL) {
+ if (unlikely (cff_subset->data == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail3;
}
@@ -2039,7 +2039,7 @@ _cairo_cff_font_fallback_create (cairo_scaled_font_subset_t *scaled_font_subset
cairo_cff_font_t *font;
font = malloc (sizeof (cairo_cff_font_t));
- if (font == NULL)
+ if (unlikely (font == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
font->backend = NULL;
@@ -2047,17 +2047,17 @@ _cairo_cff_font_fallback_create (cairo_scaled_font_subset_t *scaled_font_subset
_cairo_array_init (&font->output, sizeof (char));
status = _cairo_array_grow_by (&font->output, 4096);
- if (status)
+ if (unlikely (status))
goto fail1;
font->subset_font_name = strdup (subset_name);
- if (font->subset_font_name == NULL) {
+ if (unlikely (font->subset_font_name == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail1;
}
font->font_name = strdup (subset_name);
- if (font->subset_font_name == NULL) {
+ if (unlikely (font->subset_font_name == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail2;
}
@@ -2070,7 +2070,7 @@ _cairo_cff_font_fallback_create (cairo_scaled_font_subset_t *scaled_font_subset
font->descent = 0;
font->widths = calloc (font->scaled_font_subset->num_glyphs, sizeof (int));
- if (font->widths == NULL) {
+ if (unlikely (font->widths == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail3;
}
@@ -2080,11 +2080,11 @@ _cairo_cff_font_fallback_create (cairo_scaled_font_subset_t *scaled_font_subset
font->data_end = NULL;
status = cff_dict_init (&font->top_dict);
- if (status)
+ if (unlikely (status))
goto fail4;
status = cff_dict_init (&font->private_dict);
- if (status)
+ if (unlikely (status))
goto fail5;
cff_index_init (&font->strings_index);
@@ -2147,37 +2147,37 @@ cairo_cff_font_fallback_generate (cairo_cff_font_t *font,
end_buf = encode_integer (end_buf, type2_subset->y_max);
status = cff_dict_set_operands (font->top_dict,
FONTBBOX_OP, buf, end_buf - buf);
- if (status)
+ if (unlikely (status))
return status;
end_buf = encode_integer_max (buf, 0);
status = cff_dict_set_operands (font->top_dict,
CHARSTRINGS_OP, buf, end_buf - buf);
- if (status)
+ if (unlikely (status))
return status;
status = cff_dict_set_operands (font->top_dict,
FDSELECT_OP, buf, end_buf - buf);
- if (status)
+ if (unlikely (status))
return status;
status = cff_dict_set_operands (font->top_dict,
FDARRAY_OP, buf, end_buf - buf);
- if (status)
+ if (unlikely (status))
return status;
status = cff_dict_set_operands (font->top_dict,
CHARSET_OP, buf, end_buf - buf);
- if (status)
+ if (unlikely (status))
return status;
status = cairo_cff_font_set_ros_strings (font);
- if (status)
+ if (unlikely (status))
return status;
/* Create CID FD dictionary */
status = cairo_cff_font_create_cid_fontdict (font);
- if (status)
+ if (unlikely (status))
return status;
/* Create charstrings */
@@ -2188,12 +2188,12 @@ cairo_cff_font_fallback_generate (cairo_cff_font_t *font,
_cairo_array_index (charstring, 0),
_cairo_array_num_elements (charstring));
- if (status)
+ if (unlikely (status))
return status;
}
status = cairo_cff_font_write_subset (font);
- if (status)
+ if (unlikely (status))
return status;
*data = _cairo_array_index (&font->output, 0);
@@ -2215,25 +2215,25 @@ _cairo_cff_fallback_init (cairo_cff_subset_t *cff_subset,
cairo_type2_charstrings_t type2_subset;
status = _cairo_cff_font_fallback_create (font_subset, &font, subset_name);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_type2_charstrings_init (&type2_subset, font_subset);
- if (status)
+ if (unlikely (status))
goto fail1;
status = cairo_cff_font_fallback_generate (font, &type2_subset, &data, &length);
- if (status)
+ if (unlikely (status))
goto fail2;
cff_subset->base_font = strdup (font->font_name);
- if (cff_subset->base_font == NULL) {
+ if (unlikely (cff_subset->base_font == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail2;
}
cff_subset->widths = calloc (sizeof (int), font->scaled_font_subset->num_glyphs);
- if (cff_subset->widths == NULL) {
+ if (unlikely (cff_subset->widths == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail3;
}
@@ -2248,7 +2248,7 @@ _cairo_cff_fallback_init (cairo_cff_subset_t *cff_subset,
cff_subset->descent = type2_subset.y_min;
cff_subset->data = malloc (length);
- if (cff_subset->data == NULL) {
+ if (unlikely (cff_subset->data == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail4;
}
diff --git a/src/cairo-clip.c b/src/cairo-clip.c
index ce2a2409..cd423a44 100644
--- a/src/cairo-clip.c
+++ b/src/cairo-clip.c
@@ -88,7 +88,7 @@ _cairo_clip_init_copy (cairo_clip_t *clip, cairo_clip_t *other)
cairo_status_t status;
status = _cairo_region_copy (&clip->region, &other->region);
- if (status) {
+ if (unlikely (status)) {
_cairo_region_fini (&clip->region);
cairo_surface_destroy (clip->surface);
return status;
@@ -174,7 +174,7 @@ _cairo_clip_intersect_to_rectangle (cairo_clip_t *clip,
if (clip->path) {
status = _cairo_clip_path_intersect_to_rectangle (clip->path,
rectangle);
- if (status)
+ if (unlikely (status))
return status;
}
@@ -191,7 +191,7 @@ _cairo_clip_intersect_to_rectangle (cairo_clip_t *clip,
_cairo_region_fini (&intersection);
- if (status)
+ if (unlikely (status))
return status;
}
@@ -228,7 +228,7 @@ _cairo_clip_intersect_to_region (cairo_clip_t *clip,
if (clip->has_region) {
status = _cairo_region_intersect (region, &clip->region, region);
- if (status)
+ if (unlikely (status))
return status;
}
@@ -241,7 +241,7 @@ _cairo_clip_intersect_to_region (cairo_clip_t *clip,
_cairo_region_fini (&clip_rect);
- if (status)
+ if (unlikely (status))
return status;
}
@@ -298,11 +298,11 @@ _cairo_clip_intersect_path (cairo_clip_t *clip,
return CAIRO_INT_STATUS_UNSUPPORTED;
clip_path = malloc (sizeof (cairo_clip_path_t));
- if (clip_path == NULL)
+ if (unlikely (clip_path == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
status = _cairo_path_fixed_init_copy (&clip_path->path, path);
- if (status) {
+ if (unlikely (status)) {
free (clip_path);
return status;
}
@@ -362,7 +362,6 @@ _cairo_clip_intersect_region (cairo_clip_t *clip,
return CAIRO_INT_STATUS_UNSUPPORTED;
status = _cairo_traps_extract_region (traps, &region);
-
if (status)
return status;
@@ -492,7 +491,7 @@ _cairo_clip_intersect_mask (cairo_clip_t *clip,
_cairo_pattern_fini (&pattern.base);
- if (status) {
+ if (unlikely (status)) {
cairo_surface_destroy (surface);
return status;
}
@@ -517,7 +516,7 @@ _cairo_clip_intersect_mask (cairo_clip_t *clip,
_cairo_pattern_fini (&pattern.base);
- if (status) {
+ if (unlikely (status)) {
cairo_surface_destroy (surface);
return status;
}
@@ -535,6 +534,133 @@ _cairo_clip_intersect_mask (cairo_clip_t *clip,
return status;
}
+static cairo_status_t
+_cairo_clip_intersect_mask_using_spans (cairo_clip_t *clip,
+ cairo_path_fixed_t *path,
+ cairo_fill_rule_t fill_rule,
+ double tolerance,
+ cairo_antialias_t antialias,
+ cairo_surface_t *target)
+{
+ cairo_span_renderer_t *renderer = NULL;
+ cairo_pattern_union_t pattern;
+ cairo_rectangle_int_t surface_rect;
+ cairo_surface_t *surface = NULL;
+ cairo_status_t status;
+ cairo_operator_t op;
+ cairo_composite_rectangles_t rects;
+
+ if (clip->all_clipped)
+ return CAIRO_STATUS_SUCCESS;
+
+ _cairo_pattern_init_solid (&pattern.solid, CAIRO_COLOR_WHITE,
+ CAIRO_CONTENT_COLOR);
+
+ /* If we have a clip surface we're going to use IN to combine our
+ * new clip with the old clip. The ADD is done to a transparent
+ * surface, as that's a fast way of doing it currently. We should
+ * really be using SOURCE instead, but _cairo_surface_composite()
+ * checks that it's not called with SOURCE or DEST. */
+ op = clip->surface ? CAIRO_OPERATOR_IN : CAIRO_OPERATOR_ADD;
+
+ /* Test if the target can composite spans. We're going to assume
+ * this is a good indicator of whether a similar surface is going
+ * to be able to composite spans too. */
+ if ( !_cairo_surface_check_span_renderer (op,
+ &pattern.base,
+ target,
+ antialias,
+ NULL))
+ {
+ status = CAIRO_INT_STATUS_UNSUPPORTED;
+ goto BAIL;
+ }
+
+ /* We'll create a new surface the size of the intersection of the
+ * old mask surface and the extents of the new clip path. */
+ {
+ cairo_rectangle_int_t target_rect;
+
+ _cairo_path_fixed_approximate_extents (path, &surface_rect);
+
+ if (clip->surface != NULL &&
+ !_cairo_rectangle_intersect (&surface_rect, &clip->surface_rect))
+ goto SUCCESS;
+
+ status = _cairo_surface_get_extents (target, &target_rect);
+ if (status != CAIRO_STATUS_SUCCESS &&
+ !_cairo_rectangle_intersect (&surface_rect, &target_rect))
+ goto SUCCESS;
+ }
+
+ /* Make the new mask surface and optionally initialise it from the
+ * previous clip if we have one. */
+ surface = _cairo_surface_create_similar_solid (target,
+ CAIRO_CONTENT_ALPHA,
+ surface_rect.width,
+ surface_rect.height,
+ CAIRO_COLOR_TRANSPARENT);
+ if (surface->status) {
+ _cairo_pattern_fini (&pattern.base);
+ return surface->status;
+ }
+
+ if (clip->surface) {
+ cairo_surface_pattern_t old_clip;
+ _cairo_pattern_init_for_surface (&old_clip, clip->surface);
+ status = _cairo_surface_composite (CAIRO_OPERATOR_ADD,
+ &old_clip.base,
+ NULL,
+ surface,
+ surface_rect.x - clip->surface_rect.x,
+ surface_rect.y - clip->surface_rect.y,
+ 0, 0,
+ 0, 0,
+ surface_rect.width,
+ surface_rect.height);
+ _cairo_pattern_fini (&old_clip.base);
+ if (status)
+ goto BAIL;
+ }
+
+ _cairo_composite_rectangles_init (&rects,
+ surface_rect.x,
+ surface_rect.y,
+ surface_rect.width,
+ surface_rect.height);
+ rects.dst.x = 0;
+ rects.dst.y = 0;
+
+ /* Render the new clipping path into the new mask surface. We've
+ * chosen op to either combine the new clip path with the existing
+ * clip mask (if there is one) or just render it. */
+ status =_cairo_path_fixed_fill_using_spans (op, &pattern.base,
+ path, surface,
+ fill_rule, tolerance,
+ antialias, &rects);
+ if (status)
+ goto BAIL;
+
+ SUCCESS:
+ if (clip->surface != NULL)
+ cairo_surface_destroy (clip->surface);
+ clip->surface = surface;
+ clip->surface_rect = surface_rect;
+ clip->serial = _cairo_surface_allocate_clip_serial (target);
+ surface = NULL;
+
+ if (surface_rect.width == 0 || surface_rect.height == 0)
+ _cairo_clip_set_all_clipped (clip, target);
+
+ BAIL:
+ if (renderer)
+ renderer->destroy(renderer);
+ if (surface)
+ cairo_surface_destroy (surface);
+ _cairo_pattern_fini (&pattern.base);
+ return status;
+}
+
cairo_status_t
_cairo_clip_clip (cairo_clip_t *clip,
cairo_path_fixed_t *path,
@@ -546,6 +672,7 @@ _cairo_clip_clip (cairo_clip_t *clip,
cairo_status_t status;
cairo_rectangle_int_t rectangle;
cairo_traps_t traps;
+ cairo_box_t ignored_box;
if (clip->all_clipped)
return CAIRO_STATUS_SUCCESS;
@@ -565,6 +692,18 @@ _cairo_clip_clip (cairo_clip_t *clip,
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
return status;
+ /* TODO: allow ANTIALIAS_NONE when we have a mono scan converter
+ * again. */
+ if (antialias != CAIRO_ANTIALIAS_NONE &&
+ !_cairo_path_fixed_is_box (path, &ignored_box) &&
+ !_cairo_path_fixed_is_region (path))
+ {
+ status = _cairo_clip_intersect_mask_using_spans (
+ clip, path, fill_rule, tolerance, antialias, target);
+ if (status != CAIRO_INT_STATUS_UNSUPPORTED)
+ return status;
+ }
+
_cairo_traps_init (&traps);
/* Limit the traps to the target surface
@@ -581,7 +720,7 @@ _cairo_clip_clip (cairo_clip_t *clip,
fill_rule,
tolerance,
&traps);
- if (status)
+ if (unlikely (status))
goto bail;
status = _cairo_clip_intersect_region (clip, &traps, target);
@@ -664,7 +803,7 @@ _cairo_clip_init_deep_copy (cairo_clip_t *clip,
} else {
if (other->has_region) {
status = _cairo_region_copy (&clip->region, &other->region);
- if (status)
+ if (unlikely (status))
goto BAIL;
clip->has_region = TRUE;
@@ -679,7 +818,7 @@ _cairo_clip_init_deep_copy (cairo_clip_t *clip,
other->surface_rect.height,
&dx, &dy,
&clip->surface);
- if (status)
+ if (unlikely (status))
goto BAIL;
clip->surface_rect = other->surface_rect;
@@ -760,7 +899,7 @@ _cairo_clip_copy_rectangle_list (cairo_clip_t *clip, cairo_gstate_t *gstate)
if (n_boxes) {
rectangles = _cairo_malloc_ab (n_boxes, sizeof (cairo_rectangle_t));
- if (rectangles == NULL) {
+ if (unlikely (rectangles == NULL)) {
_cairo_region_boxes_fini (&clip->region, boxes);
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return (cairo_rectangle_list_t*) &_cairo_rectangles_nil;
@@ -790,7 +929,7 @@ _cairo_clip_copy_rectangle_list (cairo_clip_t *clip, cairo_gstate_t *gstate)
n_boxes = 1;
rectangles = malloc(sizeof (cairo_rectangle_t));
- if (rectangles == NULL) {
+ if (unlikely (rectangles == NULL)) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return (cairo_rectangle_list_t*) &_cairo_rectangles_nil;
}
@@ -806,7 +945,7 @@ _cairo_clip_copy_rectangle_list (cairo_clip_t *clip, cairo_gstate_t *gstate)
DONE:
list = malloc (sizeof (cairo_rectangle_list_t));
- if (list == NULL) {
+ if (unlikely (list == NULL)) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
free (rectangles);
return (cairo_rectangle_list_t*) &_cairo_rectangles_nil;
diff --git a/src/cairo-deflate-stream.c b/src/cairo-deflate-stream.c
index 3bb884ca..863189f4 100644
--- a/src/cairo-deflate-stream.c
+++ b/src/cairo-deflate-stream.c
@@ -121,7 +121,7 @@ _cairo_deflate_stream_create (cairo_output_stream_t *output)
return _cairo_output_stream_create_in_error (output->status);
stream = malloc (sizeof (cairo_deflate_stream_t));
- if (stream == NULL) {
+ if (unlikely (stream == NULL)) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return (cairo_output_stream_t *) &_cairo_output_stream_nil;
}
diff --git a/src/cairo-directfb-surface.c b/src/cairo-directfb-surface.c
index 8cbd3bcd..c31cf62c 100644
--- a/src/cairo-directfb-surface.c
+++ b/src/cairo-directfb-surface.c
@@ -455,7 +455,7 @@ _cairo_directfb_surface_create_similar (void *abstract_src,
format = _cairo_format_from_content (content);
surface = calloc (1, sizeof (cairo_directfb_surface_t));
- if (surface == NULL)
+ if (unlikely (surface == NULL))
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
surface->dfb = source->dfb;
@@ -549,6 +549,7 @@ _cairo_directfb_surface_release_source_image (void *abstract_su
cairo_image_surface_t *image,
void *image_extra)
{
+ cairo_directfb_surface_t *surface = abstract_surface;
IDirectFBSurface *buffer = image_extra;
D_DEBUG_AT (CairoDFB_Acquire,
@@ -1815,6 +1816,8 @@ _cairo_directfb_surface_backend = {
#else
NULL,/*composite_trapezoids*/
#endif
+ NULL, /* create_span_renderer */
+ NULL, /* check_span_renderer */
NULL, /* copy_page */
NULL, /* show_page */
_cairo_directfb_surface_set_clip_region,/* set_clip_region */
diff --git a/src/cairo-font-face.c b/src/cairo-font-face.c
index eb4921e3..a78c2aab 100644
--- a/src/cairo-font-face.c
+++ b/src/cairo-font-face.c
@@ -398,7 +398,7 @@ _cairo_toy_font_face_init (cairo_toy_font_face_t *font_face,
char *family_copy;
family_copy = strdup (family);
- if (family_copy == NULL)
+ if (unlikely (family_copy == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
_cairo_toy_font_face_init_key (font_face, family_copy,
@@ -467,10 +467,12 @@ cairo_toy_font_face_create (const char *family,
/* Make sure we've got valid UTF-8 for the family */
status = _cairo_utf8_to_ucs4 (family, -1, NULL, NULL);
- if (status == CAIRO_STATUS_INVALID_STRING)
- return (cairo_font_face_t*) &_cairo_font_face_invalid_string;
- else if (status)
+ if (unlikely (status)) {
+ if (status == CAIRO_STATUS_INVALID_STRING)
+ return (cairo_font_face_t*) &_cairo_font_face_invalid_string;
+
return (cairo_font_face_t*) &_cairo_font_face_nil;
+ }
switch (slant) {
case CAIRO_FONT_SLANT_NORMAL:
@@ -493,7 +495,7 @@ cairo_toy_font_face_create (const char *family,
family = CAIRO_FONT_FAMILY_DEFAULT;
hash_table = _cairo_toy_font_face_hash_table_lock ();
- if (hash_table == NULL)
+ if (unlikely (hash_table == NULL))
goto UNWIND;
_cairo_toy_font_face_init_key (&key, family, slant, weight);
@@ -517,17 +519,17 @@ cairo_toy_font_face_create (const char *family,
/* Otherwise create it and insert into hash table. */
font_face = malloc (sizeof (cairo_toy_font_face_t));
- if (font_face == NULL) {
+ if (unlikely (font_face == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto UNWIND_HASH_TABLE_LOCK;
}
status = _cairo_toy_font_face_init (font_face, family, slant, weight);
- if (status)
+ if (unlikely (status))
goto UNWIND_FONT_FACE_MALLOC;
status = _cairo_hash_table_insert (hash_table, &font_face->base.hash_entry);
- if (status)
+ if (unlikely (status))
goto UNWIND_FONT_FACE_INIT;
_cairo_toy_font_face_hash_table_unlock ();
@@ -614,7 +616,7 @@ _cairo_toy_font_face_scaled_font_create (void *abstract_font_face
return font_face->base.status;
status = cairo_font_options_status ((cairo_font_options_t *) options);
- if (status)
+ if (unlikely (status))
return status;
if (CAIRO_SCALED_FONT_BACKEND_DEFAULT != &_cairo_user_scaled_font_backend &&
diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c
index 4245448e..773f6ea0 100644
--- a/src/cairo-ft-font.c
+++ b/src/cairo-ft-font.c
@@ -182,7 +182,7 @@ _cairo_ft_unscaled_font_map_create (void)
assert (cairo_ft_unscaled_font_map == NULL);
font_map = malloc (sizeof (cairo_ft_unscaled_font_map_t));
- if (font_map == NULL) {
+ if (unlikely (font_map == NULL)) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
goto FAIL;
}
@@ -190,7 +190,7 @@ _cairo_ft_unscaled_font_map_create (void)
font_map->hash_table =
_cairo_hash_table_create (_cairo_ft_unscaled_font_keys_equal);
- if (font_map->hash_table == NULL)
+ if (unlikely (font_map->hash_table == NULL))
goto FAIL;
if (FT_Init_FreeType (&font_map->ft_library))
@@ -261,7 +261,7 @@ _cairo_ft_unscaled_font_map_lock (void)
{
_cairo_ft_unscaled_font_map_create ();
- if (cairo_ft_unscaled_font_map == NULL) {
+ if (unlikely (cairo_ft_unscaled_font_map == NULL)) {
CAIRO_MUTEX_UNLOCK (_cairo_ft_unscaled_font_map_mutex);
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return NULL;
@@ -340,8 +340,9 @@ _cairo_ft_unscaled_font_init (cairo_ft_unscaled_font_t *unscaled,
unscaled->face = NULL;
filename_copy = strdup (filename);
- if (filename_copy == NULL)
+ if (unlikely (filename_copy == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
_cairo_ft_unscaled_font_init_key (unscaled, FALSE, filename_copy, id, NULL);
}
@@ -416,7 +417,7 @@ _cairo_ft_unscaled_font_create_internal (cairo_bool_t from_face,
cairo_status_t status;
font_map = _cairo_ft_unscaled_font_map_lock ();
- if (font_map == NULL)
+ if (unlikely (font_map == NULL))
goto UNWIND;
_cairo_ft_unscaled_font_init_key (&key, from_face, filename, id, font_face);
@@ -432,18 +433,18 @@ _cairo_ft_unscaled_font_create_internal (cairo_bool_t from_face,
/* Otherwise create it and insert into hash table. */
unscaled = malloc (sizeof (cairo_ft_unscaled_font_t));
- if (unscaled == NULL) {
+ if (unlikely (unscaled == NULL)) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
goto UNWIND_FONT_MAP_LOCK;
}
status = _cairo_ft_unscaled_font_init (unscaled, from_face, filename, id, font_face);
- if (status)
+ if (unlikely (status))
goto UNWIND_UNSCALED_MALLOC;
status = _cairo_hash_table_insert (font_map->hash_table,
&unscaled->base.hash_entry);
- if (status)
+ if (unlikely (status))
goto UNWIND_UNSCALED_FONT_INIT;
_cairo_ft_unscaled_font_map_unlock ();
@@ -621,7 +622,7 @@ _compute_transform (cairo_ft_font_transform_t *sf,
status = _cairo_matrix_compute_basis_scale_factors (scale,
&x_scale, &y_scale,
1);
- if (status)
+ if (unlikely (status))
return status;
/* FreeType docs say this about x_scale and y_scale:
@@ -671,7 +672,7 @@ _cairo_ft_unscaled_font_set_scale (cairo_ft_unscaled_font_t *unscaled,
unscaled->current_scale = *scale;
status = _compute_transform (&sf, scale);
- if (status)
+ if (unlikely (status))
return status;
unscaled->x_scale = sf.x_scale;
@@ -874,7 +875,7 @@ _get_bitmap_surface (FT_Bitmap *bitmap,
stride = bitmap->pitch;
stride_rgba = (width_rgba * 4 + 3) & ~3;
data_rgba = calloc (stride_rgba, height);
- if (data_rgba == NULL) {
+ if (unlikely (data_rgba == NULL)) {
if (own_buffer)
free (bitmap->buffer);
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
@@ -1073,7 +1074,7 @@ _render_glyph_outline (FT_Face face,
bitmap.width = width * hmul;
bitmap.rows = height * vmul;
bitmap.buffer = calloc (stride, bitmap.rows);
- if (bitmap.buffer == NULL)
+ if (unlikely (bitmap.buffer == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
FT_Outline_Translate (outline, -cbox.xMin*hmul, -cbox.yMin*vmul);
@@ -1084,7 +1085,7 @@ _render_glyph_outline (FT_Face face,
}
status = _get_bitmap_surface (&bitmap, TRUE, font_options, surface);
- if (status)
+ if (unlikely (status))
return status;
}
@@ -1125,7 +1126,7 @@ _render_glyph_bitmap (FT_Face face,
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
status = _get_bitmap_surface (&glyphslot->bitmap, FALSE, font_options, surface);
- if (status)
+ if (unlikely (status))
return status;
/*
@@ -1212,13 +1213,13 @@ _transform_glyph_bitmap (cairo_matrix_t * shape,
transformed_to_original = original_to_transformed;
status = cairo_matrix_invert (&transformed_to_original);
- if (status)
+ if (unlikely (status))
return status;
/* We need to pad out the width to 32-bit intervals for cairo-xlib-surface.c */
width = (width + 3) & ~3;
image = cairo_image_surface_create (CAIRO_FORMAT_A8, width, height);
- if (image->status)
+ if (unlikely (image->status))
return image->status;
/* Initialize it to empty
@@ -1227,7 +1228,7 @@ _transform_glyph_bitmap (cairo_matrix_t * shape,
CAIRO_COLOR_TRANSPARENT,
0, 0,
width, height);
- if (status) {
+ if (unlikely (status)) {
cairo_surface_destroy (image);
return status;
}
@@ -1245,7 +1246,7 @@ _transform_glyph_bitmap (cairo_matrix_t * shape,
_cairo_pattern_fini (&pattern.base);
- if (status) {
+ if (unlikely (status)) {
cairo_surface_destroy (image);
return status;
}
@@ -1512,7 +1513,7 @@ _cairo_ft_scaled_font_create (cairo_ft_unscaled_font_t *unscaled,
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
scaled_font = malloc (sizeof(cairo_ft_scaled_font_t));
- if (scaled_font == NULL) {
+ if (unlikely (scaled_font == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto FAIL;
}
@@ -1527,7 +1528,7 @@ _cairo_ft_scaled_font_create (cairo_ft_unscaled_font_t *unscaled,
font_face,
font_matrix, ctm, options,
&_cairo_ft_scaled_font_backend);
- if (status) {
+ if (unlikely (status)) {
_cairo_unscaled_font_destroy (&unscaled->base);
free (scaled_font);
goto FAIL;
@@ -1535,7 +1536,7 @@ _cairo_ft_scaled_font_create (cairo_ft_unscaled_font_t *unscaled,
status = _cairo_ft_unscaled_font_set_scale (unscaled,
&scaled_font->base.scale);
- if (status) {
+ if (unlikely (status)) {
_cairo_unscaled_font_destroy (&unscaled->base);
free (scaled_font);
goto FAIL;
@@ -1626,7 +1627,7 @@ _cairo_ft_scaled_font_create_toy (cairo_toy_font_face_t *toy_face,
cairo_matrix_multiply (&scale, font_matrix, ctm);
status = _compute_transform (&sf, &scale);
- if (status)
+ if (unlikely (status))
return status;
pattern = FcPatternCreate ();
@@ -1686,7 +1687,7 @@ _cairo_ft_scaled_font_create_toy (cairo_toy_font_face_t *toy_face,
}
status = _cairo_ft_font_options_substitute (font_options, pattern);
- if (status)
+ if (unlikely (status))
goto FREE_PATTERN;
FcDefaultSubstitute (pattern);
@@ -1863,7 +1864,7 @@ _decompose_glyph_outline (FT_Face face,
}
status = _cairo_path_fixed_close_path (path);
- if (status) {
+ if (unlikely (status)) {
_cairo_path_fixed_destroy (path);
return status;
}
@@ -1918,7 +1919,7 @@ _cairo_ft_scaled_glyph_init (void *abstract_font,
status = _cairo_ft_unscaled_font_set_scale (scaled_font->unscaled,
&scaled_font->base.scale);
- if (status)
+ if (unlikely (status))
goto FAIL;
/* Ignore global advance unconditionally */
@@ -2066,14 +2067,16 @@ _cairo_ft_scaled_glyph_init (void *abstract_font,
} else {
status = _render_glyph_bitmap (face, &scaled_font->ft_options.base,
&surface);
- if (status == CAIRO_STATUS_SUCCESS && unscaled->have_shape) {
+ if (likely (status == CAIRO_STATUS_SUCCESS) &&
+ unscaled->have_shape)
+ {
status = _transform_glyph_bitmap (&unscaled->current_shape,
&surface);
- if (status)
+ if (unlikely (status))
cairo_surface_destroy (&surface->base);
}
}
- if (status)
+ if (unlikely (status))
goto FAIL;
_cairo_scaled_glyph_set_surface (scaled_glyph,
@@ -2115,7 +2118,7 @@ _cairo_ft_scaled_glyph_init (void *abstract_font,
else
status = CAIRO_INT_STATUS_UNSUPPORTED;
- if (status)
+ if (unlikely (status))
goto FAIL;
_cairo_scaled_glyph_set_path (scaled_glyph,
@@ -2530,7 +2533,7 @@ cairo_ft_font_face_create_for_pattern (FcPattern *pattern)
cairo_ft_options_t ft_options;
unscaled = _cairo_ft_unscaled_font_create_for_pattern (pattern);
- if (unscaled == NULL) {
+ if (unlikely (unscaled == NULL)) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return (cairo_font_face_t *)&_cairo_font_face_nil;
}
@@ -2597,7 +2600,7 @@ cairo_ft_font_face_create_for_ft_face (FT_Face face,
cairo_ft_options_t ft_options;
unscaled = _cairo_ft_unscaled_font_create_from_face (face);
- if (unscaled == NULL) {
+ if (unlikely (unscaled == NULL)) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return (cairo_font_face_t *)&_cairo_font_face_nil;
}
@@ -2658,14 +2661,14 @@ cairo_ft_scaled_font_lock_face (cairo_scaled_font_t *abstract_font)
return NULL;
face = _cairo_ft_unscaled_font_lock_face (scaled_font->unscaled);
- if (face == NULL) {
+ if (unlikely (face == NULL)) {
status = _cairo_scaled_font_set_error (&scaled_font->base, CAIRO_STATUS_NO_MEMORY);
return NULL;
}
status = _cairo_ft_unscaled_font_set_scale (scaled_font->unscaled,
&scaled_font->base.scale);
- if (status) {
+ if (unlikely (status)) {
_cairo_ft_unscaled_font_unlock_face (scaled_font->unscaled);
status = _cairo_scaled_font_set_error (&scaled_font->base, status);
return NULL;
diff --git a/src/cairo-glitz-surface.c b/src/cairo-glitz-surface.c
index 3916f8f1..f049f401 100644
--- a/src/cairo-glitz-surface.c
+++ b/src/cairo-glitz-surface.c
@@ -33,7 +33,8 @@ typedef struct _cairo_glitz_surface {
glitz_surface_t *surface;
glitz_format_t *format;
- cairo_bool_t has_clip;
+
+ cairo_bool_t has_clip;
glitz_box_t *clip_boxes;
int num_clip_boxes;
} cairo_glitz_surface_t;
@@ -46,10 +47,8 @@ _cairo_glitz_surface_finish (void *abstract_surface)
{
cairo_glitz_surface_t *surface = abstract_surface;
- if (surface->has_clip) {
- glitz_surface_set_clip_region (surface->surface, 0, 0, NULL, 0);
+ if (surface->clip_boxes)
free (surface->clip_boxes);
- }
glitz_surface_destroy (surface->surface);
@@ -108,7 +107,9 @@ _cairo_glitz_surface_create_similar (void *abstract_src,
}
static cairo_status_t
-_cairo_glitz_get_boxes_from_region (cairo_region_t *region, glitz_box_t **boxes, int *nboxes)
+_cairo_glitz_get_boxes_from_region (cairo_region_t *region,
+ glitz_box_t **boxes,
+ int *nboxes)
{
pixman_box32_t *pboxes;
cairo_status_t status = CAIRO_STATUS_SUCCESS;
@@ -118,15 +119,16 @@ _cairo_glitz_get_boxes_from_region (cairo_region_t *region, glitz_box_t **boxes,
n = 0;
pboxes = pixman_region32_rectangles (&region->rgn, &n);
if (n == 0) {
- *nboxes = 0;
- *boxes = NULL;
- goto done;
+ *nboxes = 0;
+ return CAIRO_STATUS_SUCCESS;
}
- *boxes = _cairo_malloc_ab (n, sizeof(glitz_box_t));
- if (*boxes == NULL) {
- status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
- goto done;
+ if (n > *nboxes) {
+ *boxes = _cairo_malloc_ab (n, sizeof (glitz_box_t));
+ if (*boxes == NULL) {
+ status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ goto done;
+ }
}
for (i = 0; i < n; i++) {
@@ -141,8 +143,6 @@ done:
return status;
}
-#define STRIDE_ALIGNMENT (sizeof (uint32_t))
-
static cairo_status_t
_cairo_glitz_surface_get_image (cairo_glitz_surface_t *surface,
cairo_rectangle_int_t *interest,
@@ -150,95 +150,62 @@ _cairo_glitz_surface_get_image (cairo_glitz_surface_t *surface,
cairo_rectangle_int_t *rect_out)
{
cairo_image_surface_t *image;
- int x1, y1, x2, y2;
- int width, height;
- unsigned char *pixels;
+ cairo_rectangle_int_t extents;
+ cairo_format_t format;
cairo_format_masks_t masks;
glitz_buffer_t *buffer;
glitz_pixel_format_t pf;
- cairo_status_t status;
- pixman_format_code_t pixman_format;
- x1 = 0;
- y1 = 0;
- x2 = glitz_surface_get_width (surface->surface);
- y2 = glitz_surface_get_height (surface->surface);
+ extents.x = 0;
+ extents.y = 0;
+ extents.width = glitz_surface_get_width (surface->surface);
+ extents.height = glitz_surface_get_height (surface->surface);
- if (interest)
- {
- if (interest->x > x1)
- x1 = interest->x;
- if (interest->y > y1)
- y1 = interest->y;
- if (interest->x + interest->width < (unsigned int)x2)
- x2 = interest->x + interest->width;
- if (interest->y + interest->height < (unsigned int)y2)
- y2 = interest->y + interest->height;
-
- if (x1 >= x2 || y1 >= y2)
- {
+ if (interest != NULL) {
+ if (! _cairo_rectangle_intersect (&extents, interest)) {
*image_out = NULL;
return CAIRO_STATUS_SUCCESS;
}
}
- width = x2 - x1;
- height = y2 - y1;
-
- if (rect_out)
- {
- rect_out->x = x1;
- rect_out->y = y1;
- rect_out->width = width;
- rect_out->height = height;
- }
+ if (rect_out != NULL)
+ *rect_out = extents;
if (surface->format->color.fourcc == GLITZ_FOURCC_RGB) {
if (surface->format->color.red_size > 0) {
- masks.bpp = 32;
-
if (surface->format->color.alpha_size > 0)
- masks.alpha_mask = 0xff000000;
+ format = CAIRO_FORMAT_ARGB32;
else
- masks.alpha_mask = 0x0;
-
- masks.red_mask = 0xff0000;
- masks.green_mask = 0xff00;
- masks.blue_mask = 0xff;
+ format = CAIRO_FORMAT_RGB24;
} else {
- masks.bpp = 8;
- masks.blue_mask = masks.green_mask = masks.red_mask = 0x0;
- masks.alpha_mask = 0xff;
+ format = CAIRO_FORMAT_A8;
}
- } else {
- masks.bpp = 32;
- masks.alpha_mask = 0xff000000;
- masks.red_mask = 0xff0000;
- masks.green_mask = 0xff00;
- masks.blue_mask = 0xff;
- }
+ } else
+ format = CAIRO_FORMAT_ARGB32;
+ image = (cairo_image_surface_t*)
+ cairo_image_surface_create (format, extents.width, extents.height);
+ if (image->base.status)
+ return image->base.status;
+
+ _pixman_format_to_masks (image->pixman_format, &masks);
pf.fourcc = GLITZ_FOURCC_RGB;
pf.masks.bpp = masks.bpp;
pf.masks.alpha_mask = masks.alpha_mask;
- pf.masks.red_mask = masks.red_mask;
+ pf.masks.red_mask = masks.red_mask;
pf.masks.green_mask = masks.green_mask;
- pf.masks.blue_mask = masks.blue_mask;
+ pf.masks.blue_mask = masks.blue_mask;
pf.xoffset = 0;
pf.skip_lines = 0;
/* XXX: we should eventually return images with negative stride,
need to verify that libpixman have no problem with this first. */
- pf.bytes_per_line = ((masks.bpp * width + 7) / 8 + STRIDE_ALIGNMENT - 1) & ~(STRIDE_ALIGNMENT - 1);
+ pf.bytes_per_line = image->stride;
pf.scanline_order = GLITZ_PIXEL_SCANLINE_ORDER_TOP_DOWN;
- pixels = _cairo_malloc_ab (height, pf.bytes_per_line);
- if (!pixels)
- return _cairo_error (CAIRO_STATUS_NO_MEMORY);
-
- buffer = glitz_buffer_create_for_data (pixels);
- if (!buffer) {
- free (pixels);
+ buffer = glitz_buffer_create_for_data (image->data);
+ if (buffer == NULL) {
+ cairo_surface_destroy (&image->base);
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
@@ -248,83 +215,24 @@ _cairo_glitz_surface_get_image (cairo_glitz_surface_t *surface,
0, 0, NULL, 0);
glitz_get_pixels (surface->surface,
- x1, y1,
- width, height,
+ extents.x, extents.y,
+ extents.width, extents.height,
&pf,
buffer);
glitz_buffer_destroy (buffer);
/* restore the clip, if any */
- if (surface->has_clip)
- glitz_surface_set_clip_region (surface->surface, 0, 0,
+ if (surface->has_clip) {
+ glitz_surface_set_clip_region (surface->surface,
+ 0, 0,
surface->clip_boxes,
surface->num_clip_boxes);
-
- if (! _pixman_format_from_masks (&masks, &pixman_format))
- {
- status = _cairo_error (CAIRO_STATUS_INVALID_FORMAT);
- goto FAIL;
- }
-
- image = (cairo_image_surface_t*)
- _cairo_image_surface_create_with_pixman_format ((unsigned char *) pixels,
- pixman_format,
- width,
- height,
- pf.bytes_per_line);
- if (image->base.status)
- {
- status = image->base.status;
- goto FAIL;
}
- _cairo_image_surface_assume_ownership_of_data (image);
-
*image_out = image;
return CAIRO_STATUS_SUCCESS;
-
- FAIL:
- free (pixels);
- return status;
-}
-
-static void
-cairo_format_get_masks (cairo_format_t format,
- uint32_t *bpp,
- uint32_t *alpha,
- uint32_t *red,
- uint32_t *green,
- uint32_t *blue)
-{
- *red = 0x0;
- *green = 0x0;
- *blue = 0x0;
- *alpha = 0x0;
-
- switch (format)
- {
- case CAIRO_FORMAT_ARGB32:
- *alpha = 0xff000000;
- case CAIRO_FORMAT_RGB24:
- default:
- *bpp = 32;
- *red = 0x00ff0000;
- *green = 0x0000ff00;
- *blue = 0x000000ff;
- break;
-
- case CAIRO_FORMAT_A8:
- *bpp = 8;
- *alpha = 0xff;
- break;
-
- case CAIRO_FORMAT_A1:
- *bpp = 1;
- *alpha = 0x1;
- break;
- }
}
static cairo_status_t
@@ -340,36 +248,33 @@ _cairo_glitz_surface_set_image (void *abstract_surface,
cairo_glitz_surface_t *surface = abstract_surface;
glitz_buffer_t *buffer;
glitz_pixel_format_t pf;
- uint32_t bpp, am, rm, gm, bm;
+ cairo_format_masks_t masks;
char *data;
- cairo_format_get_masks (image->format, &bpp, &am, &rm, &gm, &bm);
+ _pixman_format_to_masks (image->pixman_format, &masks);
pf.fourcc = GLITZ_FOURCC_RGB;
- pf.masks.bpp = bpp;
- pf.masks.alpha_mask = am;
- pf.masks.red_mask = rm;
- pf.masks.green_mask = gm;
- pf.masks.blue_mask = bm;
+ pf.masks.bpp = masks.bpp;
+ pf.masks.alpha_mask = masks.alpha_mask;
+ pf.masks.red_mask = masks.red_mask;
+ pf.masks.green_mask = masks.green_mask;
+ pf.masks.blue_mask = masks.blue_mask;
pf.xoffset = src_x;
pf.skip_lines = src_y;
/* check for negative stride */
- if (image->stride < 0)
- {
+ if (image->stride < 0) {
pf.bytes_per_line = -image->stride;
pf.scanline_order = GLITZ_PIXEL_SCANLINE_ORDER_BOTTOM_UP;
data = (char *) image->data + image->stride * (image->height - 1);
- }
- else
- {
+ } else {
pf.bytes_per_line = image->stride;
pf.scanline_order = GLITZ_PIXEL_SCANLINE_ORDER_TOP_DOWN;
data = (char *) image->data;
}
buffer = glitz_buffer_create_for_data (data);
- if (!buffer)
+ if (buffer == NULL)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
glitz_set_pixels (surface->surface,
@@ -473,46 +378,27 @@ _cairo_glitz_surface_clone_similar (void *abstract_surface,
else if (_cairo_surface_is_image (src))
{
cairo_image_surface_t *image_src = (cairo_image_surface_t *) src;
- cairo_content_t content;
- cairo_rectangle_int_t image_extent;
- cairo_rectangle_int_t extent;
-
- content = _cairo_content_from_format (image_src->format);
clone = (cairo_glitz_surface_t *)
- _cairo_glitz_surface_create_similar (surface, content,
- image_src->width,
- image_src->height);
+ _cairo_glitz_surface_create_similar (surface, src->content,
+ width, height);
if (clone == NULL)
return CAIRO_INT_STATUS_UNSUPPORTED;
if (clone->base.status)
return clone->base.status;
- image_extent.x = 0;
- image_extent.y = 0;
- image_extent.width = image_src->width;
- image_extent.height = image_src->height;
- extent.x = src_x;
- extent.y = src_y;
- extent.width = width;
- extent.height = height;
-
- if (_cairo_rectangle_intersect (&extent, &image_extent))
- {
- status = _cairo_glitz_surface_set_image (clone, image_src,
- extent.x, extent.y,
- extent.width, extent.height,
- extent.x, extent.y);
- if (status) {
- cairo_surface_destroy (&clone->base);
- return status;
- }
+ status = _cairo_glitz_surface_set_image (clone, image_src,
+ src_x, src_y,
+ width, height,
+ 0, 0);
+ if (status) {
+ cairo_surface_destroy (&clone->base);
+ return status;
}
*clone_out = &clone->base;
- *clone_offset_x = 0;
- *clone_offset_y = 0;
-
+ *clone_offset_x = src_x;
+ *clone_offset_y = src_y;
return CAIRO_STATUS_SUCCESS;
}
@@ -1113,23 +999,29 @@ _cairo_glitz_surface_fill_rectangles (void *abstract_dst,
}
switch (op) {
+ case CAIRO_OPERATOR_CLEAR:
case CAIRO_OPERATOR_SOURCE: {
glitz_color_t glitz_color;
+ glitz_format_t *format;
glitz_color.red = color->red_short;
glitz_color.green = color->green_short;
glitz_color.blue = color->blue_short;
glitz_color.alpha = color->alpha_short;
+ /*
+ * XXX even if the dst surface don't have an alpha channel, the
+ * above alpha still effect the dst surface because the
+ * underlying glitz drawable may have an alpha channel. So
+ * replacing the color with an opaque one is needed.
+ */
+ format = glitz_surface_get_format (dst->surface);
+ if (format->color.alpha_size == 0)
+ glitz_color.alpha = 0xffff;
+
glitz_set_rectangles (dst->surface, &glitz_color,
glitz_rects, n_rects);
} break;
- case CAIRO_OPERATOR_CLEAR: {
- static const glitz_color_t glitz_color = { 0, 0, 0, 0 };
-
- glitz_set_rectangles (dst->surface, &glitz_color,
- glitz_rects, n_rects);
- } break;
case CAIRO_OPERATOR_SATURATE:
return CAIRO_INT_STATUS_UNSUPPORTED;
case CAIRO_OPERATOR_OVER:
@@ -1206,8 +1098,6 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t op,
cairo_trapezoid_t *traps,
int n_traps)
{
- cairo_pattern_union_t tmp_src_pattern;
- const cairo_pattern_t *src_pattern;
cairo_glitz_surface_attributes_t attributes;
cairo_glitz_surface_t *dst = abstract_dst;
cairo_glitz_surface_t *src;
@@ -1216,10 +1106,22 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t op,
void *data = NULL;
cairo_int_status_t status;
unsigned short alpha;
- pixman_trapezoid_t stack_traps[CAIRO_STACK_ARRAY_LENGTH (pixman_trapezoid_t)];
- pixman_trapezoid_t *pixman_traps = stack_traps;
+ pixman_trapezoid_t stack_traps[CAIRO_STACK_ARRAY_LENGTH (pixman_trapezoid_t)];
+ pixman_trapezoid_t *pixman_traps = stack_traps;
int i;
+ if (antialias != CAIRO_ANTIALIAS_DEFAULT &&
+ antialias != CAIRO_ANTIALIAS_GRAY)
+ {
+ return CAIRO_INT_STATUS_UNSUPPORTED;
+ }
+
+ if (op == CAIRO_OPERATOR_SATURATE)
+ return CAIRO_INT_STATUS_UNSUPPORTED;
+
+ if (_glitz_ensure_target (dst->surface))
+ return CAIRO_INT_STATUS_UNSUPPORTED;
+
/* Convert traps to pixman traps */
if (n_traps > ARRAY_LENGTH (stack_traps)) {
pixman_traps = _cairo_malloc_ab (n_traps, sizeof (pixman_trapezoid_t));
@@ -1240,59 +1142,16 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t op,
pixman_traps[i].right.p2.y = _cairo_fixed_to_16_16 (traps[i].right.p2.y);
}
- if (antialias != CAIRO_ANTIALIAS_DEFAULT &&
- antialias != CAIRO_ANTIALIAS_GRAY)
- {
- status = CAIRO_INT_STATUS_UNSUPPORTED;
- goto finish;
- }
-
- if (dst->base.status)
- {
- status = dst->base.status;
- goto finish;
- }
-
- if (op == CAIRO_OPERATOR_SATURATE)
- {
- status = CAIRO_INT_STATUS_UNSUPPORTED;
- goto finish;
- }
-
- if (_glitz_ensure_target (dst->surface))
- {
- status = CAIRO_INT_STATUS_UNSUPPORTED;
- goto finish;
- }
-
- if (pattern->type == CAIRO_PATTERN_TYPE_SURFACE)
- {
- status = _cairo_pattern_init_copy (&tmp_src_pattern.base, pattern);
- if (status)
- goto finish;
+ status = _cairo_glitz_pattern_acquire_surface (pattern, dst,
+ src_x, src_y,
+ width, height,
+ &src, &attributes);
+ if (status)
+ goto FAIL;
- status = _cairo_glitz_pattern_acquire_surface (&tmp_src_pattern.base,
- dst,
- src_x, src_y,
- width, height,
- &src, &attributes);
- src_pattern = &tmp_src_pattern.base;
- }
- else
- {
- status = _cairo_glitz_pattern_acquire_surface (pattern, dst,
- src_x, src_y,
- width, height,
- &src, &attributes);
- src_pattern = pattern;
- }
alpha = 0xffff;
- if (status)
- goto finish;
-
- if (op == CAIRO_OPERATOR_ADD || n_traps <= 1)
- {
+ if (op == CAIRO_OPERATOR_ADD || n_traps <= 1) {
static const glitz_color_t clear_black = { 0, 0, 0, 0 };
glitz_color_t color;
glitz_geometry_format_t format;
@@ -1314,19 +1173,12 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t op,
CAIRO_CONTENT_ALPHA,
2, 1);
if (mask == NULL) {
- _cairo_glitz_pattern_release_surface (src_pattern, src, &attributes);
- if (src_pattern == &tmp_src_pattern.base)
- _cairo_pattern_fini (&tmp_src_pattern.base);
- status = CAIRO_INT_STATUS_UNSUPPORTED;
- goto finish;
+ status = CAIRO_INT_STATUS_UNSUPPORTED;
+ goto FAIL;
}
if (mask->base.status) {
- _cairo_glitz_pattern_release_surface (src_pattern, src, &attributes);
- if (src_pattern == &tmp_src_pattern.base)
- _cairo_pattern_fini (&tmp_src_pattern.base);
-
status = mask->base.status;
- goto finish;
+ goto FAIL;
}
color.red = color.green = color.blue = color.alpha = 0xffff;
@@ -1341,21 +1193,15 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t op,
size *= format.vertex.bytes_per_vertex;
- while (n_traps)
- {
- if (data_size < size)
- {
+ while (n_traps) {
+ if (data_size < size) {
void *p;
+
data_size = size;
p = realloc (data, data_size);
- if (!p)
- {
- _cairo_glitz_pattern_release_surface (src_pattern, src,
- &attributes);
- if (src_pattern == &tmp_src_pattern.base)
- _cairo_pattern_fini (&tmp_src_pattern.base);
+ if (p == NULL) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
- goto finish;
+ goto FAIL;
}
data = p;
@@ -1363,14 +1209,10 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t op,
glitz_buffer_destroy (buffer);
buffer = glitz_buffer_create_for_data (data);
- if (!buffer) {
- free (data);
- _cairo_glitz_pattern_release_surface (src_pattern, src,
- &attributes);
- if (src_pattern == &tmp_src_pattern.base)
- _cairo_pattern_fini (&tmp_src_pattern.base);
+ if (buffer == NULL) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
- goto finish;
+ free (data);
+ goto FAIL;
}
}
@@ -1392,22 +1234,16 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t op,
glitz_set_array (dst->surface, 0, 3,
offset / format.vertex.bytes_per_vertex,
0, 0);
- }
- else
- {
+ } else {
cairo_image_surface_t *image;
unsigned char *ptr;
int stride;
stride = (width + 3) & -4;
data = calloc (stride, height);
- if (!data)
- {
- _cairo_glitz_pattern_release_surface (src_pattern, src, &attributes);
- if (src_pattern == &tmp_src_pattern.base)
- _cairo_pattern_fini (&tmp_src_pattern.base);
+ if (data == NULL) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
- goto finish;
+ goto FAIL;
}
/* using negative stride */
@@ -1418,12 +1254,10 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t op,
CAIRO_FORMAT_A8,
width, height,
-stride);
- if (image->base.status)
- {
- cairo_surface_destroy (&src->base);
+ status = image->base.status;
+ if (status) {
free (data);
- status = image->base.status;
- goto finish;
+ goto FAIL;
}
pixman_add_trapezoids (image->pixman_image, -dst_x, -dst_y,
@@ -1433,21 +1267,20 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t op,
_cairo_surface_create_similar_scratch (&dst->base,
CAIRO_CONTENT_ALPHA,
width, height);
- if (mask->base.status) {
- _cairo_glitz_pattern_release_surface (src_pattern, src, &attributes);
+ status = mask->base.status;
+ if (status) {
free (data);
cairo_surface_destroy (&image->base);
- status = mask->base.status;
- goto finish;
+ goto FAIL;
}
status = _cairo_glitz_surface_set_image (mask, image,
0, 0, width, height, 0, 0);
- cairo_surface_destroy(&image->base);
+ cairo_surface_destroy (&image->base);
if (status)
- goto finish;
+ goto FAIL;
}
_cairo_glitz_surface_set_attributes (src, &attributes);
@@ -1474,18 +1307,16 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t op,
free (data);
- if (glitz_surface_get_status (dst->surface) == GLITZ_STATUS_NOT_SUPPORTED)
+ if (glitz_surface_get_status (dst->surface) == GLITZ_STATUS_NOT_SUPPORTED) {
status = CAIRO_INT_STATUS_UNSUPPORTED;
+ goto FAIL;
+ }
- if (status == CAIRO_STATUS_SUCCESS && ! _cairo_operator_bounded_by_mask (op))
- {
- int src_width, src_height;
-
- src_width = glitz_surface_get_width (src->surface);
- src_height = glitz_surface_get_height (src->surface);
+ if (! _cairo_operator_bounded_by_mask (op)) {
status = _cairo_surface_composite_shape_fixup_unbounded (&dst->base,
&attributes.base,
- src_width, src_height,
+ glitz_surface_get_width (src->surface),
+ glitz_surface_get_height (src->surface),
width, height,
src_x, src_y,
0, 0,
@@ -1493,14 +1324,12 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t op,
width, height);
}
- _cairo_glitz_pattern_release_surface (src_pattern, src, &attributes);
- if (src_pattern == &tmp_src_pattern.base)
- _cairo_pattern_fini (&tmp_src_pattern.base);
+FAIL:
+ _cairo_glitz_pattern_release_surface (pattern, src, &attributes);
- if (mask)
+ if (mask != NULL)
cairo_surface_destroy (&mask->base);
-finish:
if (pixman_traps != stack_traps)
free (pixman_traps);
@@ -1513,33 +1342,23 @@ _cairo_glitz_surface_set_clip_region (void *abstract_surface,
{
cairo_glitz_surface_t *surface = abstract_surface;
- if (region)
- {
- glitz_box_t *box;
- int n;
+ if (region != NULL) {
cairo_status_t status;
- status = _cairo_glitz_get_boxes_from_region (region, &box, &n);
+ status = _cairo_glitz_get_boxes_from_region (region,
+ &surface->clip_boxes,
+ &surface->num_clip_boxes);
if (status)
- return status;
-
- if (surface->has_clip)
- free (surface->clip_boxes);
-
- glitz_surface_set_clip_region (surface->surface, 0, 0, box, n);
+ return status;
+ glitz_surface_set_clip_region (surface->surface,
+ 0, 0,
+ surface->clip_boxes,
+ surface->num_clip_boxes);
surface->has_clip = TRUE;
- surface->clip_boxes = box;
- surface->num_clip_boxes = n;
- }
- else
- {
+ } else {
glitz_surface_set_clip_region (surface->surface, 0, 0, NULL, 0);
-
- if (surface->has_clip) {
- free (surface->clip_boxes);
- surface->has_clip = FALSE;
- }
+ surface->has_clip = FALSE;
}
return CAIRO_STATUS_SUCCESS;
@@ -1553,7 +1372,7 @@ _cairo_glitz_surface_get_extents (void *abstract_surface,
rectangle->x = 0;
rectangle->y = 0;
- rectangle->width = glitz_surface_get_width (surface->surface);
+ rectangle->width = glitz_surface_get_width (surface->surface);
rectangle->height = glitz_surface_get_height (surface->surface);
return CAIRO_STATUS_SUCCESS;
@@ -2474,6 +2293,8 @@ static const cairo_surface_backend_t cairo_glitz_surface_backend = {
_cairo_glitz_surface_composite,
_cairo_glitz_surface_fill_rectangles,
_cairo_glitz_surface_composite_trapezoids,
+ NULL, /* create_span_renderer */
+ NULL, /* check_span_renderer */
NULL, /* copy_page */
NULL, /* show_page */
_cairo_glitz_surface_set_clip_region,
@@ -2535,14 +2356,17 @@ cairo_glitz_surface_create (glitz_surface_t *surface)
format = glitz_surface_get_format (surface);
_cairo_surface_init (&crsurface->base, &cairo_glitz_surface_backend,
- _glitz_format_to_content(format));
+ _glitz_format_to_content (format));
glitz_surface_reference (surface);
crsurface->surface = surface;
crsurface->format = format;
- crsurface->has_clip = FALSE;
- return (cairo_surface_t *) crsurface;
+ crsurface->has_clip = FALSE;
+ crsurface->clip_boxes = NULL;
+ crsurface->num_clip_boxes = 0;
+
+ return &crsurface->base;
}
slim_hidden_def (cairo_glitz_surface_create);
diff --git a/src/cairo-gstate-private.h b/src/cairo-gstate-private.h
index 25900482..94043a1e 100644
--- a/src/cairo-gstate-private.h
+++ b/src/cairo-gstate-private.h
@@ -66,6 +66,9 @@ struct _cairo_gstate {
cairo_pattern_t *source;
struct _cairo_gstate *next;
+
+ int n_damage_regions;
+ cairo_region_t *damage_regions;
};
#endif /* CAIRO_GSTATE_PRIVATE_H */
diff --git a/src/cairo-gstate.c b/src/cairo-gstate.c
index 2c149677..cfea1a2c 100644
--- a/src/cairo-gstate.c
+++ b/src/cairo-gstate.c
@@ -105,6 +105,9 @@ _cairo_gstate_init (cairo_gstate_t *gstate,
gstate->source = (cairo_pattern_t *) &_cairo_pattern_black.base;
+ gstate->n_damage_regions = 0;
+ gstate->damage_regions = NULL;
+
/* Now that the gstate is fully initialized and ready for the eventual
* _cairo_gstate_fini(), we can check for errors (and not worry about
* the resource deallocation). */
@@ -113,11 +116,11 @@ _cairo_gstate_init (cairo_gstate_t *gstate,
return _cairo_error (CAIRO_STATUS_NULL_POINTER);
status = target->status;
- if (status)
+ if (unlikely (status))
return status;
status = gstate->source->status;
- if (status)
+ if (unlikely (status))
return status;
return CAIRO_STATUS_SUCCESS;
@@ -142,7 +145,7 @@ _cairo_gstate_init_copy (cairo_gstate_t *gstate, cairo_gstate_t *other)
status = _cairo_stroke_style_init_copy (&gstate->stroke_style,
&other->stroke_style);
- if (status)
+ if (unlikely (status))
return status;
gstate->fill_rule = other->fill_rule;
@@ -155,7 +158,7 @@ _cairo_gstate_init_copy (cairo_gstate_t *gstate, cairo_gstate_t *other)
_cairo_font_options_init_copy (&gstate->font_options , &other->font_options);
status = _cairo_clip_init_copy (&gstate->clip, &other->clip);
- if (status) {
+ if (unlikely (status)) {
_cairo_stroke_style_fini (&gstate->stroke_style);
cairo_font_face_destroy (gstate->font_face);
cairo_scaled_font_destroy (gstate->scaled_font);
@@ -221,13 +224,13 @@ _cairo_gstate_save (cairo_gstate_t **gstate, cairo_gstate_t **freelist)
top = *freelist;
if (top == NULL) {
top = malloc (sizeof (cairo_gstate_t));
- if (top == NULL)
+ if (unlikely (top == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
} else
*freelist = top->next;
status = _cairo_gstate_init_copy (top, *gstate);
- if (status) {
+ if (unlikely (status)) {
top->next = *freelist;
*freelist = top;
return status;
@@ -297,7 +300,7 @@ _cairo_gstate_redirect_target (cairo_gstate_t *gstate, cairo_surface_t *child)
_cairo_clip_reset (&gstate->clip);
status = _cairo_clip_init_deep_copy (&gstate->clip, &gstate->next->clip, child);
- if (status)
+ if (unlikely (status))
return status;
/* The clip is in surface backend coordinates for the previous target;
@@ -512,7 +515,7 @@ _cairo_gstate_set_dash (cairo_gstate_t *gstate, const double *dash, int num_dash
}
gstate->stroke_style.dash = _cairo_malloc_ab (gstate->stroke_style.num_dashes, sizeof (double));
- if (gstate->stroke_style.dash == NULL) {
+ if (unlikely (gstate->stroke_style.dash == NULL)) {
gstate->stroke_style.num_dashes = 0;
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
@@ -668,7 +671,7 @@ _cairo_gstate_transform (cairo_gstate_t *gstate,
tmp = *matrix;
status = cairo_matrix_invert (&tmp);
- if (status)
+ if (unlikely (status))
return status;
_cairo_gstate_unset_scaled_font (gstate);
@@ -827,7 +830,7 @@ _cairo_gstate_copy_transformed_pattern (cairo_gstate_t *gstate,
if (_cairo_surface_has_device_transform (surface)) {
status = _cairo_pattern_init_copy (*pattern, original);
- if (status)
+ if (unlikely (status))
return status;
have_copy = TRUE;
@@ -839,7 +842,7 @@ _cairo_gstate_copy_transformed_pattern (cairo_gstate_t *gstate,
if (! _cairo_matrix_is_identity (ctm_inverse)) {
if (! have_copy) {
status = _cairo_pattern_init_copy (*pattern, original);
- if (status)
+ if (unlikely (status))
return status;
have_copy = TRUE;
@@ -884,12 +887,12 @@ _cairo_gstate_paint (cairo_gstate_t *gstate)
return gstate->source->status;
status = _cairo_surface_set_clip (gstate->target, &gstate->clip);
- if (status)
+ if (unlikely (status))
return status;
pattern = &pattern_stack.base;
status = _cairo_gstate_copy_transformed_source (gstate, &pattern);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_surface_paint (gstate->target,
@@ -917,17 +920,17 @@ _cairo_gstate_mask (cairo_gstate_t *gstate,
return gstate->source->status;
status = _cairo_surface_set_clip (gstate->target, &gstate->clip);
- if (status)
+ if (unlikely (status))
return status;
source_pattern = &source_pattern_stack.base;
status = _cairo_gstate_copy_transformed_source (gstate, &source_pattern);
- if (status)
+ if (unlikely (status))
return status;
mask_pattern = &mask_pattern_stack.base;
status = _cairo_gstate_copy_transformed_mask (gstate, &mask_pattern, mask);
- if (status)
+ if (unlikely (status))
goto CLEANUP_SOURCE;
status = _cairo_surface_mask (gstate->target,
@@ -958,13 +961,13 @@ _cairo_gstate_stroke (cairo_gstate_t *gstate, cairo_path_fixed_t *path)
return CAIRO_STATUS_SUCCESS;
status = _cairo_surface_set_clip (gstate->target, &gstate->clip);
- if (status)
+ if (unlikely (status))
return status;
source_pattern = &source_pattern_stack.base;
status = _cairo_gstate_copy_transformed_source (gstate,
&source_pattern);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_surface_stroke (gstate->target,
@@ -1015,7 +1018,7 @@ _cairo_gstate_in_stroke (cairo_gstate_t *gstate,
&gstate->ctm_inverse,
gstate->tolerance,
&traps);
- if (status)
+ if (unlikely (status))
goto BAIL;
*inside_ret = _cairo_traps_contain (&traps, x, y);
@@ -1037,12 +1040,12 @@ _cairo_gstate_fill (cairo_gstate_t *gstate, cairo_path_fixed_t *path)
return gstate->source->status;
status = _cairo_surface_set_clip (gstate->target, &gstate->clip);
- if (status)
+ if (unlikely (status))
return status;
pattern = &pattern_stack.base;
status = _cairo_gstate_copy_transformed_source (gstate, &pattern);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_surface_fill (gstate->target,
@@ -1323,7 +1326,7 @@ _cairo_gstate_int_clip_extents (cairo_gstate_t *gstate,
cairo_status_t status;
status = _cairo_surface_get_extents (gstate->target, extents);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_clip_intersect_to_rectangle (&gstate->clip, extents);
@@ -1343,7 +1346,7 @@ _cairo_gstate_clip_extents (cairo_gstate_t *gstate,
cairo_status_t status;
status = _cairo_gstate_int_clip_extents (gstate, &extents);
- if (status)
+ if (unlikely (status))
return status;
px1 = extents.x;
@@ -1462,7 +1465,7 @@ _cairo_gstate_get_font_face (cairo_gstate_t *gstate,
cairo_status_t status;
status = _cairo_gstate_ensure_font_face (gstate);
- if (status)
+ if (unlikely (status))
return status;
*font_face = gstate->font_face;
@@ -1477,7 +1480,7 @@ _cairo_gstate_get_scaled_font (cairo_gstate_t *gstate,
cairo_status_t status;
status = _cairo_gstate_ensure_scaled_font (gstate);
- if (status)
+ if (unlikely (status))
return status;
*scaled_font = gstate->scaled_font;
@@ -1593,7 +1596,7 @@ _cairo_gstate_ensure_scaled_font (cairo_gstate_t *gstate)
return gstate->scaled_font->status;
status = _cairo_gstate_ensure_font_face (gstate);
- if (status)
+ if (unlikely (status))
return status;
cairo_surface_get_font_options (gstate->target, &options);
@@ -1605,7 +1608,7 @@ _cairo_gstate_ensure_scaled_font (cairo_gstate_t *gstate)
&options);
status = cairo_scaled_font_status (scaled_font);
- if (status)
+ if (unlikely (status))
return status;
gstate->scaled_font = scaled_font;
@@ -1618,7 +1621,7 @@ _cairo_gstate_get_font_extents (cairo_gstate_t *gstate,
cairo_font_extents_t *extents)
{
cairo_status_t status = _cairo_gstate_ensure_scaled_font (gstate);
- if (status)
+ if (unlikely (status))
return status;
cairo_scaled_font_extents (gstate->scaled_font, extents);
@@ -1641,7 +1644,7 @@ _cairo_gstate_text_to_glyphs (cairo_gstate_t *gstate,
cairo_status_t status;
status = _cairo_gstate_ensure_scaled_font (gstate);
- if (status)
+ if (unlikely (status))
return status;
return cairo_scaled_font_text_to_glyphs (gstate->scaled_font, x, y,
@@ -1678,7 +1681,7 @@ _cairo_gstate_glyph_extents (cairo_gstate_t *gstate,
cairo_status_t status;
status = _cairo_gstate_ensure_scaled_font (gstate);
- if (status)
+ if (unlikely (status))
return status;
cairo_scaled_font_glyph_extents (gstate->scaled_font,
@@ -1708,18 +1711,18 @@ _cairo_gstate_show_text_glyphs (cairo_gstate_t *gstate,
return gstate->source->status;
status = _cairo_surface_set_clip (gstate->target, &gstate->clip);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_gstate_ensure_scaled_font (gstate);
- if (status)
+ if (unlikely (status))
return status;
if (num_glyphs <= ARRAY_LENGTH (stack_transformed_glyphs)) {
transformed_glyphs = stack_transformed_glyphs;
} else {
transformed_glyphs = cairo_glyph_allocate (num_glyphs);
- if (transformed_glyphs == NULL)
+ if (unlikely (transformed_glyphs == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
@@ -1733,7 +1736,7 @@ _cairo_gstate_show_text_glyphs (cairo_gstate_t *gstate,
source_pattern = &source_pattern_stack.base;
status = _cairo_gstate_copy_transformed_source (gstate, &source_pattern);
- if (status)
+ if (unlikely (status))
goto CLEANUP_GLYPHS;
/* Just in case */
@@ -1802,21 +1805,22 @@ _cairo_gstate_glyph_path (cairo_gstate_t *gstate,
cairo_glyph_t stack_transformed_glyphs[CAIRO_STACK_ARRAY_LENGTH (cairo_glyph_t)];
status = _cairo_gstate_ensure_scaled_font (gstate);
- if (status)
+ if (unlikely (status))
return status;
- if (num_glyphs < ARRAY_LENGTH (stack_transformed_glyphs))
+ if (num_glyphs < ARRAY_LENGTH (stack_transformed_glyphs)) {
transformed_glyphs = stack_transformed_glyphs;
- else
- transformed_glyphs = cairo_glyph_allocate (num_glyphs);
- if (transformed_glyphs == NULL)
- return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ } else {
+ transformed_glyphs = cairo_glyph_allocate (num_glyphs);
+ if (unlikely (transformed_glyphs == NULL))
+ return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ }
status = _cairo_gstate_transform_glyphs_to_backend (gstate,
glyphs, num_glyphs,
transformed_glyphs,
NULL);
- if (status)
+ if (unlikely (status))
goto CLEANUP_GLYPHS;
status = _cairo_scaled_font_glyph_path (gstate->scaled_font,
@@ -1976,3 +1980,73 @@ _cairo_gstate_transform_glyphs_to_backend (cairo_gstate_t *gstate,
return CAIRO_STATUS_SUCCESS;
}
+
+static cairo_status_t
+allocate_regions (cairo_gstate_t *gstate,
+ int n_regions)
+{
+ cairo_region_t *regions;
+ int pot = 1;
+
+ while (pot <= n_regions && pot > 0)
+ pot *= 2;
+
+ if (pot < 0)
+ return CAIRO_STATUS_NO_MEMORY;
+
+ regions = _cairo_realloc_ab (
+ gstate->damage_regions, pot, sizeof (cairo_region_t));
+
+ if (!regions)
+ return CAIRO_STATUS_NO_MEMORY;
+
+ gstate->n_damage_regions = n_regions;
+ gstate->damage_regions = regions;
+
+ return CAIRO_STATUS_SUCCESS;
+}
+
+cairo_status_t
+_cairo_gtate_begin_damage_tracking (cairo_gstate_t *gstate)
+{
+ int last = gstate->n_damage_regions;
+ cairo_status_t status;
+
+ status = allocate_regions (gstate, last + 1);
+ if (status != CAIRO_STATUS_SUCCESS)
+ return status;
+
+ _cairo_region_init (&(gstate->damage_regions[last]));
+
+ return CAIRO_STATUS_SUCCESS;
+}
+
+cairo_status_t
+_cairo_gstate_end_damage_tracking (cairo_gstate_t *gstate,
+ int *n_rectangles,
+ cairo_rectangle_t **rectangles)
+{
+ int last = gstate->n_damage_regions - 1;
+ cairo_region_t result;
+ cairo_status_t status;
+
+ if (last > 0)
+ {
+ status = _cairo_region_union (&gstate->damage_regions[last - 1],
+ &gstate->damage_regions[last - 1],
+ &gstate->damage_regions[last]);
+
+ if (status != CAIRO_STATUS_SUCCESS)
+ return status;
+ }
+
+ result = gstate->damage_regions[last];
+
+ allocate_regions (gstate, gstate->n_damage_regions - 1);
+
+ /* FIXME - do something with result, such as turning it into
+ * a list of rectangles.
+ */
+ return CAIRO_STATUS_SUCCESS;
+}
+
diff --git a/src/cairo-hash.c b/src/cairo-hash.c
index b3f43b05..973281d4 100644
--- a/src/cairo-hash.c
+++ b/src/cairo-hash.c
@@ -148,7 +148,7 @@ _cairo_hash_table_create (cairo_hash_keys_equal_func_t keys_equal)
cairo_hash_table_t *hash_table;
hash_table = malloc (sizeof (cairo_hash_table_t));
- if (hash_table == NULL) {
+ if (unlikely (hash_table == NULL)) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return NULL;
}
@@ -159,7 +159,7 @@ _cairo_hash_table_create (cairo_hash_keys_equal_func_t keys_equal)
hash_table->entries = calloc (hash_table->arrangement->size,
sizeof(cairo_hash_entry_t *));
- if (hash_table->entries == NULL) {
+ if (unlikely (hash_table->entries == NULL)) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
free (hash_table);
return NULL;
@@ -280,7 +280,7 @@ _cairo_hash_table_resize (cairo_hash_table_t *hash_table)
new_size = tmp.arrangement->size;
tmp.entries = calloc (new_size, sizeof (cairo_hash_entry_t*));
- if (tmp.entries == NULL)
+ if (unlikely (tmp.entries == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
for (i = 0; i < hash_table->arrangement->size; ++i) {
diff --git a/src/cairo-hull.c b/src/cairo-hull.c
index 008ba7fd..a699a524 100644
--- a/src/cairo-hull.c
+++ b/src/cairo-hull.c
@@ -200,7 +200,7 @@ _cairo_hull_compute (cairo_pen_vertex_t *vertices, int *num_vertices)
if (num_hull > ARRAY_LENGTH (hull_stack)) {
hull = _cairo_malloc_ab (num_hull, sizeof (cairo_hull_t));
- if (hull == NULL)
+ if (unlikely (hull == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
} else {
hull = hull_stack;
diff --git a/src/cairo-image-surface.c b/src/cairo-image-surface.c
index 5174f145..9b768e57 100644
--- a/src/cairo-image-surface.c
+++ b/src/cairo-image-surface.c
@@ -131,7 +131,7 @@ _cairo_image_surface_create_for_pixman_image (pixman_image_t *pixman_image,
cairo_image_surface_t *surface;
surface = malloc (sizeof (cairo_image_surface_t));
- if (surface == NULL)
+ if (unlikely (surface == NULL))
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
_cairo_surface_init (&surface->base, &_cairo_image_surface_backend,
@@ -203,7 +203,7 @@ _pixman_format_from_masks (cairo_format_masks_t *masks,
}
/* A mask consisting of N bits set to 1. */
-#define MASK(N) ((1 << (N))-1)
+#define MASK(N) ((1UL << (N))-1)
void
_pixman_format_to_masks (pixman_format_code_t format,
@@ -327,7 +327,7 @@ _cairo_image_surface_create_with_pixman_format (unsigned char *data,
pixman_image = pixman_image_create_bits (pixman_format, width, height,
(uint32_t *) data, stride);
- if (pixman_image == NULL)
+ if (unlikely (pixman_image == NULL))
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
surface = _cairo_image_surface_create_for_pixman_image (pixman_image,
@@ -867,7 +867,7 @@ _cairo_image_surface_set_attributes (cairo_image_surface_t *surface,
status = _cairo_image_surface_set_matrix (surface, &attributes->matrix,
xc, yc);
- if (status)
+ if (unlikely (status))
return status;
switch (attributes->extend) {
@@ -886,7 +886,7 @@ _cairo_image_surface_set_attributes (cairo_image_surface_t *surface,
}
status = _cairo_image_surface_set_filter (surface, attributes->filter);
- if (status)
+ if (unlikely (status))
return status;
return CAIRO_STATUS_SUCCESS;
@@ -965,13 +965,13 @@ _cairo_image_surface_composite (cairo_operator_t op,
(cairo_surface_t **) &src,
(cairo_surface_t **) &mask,
&src_attr, &mask_attr);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_image_surface_set_attributes (src, &src_attr,
dst_x + width / 2.,
dst_y + height / 2.);
- if (status)
+ if (unlikely (status))
goto CLEANUP_SURFACES;
if (mask)
@@ -979,7 +979,7 @@ _cairo_image_surface_composite (cairo_operator_t op,
status = _cairo_image_surface_set_attributes (mask, &mask_attr,
dst_x + width / 2.,
dst_y + height / 2.);
- if (status)
+ if (unlikely (status))
goto CLEANUP_SURFACES;
pixman_image_composite (_pixman_operator (op),
@@ -1048,7 +1048,7 @@ _cairo_image_surface_fill_rectangles (void *abstract_surface,
if (num_rects > ARRAY_LENGTH (stack_rects)) {
pixman_rects = _cairo_malloc_ab (num_rects, sizeof (pixman_rectangle16_t));
- if (pixman_rects == NULL)
+ if (unlikely (pixman_rects == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
@@ -1075,6 +1075,15 @@ _cairo_image_surface_fill_rectangles (void *abstract_surface,
return status;
}
+static cairo_format_t
+_cairo_mask_format_from_antialias (cairo_antialias_t antialias)
+{
+ if (antialias == CAIRO_ANTIALIAS_NONE)
+ return CAIRO_FORMAT_A1;
+ return CAIRO_FORMAT_A8;
+}
+
+
static cairo_int_status_t
_cairo_image_surface_composite_trapezoids (cairo_operator_t op,
const cairo_pattern_t *pattern,
@@ -1092,13 +1101,10 @@ _cairo_image_surface_composite_trapezoids (cairo_operator_t op,
cairo_surface_attributes_t attributes;
cairo_image_surface_t *dst = abstract_dst;
cairo_image_surface_t *src;
- cairo_int_status_t status;
- pixman_image_t *mask;
- pixman_format_code_t format;
- uint32_t *mask_data;
+ cairo_int_status_t status;
+ cairo_image_surface_t *mask = NULL;
pixman_trapezoid_t stack_traps[CAIRO_STACK_ARRAY_LENGTH (pixman_trapezoid_t)];
pixman_trapezoid_t *pixman_traps = stack_traps;
- int mask_stride;
int i;
if (height == 0 || width == 0)
@@ -1107,7 +1113,7 @@ _cairo_image_surface_composite_trapezoids (cairo_operator_t op,
/* Convert traps to pixman traps */
if (num_traps > ARRAY_LENGTH (stack_traps)) {
pixman_traps = _cairo_malloc_ab (num_traps, sizeof (pixman_trapezoid_t));
- if (pixman_traps == NULL)
+ if (unlikely (pixman_traps == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
@@ -1153,49 +1159,28 @@ _cairo_image_surface_composite_trapezoids (cairo_operator_t op,
src_x, src_y, width, height,
(cairo_surface_t **) &src,
&attributes);
- if (status)
+ if (unlikely (status))
goto finish;
status = _cairo_image_surface_set_attributes (src, &attributes,
dst_x + width / 2.,
dst_y + height / 2.);
- if (status)
+ if (unlikely (status))
goto CLEANUP_SOURCE;
- switch (antialias) {
- case CAIRO_ANTIALIAS_NONE:
- format = PIXMAN_a1;
- mask_stride = ((width + 31) / 8) & ~0x03;
- break;
- case CAIRO_ANTIALIAS_GRAY:
- case CAIRO_ANTIALIAS_SUBPIXEL:
- case CAIRO_ANTIALIAS_DEFAULT:
- default:
- format = PIXMAN_a8;
- mask_stride = (width + 3) & ~3;
- break;
- }
-
- /* The image must be initially transparent */
- mask_data = calloc (mask_stride, height);
- if (mask_data == NULL) {
- status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ mask = (cairo_image_surface_t *)
+ cairo_image_surface_create (
+ _cairo_mask_format_from_antialias (antialias),
+ width, height);
+ if (cairo_surface_status (&mask->base) != CAIRO_STATUS_SUCCESS)
goto CLEANUP_SOURCE;
- }
- mask = pixman_image_create_bits (format, width, height,
- mask_data, mask_stride);
- if (mask == NULL) {
- status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
- goto CLEANUP_IMAGE_DATA;
- }
-
- pixman_add_trapezoids (mask, - dst_x, - dst_y,
+ pixman_add_trapezoids (mask->pixman_image, - dst_x, - dst_y,
num_traps, pixman_traps);
pixman_image_composite (_pixman_operator (op),
src->pixman_image,
- mask,
+ mask->pixman_image,
dst->pixman_image,
src_x + attributes.x_offset,
src_y + attributes.y_offset,
@@ -1205,15 +1190,13 @@ _cairo_image_surface_composite_trapezoids (cairo_operator_t op,
if (! _cairo_operator_bounded_by_mask (op))
status = _cairo_surface_composite_shape_fixup_unbounded (&dst->base,
- &attributes, src->width, src->height,
+ &attributes,
+ src->width, src->height,
width, height,
src_x, src_y,
0, 0,
dst_x, dst_y, width, height);
- pixman_image_unref (mask);
-
- CLEANUP_IMAGE_DATA:
- free (mask_data);
+ cairo_surface_destroy (&mask->base);
CLEANUP_SOURCE:
_cairo_pattern_release_surface (pattern, &src->base, &attributes);
@@ -1225,6 +1208,216 @@ _cairo_image_surface_composite_trapezoids (cairo_operator_t op,
return status;
}
+typedef struct _cairo_image_surface_span_renderer {
+ cairo_span_renderer_t base;
+
+ cairo_operator_t op;
+ const cairo_pattern_t *pattern;
+ cairo_antialias_t antialias;
+
+ cairo_image_surface_t *src;
+ cairo_surface_attributes_t src_attributes;
+ cairo_image_surface_t *mask;
+ cairo_image_surface_t *dst;
+
+ cairo_composite_rectangles_t composite_rectangles;
+} cairo_image_surface_span_renderer_t;
+
+static cairo_status_t
+_cairo_image_surface_span_renderer_render_row (
+ void *abstract_renderer,
+ int y,
+ const cairo_half_open_span_t *spans,
+ unsigned num_spans)
+{
+ cairo_image_surface_span_renderer_t *renderer = abstract_renderer;
+ int xmin = renderer->composite_rectangles.mask.x;
+ int xmax = xmin + renderer->composite_rectangles.width;
+ uint8_t *row;
+ int prev_x = xmin;
+ int prev_alpha = 0;
+ unsigned i;
+
+ /* Make sure we're within y-range. */
+ y -= renderer->composite_rectangles.mask.y;
+ if (y < 0 || y >= renderer->composite_rectangles.height)
+ return CAIRO_STATUS_SUCCESS;
+
+ row = (uint8_t*)(renderer->mask->data) + y*(size_t)renderer->mask->stride - xmin;
+
+ /* Find the first span within x-range. */
+ for (i=0; i < num_spans && spans[i].x < xmin; i++) {}
+ if (i>0)
+ prev_alpha = spans[i-1].coverage;
+
+ /* Set the intermediate spans. */
+ for (; i < num_spans; i++) {
+ int x = spans[i].x;
+
+ if (x >= xmax)
+ break;
+
+ if (prev_alpha != 0) {
+ /* We implement setting rendering the most common single
+ * pixel wide span case to avoid the overhead of a memset
+ * call. Open coding setting longer spans didn't show a
+ * noticeable improvement over memset. */
+ if (x == prev_x + 1) {
+ row[prev_x] = prev_alpha;
+ }
+ else {
+ memset(row + prev_x, prev_alpha, x - prev_x);
+ }
+ }
+
+ prev_x = x;
+ prev_alpha = spans[i].coverage;
+ }
+
+ if (prev_alpha != 0 && prev_x < xmax) {
+ memset(row + prev_x, prev_alpha, xmax - prev_x);
+ }
+
+ return CAIRO_STATUS_SUCCESS;
+}
+
+static void
+_cairo_image_surface_span_renderer_destroy (void *abstract_renderer)
+{
+ cairo_image_surface_span_renderer_t *renderer = abstract_renderer;
+ if (!renderer) return;
+
+ if (renderer->src != NULL) {
+ _cairo_pattern_release_surface (renderer->pattern,
+ &renderer->src->base,
+ &renderer->src_attributes);
+ }
+
+ if (renderer->mask != NULL)
+ cairo_surface_destroy (&renderer->mask->base);
+
+ free (renderer);
+}
+
+static cairo_status_t
+_cairo_image_surface_span_renderer_finish (void *abstract_renderer)
+{
+ cairo_image_surface_span_renderer_t *renderer = abstract_renderer;
+ cairo_status_t status = CAIRO_STATUS_SUCCESS;
+
+ if (renderer->src == NULL || renderer->mask == NULL)
+ return CAIRO_STATUS_SUCCESS;
+
+ status = cairo_surface_status (&renderer->mask->base);
+ if (status == CAIRO_STATUS_SUCCESS) {
+ cairo_composite_rectangles_t *rects = &renderer->composite_rectangles;
+ cairo_image_surface_t *src = renderer->src;
+ cairo_image_surface_t *dst = renderer->dst;
+ cairo_surface_attributes_t *src_attributes = &renderer->src_attributes;
+ int width = rects->width;
+ int height = rects->height;
+
+ pixman_image_composite (_pixman_operator (renderer->op),
+ src->pixman_image,
+ renderer->mask->pixman_image,
+ dst->pixman_image,
+ rects->src.x + src_attributes->x_offset,
+ rects->src.y + src_attributes->y_offset,
+ 0, 0, /* mask.x, mask.y */
+ rects->dst.x, rects->dst.y,
+ width, height);
+
+ if (! _cairo_operator_bounded_by_mask (renderer->op))
+ status = _cairo_surface_composite_shape_fixup_unbounded (
+ &dst->base,
+ src_attributes,
+ src->width, src->height,
+ rects->width, rects->height,
+ rects->src.x, rects->src.y,
+ 0, 0, /* mask.x, mask.y */
+ rects->dst.x, rects->dst.y,
+ rects->width, rects->height);
+ }
+ if (status != CAIRO_STATUS_SUCCESS)
+ return _cairo_span_renderer_set_error (abstract_renderer,
+ status);
+ return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_bool_t
+_cairo_image_surface_check_span_renderer (cairo_operator_t op,
+ const cairo_pattern_t *pattern,
+ void *abstract_dst,
+ cairo_antialias_t antialias,
+ const cairo_composite_rectangles_t *rects)
+{
+ (void) op;
+ (void) pattern;
+ (void) abstract_dst;
+ (void) antialias;
+ (void) rects;
+ return TRUE;
+}
+
+static cairo_span_renderer_t *
+_cairo_image_surface_create_span_renderer (cairo_operator_t op,
+ const cairo_pattern_t *pattern,
+ void *abstract_dst,
+ cairo_antialias_t antialias,
+ const cairo_composite_rectangles_t *rects)
+{
+ cairo_image_surface_t *dst = abstract_dst;
+ cairo_image_surface_span_renderer_t *renderer
+ = calloc(1, sizeof(*renderer));
+ cairo_status_t status;
+ int width = rects->width;
+ int height = rects->height;
+
+ if (renderer == NULL)
+ return _cairo_span_renderer_create_in_error (CAIRO_STATUS_NO_MEMORY);
+
+ renderer->base.destroy = _cairo_image_surface_span_renderer_destroy;
+ renderer->base.finish = _cairo_image_surface_span_renderer_finish;
+ renderer->base.render_row =
+ _cairo_image_surface_span_renderer_render_row;
+ renderer->op = op;
+ renderer->pattern = pattern;
+ renderer->antialias = antialias;
+ renderer->dst = dst;
+
+ renderer->composite_rectangles = *rects;
+
+ status = _cairo_pattern_acquire_surface (
+ renderer->pattern, &renderer->dst->base,
+ rects->src.x, rects->src.y,
+ width, height,
+ (cairo_surface_t **) &renderer->src,
+ &renderer->src_attributes);
+ if (status)
+ goto unwind;
+
+ status = _cairo_image_surface_set_attributes (
+ renderer->src, &renderer->src_attributes,
+ rects->dst.x + width/2, rects->dst.y + height/2);
+ if (status)
+ goto unwind;
+
+ /* TODO: support rendering to A1 surfaces (or: go add span
+ * compositing to pixman.) */
+ renderer->mask = (cairo_image_surface_t *)
+ cairo_image_surface_create (CAIRO_FORMAT_A8,
+ width, height);
+
+ status = cairo_surface_status (&renderer->mask->base);
+
+ unwind:
+ if (status != CAIRO_STATUS_SUCCESS) {
+ _cairo_image_surface_span_renderer_destroy (renderer);
+ return _cairo_span_renderer_create_in_error (status);
+ }
+ return &renderer->base;
+}
+
cairo_int_status_t
_cairo_image_surface_set_clip_region (void *abstract_surface,
cairo_region_t *region)
@@ -1300,6 +1493,8 @@ const cairo_surface_backend_t _cairo_image_surface_backend = {
_cairo_image_surface_composite,
_cairo_image_surface_fill_rectangles,
_cairo_image_surface_composite_trapezoids,
+ _cairo_image_surface_create_span_renderer,
+ _cairo_image_surface_check_span_renderer,
NULL, /* copy_page */
NULL, /* show_page */
_cairo_image_surface_set_clip_region,
@@ -1350,7 +1545,7 @@ _cairo_image_surface_clone (cairo_image_surface_t *surface,
status = cairo_status (cr);
cairo_destroy (cr);
- if (status) {
+ if (unlikely (status)) {
cairo_surface_destroy (&clone->base);
return (cairo_image_surface_t *) _cairo_surface_create_in_error (status);
}
diff --git a/src/cairo-lzw.c b/src/cairo-lzw.c
index 1241225d..a4fdf738 100644
--- a/src/cairo-lzw.c
+++ b/src/cairo-lzw.c
@@ -73,7 +73,7 @@ _lzw_buf_init (lzw_buf_t *buf, int size)
buf->pending_bits = 0;
buf->data = malloc (size);
- if (buf->data == NULL) {
+ if (unlikely (buf->data == NULL)) {
buf->data_size = 0;
buf->status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
return;
@@ -98,7 +98,7 @@ _lzw_buf_grow (lzw_buf_t *buf)
if (new_size / 2 == buf->data_size)
new_data = realloc (buf->data, new_size);
- if (new_data == NULL) {
+ if (unlikely (new_data == NULL)) {
free (buf->data);
buf->data_size = 0;
buf->status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
@@ -137,7 +137,7 @@ _lzw_buf_store_bits (lzw_buf_t *buf, uint16_t value, int num_bits)
while (buf->pending_bits >= 8) {
if (buf->num_data >= buf->data_size) {
status = _lzw_buf_grow (buf);
- if (status)
+ if (unlikely (status))
return;
}
buf->data[buf->num_data++] = buf->pending >> (buf->pending_bits - 8);
@@ -167,7 +167,7 @@ _lzw_buf_store_pending (lzw_buf_t *buf)
if (buf->num_data >= buf->data_size) {
status = _lzw_buf_grow (buf);
- if (status)
+ if (unlikely (status))
return;
}
diff --git a/src/cairo-matrix.c b/src/cairo-matrix.c
index 05589833..6dfe537f 100644
--- a/src/cairo-matrix.c
+++ b/src/cairo-matrix.c
@@ -879,6 +879,7 @@ _cairo_matrix_to_pixman_matrix (const cairo_matrix_t *matrix,
*pixman_transform = pixman_identity_transform;
} else {
cairo_matrix_t inv;
+ unsigned max_iterations;
pixman_transform->matrix[0][0] = _cairo_fixed_16_16_from_double (matrix->xx);
pixman_transform->matrix[0][1] = _cairo_fixed_16_16_from_double (matrix->xy);
@@ -913,6 +914,7 @@ _cairo_matrix_to_pixman_matrix (const cairo_matrix_t *matrix,
/* find the pattern space coordinate that maps to (xc, yc) */
xc += .5; yc += .5; /* offset for the pixel centre */
+ max_iterations = 5;
do {
double x,y;
pixman_vector_t vector;
@@ -942,6 +944,6 @@ _cairo_matrix_to_pixman_matrix (const cairo_matrix_t *matrix,
if (dx == 0 && dy == 0)
break;
- } while (TRUE);
+ } while (--max_iterations);
}
}
diff --git a/src/cairo-meta-surface.c b/src/cairo-meta-surface.c
index cfaaf304..0f6e6324 100644
--- a/src/cairo-meta-surface.c
+++ b/src/cairo-meta-surface.c
@@ -84,7 +84,7 @@ _cairo_meta_surface_create (cairo_content_t content,
cairo_meta_surface_t *meta;
meta = malloc (sizeof (cairo_meta_surface_t));
- if (meta == NULL)
+ if (unlikely (meta == NULL))
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
_cairo_surface_init (&meta->base, &cairo_meta_surface_backend,
@@ -197,7 +197,7 @@ _cairo_meta_surface_acquire_source_image (void *abstract_surface,
surface->height_pixels);
status = _cairo_meta_surface_replay (&surface->base, image);
- if (status) {
+ if (unlikely (status)) {
cairo_surface_destroy (image);
return status;
}
@@ -227,7 +227,7 @@ _cairo_meta_surface_paint (void *abstract_surface,
cairo_command_paint_t *command;
command = malloc (sizeof (cairo_command_paint_t));
- if (command == NULL)
+ if (unlikely (command == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
command->header.type = CAIRO_COMMAND_PAINT;
@@ -239,11 +239,11 @@ _cairo_meta_surface_paint (void *abstract_surface,
command->op = op;
status = _cairo_pattern_init_snapshot (&command->source.base, source);
- if (status)
+ if (unlikely (status))
goto CLEANUP_COMMAND;
status = _cairo_array_append (&meta->commands, &command);
- if (status)
+ if (unlikely (status))
goto CLEANUP_SOURCE;
/* An optimisation that takes care to not replay what was done
@@ -273,7 +273,7 @@ _cairo_meta_surface_mask (void *abstract_surface,
cairo_command_mask_t *command;
command = malloc (sizeof (cairo_command_mask_t));
- if (command == NULL)
+ if (unlikely (command == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
command->header.type = CAIRO_COMMAND_MASK;
@@ -285,15 +285,15 @@ _cairo_meta_surface_mask (void *abstract_surface,
command->op = op;
status = _cairo_pattern_init_snapshot (&command->source.base, source);
- if (status)
+ if (unlikely (status))
goto CLEANUP_COMMAND;
status = _cairo_pattern_init_snapshot (&command->mask.base, mask);
- if (status)
+ if (unlikely (status))
goto CLEANUP_SOURCE;
status = _cairo_array_append (&meta->commands, &command);
- if (status)
+ if (unlikely (status))
goto CLEANUP_MASK;
return CAIRO_STATUS_SUCCESS;
@@ -324,7 +324,7 @@ _cairo_meta_surface_stroke (void *abstract_surface,
cairo_command_stroke_t *command;
command = malloc (sizeof (cairo_command_stroke_t));
- if (command == NULL)
+ if (unlikely (command == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
command->header.type = CAIRO_COMMAND_STROKE;
@@ -336,15 +336,15 @@ _cairo_meta_surface_stroke (void *abstract_surface,
command->op = op;
status = _cairo_pattern_init_snapshot (&command->source.base, source);
- if (status)
+ if (unlikely (status))
goto CLEANUP_COMMAND;
status = _cairo_path_fixed_init_copy (&command->path, path);
- if (status)
+ if (unlikely (status))
goto CLEANUP_SOURCE;
status = _cairo_stroke_style_init_copy (&command->style, style);
- if (status)
+ if (unlikely (status))
goto CLEANUP_PATH;
command->ctm = *ctm;
@@ -353,7 +353,7 @@ _cairo_meta_surface_stroke (void *abstract_surface,
command->antialias = antialias;
status = _cairo_array_append (&meta->commands, &command);
- if (status)
+ if (unlikely (status))
goto CLEANUP_STYLE;
return CAIRO_STATUS_SUCCESS;
@@ -384,7 +384,7 @@ _cairo_meta_surface_fill (void *abstract_surface,
cairo_command_fill_t *command;
command = malloc (sizeof (cairo_command_fill_t));
- if (command == NULL)
+ if (unlikely (command == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
command->header.type = CAIRO_COMMAND_FILL;
@@ -396,11 +396,11 @@ _cairo_meta_surface_fill (void *abstract_surface,
command->op = op;
status = _cairo_pattern_init_snapshot (&command->source.base, source);
- if (status)
+ if (unlikely (status))
goto CLEANUP_COMMAND;
status = _cairo_path_fixed_init_copy (&command->path, path);
- if (status)
+ if (unlikely (status))
goto CLEANUP_SOURCE;
command->fill_rule = fill_rule;
@@ -408,7 +408,7 @@ _cairo_meta_surface_fill (void *abstract_surface,
command->antialias = antialias;
status = _cairo_array_append (&meta->commands, &command);
- if (status)
+ if (unlikely (status))
goto CLEANUP_PATH;
return CAIRO_STATUS_SUCCESS;
@@ -447,7 +447,7 @@ _cairo_meta_surface_show_text_glyphs (void *abstract_surface,
cairo_command_show_text_glyphs_t *command;
command = malloc (sizeof (cairo_command_show_text_glyphs_t));
- if (command == NULL)
+ if (unlikely (command == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
command->header.type = CAIRO_COMMAND_SHOW_TEXT_GLYPHS;
@@ -459,7 +459,7 @@ _cairo_meta_surface_show_text_glyphs (void *abstract_surface,
command->op = op;
status = _cairo_pattern_init_snapshot (&command->source.base, source);
- if (status)
+ if (unlikely (status))
goto CLEANUP_COMMAND;
command->utf8 = NULL;
@@ -471,7 +471,7 @@ _cairo_meta_surface_show_text_glyphs (void *abstract_surface,
if (utf8_len) {
command->utf8 = malloc (utf8_len);
- if (command->utf8 == NULL) {
+ if (unlikely (command->utf8 == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto CLEANUP_ARRAYS;
}
@@ -479,7 +479,7 @@ _cairo_meta_surface_show_text_glyphs (void *abstract_surface,
}
if (num_glyphs) {
command->glyphs = _cairo_malloc_ab (num_glyphs, sizeof (glyphs[0]));
- if (command->glyphs == NULL) {
+ if (unlikely (command->glyphs == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto CLEANUP_ARRAYS;
}
@@ -487,7 +487,7 @@ _cairo_meta_surface_show_text_glyphs (void *abstract_surface,
}
if (num_clusters) {
command->clusters = _cairo_malloc_ab (num_clusters, sizeof (clusters[0]));
- if (command->clusters == NULL) {
+ if (unlikely (command->clusters == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto CLEANUP_ARRAYS;
}
@@ -499,7 +499,7 @@ _cairo_meta_surface_show_text_glyphs (void *abstract_surface,
command->scaled_font = cairo_scaled_font_reference (scaled_font);
status = _cairo_array_append (&meta->commands, &command);
- if (status)
+ if (unlikely (status))
goto CLEANUP_SCALED_FONT;
return CAIRO_STATUS_SUCCESS;
@@ -537,7 +537,7 @@ _cairo_meta_surface_snapshot (void *abstract_other)
cairo_meta_surface_t *meta;
meta = malloc (sizeof (cairo_meta_surface_t));
- if (meta == NULL)
+ if (unlikely (meta == NULL))
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
_cairo_surface_init (&meta->base, &cairo_meta_surface_backend,
@@ -567,7 +567,7 @@ _cairo_meta_surface_intersect_clip_path (void *dst,
cairo_status_t status;
command = malloc (sizeof (cairo_command_intersect_clip_path_t));
- if (command == NULL)
+ if (unlikely (command == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
command->header.type = CAIRO_COMMAND_INTERSECT_CLIP_PATH;
@@ -575,7 +575,7 @@ _cairo_meta_surface_intersect_clip_path (void *dst,
if (path) {
status = _cairo_path_fixed_init_copy (&command->path, path);
- if (status) {
+ if (unlikely (status)) {
free (command);
return status;
}
@@ -590,7 +590,7 @@ _cairo_meta_surface_intersect_clip_path (void *dst,
command->antialias = antialias;
status = _cairo_array_append (&meta->commands, &command);
- if (status) {
+ if (unlikely (status)) {
if (path)
_cairo_path_fixed_fini (&command->path);
free (command);
@@ -647,6 +647,8 @@ static const cairo_surface_backend_t cairo_meta_surface_backend = {
NULL, /* composite */
NULL, /* fill_rectangles */
NULL, /* composite_trapezoids */
+ NULL, /* create_span_renderer */
+ NULL, /* check_span_renderer */
NULL, /* copy_page */
NULL, /* show_page */
NULL, /* set_clip_region */
@@ -766,7 +768,7 @@ _cairo_meta_surface_get_path (cairo_surface_t *surface,
ASSERT_NOT_REACHED;
}
- if (status)
+ if (unlikely (status))
break;
}
@@ -814,14 +816,14 @@ _cairo_meta_surface_replay_internal (cairo_surface_t *surface,
* ensure the current clip gets set on the surface. */
if (command->header.type != CAIRO_COMMAND_INTERSECT_CLIP_PATH) {
status = _cairo_surface_set_clip (target, &clip);
- if (status)
+ if (unlikely (status))
break;
}
dev_path = _cairo_command_get_path (command);
if (dev_path && has_device_transform) {
status = _cairo_path_fixed_init_copy (&path_copy, dev_path);
- if (status)
+ if (unlikely (status))
break;
_cairo_path_fixed_transform (&path_copy, device_transform);
dev_path = &path_copy;
@@ -930,7 +932,7 @@ _cairo_meta_surface_replay_internal (cairo_surface_t *surface,
* copy the array before handing it to the backend.
*/
dev_glyphs = _cairo_malloc_ab (num_glyphs, sizeof (cairo_glyph_t));
- if (dev_glyphs == NULL) {
+ if (unlikely (dev_glyphs == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
break;
}
@@ -986,7 +988,7 @@ _cairo_meta_surface_replay_internal (cairo_surface_t *surface,
}
}
- if (status)
+ if (unlikely (status))
break;
}
diff --git a/src/cairo-misc.c b/src/cairo-misc.c
index 397b0efe..6f707a66 100644
--- a/src/cairo-misc.c
+++ b/src/cairo-misc.c
@@ -287,7 +287,7 @@ _cairo_validate_text_clusters (const char *utf8,
/* Make sure we've got valid UTF-8 for the cluster */
status = _cairo_utf8_to_ucs4 (utf8+n_bytes, cluster_bytes, NULL, NULL);
- if (status)
+ if (unlikely (status))
return CAIRO_STATUS_INVALID_CLUSTERS;
n_bytes += cluster_bytes ;
@@ -714,14 +714,19 @@ _cairo_intern_string (const char **str_inout, int len)
tmpl.string = (char *) str;
CAIRO_MUTEX_LOCK (_cairo_intern_string_mutex);
- if (_cairo_intern_string_ht == NULL)
+ if (_cairo_intern_string_ht == NULL) {
_cairo_intern_string_ht = _cairo_hash_table_create (_intern_string_equal);
+ if (unlikely (_cairo_intern_string_ht == NULL)) {
+ status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ goto BAIL;
+ }
+ }
istring = _cairo_hash_table_lookup (_cairo_intern_string_ht,
&tmpl.hash_entry);
if (istring == NULL) {
istring = malloc (sizeof (cairo_intern_string_t) + len + 1);
- if (istring != NULL) {
+ if (likely (istring != NULL)) {
istring->hash_entry.hash = tmpl.hash_entry.hash;
istring->len = tmpl.len;
istring->string = (char *) (istring + 1);
@@ -730,17 +735,20 @@ _cairo_intern_string (const char **str_inout, int len)
status = _cairo_hash_table_insert (_cairo_intern_string_ht,
&istring->hash_entry);
- if (status)
+ if (unlikely (status)) {
free (istring);
- } else
+ goto BAIL;
+ }
+ } else {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ goto BAIL;
+ }
}
- CAIRO_MUTEX_UNLOCK (_cairo_intern_string_mutex);
-
- if (status == CAIRO_STATUS_SUCCESS)
- *str_inout = istring->string;
+ *str_inout = istring->string;
+ BAIL:
+ CAIRO_MUTEX_UNLOCK (_cairo_intern_string_mutex);
return status;
}
diff --git a/src/cairo-os2-surface.c b/src/cairo-os2-surface.c
index e4cef052..02840e33 100644
--- a/src/cairo-os2-surface.c
+++ b/src/cairo-os2-surface.c
@@ -1326,6 +1326,8 @@ static const cairo_surface_backend_t cairo_os2_surface_backend = {
NULL, /* composite */
NULL, /* fill_rectangles */
NULL, /* composite_trapezoids */
+ NULL, /* create_span_renderer */
+ NULL, /* check_span_renderer */
NULL, /* copy_page */
NULL, /* show_page */
NULL, /* set_clip_region */
diff --git a/src/cairo-output-stream.c b/src/cairo-output-stream.c
index 9a58aac2..71154339 100644
--- a/src/cairo-output-stream.c
+++ b/src/cairo-output-stream.c
@@ -147,7 +147,7 @@ _cairo_output_stream_create (cairo_write_func_t write_func,
cairo_output_stream_with_closure_t *stream;
stream = malloc (sizeof (cairo_output_stream_with_closure_t));
- if (stream == NULL) {
+ if (unlikely (stream == NULL)) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return (cairo_output_stream_t *) &_cairo_output_stream_nil;
}
@@ -173,7 +173,7 @@ _cairo_output_stream_create_in_error (cairo_status_t status)
return (cairo_output_stream_t *) &_cairo_output_stream_nil_write_error;
stream = malloc (sizeof (cairo_output_stream_t));
- if (stream == NULL) {
+ if (unlikely (stream == NULL)) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return (cairo_output_stream_t *) &_cairo_output_stream_nil;
}
@@ -598,7 +598,7 @@ _cairo_output_stream_create_for_file (FILE *file)
}
stream = malloc (sizeof *stream);
- if (stream == NULL) {
+ if (unlikely (stream == NULL)) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return (cairo_output_stream_t *) &_cairo_output_stream_nil;
}
@@ -632,7 +632,7 @@ _cairo_output_stream_create_for_filename (const char *filename)
}
stream = malloc (sizeof *stream);
- if (stream == NULL) {
+ if (unlikely (stream == NULL)) {
fclose (file);
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return (cairo_output_stream_t *) &_cairo_output_stream_nil;
@@ -676,7 +676,7 @@ _cairo_memory_stream_create (void)
memory_stream_t *stream;
stream = malloc (sizeof *stream);
- if (stream == NULL) {
+ if (unlikely (stream == NULL)) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return (cairo_output_stream_t *) &_cairo_output_stream_nil;
}
@@ -696,14 +696,14 @@ _cairo_memory_stream_destroy (cairo_output_stream_t *abstract_stream,
cairo_status_t status;
status = abstract_stream->status;
- if (status)
+ if (unlikely (status))
return _cairo_output_stream_destroy (abstract_stream);
stream = (memory_stream_t *) abstract_stream;
*length_out = _cairo_array_num_elements (&stream->array);
*data_out = malloc (*length_out);
- if (*data_out == NULL) {
+ if (unlikely (*data_out == NULL)) {
status = _cairo_output_stream_destroy (abstract_stream);
assert (status == CAIRO_STATUS_SUCCESS);
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
@@ -753,7 +753,7 @@ _cairo_null_stream_create (void)
cairo_output_stream_t *stream;
stream = malloc (sizeof *stream);
- if (stream == NULL) {
+ if (unlikely (stream == NULL)) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return (cairo_output_stream_t *) &_cairo_output_stream_nil;
}
diff --git a/src/cairo-paginated-surface.c b/src/cairo-paginated-surface.c
index bb542ff0..ce4e4def 100644
--- a/src/cairo-paginated-surface.c
+++ b/src/cairo-paginated-surface.c
@@ -77,7 +77,7 @@ _cairo_paginated_surface_create (cairo_surface_t *target,
cairo_status_t status;
surface = malloc (sizeof (cairo_paginated_surface_t));
- if (surface == NULL) {
+ if (unlikely (surface == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto FAIL;
}
@@ -99,7 +99,7 @@ _cairo_paginated_surface_create (cairo_surface_t *target,
surface->meta = _cairo_meta_surface_create (content, width, height);
status = cairo_surface_status (surface->meta);
- if (status)
+ if (unlikely (status))
goto FAIL_CLEANUP_SURFACE;
surface->page_num = 1;
@@ -151,7 +151,7 @@ _cairo_paginated_surface_set_size (cairo_surface_t *surface,
paginated_surface->meta = _cairo_meta_surface_create (paginated_surface->content,
width, height);
status = cairo_surface_status (paginated_surface->meta);
- if (status)
+ if (unlikely (status))
return _cairo_surface_set_error (surface, status);
return CAIRO_STATUS_SUCCESS;
@@ -215,7 +215,7 @@ _cairo_paginated_surface_acquire_source_image (void *abstract_surface,
cairo_rectangle_int_t extents;
status = _cairo_surface_get_extents (surface->target, &extents);
- if (status)
+ if (unlikely (status))
return status;
image = _cairo_paginated_surface_create_image_surface (surface,
@@ -223,7 +223,7 @@ _cairo_paginated_surface_acquire_source_image (void *abstract_surface,
extents.height);
status = _cairo_meta_surface_replay (surface->meta, image);
- if (status) {
+ if (unlikely (status)) {
cairo_surface_destroy (image);
return status;
}
@@ -267,7 +267,7 @@ _paint_fallback_image (cairo_paginated_surface_t *surface,
cairo_surface_set_device_offset (image, -x*x_scale, -y*y_scale);
status = _cairo_meta_surface_replay (surface->meta, image);
- if (status)
+ if (unlikely (status))
goto CLEANUP_IMAGE;
_cairo_pattern_init_for_surface (&pattern, image);
@@ -318,7 +318,7 @@ _paint_page (cairo_paginated_surface_t *surface)
_cairo_analysis_surface_get_bounding_box (analysis, &bbox);
status = surface->backend->set_bounding_box (surface->target, &bbox);
- if (status)
+ if (unlikely (status))
goto FAIL;
}
@@ -327,7 +327,7 @@ _paint_page (cairo_paginated_surface_t *surface)
status = surface->backend->set_fallback_images_required (surface->target,
has_fallbacks);
- if (status)
+ if (unlikely (status))
goto FAIL;
}
@@ -360,7 +360,7 @@ _paint_page (cairo_paginated_surface_t *surface)
surface->target,
CAIRO_META_REGION_NATIVE);
assert (status != CAIRO_INT_STATUS_UNSUPPORTED);
- if (status)
+ if (unlikely (status))
goto FAIL;
}
@@ -375,7 +375,7 @@ _paint_page (cairo_paginated_surface_t *surface)
box.p2.x = surface->width;
box.p2.y = surface->height;
status = _paint_fallback_image (surface, &box);
- if (status)
+ if (unlikely (status))
goto FAIL;
}
@@ -393,19 +393,19 @@ _paint_page (cairo_paginated_surface_t *surface)
CAIRO_FILL_RULE_WINDING,
CAIRO_GSTATE_TOLERANCE_DEFAULT,
CAIRO_ANTIALIAS_DEFAULT);
- if (status)
+ if (unlikely (status))
goto FAIL;
region = _cairo_analysis_surface_get_unsupported (analysis);
num_boxes = 0;
status = _cairo_region_get_boxes (region, &num_boxes, &boxes);
- if (status)
+ if (unlikely (status))
goto FAIL;
for (i = 0; i < num_boxes; i++) {
status = _paint_fallback_image (surface, &boxes[i]);
- if (status) {
+ if (unlikely (status)) {
_cairo_region_boxes_fini (region, boxes);
goto FAIL;
}
@@ -439,11 +439,11 @@ _cairo_paginated_surface_copy_page (void *abstract_surface)
cairo_paginated_surface_t *surface = abstract_surface;
status = _start_page (surface);
- if (status)
+ if (unlikely (status))
return status;
status = _paint_page (surface);
- if (status)
+ if (unlikely (status))
return status;
surface->page_num++;
@@ -466,20 +466,20 @@ _cairo_paginated_surface_show_page (void *abstract_surface)
cairo_paginated_surface_t *surface = abstract_surface;
status = _start_page (surface);
- if (status)
+ if (unlikely (status))
return status;
status = _paint_page (surface);
- if (status)
+ if (unlikely (status))
return status;
cairo_surface_show_page (surface->target);
status = cairo_surface_status (surface->target);
- if (status)
+ if (unlikely (status))
return status;
status = cairo_surface_status (surface->meta);
- if (status)
+ if (unlikely (status))
return status;
cairo_surface_destroy (surface->meta);
@@ -488,7 +488,7 @@ _cairo_paginated_surface_show_page (void *abstract_surface)
surface->width,
surface->height);
status = cairo_surface_status (surface->meta);
- if (status)
+ if (unlikely (status))
return status;
surface->page_num++;
@@ -678,6 +678,8 @@ static const cairo_surface_backend_t cairo_paginated_surface_backend = {
NULL, /* composite */
NULL, /* fill_rectangles */
NULL, /* composite_trapezoids */
+ NULL, /* create_span_renderer */
+ NULL, /* check_span_renderer */
_cairo_paginated_surface_copy_page,
_cairo_paginated_surface_show_page,
NULL, /* set_clip_region */
diff --git a/src/cairo-path-fill.c b/src/cairo-path-fill.c
index a6dea083..7af91d20 100644
--- a/src/cairo-path-fill.c
+++ b/src/cairo-path-fill.c
@@ -177,18 +177,18 @@ _cairo_path_fixed_fill_to_traps (cairo_path_fixed_t *path,
_cairo_filler_curve_to,
_cairo_filler_close_path,
&filler);
- if (status)
+ if (unlikely (status))
goto BAIL;
_cairo_polygon_close (&filler.polygon);
status = _cairo_polygon_status (&filler.polygon);
- if (status)
+ if (unlikely (status))
goto BAIL;
status = _cairo_bentley_ottmann_tessellate_polygon (filler.traps,
&filler.polygon,
fill_rule);
- if (status)
+ if (unlikely (status))
goto BAIL;
BAIL:
@@ -237,7 +237,7 @@ _cairo_path_fixed_fill_rectangle (cairo_path_fixed_t *path,
* GdkRegion clip region during exposes.
*/
_cairo_path_fixed_iter_init (&iter, path);
- while (_cairo_path_fixed_iter_is_box (&iter, &box)) {
+ while (_cairo_path_fixed_iter_is_fill_box (&iter, &box)) {
cairo_status_t status;
int cw = 0;
diff --git a/src/cairo-path-fixed-private.h b/src/cairo-path-fixed-private.h
index c995e2a9..0ade9880 100644
--- a/src/cairo-path-fixed-private.h
+++ b/src/cairo-path-fixed-private.h
@@ -54,9 +54,9 @@ typedef char cairo_path_op_t;
typedef struct _cairo_path_buf {
struct _cairo_path_buf *next, *prev;
- int buf_size;
- int num_ops;
- int num_points;
+ unsigned int buf_size;
+ unsigned int num_ops;
+ unsigned int num_points;
cairo_path_op_t *op;
cairo_point_t *points;
@@ -90,8 +90,8 @@ _cairo_path_fixed_equal (const cairo_path_fixed_t *a,
typedef struct _cairo_path_fixed_iter {
cairo_path_buf_t *buf;
- int n_op;
- int n_point;
+ unsigned int n_op;
+ unsigned int n_point;
} cairo_path_fixed_iter_t;
cairo_private void
@@ -99,8 +99,8 @@ _cairo_path_fixed_iter_init (cairo_path_fixed_iter_t *iter,
cairo_path_fixed_t *path);
cairo_private cairo_bool_t
-_cairo_path_fixed_iter_is_box (cairo_path_fixed_iter_t *_iter,
- cairo_box_t *box);
+_cairo_path_fixed_iter_is_fill_box (cairo_path_fixed_iter_t *_iter,
+ cairo_box_t *box);
cairo_private cairo_bool_t
_cairo_path_fixed_iter_at_end (const cairo_path_fixed_iter_t *iter);
diff --git a/src/cairo-path-fixed.c b/src/cairo-path-fixed.c
index ffaf58c1..dd25bb88 100644
--- a/src/cairo-path-fixed.c
+++ b/src/cairo-path-fixed.c
@@ -120,7 +120,7 @@ _cairo_path_fixed_init_copy (cairo_path_fixed_t *path,
buf_size = MAX (num_ops, (num_points + 1) / 2);
if (buf_size) {
buf = _cairo_path_buf_create (buf_size);
- if (buf == NULL) {
+ if (unlikely (buf == NULL)) {
_cairo_path_fixed_fini (path);
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
@@ -372,7 +372,7 @@ _cairo_path_fixed_move_to (cairo_path_fixed_t *path,
*last_move_to_point = point;
} else {
status = _cairo_path_fixed_add (path, CAIRO_PATH_OP_MOVE_TO, &point, 1);
- if (status)
+ if (unlikely (status))
return status;
}
@@ -426,7 +426,7 @@ _cairo_path_fixed_line_to (cairo_path_fixed_t *path,
else
status = _cairo_path_fixed_add (path, CAIRO_PATH_OP_LINE_TO, &point, 1);
- if (status)
+ if (unlikely (status))
return status;
path->current_point = point;
@@ -467,12 +467,12 @@ _cairo_path_fixed_curve_to (cairo_path_fixed_t *path,
if (! path->has_current_point) {
status = _cairo_path_fixed_add (path, CAIRO_PATH_OP_MOVE_TO,
&point[0], 1);
- if (status)
+ if (unlikely (status))
return status;
}
status = _cairo_path_fixed_add (path, CAIRO_PATH_OP_CURVE_TO, point, 3);
- if (status)
+ if (unlikely (status))
return status;
path->current_point = point[2];
@@ -519,13 +519,13 @@ _cairo_path_fixed_close_path (cairo_path_fixed_t *path)
return CAIRO_STATUS_SUCCESS;
status = _cairo_path_fixed_add (path, CAIRO_PATH_OP_CLOSE_PATH, NULL, 0);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_path_fixed_move_to (path,
path->last_move_point.x,
path->last_move_point.y);
- if (status)
+ if (unlikely (status))
return status;
return CAIRO_STATUS_SUCCESS;
@@ -557,7 +557,7 @@ _cairo_path_fixed_add (cairo_path_fixed_t *path,
buf->num_points + num_points > 2 * buf->buf_size)
{
buf = _cairo_path_buf_create (buf->buf_size * 2);
- if (buf == NULL)
+ if (unlikely (buf == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
_cairo_path_fixed_add_buf (path, buf);
@@ -692,7 +692,7 @@ _cairo_path_fixed_interpret (const cairo_path_fixed_t *path,
status = (*close_path) (closure);
break;
}
- if (status)
+ if (unlikely (status))
return status;
if (forward) {
@@ -759,7 +759,7 @@ _cairo_path_fixed_offset_and_scale (cairo_path_fixed_t *path,
cairo_fixed_t scaley)
{
cairo_path_buf_t *buf = &path->buf_head.base;
- int i;
+ unsigned int i;
while (buf) {
for (i = 0; i < buf->num_points; i++) {
@@ -790,7 +790,7 @@ _cairo_path_fixed_transform (cairo_path_fixed_t *path,
cairo_matrix_t *matrix)
{
cairo_path_buf_t *buf;
- int i;
+ unsigned int i;
double dx, dy;
if (matrix->yx == 0.0 && matrix->xy == 0.0) {
@@ -930,6 +930,15 @@ _cairo_path_fixed_interpret_flat (const cairo_path_fixed_t *path,
{
cpf_t flattener;
+ if (!path->has_curve_to) {
+ return _cairo_path_fixed_interpret (path, dir,
+ move_to,
+ line_to,
+ NULL,
+ close_path,
+ closure);
+ }
+
flattener.tolerance = tolerance;
flattener.move_to = move_to;
flattener.line_to = line_to;
@@ -1058,7 +1067,7 @@ _cairo_path_fixed_iter_init (cairo_path_fixed_iter_t *iter,
static cairo_bool_t
_cairo_path_fixed_iter_next_op (cairo_path_fixed_iter_t *iter)
{
- if (++iter->n_op == iter->buf->num_ops) {
+ if (++iter->n_op >= iter->buf->num_ops) {
iter->buf = iter->buf->next;
iter->n_op = 0;
iter->n_point = 0;
@@ -1068,8 +1077,8 @@ _cairo_path_fixed_iter_next_op (cairo_path_fixed_iter_t *iter)
}
cairo_bool_t
-_cairo_path_fixed_iter_is_box (cairo_path_fixed_iter_t *_iter,
- cairo_box_t *box)
+_cairo_path_fixed_iter_is_fill_box (cairo_path_fixed_iter_t *_iter,
+ cairo_box_t *box)
{
cairo_point_t points[5];
cairo_path_fixed_iter_t iter;
@@ -1079,6 +1088,12 @@ _cairo_path_fixed_iter_is_box (cairo_path_fixed_iter_t *_iter,
iter = *_iter;
+ if (iter.n_op == iter.buf->num_ops &&
+ ! _cairo_path_fixed_iter_next_op (&iter))
+ {
+ return FALSE;
+ }
+
/* Check whether the ops are those that would be used for a rectangle */
if (iter.buf->op[iter.n_op] != CAIRO_PATH_OP_MOVE_TO)
return FALSE;
@@ -1106,12 +1121,16 @@ _cairo_path_fixed_iter_is_box (cairo_path_fixed_iter_t *_iter,
/* Now, there are choices. The rectangle might end with a LINE_TO
* (to the original point), but this isn't required. If it
- * doesn't, then it must end with a CLOSE_PATH. */
- if (iter.buf->op[iter.n_op] == CAIRO_PATH_OP_LINE_TO) {
+ * doesn't, then it must end with a CLOSE_PATH (which may be implicit). */
+ if (iter.buf->op[iter.n_op] == CAIRO_PATH_OP_LINE_TO)
+ {
points[4] = iter.buf->points[iter.n_point++];
if (points[4].x != points[0].x || points[4].y != points[0].y)
return FALSE;
- } else if (iter.buf->op[iter.n_op] != CAIRO_PATH_OP_CLOSE_PATH) {
+ }
+ else if (! (iter.buf->op[iter.n_op] == CAIRO_PATH_OP_CLOSE_PATH ||
+ iter.buf->op[iter.n_op] == CAIRO_PATH_OP_MOVE_TO))
+ {
return FALSE;
}
if (! _cairo_path_fixed_iter_next_op (&iter))
@@ -1149,6 +1168,9 @@ _cairo_path_fixed_iter_at_end (const cairo_path_fixed_iter_t *iter)
if (iter->buf == NULL)
return TRUE;
+ if (iter->n_op == iter->buf->num_ops)
+ return TRUE;
+
if (iter->buf->op[iter->n_op] == CAIRO_PATH_OP_MOVE_TO &&
iter->buf->num_ops == iter->n_op + 1)
{
@@ -1157,3 +1179,99 @@ _cairo_path_fixed_iter_at_end (const cairo_path_fixed_iter_t *iter)
return FALSE;
}
+
+/* Closure for path region testing. Every move_to must be to integer
+ * coordinates, there must be no curves, and every line_to or
+ * close_path must represent an axis aligned line to an integer point.
+ * We're relying on the path interpreter always sending a single
+ * move_to at the start of any subpath, not receiving having any
+ * superfluous move_tos, and the path intepreter bailing with our
+ * first non-successful error. */
+typedef struct cairo_path_region_tester {
+ cairo_point_t last_move_point;
+ cairo_point_t current_point;
+} cprt_t;
+
+static cairo_status_t
+_cprt_line_to (void *closure,
+ cairo_point_t *p2)
+{
+ cprt_t *self = closure;
+ cairo_point_t *p1 = &self->current_point;
+ if (p2->x == p1->x) {
+ if (_cairo_fixed_is_integer(p2->y)) {
+ *p1 = *p2;
+ return CAIRO_STATUS_SUCCESS;
+ }
+ }
+ else if (p2->y == p1->y) {
+ if (_cairo_fixed_is_integer(p2->x)) {
+ *p1 = *p2;
+ return CAIRO_STATUS_SUCCESS;
+ }
+ }
+ return CAIRO_INT_STATUS_UNSUPPORTED;
+}
+
+static cairo_status_t
+_cprt_close_path (void *closure)
+{
+ cprt_t *self = closure;
+ return _cprt_line_to (closure, &self->last_move_point);
+}
+
+static cairo_status_t
+_cprt_move_to (void *closure,
+ cairo_point_t *p)
+{
+ cprt_t *self = closure;
+ cairo_status_t status = _cprt_close_path (closure);
+ if (status) return status;
+ if (_cairo_fixed_is_integer(p->x) &&
+ _cairo_fixed_is_integer(p->y))
+ {
+ self->current_point = *p;
+ self->last_move_point = *p;
+ return CAIRO_STATUS_SUCCESS;
+ }
+ return CAIRO_INT_STATUS_UNSUPPORTED;
+}
+
+static cairo_status_t
+_cprt_curve_to (void *closure,
+ cairo_point_t *p0,
+ cairo_point_t *p1,
+ cairo_point_t *p2)
+{
+ (void)closure;
+ (void)p0;
+ (void)p1;
+ (void)p2;
+ return CAIRO_INT_STATUS_UNSUPPORTED;
+}
+
+/**
+ * Check whether the given path is representable as a region.
+ * That is, if the path contains only axis aligned lines between
+ * integer coordinates in device space.
+ */
+cairo_bool_t
+_cairo_path_fixed_is_region (cairo_path_fixed_t *path)
+{
+ cprt_t cprt;
+ cairo_status_t status;
+ if (path->has_curve_to)
+ return FALSE;
+ cprt.current_point.x = 0;
+ cprt.current_point.y = 0;
+ cprt.last_move_point.x = 0;
+ cprt.last_move_point.y = 0;
+ status = _cairo_path_fixed_interpret (path,
+ CAIRO_DIRECTION_FORWARD,
+ _cprt_move_to,
+ _cprt_line_to,
+ _cprt_curve_to,
+ _cprt_close_path,
+ &cprt);
+ return status == CAIRO_STATUS_SUCCESS;
+}
diff --git a/src/cairo-path-stroke.c b/src/cairo-path-stroke.c
index 3c02a94c..8c3064ea 100644
--- a/src/cairo-path-stroke.c
+++ b/src/cairo-path-stroke.c
@@ -175,7 +175,7 @@ _cairo_stroker_init (cairo_stroker_t *stroker,
status = _cairo_pen_init (&stroker->pen,
stroke_style->line_width / 2.0,
tolerance, ctm);
- if (status)
+ if (unlikely (status))
return status;
stroker->has_current_face = FALSE;
@@ -658,22 +658,22 @@ _cairo_stroker_add_caps (cairo_stroker_t *stroker)
_compute_face (&stroker->first_point, &slope, dx, dy, stroker, &face);
status = _cairo_stroker_add_leading_cap (stroker, &face);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_stroker_add_trailing_cap (stroker, &face);
- if (status)
+ if (unlikely (status))
return status;
}
if (stroker->has_first_face) {
status = _cairo_stroker_add_leading_cap (stroker, &stroker->first_face);
- if (status)
+ if (unlikely (status))
return status;
}
if (stroker->has_current_face) {
status = _cairo_stroker_add_trailing_cap (stroker, &stroker->current_face);
- if (status)
+ if (unlikely (status))
return status;
}
@@ -761,7 +761,7 @@ _cairo_stroker_move_to (void *closure, cairo_point_t *point)
/* Cap the start and end of the previous sub path as needed */
status = _cairo_stroker_add_caps (stroker);
- if (status)
+ if (unlikely (status))
return status;
stroker->first_point = *point;
@@ -806,13 +806,13 @@ _cairo_stroker_line_to (void *closure, cairo_point_t *point)
_compute_normalized_device_slope (&slope_dx, &slope_dy, stroker->ctm_inverse, NULL);
status = _cairo_stroker_add_sub_edge (stroker, p1, p2, &dev_slope, slope_dx, slope_dy, &start, &end);
- if (status)
+ if (unlikely (status))
return status;
if (stroker->has_current_face) {
/* Join with final face from previous segment */
status = _cairo_stroker_join (stroker, &stroker->current_face, &start);
- if (status)
+ if (unlikely (status))
return status;
} else if (!stroker->has_first_face) {
/* Save sub path's first face in case needed for closing join */
@@ -890,7 +890,7 @@ _cairo_stroker_line_to_dashed (void *closure, cairo_point_t *point)
&dev_slope,
slope_dx, slope_dy,
&sub_start, &sub_end);
- if (status)
+ if (unlikely (status))
return status;
if (stroker->has_current_face) {
@@ -898,7 +898,7 @@ _cairo_stroker_line_to_dashed (void *closure, cairo_point_t *point)
status = _cairo_stroker_join (stroker,
&stroker->current_face,
&sub_start);
- if (status)
+ if (unlikely (status))
return status;
stroker->has_current_face = FALSE;
@@ -909,14 +909,14 @@ _cairo_stroker_line_to_dashed (void *closure, cairo_point_t *point)
} else {
/* Cap dash start if not connecting to a previous segment */
status = _cairo_stroker_add_leading_cap (stroker, &sub_start);
- if (status)
+ if (unlikely (status))
return status;
}
if (remain) {
/* Cap dash end if not at end of segment */
status = _cairo_stroker_add_trailing_cap (stroker, &sub_end);
- if (status)
+ if (unlikely (status))
return status;
} else {
stroker->current_face = sub_end;
@@ -927,7 +927,7 @@ _cairo_stroker_line_to_dashed (void *closure, cairo_point_t *point)
/* Cap final face from previous segment */
status = _cairo_stroker_add_trailing_cap (stroker,
&stroker->current_face);
- if (status)
+ if (unlikely (status))
return status;
stroker->has_current_face = FALSE;
@@ -955,7 +955,7 @@ _cairo_stroker_line_to_dashed (void *closure, cairo_point_t *point)
status = _cairo_stroker_add_leading_cap (stroker,
&stroker->current_face);
- if (status)
+ if (unlikely (status))
return status;
stroker->has_current_face = TRUE;
@@ -986,7 +986,7 @@ _cairo_stroker_curve_to (void *closure,
a, b, c, d);
if (status == CAIRO_INT_STATUS_DEGENERATE)
return _cairo_stroker_line_to (closure, d);
- else if (status)
+ else if (unlikely (status))
return status;
initial_slope_dx = _cairo_fixed_to_double (spline_pen.spline.initial_slope.dx);
@@ -1014,7 +1014,7 @@ _cairo_stroker_curve_to (void *closure,
if (stroker->has_current_face) {
status = _cairo_stroker_join (stroker, &stroker->current_face, &start);
- if (status)
+ if (unlikely (status))
goto CLEANUP_PEN;
} else if (! stroker->has_first_face) {
stroker->first_face = start;
@@ -1037,7 +1037,7 @@ _cairo_stroker_curve_to (void *closure,
extra_points[3].y -= end.point.y;
status = _cairo_pen_add_points (&spline_pen.pen, extra_points, 4);
- if (status)
+ if (unlikely (status))
goto CLEANUP_PEN;
status = _cairo_pen_stroke_spline (&spline_pen,
@@ -1121,18 +1121,18 @@ _cairo_stroker_close_path (void *closure)
status = _cairo_stroker_line_to_dashed (stroker, &stroker->first_point);
else
status = _cairo_stroker_line_to (stroker, &stroker->first_point);
- if (status)
+ if (unlikely (status))
return status;
if (stroker->has_first_face && stroker->has_current_face) {
/* Join first and final faces of sub path */
status = _cairo_stroker_join (stroker, &stroker->current_face, &stroker->first_face);
- if (status)
+ if (unlikely (status))
return status;
} else {
/* Cap the start and end of the sub path as needed */
status = _cairo_stroker_add_caps (stroker);
- if (status)
+ if (unlikely (status))
return status;
}
@@ -1175,7 +1175,7 @@ _cairo_path_fixed_stroke_to_traps (cairo_path_fixed_t *path,
status = _cairo_stroker_init (&stroker, stroke_style,
ctm, ctm_inverse, tolerance,
traps);
- if (status)
+ if (unlikely (status))
return status;
if (stroker.style->dash)
@@ -1194,7 +1194,7 @@ _cairo_path_fixed_stroke_to_traps (cairo_path_fixed_t *path,
_cairo_stroker_curve_to,
_cairo_stroker_close_path,
&stroker);
- if (status)
+ if (unlikely (status))
goto BAIL;
/* Cap the start and end of the final sub path as needed */
@@ -1254,7 +1254,7 @@ _cairo_rectilinear_stroker_add_segment (cairo_rectilinear_stroker_t *stroker,
if (stroker->segments == stroker->segments_embedded) {
new_segments = _cairo_malloc_ab (new_size, sizeof (cairo_line_t));
- if (new_segments == NULL)
+ if (unlikely (new_segments == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
memcpy (new_segments, stroker->segments,
@@ -1262,7 +1262,7 @@ _cairo_rectilinear_stroker_add_segment (cairo_rectilinear_stroker_t *stroker,
} else {
new_segments = _cairo_realloc_ab (stroker->segments,
new_size, sizeof (cairo_line_t));
- if (new_segments == NULL)
+ if (unlikely (new_segments == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
@@ -1386,7 +1386,7 @@ _cairo_rectilinear_stroker_emit_segments (cairo_rectilinear_stroker_t *stroker)
}
status = _cairo_traps_tessellate_rectangle (stroker->traps, a, b);
- if (status)
+ if (unlikely (status))
return status;
}
@@ -1403,7 +1403,7 @@ _cairo_rectilinear_stroker_move_to (void *closure,
cairo_status_t status;
status = _cairo_rectilinear_stroker_emit_segments (stroker);
- if (status)
+ if (unlikely (status))
return status;
stroker->current_point = *point;
@@ -1449,13 +1449,13 @@ _cairo_rectilinear_stroker_close_path (void *closure)
status = _cairo_rectilinear_stroker_line_to (stroker,
&stroker->first_point);
- if (status)
+ if (unlikely (status))
return status;
stroker->open_sub_path = FALSE;
status = _cairo_rectilinear_stroker_emit_segments (stroker);
- if (status)
+ if (unlikely (status))
return status;
return CAIRO_STATUS_SUCCESS;
@@ -1512,7 +1512,7 @@ _cairo_path_fixed_stroke_rectilinear (cairo_path_fixed_t *path,
NULL,
_cairo_rectilinear_stroker_close_path,
&rectilinear_stroker);
- if (status)
+ if (unlikely (status))
goto BAIL;
status = _cairo_rectilinear_stroker_emit_segments (&rectilinear_stroker);
@@ -1520,7 +1520,7 @@ _cairo_path_fixed_stroke_rectilinear (cairo_path_fixed_t *path,
BAIL:
_cairo_rectilinear_stroker_fini (&rectilinear_stroker);
- if (status)
+ if (unlikely (status))
_cairo_traps_clear (traps);
return status;
diff --git a/src/cairo-path.c b/src/cairo-path.c
index c6639f3f..84dfc0c4 100644
--- a/src/cairo-path.c
+++ b/src/cairo-path.c
@@ -127,7 +127,7 @@ _cairo_path_count (cairo_path_t *path,
&cpc);
}
- if (status)
+ if (unlikely (status))
return -1;
return cpc.count;
@@ -283,7 +283,7 @@ _cairo_path_populate (cairo_path_t *path,
&cpp);
}
- if (status)
+ if (unlikely (status))
return status;
/* Sanity check the count */
@@ -302,7 +302,7 @@ _cairo_path_create_in_error (cairo_status_t status)
return (cairo_path_t*) &_cairo_path_nil;
path = malloc (sizeof (cairo_path_t));
- if (path == NULL) {
+ if (unlikely (path == NULL)) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return (cairo_path_t*) &_cairo_path_nil;
}
@@ -322,7 +322,7 @@ _cairo_path_create_internal (cairo_path_fixed_t *path_fixed,
cairo_path_t *path;
path = malloc (sizeof (cairo_path_t));
- if (path == NULL) {
+ if (unlikely (path == NULL)) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return (cairo_path_t*) &_cairo_path_nil;
}
@@ -337,8 +337,8 @@ _cairo_path_create_internal (cairo_path_fixed_t *path_fixed,
if (path->num_data) {
path->data = _cairo_malloc_ab (path->num_data,
- sizeof (cairo_path_data_t));
- if (path->data == NULL) {
+ sizeof (cairo_path_data_t));
+ if (unlikely (path->data == NULL)) {
free (path);
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return (cairo_path_t*) &_cairo_path_nil;
@@ -474,7 +474,7 @@ _cairo_path_append_to_context (const cairo_path_t *path,
}
status = cairo_status (cr);
- if (status)
+ if (unlikely (status))
return status;
}
diff --git a/src/cairo-pattern.c b/src/cairo-pattern.c
index bdcafe7c..aa580d55 100644
--- a/src/cairo-pattern.c
+++ b/src/cairo-pattern.c
@@ -140,7 +140,7 @@ _cairo_gradient_pattern_init_copy (cairo_gradient_pattern_t *pattern,
{
pattern->stops = _cairo_malloc_ab (other->stops_size,
sizeof (cairo_gradient_stop_t));
- if (pattern->stops == NULL) {
+ if (unlikely (pattern->stops == NULL)) {
pattern->stops_size = 0;
pattern->n_stops = 0;
return _cairo_pattern_set_error (&pattern->base, CAIRO_STATUS_NO_MEMORY);
@@ -181,7 +181,7 @@ _cairo_pattern_init_copy (cairo_pattern_t *pattern,
cairo_status_t status;
status = _cairo_gradient_pattern_init_copy (dst, src);
- if (status)
+ if (unlikely (status))
return status;
} break;
@@ -203,7 +203,7 @@ _cairo_pattern_init_snapshot (cairo_pattern_t *pattern,
/* We don't bother doing any fancy copy-on-write implementation
* for the pattern's data. It's generally quite tiny. */
status = _cairo_pattern_init_copy (pattern, other);
- if (status)
+ if (unlikely (status))
return status;
/* But we do let the surface snapshot stuff be as fancy as it
@@ -272,11 +272,11 @@ _cairo_pattern_create_copy (cairo_pattern_t **pattern,
*pattern = malloc (sizeof (cairo_radial_pattern_t));
break;
}
- if (*pattern == NULL)
+ if (unlikely (*pattern == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
status = _cairo_pattern_init_copy (*pattern, other);
- if (status) {
+ if (unlikely (status)) {
free (*pattern);
return status;
}
@@ -379,18 +379,17 @@ _cairo_pattern_create_solid (const cairo_color_t *color,
CAIRO_MUTEX_UNLOCK (_cairo_pattern_solid_pattern_cache_lock);
- if (pattern == NULL) {
+ if (unlikely (pattern == NULL)) {
/* None cached, need to create a new pattern. */
pattern = malloc (sizeof (cairo_solid_pattern_t));
+ if (unlikely (pattern == NULL)) {
+ _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
+ return (cairo_pattern_t *) &_cairo_pattern_nil;
+ }
}
- if (pattern == NULL) {
- _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
- pattern = (cairo_solid_pattern_t *) &_cairo_pattern_nil;
- } else {
- _cairo_pattern_init_solid (pattern, color, content);
- CAIRO_REFERENCE_COUNT_INIT (&pattern->base.ref_count, 1);
- }
+ _cairo_pattern_init_solid (pattern, color, content);
+ CAIRO_REFERENCE_COUNT_INIT (&pattern->base.ref_count, 1);
return &pattern->base;
}
@@ -535,7 +534,7 @@ cairo_pattern_create_for_surface (cairo_surface_t *surface)
return (cairo_pattern_t*) _cairo_pattern_create_in_error (surface->status);
pattern = malloc (sizeof (cairo_surface_pattern_t));
- if (pattern == NULL) {
+ if (unlikely (pattern == NULL)) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return (cairo_pattern_t *)&_cairo_pattern_nil.base;
}
@@ -581,7 +580,7 @@ cairo_pattern_create_linear (double x0, double y0, double x1, double y1)
cairo_linear_pattern_t *pattern;
pattern = malloc (sizeof (cairo_linear_pattern_t));
- if (pattern == NULL) {
+ if (unlikely (pattern == NULL)) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return (cairo_pattern_t *) &_cairo_pattern_nil.base;
}
@@ -629,7 +628,7 @@ cairo_pattern_create_radial (double cx0, double cy0, double radius0,
cairo_radial_pattern_t *pattern;
pattern = malloc (sizeof (cairo_radial_pattern_t));
- if (pattern == NULL) {
+ if (unlikely (pattern == NULL)) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return (cairo_pattern_t *) &_cairo_pattern_nil.base;
}
@@ -846,11 +845,11 @@ _cairo_pattern_gradient_grow (cairo_gradient_pattern_t *pattern)
memcpy (new_stops, pattern->stops, old_size * sizeof (cairo_gradient_stop_t));
} else {
new_stops = _cairo_realloc_ab (pattern->stops,
- new_size,
+ new_size,
sizeof (cairo_gradient_stop_t));
}
- if (new_stops == NULL)
+ if (unlikely (new_stops == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
pattern->stops = new_stops;
@@ -872,7 +871,7 @@ _cairo_pattern_add_color_stop (cairo_gradient_pattern_t *pattern,
if (pattern->n_stops >= pattern->stops_size) {
cairo_status_t status = _cairo_pattern_gradient_grow (pattern);
- if (status) {
+ if (unlikely (status)) {
status = _cairo_pattern_set_error (&pattern->base, status);
return;
}
@@ -1063,7 +1062,7 @@ cairo_pattern_set_matrix (cairo_pattern_t *pattern,
inverse = *matrix;
status = cairo_matrix_invert (&inverse);
- if (status)
+ if (unlikely (status))
status = _cairo_pattern_set_error (pattern, status);
}
slim_hidden_def (cairo_pattern_set_matrix);
@@ -1255,8 +1254,9 @@ _cairo_pattern_acquire_surface_for_gradient (const cairo_gradient_pattern_t *pat
cairo_matrix_t matrix = pattern->base.matrix;
if (pattern->n_stops > ARRAY_LENGTH(pixman_stops_static)) {
- pixman_stops = _cairo_malloc_ab (pattern->n_stops, sizeof(pixman_gradient_stop_t));
- if (pixman_stops == NULL)
+ pixman_stops = _cairo_malloc_ab (pattern->n_stops,
+ sizeof(pixman_gradient_stop_t));
+ if (unlikely (pixman_stops == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
@@ -1340,7 +1340,7 @@ _cairo_pattern_acquire_surface_for_gradient (const cairo_gradient_pattern_t *pat
if (pixman_stops != pixman_stops_static)
free (pixman_stops);
- if (pixman_image == NULL)
+ if (unlikely (pixman_image == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
if (_cairo_surface_is_image (dst))
@@ -1519,7 +1519,7 @@ _cairo_pattern_acquire_surface_for_solid (const cairo_solid_pattern_t *patt
dst))
{
status = _cairo_surface_reset (solid_surface_cache.cache[i].surface);
- if (status)
+ if (unlikely (status))
goto UNLOCK;
goto DONE;
@@ -1531,7 +1531,7 @@ _cairo_pattern_acquire_surface_for_solid (const cairo_solid_pattern_t *patt
dst))
{
status = _cairo_surface_reset (solid_surface_cache.cache[i].surface);
- if (status)
+ if (unlikely (status))
goto UNLOCK;
goto DONE;
@@ -1551,11 +1551,11 @@ _cairo_pattern_acquire_surface_for_solid (const cairo_solid_pattern_t *patt
/* Reuse the surface instead of evicting */
status = _cairo_surface_reset (surface);
- if (status)
+ if (unlikely (status))
goto EVICT;
status = _cairo_surface_repaint_solid_pattern_surface (dst, surface, pattern);
- if (status)
+ if (unlikely (status))
goto EVICT;
cairo_surface_reference (surface);
@@ -1839,14 +1839,14 @@ _cairo_pattern_acquire_surface_for_surface (const cairo_surface_pattern_t *pat
int w, h;
status = _cairo_surface_get_extents (surface, &extents);
- if (status)
+ if (unlikely (status))
goto BAIL;
status = _cairo_surface_clone_similar (dst, surface,
extents.x, extents.y,
extents.width, extents.height,
&extents.x, &extents.y, &src);
- if (status)
+ if (unlikely (status))
goto BAIL;
w = 2 * extents.width;
@@ -1914,14 +1914,14 @@ _cairo_pattern_acquire_surface_for_surface (const cairo_surface_pattern_t *pat
cairo_surface_destroy (src);
- if (status)
+ if (unlikely (status))
goto BAIL;
attr->extend = CAIRO_EXTEND_REPEAT;
}
status = _cairo_surface_get_extents (surface, &extents);
- if (status)
+ if (unlikely (status))
goto BAIL;
/* We first transform the rectangle to the coordinate space of the
@@ -1969,7 +1969,7 @@ _cairo_pattern_acquire_surface_for_surface (const cairo_surface_pattern_t *pat
extents.x, extents.y,
extents.width, extents.height,
&x, &y, out);
- if (status)
+ if (unlikely (status))
goto BAIL;
if (x != 0 || y != 0) {
@@ -2184,7 +2184,7 @@ _cairo_pattern_acquire_surfaces (const cairo_pattern_t *src,
src_x, src_y,
width, height,
src_out, src_attributes);
- if (status)
+ if (unlikely (status))
goto BAIL;
if (mask == NULL) {
@@ -2196,7 +2196,7 @@ _cairo_pattern_acquire_surfaces (const cairo_pattern_t *src,
mask_x, mask_y,
width, height,
mask_out, mask_attributes);
- if (status)
+ if (unlikely (status))
_cairo_pattern_release_surface (src, *src_out, src_attributes);
BAIL:
@@ -2237,7 +2237,7 @@ _cairo_pattern_get_extents (const cairo_pattern_t *pattern,
status = _cairo_surface_get_extents (surface, &surface_extents);
if (status == CAIRO_INT_STATUS_UNSUPPORTED)
goto UNBOUNDED;
- if (status)
+ if (unlikely (status))
return status;
/* The filter can effectively enlarge the extents of the
diff --git a/src/cairo-pdf-operators.c b/src/cairo-pdf-operators.c
index d363805f..ea5c5148 100644
--- a/src/cairo-pdf-operators.c
+++ b/src/cairo-pdf-operators.c
@@ -301,7 +301,7 @@ _word_wrap_stream_create (cairo_output_stream_t *output, int max_column)
return _cairo_output_stream_create_in_error (output->status);
stream = malloc (sizeof (word_wrap_stream_t));
- if (stream == NULL) {
+ if (unlikely (stream == NULL)) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return (cairo_output_stream_t *) &_cairo_output_stream_nil;
}
@@ -447,7 +447,7 @@ _cairo_pdf_operators_emit_path (cairo_pdf_operators_t *pdf_operators,
word_wrap = _word_wrap_stream_create (pdf_operators->stream, 72);
status = _cairo_output_stream_get_status (word_wrap);
- if (status)
+ if (unlikely (status))
return _cairo_output_stream_destroy (word_wrap);
info.output = word_wrap;
@@ -488,7 +488,7 @@ _cairo_pdf_operators_clip (cairo_pdf_operators_t *pdf_operators,
path,
&pdf_operators->cairo_to_pdf,
CAIRO_LINE_CAP_ROUND);
- if (status)
+ if (unlikely (status))
return status;
}
@@ -569,7 +569,7 @@ _cairo_pdf_operators_emit_stroke_style (cairo_pdf_operators_t *pdf_operators,
*/
if (num_dashes % 2) {
dash = _cairo_malloc_abc (num_dashes, 2, sizeof (double));
- if (dash == NULL)
+ if (unlikely (dash == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
memcpy (dash, style->dash, num_dashes * sizeof (double));
@@ -585,7 +585,7 @@ _cairo_pdf_operators_emit_stroke_style (cairo_pdf_operators_t *pdf_operators,
*/
if (dash == style->dash) {
dash = _cairo_malloc_ab (num_dashes, sizeof (double));
- if (dash == NULL)
+ if (unlikely (dash == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
memcpy (dash, style->dash, num_dashes * sizeof (double));
}
@@ -714,7 +714,7 @@ _cairo_pdf_operators_emit_stroke (cairo_pdf_operators_t *pdf_operators,
if (pdf_operators->in_text_object) {
status = _cairo_pdf_operators_end_text (pdf_operators);
- if (status)
+ if (unlikely (status))
return status;
}
@@ -753,7 +753,7 @@ _cairo_pdf_operators_emit_stroke (cairo_pdf_operators_t *pdf_operators,
_cairo_matrix_factor_out_scale (&m, &scale);
path_transform = m;
status = cairo_matrix_invert (&path_transform);
- if (status)
+ if (unlikely (status))
return status;
cairo_matrix_multiply (&m, &m, &pdf_operators->cairo_to_pdf);
@@ -762,7 +762,7 @@ _cairo_pdf_operators_emit_stroke (cairo_pdf_operators_t *pdf_operators,
status = _cairo_pdf_operators_emit_stroke_style (pdf_operators, style, scale);
if (status == CAIRO_INT_STATUS_NOTHING_TO_DO)
return CAIRO_STATUS_SUCCESS;
- if (status)
+ if (unlikely (status))
return status;
if (has_ctm) {
@@ -778,7 +778,7 @@ _cairo_pdf_operators_emit_stroke (cairo_pdf_operators_t *pdf_operators,
path,
&path_transform,
style->line_cap);
- if (status)
+ if (unlikely (status))
return status;
_cairo_output_stream_printf (pdf_operators->stream, "%s", pdf_operator);
@@ -815,7 +815,7 @@ _cairo_pdf_operators_fill (cairo_pdf_operators_t *pdf_operators,
if (pdf_operators->in_text_object) {
status = _cairo_pdf_operators_end_text (pdf_operators);
- if (status)
+ if (unlikely (status))
return status;
}
@@ -823,7 +823,7 @@ _cairo_pdf_operators_fill (cairo_pdf_operators_t *pdf_operators,
path,
&pdf_operators->cairo_to_pdf,
CAIRO_LINE_CAP_ROUND);
- if (status)
+ if (unlikely (status))
return status;
switch (fill_rule) {
@@ -964,7 +964,7 @@ _cairo_pdf_operators_flush_glyphs (cairo_pdf_operators_t *pdf_operators)
word_wrap_stream = _word_wrap_stream_create (pdf_operators->stream, 72);
status = _cairo_output_stream_get_status (word_wrap_stream);
- if (status)
+ if (unlikely (status))
return _cairo_output_stream_destroy (word_wrap_stream);
/* Check if glyph advance used to position every glyph */
@@ -1023,7 +1023,7 @@ _cairo_pdf_operators_set_text_matrix (cairo_pdf_operators_t *pdf_operators,
/* We require the matrix to be invertable. */
inverse = *matrix;
status = cairo_matrix_invert (&inverse);
- if (status)
+ if (unlikely (status))
return status;
pdf_operators->text_matrix = *matrix;
@@ -1112,7 +1112,7 @@ _cairo_pdf_operators_set_font_subset (cairo_pdf_operators_t *pdf_ope
status = pdf_operators->use_font_subset (subset_glyph->font_id,
subset_glyph->subset_id,
pdf_operators->use_font_subset_closure);
- if (status)
+ if (unlikely (status))
return status;
}
pdf_operators->font_id = subset_glyph->font_id;
@@ -1143,7 +1143,7 @@ _cairo_pdf_operators_end_text (cairo_pdf_operators_t *pdf_operators)
cairo_status_t status;
status = _cairo_pdf_operators_flush_glyphs (pdf_operators);
- if (status)
+ if (unlikely (status))
return status;
_cairo_output_stream_printf (pdf_operators->stream, "ET\n");
@@ -1177,7 +1177,7 @@ _cairo_pdf_operators_begin_actualtext (cairo_pdf_operators_t *pdf_operators,
_cairo_output_stream_printf (pdf_operators->stream, "/Span << /ActualText <feff");
if (utf8_len) {
status = _cairo_utf8_to_utf16 (utf8, utf8_len, &utf16, &utf16_len);
- if (status)
+ if (unlikely (status))
return status;
for (i = 0; i < utf16_len; i++) {
@@ -1212,11 +1212,11 @@ _cairo_pdf_operators_emit_glyph (cairo_pdf_operators_t *pdf_operator
pdf_operators->subset_id != subset_glyph->subset_id)
{
status = _cairo_pdf_operators_flush_glyphs (pdf_operators);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_pdf_operators_set_font_subset (pdf_operators, subset_glyph);
- if (status)
+ if (unlikely (status))
return status;
pdf_operators->is_new_text_object = FALSE;
@@ -1241,14 +1241,14 @@ _cairo_pdf_operators_emit_glyph (cairo_pdf_operators_t *pdf_operator
fabs(y - pdf_operators->cur_y) > GLYPH_POSITION_TOLERANCE)
{
status = _cairo_pdf_operators_flush_glyphs (pdf_operators);
- if (status)
+ if (unlikely (status))
return status;
x = glyph->x;
y = glyph->y;
cairo_matrix_transform_point (&pdf_operators->cairo_to_pdf, &x, &y);
status = _cairo_pdf_operators_set_text_position (pdf_operators, x, y);
- if (status)
+ if (unlikely (status))
return status;
x = 0.0;
@@ -1296,14 +1296,14 @@ _cairo_pdf_operators_emit_cluster (cairo_pdf_operators_t *pdf_operators,
utf8,
utf8_len,
&subset_glyph);
- if (status)
+ if (unlikely (status))
return status;
if (subset_glyph.utf8_is_mapped || utf8_len < 0) {
status = _cairo_pdf_operators_emit_glyph (pdf_operators,
glyphs,
&subset_glyph);
- if (status)
+ if (unlikely (status))
return status;
return CAIRO_STATUS_SUCCESS;
@@ -1313,11 +1313,11 @@ _cairo_pdf_operators_emit_cluster (cairo_pdf_operators_t *pdf_operators,
/* Fallback to using ActualText to map zero or more glyphs to a
* unicode string. */
status = _cairo_pdf_operators_flush_glyphs (pdf_operators);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_pdf_operators_begin_actualtext (pdf_operators, utf8, utf8_len);
- if (status)
+ if (unlikely (status))
return status;
cur_glyph = glyphs;
@@ -1329,13 +1329,13 @@ _cairo_pdf_operators_emit_cluster (cairo_pdf_operators_t *pdf_operators,
cur_glyph->index,
NULL, -1,
&subset_glyph);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_pdf_operators_emit_glyph (pdf_operators,
cur_glyph,
&subset_glyph);
- if (status)
+ if (unlikely (status))
return status;
if ((cluster_flags & CAIRO_TEXT_CLUSTER_FLAG_BACKWARD))
@@ -1344,7 +1344,7 @@ _cairo_pdf_operators_emit_cluster (cairo_pdf_operators_t *pdf_operators,
cur_glyph++;
}
status = _cairo_pdf_operators_flush_glyphs (pdf_operators);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_pdf_operators_end_actualtext (pdf_operators);
@@ -1374,13 +1374,13 @@ _cairo_pdf_operators_show_text_glyphs (cairo_pdf_operators_t *pdf_operators,
status = cairo_matrix_invert (&pdf_operators->font_matrix_inverse);
if (status == CAIRO_STATUS_INVALID_MATRIX)
return CAIRO_STATUS_SUCCESS;
- if (status)
+ if (unlikely (status))
return status;
pdf_operators->is_new_text_object = FALSE;
if (pdf_operators->in_text_object == FALSE) {
status = _cairo_pdf_operators_begin_text (pdf_operators);
- if (status)
+ if (unlikely (status))
return status;
/* Force Tm and Tf to be emitted when starting a new text
@@ -1401,7 +1401,7 @@ _cairo_pdf_operators_show_text_glyphs (cairo_pdf_operators_t *pdf_operators,
! _cairo_matrix_scale_equal (&pdf_operators->text_matrix, &text_matrix))
{
status = _cairo_pdf_operators_flush_glyphs (pdf_operators);
- if (status)
+ if (unlikely (status))
return status;
x = glyphs[0].x;
@@ -1412,7 +1412,7 @@ _cairo_pdf_operators_show_text_glyphs (cairo_pdf_operators_t *pdf_operators,
status = _cairo_pdf_operators_set_text_matrix (pdf_operators, &text_matrix);
if (status == CAIRO_STATUS_INVALID_MATRIX)
return CAIRO_STATUS_SUCCESS;
- if (status)
+ if (unlikely (status))
return status;
}
@@ -1432,7 +1432,7 @@ _cairo_pdf_operators_show_text_glyphs (cairo_pdf_operators_t *pdf_operators,
clusters[i].num_glyphs,
cluster_flags,
scaled_font);
- if (status)
+ if (unlikely (status))
return status;
cur_text += clusters[i].num_bytes;
@@ -1448,7 +1448,7 @@ _cairo_pdf_operators_show_text_glyphs (cairo_pdf_operators_t *pdf_operators,
1,
FALSE,
scaled_font);
- if (status)
+ if (unlikely (status))
return status;
}
}
diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c
index 97902505..5862c4b5 100644
--- a/src/cairo-pdf-surface.c
+++ b/src/cairo-pdf-surface.c
@@ -207,7 +207,7 @@ _cairo_pdf_surface_new_object (cairo_pdf_surface_t *surface)
object.offset = _cairo_output_stream_get_position (surface->output);
status = _cairo_array_append (&surface->objects, &object);
- if (status) {
+ if (unlikely (status)) {
resource.id = 0;
return resource;
}
@@ -249,7 +249,7 @@ _cairo_pdf_surface_create_for_stream_internal (cairo_output_stream_t *output,
cairo_status_t status, status_ignored;
surface = malloc (sizeof (cairo_pdf_surface_t));
- if (surface == NULL) {
+ if (unlikely (surface == NULL)) {
/* destroy stream on behalf of caller */
status = _cairo_output_stream_destroy (output);
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
@@ -551,7 +551,7 @@ cairo_pdf_surface_set_size (cairo_surface_t *surface,
cairo_status_t status;
status = _extract_pdf_surface (surface, &pdf_surface);
- if (status) {
+ if (unlikely (status)) {
status = _cairo_surface_set_error (surface, status);
return;
}
@@ -562,7 +562,7 @@ cairo_pdf_surface_set_size (cairo_surface_t *surface,
status = _cairo_paginated_surface_set_size (pdf_surface->paginated_surface,
width_in_points,
height_in_points);
- if (status)
+ if (unlikely (status))
status = _cairo_surface_set_error (surface, status);
}
@@ -639,7 +639,7 @@ _cairo_pdf_surface_add_alpha (cairo_pdf_surface_t *surface,
}
status = _cairo_array_append (&res->alphas, &alpha);
- if (status)
+ if (unlikely (status))
return status;
*index = _cairo_array_num_elements (&res->alphas) - 1;
@@ -702,7 +702,7 @@ _cairo_pdf_surface_add_font (unsigned int font_id,
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
status = _cairo_array_append (&surface->fonts, &font);
- if (status)
+ if (unlikely (status))
return status;
return _cairo_array_append (&res->fonts, &font);
@@ -817,7 +817,7 @@ _cairo_pdf_surface_create_smask_group (cairo_pdf_surface_t *surface)
cairo_pdf_smask_group_t *group;
group = calloc (1, sizeof (cairo_pdf_smask_group_t));
- if (group == NULL) {
+ if (unlikely (group == NULL)) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return NULL;
}
@@ -898,7 +898,7 @@ _cairo_pdf_surface_add_pdf_pattern (cairo_pdf_surface_t *surface,
}
status = _cairo_pattern_create_copy (&pdf_pattern.pattern, pattern);
- if (status)
+ if (unlikely (status))
return status;
pdf_pattern.pattern_res = _cairo_pdf_surface_new_object (surface);
@@ -936,7 +936,7 @@ _cairo_pdf_surface_add_pdf_pattern (cairo_pdf_surface_t *surface,
*gstate_res = pdf_pattern.gstate_res;
status = _cairo_array_append (&surface->patterns, &pdf_pattern);
- if (status) {
+ if (unlikely (status)) {
cairo_pattern_destroy (pdf_pattern.pattern);
return status;
}
@@ -1022,7 +1022,7 @@ _cairo_pdf_surface_close_stream (cairo_pdf_surface_t *surface)
return CAIRO_STATUS_SUCCESS;
status = _cairo_pdf_operators_flush (&surface->pdf_operators);
- if (status)
+ if (unlikely (status))
return status;
if (surface->pdf_stream.compressed) {
@@ -1151,7 +1151,7 @@ _cairo_pdf_surface_open_knockout_group (cairo_pdf_surface_t *surface)
cairo_status_t status;
status = _cairo_pdf_surface_open_group (surface, NULL);
- if (status)
+ if (unlikely (status))
return status;
surface->group_stream.is_knockout = TRUE;
@@ -1169,7 +1169,7 @@ _cairo_pdf_surface_close_group (cairo_pdf_surface_t *surface,
assert (surface->group_stream.active == TRUE);
status = _cairo_pdf_operators_flush (&surface->pdf_operators);
- if (status)
+ if (unlikely (status))
return status;
if (surface->compress_content) {
@@ -1237,7 +1237,7 @@ _cairo_pdf_surface_open_content_stream (cairo_pdf_surface_t *surface,
surface->compress_content,
NULL);
}
- if (status)
+ if (unlikely (status))
return status;
surface->content = surface->pdf_stream.self;
@@ -1256,12 +1256,12 @@ _cairo_pdf_surface_close_content_stream (cairo_pdf_surface_t *surface)
assert (surface->group_stream.active == FALSE);
status = _cairo_pdf_operators_flush (&surface->pdf_operators);
- if (status)
+ if (unlikely (status))
return status;
_cairo_output_stream_printf (surface->output, "Q\n");
status = _cairo_pdf_surface_close_stream (surface);
- if (status)
+ if (unlikely (status))
return status;
_cairo_pdf_surface_update_object (surface, surface->content_resources);
@@ -1414,7 +1414,7 @@ _cairo_pdf_surface_has_fallback_images (void *abstract_surface,
surface->has_fallback_images = has_fallbacks;
status = _cairo_pdf_surface_open_content_stream (surface, has_fallbacks);
- if (status)
+ if (unlikely (status))
return status;
return CAIRO_STATUS_SUCCESS;
@@ -1461,7 +1461,7 @@ _cairo_pdf_surface_emit_smask (cairo_pdf_surface_t *surface,
alpha = _cairo_malloc_ab (image->height, image->width);
}
- if (alpha == NULL) {
+ if (unlikely (alpha == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto CLEANUP;
}
@@ -1515,7 +1515,7 @@ _cairo_pdf_surface_emit_smask (cairo_pdf_surface_t *surface,
" /BitsPerComponent %d\n",
image->width, image->height,
image->format == CAIRO_FORMAT_A1 ? 1 : 8);
- if (status)
+ if (unlikely (status))
goto CLEANUP_ALPHA;
*stream_ret = surface->pdf_stream.self;
@@ -1557,7 +1557,7 @@ _cairo_pdf_surface_emit_image (cairo_pdf_surface_t *surface,
rgb_size = image->height * image->width * 3;
rgb = _cairo_malloc_abc (image->width, image->height, 3);
- if (rgb == NULL) {
+ if (unlikely (rgb == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto CLEANUP;
}
@@ -1601,7 +1601,7 @@ _cairo_pdf_surface_emit_image (cairo_pdf_surface_t *surface,
image->format == CAIRO_FORMAT_A8 ||
image->format == CAIRO_FORMAT_A1) {
status = _cairo_pdf_surface_emit_smask (surface, image, &smask);
- if (status)
+ if (unlikely (status))
goto CLEANUP_RGB;
if (smask.id)
@@ -1645,7 +1645,7 @@ _cairo_pdf_surface_emit_image (cairo_pdf_surface_t *surface,
IMAGE_DICTIONARY,
image->width, image->height,
interpolate);
- if (status)
+ if (unlikely (status))
goto CLEANUP_RGB;
#undef IMAGE_DICTIONARY
@@ -1727,7 +1727,7 @@ _cairo_pdf_surface_emit_jpeg_image (cairo_pdf_surface_t *surface,
return CAIRO_INT_STATUS_UNSUPPORTED;
status = _cairo_image_info_get_jpeg_info (&info, mime_data, mime_data_length);
- if (status)
+ if (unlikely (status))
return status;
if (info.num_components != 1 && info.num_components != 3)
@@ -1747,7 +1747,7 @@ _cairo_pdf_surface_emit_jpeg_image (cairo_pdf_surface_t *surface,
info.height,
info.num_components == 1 ? "/DeviceGray" : "/DeviceRGB",
info.bits_per_component);
- if (status)
+ if (unlikely (status))
return status;
*res = surface->pdf_stream.self;
@@ -1789,7 +1789,7 @@ _cairo_pdf_surface_emit_image_surface (cairo_pdf_surface_t *surface,
return status;
status = _cairo_surface_acquire_source_image (pattern->surface, &image, &image_extra);
- if (status)
+ if (unlikely (status))
goto BAIL;
pad_image = &image->base;
@@ -1826,13 +1826,13 @@ _cairo_pdf_surface_emit_image_surface (cairo_pdf_surface_t *surface,
rect.width,
rect.height);
_cairo_pattern_fini (&pad_pattern.base);
- if (status)
+ if (unlikely (status))
goto BAIL;
}
status = _cairo_pdf_surface_emit_image (surface, (cairo_image_surface_t *)pad_image,
resource, pattern->base.filter);
- if (status)
+ if (unlikely (status))
goto BAIL;
*width = ((cairo_image_surface_t *)pad_image)->width;
@@ -1862,7 +1862,7 @@ _cairo_pdf_surface_emit_meta_surface (cairo_pdf_surface_t *surface,
int alpha = 0;
status = _cairo_surface_get_extents (meta_surface, &meta_extents);
- if (status)
+ if (unlikely (status))
return status;
old_width = surface->width;
@@ -1879,13 +1879,13 @@ _cairo_pdf_surface_emit_meta_surface (cairo_pdf_surface_t *surface,
surface->paginated_mode = CAIRO_PAGINATED_MODE_RENDER;
_cairo_pdf_group_resources_clear (&surface->resources);
status = _cairo_pdf_surface_open_content_stream (surface, TRUE);
- if (status)
+ if (unlikely (status))
return status;
*resource = surface->content;
if (cairo_surface_get_content (meta_surface) == CAIRO_CONTENT_COLOR) {
status = _cairo_pdf_surface_add_alpha (surface, 1.0, &alpha);
- if (status)
+ if (unlikely (status))
return status;
_cairo_output_stream_printf (surface->output,
@@ -1898,11 +1898,11 @@ _cairo_pdf_surface_emit_meta_surface (cairo_pdf_surface_t *surface,
status = _cairo_meta_surface_replay_region (meta_surface, &surface->base,
CAIRO_META_REGION_NATIVE);
assert (status != CAIRO_INT_STATUS_UNSUPPORTED);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_surface_set_clip (&surface->base, old_clip);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_pdf_surface_close_content_stream (surface);
@@ -1940,11 +1940,11 @@ _cairo_pdf_surface_emit_surface_pattern (cairo_pdf_surface_t *surface,
status = _cairo_pdf_surface_emit_meta_surface (surface,
meta_surface,
&pattern_resource);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_surface_get_extents (meta_surface, &pattern_extents);
- if (status)
+ if (unlikely (status))
return status;
pattern_width = pattern_extents.width;
@@ -1957,12 +1957,12 @@ _cairo_pdf_surface_emit_surface_pattern (cairo_pdf_surface_t *surface,
&pattern_height,
&origin_x,
&origin_y);
- if (status)
+ if (unlikely (status))
return status;
}
status = _cairo_surface_get_extents (&surface->base, &surface_extents);
- if (status)
+ if (unlikely (status))
return status;
bbox_x = pattern_width;
@@ -2074,7 +2074,7 @@ _cairo_pdf_surface_emit_surface_pattern (cairo_pdf_surface_t *surface,
pdf_p2d.x0, pdf_p2d.y0,
pattern_resource.id,
pattern_resource.id);
- if (status)
+ if (unlikely (status))
return status;
if (_cairo_surface_is_meta (pattern->surface)) {
@@ -2112,7 +2112,7 @@ _cairo_pdf_surface_emit_surface_pattern (cairo_pdf_surface_t *surface,
}
status = _cairo_pdf_surface_close_stream (surface);
- if (status)
+ if (unlikely (status))
return status;
return _cairo_output_stream_get_status (surface->output);
@@ -2244,14 +2244,14 @@ _cairo_pdf_surface_emit_stitched_colorgradient (cairo_pdf_surface_t *surface,
&stops[i],
&stops[i+1],
&stops[i].resource);
- if (status)
+ if (unlikely (status))
return status;
} else {
status = cairo_pdf_surface_emit_rgb_linear_function (surface,
&stops[i],
&stops[i+1],
&stops[i].resource);
- if (status)
+ if (unlikely (status))
return status;
}
}
@@ -2333,7 +2333,7 @@ _cairo_pdf_surface_emit_pattern_stops (cairo_pdf_surface_t *surface,
alpha_function->id = 0;
allstops = _cairo_malloc_ab ((pattern->n_stops + 2), sizeof (cairo_pdf_color_stop_t));
- if (allstops == NULL)
+ if (unlikely (allstops == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
stops = &allstops[1];
@@ -2380,7 +2380,7 @@ _cairo_pdf_surface_emit_pattern_stops (cairo_pdf_surface_t *surface,
&stops[0],
&stops[1],
color_function);
- if (status)
+ if (unlikely (status))
goto BAIL;
if (emit_alpha) {
@@ -2388,7 +2388,7 @@ _cairo_pdf_surface_emit_pattern_stops (cairo_pdf_surface_t *surface,
&stops[0],
&stops[1],
alpha_function);
- if (status)
+ if (unlikely (status))
goto BAIL;
}
} else {
@@ -2399,7 +2399,7 @@ _cairo_pdf_surface_emit_pattern_stops (cairo_pdf_surface_t *surface,
stops,
FALSE,
color_function);
- if (status)
+ if (unlikely (status))
goto BAIL;
if (emit_alpha) {
@@ -2408,7 +2408,7 @@ _cairo_pdf_surface_emit_pattern_stops (cairo_pdf_surface_t *surface,
stops,
TRUE,
alpha_function);
- if (status)
+ if (unlikely (status))
goto BAIL;
}
}
@@ -2510,7 +2510,7 @@ cairo_pdf_surface_emit_transparency_group (cairo_pdf_surface_t *surface,
surface->height,
gradient_mask.id,
gradient_mask.id);
- if (status)
+ if (unlikely (status))
return status;
_cairo_output_stream_printf (surface->output,
@@ -2525,7 +2525,7 @@ cairo_pdf_surface_emit_transparency_group (cairo_pdf_surface_t *surface,
surface->height);
status = _cairo_pdf_surface_close_stream (surface);
- if (status)
+ if (unlikely (status))
return status;
smask_resource = _cairo_pdf_surface_new_object (surface);
@@ -2648,7 +2648,7 @@ _cairo_pdf_surface_emit_linear_pattern (cairo_pdf_surface_t *surface,
&pattern->base,
&color_function,
&alpha_function);
- if (status)
+ if (unlikely (status))
return status;
if (pattern->base.base.extend == CAIRO_EXTEND_REPEAT ||
@@ -2658,7 +2658,7 @@ _cairo_pdf_surface_emit_linear_pattern (cairo_pdf_surface_t *surface,
&color_function,
repeat_begin,
repeat_end);
- if (status)
+ if (unlikely (status))
return status;
if (alpha_function.id != 0) {
@@ -2667,7 +2667,7 @@ _cairo_pdf_surface_emit_linear_pattern (cairo_pdf_surface_t *surface,
&alpha_function,
repeat_begin,
repeat_end);
- if (status)
+ if (unlikely (status))
return status;
}
}
@@ -2747,13 +2747,13 @@ _cairo_pdf_surface_emit_linear_pattern (cairo_pdf_surface_t *surface,
">>\n"
"endobj\n");
status = _cairo_pdf_surface_add_pattern (surface, mask_resource);
- if (status)
+ if (unlikely (status))
return status;
status = cairo_pdf_surface_emit_transparency_group (surface,
pdf_pattern->gstate_res,
mask_resource);
- if (status)
+ if (unlikely (status))
return status;
}
@@ -2779,7 +2779,7 @@ _cairo_pdf_surface_emit_radial_pattern (cairo_pdf_surface_t *surface,
&pattern->base,
&color_function,
&alpha_function);
- if (status)
+ if (unlikely (status))
return status;
pat_to_pdf = pattern->base.base.matrix;
@@ -2870,7 +2870,7 @@ _cairo_pdf_surface_emit_radial_pattern (cairo_pdf_surface_t *surface,
status = cairo_pdf_surface_emit_transparency_group (surface,
pdf_pattern->gstate_res,
mask_resource);
- if (status)
+ if (unlikely (status))
return status;
}
@@ -2953,7 +2953,7 @@ _cairo_pdf_surface_select_pattern (cairo_pdf_surface_t *surface,
surface->current_color_is_stroke != is_stroke)
{
status = _cairo_pdf_operators_flush (&surface->pdf_operators);
- if (status)
+ if (unlikely (status))
return status;
_cairo_output_stream_printf (surface->output,
@@ -2977,11 +2977,11 @@ _cairo_pdf_surface_select_pattern (cairo_pdf_surface_t *surface,
surface->current_color_alpha != solid_color->alpha)
{
status = _cairo_pdf_surface_add_alpha (surface, solid_color->alpha, &alpha);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_pdf_operators_flush (&surface->pdf_operators);
- if (status)
+ if (unlikely (status))
return status;
_cairo_output_stream_printf (surface->output,
@@ -2993,15 +2993,15 @@ _cairo_pdf_surface_select_pattern (cairo_pdf_surface_t *surface,
surface->current_pattern_is_solid_color = TRUE;
} else {
status = _cairo_pdf_surface_add_alpha (surface, 1.0, &alpha);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_pdf_surface_add_pattern (surface, pattern_res);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_pdf_operators_flush (&surface->pdf_operators);
- if (status)
+ if (unlikely (status))
return status;
/* fill-stroke calls select_pattern twice. Don't save if the
@@ -3035,7 +3035,7 @@ _cairo_pdf_surface_unselect_pattern (cairo_pdf_surface_t *surface)
if (surface->select_pattern_gstate_saved) {
status = _cairo_pdf_operators_flush (&surface->pdf_operators);
- if (status)
+ if (unlikely (status))
return status;
_cairo_output_stream_printf (surface->output, "Q\n");
@@ -3053,11 +3053,11 @@ _cairo_pdf_surface_show_page (void *abstract_surface)
cairo_int_status_t status;
status = _cairo_pdf_surface_close_content_stream (surface);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_pdf_surface_write_page (surface);
- if (status)
+ if (unlikely (status))
return status;
_cairo_pdf_surface_clear (surface);
@@ -3096,7 +3096,7 @@ _cairo_pdf_surface_intersect_clip_path (void *abstract_surface,
if (path == NULL) {
status = _cairo_pdf_operators_flush (&surface->pdf_operators);
- if (status)
+ if (unlikely (status))
return status;
_cairo_output_stream_printf (surface->output, "Q q\n");
@@ -3183,7 +3183,7 @@ _cairo_pdf_surface_emit_unicode_for_glyph (cairo_pdf_surface_t *surface,
if (utf8 && *utf8) {
status = _cairo_utf8_to_utf16 (utf8, -1, &utf16, &utf16_len);
- if (status)
+ if (unlikely (status))
return status;
}
@@ -3225,7 +3225,7 @@ _cairo_pdf_surface_emit_to_unicode_stream (cairo_pdf_surface_t *surface,
NULL,
surface->compress_content,
NULL);
- if (status)
+ if (unlikely (status))
return status;
_cairo_output_stream_printf (surface->output,
@@ -3277,7 +3277,7 @@ _cairo_pdf_surface_emit_to_unicode_stream (cairo_pdf_surface_t *surface,
}
status = _cairo_pdf_surface_emit_unicode_for_glyph (surface,
font_subset->utf8[i + 1]);
- if (status)
+ if (unlikely (status))
return status;
_cairo_output_stream_printf (surface->output,
@@ -3317,14 +3317,14 @@ _cairo_pdf_surface_emit_cff_font (cairo_pdf_surface_t *surface,
NULL,
TRUE,
" /Subtype /CIDFontType0C\n");
- if (status)
+ if (unlikely (status))
return status;
stream = surface->pdf_stream.self;
_cairo_output_stream_write (surface->output,
subset->data, subset->data_length);
status = _cairo_pdf_surface_close_stream (surface);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_pdf_surface_emit_to_unicode_stream (surface,
@@ -3432,7 +3432,7 @@ _cairo_pdf_surface_emit_cff_font_subset (cairo_pdf_surface_t *surface,
snprintf (name, sizeof name, "CairoFont-%d-%d",
font_subset->font_id, font_subset->subset_id);
status = _cairo_cff_subset_init (&subset, name, font_subset);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_pdf_surface_emit_cff_font (surface, font_subset, &subset);
@@ -3453,7 +3453,7 @@ _cairo_pdf_surface_emit_cff_fallback_font (cairo_pdf_surface_t *surface,
snprintf (name, sizeof name, "CairoFont-%d-%d",
font_subset->font_id, font_subset->subset_id);
status = _cairo_cff_fallback_init (&subset, name, font_subset);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_pdf_surface_emit_cff_font (surface, font_subset, &subset);
@@ -3490,13 +3490,13 @@ _cairo_pdf_surface_emit_type1_font (cairo_pdf_surface_t *surface,
" /Length3 0\n",
subset->header_length,
subset->data_length);
- if (status)
+ if (unlikely (status))
return status;
stream = surface->pdf_stream.self;
_cairo_output_stream_write (surface->output, subset->data, length);
status = _cairo_pdf_surface_close_stream (surface);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_pdf_surface_emit_to_unicode_stream (surface,
@@ -3584,7 +3584,7 @@ _cairo_pdf_surface_emit_type1_font_subset (cairo_pdf_surface_t *surface,
snprintf (name, sizeof name, "CairoFont-%d-%d",
font_subset->font_id, font_subset->subset_id);
status = _cairo_type1_subset_init (&subset, name, font_subset, FALSE);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_pdf_surface_emit_type1_font (surface, font_subset, &subset);
@@ -3605,7 +3605,7 @@ _cairo_pdf_surface_emit_type1_fallback_font (cairo_pdf_surface_t *surface,
snprintf (name, sizeof name, "CairoFont-%d-%d",
font_subset->font_id, font_subset->subset_id);
status = _cairo_type1_fallback_init_binary (&subset, name, font_subset);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_pdf_surface_emit_type1_font (surface, font_subset, &subset);
@@ -3634,7 +3634,7 @@ _cairo_pdf_surface_emit_truetype_font_subset (cairo_pdf_surface_t *surface,
return CAIRO_STATUS_SUCCESS;
status = _cairo_truetype_subset_init (&subset, font_subset);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_pdf_surface_open_stream (surface,
@@ -3642,7 +3642,7 @@ _cairo_pdf_surface_emit_truetype_font_subset (cairo_pdf_surface_t *surface,
TRUE,
" /Length1 %lu\n",
subset.data_length);
- if (status) {
+ if (unlikely (status)) {
_cairo_truetype_subset_fini (&subset);
return status;
}
@@ -3651,7 +3651,7 @@ _cairo_pdf_surface_emit_truetype_font_subset (cairo_pdf_surface_t *surface,
_cairo_output_stream_write (surface->output,
subset.data, subset.data_length);
status = _cairo_pdf_surface_close_stream (surface);
- if (status) {
+ if (unlikely (status)) {
_cairo_truetype_subset_fini (&subset);
return status;
}
@@ -3822,7 +3822,7 @@ _cairo_pdf_surface_analyze_user_font_subset (cairo_scaled_font_subset_t *font_su
for (i = 0; i < font_subset->num_glyphs; i++) {
status = _cairo_type3_glyph_surface_analyze_glyph (type3_surface,
font_subset->glyphs[i]);
- if (status)
+ if (unlikely (status))
break;
}
@@ -3857,11 +3857,11 @@ _cairo_pdf_surface_emit_type3_font_subset (cairo_pdf_surface_t *surface,
return CAIRO_STATUS_SUCCESS;
glyphs = _cairo_malloc_ab (font_subset->num_glyphs, sizeof (cairo_pdf_resource_t));
- if (glyphs == NULL)
+ if (unlikely (glyphs == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
widths = _cairo_malloc_ab (font_subset->num_glyphs, sizeof (double));
- if (widths == NULL) {
+ if (unlikely (widths == NULL)) {
free (glyphs);
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
@@ -3880,7 +3880,7 @@ _cairo_pdf_surface_emit_type3_font_subset (cairo_pdf_surface_t *surface,
NULL,
surface->compress_content,
NULL);
- if (status)
+ if (unlikely (status))
break;
glyphs[i] = surface->pdf_stream.self;
@@ -3889,11 +3889,11 @@ _cairo_pdf_surface_emit_type3_font_subset (cairo_pdf_surface_t *surface,
font_subset->glyphs[i],
&bbox,
&widths[i]);
- if (status)
+ if (unlikely (status))
break;
status = _cairo_pdf_surface_close_stream (surface);
- if (status)
+ if (unlikely (status))
break;
if (i == 0) {
@@ -3913,7 +3913,7 @@ _cairo_pdf_surface_emit_type3_font_subset (cairo_pdf_surface_t *surface,
}
}
cairo_surface_destroy (type3_surface);
- if (status) {
+ if (unlikely (status)) {
free (glyphs);
free (widths);
return status;
@@ -4072,19 +4072,19 @@ _cairo_pdf_surface_emit_font_subsets (cairo_pdf_surface_t *surface)
status = _cairo_scaled_font_subsets_foreach_user (surface->font_subsets,
_cairo_pdf_surface_analyze_user_font_subset,
surface);
- if (status)
+ if (unlikely (status))
goto BAIL;
status = _cairo_scaled_font_subsets_foreach_unscaled (surface->font_subsets,
_cairo_pdf_surface_emit_unscaled_font_subset,
surface);
- if (status)
+ if (unlikely (status))
goto BAIL;
status = _cairo_scaled_font_subsets_foreach_scaled (surface->font_subsets,
_cairo_pdf_surface_emit_scaled_font_subset,
surface);
- if (status)
+ if (unlikely (status))
goto BAIL;
status = _cairo_scaled_font_subsets_foreach_user (surface->font_subsets,
@@ -4159,36 +4159,36 @@ _cairo_pdf_surface_write_mask_group (cairo_pdf_surface_t *surface,
/* Create mask group */
status = _cairo_pdf_surface_open_group (surface, NULL);
- if (status)
+ if (unlikely (status))
return status;
pattern_res.id = 0;
gstate_res.id = 0;
status = _cairo_pdf_surface_add_pdf_pattern (surface, group->mask, NULL,
&pattern_res, &gstate_res);
- if (status)
+ if (unlikely (status))
return status;
if (gstate_res.id != 0) {
smask_group = _cairo_pdf_surface_create_smask_group (surface);
- if (smask_group == NULL)
+ if (unlikely (smask_group == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
smask_group->operation = PDF_PAINT;
smask_group->source = cairo_pattern_reference (group->mask);
smask_group->source_res = pattern_res;
status = _cairo_pdf_surface_add_smask_group (surface, smask_group);
- if (status) {
+ if (unlikely (status)) {
_cairo_pdf_smask_group_destroy (smask_group);
return status;
}
status = _cairo_pdf_surface_add_smask (surface, gstate_res);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_pdf_surface_add_xobject (surface, smask_group->group_res);
- if (status)
+ if (unlikely (status))
return status;
_cairo_output_stream_printf (surface->output,
@@ -4197,7 +4197,7 @@ _cairo_pdf_surface_write_mask_group (cairo_pdf_surface_t *surface,
smask_group->group_res.id);
} else {
status = _cairo_pdf_surface_select_pattern (surface, group->mask, pattern_res, FALSE);
- if (status)
+ if (unlikely (status))
return status;
_cairo_output_stream_printf (surface->output,
@@ -4205,46 +4205,46 @@ _cairo_pdf_surface_write_mask_group (cairo_pdf_surface_t *surface,
surface->width, surface->height);
status = _cairo_pdf_surface_unselect_pattern (surface);
- if (status)
+ if (unlikely (status))
return status;
}
status = _cairo_pdf_surface_close_group (surface, &mask_group);
- if (status)
+ if (unlikely (status))
return status;
/* Create source group */
status = _cairo_pdf_surface_open_group (surface, &group->source_res);
- if (status)
+ if (unlikely (status))
return status;
pattern_res.id = 0;
gstate_res.id = 0;
status = _cairo_pdf_surface_add_pdf_pattern (surface, group->source, NULL,
&pattern_res, &gstate_res);
- if (status)
+ if (unlikely (status))
return status;
if (gstate_res.id != 0) {
smask_group = _cairo_pdf_surface_create_smask_group (surface);
- if (smask_group == NULL)
+ if (unlikely (smask_group == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
smask_group->operation = PDF_PAINT;
smask_group->source = cairo_pattern_reference (group->source);
smask_group->source_res = pattern_res;
status = _cairo_pdf_surface_add_smask_group (surface, smask_group);
- if (status) {
+ if (unlikely (status)) {
_cairo_pdf_smask_group_destroy (smask_group);
return status;
}
status = _cairo_pdf_surface_add_smask (surface, gstate_res);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_pdf_surface_add_xobject (surface, smask_group->group_res);
- if (status)
+ if (unlikely (status))
return status;
_cairo_output_stream_printf (surface->output,
@@ -4253,7 +4253,7 @@ _cairo_pdf_surface_write_mask_group (cairo_pdf_surface_t *surface,
smask_group->group_res.id);
} else {
status = _cairo_pdf_surface_select_pattern (surface, group->source, pattern_res, FALSE);
- if (status)
+ if (unlikely (status))
return status;
_cairo_output_stream_printf (surface->output,
@@ -4261,12 +4261,12 @@ _cairo_pdf_surface_write_mask_group (cairo_pdf_surface_t *surface,
surface->width, surface->height);
status = _cairo_pdf_surface_unselect_pattern (surface);
- if (status)
+ if (unlikely (status))
return status;
}
status = _cairo_pdf_surface_close_group (surface, NULL);
- if (status)
+ if (unlikely (status))
return status;
/* Create an smask based on the alpha component of mask_group */
@@ -4319,14 +4319,14 @@ _cairo_pdf_surface_write_smask_group (cairo_pdf_surface_t *surface,
return _cairo_pdf_surface_write_mask_group (surface, group);
status = _cairo_pdf_surface_open_group (surface, &group->group_res);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_pdf_surface_select_pattern (surface,
group->source,
group->source_res,
group->operation == PDF_STROKE);
- if (status)
+ if (unlikely (status))
return status;
switch (group->operation) {
@@ -4359,11 +4359,11 @@ _cairo_pdf_surface_write_smask_group (cairo_pdf_surface_t *surface,
group->scaled_font);
break;
}
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_pdf_surface_unselect_pattern (surface);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_pdf_surface_close_group (surface, NULL);
@@ -4398,14 +4398,14 @@ _cairo_pdf_surface_write_patterns_and_smask_groups (cairo_pdf_surface_t *surface
for (; group_index < _cairo_array_num_elements (&surface->smask_groups); group_index++) {
_cairo_array_copy_element (&surface->smask_groups, group_index, &group);
status = _cairo_pdf_surface_write_smask_group (surface, group);
- if (status)
+ if (unlikely (status))
return status;
}
for (; pattern_index < _cairo_array_num_elements (&surface->patterns); pattern_index++) {
_cairo_array_copy_element (&surface->patterns, pattern_index, &pattern);
status = _cairo_pdf_surface_emit_pattern (surface, &pattern);
- if (status)
+ if (unlikely (status))
return status;
}
}
@@ -4423,7 +4423,7 @@ _cairo_pdf_surface_write_page (cairo_pdf_surface_t *surface)
_cairo_pdf_group_resources_clear (&surface->resources);
if (surface->has_fallback_images) {
status = _cairo_pdf_surface_open_knockout_group (surface);
- if (status)
+ if (unlikely (status))
return status;
len = _cairo_array_num_elements (&surface->knockout_group);
@@ -4433,34 +4433,34 @@ _cairo_pdf_surface_write_page (cairo_pdf_surface_t *surface)
"/x%d Do\n",
res.id);
status = _cairo_pdf_surface_add_xobject (surface, res);
- if (status)
+ if (unlikely (status))
return status;
}
_cairo_output_stream_printf (surface->output,
"/x%d Do\n",
surface->content.id);
status = _cairo_pdf_surface_add_xobject (surface, surface->content);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_pdf_surface_close_group (surface, &knockout);
- if (status)
+ if (unlikely (status))
return status;
_cairo_pdf_group_resources_clear (&surface->resources);
status = _cairo_pdf_surface_open_content_stream (surface, FALSE);
- if (status)
+ if (unlikely (status))
return status;
_cairo_output_stream_printf (surface->output,
"/x%d Do\n",
knockout.id);
status = _cairo_pdf_surface_add_xobject (surface, knockout);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_pdf_surface_close_content_stream (surface);
- if (status)
+ if (unlikely (status))
return status;
}
@@ -4490,11 +4490,11 @@ _cairo_pdf_surface_write_page (cairo_pdf_surface_t *surface)
surface->content_resources.id);
status = _cairo_array_append (&surface->pages, &page);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_pdf_surface_write_patterns_and_smask_groups (surface);
- if (status)
+ if (unlikely (status))
return status;
return CAIRO_STATUS_SUCCESS;
@@ -4512,7 +4512,7 @@ _cairo_pdf_surface_analyze_surface_pattern_transparency (cairo_pdf_surface_t
status = _cairo_surface_acquire_source_image (pattern->surface,
&image,
&image_extra);
- if (status)
+ if (unlikely (status))
return status;
if (image->base.status)
@@ -4697,11 +4697,11 @@ _cairo_pdf_surface_start_fallback (cairo_pdf_surface_t *surface)
cairo_status_t status;
status = _cairo_pdf_surface_close_content_stream (surface);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_array_append (&surface->knockout_group, &surface->content);
- if (status)
+ if (unlikely (status))
return status;
_cairo_pdf_group_resources_clear (&surface->resources);
@@ -4723,7 +4723,7 @@ _cairo_pdf_surface_paint (void *abstract_surface,
return _cairo_pdf_surface_analyze_operation (surface, op, source);
} else if (surface->paginated_mode == CAIRO_PAGINATED_MODE_FALLBACK) {
status = _cairo_pdf_surface_start_fallback (surface);
- if (status)
+ if (unlikely (status))
return status;
}
@@ -4735,37 +4735,37 @@ _cairo_pdf_surface_paint (void *abstract_surface,
&pattern_res, &gstate_res);
if (status == CAIRO_INT_STATUS_NOTHING_TO_DO)
return CAIRO_STATUS_SUCCESS;
- if (status)
+ if (unlikely (status))
return status;
if (gstate_res.id != 0) {
group = _cairo_pdf_surface_create_smask_group (surface);
- if (group == NULL)
+ if (unlikely (group == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
group->operation = PDF_PAINT;
status = _cairo_pattern_create_copy (&group->source, source);
- if (status) {
+ if (unlikely (status)) {
_cairo_pdf_smask_group_destroy (group);
return status;
}
group->source_res = pattern_res;
status = _cairo_pdf_surface_add_smask_group (surface, group);
- if (status) {
+ if (unlikely (status)) {
_cairo_pdf_smask_group_destroy (group);
return status;
}
status = _cairo_pdf_surface_add_smask (surface, gstate_res);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_pdf_surface_add_xobject (surface, group->group_res);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_pdf_operators_flush (&surface->pdf_operators);
- if (status)
+ if (unlikely (status))
return status;
_cairo_output_stream_printf (surface->output,
@@ -4774,7 +4774,7 @@ _cairo_pdf_surface_paint (void *abstract_surface,
group->group_res.id);
} else {
status = _cairo_pdf_surface_select_pattern (surface, source, pattern_res, FALSE);
- if (status)
+ if (unlikely (status))
return status;
_cairo_output_stream_printf (surface->output,
@@ -4782,7 +4782,7 @@ _cairo_pdf_surface_paint (void *abstract_surface,
surface->width, surface->height);
status = _cairo_pdf_surface_unselect_pattern (surface);
- if (status)
+ if (unlikely (status))
return status;
}
@@ -4815,7 +4815,7 @@ _cairo_pdf_surface_mask (void *abstract_surface,
mask_status);
} else if (surface->paginated_mode == CAIRO_PAGINATED_MODE_FALLBACK) {
status = _cairo_pdf_surface_start_fallback (surface);
- if (status)
+ if (unlikely (status))
return status;
}
@@ -4823,17 +4823,17 @@ _cairo_pdf_surface_mask (void *abstract_surface,
assert (_cairo_pdf_surface_operation_supported (surface, op, mask));
group = _cairo_pdf_surface_create_smask_group (surface);
- if (group == NULL)
+ if (unlikely (group == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
group->operation = PDF_MASK;
status = _cairo_pattern_create_copy (&group->source, source);
- if (status) {
+ if (unlikely (status)) {
_cairo_pdf_smask_group_destroy (group);
return status;
}
status = _cairo_pattern_create_copy (&group->mask, mask);
- if (status) {
+ if (unlikely (status)) {
_cairo_pdf_smask_group_destroy (group);
return status;
}
@@ -4844,21 +4844,21 @@ _cairo_pdf_surface_mask (void *abstract_surface,
}
status = _cairo_pdf_surface_add_smask_group (surface, group);
- if (status) {
+ if (unlikely (status)) {
_cairo_pdf_smask_group_destroy (group);
return status;
}
status = _cairo_pdf_surface_add_smask (surface, group->group_res);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_pdf_surface_add_xobject (surface, group->source_res);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_pdf_operators_flush (&surface->pdf_operators);
- if (status)
+ if (unlikely (status))
return status;
_cairo_output_stream_printf (surface->output,
@@ -4897,23 +4897,23 @@ _cairo_pdf_surface_stroke (void *abstract_surface,
&pattern_res, &gstate_res);
if (status == CAIRO_INT_STATUS_NOTHING_TO_DO)
return CAIRO_STATUS_SUCCESS;
- if (status)
+ if (unlikely (status))
return status;
if (gstate_res.id != 0) {
group = _cairo_pdf_surface_create_smask_group (surface);
- if (group == NULL)
+ if (unlikely (group == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
group->operation = PDF_STROKE;
status = _cairo_pattern_create_copy (&group->source, source);
- if (status) {
+ if (unlikely (status)) {
_cairo_pdf_smask_group_destroy (group);
return status;
}
group->source_res = pattern_res;
status = _cairo_path_fixed_init_copy (&group->path, path);
- if (status) {
+ if (unlikely (status)) {
_cairo_pdf_smask_group_destroy (group);
return status;
}
@@ -4922,21 +4922,21 @@ _cairo_pdf_surface_stroke (void *abstract_surface,
group->ctm = *ctm;
group->ctm_inverse = *ctm_inverse;
status = _cairo_pdf_surface_add_smask_group (surface, group);
- if (status) {
+ if (unlikely (status)) {
_cairo_pdf_smask_group_destroy (group);
return status;
}
status = _cairo_pdf_surface_add_smask (surface, gstate_res);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_pdf_surface_add_xobject (surface, group->group_res);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_pdf_operators_flush (&surface->pdf_operators);
- if (status)
+ if (unlikely (status))
return status;
_cairo_output_stream_printf (surface->output,
@@ -4945,7 +4945,7 @@ _cairo_pdf_surface_stroke (void *abstract_surface,
group->group_res.id);
} else {
status = _cairo_pdf_surface_select_pattern (surface, source, pattern_res, TRUE);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_pdf_operators_stroke (&surface->pdf_operators,
@@ -4953,11 +4953,11 @@ _cairo_pdf_surface_stroke (void *abstract_surface,
style,
ctm,
ctm_inverse);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_pdf_surface_unselect_pattern (surface);
- if (status)
+ if (unlikely (status))
return status;
}
@@ -4983,7 +4983,7 @@ _cairo_pdf_surface_fill (void *abstract_surface,
return _cairo_pdf_surface_analyze_operation (surface, op, source);
} else if (surface->paginated_mode == CAIRO_PAGINATED_MODE_FALLBACK) {
status = _cairo_pdf_surface_start_fallback (surface);
- if (status)
+ if (unlikely (status))
return status;
}
@@ -4995,44 +4995,44 @@ _cairo_pdf_surface_fill (void *abstract_surface,
&pattern_res, &gstate_res);
if (status == CAIRO_INT_STATUS_NOTHING_TO_DO)
return CAIRO_STATUS_SUCCESS;
- if (status)
+ if (unlikely (status))
return status;
if (gstate_res.id != 0) {
group = _cairo_pdf_surface_create_smask_group (surface);
- if (group == NULL)
+ if (unlikely (group == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
group->operation = PDF_FILL;
status = _cairo_pattern_create_copy (&group->source, source);
- if (status) {
+ if (unlikely (status)) {
_cairo_pdf_smask_group_destroy (group);
return status;
}
group->source_res = pattern_res;
status = _cairo_path_fixed_init_copy (&group->path, path);
- if (status) {
+ if (unlikely (status)) {
_cairo_pdf_smask_group_destroy (group);
return status;
}
group->fill_rule = fill_rule;
status = _cairo_pdf_surface_add_smask_group (surface, group);
- if (status) {
+ if (unlikely (status)) {
_cairo_pdf_smask_group_destroy (group);
return status;
}
status = _cairo_pdf_surface_add_smask (surface, gstate_res);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_pdf_surface_add_xobject (surface, group->group_res);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_pdf_operators_flush (&surface->pdf_operators);
- if (status)
+ if (unlikely (status))
return status;
_cairo_output_stream_printf (surface->output,
@@ -5041,17 +5041,17 @@ _cairo_pdf_surface_fill (void *abstract_surface,
group->group_res.id);
} else {
status = _cairo_pdf_surface_select_pattern (surface, source, pattern_res, FALSE);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_pdf_operators_fill (&surface->pdf_operators,
path,
fill_rule);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_pdf_surface_unselect_pattern (surface);
- if (status)
+ if (unlikely (status))
return status;
}
@@ -5104,7 +5104,7 @@ _cairo_pdf_surface_fill_stroke (void *abstract_surface,
extents,
&fill_pattern_res,
&gstate_res);
- if (status)
+ if (unlikely (status))
return status;
assert (gstate_res.id == 0);
@@ -5116,7 +5116,7 @@ _cairo_pdf_surface_fill_stroke (void *abstract_surface,
extents,
&stroke_pattern_res,
&gstate_res);
- if (status)
+ if (unlikely (status))
return status;
assert (gstate_res.id == 0);
@@ -5125,12 +5125,12 @@ _cairo_pdf_surface_fill_stroke (void *abstract_surface,
* select both at the same time */
status = _cairo_pdf_surface_select_pattern (surface, fill_source,
fill_pattern_res, FALSE);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_pdf_surface_select_pattern (surface, stroke_source,
stroke_pattern_res, TRUE);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_pdf_operators_fill_stroke (&surface->pdf_operators,
@@ -5139,11 +5139,11 @@ _cairo_pdf_surface_fill_stroke (void *abstract_surface,
stroke_style,
stroke_ctm,
stroke_ctm_inverse);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_pdf_surface_unselect_pattern (surface);
- if (status)
+ if (unlikely (status))
return status;
return _cairo_output_stream_get_status (surface->output);
@@ -5185,17 +5185,17 @@ _cairo_pdf_surface_show_text_glyphs (void *abstract_surface,
&pattern_res, &gstate_res);
if (status == CAIRO_INT_STATUS_NOTHING_TO_DO)
return CAIRO_STATUS_SUCCESS;
- if (status)
+ if (unlikely (status))
return status;
if (gstate_res.id != 0) {
group = _cairo_pdf_surface_create_smask_group (surface);
- if (group == NULL)
+ if (unlikely (group == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
group->operation = PDF_SHOW_GLYPHS;
status = _cairo_pattern_create_copy (&group->source, source);
- if (status) {
+ if (unlikely (status)) {
_cairo_pdf_smask_group_destroy (group);
return status;
}
@@ -5203,7 +5203,7 @@ _cairo_pdf_surface_show_text_glyphs (void *abstract_surface,
if (utf8_len) {
group->utf8 = malloc (utf8_len);
- if (group->utf8 == NULL) {
+ if (unlikely (group->utf8 == NULL)) {
_cairo_pdf_smask_group_destroy (group);
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
@@ -5213,7 +5213,7 @@ _cairo_pdf_surface_show_text_glyphs (void *abstract_surface,
if (num_glyphs) {
group->glyphs = _cairo_malloc_ab (num_glyphs, sizeof (cairo_glyph_t));
- if (group->glyphs == NULL) {
+ if (unlikely (group->glyphs == NULL)) {
_cairo_pdf_smask_group_destroy (group);
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
@@ -5223,7 +5223,7 @@ _cairo_pdf_surface_show_text_glyphs (void *abstract_surface,
if (num_clusters) {
group->clusters = _cairo_malloc_ab (num_clusters, sizeof (cairo_text_cluster_t));
- if (group->clusters == NULL) {
+ if (unlikely (group->clusters == NULL)) {
_cairo_pdf_smask_group_destroy (group);
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
@@ -5233,21 +5233,21 @@ _cairo_pdf_surface_show_text_glyphs (void *abstract_surface,
group->scaled_font = cairo_scaled_font_reference (scaled_font);
status = _cairo_pdf_surface_add_smask_group (surface, group);
- if (status) {
+ if (unlikely (status)) {
_cairo_pdf_smask_group_destroy (group);
return status;
}
status = _cairo_pdf_surface_add_smask (surface, gstate_res);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_pdf_surface_add_xobject (surface, group->group_res);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_pdf_operators_flush (&surface->pdf_operators);
- if (status)
+ if (unlikely (status))
return status;
_cairo_output_stream_printf (surface->output,
@@ -5256,7 +5256,7 @@ _cairo_pdf_surface_show_text_glyphs (void *abstract_surface,
group->group_res.id);
} else {
status = _cairo_pdf_surface_select_pattern (surface, source, pattern_res, FALSE);
- if (status)
+ if (unlikely (status))
return status;
/* Each call to show_glyphs() with a transclucent pattern must
@@ -5265,7 +5265,7 @@ _cairo_pdf_surface_show_text_glyphs (void *abstract_surface,
* each other. */
if (! _cairo_pattern_is_opaque (source)) {
status = _cairo_pdf_operators_flush (&surface->pdf_operators);
- if (status)
+ if (unlikely (status))
return status;
}
@@ -5275,11 +5275,11 @@ _cairo_pdf_surface_show_text_glyphs (void *abstract_surface,
clusters, num_clusters,
cluster_flags,
scaled_font);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_pdf_surface_unselect_pattern (surface);
- if (status)
+ if (unlikely (status))
return status;
}
@@ -5308,6 +5308,8 @@ static const cairo_surface_backend_t cairo_pdf_surface_backend = {
NULL, /* composite */
NULL, /* fill_rectangles */
NULL, /* composite_trapezoids */
+ NULL, /* create_span_renderer */
+ NULL, /* check_span_renderer */
NULL, /* _cairo_pdf_surface_copy_page */
_cairo_pdf_surface_show_page,
NULL, /* set_clip_region */
diff --git a/src/cairo-pen.c b/src/cairo-pen.c
index 43d344a1..4158f175 100644
--- a/src/cairo-pen.c
+++ b/src/cairo-pen.c
@@ -65,7 +65,7 @@ _cairo_pen_init (cairo_pen_t *pen,
if (pen->num_vertices > ARRAY_LENGTH (pen->vertices_embedded)) {
pen->vertices = _cairo_malloc_ab (pen->num_vertices,
sizeof (cairo_pen_vertex_t));
- if (pen->vertices == NULL)
+ if (unlikely (pen->vertices == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
} else {
pen->vertices = pen->vertices_embedded;
@@ -112,7 +112,7 @@ _cairo_pen_init_copy (cairo_pen_t *pen, const cairo_pen_t *other)
if (pen->num_vertices > ARRAY_LENGTH (pen->vertices_embedded)) {
pen->vertices = _cairo_malloc_ab (pen->num_vertices,
sizeof (cairo_pen_vertex_t));
- if (pen->vertices == NULL)
+ if (unlikely (pen->vertices == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
@@ -139,7 +139,7 @@ _cairo_pen_add_points (cairo_pen_t *pen, cairo_point_t *point, int num_points)
if (pen->vertices == pen->vertices_embedded) {
vertices = _cairo_malloc_ab (num_vertices,
sizeof (cairo_pen_vertex_t));
- if (vertices == NULL)
+ if (unlikely (vertices == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
memcpy (vertices, pen->vertices,
@@ -148,7 +148,7 @@ _cairo_pen_add_points (cairo_pen_t *pen, cairo_point_t *point, int num_points)
vertices = _cairo_realloc_ab (pen->vertices,
num_vertices,
sizeof (cairo_pen_vertex_t));
- if (vertices == NULL)
+ if (unlikely (vertices == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
@@ -162,7 +162,7 @@ _cairo_pen_add_points (cairo_pen_t *pen, cairo_point_t *point, int num_points)
pen->vertices[pen->num_vertices-num_points+i].point = point[i];
status = _cairo_hull_compute (pen->vertices, &pen->num_vertices);
- if (status)
+ if (unlikely (status))
return status;
_cairo_pen_compute_slopes (pen);
@@ -491,7 +491,7 @@ _cairo_pen_stroke_spline (cairo_pen_stroke_spline_t *stroker,
1);
status = _cairo_polygon_status (&stroker->polygon);
- if (status)
+ if (unlikely (status))
goto BAIL;
status = _cairo_bentley_ottmann_tessellate_polygon (traps,
@@ -548,7 +548,7 @@ _cairo_pen_stroke_spline_init (cairo_pen_stroke_spline_t *stroker,
}
status = _cairo_pen_init_copy (&stroker->pen, pen);
- if (status) {
+ if (unlikely (status)) {
_cairo_spline_fini (&stroker->spline);
return status;
}
diff --git a/src/cairo-png.c b/src/cairo-png.c
index 5bb658cb..fd16c4dc 100644
--- a/src/cairo-png.c
+++ b/src/cairo-png.c
@@ -159,7 +159,7 @@ write_png (cairo_surface_t *surface,
if (status == CAIRO_INT_STATUS_UNSUPPORTED)
return _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
- else if (status)
+ else if (unlikely (status))
return status;
/* PNG complains about "Image width or height is zero in IHDR" */
@@ -169,7 +169,7 @@ write_png (cairo_surface_t *surface,
}
rows = _cairo_malloc_ab (image->height, sizeof (png_byte*));
- if (rows == NULL) {
+ if (unlikely (rows == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto BAIL1;
}
@@ -180,13 +180,13 @@ write_png (cairo_surface_t *surface,
png = png_create_write_struct (PNG_LIBPNG_VER_STRING, &status,
png_simple_error_callback,
png_simple_warning_callback);
- if (png == NULL) {
+ if (unlikely (png == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto BAIL2;
}
info = png_create_info_struct (png);
- if (info == NULL) {
+ if (unlikely (info == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto BAIL3;
}
@@ -361,7 +361,7 @@ stream_write_func (png_structp png, png_bytep data, png_size_t size)
png_closure = png_get_io_ptr (png);
status = png_closure->write_func (png_closure->closure, data, size);
- if (status) {
+ if (unlikely (status)) {
cairo_status_t *error = png_get_error_ptr (png);
if (*error == CAIRO_STATUS_SUCCESS)
*error = status;
@@ -486,7 +486,7 @@ stream_read_func (png_structp png, png_bytep data, png_size_t size)
png_closure = png_get_io_ptr (png);
status = png_closure->read_func (png_closure->closure, data, size);
- if (status) {
+ if (unlikely (status)) {
cairo_status_t *error = png_get_error_ptr (png);
if (*error == CAIRO_STATUS_SUCCESS)
*error = status;
@@ -512,23 +512,24 @@ read_png (struct png_read_closure_t *png_closure)
unsigned char *mime_data;
unsigned int mime_data_length;
+ png_closure->png_data = _cairo_memory_stream_create ();
+
/* XXX: Perhaps we'll want some other error handlers? */
png = png_create_read_struct (PNG_LIBPNG_VER_STRING,
&status,
png_simple_error_callback,
png_simple_warning_callback);
- if (png == NULL) {
+ if (unlikely (png == NULL)) {
surface = _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
goto BAIL;
}
info = png_create_info_struct (png);
- if (info == NULL) {
+ if (unlikely (info == NULL)) {
surface = _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
goto BAIL;
}
- png_closure->png_data = _cairo_memory_stream_create ();
png_set_read_fn (png, png_closure, stream_read_func);
status = CAIRO_STATUS_SUCCESS;
@@ -544,7 +545,7 @@ read_png (struct png_read_closure_t *png_closure)
png_get_IHDR (png, info,
&png_width, &png_height, &depth,
&color_type, &interlace, NULL, NULL);
- if (status) { /* catch any early warnings */
+ if (unlikely (status)) { /* catch any early warnings */
surface = _cairo_surface_create_in_error (status);
goto BAIL;
}
@@ -620,13 +621,13 @@ read_png (struct png_read_closure_t *png_closure)
}
data = _cairo_malloc_ab (png_height, stride);
- if (data == NULL) {
+ if (unlikely (data == NULL)) {
surface = _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
goto BAIL;
}
row_pointers = _cairo_malloc_ab (png_height, sizeof (char *));
- if (row_pointers == NULL) {
+ if (unlikely (row_pointers == NULL)) {
surface = _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
goto BAIL;
}
@@ -637,7 +638,7 @@ read_png (struct png_read_closure_t *png_closure)
png_read_image (png, row_pointers);
png_read_end (png, info);
- if (status) { /* catch any late warnings - probably hit an error already */
+ if (unlikely (status)) { /* catch any late warnings - probably hit an error already */
surface = _cairo_surface_create_in_error (status);
goto BAIL;
}
@@ -654,11 +655,12 @@ read_png (struct png_read_closure_t *png_closure)
status = _cairo_memory_stream_destroy (png_closure->png_data,
&mime_data,
&mime_data_length);
- if (status) {
+ if (unlikely (status)) {
cairo_surface_destroy (surface);
surface = _cairo_surface_create_in_error (status);
goto BAIL;
}
+ png_closure->png_data = NULL;
status = cairo_surface_set_mime_data (surface,
CAIRO_MIME_TYPE_PNG,
@@ -666,7 +668,7 @@ read_png (struct png_read_closure_t *png_closure)
mime_data_length,
free,
mime_data);
- if (status) {
+ if (unlikely (status)) {
free (mime_data);
cairo_surface_destroy (surface);
surface = _cairo_surface_create_in_error (status);
@@ -674,12 +676,17 @@ read_png (struct png_read_closure_t *png_closure)
}
BAIL:
- if (row_pointers)
+ if (row_pointers != NULL)
free (row_pointers);
- if (data)
+ if (data != NULL)
free (data);
- if (png)
+ if (png != NULL)
png_destroy_read_struct (&png, &info, NULL);
+ if (png_closure->png_data != NULL) {
+ cairo_status_t status_ignored;
+
+ status_ignored = _cairo_output_stream_destroy (png_closure->png_data);
+ }
return surface;
}
diff --git a/src/cairo-polygon.c b/src/cairo-polygon.c
index 95cadc9c..0b0fa991 100644
--- a/src/cairo-polygon.c
+++ b/src/cairo-polygon.c
@@ -73,7 +73,7 @@ _cairo_polygon_grow (cairo_polygon_t *polygon)
new_size, sizeof (cairo_edge_t));
}
- if (new_edges == NULL) {
+ if (unlikely (new_edges == NULL)) {
polygon->status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
return FALSE;
}
diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c
index 0c9ef7f4..a13be1d8 100644
--- a/src/cairo-ps-surface.c
+++ b/src/cairo-ps-surface.c
@@ -262,7 +262,7 @@ _cairo_ps_surface_emit_type1_font_subset (cairo_ps_surface_t *surface,
snprintf (name, sizeof name, "f-%d-%d",
font_subset->font_id, font_subset->subset_id);
status = _cairo_type1_subset_init (&subset, name, font_subset, TRUE);
- if (status)
+ if (unlikely (status))
return status;
/* FIXME: Figure out document structure convention for fonts */
@@ -293,7 +293,7 @@ _cairo_ps_surface_emit_type1_font_fallback (cairo_ps_surface_t *surface,
snprintf (name, sizeof name, "f-%d-%d",
font_subset->font_id, font_subset->subset_id);
status = _cairo_type1_fallback_init_hex (&subset, name, font_subset);
- if (status)
+ if (unlikely (status))
return status;
/* FIXME: Figure out document structure convention for fonts */
@@ -322,7 +322,7 @@ _cairo_ps_surface_emit_truetype_font_subset (cairo_ps_surface_t *surface,
unsigned int i, begin, end;
status = _cairo_truetype_subset_init (&subset, font_subset);
- if (status)
+ if (unlikely (status))
return status;
/* FIXME: Figure out document structure convention for fonts */
@@ -463,7 +463,7 @@ _cairo_ps_surface_analyze_user_font_subset (cairo_scaled_font_subset_t *font_sub
for (i = 0; i < font_subset->num_glyphs; i++) {
status = _cairo_type3_glyph_surface_analyze_glyph (type3_surface,
font_subset->glyphs[i]);
- if (status)
+ if (unlikely (status))
break;
}
@@ -527,7 +527,7 @@ _cairo_ps_surface_emit_type3_font_subset (cairo_ps_surface_t *surface,
font_subset->glyphs[i],
&bbox,
&width);
- if (status)
+ if (unlikely (status))
break;
_cairo_output_stream_printf (surface->final_stream,
@@ -549,7 +549,7 @@ _cairo_ps_surface_emit_type3_font_subset (cairo_ps_surface_t *surface,
}
}
cairo_surface_destroy (type3_surface);
- if (status)
+ if (unlikely (status))
return status;
_cairo_output_stream_printf (surface->final_stream,
@@ -635,19 +635,19 @@ _cairo_ps_surface_emit_font_subsets (cairo_ps_surface_t *surface)
status = _cairo_scaled_font_subsets_foreach_user (surface->font_subsets,
_cairo_ps_surface_analyze_user_font_subset,
surface);
- if (status)
+ if (unlikely (status))
goto BAIL;
status = _cairo_scaled_font_subsets_foreach_unscaled (surface->font_subsets,
_cairo_ps_surface_emit_unscaled_font_subset,
surface);
- if (status)
+ if (unlikely (status))
goto BAIL;
status = _cairo_scaled_font_subsets_foreach_scaled (surface->font_subsets,
_cairo_ps_surface_emit_scaled_font_subset,
surface);
- if (status)
+ if (unlikely (status))
goto BAIL;
status = _cairo_scaled_font_subsets_foreach_user (surface->font_subsets,
@@ -705,7 +705,7 @@ _cairo_ps_surface_create_for_stream_internal (cairo_output_stream_t *stream,
cairo_ps_surface_t *surface;
surface = malloc (sizeof (cairo_ps_surface_t));
- if (surface == NULL) {
+ if (unlikely (surface == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto CLEANUP;
}
@@ -730,11 +730,11 @@ _cairo_ps_surface_create_for_stream_internal (cairo_output_stream_t *stream,
surface->stream = _cairo_output_stream_create_for_file (surface->tmpfile);
status = _cairo_output_stream_get_status (surface->stream);
- if (status)
+ if (unlikely (status))
goto CLEANUP_OUTPUT_STREAM;
surface->font_subsets = _cairo_scaled_font_subsets_create_simple ();
- if (surface->font_subsets == NULL) {
+ if (unlikely (surface->font_subsets == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto CLEANUP_OUTPUT_STREAM;
}
@@ -935,7 +935,7 @@ cairo_ps_surface_restrict_to_level (cairo_surface_t *surface,
cairo_status_t status;
status = _extract_ps_surface (surface, &ps_surface);
- if (status) {
+ if (unlikely (status)) {
status = _cairo_surface_set_error (surface, status);
return;
}
@@ -1010,7 +1010,7 @@ cairo_ps_surface_set_eps (cairo_surface_t *surface,
cairo_status_t status;
status = _extract_ps_surface (surface, &ps_surface);
- if (status) {
+ if (unlikely (status)) {
status = _cairo_surface_set_error (surface, status);
return;
}
@@ -1035,7 +1035,7 @@ cairo_ps_surface_get_eps (cairo_surface_t *surface)
cairo_status_t status;
status = _extract_ps_surface (surface, &ps_surface);
- if (status) {
+ if (unlikely (status)) {
status = _cairo_surface_set_error (surface, status);
return FALSE;
}
@@ -1069,7 +1069,7 @@ cairo_ps_surface_set_size (cairo_surface_t *surface,
cairo_status_t status;
status = _extract_ps_surface (surface, &ps_surface);
- if (status) {
+ if (unlikely (status)) {
status = _cairo_surface_set_error (surface, status);
return;
}
@@ -1082,7 +1082,7 @@ cairo_ps_surface_set_size (cairo_surface_t *surface,
status = _cairo_paginated_surface_set_size (ps_surface->paginated_surface,
width_in_points,
height_in_points);
- if (status)
+ if (unlikely (status))
status = _cairo_surface_set_error (surface, status);
}
@@ -1183,7 +1183,7 @@ cairo_ps_surface_dsc_comment (cairo_surface_t *surface,
char *comment_copy;
status = _extract_ps_surface (surface, &ps_surface);
- if (status) {
+ if (unlikely (status)) {
status = _cairo_surface_set_error (surface, status);
return;
}
@@ -1201,13 +1201,13 @@ cairo_ps_surface_dsc_comment (cairo_surface_t *surface,
/* Then, copy the comment and store it in the appropriate array. */
comment_copy = strdup (comment);
- if (comment_copy == NULL) {
+ if (unlikely (comment_copy == NULL)) {
status = _cairo_surface_set_error (surface, CAIRO_STATUS_NO_MEMORY);
return;
}
status = _cairo_array_append (ps_surface->dsc_comment_target, &comment_copy);
- if (status) {
+ if (unlikely (status)) {
free (comment_copy);
status = _cairo_surface_set_error (surface, status);
return;
@@ -1237,7 +1237,7 @@ cairo_ps_surface_dsc_begin_setup (cairo_surface_t *surface)
cairo_status_t status;
status = _extract_ps_surface (surface, &ps_surface);
- if (status) {
+ if (unlikely (status)) {
status = _cairo_surface_set_error (surface, status);
return;
}
@@ -1272,7 +1272,7 @@ cairo_ps_surface_dsc_begin_page_setup (cairo_surface_t *surface)
cairo_status_t status;
status = _extract_ps_surface (surface, &ps_surface);
- if (status) {
+ if (unlikely (status)) {
status = _cairo_surface_set_error (surface, status);
return;
}
@@ -1304,11 +1304,11 @@ _cairo_ps_surface_finish (void *abstract_surface)
_cairo_ps_surface_emit_header (surface);
status = _cairo_ps_surface_emit_font_subsets (surface);
- if (status)
+ if (unlikely (status))
goto CLEANUP;
status = _cairo_ps_surface_emit_body (surface);
- if (status)
+ if (unlikely (status))
goto CLEANUP;
_cairo_ps_surface_emit_footer (surface);
@@ -1362,7 +1362,7 @@ _cairo_ps_surface_end_page (cairo_ps_surface_t *surface)
cairo_int_status_t status;
status = _cairo_pdf_operators_flush (&surface->pdf_operators);
- if (status)
+ if (unlikely (status))
return status;
_cairo_output_stream_printf (surface->stream,
@@ -1378,7 +1378,7 @@ _cairo_ps_surface_show_page (void *abstract_surface)
cairo_int_status_t status;
status = _cairo_ps_surface_end_page (surface);
- if (status)
+ if (unlikely (status))
return status;
_cairo_output_stream_printf (surface->stream, "showpage\n");
@@ -1407,7 +1407,7 @@ _cairo_ps_surface_analyze_surface_pattern_transparency (cairo_ps_surface_t
status = _cairo_surface_acquire_source_image (pattern->surface,
&image,
&image_extra);
- if (status)
+ if (unlikely (status))
return status;
if (image->base.status)
@@ -1733,7 +1733,7 @@ _string_array_stream_create (cairo_output_stream_t *output)
string_array_stream_t *stream;
stream = malloc (sizeof (string_array_stream_t));
- if (stream == NULL) {
+ if (unlikely (stream == NULL)) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return (cairo_output_stream_t *) &_cairo_output_stream_nil;
}
@@ -1760,7 +1760,7 @@ _base85_array_stream_create (cairo_output_stream_t *output)
string_array_stream_t *stream;
stream = malloc (sizeof (string_array_stream_t));
- if (stream == NULL) {
+ if (unlikely (stream == NULL)) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return (cairo_output_stream_t *) &_cairo_output_stream_nil;
}
@@ -1809,7 +1809,7 @@ _cairo_ps_surface_flatten_image_transparency (cairo_ps_surface_t *surface,
background_color,
0, 0,
image->width, image->height);
- if (status)
+ if (unlikely (status))
goto fail;
status = _cairo_surface_composite (CAIRO_OPERATOR_OVER,
@@ -1821,7 +1821,7 @@ _cairo_ps_surface_flatten_image_transparency (cairo_ps_surface_t *surface,
0, 0,
image->width,
image->height);
- if (status)
+ if (unlikely (status))
goto fail;
_cairo_pattern_fini (&pattern.base);
@@ -1851,12 +1851,12 @@ _cairo_ps_surface_emit_base85_string (cairo_ps_surface_t *surface,
string_array_stream = _base85_array_stream_create (surface->stream);
status = _cairo_output_stream_get_status (string_array_stream);
- if (status)
+ if (unlikely (status))
return _cairo_output_stream_destroy (string_array_stream);
base85_stream = _cairo_base85_stream_create (string_array_stream);
status = _cairo_output_stream_get_status (base85_stream);
- if (status) {
+ if (unlikely (status)) {
status2 = _cairo_output_stream_destroy (string_array_stream);
return _cairo_output_stream_destroy (base85_stream);
}
@@ -1918,7 +1918,7 @@ _cairo_ps_surface_emit_image (cairo_ps_surface_t *surface,
status = _cairo_ps_surface_flatten_image_transparency (surface,
image,
&opaque_image);
- if (status)
+ if (unlikely (status))
return status;
use_mask = FALSE;
@@ -1940,7 +1940,7 @@ _cairo_ps_surface_emit_image (cairo_ps_surface_t *surface,
data_size = image->height * image->width * 3;
}
data = malloc (data_size);
- if (data == NULL) {
+ if (unlikely (data == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto bail1;
}
@@ -1989,7 +1989,7 @@ _cairo_ps_surface_emit_image (cairo_ps_surface_t *surface,
* instead. */
data_compressed_size = data_size;
data_compressed = _cairo_lzw_compress (data, &data_compressed_size);
- if (data_compressed == NULL) {
+ if (unlikely (data_compressed == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto bail2;
}
@@ -2004,7 +2004,7 @@ _cairo_ps_surface_emit_image (cairo_ps_surface_t *surface,
data_compressed,
data_compressed_size,
TRUE);
- if (status)
+ if (unlikely (status))
goto bail3;
_cairo_output_stream_printf (surface->stream,
@@ -2138,7 +2138,7 @@ _cairo_ps_surface_emit_jpeg_image (cairo_ps_surface_t *surface,
return CAIRO_INT_STATUS_UNSUPPORTED;
status = _cairo_image_info_get_jpeg_info (&info, mime_data, mime_data_length);
- if (status)
+ if (unlikely (status))
return status;
if (info.num_components != 1 && info.num_components != 3)
@@ -2154,7 +2154,7 @@ _cairo_ps_surface_emit_jpeg_image (cairo_ps_surface_t *surface,
mime_data,
mime_data_length,
TRUE);
- if (status)
+ if (unlikely (status))
return status;
_cairo_output_stream_printf (surface->stream,
@@ -2219,7 +2219,7 @@ _cairo_ps_surface_emit_meta_surface (cairo_ps_surface_t *surface,
cairo_status_t status;
status = _cairo_surface_get_extents (meta_surface, &meta_extents);
- if (status)
+ if (unlikely (status))
return status;
old_content = surface->content;
@@ -2251,11 +2251,11 @@ _cairo_ps_surface_emit_meta_surface (cairo_ps_surface_t *surface,
status = _cairo_meta_surface_replay_region (meta_surface, &surface->base,
CAIRO_META_REGION_NATIVE);
assert (status != CAIRO_INT_STATUS_UNSUPPORTED);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_pdf_operators_flush (&surface->pdf_operators);
- if (status)
+ if (unlikely (status))
return status;
_cairo_output_stream_printf (surface->stream,
@@ -2267,7 +2267,7 @@ _cairo_ps_surface_emit_meta_surface (cairo_ps_surface_t *surface,
_cairo_pdf_operators_reset (&surface->pdf_operators);
surface->cairo_to_ps = old_cairo_to_ps;
status = _cairo_surface_set_clip (&surface->base, old_clip);
- if (status)
+ if (unlikely (status))
return status;
_cairo_pdf_operators_set_cairo_to_pdf_matrix (&surface->pdf_operators,
@@ -2337,7 +2337,7 @@ _cairo_ps_surface_acquire_surface (cairo_ps_surface_t *surface,
cairo_rectangle_int_t pattern_extents;
status = _cairo_surface_get_extents (meta_surface, &pattern_extents);
- if (status)
+ if (unlikely (status))
return status;
*width = pattern_extents.width;
@@ -2346,7 +2346,7 @@ _cairo_ps_surface_acquire_surface (cairo_ps_surface_t *surface,
status = _cairo_surface_acquire_source_image (pattern->surface,
&surface->acquired_image,
&surface->image_extra);
- if (status)
+ if (unlikely (status))
return status;
pad_image = &surface->acquired_image->base;
@@ -2383,7 +2383,7 @@ _cairo_ps_surface_acquire_surface (cairo_ps_surface_t *surface,
rect.width,
rect.height);
_cairo_pattern_fini (&pad_pattern.base);
- if (status)
+ if (unlikely (status))
goto BAIL;
}
@@ -2458,7 +2458,7 @@ _cairo_ps_surface_paint_surface (cairo_ps_surface_t *surface,
extents,
&width, &height,
&origin_x, &origin_y);
- if (status)
+ if (unlikely (status))
return status;
cairo_p2d = pattern->base.matrix;
@@ -2540,7 +2540,7 @@ _cairo_ps_surface_emit_surface_pattern (cairo_ps_surface_t *surface,
extents,
&pattern_width, &pattern_height,
&origin_x, &origin_y);
- if (status)
+ if (unlikely (status))
return status;
switch (pattern->base.extend) {
@@ -2602,7 +2602,7 @@ _cairo_ps_surface_emit_surface_pattern (cairo_ps_surface_t *surface,
}
status = _cairo_ps_surface_emit_surface (surface, pattern, op,
pattern_width, pattern_height);
- if (status)
+ if (unlikely (status))
return status;
surface->use_string_datasource = old_use_string_datasource;
@@ -2649,7 +2649,7 @@ _cairo_ps_surface_emit_surface_pattern (cairo_ps_surface_t *surface,
">>\n");
status = _cairo_surface_get_extents (&surface->base, &surface_extents);
- if (status)
+ if (unlikely (status))
return status;
cairo_p2d = pattern->base.matrix;
@@ -2749,7 +2749,7 @@ _cairo_ps_surface_emit_pattern_stops (cairo_ps_surface_t *surface,
unsigned int i, n_stops;
allstops = _cairo_malloc_ab ((pattern->n_stops + 2), sizeof (cairo_ps_color_stop_t));
- if (allstops == NULL)
+ if (unlikely (allstops == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
stops = &allstops[1];
@@ -2955,7 +2955,7 @@ _cairo_ps_surface_emit_linear_pattern (cairo_ps_surface_t *surface,
status = _cairo_ps_surface_emit_pattern_stops (surface,
&pattern->base);
- if (status)
+ if (unlikely (status))
return status;
if (pattern->base.base.extend == CAIRO_EXTEND_REPEAT ||
@@ -2964,7 +2964,7 @@ _cairo_ps_surface_emit_linear_pattern (cairo_ps_surface_t *surface,
&pattern->base,
repeat_begin,
repeat_end);
- if (status)
+ if (unlikely (status))
return status;
}
@@ -3042,7 +3042,7 @@ _cairo_ps_surface_emit_radial_pattern (cairo_ps_surface_t *surface,
r2 = _cairo_fixed_to_double (pattern->r2);
status = _cairo_ps_surface_emit_pattern_stops (surface, &pattern->base);
- if (status)
+ if (unlikely (status))
return status;
_cairo_output_stream_printf (surface->stream,
@@ -3092,7 +3092,7 @@ _cairo_ps_surface_emit_pattern (cairo_ps_surface_t *surface,
! _cairo_color_equal (&surface->current_color, &solid->color))
{
status = _cairo_pdf_operators_flush (&surface->pdf_operators);
- if (status)
+ if (unlikely (status))
return status;
_cairo_ps_surface_emit_solid_pattern (surface, (cairo_solid_pattern_t *) pattern);
@@ -3106,7 +3106,7 @@ _cairo_ps_surface_emit_pattern (cairo_ps_surface_t *surface,
surface->current_pattern_is_solid_color = FALSE;
status = _cairo_pdf_operators_flush (&surface->pdf_operators);
- if (status)
+ if (unlikely (status))
return status;
switch (pattern->type) {
@@ -3120,21 +3120,21 @@ _cairo_ps_surface_emit_pattern (cairo_ps_surface_t *surface,
(cairo_surface_pattern_t *) pattern,
extents,
op);
- if (status)
+ if (unlikely (status))
return status;
break;
case CAIRO_PATTERN_TYPE_LINEAR:
status = _cairo_ps_surface_emit_linear_pattern (surface,
(cairo_linear_pattern_t *) pattern);
- if (status)
+ if (unlikely (status))
return status;
break;
case CAIRO_PATTERN_TYPE_RADIAL:
status = _cairo_ps_surface_emit_radial_pattern (surface,
(cairo_radial_pattern_t *) pattern);
- if (status)
+ if (unlikely (status))
return status;
break;
}
@@ -3163,7 +3163,7 @@ _cairo_ps_surface_intersect_clip_path (void *abstract_surface,
if (path == NULL) {
status = _cairo_pdf_operators_flush (&surface->pdf_operators);
- if (status)
+ if (unlikely (status))
return status;
_cairo_output_stream_printf (stream, "Q q\n");
@@ -3230,11 +3230,11 @@ _cairo_ps_surface_paint (void *abstract_surface,
#endif
status = _cairo_surface_get_extents (&surface->base, &extents);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_pdf_operators_flush (&surface->pdf_operators);
- if (status)
+ if (unlikely (status))
return status;
if (source->type == CAIRO_PATTERN_TYPE_SURFACE &&
@@ -3248,7 +3248,7 @@ _cairo_ps_surface_paint (void *abstract_surface,
status = _cairo_ps_surface_paint_surface (surface,
(cairo_surface_pattern_t *) source,
paint_extents, op);
- if (status)
+ if (unlikely (status))
return status;
_cairo_output_stream_printf (stream, "Q\n");
@@ -3257,7 +3257,7 @@ _cairo_ps_surface_paint (void *abstract_surface,
if (status == CAIRO_INT_STATUS_NOTHING_TO_DO)
return CAIRO_STATUS_SUCCESS;
- if (status)
+ if (unlikely (status))
return status;
_cairo_output_stream_printf (stream, "0 0 %d %d rectfill\n",
@@ -3332,7 +3332,7 @@ _cairo_ps_surface_fill (void *abstract_surface,
source->extend == CAIRO_EXTEND_PAD))
{
status = _cairo_pdf_operators_flush (&surface->pdf_operators);
- if (status)
+ if (unlikely (status))
return status;
_cairo_output_stream_printf (surface->stream, "q\n");
@@ -3340,13 +3340,13 @@ _cairo_ps_surface_fill (void *abstract_surface,
status = _cairo_pdf_operators_clip (&surface->pdf_operators,
path,
fill_rule);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_ps_surface_paint_surface (surface,
(cairo_surface_pattern_t *) source,
extents, op);
- if (status)
+ if (unlikely (status))
return status;
_cairo_output_stream_printf (surface->stream, "Q\n");
@@ -3356,7 +3356,7 @@ _cairo_ps_surface_fill (void *abstract_surface,
if (status == CAIRO_INT_STATUS_NOTHING_TO_DO)
return CAIRO_STATUS_SUCCESS;
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_pdf_operators_fill (&surface->pdf_operators,
@@ -3397,7 +3397,7 @@ _cairo_ps_surface_show_glyphs (void *abstract_surface,
if (status == CAIRO_INT_STATUS_NOTHING_TO_DO)
return CAIRO_STATUS_SUCCESS;
- if (status)
+ if (unlikely (status))
return status;
return _cairo_pdf_operators_show_text_glyphs (&surface->pdf_operators,
@@ -3503,6 +3503,8 @@ static const cairo_surface_backend_t cairo_ps_surface_backend = {
NULL, /* composite */
NULL, /* fill_rectangles */
NULL, /* composite_trapezoids */
+ NULL, /* create_span_renderer */
+ NULL, /* check_span_renderer */
NULL, /* cairo_ps_surface_copy_page */
_cairo_ps_surface_show_page,
NULL, /* set_clip_region */
diff --git a/src/cairo-quartz-image-surface.c b/src/cairo-quartz-image-surface.c
index 3eee2c11..3bfd9e21 100644
--- a/src/cairo-quartz-image-surface.c
+++ b/src/cairo-quartz-image-surface.c
@@ -163,6 +163,8 @@ static const cairo_surface_backend_t cairo_quartz_image_surface_backend = {
NULL, /* composite */
NULL, /* fill_rectangles */
NULL, /* composite_trapezoids */
+ NULL, /* create_span_renderer */
+ NULL, /* check_span_renderer */
NULL, /* copy_page */
NULL, /* show_page */
NULL, /* set_clip_region */
diff --git a/src/cairo-quartz-surface.c b/src/cairo-quartz-surface.c
index 19160b4b..34661853 100644
--- a/src/cairo-quartz-surface.c
+++ b/src/cairo-quartz-surface.c
@@ -680,15 +680,21 @@ ComputeGradientValue (void *info, const float *in, float *out)
}
static CGFunctionRef
-CreateGradientFunction (cairo_gradient_pattern_t *gpat)
+CreateGradientFunction (const cairo_gradient_pattern_t *gpat)
{
+ cairo_pattern_t *pat;
float input_value_range[2] = { 0.f, 1.f };
float output_value_ranges[8] = { 0.f, 1.f, 0.f, 1.f, 0.f, 1.f, 0.f, 1.f };
CGFunctionCallbacks callbacks = {
0, ComputeGradientValue, (CGFunctionReleaseInfoCallback) cairo_pattern_destroy
};
- return CGFunctionCreate (cairo_pattern_reference (&gpat->base),
+ if (_cairo_pattern_create_copy (&pat, &gpat->base))
+ /* quartz doesn't deal very well with malloc failing, so there's
+ * not much point in us trying either */
+ return NULL;
+
+ return CGFunctionCreate (pat,
1,
input_value_range,
4,
@@ -698,10 +704,11 @@ CreateGradientFunction (cairo_gradient_pattern_t *gpat)
static CGFunctionRef
CreateRepeatingGradientFunction (cairo_quartz_surface_t *surface,
- cairo_gradient_pattern_t *gpat,
+ const cairo_gradient_pattern_t *gpat,
CGPoint *start, CGPoint *end,
CGAffineTransform matrix)
{
+ cairo_pattern_t *pat;
float input_value_range[2];
float output_value_ranges[8] = { 0.f, 1.f, 0.f, 1.f, 0.f, 1.f, 0.f, 1.f };
CGFunctionCallbacks callbacks = {
@@ -766,7 +773,12 @@ CreateRepeatingGradientFunction (cairo_quartz_surface_t *surface,
input_value_range[0] = 0.0 - 1.0 * rep_start;
input_value_range[1] = 1.0 + 1.0 * rep_end;
- return CGFunctionCreate (cairo_pattern_reference (&gpat->base),
+ if (_cairo_pattern_create_copy (&pat, &gpat->base))
+ /* quartz doesn't deal very well with malloc failing, so there's
+ * not much point in us trying either */
+ return NULL;
+
+ return CGFunctionCreate (pat,
1,
input_value_range,
4,
@@ -1013,7 +1025,7 @@ typedef enum {
static cairo_quartz_action_t
_cairo_quartz_setup_fallback_source (cairo_quartz_surface_t *surface,
- cairo_pattern_t *source)
+ const cairo_pattern_t *source)
{
CGRect clipBox = CGContextGetClipBoundingBox (surface->cgContext);
CGAffineTransform ctm;
@@ -1022,6 +1034,7 @@ _cairo_quartz_setup_fallback_source (cairo_quartz_surface_t *surface,
cairo_surface_t *fallback;
cairo_t *fallback_cr;
CGImageRef img;
+ cairo_pattern_t *source_copy;
cairo_status_t status;
@@ -1050,7 +1063,13 @@ _cairo_quartz_setup_fallback_source (cairo_quartz_surface_t *surface,
/* Paint the source onto our temporary */
fallback_cr = cairo_create (fallback);
cairo_set_operator (fallback_cr, CAIRO_OPERATOR_SOURCE);
- cairo_set_source (fallback_cr, source);
+
+ /* Use a copy of the pattern because it is const and could be allocated
+ * on the stack */
+ status = _cairo_pattern_create_copy (&source_copy, source);
+ cairo_set_source (fallback_cr, source_copy);
+ cairo_pattern_destroy (source_copy);
+
cairo_paint (fallback_cr);
cairo_destroy (fallback_cr);
@@ -1070,9 +1089,9 @@ _cairo_quartz_setup_fallback_source (cairo_quartz_surface_t *surface,
static cairo_quartz_action_t
_cairo_quartz_setup_linear_source (cairo_quartz_surface_t *surface,
- cairo_linear_pattern_t *lpat)
+ const cairo_linear_pattern_t *lpat)
{
- cairo_pattern_t *abspat = (cairo_pattern_t *) lpat;
+ const cairo_pattern_t *abspat = &lpat->base.base;
cairo_matrix_t mat;
CGPoint start, end;
CGFunctionRef gradFunc;
@@ -1085,7 +1104,7 @@ _cairo_quartz_setup_linear_source (cairo_quartz_surface_t *surface,
return DO_SOLID;
}
- cairo_pattern_get_matrix (abspat, &mat);
+ mat = abspat->matrix;
cairo_matrix_invert (&mat);
_cairo_quartz_cairo_matrix_to_quartz (&mat, &surface->sourceTransform);
@@ -1099,10 +1118,10 @@ _cairo_quartz_setup_linear_source (cairo_quartz_surface_t *surface,
if (abspat->extend == CAIRO_EXTEND_NONE ||
abspat->extend == CAIRO_EXTEND_PAD)
{
- gradFunc = CreateGradientFunction ((cairo_gradient_pattern_t*) lpat);
+ gradFunc = CreateGradientFunction (&lpat->base);
} else {
gradFunc = CreateRepeatingGradientFunction (surface,
- (cairo_gradient_pattern_t*) lpat,
+ &lpat->base,
&start, &end, surface->sourceTransform);
}
@@ -1119,9 +1138,9 @@ _cairo_quartz_setup_linear_source (cairo_quartz_surface_t *surface,
static cairo_quartz_action_t
_cairo_quartz_setup_radial_source (cairo_quartz_surface_t *surface,
- cairo_radial_pattern_t *rpat)
+ const cairo_radial_pattern_t *rpat)
{
- cairo_pattern_t *abspat = (cairo_pattern_t *)rpat;
+ const cairo_pattern_t *abspat = &rpat->base.base;
cairo_matrix_t mat;
CGPoint start, end;
CGFunctionRef gradFunc;
@@ -1142,10 +1161,10 @@ _cairo_quartz_setup_radial_source (cairo_quartz_surface_t *surface,
* Radial shadings). So, instead, let's just render an image
* for pixman to draw the shading into, and use that.
*/
- return _cairo_quartz_setup_fallback_source (surface, (cairo_pattern_t*) rpat);
+ return _cairo_quartz_setup_fallback_source (surface, &rpat->base.base);
}
- cairo_pattern_get_matrix (abspat, &mat);
+ mat = abspat->matrix;
cairo_matrix_invert (&mat);
_cairo_quartz_cairo_matrix_to_quartz (&mat, &surface->sourceTransform);
@@ -1156,7 +1175,7 @@ _cairo_quartz_setup_radial_source (cairo_quartz_surface_t *surface,
end = CGPointMake (_cairo_fixed_to_double (rpat->c2.x),
_cairo_fixed_to_double (rpat->c2.y));
- gradFunc = CreateGradientFunction ((cairo_gradient_pattern_t*) rpat);
+ gradFunc = CreateGradientFunction (&rpat->base);
surface->sourceShading = CGShadingCreateRadial (rgb,
start,
@@ -1199,13 +1218,13 @@ _cairo_quartz_setup_source (cairo_quartz_surface_t *surface,
}
if (source->type == CAIRO_PATTERN_TYPE_LINEAR) {
- cairo_linear_pattern_t *lpat = (cairo_linear_pattern_t *)source;
+ const cairo_linear_pattern_t *lpat = (const cairo_linear_pattern_t *)source;
return _cairo_quartz_setup_linear_source (surface, lpat);
}
if (source->type == CAIRO_PATTERN_TYPE_RADIAL) {
- cairo_radial_pattern_t *rpat = (cairo_radial_pattern_t *)source;
+ const cairo_radial_pattern_t *rpat = (const cairo_radial_pattern_t *)source;
return _cairo_quartz_setup_radial_source (surface, rpat);
}
@@ -1213,7 +1232,7 @@ _cairo_quartz_setup_source (cairo_quartz_surface_t *surface,
if (source->type == CAIRO_PATTERN_TYPE_SURFACE &&
(source->extend == CAIRO_EXTEND_NONE || (CGContextDrawTiledImagePtr && source->extend == CAIRO_EXTEND_REPEAT)))
{
- cairo_surface_pattern_t *spat = (cairo_surface_pattern_t *) source;
+ const cairo_surface_pattern_t *spat = (const cairo_surface_pattern_t *) source;
cairo_surface_t *pat_surf = spat->surface;
CGImageRef img;
cairo_matrix_t m = spat->base.matrix;
@@ -2259,7 +2278,7 @@ _cairo_quartz_surface_mask_with_generic (cairo_quartz_surface_t *surface,
cairo_t *gradient_surf_cr = NULL;
cairo_surface_pattern_t surface_pattern;
- cairo_pattern_t *mask_copy = NULL;
+ cairo_pattern_t *mask_copy;
cairo_int_status_t status;
/* Render the gradient to a surface */
@@ -2271,13 +2290,13 @@ _cairo_quartz_surface_mask_with_generic (cairo_quartz_surface_t *surface,
/* make a copy of the pattern because because cairo_set_source doesn't take
* a 'const cairo_pattern_t *' */
_cairo_pattern_create_copy (&mask_copy, mask);
-
cairo_set_source (gradient_surf_cr, mask_copy);
+ cairo_pattern_destroy (mask_copy);
+
cairo_set_operator (gradient_surf_cr, CAIRO_OPERATOR_SOURCE);
cairo_paint (gradient_surf_cr);
status = cairo_status (gradient_surf_cr);
cairo_destroy (gradient_surf_cr);
- cairo_pattern_destroy (mask_copy);
if (status)
goto BAIL;
@@ -2404,6 +2423,8 @@ static const struct _cairo_surface_backend cairo_quartz_surface_backend = {
NULL, /* composite */
NULL, /* fill_rectangles */
NULL, /* composite_trapezoids */
+ NULL, /* create_span_renderer */
+ NULL, /* check_span_renderer */
NULL, /* copy_page */
NULL, /* show_page */
NULL, /* set_clip_region */
diff --git a/src/cairo-rectangle.c b/src/cairo-rectangle.c
index 2143f0c6..9a68409c 100644
--- a/src/cairo-rectangle.c
+++ b/src/cairo-rectangle.c
@@ -223,3 +223,24 @@ _cairo_box_contains_point (cairo_box_t *box, cairo_point_t *point)
return FALSE;
return TRUE;
}
+
+void
+_cairo_composite_rectangles_init(
+ cairo_composite_rectangles_t *rects,
+ int all_x,
+ int all_y,
+ int width,
+ int height)
+{
+ rects->src.x = all_x;
+ rects->src.y = all_y;
+ rects->mask.x = all_x;
+ rects->mask.y = all_y;
+ rects->clip.x = all_x;
+ rects->clip.y = all_y;
+ rects->dst.x = all_x;
+ rects->dst.y = all_y;
+
+ rects->width = width;
+ rects->height = height;
+}
diff --git a/src/cairo-region-private.h b/src/cairo-region-private.h
index 588762e5..1f4cfb47 100644
--- a/src/cairo-region-private.h
+++ b/src/cairo-region-private.h
@@ -96,6 +96,11 @@ _cairo_region_intersect (cairo_region_t *dst,
cairo_region_t *b);
cairo_private cairo_int_status_t
+_cairo_region_union (cairo_region_t *dst,
+ cairo_region_t *a,
+ cairo_region_t *b);
+
+cairo_private cairo_int_status_t
_cairo_region_union_rect (cairo_region_t *dst,
cairo_region_t *src,
cairo_rectangle_int_t *rect);
diff --git a/src/cairo-region.c b/src/cairo-region.c
index 146ae60b..376dbc84 100644
--- a/src/cairo-region.c
+++ b/src/cairo-region.c
@@ -64,7 +64,7 @@ _cairo_region_init_boxes (cairo_region_t *region,
if (count > ARRAY_LENGTH (stack_pboxes)) {
pboxes = _cairo_malloc_ab (count, sizeof (pixman_box32_t));
- if (pboxes == NULL)
+ if (unlikely (pboxes == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
@@ -181,6 +181,17 @@ _cairo_region_intersect (cairo_region_t *dst, cairo_region_t *a, cairo_region_t
return CAIRO_STATUS_SUCCESS;
}
+cairo_private cairo_int_status_t
+_cairo_region_union (cairo_region_t *dst,
+ cairo_region_t *a,
+ cairo_region_t *b)
+{
+ if (!pixman_region_union (&dst->rgn, &a->rgn, &b->rgn))
+ return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
+ return CAIRO_STATUS_SUCCESS;
+}
+
cairo_int_status_t
_cairo_region_union_rect (cairo_region_t *dst,
cairo_region_t *src,
diff --git a/src/cairo-scaled-font-subsets.c b/src/cairo-scaled-font-subsets.c
index d8771bba..c802c314 100644
--- a/src/cairo-scaled-font-subsets.c
+++ b/src/cairo-scaled-font-subsets.c
@@ -163,7 +163,7 @@ _cairo_sub_font_glyph_create (unsigned long scaled_font_glyph_index,
cairo_sub_font_glyph_t *sub_font_glyph;
sub_font_glyph = malloc (sizeof (cairo_sub_font_glyph_t));
- if (sub_font_glyph == NULL) {
+ if (unlikely (sub_font_glyph == NULL)) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return NULL;
}
@@ -267,7 +267,7 @@ _cairo_sub_font_create (cairo_scaled_font_subsets_t *parent,
cairo_scaled_font_subsets_glyph_t subset_glyph;
sub_font = malloc (sizeof (cairo_sub_font_t));
- if (sub_font == NULL)
+ if (unlikely (sub_font == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
sub_font->is_scaled = is_scaled;
@@ -284,7 +284,7 @@ _cairo_sub_font_create (cairo_scaled_font_subsets_t *parent,
sub_font->max_glyphs_per_subset = max_glyphs_per_subset;
sub_font->sub_font_glyphs = _cairo_hash_table_create (_cairo_sub_font_glyphs_equal);
- if (sub_font->sub_font_glyphs == NULL) {
+ if (unlikely (sub_font->sub_font_glyphs == NULL)) {
free (sub_font);
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
@@ -294,7 +294,7 @@ _cairo_sub_font_create (cairo_scaled_font_subsets_t *parent,
* Type 3 fonts */
if (! _cairo_font_face_is_user (scaled_font->font_face)) {
status = _cairo_sub_font_map_glyph (sub_font, 0, NULL, -1, &subset_glyph);
- if (status) {
+ if (unlikely (status)) {
_cairo_hash_table_destroy (sub_font->sub_font_glyphs);
free (sub_font);
return status;
@@ -349,7 +349,7 @@ _cairo_sub_font_glyph_lookup_unicode (cairo_sub_font_glyph_t *sub_font_glyph,
status = scaled_font->backend->index_to_ucs4 (scaled_font,
scaled_font_glyph_index,
&unicode);
- if (status)
+ if (unlikely (status))
return status;
}
@@ -360,7 +360,7 @@ _cairo_sub_font_glyph_lookup_unicode (cairo_sub_font_glyph_t *sub_font_glyph,
len = _cairo_ucs4_to_utf8 (unicode, buf);
if (len > 0) {
sub_font_glyph->utf8 = malloc (len + 1);
- if (sub_font_glyph->utf8 == NULL)
+ if (unlikely (sub_font_glyph->utf8 == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
memcpy (sub_font_glyph->utf8, buf, len);
@@ -466,7 +466,7 @@ _cairo_sub_font_map_glyph (cairo_sub_font_t *sub_font,
* except for Type 3 fonts */
if (! _cairo_font_face_is_user (sub_font->scaled_font->font_face)) {
status = _cairo_sub_font_map_glyph (sub_font, 0, NULL, -1, &tmp_subset_glyph);
- if (status)
+ if (unlikely (status))
return status;
}
}
@@ -477,7 +477,7 @@ _cairo_sub_font_map_glyph (cairo_sub_font_t *sub_font,
CAIRO_SCALED_GLYPH_INFO_METRICS,
&scaled_glyph);
assert (status != CAIRO_INT_STATUS_UNSUPPORTED);
- if (status) {
+ if (unlikely (status)) {
_cairo_scaled_font_thaw_cache (sub_font->scaled_font);
return status;
}
@@ -489,19 +489,19 @@ _cairo_sub_font_map_glyph (cairo_sub_font_t *sub_font,
scaled_glyph->metrics.y_advance);
_cairo_scaled_font_thaw_cache (sub_font->scaled_font);
- if (sub_font_glyph == NULL)
+ if (unlikely (sub_font_glyph == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
status = _cairo_sub_font_glyph_lookup_unicode (sub_font_glyph,
sub_font->scaled_font,
scaled_font_glyph_index);
- if (status) {
+ if (unlikely (status)) {
_cairo_sub_font_glyph_destroy (sub_font_glyph);
return status;
}
status = _cairo_hash_table_insert (sub_font->sub_font_glyphs, &sub_font_glyph->base);
- if (status) {
+ if (unlikely (status)) {
_cairo_sub_font_glyph_destroy (sub_font_glyph);
return status;
}
@@ -596,8 +596,8 @@ _cairo_scaled_font_subsets_create_internal (cairo_subsets_type_t type)
{
cairo_scaled_font_subsets_t *subsets;
- subsets = malloc (sizeof (cairo_scaled_font_subsets_t));
- if (subsets == NULL) {
+ subsets = malloc (sizeof (cairo_scaled_font_subsets_t));
+ if (unlikely (subsets == NULL)) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return NULL;
}
@@ -744,7 +744,7 @@ _cairo_scaled_font_subsets_map_glyph (cairo_scaled_font_subsets_t *subsets,
&identity,
&identity,
&font_options);
- if (unscaled_font->status)
+ if (unlikely (unscaled_font->status))
return unscaled_font->status;
subset_glyph->is_scaled = FALSE;
@@ -768,7 +768,7 @@ _cairo_scaled_font_subsets_map_glyph (cairo_scaled_font_subsets_t *subsets,
subset_glyph->is_composite,
&sub_font);
- if (status) {
+ if (unlikely (status)) {
cairo_scaled_font_destroy (unscaled_font);
return status;
}
@@ -776,7 +776,7 @@ _cairo_scaled_font_subsets_map_glyph (cairo_scaled_font_subsets_t *subsets,
status = _cairo_hash_table_insert (subsets->unscaled_sub_fonts,
&sub_font->base);
- if (status) {
+ if (unlikely (status)) {
_cairo_sub_font_destroy (sub_font);
return status;
}
@@ -808,14 +808,14 @@ _cairo_scaled_font_subsets_map_glyph (cairo_scaled_font_subsets_t *subsets,
subset_glyph->is_scaled,
subset_glyph->is_composite,
&sub_font);
- if (status) {
+ if (unlikely (status)) {
cairo_scaled_font_destroy (scaled_font);
return status;
}
status = _cairo_hash_table_insert (subsets->scaled_sub_fonts,
&sub_font->base);
- if (status) {
+ if (unlikely (status)) {
_cairo_sub_font_destroy (sub_font);
return status;
}
@@ -866,7 +866,7 @@ _cairo_scaled_font_subsets_foreach_internal (cairo_scaled_font_subsets_t
collection.glyphs = _cairo_malloc_ab (collection.glyphs_size, sizeof(unsigned long));
collection.utf8 = _cairo_malloc_ab (collection.glyphs_size, sizeof(char *));
- if (collection.glyphs == NULL || collection.utf8 == NULL) {
+ if (unlikely (collection.glyphs == NULL || collection.utf8 == NULL)) {
if (collection.glyphs != NULL)
free (collection.glyphs);
if (collection.utf8 != NULL)
@@ -957,7 +957,7 @@ static cairo_status_t
create_string_entry (char *s, cairo_string_entry_t **entry)
{
*entry = malloc (sizeof (cairo_string_entry_t));
- if (*entry == NULL)
+ if (unlikely (*entry == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
_cairo_string_init_key (*entry, s);
@@ -985,11 +985,11 @@ _cairo_scaled_font_subset_create_glyph_names (cairo_scaled_font_subset_t *subset
cairo_status_t status = CAIRO_STATUS_SUCCESS;
names = _cairo_hash_table_create (_cairo_string_equal);
- if (names == NULL)
+ if (unlikely (names == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
subset->glyph_names = calloc (subset->num_glyphs, sizeof (char *));
- if (subset->glyph_names == NULL) {
+ if (unlikely (subset->glyph_names == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto CLEANUP_HASH;
}
@@ -997,17 +997,17 @@ _cairo_scaled_font_subset_create_glyph_names (cairo_scaled_font_subset_t *subset
i = 0;
if (! _cairo_font_face_is_user (subset->scaled_font->font_face)) {
subset->glyph_names[0] = strdup (".notdef");
- if (subset->glyph_names[0] == NULL) {
+ if (unlikely (subset->glyph_names[0] == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto CLEANUP_HASH;
}
status = create_string_entry (subset->glyph_names[0], &entry);
- if (status)
+ if (unlikely (status))
goto CLEANUP_HASH;
status = _cairo_hash_table_insert (names, &entry->base);
- if (status) {
+ if (unlikely (status)) {
free (entry);
goto CLEANUP_HASH;
}
@@ -1020,7 +1020,7 @@ _cairo_scaled_font_subset_create_glyph_names (cairo_scaled_font_subset_t *subset
utf16_len = 0;
if (utf8 && *utf8) {
status = _cairo_utf8_to_utf16 (utf8, -1, &utf16, &utf16_len);
- if (status)
+ if (unlikely (status))
return status; /* FIXME */
}
@@ -1037,17 +1037,17 @@ _cairo_scaled_font_subset_create_glyph_names (cairo_scaled_font_subset_t *subset
free (utf16);
subset->glyph_names[i] = strdup (buf);
- if (subset->glyph_names[i] == NULL) {
+ if (unlikely (subset->glyph_names[i] == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto CLEANUP_HASH;
}
status = create_string_entry (subset->glyph_names[i], &entry);
- if (status)
+ if (unlikely (status))
goto CLEANUP_HASH;
status = _cairo_hash_table_insert (names, &entry->base);
- if (status) {
+ if (unlikely (status)) {
free (entry);
goto CLEANUP_HASH;
}
diff --git a/src/cairo-scaled-font.c b/src/cairo-scaled-font.c
index 8b749940..ca86f512 100644
--- a/src/cairo-scaled-font.c
+++ b/src/cairo-scaled-font.c
@@ -321,14 +321,14 @@ _cairo_scaled_font_map_lock (void)
if (cairo_scaled_font_map == NULL) {
cairo_scaled_font_map = malloc (sizeof (cairo_scaled_font_map_t));
- if (cairo_scaled_font_map == NULL)
+ if (unlikely (cairo_scaled_font_map == NULL))
goto CLEANUP_MUTEX_LOCK;
cairo_scaled_font_map->mru_scaled_font = NULL;
cairo_scaled_font_map->hash_table =
_cairo_hash_table_create (_cairo_scaled_font_keys_equal);
- if (cairo_scaled_font_map->hash_table == NULL)
+ if (unlikely (cairo_scaled_font_map->hash_table == NULL))
goto CLEANUP_SCALED_FONT_MAP;
cairo_scaled_font_map->num_holdovers = 0;
@@ -360,7 +360,7 @@ _cairo_scaled_font_map_destroy (void)
CAIRO_MUTEX_LOCK (_cairo_scaled_font_map_mutex);
font_map = cairo_scaled_font_map;
- if (font_map == NULL) {
+ if (unlikely (font_map == NULL)) {
goto CLEANUP_MUTEX_LOCK;
}
@@ -425,11 +425,11 @@ _cairo_scaled_font_register_placeholder_and_unlock_font_map (cairo_scaled_font_t
assert (CAIRO_MUTEX_IS_LOCKED (_cairo_scaled_font_map_mutex));
status = scaled_font->status;
- if (status)
+ if (unlikely (status))
return status;
placeholder_scaled_font = malloc (sizeof (cairo_scaled_font_t));
- if (placeholder_scaled_font == NULL)
+ if (unlikely (placeholder_scaled_font == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
/* full initialization is wasteful, but who cares... */
@@ -439,14 +439,14 @@ _cairo_scaled_font_register_placeholder_and_unlock_font_map (cairo_scaled_font_t
&scaled_font->ctm,
&scaled_font->options,
NULL);
- if (status)
+ if (unlikely (status))
goto FREE_PLACEHOLDER;
placeholder_scaled_font->placeholder = TRUE;
status = _cairo_hash_table_insert (cairo_scaled_font_map->hash_table,
&placeholder_scaled_font->hash_entry);
- if (status)
+ if (unlikely (status))
goto FINI_PLACEHOLDER;
CAIRO_MUTEX_UNLOCK (_cairo_scaled_font_map_mutex);
@@ -599,7 +599,7 @@ _cairo_scaled_font_init (cairo_scaled_font_t *scaled_font,
cairo_status_t status;
status = cairo_font_options_status ((cairo_font_options_t *) options);
- if (status)
+ if (unlikely (status))
return status;
_cairo_scaled_font_init_key (scaled_font, font_face,
@@ -613,7 +613,7 @@ _cairo_scaled_font_init (cairo_scaled_font_t *scaled_font,
fabs (scaled_font->scale.yx) + fabs (scaled_font->scale.yy));
scaled_font->scale_inverse = scaled_font->scale;
status = cairo_matrix_invert (&scaled_font->scale_inverse);
- if (status) {
+ if (unlikely (status)) {
/* If the font scale matrix is rank 0, just using an all-zero inverse matrix
* makes everything work correctly. This make font size 0 work without
* producing an error.
@@ -638,7 +638,7 @@ _cairo_scaled_font_init (cairo_scaled_font_t *scaled_font,
scaled_font->glyphs = _cairo_cache_create (_cairo_scaled_glyph_keys_equal,
_cairo_scaled_glyph_destroy,
MAX_GLYPHS_CACHED_PER_FONT);
- if (scaled_font->glyphs == NULL)
+ if (unlikely (scaled_font->glyphs == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
CAIRO_REFERENCE_COUNT_INIT (&scaled_font->ref_count, 1);
@@ -697,7 +697,7 @@ _cairo_scaled_font_set_metrics (cairo_scaled_font_t *scaled_font,
status = _cairo_matrix_compute_basis_scale_factors (&scaled_font->font_matrix,
&font_scale_x, &font_scale_y,
1);
- if (status)
+ if (unlikely (status))
return status;
/*
@@ -782,7 +782,7 @@ cairo_scaled_font_create (cairo_font_face_t *font_face,
return _cairo_scaled_font_create_in_error (font_face->status);
status = cairo_font_options_status ((cairo_font_options_t *) options);
- if (status)
+ if (unlikely (status))
return _cairo_scaled_font_create_in_error (status);
/* Note that degenerate ctm or font_matrix *are* allowed.
@@ -791,13 +791,13 @@ cairo_scaled_font_create (cairo_font_face_t *font_face,
if (font_face->backend->get_implementation != NULL) {
/* indirect implementation, lookup the face that is used for the key */
status = font_face->backend->get_implementation (font_face, &impl_face);
- if (status)
+ if (unlikely (status))
return _cairo_scaled_font_create_in_error (status);
} else
impl_face = font_face;
font_map = _cairo_scaled_font_map_lock ();
- if (font_map == NULL)
+ if (unlikely (font_map == NULL))
return _cairo_scaled_font_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
_cairo_scaled_font_init_key (&key, impl_face,
@@ -889,7 +889,7 @@ cairo_scaled_font_create (cairo_font_face_t *font_face,
/* Otherwise create it and insert it into the hash table. */
status = font_face->backend->scaled_font_create (font_face, font_matrix,
ctm, options, &scaled_font);
- if (status) {
+ if (unlikely (status)) {
_cairo_scaled_font_map_unlock ();
status = _cairo_font_face_set_error (font_face, status);
return _cairo_scaled_font_create_in_error (status);
@@ -905,7 +905,7 @@ cairo_scaled_font_create (cairo_font_face_t *font_face,
_cairo_scaled_font_map_unlock ();
- if (status) {
+ if (unlikely (status)) {
/* We can't call _cairo_scaled_font_destroy here since it expects
* that the font has already been successfully inserted into the
* hash table. */
@@ -935,9 +935,9 @@ _cairo_scaled_font_create_in_error (cairo_status_t status)
CAIRO_MUTEX_LOCK (_cairo_scaled_font_error_mutex);
scaled_font = _cairo_scaled_font_nil_objects[status];
- if (scaled_font == NULL) {
+ if (unlikely (scaled_font == NULL)) {
scaled_font = malloc (sizeof (cairo_scaled_font_t));
- if (scaled_font == NULL) {
+ if (unlikely (scaled_font == NULL)) {
CAIRO_MUTEX_UNLOCK (_cairo_scaled_font_error_mutex);
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return (cairo_scaled_font_t *) &_cairo_scaled_font_nil;
@@ -1221,7 +1221,7 @@ cairo_scaled_font_text_extents (cairo_scaled_font_t *scaled_font,
&glyphs, &num_glyphs,
NULL, NULL,
NULL);
- if (status) {
+ if (unlikely (status)) {
status = _cairo_scaled_font_set_error (scaled_font, status);
goto ZERO_EXTENTS;
}
@@ -1304,7 +1304,7 @@ cairo_scaled_font_glyph_extents (cairo_scaled_font_t *scaled_font,
glyphs[i].index,
CAIRO_SCALED_GLYPH_INFO_METRICS,
&scaled_glyph);
- if (status) {
+ if (unlikely (status)) {
status = _cairo_scaled_font_set_error (scaled_font, status);
goto UNLOCK;
}
@@ -1521,7 +1521,7 @@ cairo_scaled_font_text_to_glyphs (cairo_scaled_font_t *scaled_font,
cairo_text_cluster_t *orig_clusters;
status = scaled_font->status;
- if (status)
+ if (unlikely (status))
return status;
/* A slew of sanity checks */
@@ -1584,7 +1584,7 @@ cairo_scaled_font_text_to_glyphs (cairo_scaled_font_t *scaled_font,
/* validate input so backend does not have to */
status = _cairo_utf8_to_ucs4 (utf8, utf8_len, NULL, &num_chars);
- if (status)
+ if (unlikely (status))
goto BAIL;
_cairo_scaled_font_freeze_cache (scaled_font);
@@ -1642,7 +1642,7 @@ cairo_scaled_font_text_to_glyphs (cairo_scaled_font_t *scaled_font,
if (*num_glyphs < num_chars) {
*glyphs = cairo_glyph_allocate (num_chars);
- if (*glyphs == NULL) {
+ if (unlikely (*glyphs == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto DONE;
}
@@ -1652,7 +1652,7 @@ cairo_scaled_font_text_to_glyphs (cairo_scaled_font_t *scaled_font,
if (clusters) {
if (*num_clusters < num_chars) {
*clusters = cairo_text_cluster_allocate (num_chars);
- if (*clusters == NULL) {
+ if (unlikely (*clusters == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto DONE;
}
@@ -1682,7 +1682,7 @@ cairo_scaled_font_text_to_glyphs (cairo_scaled_font_t *scaled_font,
(*glyphs)[i].index,
CAIRO_SCALED_GLYPH_INFO_METRICS,
&scaled_glyph);
- if (status) {
+ if (unlikely (status)) {
goto DONE;
}
@@ -1693,7 +1693,7 @@ cairo_scaled_font_text_to_glyphs (cairo_scaled_font_t *scaled_font,
DONE: /* error that should be logged on scaled_font happened */
_cairo_scaled_font_thaw_cache (scaled_font);
- if (status) {
+ if (unlikely (status)) {
*num_glyphs = 0;
if (*glyphs != orig_glyphs) {
cairo_glyph_free (*glyphs);
@@ -1752,7 +1752,7 @@ _cairo_scaled_font_glyph_device_extents (cairo_scaled_font_t *scaled_font,
glyphs[i].index,
CAIRO_SCALED_GLYPH_INFO_METRICS,
&scaled_glyph);
- if (status)
+ if (unlikely (status))
break;
/* XXX glyph images are snapped to pixel locations */
@@ -1771,7 +1771,7 @@ _cairo_scaled_font_glyph_device_extents (cairo_scaled_font_t *scaled_font,
}
_cairo_scaled_font_thaw_cache (scaled_font);
- if (status)
+ if (unlikely (status))
return _cairo_scaled_font_set_error (scaled_font, status);
if (min.x < max.x && min.y < max.y) {
@@ -1853,7 +1853,7 @@ _cairo_scaled_font_show_glyphs (cairo_scaled_font_t *scaled_font,
CAIRO_SCALED_GLYPH_INFO_SURFACE,
&scaled_glyph);
- if (status)
+ if (unlikely (status))
goto CLEANUP_MASK;
glyph_surface = scaled_glyph->surface;
@@ -1864,10 +1864,9 @@ _cairo_scaled_font_show_glyphs (cairo_scaled_font_t *scaled_font,
mask_format = glyph_surface->format;
mask = cairo_image_surface_create (mask_format,
width, height);
- if (mask->status) {
- status = mask->status;
+ status = mask->status;
+ if (unlikely (status))
goto CLEANUP_MASK;
- }
}
/* If we have glyphs of different formats, we "upgrade" the mask
@@ -1912,7 +1911,7 @@ _cairo_scaled_font_show_glyphs (cairo_scaled_font_t *scaled_font,
_cairo_pattern_fini (&mask_pattern.base);
- if (status) {
+ if (unlikely (status)) {
cairo_surface_destroy (new_mask);
goto CLEANUP_MASK;
}
@@ -1940,7 +1939,7 @@ _cairo_scaled_font_show_glyphs (cairo_scaled_font_t *scaled_font,
_cairo_pattern_fini (&glyph_pattern.base);
- if (status)
+ if (unlikely (status))
goto CLEANUP_MASK;
}
@@ -2027,29 +2026,29 @@ _add_unit_rectangle_to_path (cairo_path_fixed_t *path, int x, int y)
status = _cairo_path_fixed_move_to (path,
_cairo_fixed_from_int (x),
_cairo_fixed_from_int (y));
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_path_fixed_rel_line_to (path,
_cairo_fixed_from_int (1),
_cairo_fixed_from_int (0));
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_path_fixed_rel_line_to (path,
_cairo_fixed_from_int (0),
_cairo_fixed_from_int (1));
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_path_fixed_rel_line_to (path,
_cairo_fixed_from_int (-1),
_cairo_fixed_from_int (0));
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_path_fixed_close_path (path);
- if (status)
+ if (unlikely (status))
return status;
return CAIRO_STATUS_SUCCESS;
@@ -2089,7 +2088,7 @@ _trace_mask_to_path (cairo_image_surface_t *mask,
a1_mask = _cairo_image_surface_clone (mask, CAIRO_FORMAT_A1);
status = cairo_surface_status (&a1_mask->base);
- if (status) {
+ if (unlikely (status)) {
cairo_surface_destroy (&a1_mask->base);
return status;
}
@@ -2104,7 +2103,7 @@ _trace_mask_to_path (cairo_image_surface_t *mask,
if (byte & (1 << bit)) {
status = _add_unit_rectangle_to_path (path,
x - xoff, y - yoff);
- if (status)
+ if (unlikely (status))
goto BAIL;
}
}
@@ -2129,7 +2128,7 @@ _cairo_scaled_font_glyph_path (cairo_scaled_font_t *scaled_font,
cairo_path_fixed_t *glyph_path;
status = scaled_font->status;
- if (status)
+ if (unlikely (status))
return status;
closure.path = path;
@@ -2153,17 +2152,17 @@ _cairo_scaled_font_glyph_path (cairo_scaled_font_t *scaled_font,
glyphs[i].index,
CAIRO_SCALED_GLYPH_INFO_SURFACE,
&scaled_glyph);
- if (status)
+ if (unlikely (status))
goto BAIL;
glyph_path = _cairo_path_fixed_create ();
- if (glyph_path == NULL) {
+ if (unlikely (glyph_path == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto BAIL;
}
status = _trace_mask_to_path (scaled_glyph->surface, glyph_path);
- if (status) {
+ if (unlikely (status)) {
_cairo_path_fixed_destroy (glyph_path);
goto BAIL;
}
@@ -2182,7 +2181,7 @@ _cairo_scaled_font_glyph_path (cairo_scaled_font_t *scaled_font,
if (glyph_path != scaled_glyph->path)
_cairo_path_fixed_destroy (glyph_path);
- if (status)
+ if (unlikely (status))
goto BAIL;
}
BAIL:
@@ -2361,7 +2360,7 @@ _cairo_scaled_glyph_lookup (cairo_scaled_font_t *scaled_font,
* On miss, create glyph and insert into cache
*/
scaled_glyph = malloc (sizeof (cairo_scaled_glyph_t));
- if (scaled_glyph == NULL) {
+ if (unlikely (scaled_glyph == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto CLEANUP;
}
@@ -2377,7 +2376,7 @@ _cairo_scaled_glyph_lookup (cairo_scaled_font_t *scaled_font,
/* ask backend to initialize metrics and shape fields */
status = (*scaled_font->backend->
scaled_glyph_init) (scaled_font, scaled_glyph, info);
- if (status) {
+ if (unlikely (status)) {
_cairo_scaled_glyph_destroy (scaled_glyph);
goto CLEANUP;
}
@@ -2385,7 +2384,7 @@ _cairo_scaled_glyph_lookup (cairo_scaled_font_t *scaled_font,
/* on success, the cache takes ownership of the scaled_glyph */
status = _cairo_cache_insert (scaled_font->glyphs,
&scaled_glyph->cache_entry);
- if (status) {
+ if (unlikely (status)) {
_cairo_scaled_glyph_destroy (scaled_glyph);
goto CLEANUP;
}
@@ -2410,7 +2409,7 @@ _cairo_scaled_glyph_lookup (cairo_scaled_font_t *scaled_font,
if (need_info) {
status = (*scaled_font->backend->
scaled_glyph_init) (scaled_font, scaled_glyph, need_info);
- if (status)
+ if (unlikely (status))
goto CLEANUP;
/* Don't trust the scaled_glyph_init() return value, the font
@@ -2438,7 +2437,7 @@ _cairo_scaled_glyph_lookup (cairo_scaled_font_t *scaled_font,
}
CLEANUP:
- if (status) {
+ if (unlikely (status)) {
/* It's not an error for the backend to not support the info we want. */
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
status = _cairo_scaled_font_set_error (scaled_font, status);
diff --git a/src/cairo-script-surface.c b/src/cairo-script-surface.c
index 9118d66d..cf2809f5 100644
--- a/src/cairo-script-surface.c
+++ b/src/cairo-script-surface.c
@@ -186,7 +186,7 @@ _bitmap_next_id (struct _bitmap *b,
} while (b != NULL);
bb = malloc (sizeof (struct _bitmap));
- if (bb == NULL)
+ if (unlikely (bb == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
*prev = bb;
@@ -335,7 +335,7 @@ _emit_context (cairo_script_surface_t *surface)
status = _bitmap_next_id (&surface->ctx->surface_id,
&surface->id);
- if (status)
+ if (unlikely (status))
return status;
_cairo_output_stream_printf (surface->ctx->stream,
@@ -586,25 +586,25 @@ _emit_stroke_style (cairo_script_surface_t *surface,
assert (_cairo_script_surface_owns_context (surface));
status = _emit_line_width (surface, style->line_width, force);
- if (status)
+ if (unlikely (status))
return status;
status = _emit_line_cap (surface, style->line_cap);
- if (status)
+ if (unlikely (status))
return status;
status = _emit_line_join (surface, style->line_join);
- if (status)
+ if (unlikely (status))
return status;
status = _emit_miter_limit (surface, style->miter_limit, force);
- if (status)
+ if (unlikely (status))
return status;
status = _emit_dash (surface,
style->dash, style->num_dashes, style->dash_offset,
force);
- if (status)
+ if (unlikely (status))
return status;
return CAIRO_STATUS_SUCCESS;
@@ -750,13 +750,13 @@ _emit_meta_surface_pattern (cairo_script_surface_t *surface,
cairo_surface_destroy (null_surface);
status = analysis_surface->status;
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_meta_surface_replay (source, analysis_surface);
_cairo_analysis_surface_get_bounding_box (analysis_surface, &bbox);
cairo_surface_destroy (analysis_surface);
- if (status)
+ if (unlikely (status))
return status;
similar = cairo_surface_create_similar (&surface->base,
@@ -767,13 +767,13 @@ _emit_meta_surface_pattern (cairo_script_surface_t *surface,
return similar->status;
status = _cairo_meta_surface_replay (source, similar);
- if (status) {
+ if (unlikely (status)) {
cairo_surface_destroy (similar);
return status;
}
status = _emit_context (surface);
- if (status) {
+ if (unlikely (status)) {
cairo_surface_destroy (similar);
return status;
}
@@ -852,7 +852,7 @@ _write_image_surface (cairo_output_stream_t *output,
#else
if (stride > ARRAY_LENGTH (row_stack)) {
rowdata = malloc (stride);
- if (rowdata == NULL)
+ if (unlikely (rowdata == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
} else
rowdata = row_stack;
@@ -936,7 +936,7 @@ _emit_png_surface (cairo_script_surface_t *surface,
base85_stream = _cairo_base85_stream_create (surface->ctx->stream);
_cairo_output_stream_write (base85_stream, mime_data, mime_data_length);
status = _cairo_output_stream_destroy (base85_stream);
- if (status)
+ if (unlikely (status))
return status;
_cairo_output_stream_puts (surface->ctx->stream,
@@ -979,7 +979,7 @@ _emit_image_surface (cairo_script_surface_t *surface,
status2 = _cairo_output_stream_destroy (base85_stream);
if (status == CAIRO_STATUS_SUCCESS)
status = status2;
- if (status)
+ if (unlikely (status))
return status;
_cairo_output_stream_puts (surface->ctx->stream,
@@ -1006,7 +1006,7 @@ _emit_image_surface (cairo_script_surface_t *surface,
base85_stream = _cairo_base85_stream_create (surface->ctx->stream);
_cairo_output_stream_write (base85_stream, mime_data, mime_data_length);
status = _cairo_output_stream_destroy (base85_stream);
- if (status)
+ if (unlikely (status))
return status;
_cairo_output_stream_puts (surface->ctx->stream,
@@ -1034,7 +1034,7 @@ _emit_image_surface_pattern (cairo_script_surface_t *surface,
/* XXX snapshot-cow */
status = _cairo_surface_acquire_source_image (source, &image, &image_extra);
- if (status)
+ if (unlikely (status))
return status;
status = _emit_image_surface (surface, image);
@@ -1089,7 +1089,7 @@ _emit_pattern (cairo_script_surface_t *surface,
ASSERT_NOT_REACHED;
status = CAIRO_INT_STATUS_UNSUPPORTED;
}
- if (status)
+ if (unlikely (status))
return status;
if (! _cairo_matrix_is_identity (&pattern->matrix)) {
@@ -1151,15 +1151,15 @@ _emit_source (cairo_script_surface_t *surface,
cairo_pattern_destroy (surface->cr.current_source);
status = _cairo_pattern_create_copy (&surface->cr.current_source,
source);
- if (status)
+ if (unlikely (status))
return status;
status = _emit_identity (surface, &matrix_updated);
- if (status)
+ if (unlikely (status))
return status;
status = _emit_pattern (surface, source);
- if (status)
+ if (unlikely (status))
return status;
_cairo_output_stream_puts (surface->ctx->stream,
@@ -1242,7 +1242,7 @@ _emit_path (cairo_script_surface_t *surface,
double y2 = _cairo_fixed_to_double (box.p2.y);
status = _cairo_path_fixed_init_copy (&surface->cr.current_path, path);
- if (status)
+ if (unlikely (status))
return status;
_cairo_output_stream_printf (surface->ctx->stream,
@@ -1252,7 +1252,7 @@ _emit_path (cairo_script_surface_t *surface,
cairo_status_t status;
status = _cairo_path_fixed_init_copy (&surface->cr.current_path, path);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_path_fixed_interpret (path,
@@ -1262,7 +1262,7 @@ _emit_path (cairo_script_surface_t *surface,
_path_curve_to,
_path_close,
surface->ctx->stream);
- if (status)
+ if (unlikely (status))
return status;
}
@@ -1356,7 +1356,7 @@ _cairo_script_surface_create_similar (void *abstract_surface,
status = _bitmap_next_id (&ctx->surface_id,
&other->id);
- if (status)
+ if (unlikely (status))
return _cairo_surface_create_in_error (status);
_cairo_output_stream_printf (ctx->stream,
@@ -1378,7 +1378,7 @@ _cairo_script_surface_create_similar (void *abstract_surface,
status = _bitmap_next_id (&ctx->surface_id,
&surface->id);
- if (status) {
+ if (unlikely (status)) {
cairo_surface_destroy (&surface->base);
return _cairo_surface_create_in_error (status);
}
@@ -1455,7 +1455,7 @@ _cairo_script_surface_copy_page (void *abstract_surface)
cairo_status_t status;
status = _emit_context (surface);
- if (status)
+ if (unlikely (status))
return status;
_cairo_output_stream_puts (surface->ctx->stream, "copy_page\n");
@@ -1470,7 +1470,7 @@ _cairo_script_surface_show_page (void *abstract_surface)
cairo_status_t status;
status = _emit_context (surface);
- if (status)
+ if (unlikely (status))
return status;
_cairo_output_stream_puts (surface->ctx->stream, "show_page\n");
@@ -1490,7 +1490,7 @@ _cairo_script_surface_intersect_clip_path (void *abstract_surface,
cairo_status_t status;
status = _emit_context (surface);
- if (status)
+ if (unlikely (status))
return status;
if (path == NULL) {
@@ -1499,23 +1499,23 @@ _cairo_script_surface_intersect_clip_path (void *abstract_surface,
}
status = _emit_identity (surface, &matrix_updated);
- if (status)
+ if (unlikely (status))
return status;
status = _emit_fill_rule (surface, fill_rule);
- if (status)
+ if (unlikely (status))
return status;
status = _emit_tolerance (surface, tolerance, matrix_updated);
- if (status)
+ if (unlikely (status))
return status;
status = _emit_antialias (surface, antialias);
- if (status)
+ if (unlikely (status))
return status;
status = _emit_path (surface, path);
- if (status)
+ if (unlikely (status))
return status;
_cairo_output_stream_puts (surface->ctx->stream, "clip+\n");
@@ -1533,15 +1533,15 @@ _cairo_script_surface_paint (void *abstract_surface,
cairo_status_t status;
status = _emit_context (surface);
- if (status)
+ if (unlikely (status))
return status;
status = _emit_operator (surface, op);
- if (status)
+ if (unlikely (status))
return status;
status = _emit_source (surface, op, source);
- if (status)
+ if (unlikely (status))
return status;
_cairo_output_stream_puts (surface->ctx->stream,
@@ -1561,19 +1561,19 @@ _cairo_script_surface_mask (void *abstract_surface,
cairo_status_t status;
status = _emit_context (surface);
- if (status)
+ if (unlikely (status))
return status;
status = _emit_operator (surface, op);
- if (status)
+ if (unlikely (status))
return status;
status = _emit_source (surface, op, source);
- if (status)
+ if (unlikely (status))
return status;
status = _emit_pattern (surface, mask);
- if (status)
+ if (unlikely (status))
return status;
_cairo_output_stream_puts (surface->ctx->stream,
@@ -1599,39 +1599,39 @@ _cairo_script_surface_stroke (void *abstract_surface,
cairo_status_t status;
status = _emit_context (surface);
- if (status)
+ if (unlikely (status))
return status;
status = _emit_identity (surface, &matrix_updated);
- if (status)
+ if (unlikely (status))
return status;
status = _emit_path (surface, path);
- if (status)
+ if (unlikely (status))
return status;
status = _emit_source (surface, op, source);
- if (status)
+ if (unlikely (status))
return status;
status = _emit_matrix (surface, ctm, &matrix_updated);
- if (status)
+ if (unlikely (status))
return status;
status = _emit_operator (surface, op);
- if (status)
+ if (unlikely (status))
return status;
status = _emit_stroke_style (surface, style, matrix_updated);
- if (status)
+ if (unlikely (status))
return status;
status = _emit_tolerance (surface, tolerance, matrix_updated);
- if (status)
+ if (unlikely (status))
return status;
status = _emit_antialias (surface, antialias);
- if (status)
+ if (unlikely (status))
return status;
_cairo_output_stream_puts (surface->ctx->stream, "stroke+\n");
@@ -1654,35 +1654,35 @@ _cairo_script_surface_fill (void *abstract_surface,
cairo_status_t status;
status = _emit_context (surface);
- if (status)
+ if (unlikely (status))
return status;
status = _emit_operator (surface, op);
- if (status)
+ if (unlikely (status))
return status;
status = _emit_identity (surface, &matrix_updated);
- if (status)
+ if (unlikely (status))
return status;
status = _emit_source (surface, op, source);
- if (status)
+ if (unlikely (status))
return status;
status = _emit_fill_rule (surface, fill_rule);
- if (status)
+ if (unlikely (status))
return status;
status = _emit_tolerance (surface, tolerance, matrix_updated);
- if (status)
+ if (unlikely (status))
return status;
status = _emit_antialias (surface, antialias);
- if (status)
+ if (unlikely (status))
return status;
status = _emit_path (surface, path);
- if (status)
+ if (unlikely (status))
return status;
_cairo_output_stream_puts (surface->ctx->stream, "fill+\n");
@@ -1828,15 +1828,15 @@ _emit_type42_font (cairo_script_surface_t *surface,
size = 0;
status = backend->load_truetype_table (scaled_font, 0, 0, NULL, &size);
- if (status)
+ if (unlikely (status))
return status;
buf = malloc (size);
- if (buf == NULL)
+ if (unlikely (buf == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
status = backend->load_truetype_table (scaled_font, 0, 0, buf, NULL);
- if (status) {
+ if (unlikely (status)) {
free (buf);
return status;
}
@@ -1882,7 +1882,7 @@ _emit_scaled_font_init (cairo_script_surface_t *surface,
cairo_status_t status;
font_private = malloc (sizeof (cairo_script_surface_font_private_t));
- if (font_private == NULL)
+ if (unlikely (font_private == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
font_private->ctx = surface->ctx;
@@ -1898,7 +1898,7 @@ _emit_scaled_font_init (cairo_script_surface_t *surface,
status = _bitmap_next_id (&surface->ctx->font_id,
&font_private->id);
- if (status) {
+ if (unlikely (status)) {
free (font_private);
return status;
}
@@ -1907,7 +1907,7 @@ _emit_scaled_font_init (cairo_script_surface_t *surface,
scaled_font->surface_backend = &_cairo_script_surface_backend;
status = _emit_context (surface);
- if (status)
+ if (unlikely (status))
return status;
status = _emit_type42_font (surface, scaled_font);
@@ -1943,7 +1943,7 @@ _emit_scaled_font (cairo_script_surface_t *surface,
cairo_scaled_font_get_ctm (scaled_font, &matrix);
status = _emit_matrix (surface, &matrix, &matrix_updated);
- if (status)
+ if (unlikely (status))
return status;
if (! matrix_updated && surface->cr.current_scaled_font == scaled_font)
@@ -1951,12 +1951,12 @@ _emit_scaled_font (cairo_script_surface_t *surface,
cairo_scaled_font_get_font_matrix (scaled_font, &matrix);
status = _emit_font_matrix (surface, &matrix);
- if (status)
+ if (unlikely (status))
return status;
cairo_scaled_font_get_font_options (scaled_font, &options);
status = _emit_font_options (surface, &options);
- if (status)
+ if (unlikely (status))
return status;
surface->cr.current_scaled_font = scaled_font;
@@ -1967,11 +1967,11 @@ _emit_scaled_font (cairo_script_surface_t *surface,
font_private = scaled_font->surface_private;
if (font_private == NULL) {
status = _emit_scaled_font_init (surface, scaled_font);
- if (status)
+ if (unlikely (status))
return status;
} else {
status = _emit_context (surface);
- if (status)
+ if (unlikely (status))
return status;
_cairo_output_stream_printf (surface->ctx->stream,
@@ -2059,7 +2059,7 @@ _emit_scaled_glyph_bitmap (cairo_script_surface_t *surface,
scaled_glyph->fs_metrics.y_bearing);
status = _emit_image_surface (surface, scaled_glyph->surface);
- if (status)
+ if (unlikely (status))
return status;
if (! _cairo_matrix_is_identity (&scaled_font->font_matrix)) {
@@ -2121,7 +2121,7 @@ _emit_scaled_glyphs (cairo_script_surface_t *surface,
glyphs[n].index,
CAIRO_SCALED_GLYPH_INFO_METRICS,
&scaled_glyph);
- if (status)
+ if (unlikely (status))
break;
if (scaled_glyph->surface_private != NULL)
@@ -2137,7 +2137,7 @@ _emit_scaled_glyphs (cairo_script_surface_t *surface,
if (status == CAIRO_STATUS_SUCCESS) {
if (! have_glyph_prologue) {
status = _emit_scaled_glyph_prologue (surface, scaled_font);
- if (status)
+ if (unlikely (status))
break;
have_glyph_prologue = TRUE;
@@ -2146,7 +2146,7 @@ _emit_scaled_glyphs (cairo_script_surface_t *surface,
status = _emit_scaled_glyph_vector (surface,
scaled_font,
scaled_glyph);
- if (status)
+ if (unlikely (status))
break;
continue;
@@ -2162,7 +2162,7 @@ _emit_scaled_glyphs (cairo_script_surface_t *surface,
if (status == CAIRO_STATUS_SUCCESS) {
if (! have_glyph_prologue) {
status = _emit_scaled_glyph_prologue (surface, scaled_font);
- if (status)
+ if (unlikely (status))
break;
have_glyph_prologue = TRUE;
@@ -2171,7 +2171,7 @@ _emit_scaled_glyphs (cairo_script_surface_t *surface,
status = _emit_scaled_glyph_bitmap (surface,
scaled_font,
scaled_glyph);
- if (status)
+ if (unlikely (status))
break;
continue;
@@ -2210,23 +2210,23 @@ _cairo_script_surface_show_text_glyphs (void *abstract_surface,
cairo_output_stream_t *base85_stream = NULL;
status = _emit_context (surface);
- if (status)
+ if (unlikely (status))
return status;
status = _emit_operator (surface, op);
- if (status)
+ if (unlikely (status))
return status;
status = _emit_source (surface, op, source);
- if (status)
+ if (unlikely (status))
return status;
status = _emit_scaled_font (surface, scaled_font);
- if (status)
+ if (unlikely (status))
return status;
status = _emit_scaled_glyphs (surface, scaled_font, glyphs, num_glyphs);
- if (status)
+ if (unlikely (status))
return status;
/* (utf8) [cx cy [glyphs]] [clusters] backward show_text_glyphs */
@@ -2264,7 +2264,7 @@ _cairo_script_surface_show_text_glyphs (void *abstract_surface,
glyphs[n].index,
CAIRO_SCALED_GLYPH_INFO_METRICS,
&scaled_glyph);
- if (status) {
+ if (unlikely (status)) {
_cairo_scaled_font_thaw_cache (scaled_font);
return status;
}
@@ -2284,7 +2284,7 @@ _cairo_script_surface_show_text_glyphs (void *abstract_surface,
glyphs[n].index,
CAIRO_SCALED_GLYPH_INFO_METRICS,
&scaled_glyph);
- if (status)
+ if (unlikely (status))
break;
if (fabs (glyphs[n].x - x) > 1e-5 || fabs (glyphs[n].y - y) > 1e-5) {
@@ -2295,7 +2295,7 @@ _cairo_script_surface_show_text_glyphs (void *abstract_surface,
iy -= scaled_font->font_matrix.y0;
if (base85_stream != NULL) {
status = _cairo_output_stream_destroy (base85_stream);
- if (status) {
+ if (unlikely (status)) {
base85_stream = NULL;
break;
}
@@ -2345,7 +2345,7 @@ _cairo_script_surface_show_text_glyphs (void *abstract_surface,
} else {
_cairo_output_stream_puts (surface->ctx->stream, " ]");
}
- if (status)
+ if (unlikely (status))
return status;
if (utf8 != NULL && clusters != NULL) {
@@ -2378,7 +2378,7 @@ _cairo_script_surface_show_text_glyphs (void *abstract_surface,
_cairo_output_stream_write (base85_stream, c, 2);
}
status = _cairo_output_stream_destroy (base85_stream);
- if (status)
+ if (unlikely (status))
return status;
}
@@ -2423,6 +2423,8 @@ _cairo_script_surface_backend = {
NULL, /* composite */
NULL, /* fill_rectangles */
NULL, /* composite_trapezoids */
+ NULL, /* create_span_renderer */
+ NULL, /* check_span_renderer */
_cairo_script_surface_copy_page,
_cairo_script_surface_show_page,
NULL, /* set_clip_region */
@@ -2466,7 +2468,7 @@ _cairo_script_vmcontext_create (cairo_output_stream_t *stream)
cairo_script_vmcontext_t *ctx;
ctx = malloc (sizeof (cairo_script_vmcontext_t));
- if (ctx == NULL)
+ if (unlikely (ctx == NULL))
return NULL;
memset (ctx, 0, sizeof (cairo_script_vmcontext_t));
@@ -2500,11 +2502,11 @@ _cairo_script_surface_create_internal (cairo_script_vmcontext_t *ctx,
{
cairo_script_surface_t *surface;
- if (ctx == NULL)
+ if (unlikely (ctx == NULL))
return (cairo_script_surface_t *) _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
surface = malloc (sizeof (cairo_script_surface_t));
- if (surface == NULL)
+ if (unlikely (surface == NULL))
return (cairo_script_surface_t *) _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
_cairo_surface_init (&surface->base,
diff --git a/src/cairo-sdl-surface.c b/src/cairo-sdl-surface.c
index 18f13eaf..1f97fb47 100644
--- a/src/cairo-sdl-surface.c
+++ b/src/cairo-sdl-surface.c
@@ -52,7 +52,7 @@ _cairo_sdl_surface_create_internal (SDL_Surface *sdl,
cairo_sdl_surface_t *surface;
surface = malloc (sizeof (cairo_sdl_surface_t));
- if (surface == NULL)
+ if (unlikely (surface == NULL))
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
_cairo_surface_init (&surface->base,
@@ -240,7 +240,7 @@ _cairo_sdl_surface_composite (cairo_operator_t op,
src_x, src_y, width, height,
(cairo_surface_t **) &src,
&src_attr);
- if (status)
+ if (unlikely (status))
return status;
is_integer_translation =
@@ -324,7 +324,7 @@ _cairo_sdl_surface_flush (void *abstract_surface)
n_boxes = 0;
status = _cairo_region_get_boxes (&surface->update, &n_boxes, &boxes);
- if (status)
+ if (unlikely (status))
return status;
if (n_boxes == 0)
return CAIRO_STATUS_SUCCESS;
@@ -357,6 +357,8 @@ static const cairo_surface_backend_t _cairo_sdl_surface_backend = {
_cairo_sdl_surface_composite,
NULL, /* fill rectangles */
NULL, /* composite traps */
+ NULL, /* create_span_renderer */
+ NULL, /* check_span_renderer */
NULL, /* copy_page */
NULL, /* show_page */
_cairo_sdl_surface_set_clip_region,
diff --git a/src/cairo-skiplist.c b/src/cairo-skiplist.c
index b08453b0..d03a6bfc 100644
--- a/src/cairo-skiplist.c
+++ b/src/cairo-skiplist.c
@@ -91,20 +91,22 @@ _cairo_skip_list_fini (cairo_skip_list_t *list)
static int
random_level (void)
{
- int level = 0;
/* tricky bit -- each bit is '1' 75% of the time.
* This works because we only use the lower MAX_LEVEL
* bits, and MAX_LEVEL < 16 */
uint32_t bits = hars_petruska_f54_1_random ();
- bits |= bits >> 16;
-
- while (++level < MAX_LEVEL)
- {
- if (bits & 1)
- break;
+#if HAVE_FFS
+ return ffs (-(1<<MAX_LEVEL) | bits | bits >> 16);
+#else
+ int level = 1;
+
+ bits |= -(1<<MAX_LEVEL) | bits >> 16;
+ while ((bits & 1) == 0) {
+ level++;
bits >>= 1;
}
return level;
+#endif
}
static void *
@@ -181,7 +183,7 @@ _cairo_skip_list_insert (cairo_skip_list_t *list, void *data, int unique)
}
data_and_elt = alloc_node_for_level (list, level);
- if (data_and_elt == NULL) {
+ if (unlikely (data_and_elt == NULL)) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return NULL;
}
diff --git a/src/cairo-spans-private.h b/src/cairo-spans-private.h
new file mode 100644
index 00000000..c285f949
--- /dev/null
+++ b/src/cairo-spans-private.h
@@ -0,0 +1,144 @@
+/* -*- 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.
+ */
+#ifndef CAIRO_SPANS_PRIVATE_H
+#define CAIRO_SPANS_PRIVATE_H
+#include "cairo-types-private.h"
+#include "cairo-compiler-private.h"
+
+/* Number of bits of precision used for alpha. */
+#define CAIRO_SPANS_UNIT_COVERAGE_BITS 8
+#define CAIRO_SPANS_UNIT_COVERAGE ((1 << CAIRO_SPANS_UNIT_COVERAGE_BITS)-1)
+
+/* A structure representing an open-ended horizontal span of constant
+ * pixel coverage. */
+typedef struct _cairo_half_open_span {
+ /* The inclusive x-coordinate of the start of the span. */
+ int x;
+
+ /* The pixel coverage for the pixels to the right. */
+ int coverage;
+} cairo_half_open_span_t;
+
+/* Span renderer interface. Instances of renderers are provided by
+ * surfaces if they want to composite spans instead of trapezoids. */
+typedef struct _cairo_span_renderer cairo_span_renderer_t;
+struct _cairo_span_renderer {
+ /* Called to destroy the renderer. */
+ cairo_destroy_func_t destroy;
+
+ /* Render the spans on row y of the source by whatever compositing
+ * method is required. The function should ignore spans outside
+ * the bounding box set by the init() function. */
+ cairo_status_t (*render_row)(
+ void *abstract_renderer,
+ int y,
+ const cairo_half_open_span_t *coverages,
+ unsigned num_coverages);
+
+ /* Called after all rows have been rendered to perform whatever
+ * final rendering step is required. This function is called just
+ * once before the renderer is destroyed. */
+ cairo_status_t (*finish)(
+ void *abstract_renderer);
+
+ /* Private status variable. */
+ cairo_status_t status;
+};
+
+/* Scan converter interface. */
+typedef struct _cairo_scan_converter cairo_scan_converter_t;
+struct _cairo_scan_converter {
+ /* Destroy this scan converter. */
+ cairo_destroy_func_t destroy;
+
+ /* Add an edge to the converter. */
+ cairo_status_t
+ (*add_edge)(
+ void *abstract_converter,
+ cairo_fixed_t x1,
+ cairo_fixed_t y1,
+ cairo_fixed_t x2,
+ cairo_fixed_t y2);
+
+ /* Generates coverage spans for rows for the added edges and calls
+ * the renderer function for each row. After generating spans the
+ * only valid thing to do with the converter is to destroy it. */
+ cairo_status_t
+ (*generate)(
+ void *abstract_converter,
+ cairo_span_renderer_t *renderer);
+
+ /* Private status. Read with _cairo_scan_converter_status(). */
+ cairo_status_t status;
+};
+
+/* Scan converter constructors. */
+
+cairo_private cairo_scan_converter_t *
+_cairo_tor_scan_converter_create(
+ int xmin,
+ int ymin,
+ int xmax,
+ int ymax,
+ cairo_fill_rule_t fill_rule);
+
+/* cairo-spans.c: */
+
+cairo_private cairo_scan_converter_t *
+_cairo_scan_converter_create_in_error (cairo_status_t error);
+
+cairo_private cairo_status_t
+_cairo_scan_converter_status (void *abstract_converter);
+
+cairo_private cairo_status_t
+_cairo_scan_converter_set_error (void *abstract_converter,
+ cairo_status_t error);
+
+cairo_private cairo_span_renderer_t *
+_cairo_span_renderer_create_in_error (cairo_status_t error);
+
+cairo_private cairo_status_t
+_cairo_span_renderer_status (void *abstract_renderer);
+
+/* Set the renderer into an error state. This sets all the method
+ * pointers except ->destroy() of the renderer to no-op
+ * implementations that just return the error status. */
+cairo_private cairo_status_t
+_cairo_span_renderer_set_error (void *abstract_renderer,
+ cairo_status_t error);
+
+cairo_private cairo_status_t
+_cairo_path_fixed_fill_using_spans (
+ cairo_operator_t op,
+ const cairo_pattern_t *pattern,
+ cairo_path_fixed_t *path,
+ cairo_surface_t *dst,
+ cairo_fill_rule_t fill_rule,
+ double tolerance,
+ cairo_antialias_t antialias,
+ const cairo_composite_rectangles_t *rects);
+#endif /* CAIRO_SPANS_PRIVATE_H */
diff --git a/src/cairo-spans.c b/src/cairo-spans.c
new file mode 100644
index 00000000..e441143b
--- /dev/null
+++ b/src/cairo-spans.c
@@ -0,0 +1,395 @@
+/* -*- 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 "cairoint.h"
+
+typedef struct {
+ cairo_scan_converter_t *converter;
+ cairo_point_t current_point;
+ cairo_point_t first_point;
+} scan_converter_filler_t;
+
+static void
+scan_converter_filler_init (
+ scan_converter_filler_t *filler,
+ cairo_scan_converter_t *converter)
+{
+ filler->converter = converter;
+ filler->current_point.x = 0;
+ filler->current_point.y = 0;
+ filler->first_point = filler->current_point;
+}
+
+static cairo_status_t
+scan_converter_filler_move_to (
+ void *closure,
+ cairo_point_t *p)
+{
+ scan_converter_filler_t *filler = closure;
+ filler->current_point.x = p->x;
+ filler->current_point.y = p->y;
+ filler->first_point = filler->current_point;
+ return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_status_t
+scan_converter_filler_line_to (
+ void *closure,
+ cairo_point_t *p)
+{
+ scan_converter_filler_t *filler = closure;
+ cairo_status_t status;
+ cairo_point_t to;
+
+ to.x = p->x;
+ to.y = p->y;
+
+ status = filler->converter->add_edge (
+ filler->converter,
+ filler->current_point.x, filler->current_point.y,
+ to.x, to.y);
+
+ filler->current_point = to;
+
+ return status;
+}
+
+static cairo_status_t
+scan_converter_filler_close_path (
+ void *closure)
+{
+ scan_converter_filler_t *filler = closure;
+ cairo_status_t status;
+
+ if (filler->first_point.x == filler->current_point.x &&
+ filler->first_point.y == filler->current_point.y)
+ {
+ return CAIRO_STATUS_SUCCESS;
+ }
+
+ status = filler->converter->add_edge (
+ filler->converter,
+ filler->current_point.x, filler->current_point.y,
+ filler->first_point.x, filler->first_point.y);
+
+ filler->current_point = filler->first_point;
+
+ return status;
+}
+
+static cairo_status_t
+_cairo_path_fixed_fill_to_scan_converter (
+ cairo_path_fixed_t *path,
+ double tolerance,
+ cairo_scan_converter_t *converter)
+{
+ scan_converter_filler_t filler;
+ cairo_status_t status;
+
+ scan_converter_filler_init (&filler, converter);
+
+ status = _cairo_path_fixed_interpret_flat (
+ path, CAIRO_DIRECTION_FORWARD,
+ scan_converter_filler_move_to,
+ scan_converter_filler_line_to,
+ scan_converter_filler_close_path,
+ &filler, tolerance);
+ if (status)
+ return status;
+
+ return scan_converter_filler_close_path (&filler);
+}
+
+static cairo_scan_converter_t *
+_create_scan_converter (cairo_fill_rule_t fill_rule,
+ cairo_antialias_t antialias,
+ const cairo_composite_rectangles_t *rects)
+{
+ if (antialias == CAIRO_ANTIALIAS_NONE) {
+ ASSERT_NOT_REACHED;
+ return _cairo_scan_converter_create_in_error (
+ CAIRO_INT_STATUS_UNSUPPORTED);
+ }
+ else {
+ return _cairo_tor_scan_converter_create (
+ rects->mask.x,
+ rects->mask.y,
+ rects->mask.x + rects->width,
+ rects->mask.y + rects->height,
+ fill_rule);
+ }
+}
+
+cairo_status_t
+_cairo_path_fixed_fill_using_spans (
+ cairo_operator_t op,
+ const cairo_pattern_t *pattern,
+ cairo_path_fixed_t *path,
+ cairo_surface_t *dst,
+ cairo_fill_rule_t fill_rule,
+ double tolerance,
+ cairo_antialias_t antialias,
+ const cairo_composite_rectangles_t *rects)
+{
+ cairo_status_t status;
+ cairo_span_renderer_t *renderer = _cairo_surface_create_span_renderer (
+ op, pattern, dst, antialias, rects);
+ cairo_scan_converter_t *converter = _create_scan_converter (
+ fill_rule, antialias, rects);
+
+ status = _cairo_path_fixed_fill_to_scan_converter (
+ path, tolerance, converter);
+ if (status)
+ goto BAIL;
+
+ status = converter->generate (converter, renderer);
+ if (status)
+ goto BAIL;
+
+ status = renderer->finish (renderer);
+ if (status)
+ goto BAIL;
+
+ BAIL:
+ renderer->destroy (renderer);
+ converter->destroy (converter);
+ return status;
+}
+
+static void
+_cairo_nil_destroy (void *abstract)
+{
+ (void) abstract;
+}
+
+static cairo_status_t
+_cairo_nil_scan_converter_add_edge (void *abstract_converter,
+ cairo_fixed_t x1,
+ cairo_fixed_t y1,
+ cairo_fixed_t x2,
+ cairo_fixed_t y2)
+{
+ (void) abstract_converter;
+ (void) x1;
+ (void) y1;
+ (void) x2;
+ (void) y2;
+ return _cairo_scan_converter_status (abstract_converter);
+}
+
+static cairo_status_t
+_cairo_nil_scan_converter_generate (void *abstract_converter,
+ cairo_span_renderer_t *renderer)
+{
+ (void) abstract_converter;
+ (void) renderer;
+ return _cairo_scan_converter_status (abstract_converter);
+}
+
+cairo_status_t
+_cairo_scan_converter_status (void *abstract_converter)
+{
+ cairo_scan_converter_t *converter = abstract_converter;
+ return converter->status;
+}
+
+cairo_status_t
+_cairo_scan_converter_set_error (void *abstract_converter,
+ cairo_status_t error)
+{
+ cairo_scan_converter_t *converter = abstract_converter;
+ if (error == CAIRO_STATUS_SUCCESS)
+ ASSERT_NOT_REACHED;
+ if (converter->status == CAIRO_STATUS_SUCCESS) {
+ converter->add_edge = _cairo_nil_scan_converter_add_edge;
+ converter->generate = _cairo_nil_scan_converter_generate;
+ converter->status = error;
+ }
+ return converter->status;
+}
+
+static void
+_cairo_nil_scan_converter_init (cairo_scan_converter_t *converter,
+ cairo_status_t status)
+{
+ converter->destroy = _cairo_nil_destroy;
+ converter->status = CAIRO_STATUS_SUCCESS;
+ status = _cairo_scan_converter_set_error (converter, status);
+}
+
+cairo_scan_converter_t *
+_cairo_scan_converter_create_in_error (cairo_status_t status)
+{
+#define RETURN_NIL {\
+ static cairo_scan_converter_t nil;\
+ _cairo_nil_scan_converter_init (&nil, status);\
+ return &nil;\
+ }
+ switch (status) {
+ case CAIRO_STATUS_SUCCESS:
+ ASSERT_NOT_REACHED;
+ break;
+ case CAIRO_STATUS_INVALID_RESTORE: RETURN_NIL;
+ case CAIRO_STATUS_INVALID_POP_GROUP: RETURN_NIL;
+ case CAIRO_STATUS_NO_CURRENT_POINT: RETURN_NIL;
+ case CAIRO_STATUS_INVALID_MATRIX: RETURN_NIL;
+ case CAIRO_STATUS_INVALID_STATUS: RETURN_NIL;
+ case CAIRO_STATUS_NULL_POINTER: RETURN_NIL;
+ case CAIRO_STATUS_INVALID_STRING: RETURN_NIL;
+ case CAIRO_STATUS_INVALID_PATH_DATA: RETURN_NIL;
+ case CAIRO_STATUS_READ_ERROR: RETURN_NIL;
+ case CAIRO_STATUS_WRITE_ERROR: RETURN_NIL;
+ case CAIRO_STATUS_SURFACE_FINISHED: RETURN_NIL;
+ case CAIRO_STATUS_SURFACE_TYPE_MISMATCH: RETURN_NIL;
+ case CAIRO_STATUS_PATTERN_TYPE_MISMATCH: RETURN_NIL;
+ case CAIRO_STATUS_INVALID_CONTENT: RETURN_NIL;
+ case CAIRO_STATUS_INVALID_FORMAT: RETURN_NIL;
+ case CAIRO_STATUS_INVALID_VISUAL: RETURN_NIL;
+ case CAIRO_STATUS_FILE_NOT_FOUND: RETURN_NIL;
+ case CAIRO_STATUS_INVALID_DASH: RETURN_NIL;
+ case CAIRO_STATUS_INVALID_DSC_COMMENT: RETURN_NIL;
+ case CAIRO_STATUS_INVALID_INDEX: RETURN_NIL;
+ case CAIRO_STATUS_CLIP_NOT_REPRESENTABLE: RETURN_NIL;
+ case CAIRO_STATUS_TEMP_FILE_ERROR: RETURN_NIL;
+ case CAIRO_STATUS_INVALID_STRIDE: RETURN_NIL;
+ case CAIRO_STATUS_FONT_TYPE_MISMATCH: RETURN_NIL;
+ case CAIRO_STATUS_USER_FONT_IMMUTABLE: RETURN_NIL;
+ case CAIRO_STATUS_USER_FONT_ERROR: RETURN_NIL;
+ case CAIRO_STATUS_NEGATIVE_COUNT: RETURN_NIL;
+ case CAIRO_STATUS_INVALID_CLUSTERS: RETURN_NIL;
+ case CAIRO_STATUS_INVALID_SLANT: RETURN_NIL;
+ case CAIRO_STATUS_INVALID_WEIGHT: RETURN_NIL;
+ case CAIRO_STATUS_NO_MEMORY: RETURN_NIL;
+ default:
+ break;
+ }
+ status = CAIRO_STATUS_NO_MEMORY;
+ RETURN_NIL;
+#undef RETURN_NIL
+}
+
+static cairo_status_t
+_cairo_nil_span_renderer_render_row (
+ void *abstract_renderer,
+ int y,
+ const cairo_half_open_span_t *coverages,
+ unsigned num_coverages)
+{
+ (void) y;
+ (void) coverages;
+ (void) num_coverages;
+ return _cairo_span_renderer_status (abstract_renderer);
+}
+
+static cairo_status_t
+_cairo_nil_span_renderer_finish (void *abstract_renderer)
+{
+ return _cairo_span_renderer_status (abstract_renderer);
+}
+
+cairo_status_t
+_cairo_span_renderer_status (void *abstract_renderer)
+{
+ cairo_span_renderer_t *renderer = abstract_renderer;
+ return renderer->status;
+}
+
+cairo_status_t
+_cairo_span_renderer_set_error (
+ void *abstract_renderer,
+ cairo_status_t error)
+{
+ cairo_span_renderer_t *renderer = abstract_renderer;
+ if (error == CAIRO_STATUS_SUCCESS) {
+ ASSERT_NOT_REACHED;
+ }
+ if (renderer->status == CAIRO_STATUS_SUCCESS) {
+ renderer->render_row = _cairo_nil_span_renderer_render_row;
+ renderer->finish = _cairo_nil_span_renderer_finish;
+ renderer->status = error;
+ }
+ return renderer->status;
+}
+
+static void
+_cairo_nil_span_renderer_init (cairo_span_renderer_t *renderer,
+ cairo_status_t status)
+{
+ renderer->destroy = _cairo_nil_destroy;
+ renderer->status = CAIRO_STATUS_SUCCESS;
+ status = _cairo_span_renderer_set_error (renderer, status);
+}
+
+cairo_span_renderer_t *
+_cairo_span_renderer_create_in_error (cairo_status_t status)
+{
+#define RETURN_NIL {\
+ static cairo_span_renderer_t nil;\
+ _cairo_nil_span_renderer_init (&nil, status);\
+ return &nil;\
+ }
+ switch (status) {
+ case CAIRO_STATUS_SUCCESS:
+ ASSERT_NOT_REACHED;
+ break;
+ case CAIRO_STATUS_INVALID_RESTORE: RETURN_NIL;
+ case CAIRO_STATUS_INVALID_POP_GROUP: RETURN_NIL;
+ case CAIRO_STATUS_NO_CURRENT_POINT: RETURN_NIL;
+ case CAIRO_STATUS_INVALID_MATRIX: RETURN_NIL;
+ case CAIRO_STATUS_INVALID_STATUS: RETURN_NIL;
+ case CAIRO_STATUS_NULL_POINTER: RETURN_NIL;
+ case CAIRO_STATUS_INVALID_STRING: RETURN_NIL;
+ case CAIRO_STATUS_INVALID_PATH_DATA: RETURN_NIL;
+ case CAIRO_STATUS_READ_ERROR: RETURN_NIL;
+ case CAIRO_STATUS_WRITE_ERROR: RETURN_NIL;
+ case CAIRO_STATUS_SURFACE_FINISHED: RETURN_NIL;
+ case CAIRO_STATUS_SURFACE_TYPE_MISMATCH: RETURN_NIL;
+ case CAIRO_STATUS_PATTERN_TYPE_MISMATCH: RETURN_NIL;
+ case CAIRO_STATUS_INVALID_CONTENT: RETURN_NIL;
+ case CAIRO_STATUS_INVALID_FORMAT: RETURN_NIL;
+ case CAIRO_STATUS_INVALID_VISUAL: RETURN_NIL;
+ case CAIRO_STATUS_FILE_NOT_FOUND: RETURN_NIL;
+ case CAIRO_STATUS_INVALID_DASH: RETURN_NIL;
+ case CAIRO_STATUS_INVALID_DSC_COMMENT: RETURN_NIL;
+ case CAIRO_STATUS_INVALID_INDEX: RETURN_NIL;
+ case CAIRO_STATUS_CLIP_NOT_REPRESENTABLE: RETURN_NIL;
+ case CAIRO_STATUS_TEMP_FILE_ERROR: RETURN_NIL;
+ case CAIRO_STATUS_INVALID_STRIDE: RETURN_NIL;
+ case CAIRO_STATUS_FONT_TYPE_MISMATCH: RETURN_NIL;
+ case CAIRO_STATUS_USER_FONT_IMMUTABLE: RETURN_NIL;
+ case CAIRO_STATUS_USER_FONT_ERROR: RETURN_NIL;
+ case CAIRO_STATUS_NEGATIVE_COUNT: RETURN_NIL;
+ case CAIRO_STATUS_INVALID_CLUSTERS: RETURN_NIL;
+ case CAIRO_STATUS_INVALID_SLANT: RETURN_NIL;
+ case CAIRO_STATUS_INVALID_WEIGHT: RETURN_NIL;
+ case CAIRO_STATUS_NO_MEMORY: RETURN_NIL;
+ default:
+ break;
+ }
+ status = CAIRO_STATUS_NO_MEMORY;
+ RETURN_NIL;
+#undef RETURN_NIL
+}
diff --git a/src/cairo-stroke-style.c b/src/cairo-stroke-style.c
index 3bc234e9..edc4f889 100644
--- a/src/cairo-stroke-style.c
+++ b/src/cairo-stroke-style.c
@@ -63,7 +63,7 @@ _cairo_stroke_style_init_copy (cairo_stroke_style_t *style,
style->dash = NULL;
} else {
style->dash = _cairo_malloc_ab (style->num_dashes, sizeof (double));
- if (style->dash == NULL)
+ if (unlikely (style->dash == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
memcpy (style->dash, other->dash,
diff --git a/src/cairo-surface-fallback.c b/src/cairo-surface-fallback.c
index 2dcaa58e..88975e9a 100644
--- a/src/cairo-surface-fallback.c
+++ b/src/cairo-surface-fallback.c
@@ -79,7 +79,7 @@ _fallback_init (fallback_state_t *state,
status = _cairo_surface_acquire_dest_image (dst, &state->extents,
&state->image, &state->image_rect,
&state->image_extra);
- if (status)
+ if (unlikely (status))
return status;
/* XXX: This NULL value tucked away in state->image is a rather
@@ -131,7 +131,7 @@ _create_composite_mask_pattern (cairo_surface_pattern_t *mask_pattern,
NULL, mask,
extents->x, extents->y,
extents);
- if (status)
+ if (unlikely (status))
goto CLEANUP_SURFACE;
if (clip && clip->surface)
@@ -139,7 +139,7 @@ _create_composite_mask_pattern (cairo_surface_pattern_t *mask_pattern,
mask,
extents->x, extents->y,
extents);
- if (status)
+ if (unlikely (status))
goto CLEANUP_SURFACE;
_cairo_pattern_init_for_surface (mask_pattern, mask);
@@ -169,7 +169,7 @@ _clip_and_composite_with_mask (cairo_clip_t *clip,
clip,
draw_func, draw_closure,
dst, extents);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_surface_composite (op,
@@ -226,14 +226,14 @@ _clip_and_composite_combine (cairo_clip_t *clip,
_cairo_pattern_fini (&dst_pattern.base);
- if (status)
+ if (unlikely (status))
goto CLEANUP_SURFACE;
status = (*draw_func) (draw_closure, op,
src, intermediate,
extents->x, extents->y,
extents);
- if (status)
+ if (unlikely (status))
goto CLEANUP_SURFACE;
/* Combine that with the clip
@@ -242,7 +242,7 @@ _clip_and_composite_combine (cairo_clip_t *clip,
intermediate,
extents->x, extents->y,
extents);
- if (status)
+ if (unlikely (status))
goto CLEANUP_SURFACE;
/* Punch the clip out of the destination
@@ -251,7 +251,7 @@ _clip_and_composite_combine (cairo_clip_t *clip,
dst,
0, 0,
extents);
- if (status)
+ if (unlikely (status))
goto CLEANUP_SURFACE;
/* Now add the two results together
@@ -293,7 +293,7 @@ _clip_and_composite_source (cairo_clip_t *clip,
clip,
draw_func, draw_closure,
dst, extents);
- if (status)
+ if (unlikely (status))
return status;
/* Compute dest' = dest OUT (mask IN clip)
@@ -305,7 +305,7 @@ _clip_and_composite_source (cairo_clip_t *clip,
extents->x, extents->y,
extents->width, extents->height);
- if (status)
+ if (unlikely (status))
goto CLEANUP_MASK_PATTERN;
/* Now compute (src IN (mask IN clip)) ADD dest'
@@ -439,7 +439,7 @@ _composite_trap_region (cairo_clip_t *clip,
status = _cairo_surface_set_clip_region (dst,
trap_region,
clip_serial);
- if (status)
+ if (unlikely (status))
return status;
}
@@ -531,7 +531,7 @@ _clip_and_composite_trapezoids (const cairo_pattern_t *src,
return CAIRO_STATUS_SUCCESS;
status = _cairo_surface_get_extents (dst, &extents);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_traps_extract_region (traps, &trap_region);
@@ -548,7 +548,7 @@ _clip_and_composite_trapezoids (const cairo_pattern_t *src,
if (has_trap_region) {
status = _cairo_clip_intersect_to_region (clip, &trap_region);
- if (status)
+ if (unlikely (status))
goto out;
_cairo_region_get_extents (&trap_region, &trap_extents);
@@ -564,7 +564,7 @@ _clip_and_composite_trapezoids (const cairo_pattern_t *src,
}
status = _cairo_clip_intersect_to_rectangle (clip, &extents);
- if (status)
+ if (unlikely (status))
goto out;
} else {
cairo_surface_t *clip_surface = clip ? clip->surface : NULL;
@@ -579,13 +579,13 @@ _clip_and_composite_trapezoids (const cairo_pattern_t *src,
has_clear_region = TRUE;
status = _cairo_clip_intersect_to_region (clip, &clear_region);
- if (status)
+ if (unlikely (status))
goto out;
_cairo_region_get_extents (&clear_region, &extents);
status = _cairo_region_subtract (&clear_region, &clear_region, &trap_region);
- if (status)
+ if (unlikely (status))
goto out;
if (!_cairo_region_not_empty (&clear_region)) {
@@ -597,7 +597,7 @@ _clip_and_composite_trapezoids (const cairo_pattern_t *src,
}
}
- if (status)
+ if (unlikely (status))
goto out;
if (has_trap_region) {
@@ -670,6 +670,53 @@ out:
return status;
}
+typedef struct {
+ cairo_path_fixed_t *path;
+ cairo_fill_rule_t fill_rule;
+ double tolerance;
+ cairo_antialias_t antialias;
+} cairo_composite_spans_fill_info_t;
+
+static cairo_status_t
+_composite_spans_fill_func (void *closure,
+ cairo_operator_t op,
+ const cairo_pattern_t *src,
+ cairo_surface_t *dst,
+ int dst_x,
+ int dst_y,
+ const cairo_rectangle_int_t *extents)
+{
+ cairo_composite_rectangles_t rects;
+ cairo_composite_spans_fill_info_t *info = closure;
+ cairo_pattern_union_t pattern;
+ cairo_status_t status = CAIRO_STATUS_SUCCESS;
+
+ _cairo_composite_rectangles_init (
+ &rects, extents->x, extents->y,
+ extents->width, extents->height);
+
+ /* The incoming dst_x/y are where we're pretending the origin of
+ * the dst surface is -- *not* the offset of a rectangle where
+ * we'd like to place the result. */
+ rects.dst.x -= dst_x;
+ rects.dst.y -= dst_y;
+
+ /* We're called without a source pattern from
+ * _create_composite_mask_pattern(). */
+ _cairo_pattern_init_solid (&pattern.solid, CAIRO_COLOR_WHITE,
+ CAIRO_CONTENT_COLOR);
+ if (src == NULL)
+ src = &pattern.base;
+
+ status = _cairo_path_fixed_fill_using_spans (
+ op, src, info->path, dst,
+ info->fill_rule, info->tolerance, info->antialias,
+ &rects);
+
+ _cairo_pattern_fini (&pattern.base);
+ return status;
+}
+
cairo_status_t
_cairo_surface_fallback_paint (cairo_surface_t *surface,
cairo_operator_t op,
@@ -681,14 +728,14 @@ _cairo_surface_fallback_paint (cairo_surface_t *surface,
cairo_traps_t traps;
status = _cairo_surface_get_extents (surface, &extents);
- if (status)
+ if (unlikely (status))
return status;
if (_cairo_operator_bounded_by_source (op)) {
cairo_rectangle_int_t source_extents;
status = _cairo_pattern_get_extents (source, &source_extents);
- if (status)
+ if (unlikely (status))
return status;
if (! _cairo_rectangle_intersect (&extents, &source_extents))
@@ -696,7 +743,7 @@ _cairo_surface_fallback_paint (cairo_surface_t *surface,
}
status = _cairo_clip_intersect_to_rectangle (surface->clip, &extents);
- if (status)
+ if (unlikely (status))
return status;
_cairo_box_from_rectangle (&box, &extents);
@@ -752,12 +799,12 @@ _cairo_surface_fallback_mask (cairo_surface_t *surface,
cairo_rectangle_int_t extents, source_extents, mask_extents;
status = _cairo_surface_get_extents (surface, &extents);
- if (status)
+ if (unlikely (status))
return status;
if (_cairo_operator_bounded_by_source (op)) {
status = _cairo_pattern_get_extents (source, &source_extents);
- if (status)
+ if (unlikely (status))
return status;
if (! _cairo_rectangle_intersect (&extents, &source_extents))
@@ -766,7 +813,7 @@ _cairo_surface_fallback_mask (cairo_surface_t *surface,
if (_cairo_operator_bounded_by_mask (op)) {
status = _cairo_pattern_get_extents (mask, &mask_extents);
- if (status)
+ if (unlikely (status))
return status;
if (! _cairo_rectangle_intersect (&extents, &mask_extents))
@@ -774,7 +821,7 @@ _cairo_surface_fallback_mask (cairo_surface_t *surface,
}
status = _cairo_clip_intersect_to_rectangle (surface->clip, &extents);
- if (status)
+ if (unlikely (status))
return status;
status = _clip_and_composite (surface->clip, op,
@@ -804,13 +851,13 @@ _cairo_surface_fallback_stroke (cairo_surface_t *surface,
cairo_rectangle_int_t extents;
status = _cairo_surface_get_extents (surface, &extents);
- if (status)
+ if (unlikely (status))
return status;
if (_cairo_operator_bounded_by_source (op)) {
cairo_rectangle_int_t source_extents;
status = _cairo_pattern_get_extents (source, &source_extents);
- if (status)
+ if (unlikely (status))
return status;
if (! _cairo_rectangle_intersect (&extents, &source_extents))
@@ -818,7 +865,7 @@ _cairo_surface_fallback_stroke (cairo_surface_t *surface,
}
status = _cairo_clip_intersect_to_rectangle (surface->clip, &extents);
- if (status)
+ if (unlikely (status))
return status;
if (extents.width == 0 || extents.height == 0)
@@ -834,7 +881,7 @@ _cairo_surface_fallback_stroke (cairo_surface_t *surface,
ctm, ctm_inverse,
tolerance,
&traps);
- if (status)
+ if (unlikely (status))
goto FAIL;
status = _clip_and_composite_trapezoids (source,
@@ -865,14 +912,14 @@ _cairo_surface_fallback_fill (cairo_surface_t *surface,
cairo_rectangle_int_t extents;
status = _cairo_surface_get_extents (surface, &extents);
- if (status)
+ if (unlikely (status))
return status;
if (_cairo_operator_bounded_by_source (op)) {
cairo_rectangle_int_t source_extents;
status = _cairo_pattern_get_extents (source, &source_extents);
- if (status)
+ if (unlikely (status))
return status;
if (! _cairo_rectangle_intersect (&extents, &source_extents))
@@ -880,14 +927,51 @@ _cairo_surface_fallback_fill (cairo_surface_t *surface,
}
status = _cairo_clip_intersect_to_rectangle (surface->clip, &extents);
- if (status)
+ if (unlikely (status))
return status;
if (extents.width == 0 || extents.height == 0)
return CAIRO_STATUS_SUCCESS;
- _cairo_box_from_rectangle (&box, &extents);
+ /* Ask if the surface would like to render this combination of
+ * op/source/dst/antialias with spans or not, but don't actually
+ * make a renderer yet. We'll try to hit the region optimisations
+ * in _clip_and_composite_trapezoids() if it looks like the path
+ * is a region. */
+ /* TODO: Until we have a mono scan converter we won't even try
+ * to use spans for CAIRO_ANTIALIAS_NONE. */
+ /* TODO: The region filling code should be lifted from
+ * _clip_and_composite_trapezoids() and given first priority
+ * explicitly before deciding between spans and trapezoids. */
+ if (antialias != CAIRO_ANTIALIAS_NONE &&
+ !_cairo_path_fixed_is_box (path, &box) &&
+ !_cairo_path_fixed_is_region (path) &&
+ _cairo_surface_check_span_renderer (
+ op, source, surface, antialias, NULL))
+ {
+ cairo_composite_spans_fill_info_t info;
+ info.path = path;
+ info.fill_rule = fill_rule;
+ info.tolerance = tolerance;
+ info.antialias = antialias;
+
+ if (_cairo_operator_bounded_by_mask (op)) {
+ cairo_rectangle_int_t path_extents;
+ _cairo_path_fixed_approximate_extents (path, &path_extents);
+ if (! _cairo_rectangle_intersect (&extents, &path_extents))
+ return CAIRO_STATUS_SUCCESS;
+ }
+ return _clip_and_composite (
+ surface->clip, op, source,
+ _composite_spans_fill_func,
+ &info,
+ surface,
+ &extents);
+ }
+
+ /* Fall back to trapezoid fills. */
+ _cairo_box_from_rectangle (&box, &extents);
_cairo_traps_init (&traps);
_cairo_traps_limit (&traps, &box);
@@ -895,7 +979,7 @@ _cairo_surface_fallback_fill (cairo_surface_t *surface,
fill_rule,
tolerance,
&traps);
- if (status) {
+ if (unlikely (status)) {
_cairo_traps_fini (&traps);
return status;
}
@@ -992,7 +1076,7 @@ _cairo_surface_fallback_show_glyphs (cairo_surface_t *surface,
cairo_show_glyphs_info_t glyph_info;
status = _cairo_surface_get_extents (surface, &extents);
- if (status)
+ if (unlikely (status))
return status;
if (_cairo_operator_bounded_by_mask (op)) {
@@ -1002,7 +1086,7 @@ _cairo_surface_fallback_show_glyphs (cairo_surface_t *surface,
glyphs,
num_glyphs,
&glyph_extents);
- if (status)
+ if (unlikely (status))
return status;
if (! _cairo_rectangle_intersect (&extents, &glyph_extents))
@@ -1010,7 +1094,7 @@ _cairo_surface_fallback_show_glyphs (cairo_surface_t *surface,
}
status = _cairo_clip_intersect_to_rectangle (surface->clip, &extents);
- if (status)
+ if (unlikely (status))
return status;
glyph_info.font = scaled_font;
@@ -1045,7 +1129,7 @@ _cairo_surface_fallback_snapshot (cairo_surface_t *surface)
status = _cairo_surface_acquire_source_image (surface,
&image, &image_extra);
- if (status)
+ if (unlikely (status))
return _cairo_surface_create_in_error (status);
snapshot = cairo_image_surface_create (image->format,
@@ -1073,7 +1157,7 @@ _cairo_surface_fallback_snapshot (cairo_surface_t *surface)
_cairo_surface_release_source_image (surface,
image, image_extra);
- if (status) {
+ if (unlikely (status)) {
cairo_surface_destroy (snapshot);
return _cairo_surface_create_in_error (status);
}
@@ -1083,7 +1167,7 @@ _cairo_surface_fallback_snapshot (cairo_surface_t *surface)
for (mime_type = mime_types; *mime_type; mime_type++) {
status = _cairo_surface_copy_mime_data (snapshot, surface, *mime_type);
- if (status) {
+ if (unlikely (status)) {
cairo_surface_destroy (snapshot);
return _cairo_surface_create_in_error (status);
}
@@ -1112,7 +1196,7 @@ _cairo_surface_fallback_composite (cairo_operator_t op,
cairo_status_t status;
status = _fallback_init (&state, dst, dst_x, dst_y, width, height);
- if (status) {
+ if (unlikely (status)) {
if (status == CAIRO_INT_STATUS_NOTHING_TO_DO)
return CAIRO_STATUS_SUCCESS;
return status;
@@ -1173,7 +1257,7 @@ _cairo_surface_fallback_fill_rectangles (cairo_surface_t *surface,
}
status = _fallback_init (&state, surface, x1, y1, x2 - x1, y2 - y1);
- if (status) {
+ if (unlikely (status)) {
if (status == CAIRO_INT_STATUS_NOTHING_TO_DO)
return CAIRO_STATUS_SUCCESS;
return status;
@@ -1183,7 +1267,7 @@ _cairo_surface_fallback_fill_rectangles (cairo_surface_t *surface,
if (state.image_rect.x != 0 || state.image_rect.y != 0) {
offset_rects = _cairo_malloc_ab (num_rects, sizeof (cairo_rectangle_int_t));
- if (offset_rects == NULL) {
+ if (unlikely (offset_rects == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto DONE;
}
@@ -1229,7 +1313,7 @@ _cairo_surface_fallback_composite_trapezoids (cairo_operator_t op,
cairo_status_t status;
status = _fallback_init (&state, dst, dst_x, dst_y, width, height);
- if (status) {
+ if (unlikely (status)) {
if (status == CAIRO_INT_STATUS_NOTHING_TO_DO)
return CAIRO_STATUS_SUCCESS;
return status;
diff --git a/src/cairo-surface.c b/src/cairo-surface.c
index 4c10f958..077af5b4 100644
--- a/src/cairo-surface.c
+++ b/src/cairo-surface.c
@@ -237,7 +237,7 @@ _cairo_surface_create_similar_scratch (cairo_surface_t *other,
}
/* If any error occurred, then return the nil surface we received. */
- if (surface->status)
+ if (unlikely (surface->status))
return surface;
if (other->has_font_options || other->backend != surface->backend) {
@@ -322,7 +322,7 @@ _cairo_surface_create_similar_solid (cairo_surface_t *other,
_cairo_pattern_fini (&solid_pattern.base);
- if (status) {
+ if (unlikely (status)) {
cairo_surface_destroy (surface);
return _cairo_surface_create_in_error (status);
}
@@ -455,7 +455,7 @@ _cairo_surface_reset (cairo_surface_t *surface)
if (surface->backend->reset != NULL) {
cairo_status_t status = surface->backend->reset (surface);
- if (status)
+ if (unlikely (status))
return _cairo_surface_set_error (surface, status);
}
@@ -523,7 +523,7 @@ cairo_surface_finish (cairo_surface_t *surface)
/* call finish even if in error mode */
if (surface->backend->finish) {
status = surface->backend->finish (surface);
- if (status)
+ if (unlikely (status))
status = _cairo_surface_set_error (surface, status);
}
@@ -608,7 +608,7 @@ cairo_surface_get_mime_data (cairo_surface_t *surface,
return;
status = _cairo_intern_string (&mime_type, -1);
- if (status) {
+ if (unlikely (status)) {
status = _cairo_surface_set_error (surface, status);
return;
}
@@ -672,12 +672,12 @@ cairo_surface_set_mime_data (cairo_surface_t *surface,
return surface->status;
status = _cairo_intern_string (&mime_type, -1);
- if (status)
+ if (unlikely (status))
return _cairo_surface_set_error (surface, status);
if (data != NULL) {
mime_data = malloc (sizeof (cairo_mime_data_t));
- if (mime_data == NULL)
+ if (unlikely (mime_data == NULL))
return _cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_NO_MEMORY));
CAIRO_REFERENCE_COUNT_INIT (&mime_data->ref_count, 1);
@@ -693,7 +693,7 @@ cairo_surface_set_mime_data (cairo_surface_t *surface,
(cairo_user_data_key_t *) mime_type,
mime_data,
_cairo_mime_data_destroy);
- if (status)
+ if (unlikely (status))
return _cairo_surface_set_error (surface, status);
return CAIRO_STATUS_SUCCESS;
@@ -715,7 +715,7 @@ _cairo_surface_copy_mime_data (cairo_surface_t *dst,
return _cairo_surface_set_error (dst, src->status);
status = _cairo_intern_string (&mime_type, -1);
- if (status)
+ if (unlikely (status))
return _cairo_surface_set_error (dst, status);
mime_data = _cairo_user_data_array_get_data (&src->user_data,
@@ -729,7 +729,7 @@ _cairo_surface_copy_mime_data (cairo_surface_t *dst,
(cairo_user_data_key_t *) mime_type,
mime_data,
_cairo_mime_data_destroy);
- if (status) {
+ if (unlikely (status)) {
_cairo_mime_data_destroy (mime_data);
return _cairo_surface_set_error (dst, status);
}
@@ -839,7 +839,7 @@ cairo_surface_flush (cairo_surface_t *surface)
if (surface->backend->flush) {
status = surface->backend->flush (surface);
- if (status)
+ if (unlikely (status))
status = _cairo_surface_set_error (surface, status);
}
}
@@ -917,7 +917,7 @@ cairo_surface_mark_dirty_rectangle (cairo_surface_t *surface,
y + surface->device_transform.y0,
width, height);
- if (status)
+ if (unlikely (status))
status = _cairo_surface_set_error (surface, status);
}
}
@@ -1355,7 +1355,7 @@ _cairo_surface_clone_similar (cairo_surface_t *surface,
clone_out);
/* We should never get UNSUPPORTED here, so if we have an error, bail. */
- if (status)
+ if (unlikely (status))
return status;
/* Update the clone's device_transform (which the underlying surface
@@ -1562,7 +1562,7 @@ _cairo_surface_fill_region (cairo_surface_t *surface,
if (num_boxes > 1) {
num_boxes = sizeof (stack_rects) / sizeof (cairo_box_int_t);
status = _cairo_region_get_boxes (region, &num_boxes, &boxes);
- if (status)
+ if (unlikely (status))
return status;
if (num_boxes > ARRAY_LENGTH (stack_rects)) {
@@ -1661,7 +1661,7 @@ _cairo_surface_paint (cairo_surface_t *surface,
status = _cairo_surface_copy_pattern_for_destination (&source,
surface,
&dev_source.base);
- if (status)
+ if (unlikely (status))
return _cairo_surface_set_error (surface, status);
if (surface->backend->paint) {
@@ -1698,13 +1698,13 @@ _cairo_surface_mask (cairo_surface_t *surface,
status = _cairo_surface_copy_pattern_for_destination (&source,
surface,
&dev_source.base);
- if (status)
+ if (unlikely (status))
goto FINISH;
status = _cairo_surface_copy_pattern_for_destination (&mask,
surface,
&dev_mask.base);
- if (status)
+ if (unlikely (status))
goto CLEANUP_SOURCE;
if (surface->backend->mask) {
@@ -1757,13 +1757,13 @@ _cairo_surface_fill_stroke (cairo_surface_t *surface,
status = _cairo_surface_copy_pattern_for_destination (&stroke_source,
surface,
&dev_stroke_source.base);
- if (status)
+ if (unlikely (status))
return _cairo_surface_set_error (surface, status);
status = _cairo_surface_copy_pattern_for_destination (&fill_source,
surface,
&dev_fill_source.base);
- if (status) {
+ if (unlikely (status)) {
if (stroke_source == &dev_stroke_source.base)
_cairo_pattern_fini (&dev_stroke_source.base);
@@ -1792,13 +1792,13 @@ _cairo_surface_fill_stroke (cairo_surface_t *surface,
status = _cairo_surface_fill (surface, fill_op, fill_source, path,
fill_rule, fill_tolerance, fill_antialias, NULL);
- if (status)
+ if (unlikely (status))
return _cairo_surface_set_error (surface, status);
status = _cairo_surface_stroke (surface, stroke_op, stroke_source, path,
stroke_style, stroke_ctm, stroke_ctm_inverse,
stroke_tolerance, stroke_antialias, NULL);
- if (status)
+ if (unlikely (status))
return _cairo_surface_set_error (surface, status);
return CAIRO_STATUS_SUCCESS;
@@ -1831,7 +1831,7 @@ _cairo_surface_stroke (cairo_surface_t *surface,
status = _cairo_surface_copy_pattern_for_destination (&source,
surface,
&dev_source.base);
- if (status)
+ if (unlikely (status))
return _cairo_surface_set_error (surface, status);
if (surface->backend->stroke) {
@@ -1880,7 +1880,7 @@ _cairo_surface_fill (cairo_surface_t *surface,
status = _cairo_surface_copy_pattern_for_destination (&source,
surface,
&dev_source.base);
- if (status)
+ if (unlikely (status))
return _cairo_surface_set_error (surface, status);
if (surface->backend->fill) {
@@ -1953,6 +1953,59 @@ _cairo_surface_composite_trapezoids (cairo_operator_t op,
traps, num_traps));
}
+cairo_span_renderer_t *
+_cairo_surface_create_span_renderer (cairo_operator_t op,
+ const cairo_pattern_t *pattern,
+ cairo_surface_t *dst,
+ cairo_antialias_t antialias,
+ const cairo_composite_rectangles_t *rects)
+{
+ assert (! dst->is_snapshot);
+
+ if (dst->status)
+ return _cairo_span_renderer_create_in_error (dst->status);
+
+ if (dst->finished)
+ return _cairo_span_renderer_create_in_error (CAIRO_STATUS_SURFACE_FINISHED);
+
+ if (dst->backend->create_span_renderer) {
+ return dst->backend->create_span_renderer (op,
+ pattern, dst,
+ antialias,
+ rects);
+ }
+ ASSERT_NOT_REACHED;
+ return _cairo_span_renderer_create_in_error (CAIRO_INT_STATUS_UNSUPPORTED);
+}
+
+cairo_bool_t
+_cairo_surface_check_span_renderer (cairo_operator_t op,
+ const cairo_pattern_t *pattern,
+ cairo_surface_t *dst,
+ cairo_antialias_t antialias,
+ const cairo_composite_rectangles_t *rects)
+{
+ cairo_int_status_t status;
+
+ assert (! dst->is_snapshot);
+
+ if (dst->status)
+ return FALSE;
+
+ if (dst->finished) {
+ status = _cairo_surface_set_error (dst, CAIRO_STATUS_SURFACE_FINISHED);
+ return FALSE;
+ }
+
+ if (dst->backend->check_span_renderer) {
+ return dst->backend->check_span_renderer (op,
+ pattern, dst,
+ antialias,
+ rects);
+ }
+ return FALSE;
+}
+
/**
* cairo_surface_copy_page:
* @surface: a #cairo_surface_t
@@ -2097,13 +2150,13 @@ _cairo_surface_reset_clip (cairo_surface_t *surface)
CAIRO_FILL_RULE_WINDING,
0,
CAIRO_ANTIALIAS_DEFAULT);
- if (status)
+ if (unlikely (status))
return _cairo_surface_set_error (surface, status);
}
if (surface->backend->set_clip_region != NULL) {
status = surface->backend->set_clip_region (surface, NULL);
- if (status)
+ if (unlikely (status))
return _cairo_surface_set_error (surface, status);
}
@@ -2181,7 +2234,7 @@ _cairo_surface_set_clip_path_recursive (cairo_surface_t *surface,
return CAIRO_STATUS_SUCCESS;
status = _cairo_surface_set_clip_path_recursive (surface, clip_path->prev);
- if (status)
+ if (unlikely (status))
return status;
return _cairo_surface_intersect_clip_path (surface,
@@ -2220,11 +2273,11 @@ _cairo_surface_set_clip_path (cairo_surface_t *surface,
CAIRO_FILL_RULE_WINDING,
0,
CAIRO_ANTIALIAS_DEFAULT);
- if (status)
+ if (unlikely (status))
return _cairo_surface_set_error (surface, status);
status = _cairo_surface_set_clip_path_recursive (surface, clip_path);
- if (status)
+ if (unlikely (status))
return _cairo_surface_set_error (surface, status);
surface->current_clip_serial = serial;
@@ -2458,7 +2511,7 @@ _cairo_surface_show_text_glyphs (cairo_surface_t *surface,
status = _cairo_surface_copy_pattern_for_destination (&source,
surface,
&dev_source.base);
- if (status)
+ if (unlikely (status))
return _cairo_surface_set_error (surface, status);
if (_cairo_surface_has_device_transform (surface) &&
@@ -2477,7 +2530,7 @@ _cairo_surface_show_text_glyphs (cairo_surface_t *surface,
&font_options);
}
status = cairo_scaled_font_status (dev_scaled_font);
- if (status) {
+ if (unlikely (status)) {
if (source == &dev_source.base)
_cairo_pattern_fini (&dev_source.base);
@@ -2644,7 +2697,7 @@ _cairo_surface_composite_fixup_unbounded_internal (cairo_surface_t *dst,
status = _cairo_region_subtract (&clear_region,
&clear_region,
&drawn_region);
- if (status)
+ if (unlikely (status))
goto CLEANUP_REGIONS;
EMPTY:
@@ -2833,7 +2886,7 @@ _cairo_surface_copy_pattern_for_destination (const cairo_pattern_t **pattern,
return CAIRO_STATUS_SUCCESS;
status = _cairo_pattern_init_copy (pattern_copy, *pattern);
- if (status)
+ if (unlikely (status))
return status;
_cairo_pattern_transform (pattern_copy,
diff --git a/src/cairo-svg-surface.c b/src/cairo-svg-surface.c
index ab2e4b94..cfd9a2d5 100644
--- a/src/cairo-svg-surface.c
+++ b/src/cairo-svg-surface.c
@@ -285,7 +285,7 @@ cairo_svg_surface_restrict_to_version (cairo_surface_t *abstract_surface,
cairo_status_t status;
status = _extract_svg_surface (abstract_surface, &surface);
- if (status) {
+ if (unlikely (status)) {
status = _cairo_surface_set_error (abstract_surface, status);
return;
}
@@ -347,7 +347,7 @@ _cairo_svg_surface_create_for_document (cairo_svg_document_t *document,
cairo_status_t status, status_ignored;
surface = malloc (sizeof (cairo_svg_surface_t));
- if (surface == NULL)
+ if (unlikely (surface == NULL))
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
_cairo_surface_init (&surface->base, &cairo_svg_surface_backend,
@@ -366,7 +366,7 @@ _cairo_svg_surface_create_for_document (cairo_svg_document_t *document,
surface->xml_node = _cairo_memory_stream_create ();
status = _cairo_output_stream_get_status (surface->xml_node);
- if (status)
+ if (unlikely (status))
goto CLEANUP;
_cairo_array_init (&surface->page_set, sizeof (cairo_svg_page_t));
@@ -378,7 +378,7 @@ _cairo_svg_surface_create_for_document (cairo_svg_document_t *document,
"fill:rgb(0,0,0);\"/>\n",
width, height);
status = _cairo_output_stream_get_status (surface->xml_node);
- if (status)
+ if (unlikely (status))
goto CLEANUP;
}
@@ -421,7 +421,7 @@ _cairo_svg_surface_create_for_stream_internal (cairo_output_stream_t *stream,
status = _cairo_svg_document_create (stream,
width, height, version,
&document);
- if (status) {
+ if (unlikely (status)) {
surface = _cairo_surface_create_in_error (status);
/* consume the output stream on behalf of caller */
status = _cairo_output_stream_destroy (stream);
@@ -482,7 +482,7 @@ _cairo_svg_surface_copy_page (void *abstract_surface)
cairo_svg_page_t *page;
page = _cairo_svg_surface_store_page (surface);
- if (page == NULL)
+ if (unlikely (page == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
_cairo_memory_stream_copy (page->xml_node, surface->xml_node);
@@ -496,7 +496,7 @@ _cairo_svg_surface_show_page (void *abstract_surface)
{
cairo_svg_surface_t *surface = abstract_surface;
- if (_cairo_svg_surface_store_page (surface) == NULL)
+ if (unlikely (_cairo_svg_surface_store_page (surface) == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
return CAIRO_STATUS_SUCCESS;
@@ -614,7 +614,7 @@ _cairo_svg_surface_emit_path (cairo_output_stream_t *output,
_cairo_svg_path_curve_to,
_cairo_svg_path_close_path,
&info);
- if (status)
+ if (unlikely (status))
return status;
_cairo_output_stream_printf (output, "\"");
@@ -635,14 +635,14 @@ _cairo_svg_document_emit_outline_glyph_data (cairo_svg_document_t *document,
CAIRO_SCALED_GLYPH_INFO_METRICS|
CAIRO_SCALED_GLYPH_INFO_PATH,
&scaled_glyph);
- if (status)
+ if (unlikely (status))
return status;
_cairo_output_stream_printf (document->xml_node_glyphs,
"<path style=\"stroke:none;\" ");
status = _cairo_svg_surface_emit_path (document->xml_node_glyphs, scaled_glyph->path, NULL);
- if (status)
+ if (unlikely (status))
return status;
_cairo_output_stream_printf (document->xml_node_glyphs,
@@ -668,7 +668,7 @@ _cairo_svg_document_emit_bitmap_glyph_data (cairo_svg_document_t *document,
CAIRO_SCALED_GLYPH_INFO_METRICS|
CAIRO_SCALED_GLYPH_INFO_SURFACE,
&scaled_glyph);
- if (status)
+ if (unlikely (status))
return status;
image = scaled_glyph->surface;
@@ -724,7 +724,7 @@ _cairo_svg_document_emit_glyph (cairo_svg_document_t *document,
status = _cairo_svg_document_emit_bitmap_glyph_data (document,
scaled_font,
scaled_font_glyph_index);
- if (status)
+ if (unlikely (status))
return status;
_cairo_output_stream_printf (document->xml_node_glyphs, "</symbol>\n");
@@ -746,7 +746,7 @@ _cairo_svg_document_emit_font_subset (cairo_scaled_font_subset_t *font_subset,
font_subset->scaled_font,
font_subset->glyphs[i],
font_subset->font_id, i);
- if (status)
+ if (unlikely (status))
break;
}
_cairo_scaled_font_thaw_cache (font_subset->scaled_font);
@@ -762,7 +762,7 @@ _cairo_svg_document_emit_font_subsets (cairo_svg_document_t *document)
status = _cairo_scaled_font_subsets_foreach_scaled (document->font_subsets,
_cairo_svg_document_emit_font_subset,
document);
- if (status)
+ if (unlikely (status))
goto FAIL;
status = _cairo_scaled_font_subsets_foreach_user (document->font_subsets,
@@ -992,7 +992,7 @@ _cairo_surface_base64_encode_jpeg (cairo_surface_t *surface,
return CAIRO_INT_STATUS_UNSUPPORTED;
status = _cairo_image_info_get_jpeg_info (&image_info, mime_data, mime_data_length);
- if (status)
+ if (unlikely (status))
return status;
_cairo_output_stream_printf (output, "data:image/jpeg;base64,");
@@ -1002,7 +1002,7 @@ _cairo_surface_base64_encode_jpeg (cairo_surface_t *surface,
info.trailing = 0;
status = base64_write_func (&info, mime_data, mime_data_length);
- if (status)
+ if (unlikely (status))
return status;
if (info.in_mem > 0) {
@@ -1036,7 +1036,7 @@ _cairo_surface_base64_encode_png (cairo_surface_t *surface,
info.trailing = 0;
status = base64_write_func (&info, mime_data, mime_data_length);
- if (status)
+ if (unlikely (status))
return status;
if (info.in_mem > 0) {
@@ -1073,7 +1073,7 @@ _cairo_surface_base64_encode (cairo_surface_t *surface,
status = cairo_surface_write_to_png_stream (surface, base64_write_func,
(void *) &info);
- if (status)
+ if (unlikely (status))
return status;
if (info.in_mem > 0) {
@@ -1126,7 +1126,7 @@ _cairo_svg_surface_emit_composite_image_pattern (cairo_output_stream_t *output
cairo_matrix_t p2u;
status = _cairo_surface_get_extents (pattern->surface, &extents);
- if (status)
+ if (unlikely (status))
return status;
p2u = pattern->base.matrix;
@@ -1214,7 +1214,7 @@ _cairo_svg_surface_emit_meta_surface (cairo_svg_document_t *document,
document->owner->y_fallback_resolution);
status = _cairo_meta_surface_replay (&meta->base, paginated_surface);
- if (status) {
+ if (unlikely (status)) {
cairo_surface_destroy (&meta->base);
cairo_surface_destroy (paginated_surface);
return status;
@@ -1222,7 +1222,7 @@ _cairo_svg_surface_emit_meta_surface (cairo_svg_document_t *document,
cairo_surface_show_page (paginated_surface);
status = cairo_surface_status (paginated_surface);
- if (status) {
+ if (unlikely (status)) {
cairo_surface_destroy (&meta->base);
cairo_surface_destroy (paginated_surface);
return status;
@@ -1231,7 +1231,7 @@ _cairo_svg_surface_emit_meta_surface (cairo_svg_document_t *document,
new_snapshot.meta = meta;
new_snapshot.id = svg_surface->id;
status = _cairo_array_append (&document->meta_snapshots, &new_snapshot);
- if (status) {
+ if (unlikely (status)) {
cairo_surface_destroy (&meta->base);
cairo_surface_destroy (paginated_surface);
return status;
@@ -1268,7 +1268,7 @@ _cairo_svg_surface_emit_meta_surface (cairo_svg_document_t *document,
page_set = &svg_surface->page_set;
if (_cairo_memory_stream_length (contents) > 0) {
- if (_cairo_svg_surface_store_page (svg_surface) == NULL) {
+ if (unlikely (_cairo_svg_surface_store_page (svg_surface) == NULL)) {
cairo_surface_destroy (paginated_surface);
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
@@ -1321,7 +1321,7 @@ _cairo_svg_surface_emit_composite_meta_pattern (cairo_output_stream_t *output,
meta_surface = (cairo_meta_surface_t *) pattern->surface;
status = _cairo_svg_surface_emit_meta_surface (document, meta_surface, &id);
- if (status)
+ if (unlikely (status))
return status;
if (pattern_id != invalid_pattern_id) {
@@ -1407,7 +1407,7 @@ _cairo_svg_surface_emit_surface_pattern (cairo_svg_surface_t *surface,
status = _cairo_svg_surface_emit_composite_pattern (document->xml_node_defs,
surface, CAIRO_OPERATOR_SOURCE, pattern,
pattern_id, parent_matrix, NULL);
- if (status)
+ if (unlikely (status))
return status;
_cairo_output_stream_printf (style,
@@ -1449,7 +1449,7 @@ _cairo_svg_surface_emit_pattern_stops (cairo_output_stream_t *output,
if (emulate_reflect || reverse_stops) {
n_stops = emulate_reflect ? pattern->n_stops * 2 - 2: pattern->n_stops;
stops = _cairo_malloc_ab (n_stops, sizeof (cairo_gradient_stop_t));
- if (stops == NULL)
+ if (unlikely (stops == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
for (i = 0; i < pattern->n_stops; i++) {
@@ -1634,7 +1634,7 @@ _cairo_svg_surface_emit_linear_pattern (cairo_svg_surface_t *surface,
status = _cairo_svg_surface_emit_pattern_stops (document->xml_node_defs,
&pattern->base, 0.0,
FALSE, FALSE);
- if (status)
+ if (unlikely (status))
return status;
_cairo_output_stream_printf (document->xml_node_defs,
@@ -1812,7 +1812,7 @@ _cairo_svg_surface_emit_radial_pattern (cairo_svg_surface_t *surface,
&pattern->base, offset,
reverse_stops,
emulate_reflect);
- if (status)
+ if (unlikely (status))
return status;
if (pattern->base.base.extend == CAIRO_EXTEND_NONE)
@@ -1927,7 +1927,7 @@ _cairo_svg_surface_emit_stroke_style (cairo_output_stream_t *output,
line_join);
status = _cairo_svg_surface_emit_pattern (surface, source, output, TRUE, parent_matrix);
- if (status)
+ if (unlikely (status))
return status;
_cairo_svg_surface_emit_operator_for_style (output, surface, op);
@@ -1979,18 +1979,18 @@ _cairo_svg_surface_fill_stroke (void *abstract_surface,
_cairo_output_stream_printf (surface->xml_node, "<path style=\"");
status = _cairo_svg_surface_emit_fill_style (surface->xml_node, surface, fill_op,
fill_source, fill_rule, stroke_ctm_inverse);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_svg_surface_emit_stroke_style (surface->xml_node, surface, stroke_op,
stroke_source, stroke_style, stroke_ctm_inverse);
- if (status)
+ if (unlikely (status))
return status;
_cairo_output_stream_printf (surface->xml_node, "\" ");
status = _cairo_svg_surface_emit_path (surface->xml_node, path, stroke_ctm_inverse);
- if (status)
+ if (unlikely (status))
return status;
_cairo_svg_surface_emit_transform (surface->xml_node, " transform", stroke_ctm, NULL);
@@ -2019,13 +2019,13 @@ _cairo_svg_surface_fill (void *abstract_surface,
_cairo_output_stream_printf (surface->xml_node, "<path style=\" stroke:none;");
status = _cairo_svg_surface_emit_fill_style (surface->xml_node, surface, op, source, fill_rule, NULL);
- if (status)
+ if (unlikely (status))
return status;
_cairo_output_stream_printf (surface->xml_node, "\" ");
status = _cairo_svg_surface_emit_path (surface->xml_node, path, NULL);
- if (status)
+ if (unlikely (status))
return status;
_cairo_output_stream_printf (surface->xml_node, "/>\n");
@@ -2079,7 +2079,7 @@ _cairo_svg_surface_emit_paint (cairo_output_stream_t *output,
surface->width, surface->height);
_cairo_svg_surface_emit_operator_for_style (output, surface, op);
status = _cairo_svg_surface_emit_pattern (surface, source, output, FALSE, NULL);
- if (status)
+ if (unlikely (status))
return status;
_cairo_output_stream_printf (output, "stroke:none;\"");
@@ -2116,7 +2116,7 @@ _cairo_svg_surface_paint (void *abstract_surface,
* and an optimization in meta surface. */
if (surface->clip_level == 0 && op == CAIRO_OPERATOR_CLEAR) {
status = _cairo_output_stream_destroy (surface->xml_node);
- if (status) {
+ if (unlikely (status)) {
surface->xml_node = NULL;
return status;
}
@@ -2204,7 +2204,7 @@ _cairo_svg_surface_mask (void *abstract_surface,
mask_id,
discard_filter ? "" : " <g filter=\"url(#alpha)\">\n");
status = _cairo_svg_surface_emit_paint (mask_stream, surface, CAIRO_OPERATOR_OVER, mask, source, NULL);
- if (status) {
+ if (unlikely (status)) {
cairo_status_t ignore = _cairo_output_stream_destroy (mask_stream);
return status;
(void) ignore;
@@ -2217,13 +2217,13 @@ _cairo_svg_surface_mask (void *abstract_surface,
_cairo_memory_stream_copy (mask_stream, document->xml_node_defs);
status = _cairo_output_stream_destroy (mask_stream);
- if (status)
+ if (unlikely (status))
return status;
snprintf (buffer, sizeof buffer, "mask=\"url(#mask%d)\"",
mask_id);
status = _cairo_svg_surface_emit_paint (surface->xml_node, surface, op, source, 0, buffer);
- if (status)
+ if (unlikely (status))
return status;
return CAIRO_STATUS_SUCCESS;
@@ -2252,13 +2252,13 @@ _cairo_svg_surface_stroke (void *abstract_dst,
_cairo_output_stream_printf (surface->xml_node, "<path style=\"fill:none;");
status = _cairo_svg_surface_emit_stroke_style (surface->xml_node, surface, op,
source, stroke_style, ctm_inverse);
- if (status)
+ if (unlikely (status))
return status;
_cairo_output_stream_printf (surface->xml_node, "\" ");
status = _cairo_svg_surface_emit_path (surface->xml_node, path, ctm_inverse);
- if (status)
+ if (unlikely (status))
return status;
_cairo_svg_surface_emit_transform (surface->xml_node, " transform", ctm, NULL);
@@ -2301,7 +2301,7 @@ _cairo_svg_surface_show_glyphs (void *abstract_surface,
_cairo_output_stream_printf (surface->xml_node, "<g style=\"");
status = _cairo_svg_surface_emit_pattern (surface, pattern,
surface->xml_node, FALSE, NULL);
- if (status)
+ if (unlikely (status))
return status;
_cairo_svg_surface_emit_operator_for_style (surface->xml_node, surface, op);
@@ -2321,7 +2321,7 @@ _cairo_svg_surface_show_glyphs (void *abstract_surface,
goto FALLBACK;
}
- if (status)
+ if (unlikely (status))
return status;
_cairo_output_stream_printf (surface->xml_node,
@@ -2341,7 +2341,7 @@ FALLBACK:
status = _cairo_scaled_font_glyph_path (scaled_font,(cairo_glyph_t *) glyphs, num_glyphs, &path);
- if (status) {
+ if (unlikely (status)) {
_cairo_path_fixed_fini (&path);
return status;
}
@@ -2379,7 +2379,7 @@ _cairo_svg_surface_intersect_clip_path (void *dst,
" <path ",
document->clip_id);
status = _cairo_svg_surface_emit_path (document->xml_node_defs, path, NULL);
- if (status)
+ if (unlikely (status))
return status;
_cairo_output_stream_printf (document->xml_node_defs,
@@ -2422,6 +2422,8 @@ static const cairo_surface_backend_t cairo_svg_surface_backend = {
NULL, /* _cairo_svg_surface_composite, */
NULL, /* _cairo_svg_surface_fill_rectangles, */
NULL, /* _cairo_svg_surface_composite_trapezoids,*/
+ NULL, /* create_span_renderer */
+ NULL, /* check_span_renderer */
_cairo_svg_surface_copy_page,
_cairo_svg_surface_show_page,
NULL, /* set_clip_region */
@@ -2458,12 +2460,12 @@ _cairo_svg_document_create (cairo_output_stream_t *output_stream,
return output_stream->status;
document = malloc (sizeof (cairo_svg_document_t));
- if (document == NULL)
+ if (unlikely (document == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
/* The use of defs for font glyphs imposes no per-subset limit. */
document->font_subsets = _cairo_scaled_font_subsets_create_scaled ();
- if (document->font_subsets == NULL) {
+ if (unlikely (document->font_subsets == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto CLEANUP_DOCUMENT;
}
@@ -2485,12 +2487,12 @@ _cairo_svg_document_create (cairo_output_stream_t *output_stream,
document->xml_node_defs = _cairo_memory_stream_create ();
status = _cairo_output_stream_get_status (document->xml_node_defs);
- if (status)
+ if (unlikely (status))
goto CLEANUP_NODE_DEFS;
document->xml_node_glyphs = _cairo_memory_stream_create ();
status = _cairo_output_stream_get_status (document->xml_node_glyphs);
- if (status)
+ if (unlikely (status))
goto CLEANUP_NODE_GLYPHS;
document->alpha_filter = FALSE;
@@ -2607,7 +2609,7 @@ _cairo_svg_document_finish (cairo_svg_document_t *document)
surface = (cairo_svg_surface_t *) _cairo_paginated_surface_get_target (document->owner);
if (surface->xml_node != NULL &&
_cairo_memory_stream_length (surface->xml_node) > 0) {
- if (_cairo_svg_surface_store_page (surface) == NULL) {
+ if (unlikely (_cairo_svg_surface_store_page (surface) == NULL)) {
if (status == CAIRO_STATUS_SUCCESS)
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
diff --git a/src/cairo-tor-scan-converter.c b/src/cairo-tor-scan-converter.c
new file mode 100644
index 00000000..20104a7f
--- /dev/null
+++ b/src/cairo-tor-scan-converter.c
@@ -0,0 +1,2003 @@
+/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
+/* glitter-paths - polygon scan converter
+ *
+ * Copyright (c) 2008 M Joonas Pihlaja
+ * Copyright (c) 2007 David Turner
+ *
+ * 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.
+ */
+/* This is the Glitter paths scan converter incorporated into cairo.
+ * The source is from commit 734c53237a867a773640bd5b64816249fa1730f8
+ * of
+ *
+ * http://gitweb.freedesktop.org/?p=users/joonas/glitter-paths
+ */
+/* Glitter-paths is a stand alone polygon rasteriser derived from
+ * David Turner's reimplementation of Tor Anderssons's 15x17
+ * supersampling rasteriser from the Apparition graphics library. The
+ * main new feature here is cheaply choosing per-scan line between
+ * doing fully analytical coverage computation for an entire row at a
+ * time vs. using a supersampling approach.
+ *
+ * David Turner's code can be found at
+ *
+ * http://david.freetype.org/rasterizer-shootout/raster-comparison-20070813.tar.bz2
+ *
+ * In particular this file incorporates large parts of ftgrays_tor10.h
+ * from raster-comparison-20070813.tar.bz2
+ */
+/* Overview
+ *
+ * A scan converter's basic purpose to take polygon edges and convert
+ * them into an RLE compressed A8 mask. This one works in two phases:
+ * gathering edges and generating spans.
+ *
+ * 1) As the user feeds the scan converter edges they are vertically
+ * clipped and bucketted into a _polygon_ data structure. The edges
+ * are also snapped from the user's coordinates to the subpixel grid
+ * coordinates used during scan conversion.
+ *
+ * user
+ * |
+ * | edges
+ * V
+ * polygon buckets
+ *
+ * 2) Generating spans works by performing a vertical sweep of pixel
+ * rows from top to bottom and maintaining an _active_list_ of edges
+ * that intersect the row. From the active list the fill rule
+ * determines which edges are the left and right edges of the start of
+ * each span, and their contribution is then accumulated into a pixel
+ * coverage list (_cell_list_) as coverage deltas. Once the coverage
+ * deltas of all edges are known we can form spans of constant pixel
+ * coverage by summing the deltas during a traversal of the cell list.
+ * At the end of a pixel row the cell list is sent to a coverage
+ * blitter for rendering to some target surface.
+ *
+ * The pixel coverages are computed by either supersampling the row
+ * and box filtering a mono rasterisation, or by computing the exact
+ * coverages of edges in the active list. The supersampling method is
+ * used whenever some edge starts or stops within the row or there are
+ * edge intersections in the row.
+ *
+ * polygon bucket for \
+ * current pixel row |
+ * | |
+ * | activate new edges | Repeat GRID_Y times if we
+ * V \ are supersampling this row,
+ * active list / or just once if we're computing
+ * | | analytical coverage.
+ * | coverage deltas |
+ * V |
+ * pixel coverage list /
+ * |
+ * V
+ * coverage blitter
+ */
+#include "cairoint.h"
+#include "cairo-spans-private.h"
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+
+/*-------------------------------------------------------------------------
+ * cairo specific config
+ */
+#define I static
+
+/* Prefer cairo's status type. */
+#define GLITTER_HAVE_STATUS_T 1
+#define GLITTER_STATUS_SUCCESS CAIRO_STATUS_SUCCESS
+#define GLITTER_STATUS_NO_MEMORY CAIRO_STATUS_NO_MEMORY
+typedef cairo_status_t glitter_status_t;
+
+/* The input coordinate scale and the rasterisation grid scales. */
+#define GLITTER_INPUT_BITS CAIRO_FIXED_FRAC_BITS
+#define GRID_X_BITS CAIRO_FIXED_FRAC_BITS
+#define GRID_Y 15
+
+/* Set glitter up to use a cairo span renderer to do the coverage
+ * blitting. */
+struct pool;
+struct cell_list;
+
+static glitter_status_t
+blit_with_span_renderer(
+ struct cell_list *coverages,
+ cairo_span_renderer_t *span_renderer,
+ struct pool *span_pool,
+ int y,
+ int xmin,
+ int xmax);
+
+#define GLITTER_BLIT_COVERAGES_ARGS \
+ cairo_span_renderer_t *span_renderer, \
+ struct pool *span_pool
+
+#define GLITTER_BLIT_COVERAGES(cells, y, xmin, xmax) do { \
+ cairo_status_t status = blit_with_span_renderer (cells, \
+ span_renderer, \
+ span_pool, \
+ y, xmin, xmax); \
+ if (unlikely (status)) \
+ return status; \
+} while (0)
+
+/*-------------------------------------------------------------------------
+ * glitter-paths.h
+ */
+
+/* "Input scaled" numbers are fixed precision reals with multiplier
+ * 2**GLITTER_INPUT_BITS. Input coordinates are given to glitter as
+ * pixel scaled numbers. These get converted to the internal grid
+ * scaled numbers as soon as possible. Internal overflow is possible
+ * if GRID_X/Y inside glitter-paths.c is larger than
+ * 1<<GLITTER_INPUT_BITS. */
+#ifndef GLITTER_INPUT_BITS
+# define GLITTER_INPUT_BITS 8
+#endif
+#define GLITTER_INPUT_SCALE (1<<GLITTER_INPUT_BITS)
+typedef int glitter_input_scaled_t;
+
+#if !GLITTER_HAVE_STATUS_T
+typedef enum {
+ GLITTER_STATUS_SUCCESS = 0,
+ GLITTER_STATUS_NO_MEMORY
+} glitter_status_t;
+#endif
+
+#ifndef I
+# define I /*static*/
+#endif
+
+/* Opaque type for scan converting. */
+typedef struct glitter_scan_converter glitter_scan_converter_t;
+
+/* Reset a scan converter to accept polygon edges and set the clip box
+ * in pixels. Allocates O(ymax-ymin) bytes of memory. The clip box
+ * is set to integer pixel coordinates xmin <= x < xmax, ymin <= y <
+ * ymax. */
+I glitter_status_t
+glitter_scan_converter_reset(
+ glitter_scan_converter_t *converter,
+ int xmin, int ymin,
+ int xmax, int ymax);
+
+/* 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
+ * converter should be reset or destroyed. Dir must be +1 or -1,
+ * with the latter reversing the orientation of the edge. */
+I glitter_status_t
+glitter_scan_converter_add_edge(
+ glitter_scan_converter_t *converter,
+ glitter_input_scaled_t x1, glitter_input_scaled_t y1,
+ glitter_input_scaled_t x2, glitter_input_scaled_t y2,
+ int dir);
+
+/* Render the polygon in the scan converter to the given A8 format
+ * image raster. Only the pixels accessible as pixels[y*stride+x] for
+ * x,y inside the clip box are written to, where xmin <= x < xmax,
+ * ymin <= y < ymax. The image is assumed to be clear on input.
+ *
+ * If nonzero_fill is true then the interior of the polygon is
+ * computed with the non-zero fill rule. Otherwise the even-odd fill
+ * rule is used.
+ *
+ * The scan converter must be reset or destroyed after this call. */
+#ifndef GLITTER_BLIT_COVERAGES_ARGS
+# define GLITTER_BLIT_COVERAGES_ARGS unsigned char *raster_pixels, long raster_stride
+#endif
+I glitter_status_t
+glitter_scan_converter_render(
+ glitter_scan_converter_t *converter,
+ int nonzero_fill,
+ GLITTER_BLIT_COVERAGES_ARGS);
+
+/*-------------------------------------------------------------------------
+ * glitter-paths.c: Implementation internal types
+ */
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+
+/* All polygon coordinates are snapped onto a subsample grid. "Grid
+ * scaled" numbers are fixed precision reals with multiplier GRID_X or
+ * GRID_Y. */
+typedef int grid_scaled_t;
+typedef int grid_scaled_x_t;
+typedef int grid_scaled_y_t;
+
+/* Default x/y scale factors.
+ * You can either define GRID_X/Y_BITS to get a power-of-two scale
+ * or define GRID_X/Y separately. */
+#if !defined(GRID_X) && !defined(GRID_X_BITS)
+# define GRID_X_BITS 8
+#endif
+#if !defined(GRID_Y) && !defined(GRID_Y_BITS)
+# define GRID_Y 15
+#endif
+
+/* Use GRID_X/Y_BITS to define GRID_X/Y if they're available. */
+#ifdef GRID_X_BITS
+# define GRID_X (1 << GRID_X_BITS)
+#endif
+#ifdef GRID_Y_BITS
+# define GRID_Y (1 << GRID_Y_BITS)
+#endif
+
+/* The GRID_X_TO_INT_FRAC macro splits a grid scaled coordinate into
+ * integer and fractional parts. The integer part is floored. */
+#if defined(GRID_X_TO_INT_FRAC)
+ /* do nothing */
+#elif defined(GRID_X_BITS)
+# define GRID_X_TO_INT_FRAC(x, i, f) \
+ _GRID_TO_INT_FRAC_shift(x, i, f, GRID_X_BITS)
+#else
+# define GRID_X_TO_INT_FRAC(x, i, f) \
+ _GRID_TO_INT_FRAC_general(x, i, f, GRID_X)
+#endif
+
+#define _GRID_TO_INT_FRAC_general(t, i, f, m) do { \
+ (i) = (t) / (m); \
+ (f) = (t) % (m); \
+ if ((f) < 0) { \
+ --(i); \
+ (f) += (m); \
+ } \
+} while (0)
+
+#define _GRID_TO_INT_FRAC_shift(t, i, f, b) do { \
+ (f) = (t) & ((1 << (b)) - 1); \
+ (i) = (t) >> (b); \
+} while (0)
+
+/* A grid area is a real in [0,1] scaled by 2*GRID_X*GRID_Y. We want
+ * to be able to represent exactly areas of subpixel trapezoids whose
+ * vertices are given in grid scaled coordinates. The scale factor
+ * comes from needing to accurately represent the area 0.5*dx*dy of a
+ * triangle with base dx and height dy in grid scaled numbers. */
+typedef int grid_area_t;
+#define GRID_XY (2*GRID_X*GRID_Y) /* Unit area on the grid. */
+
+/* GRID_AREA_TO_ALPHA(area): map [0,GRID_XY] to [0,255]. */
+#if GRID_XY == 510
+# define GRID_AREA_TO_ALPHA(c) (((c)+1) >> 1)
+#elif GRID_XY == 255
+# define GRID_AREA_TO_ALPHA(c) (c)
+#elif GRID_XY == 64
+# define GRID_AREA_TO_ALPHA(c) (((c) << 2) | -(((c) & 0x40) >> 6))
+#elif GRID_XY == 128
+# define GRID_AREA_TO_ALPHA(c) ((((c) << 1) | -((c) >> 7)) & 255)
+#elif GRID_XY == 256
+# define GRID_AREA_TO_ALPHA(c) (((c) | -((c) >> 8)) & 255)
+#elif GRID_XY == 15
+# define GRID_AREA_TO_ALPHA(c) (((c) << 4) + (c))
+#elif GRID_XY == 2*256*15
+# define GRID_AREA_TO_ALPHA(c) (((c) + ((c)<<4)) >> 9)
+#else
+# define GRID_AREA_TO_ALPHA(c) ((c)*255 / GRID_XY) /* tweak me for rounding */
+#endif
+
+#define UNROLL3(x) x x x
+
+struct quorem {
+ int quo;
+ int rem;
+};
+
+/* Header for a chunk of memory in a memory pool. */
+struct _pool_chunk {
+ /* # bytes used in this chunk. */
+ size_t size;
+
+ /* # bytes total in this chunk */
+ size_t capacity;
+
+ /* Pointer to the previous chunk or %NULL if this is the sentinel
+ * chunk in the pool header. */
+ struct _pool_chunk *prev_chunk;
+
+ /* Actual data starts here. Well aligned for pointers. */
+ unsigned char data[0];
+};
+
+/* 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
+ * malloc needs to be called to allocate a first real chunk. */
+struct pool {
+ /* Chunk we're allocating from. */
+ struct _pool_chunk *current;
+
+ /* Free list of previously allocated chunks. All have >= default
+ * capacity. */
+ struct _pool_chunk *first_free;
+
+ /* The default capacity of a chunk. */
+ size_t default_capacity;
+
+ /* 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];
+};
+
+/* A polygon edge. */
+struct edge {
+ /* Next in y-bucket or active list. */
+ struct edge *next;
+
+ /* Current x coordinate while the edge is on the active
+ * list. Initialised to the x coordinate of the top of the
+ * edge. The quotient is in grid_scaled_x_t units and the
+ * remainder is mod dy in grid_scaled_y_t units.*/
+ struct quorem x;
+
+ /* Advance of the current x when moving down a subsample line. */
+ struct quorem dxdy;
+
+ /* Advance of the current x when moving down a full pixel
+ * row. Only initialised when the height of the edge is large
+ * enough that there's a chance the edge could be stepped by a
+ * 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;
+
+ /* Number of subsample rows remaining to scan convert of this
+ * edge. */
+ grid_scaled_y_t height_left;
+
+ /* Original sign of the edge: +1 for downwards, -1 for upwards
+ * edges. */
+ int dir;
+};
+
+/* Number of subsample rows per y-bucket. Must be GRID_Y. */
+#define EDGE_Y_BUCKET_HEIGHT GRID_Y
+
+#define EDGE_Y_BUCKET_INDEX(y, ymin) (((y) - (ymin))/EDGE_Y_BUCKET_HEIGHT)
+
+/* A collection of sorted and vertically clipped edges of the polygon.
+ * Edges are moved from the polygon to an active list while scan
+ * converting. */
+struct polygon {
+ /* The vertical clip extents. */
+ grid_scaled_y_t ymin, ymax;
+
+ /* Array of edges all starting in the same bucket. An edge is put
+ * into bucket EDGE_BUCKET_INDEX(edge->ytop, polygon->ymin) when
+ * it is added to the polygon. */
+ struct edge **y_buckets;
+
+ struct {
+ struct pool base[1];
+ struct edge embedded[32];
+ } edge_pool;
+};
+
+/* A cell records the effect on pixel coverage of polygon edges
+ * passing through a pixel. It contains two accumulators of pixel
+ * coverage.
+ *
+ * Consider the effects of a polygon edge on the coverage of a pixel
+ * it intersects and that of the following one. The coverage of the
+ * following pixel is the height of the edge multiplied by the width
+ * of the pixel, and the coverage of the pixel itself is the area of
+ * the trapezoid formed by the edge and the right side of the pixel.
+ *
+ * +-----------------------+-----------------------+
+ * | | |
+ * | | |
+ * |_______________________|_______________________|
+ * | \...................|.......................|\
+ * | \..................|.......................| |
+ * | \.................|.......................| |
+ * | \....covered.....|.......................| |
+ * | \....area.......|.......................| } covered height
+ * | \..............|.......................| |
+ * |uncovered\.............|.......................| |
+ * | area \............|.......................| |
+ * |___________\...........|.......................|/
+ * | | |
+ * | | |
+ * | | |
+ * +-----------------------+-----------------------+
+ *
+ * Since the coverage of the following pixel will always be a multiple
+ * of the width of the pixel, we can store the height of the covered
+ * area instead. The coverage of the pixel itself is the total
+ * coverage minus the area of the uncovered area to the left of the
+ * edge. As it's faster to compute the uncovered area we only store
+ * that and subtract it from the total coverage later when forming
+ * spans to blit.
+ *
+ * The heights and areas are signed, with left edges of the polygon
+ * having positive sign and right edges having negative sign. When
+ * two edges intersect they swap their left/rightness so their
+ * contribution above and below the intersection point must be
+ * computed separately. */
+struct cell {
+ struct cell *next;
+ int x;
+ grid_area_t uncovered_area;
+ grid_scaled_y_t covered_height;
+};
+
+/* A cell list represents the scan line sparsely as cells ordered by
+ * ascending x. It is geared towards scanning the cells in order
+ * using an internal cursor. */
+struct cell_list {
+ /* Points to the left-most cell in the scan line. */
+ struct cell *head;
+
+ /* Cursor state for iterating through the cell list. Points to
+ * a pointer to the current cell: either &cell_list->head or the next
+ * field of the previous cell. */
+ struct cell **cursor;
+
+ /* Cells in the cell list are owned by the cell list and are
+ * allocated from this pool. */
+ struct {
+ struct pool base[1];
+ struct cell embedded[32];
+ } cell_pool;
+};
+
+struct cell_pair {
+ struct cell *cell1;
+ struct cell *cell2;
+};
+
+/* The active list contains edges in the current scan line ordered by
+ * the x-coordinate of the intercept of the edge and the scan line. */
+struct active_list {
+ /* Leftmost edge on the current scan line. */
+ struct edge *head;
+
+ /* A lower bound on the height of the active edges is used to
+ * estimate how soon some active edge ends. We can't advance the
+ * scan conversion by a full pixel row if an edge ends somewhere
+ * within it. */
+ grid_scaled_y_t min_height;
+};
+
+struct glitter_scan_converter {
+ struct polygon polygon[1];
+ struct active_list active[1];
+ struct cell_list coverages[1];
+
+ /* Clip box. */
+ grid_scaled_x_t xmin, xmax;
+ 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 void
+_pool_chunk_init(
+ struct _pool_chunk *p,
+ struct _pool_chunk *prev_chunk,
+ size_t capacity)
+{
+ p->prev_chunk = prev_chunk;
+ p->size = 0;
+ p->capacity = capacity;
+}
+
+static struct _pool_chunk *
+_pool_chunk_create(
+ struct _pool_chunk *prev_chunk,
+ size_t size)
+{
+ struct _pool_chunk *p;
+ size_t size_with_head = size + sizeof(struct _pool_chunk);
+ if (size_with_head < size)
+ return NULL;
+ p = malloc(size_with_head);
+ if (p)
+ _pool_chunk_init(p, prev_chunk, size);
+ return p;
+}
+
+static void
+pool_init(
+ struct pool *pool,
+ size_t default_capacity,
+ size_t embedded_capacity)
+{
+ pool->current = pool->sentinel;
+ pool->first_free = NULL;
+ pool->default_capacity = default_capacity;
+ _pool_chunk_init(pool->sentinel, NULL, embedded_capacity);
+}
+
+static void
+pool_fini(struct pool *pool)
+{
+ struct _pool_chunk *p = pool->current;
+ do {
+ while (NULL != p) {
+ struct _pool_chunk *prev = p->prev_chunk;
+ if (p != pool->sentinel)
+ free(p);
+ p = prev;
+ }
+ p = pool->first_free;
+ pool->first_free = NULL;
+ } while (NULL != p);
+ pool_init(pool, 0, 0);
+}
+
+/* Satisfy an allocation by first allocating a new large enough chunk
+ * and adding it to the head of the pool's chunk list. This function
+ * is called as a fallback if pool_alloc() couldn't do a quick
+ * allocation from the current chunk in the pool. */
+static void *
+_pool_alloc_from_new_chunk(
+ struct pool *pool,
+ size_t size)
+{
+ struct _pool_chunk *chunk;
+ void *obj;
+ size_t capacity;
+
+ /* If the allocation is smaller than the default chunk size then
+ * try getting a chunk off the free list. Force alloc of a new
+ * chunk for large requests. */
+ capacity = size;
+ chunk = NULL;
+ if (size < pool->default_capacity) {
+ capacity = pool->default_capacity;
+ chunk = pool->first_free;
+ if (chunk) {
+ pool->first_free = chunk->prev_chunk;
+ _pool_chunk_init(chunk, pool->current, chunk->capacity);
+ }
+ }
+
+ if (NULL == chunk) {
+ chunk = _pool_chunk_create(
+ pool->current,
+ capacity);
+ if (NULL == chunk)
+ return NULL;
+ }
+ pool->current = chunk;
+
+ obj = &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
+ * allocated. Returns the address of a new memory area or %NULL on
+ * allocation failures. The pool retains ownership of the returned
+ * memory. */
+inline static void *
+pool_alloc(
+ struct pool *pool,
+ size_t size)
+{
+ struct _pool_chunk *chunk = pool->current;
+
+ if (size <= chunk->capacity - chunk->size) {
+ void *obj = &chunk->data[chunk->size];
+ chunk->size += size;
+ return obj;
+ }
+ else {
+ return _pool_alloc_from_new_chunk(pool, size);
+ }
+}
+
+/* Relinquish all pool_alloced memory back to the pool. */
+static void
+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) {
+ 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;
+}
+
+/* Rewinds the cell list's cursor to the beginning. After rewinding
+ * we're good to cell_list_find() the cell any x coordinate. */
+inline static void
+cell_list_rewind(struct cell_list *cells)
+{
+ cells->cursor = &cells->head;
+}
+
+/* Rewind the cell list if its cursor has been advanced past x. */
+inline static void
+cell_list_maybe_rewind(struct cell_list *cells, int x)
+{
+ struct cell *tail = *cells->cursor;
+ if (tail && tail->x > x) {
+ cell_list_rewind(cells);
+ }
+}
+
+static void
+cell_list_init(struct cell_list *cells)
+{
+ pool_init(cells->cell_pool.base,
+ 256*sizeof(struct cell),
+ sizeof(cells->cell_pool.embedded));
+ cells->head = NULL;
+ cell_list_rewind(cells);
+}
+
+static void
+cell_list_fini(struct cell_list *cells)
+{
+ pool_fini(cells->cell_pool.base);
+ cell_list_init(cells);
+}
+
+/* Empty the cell list. This is called at the start of every pixel
+ * row. */
+inline static void
+cell_list_reset(struct cell_list *cells)
+{
+ cell_list_rewind(cells);
+ cells->head = NULL;
+ pool_reset(cells->cell_pool.base);
+}
+
+/* Find a cell at the given x-coordinate. Returns %NULL if a new cell
+ * needed to be allocated but couldn't be. Cells must be found with
+ * non-decreasing x-coordinate until the cell list is rewound using
+ * cell_list_rewind(). Ownership of the returned cell is retained by
+ * the cell list. */
+inline static struct cell *
+cell_list_find(struct cell_list *cells, int x)
+{
+ struct cell **cursor = cells->cursor;
+ struct cell *tail;
+
+ while (1) {
+ UNROLL3({
+ tail = *cursor;
+ if (NULL == tail || tail->x >= x) {
+ break;
+ }
+ cursor = &tail->next;
+ });
+ }
+ cells->cursor = cursor;
+ if (tail && tail->x == x) {
+ return tail;
+ } else {
+ struct cell *cell = pool_alloc(
+ cells->cell_pool.base,
+ sizeof(struct cell));
+ if (NULL == cell)
+ return NULL;
+ *cursor = cell;
+ cell->next = tail;
+ cell->x = x;
+ cell->uncovered_area = 0;
+ cell->covered_height = 0;
+ return cell;
+ }
+}
+
+/* Find two cells at x1 and x2. This is exactly equivalent
+ * to
+ *
+ * pair.cell1 = cell_list_find(cells, x1);
+ * pair.cell2 = cell_list_find(cells, x2);
+ *
+ * except with less function call overhead. */
+inline static struct cell_pair
+cell_list_find2(struct cell_list *cells, int x1, int x2)
+{
+ struct cell_pair pair;
+ struct cell **cursor = cells->cursor;
+ struct cell *cell1;
+ struct cell *cell2;
+ struct cell *newcell;
+
+ /* Find first cell at x1. */
+ while (1) {
+ UNROLL3({
+ cell1 = *cursor;
+ if (NULL == cell1 || cell1->x > x1)
+ break;
+ if (cell1->x == x1)
+ goto found_first;
+ cursor = &cell1->next;
+ });
+ }
+
+ /* New first cell at x1. */
+ newcell = pool_alloc(
+ cells->cell_pool.base,
+ sizeof(struct cell));
+ if (NULL != newcell) {
+ *cursor = newcell;
+ newcell->next = cell1;
+ newcell->x = x1;
+ newcell->uncovered_area = 0;
+ newcell->covered_height = 0;
+ }
+ cell1 = newcell;
+ found_first:
+
+ /* Find second cell at x2. */
+ while (1) {
+ UNROLL3({
+ cell2 = *cursor;
+ if (NULL == cell2 || cell2->x > x2)
+ break;
+ if (cell2->x == x2)
+ goto found_second;
+ cursor = &cell2->next;
+ });
+ }
+
+ /* New second cell at x2. */
+ newcell = pool_alloc(
+ cells->cell_pool.base,
+ sizeof(struct cell));
+ if (NULL != newcell) {
+ *cursor = newcell;
+ newcell->next = cell2;
+ newcell->x = x2;
+ newcell->uncovered_area = 0;
+ newcell->covered_height = 0;
+ }
+ cell2 = newcell;
+ found_second:
+
+ cells->cursor = cursor;
+ pair.cell1 = cell1;
+ pair.cell2 = cell2;
+ return pair;
+}
+
+/* Add an unbounded subpixel span covering subpixels >= x to the
+ * coverage cells. */
+static glitter_status_t
+cell_list_add_unbounded_subspan(
+ struct cell_list *cells,
+ grid_scaled_x_t x)
+{
+ struct cell *cell;
+ int ix, fx;
+
+ GRID_X_TO_INT_FRAC(x, ix, fx);
+
+ cell = cell_list_find(cells, ix);
+ if (cell) {
+ cell->uncovered_area += 2*fx;
+ cell->covered_height++;
+ return GLITTER_STATUS_SUCCESS;
+ }
+ return GLITTER_STATUS_NO_MEMORY;
+}
+
+/* Add a subpixel span covering [x1, x2) to the coverage cells. */
+inline static glitter_status_t
+cell_list_add_subspan(
+ struct cell_list *cells,
+ grid_scaled_x_t x1,
+ grid_scaled_x_t x2)
+{
+ int ix1, fx1;
+ int ix2, fx2;
+
+ GRID_X_TO_INT_FRAC(x1, ix1, fx1);
+ GRID_X_TO_INT_FRAC(x2, ix2, fx2);
+
+ if (ix1 != ix2) {
+ struct cell_pair p;
+ p = cell_list_find2(cells, ix1, ix2);
+ if (p.cell1 && p.cell2) {
+ p.cell1->uncovered_area += 2*fx1;
+ ++p.cell1->covered_height;
+ p.cell2->uncovered_area -= 2*fx2;
+ --p.cell2->covered_height;
+ return GLITTER_STATUS_SUCCESS;
+ }
+ }
+ else {
+ struct cell *cell = cell_list_find(cells, ix1);
+ if (cell) {
+ cell->uncovered_area += 2*(fx1-fx2);
+ return GLITTER_STATUS_SUCCESS;
+ }
+ }
+ return GLITTER_STATUS_NO_MEMORY;
+}
+
+/* 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.
+ *
+ * This function is only called when we know that during this pixel row:
+ *
+ * 1) The relative order of all edges on the active list doesn't
+ * change. In particular, no edges intersect within this row to pixel
+ * precision.
+ *
+ * 2) No new edges start in this row.
+ *
+ * 3) No existing edges end mid-row.
+ *
+ * This function depends on being called with all edges from the
+ * active list in the order they appear on the list (i.e. with
+ * non-decreasing x-coordinate.) */
+static glitter_status_t
+cell_list_render_edge(
+ struct cell_list *cells,
+ struct edge *edge,
+ int sign)
+{
+ struct quorem x1 = edge->x;
+ struct quorem x2 = x1;
+ grid_scaled_y_t y1, y2, dy;
+ grid_scaled_x_t dx;
+ int ix1, ix2;
+ grid_scaled_x_t fx1, fx2;
+
+ x2.quo += edge->dxdy_full.quo;
+ x2.rem += edge->dxdy_full.rem;
+ if (x2.rem >= 0) {
+ ++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);
+
+ /* Edge is entirely within a column? */
+ if (ix1 == ix2) {
+ /* We always know that ix1 is >= the cell list cursor in this
+ * case due to the no-intersections precondition. */
+ struct cell *cell = cell_list_find(cells, ix1);
+ if (NULL == cell)
+ return GLITTER_STATUS_NO_MEMORY;
+ cell->covered_height += sign*GRID_Y;
+ cell->uncovered_area += sign*(fx1 + fx2)*GRID_Y;
+ return GLITTER_STATUS_SUCCESS;
+ }
+
+ /* 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;
+ }
+ 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);
+
+ /* When rendering a previous edge on the active list we may
+ * advance the cell list cursor past the leftmost pixel of the
+ * current edge even though the two edges don't intersect.
+ * e.g. consider two edges going down and rightwards:
+ *
+ * --\_+---\_+-----+-----+----
+ * \_ \_ | |
+ * | \_ | \_ | |
+ * | \_| \_| |
+ * | \_ \_ |
+ * ----+-----+-\---+-\---+----
+ *
+ * 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_find2(cells, ix1, ix1+1);
+ if (!pair.cell1 || !pair.cell2)
+ return GLITTER_STATUS_NO_MEMORY;
+
+ pair.cell1->uncovered_area += sign*y.quo*(GRID_X + fx1);
+ pair.cell1->covered_height += sign*y.quo;
+ y.quo += y1;
+
+ if (ix1+1 < ix2) {
+ struct quorem dydx_full = floored_divrem(GRID_X*dy, dx);
+ struct cell *cell = pair.cell2;
+
+ ++ix1;
+ do {
+ grid_scaled_y_t y_skip = dydx_full.quo;
+ y.rem += dydx_full.rem;
+ if (y.rem >= dx) {
+ ++y_skip;
+ y.rem -= dx;
+ }
+
+ y.quo += y_skip;
+
+ y_skip *= sign;
+ cell->uncovered_area += y_skip*GRID_X;
+ cell->covered_height += y_skip;
+
+ ++ix1;
+ cell = cell_list_find(cells, ix1);
+ if (NULL == cell)
+ return GLITTER_STATUS_NO_MEMORY;
+ } while (ix1 != ix2);
+
+ pair.cell2 = cell;
+ }
+ pair.cell2->uncovered_area += sign*(y2 - y.quo)*fx2;
+ pair.cell2->covered_height += sign*(y2 - y.quo);
+ }
+
+ return GLITTER_STATUS_SUCCESS;
+}
+
+static void
+polygon_init(struct polygon *polygon)
+{
+ polygon->ymin = polygon->ymax = 0;
+ polygon->y_buckets = NULL;
+ pool_init(polygon->edge_pool.base,
+ (8192 - sizeof(struct _pool_chunk))/sizeof(struct edge),
+ sizeof(polygon->edge_pool.embedded));
+}
+
+static void
+polygon_fini(struct polygon *polygon)
+{
+ free(polygon->y_buckets);
+ pool_fini(polygon->edge_pool.base);
+ polygon_init(polygon);
+}
+
+static void *
+realloc_and_clear(void *p, size_t a, size_t b)
+{
+ size_t total = a*b;
+ if (b && total / b != a)
+ return NULL;
+ p = realloc(p, total);
+ if (p)
+ memset(p, 0, total);
+ return p;
+}
+
+/* Empties the polygon of all edges. The polygon is then prepared to
+ * receive new edges and clip them to the vertical range
+ * [ymin,ymax). */
+static glitter_status_t
+polygon_reset(
+ struct polygon *polygon,
+ grid_scaled_y_t ymin,
+ grid_scaled_y_t ymax)
+{
+ void *p;
+ unsigned h = ymax - ymin;
+ unsigned num_buckets = EDGE_Y_BUCKET_INDEX(ymax + EDGE_Y_BUCKET_HEIGHT-1,
+ ymin);
+
+ pool_reset(polygon->edge_pool.base);
+
+ if (h > 0x7FFFFFFFU - EDGE_Y_BUCKET_HEIGHT)
+ goto bail_no_mem; /* even if you could, you wouldn't want to. */
+
+ if (num_buckets > 0) {
+ p = realloc_and_clear(
+ polygon->y_buckets,
+ num_buckets,
+ sizeof(struct edge*));
+ if (NULL == p)
+ goto bail_no_mem;
+ }
+ else {
+ free(polygon->y_buckets);
+ p = NULL;
+ }
+ polygon->y_buckets = p;
+
+ polygon->ymin = ymin;
+ polygon->ymax = ymax;
+ return GLITTER_STATUS_SUCCESS;
+
+ bail_no_mem:
+ free(polygon->y_buckets);
+ polygon->y_buckets = NULL;
+ polygon->ymin = 0;
+ polygon->ymax = 0;
+ return GLITTER_STATUS_NO_MEMORY;
+}
+
+static void
+_polygon_insert_edge_into_its_y_bucket(
+ struct polygon *polygon,
+ struct edge *e)
+{
+ unsigned ix = EDGE_Y_BUCKET_INDEX(e->ytop, polygon->ymin);
+ struct edge **ptail = &polygon->y_buckets[ix];
+ e->next = *ptail;
+ *ptail = e;
+}
+
+inline static glitter_status_t
+polygon_add_edge(
+ struct polygon *polygon,
+ int x0, int y0,
+ int x1, int y1,
+ int dir)
+{
+ 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 (y0 == y1)
+ return GLITTER_STATUS_SUCCESS;
+
+ if (y0 > y1) {
+ int tmp;
+ tmp = x0; x0 = x1; x1 = tmp;
+ tmp = y0; y0 = y1; y1 = tmp;
+ dir = -dir;
+ }
+
+ if (y0 >= ymax || y1 <= ymin)
+ return GLITTER_STATUS_SUCCESS;
+
+ e = pool_alloc(polygon->edge_pool.base,
+ sizeof(struct edge));
+ if (NULL == e)
+ return GLITTER_STATUS_NO_MEMORY;
+
+ dx = x1 - x0;
+ dy = y1 - y0;
+ e->dy = dy;
+ e->dxdy = floored_divrem(dx, dy);
+
+ if (ymin <= y0) {
+ ytop = y0;
+ e->x.quo = x0;
+ e->x.rem = 0;
+ }
+ else {
+ ytop = ymin;
+ e->x = floored_muldivrem(ymin - y0, dx, dy);
+ e->x.quo += x0;
+ }
+
+ e->dir = dir;
+ e->ytop = ytop;
+ ybot = y1 < ymax ? y1 : ymax;
+ e->height_left = ybot - ytop;
+
+ 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. */
+ return GLITTER_STATUS_SUCCESS;
+}
+
+static void
+active_list_reset(
+ struct active_list *active)
+{
+ active->head = NULL;
+ active->min_height = 0;
+}
+
+static void
+active_list_init(struct active_list *active)
+{
+ active_list_reset(active);
+}
+
+static void
+active_list_fini(
+ struct active_list *active)
+{
+ active_list_reset(active);
+}
+
+/* Merge the edges in an unsorted list of edges into a sorted
+ * list. The sort order is edges ascending by edge->x.quo. Returns
+ * the new head of the sorted list. */
+static struct edge *
+merge_unsorted_edges(struct edge *sorted_head, struct edge *unsorted_head)
+{
+ struct edge *head = unsorted_head;
+ struct edge **cursor = &sorted_head;
+ int x;
+
+ while (NULL != head) {
+ struct edge *prev = *cursor;
+ struct edge *next = head->next;
+ x = head->x.quo;
+
+ if (NULL == prev || x < prev->x.quo) {
+ cursor = &sorted_head;
+ }
+
+ while (1) {
+ UNROLL3({
+ prev = *cursor;
+ if (NULL == prev || prev->x.quo >= x)
+ break;
+ cursor = &prev->next;
+ });
+ }
+
+ head->next = *cursor;
+ *cursor = head;
+
+ head = next;
+ }
+ return sorted_head;
+}
+
+/* Test if the edges on the active list can be safely advanced by a
+ * full row without intersections or any edges ending. */
+inline static int
+active_list_can_step_full_row(
+ struct active_list *active)
+{
+ /* Recomputes the minimum height of all edges on the active
+ * list if we have been dropping edges. */
+ if (active->min_height <= 0) {
+ struct edge *e = active->head;
+ int min_height = INT_MAX;
+
+ while (NULL != e) {
+ if (e->height_left < min_height)
+ min_height = e->height_left;
+ e = e->next;
+ }
+
+ active->min_height = min_height;
+ }
+
+ /* Check for intersections only if no edges end during the next
+ * row. */
+ if (active->min_height >= GRID_Y) {
+ grid_scaled_x_t prev_x = INT_MIN;
+ struct edge *e = active->head;
+ while (NULL != e) {
+ 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.quo <= prev_x)
+ return 0;
+ prev_x = x.quo;
+ e = e->next;
+ }
+ return 1;
+ }
+ return 0;
+}
+
+/* Merges edges on the given subpixel row from the polygon to the
+ * active_list. */
+inline static void
+active_list_merge_edges_from_polygon(
+ struct active_list *active,
+ grid_scaled_y_t y,
+ struct polygon *polygon)
+{
+ /* Split off the edges on the current subrow and merge them into
+ * the active list. */
+ unsigned ix = EDGE_Y_BUCKET_INDEX(y, polygon->ymin);
+ int min_height = active->min_height;
+ struct edge *subrow_edges = NULL;
+ struct edge **ptail = &polygon->y_buckets[ix];
+
+ while (1) {
+ struct edge *tail = *ptail;
+ if (NULL == tail) break;
+
+ if (y == tail->ytop) {
+ *ptail = tail->next;
+ tail->next = subrow_edges;
+ subrow_edges = tail;
+ if (tail->height_left < min_height)
+ min_height = tail->height_left;
+ }
+ else {
+ ptail = &tail->next;
+ }
+ }
+ active->head = merge_unsorted_edges(active->head, subrow_edges);
+ active->min_height = min_height;
+}
+
+/* Advance the edges on the active list by one subsample row by
+ * updating their x positions. Drop edges from the list that end. */
+inline static void
+active_list_substep_edges(
+ struct active_list *active)
+{
+ struct edge **cursor = &active->head;
+ grid_scaled_x_t prev_x = INT_MIN;
+ struct edge *unsorted = NULL;
+
+ while (1) {
+ struct edge *edge;
+
+ UNROLL3({
+ edge = *cursor;
+ if (NULL == edge)
+ break;
+
+ if (0 != --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;
+ }
+
+ if (edge->x.quo < prev_x) {
+ *cursor = edge->next;
+ edge->next = unsorted;
+ unsorted = edge;
+ } else {
+ prev_x = edge->x.quo;
+ cursor = &edge->next;
+ }
+
+ } else {
+ *cursor = edge->next;
+ }
+ });
+ }
+
+ if (unsorted)
+ active->head = merge_unsorted_edges(active->head, unsorted);
+}
+
+inline static glitter_status_t
+apply_nonzero_fill_rule_for_subrow(
+ struct active_list *active,
+ struct cell_list *coverages)
+{
+ struct edge *edge = active->head;
+ int winding = 0;
+ int xstart;
+ int xend;
+ int status;
+
+ cell_list_rewind(coverages);
+
+ while (NULL != edge) {
+ xstart = edge->x.quo;
+ winding = edge->dir;
+ while (1) {
+ edge = edge->next;
+ if (NULL == edge) {
+ return cell_list_add_unbounded_subspan(
+ coverages, xstart);
+ }
+ winding += edge->dir;
+ if (0 == winding)
+ break;
+ }
+
+ xend = edge->x.quo;
+ status = cell_list_add_subspan(coverages, xstart, xend);
+ if (status)
+ return status;
+
+ edge = edge->next;
+ }
+
+ return GLITTER_STATUS_SUCCESS;
+}
+
+static glitter_status_t
+apply_evenodd_fill_rule_for_subrow(
+ struct active_list *active,
+ struct cell_list *coverages)
+{
+ struct edge *edge = active->head;
+ int xstart;
+ int xend;
+ int status;
+
+ cell_list_rewind(coverages);
+
+ while (NULL != edge) {
+ xstart = edge->x.quo;
+
+ edge = edge->next;
+ if (NULL == edge) {
+ return cell_list_add_unbounded_subspan(
+ coverages, xstart);
+ }
+
+ xend = edge->x.quo;
+ status = cell_list_add_subspan(coverages, xstart, xend);
+ if (status)
+ return status;
+
+ edge = edge->next;
+ }
+
+ return GLITTER_STATUS_SUCCESS;
+}
+
+static glitter_status_t
+apply_nonzero_fill_rule_and_step_edges(
+ struct active_list *active,
+ struct cell_list *coverages)
+{
+ struct edge **cursor = &active->head;
+ struct edge *left_edge;
+ int status;
+
+ left_edge = *cursor;
+ while (NULL != left_edge) {
+ struct edge *right_edge;
+ int winding = left_edge->dir;
+
+ left_edge->height_left -= GRID_Y;
+ if (left_edge->height_left) {
+ cursor = &left_edge->next;
+ }
+ else {
+ *cursor = left_edge->next;
+ }
+
+ while (1) {
+ right_edge = *cursor;
+
+ if (NULL == right_edge) {
+ return cell_list_render_edge(
+ coverages, left_edge, +1);
+ }
+
+ right_edge->height_left -= GRID_Y;
+ if (right_edge->height_left) {
+ cursor = &right_edge->next;
+ }
+ else {
+ *cursor = right_edge->next;
+ }
+
+ winding += right_edge->dir;
+ if (0 == winding)
+ break;
+
+ right_edge->x.quo += right_edge->dxdy_full.quo;
+ right_edge->x.rem += right_edge->dxdy_full.rem;
+ if (right_edge->x.rem >= 0) {
+ ++right_edge->x.quo;
+ right_edge->x.rem -= right_edge->dy;
+ }
+ }
+
+ status = cell_list_render_edge(
+ coverages, left_edge, +1);
+ if (status)
+ return status;
+ status = cell_list_render_edge(
+ coverages, right_edge, -1);
+ if (status)
+ return status;
+
+ left_edge = *cursor;
+ }
+
+ return GLITTER_STATUS_SUCCESS;
+}
+
+static glitter_status_t
+apply_evenodd_fill_rule_and_step_edges(
+ struct active_list *active,
+ struct cell_list *coverages)
+{
+ struct edge **cursor = &active->head;
+ struct edge *left_edge;
+ int status;
+
+ left_edge = *cursor;
+ while (NULL != left_edge) {
+ struct edge *right_edge;
+
+ left_edge->height_left -= GRID_Y;
+ if (left_edge->height_left) {
+ cursor = &left_edge->next;
+ }
+ else {
+ *cursor = left_edge->next;
+ }
+
+ right_edge = *cursor;
+
+ if (NULL == right_edge) {
+ return cell_list_render_edge(
+ coverages, left_edge, +1);
+ }
+
+ right_edge->height_left -= GRID_Y;
+ if (right_edge->height_left) {
+ cursor = &right_edge->next;
+ }
+ else {
+ *cursor = right_edge->next;
+ }
+
+ status = cell_list_render_edge(
+ coverages, left_edge, +1);
+ if (status)
+ return status;
+ status = cell_list_render_edge(
+ coverages, right_edge, -1);
+ if (status)
+ return status;
+
+ left_edge = *cursor;
+ }
+
+ return GLITTER_STATUS_SUCCESS;
+}
+
+/* If the user hasn't configured a coverage blitter, use a default one
+ * that blits spans directly to an A8 raster. */
+#ifndef GLITTER_BLIT_COVERAGES
+
+inline static void
+blit_span(
+ unsigned char *row_pixels,
+ int x, unsigned len,
+ grid_area_t coverage)
+{
+ int alpha = GRID_AREA_TO_ALPHA(coverage);
+ if (1 == len) {
+ row_pixels[x] = alpha;
+ }
+ else {
+ memset(row_pixels + x, alpha, len);
+ }
+}
+
+#define GLITTER_BLIT_COVERAGES(coverages, y, xmin, xmax) \
+ blit_cells(coverages, raster_pixels + (y)*raster_stride, xmin, xmax)
+
+static void
+blit_cells(
+ struct cell_list *cells,
+ unsigned char *row_pixels,
+ int xmin, int xmax)
+{
+ struct cell *cell = cells->head;
+ int prev_x = xmin;
+ int coverage = 0;
+ if (NULL == cell)
+ return;
+
+ while (NULL != cell && cell->x < xmin) {
+ coverage += cell->covered_height;
+ cell = cell->next;
+ }
+ coverage *= GRID_X*2;
+
+ for (; NULL != cell; cell = cell->next) {
+ int x = cell->x;
+ int area;
+ if (x >= xmax)
+ break;
+ if (x > prev_x && 0 != coverage) {
+ blit_span(row_pixels, prev_x, x - prev_x, coverage);
+ }
+
+ coverage += cell->covered_height * GRID_X*2;
+ area = coverage - cell->uncovered_area;
+ if (area) {
+ blit_span(row_pixels, x, 1, area);
+ }
+ prev_x = x+1;
+ }
+
+ if (0 != coverage && prev_x < xmax) {
+ blit_span(row_pixels, prev_x, xmax - prev_x, coverage);
+ }
+}
+#endif /* GLITTER_BLIT_COVERAGES */
+
+static void
+_glitter_scan_converter_init(glitter_scan_converter_t *converter)
+{
+ polygon_init(converter->polygon);
+ active_list_init(converter->active);
+ cell_list_init(converter->coverages);
+ converter->xmin=0;
+ converter->ymin=0;
+ converter->xmax=0;
+ converter->ymax=0;
+}
+
+static void
+_glitter_scan_converter_fini(glitter_scan_converter_t *converter)
+{
+ polygon_fini(converter->polygon);
+ active_list_fini(converter->active);
+ cell_list_fini(converter->coverages);
+ converter->xmin=0;
+ converter->ymin=0;
+ converter->xmax=0;
+ converter->ymax=0;
+}
+
+static grid_scaled_t
+int_to_grid_scaled(int i, int scale)
+{
+ /* Clamp to max/min representable scaled number. */
+ if (i >= 0) {
+ if (i >= INT_MAX/scale)
+ i = INT_MAX/scale;
+ }
+ else {
+ if (i <= INT_MIN/scale)
+ i = INT_MIN/scale;
+ }
+ return i*scale;
+}
+
+#define int_to_grid_scaled_x(x) int_to_grid_scaled((x), GRID_X)
+#define int_to_grid_scaled_y(x) int_to_grid_scaled((x), GRID_Y)
+
+I glitter_status_t
+glitter_scan_converter_reset(
+ glitter_scan_converter_t *converter,
+ int xmin, int ymin,
+ int xmax, int ymax)
+{
+ glitter_status_t status;
+
+ converter->xmin = 0; converter->xmax = 0;
+ converter->ymin = 0; converter->ymax = 0;
+
+ xmin = int_to_grid_scaled_x(xmin);
+ ymin = int_to_grid_scaled_y(ymin);
+ xmax = int_to_grid_scaled_x(xmax);
+ ymax = int_to_grid_scaled_y(ymax);
+
+ active_list_reset(converter->active);
+ cell_list_reset(converter->coverages);
+ status = polygon_reset(converter->polygon, ymin, ymax);
+ if (status)
+ return status;
+
+ converter->xmin = xmin;
+ converter->xmax = xmax;
+ converter->ymin = ymin;
+ converter->ymax = ymax;
+ return GLITTER_STATUS_SUCCESS;
+}
+
+/* INPUT_TO_GRID_X/Y (in_coord, out_grid_scaled, grid_scale)
+ * These macros convert an input coordinate in the client's
+ * device space to the rasterisation grid.
+ */
+/* Gah.. this bit of ugly defines INPUT_TO_GRID_X/Y so as to use
+ * shifts if possible, and something saneish if not.
+ */
+#if !defined(INPUT_TO_GRID_Y) && defined(GRID_Y_BITS) && GRID_Y_BITS <= GLITTER_INPUT_BITS
+# define INPUT_TO_GRID_Y(in, out) (out) = (in) >> (GLITTER_INPUT_BITS - GRID_Y_BITS)
+#else
+# define INPUT_TO_GRID_Y(in, out) INPUT_TO_GRID_general(in, out, GRID_Y)
+#endif
+
+#if !defined(INPUT_TO_GRID_X) && defined(GRID_X_BITS) && GRID_X_BITS <= GLITTER_INPUT_BITS
+# define INPUT_TO_GRID_X(in, out) (out) = (in) >> (GLITTER_INPUT_BITS - GRID_X_BITS)
+#else
+# define INPUT_TO_GRID_X(in, out) INPUT_TO_GRID_general(in, out, GRID_X)
+#endif
+
+#define INPUT_TO_GRID_general(in, out, grid_scale) do { \
+ long long tmp__ = (long long)(grid_scale) * (in); \
+ tmp__ >>= GLITTER_INPUT_BITS; \
+ (out) = tmp__; \
+} while (0)
+
+I glitter_status_t
+glitter_scan_converter_add_edge(
+ glitter_scan_converter_t *converter,
+ glitter_input_scaled_t x1, glitter_input_scaled_t y1,
+ glitter_input_scaled_t x2, glitter_input_scaled_t y2,
+ int dir)
+{
+ /* XXX: possible overflows if GRID_X/Y > 2**GLITTER_INPUT_BITS */
+ grid_scaled_y_t sx1, sy1;
+ grid_scaled_y_t sx2, sy2;
+
+ INPUT_TO_GRID_Y(y1, sy1);
+ INPUT_TO_GRID_Y(y2, sy2);
+ if (sy1 == sy2)
+ return GLITTER_STATUS_SUCCESS;
+
+ INPUT_TO_GRID_X(x1, sx1);
+ INPUT_TO_GRID_X(x2, sx2);
+
+ return polygon_add_edge(
+ converter->polygon, sx1, sy1, sx2, sy2, dir);
+}
+
+#ifndef GLITTER_BLIT_COVERAGES_BEGIN
+# define GLITTER_BLIT_COVERAGES_BEGIN
+#endif
+
+#ifndef GLITTER_BLIT_COVERAGES_END
+# define GLITTER_BLIT_COVERAGES_END
+#endif
+
+#ifndef GLITTER_BLIT_COVERAGES_EMPTY
+# define GLITTER_BLIT_COVERAGES_EMPTY(y, xmin, xmax)
+#endif
+
+I glitter_status_t
+glitter_scan_converter_render(
+ glitter_scan_converter_t *converter,
+ int nonzero_fill,
+ GLITTER_BLIT_COVERAGES_ARGS)
+{
+ int i;
+ int ymax_i = converter->ymax / GRID_Y;
+ int ymin_i = converter->ymin / GRID_Y;
+ int xmin_i, xmax_i;
+ int h = ymax_i - ymin_i;
+ struct polygon *polygon = converter->polygon;
+ struct cell_list *coverages = converter->coverages;
+ struct active_list *active = converter->active;
+
+ xmin_i = converter->xmin / GRID_X;
+ xmax_i = converter->xmax / GRID_X;
+ if (xmin_i >= xmax_i)
+ return GLITTER_STATUS_SUCCESS;
+
+ /* Let the coverage blitter initialise itself. */
+ GLITTER_BLIT_COVERAGES_BEGIN;
+
+ /* Render each pixel row. */
+ for (i=0; i<h; i++) {
+ int do_full_step = 0;
+ glitter_status_t status = 0;
+
+ /* Determine if we can ignore this row or use the full pixel
+ * stepper. */
+ if (GRID_Y == EDGE_Y_BUCKET_HEIGHT
+ && !polygon->y_buckets[i])
+ {
+ if (!active->head) {
+ GLITTER_BLIT_COVERAGES_EMPTY(i+ymin_i, xmin_i, xmax_i);
+ continue;
+ }
+ do_full_step = active_list_can_step_full_row(active);
+ }
+
+ cell_list_reset(coverages);
+
+ if (do_full_step) {
+ /* Step by a full pixel row's worth. */
+ if (nonzero_fill) {
+ status = apply_nonzero_fill_rule_and_step_edges(
+ active, coverages);
+ }
+ else {
+ status = apply_evenodd_fill_rule_and_step_edges(
+ active, coverages);
+ }
+ }
+ else {
+ /* Subsample this row. */
+ grid_scaled_y_t suby;
+ for (suby = 0; suby < GRID_Y; suby++) {
+ grid_scaled_y_t y = (i+ymin_i)*GRID_Y + suby;
+
+ active_list_merge_edges_from_polygon(
+ active, y, polygon);
+
+ if (nonzero_fill)
+ status |= apply_nonzero_fill_rule_for_subrow(
+ active, coverages);
+ else
+ status |= apply_evenodd_fill_rule_for_subrow(
+ active, coverages);
+
+ active_list_substep_edges(active);
+ }
+ }
+
+ if (status)
+ return status;
+
+ GLITTER_BLIT_COVERAGES(coverages, i+ymin_i, xmin_i, xmax_i);
+
+ if (!active->head) {
+ active->min_height = INT_MAX;
+ }
+ else {
+ active->min_height -= GRID_Y;
+ }
+ }
+
+ /* Clean up the coverage blitter. */
+ GLITTER_BLIT_COVERAGES_END;
+
+ return GLITTER_STATUS_SUCCESS;
+}
+
+/*-------------------------------------------------------------------------
+ * cairo specific implementation: the coverage blitter and
+ * scan converter subclass. */
+
+static glitter_status_t
+blit_with_span_renderer(
+ struct cell_list *cells,
+ cairo_span_renderer_t *renderer,
+ struct pool *span_pool,
+ int y,
+ int xmin,
+ int xmax)
+{
+ struct cell *cell = cells->head;
+ int prev_x = xmin;
+ int cover = 0;
+ cairo_half_open_span_t *spans;
+ unsigned num_spans;
+ if (cell == NULL)
+ return CAIRO_STATUS_SUCCESS;
+
+ /* Skip cells to the left of the clip region. */
+ while (cell != NULL && cell->x < xmin) {
+ cover += cell->covered_height;
+ cell = cell->next;
+ }
+ cover *= GRID_X*2;
+
+ /* Count number of cells remaining. */
+ {
+ struct cell *next = cell;
+ num_spans = 0;
+ while (next) {
+ next = next->next;
+ ++num_spans;
+ }
+ num_spans = 2*num_spans + 1;
+ }
+
+ /* Allocate enough spans for the row. */
+ pool_reset (span_pool);
+ spans = pool_alloc (span_pool, sizeof(spans[0])*num_spans);
+ if (spans == NULL)
+ return GLITTER_STATUS_NO_MEMORY;
+
+ num_spans = 0;
+
+ /* Form the spans from the coverages and areas. */
+ for (; cell != NULL; cell = cell->next) {
+ int x = cell->x;
+ int area;
+ if (x >= xmax)
+ break;
+
+ if (x > prev_x) {
+ spans[num_spans].x = prev_x;
+ spans[num_spans].coverage = GRID_AREA_TO_ALPHA (cover);
+ ++num_spans;
+ }
+
+ cover += cell->covered_height*GRID_X*2;
+ area = cover - cell->uncovered_area;
+
+ spans[num_spans].x = x;
+ spans[num_spans].coverage = GRID_AREA_TO_ALPHA (area);
+ ++num_spans;
+
+ prev_x = x+1;
+ }
+
+ if (prev_x < xmax) {
+ spans[num_spans].x = prev_x;
+ spans[num_spans].coverage = GRID_AREA_TO_ALPHA (cover);
+ ++num_spans;
+ }
+
+ /* Dump them into the renderer. */
+ return renderer->render_row (renderer, y, spans, num_spans);
+}
+
+struct _cairo_tor_scan_converter {
+ cairo_scan_converter_t base;
+ glitter_scan_converter_t converter[1];
+ cairo_fill_rule_t fill_rule;
+
+ struct {
+ struct pool base[1];
+ cairo_half_open_span_t embedded[32];
+ } span_pool;
+};
+
+typedef struct _cairo_tor_scan_converter cairo_tor_scan_converter_t;
+
+static void
+_cairo_tor_scan_converter_destroy(void *abstract_converter)
+{
+ cairo_tor_scan_converter_t *self = abstract_converter;
+ if (self == NULL) {
+ return;
+ }
+ _glitter_scan_converter_fini (self->converter);
+ pool_fini (self->span_pool.base);
+ free(self);
+}
+
+static cairo_status_t
+_cairo_tor_scan_converter_add_edge(
+ void *abstract_converter,
+ cairo_fixed_t x1,
+ cairo_fixed_t y1,
+ cairo_fixed_t x2,
+ cairo_fixed_t y2)
+{
+ cairo_tor_scan_converter_t *self = abstract_converter;
+ cairo_status_t status;
+ status = glitter_scan_converter_add_edge (
+ self->converter,
+ x1, y1, x2, y2, +1);
+ if (status) {
+ return _cairo_scan_converter_set_error (self,
+ _cairo_error (status));
+ }
+ return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_status_t
+_cairo_tor_scan_converter_generate(
+ void *abstract_converter,
+ cairo_span_renderer_t *renderer)
+{
+ cairo_tor_scan_converter_t *self = abstract_converter;
+ cairo_status_t status = glitter_scan_converter_render (
+ self->converter,
+ self->fill_rule == CAIRO_FILL_RULE_WINDING,
+ renderer,
+ self->span_pool.base);
+ if (status) {
+ return _cairo_scan_converter_set_error (self,
+ _cairo_error (status));
+ }
+ return CAIRO_STATUS_SUCCESS;
+}
+
+cairo_scan_converter_t *
+_cairo_tor_scan_converter_create(
+ int xmin,
+ int ymin,
+ int xmax,
+ int ymax,
+ cairo_fill_rule_t fill_rule)
+{
+ cairo_status_t status;
+ cairo_tor_scan_converter_t *self =
+ calloc (1, sizeof(struct _cairo_tor_scan_converter));
+ if (self == NULL)
+ goto bail_nomem;
+
+ self->base.destroy = &_cairo_tor_scan_converter_destroy;
+ self->base.add_edge = &_cairo_tor_scan_converter_add_edge;
+ self->base.generate = &_cairo_tor_scan_converter_generate;
+
+ pool_init (self->span_pool.base,
+ 250 * sizeof(self->span_pool.embedded[0]),
+ sizeof(self->span_pool.embedded));
+
+ _glitter_scan_converter_init (self->converter);
+ status = glitter_scan_converter_reset (
+ self->converter, xmin, ymin, xmax, ymax);
+ if (status != CAIRO_STATUS_SUCCESS)
+ goto bail;
+
+ self->fill_rule = fill_rule;
+
+ return &self->base;
+
+ bail:
+ self->base.destroy(&self->base);
+ bail_nomem:
+ return _cairo_scan_converter_create_in_error (CAIRO_STATUS_NO_MEMORY);
+}
diff --git a/src/cairo-traps.c b/src/cairo-traps.c
index 5cf13d9c..2494696c 100644
--- a/src/cairo-traps.c
+++ b/src/cairo-traps.c
@@ -140,7 +140,7 @@ _cairo_traps_grow (cairo_traps_t *traps)
new_size, sizeof (cairo_trapezoid_t));
}
- if (new_traps == NULL) {
+ if (unlikely (new_traps == NULL)) {
traps->status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
return FALSE;
}
@@ -690,7 +690,7 @@ _cairo_traps_extract_region (const cairo_traps_t *traps,
if (traps->num_traps > ARRAY_LENGTH (stack_boxes)) {
boxes = _cairo_malloc_ab (traps->num_traps, sizeof (cairo_box_int_t));
- if (boxes == NULL)
+ if (unlikely (boxes == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
@@ -721,7 +721,7 @@ _cairo_traps_extract_region (const cairo_traps_t *traps,
if (boxes != stack_boxes)
free (boxes);
- if (status)
+ if (unlikely (status))
_cairo_region_fini (region);
return status;
@@ -760,15 +760,15 @@ _cairo_traps_path (const cairo_traps_t *traps,
_sanitize_trap (&trap);
status = _cairo_path_fixed_move_to (path, trap.left.p1.x, trap.top);
- if (status) return status;
+ if (unlikely (status)) return status;
status = _cairo_path_fixed_line_to (path, trap.right.p1.x, trap.top);
- if (status) return status;
+ if (unlikely (status)) return status;
status = _cairo_path_fixed_line_to (path, trap.right.p2.x, trap.bottom);
- if (status) return status;
+ if (unlikely (status)) return status;
status = _cairo_path_fixed_line_to (path, trap.left.p2.x, trap.bottom);
- if (status) return status;
+ if (unlikely (status)) return status;
status = _cairo_path_fixed_close_path (path);
- if (status) return status;
+ if (unlikely (status)) return status;
}
return CAIRO_STATUS_SUCCESS;
diff --git a/src/cairo-truetype-subset.c b/src/cairo-truetype-subset.c
index e8be4b44..4662eaa3 100644
--- a/src/cairo-truetype-subset.c
+++ b/src/cairo-truetype-subset.c
@@ -146,7 +146,7 @@ _cairo_truetype_font_create (cairo_scaled_font_subset_t *scaled_font_subset,
TT_TAG_head, 0,
(unsigned char *) &head,
&size);
- if (status)
+ if (unlikely (status))
return status;
size = sizeof (tt_maxp_t);
@@ -154,7 +154,7 @@ _cairo_truetype_font_create (cairo_scaled_font_subset_t *scaled_font_subset,
TT_TAG_maxp, 0,
(unsigned char *) &maxp,
&size);
- if (status)
+ if (unlikely (status))
return status;
size = sizeof (tt_hhea_t);
@@ -162,7 +162,7 @@ _cairo_truetype_font_create (cairo_scaled_font_subset_t *scaled_font_subset,
TT_TAG_hhea, 0,
(unsigned char *) &hhea,
&size);
- if (status)
+ if (unlikely (status))
return status;
size = 0;
@@ -170,22 +170,22 @@ _cairo_truetype_font_create (cairo_scaled_font_subset_t *scaled_font_subset,
TT_TAG_name, 0,
NULL,
&size);
- if (status)
+ if (unlikely (status))
return status;
- name = malloc(size);
- if (name == NULL)
+ name = malloc (size);
+ if (unlikely (name == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
status = backend->load_truetype_table (scaled_font_subset->scaled_font,
TT_TAG_name, 0,
(unsigned char *) name,
&size);
- if (status)
+ if (unlikely (status))
goto fail0;
font = malloc (sizeof (cairo_truetype_font_t));
- if (font == NULL) {
+ if (unlikely (font == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail0;
}
@@ -198,17 +198,17 @@ _cairo_truetype_font_create (cairo_scaled_font_subset_t *scaled_font_subset,
font->last_boundary = 0;
_cairo_array_init (&font->output, sizeof (char));
status = _cairo_array_grow_by (&font->output, 4096);
- if (status)
+ if (unlikely (status))
goto fail1;
font->glyphs = calloc (font->num_glyphs_in_face + 1, sizeof (subset_glyph_t));
- if (font->glyphs == NULL) {
+ if (unlikely (font->glyphs == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail1;
}
font->parent_to_subset = calloc (font->num_glyphs_in_face, sizeof (int));
- if (font->parent_to_subset == NULL) {
+ if (unlikely (font->parent_to_subset == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail2;
}
@@ -252,7 +252,7 @@ _cairo_truetype_font_create (cairo_scaled_font_subset_t *scaled_font_subset,
if (font->base.base_font == NULL) {
font->base.base_font = malloc (30);
- if (font->base.base_font == NULL) {
+ if (unlikely (font->base.base_font == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail3;
}
@@ -270,14 +270,14 @@ _cairo_truetype_font_create (cairo_scaled_font_subset_t *scaled_font_subset,
font->base.base_font[i] = '\0';
font->base.widths = calloc (font->num_glyphs_in_face, sizeof (int));
- if (font->base.widths == NULL) {
+ if (unlikely (font->base.widths == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail4;
}
_cairo_array_init (&font->string_offsets, sizeof (unsigned long));
status = _cairo_array_grow_by (&font->string_offsets, 10);
- if (status)
+ if (unlikely (status))
goto fail5;
font->status = CAIRO_STATUS_SUCCESS;
@@ -328,7 +328,7 @@ cairo_truetype_font_allocate_write_buffer (cairo_truetype_font_t *font,
return font->status;
status = _cairo_array_allocate (&font->output, length, (void **) buffer);
- if (status)
+ if (unlikely (status))
return _cairo_truetype_font_set_error (font, status);
return CAIRO_STATUS_SUCCESS;
@@ -345,7 +345,7 @@ cairo_truetype_font_write (cairo_truetype_font_t *font,
return;
status = _cairo_array_append_multiple (&font->output, data, length);
- if (status)
+ if (unlikely (status))
status = _cairo_truetype_font_set_error (font, status);
}
@@ -391,7 +391,7 @@ cairo_truetype_font_align_output (cairo_truetype_font_t *font,
status = cairo_truetype_font_allocate_write_buffer (font, pad,
&padding);
- if (status)
+ if (unlikely (status))
return status;
memset (padding, 0, pad);
@@ -413,7 +413,7 @@ cairo_truetype_font_check_boundary (cairo_truetype_font_t *font,
{
status = _cairo_array_append (&font->string_offsets,
&font->last_boundary);
- if (status)
+ if (unlikely (status))
return _cairo_truetype_font_set_error (font, status);
font->last_offset = font->last_boundary;
@@ -486,16 +486,16 @@ cairo_truetype_font_write_generic_table (cairo_truetype_font_t *font,
size = 0;
status = font->backend->load_truetype_table(font->scaled_font_subset->scaled_font,
tag, 0, NULL, &size);
- if (status)
+ if (unlikely (status))
return _cairo_truetype_font_set_error (font, status);
status = cairo_truetype_font_allocate_write_buffer (font, size, &buffer);
- if (status)
+ if (unlikely (status))
return _cairo_truetype_font_set_error (font, status);
status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
tag, 0, buffer, &size);
- if (status)
+ if (unlikely (status))
return _cairo_truetype_font_set_error (font, status);
return CAIRO_STATUS_SUCCESS;
@@ -533,7 +533,7 @@ cairo_truetype_font_remap_composite_glyph (cairo_truetype_font_t *font,
flags = be16_to_cpu (composite_glyph->flags);
has_more_components = flags & TT_MORE_COMPONENTS;
status = cairo_truetype_font_use_glyph (font, be16_to_cpu (composite_glyph->index), &index);
- if (status)
+ if (unlikely (status))
return status;
composite_glyph->index = cpu_to_be16 (index);
@@ -575,21 +575,21 @@ cairo_truetype_font_write_glyf_table (cairo_truetype_font_t *font,
status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
TT_TAG_head, 0,
(unsigned char*) &header, &size);
- if (status)
+ if (unlikely (status))
return _cairo_truetype_font_set_error (font, status);
-
+
if (be16_to_cpu (header.index_to_loc_format) == 0)
size = sizeof (int16_t) * (font->num_glyphs_in_face + 1);
else
size = sizeof (int32_t) * (font->num_glyphs_in_face + 1);
u.bytes = malloc (size);
- if (u.bytes == NULL)
+ if (unlikely (u.bytes == NULL))
return _cairo_truetype_font_set_error (font, CAIRO_STATUS_NO_MEMORY);
status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
TT_TAG_loca, 0, u.bytes, &size);
- if (status)
+ if (unlikely (status))
return _cairo_truetype_font_set_error (font, status);
start_offset = _cairo_array_num_elements (&font->output);
@@ -612,33 +612,33 @@ cairo_truetype_font_write_glyf_table (cairo_truetype_font_t *font,
size = end - begin;
status = cairo_truetype_font_align_output (font, &next);
- if (status)
+ if (unlikely (status))
goto FAIL;
status = cairo_truetype_font_check_boundary (font, next);
- if (status)
+ if (unlikely (status))
goto FAIL;
font->glyphs[i].location = next - start_offset;
status = cairo_truetype_font_allocate_write_buffer (font, size, &buffer);
- if (status)
+ if (unlikely (status))
goto FAIL;
if (size != 0) {
status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
TT_TAG_glyf, begin, buffer, &size);
- if (status)
+ if (unlikely (status))
goto FAIL;
status = cairo_truetype_font_remap_composite_glyph (font, buffer, size);
- if (status)
+ if (unlikely (status))
goto FAIL;
}
}
status = cairo_truetype_font_align_output (font, &next);
- if (status)
+ if (unlikely (status))
goto FAIL;
font->glyphs[i].location = next - start_offset;
@@ -664,17 +664,17 @@ cairo_truetype_font_write_head_table (cairo_truetype_font_t *font,
size = 0;
status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
tag, 0, NULL, &size);
- if (status)
+ if (unlikely (status))
return _cairo_truetype_font_set_error (font, status);
font->checksum_index = _cairo_array_num_elements (&font->output) + 8;
status = cairo_truetype_font_allocate_write_buffer (font, size, &buffer);
- if (status)
+ if (unlikely (status))
return _cairo_truetype_font_set_error (font, status);
status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
tag, 0, buffer, &size);
- if (status)
+ if (unlikely (status))
return _cairo_truetype_font_set_error (font, status);
/* set checkSumAdjustment to 0 for table checksum calcualtion */
@@ -695,12 +695,12 @@ cairo_truetype_font_write_hhea_table (cairo_truetype_font_t *font, unsigned long
size = sizeof (tt_hhea_t);
status = cairo_truetype_font_allocate_write_buffer (font, size, (unsigned char **) &hhea);
- if (status)
+ if (unlikely (status))
return _cairo_truetype_font_set_error (font, status);
status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
tag, 0, (unsigned char *) hhea, &size);
- if (status)
+ if (unlikely (status))
return _cairo_truetype_font_set_error (font, status);
hhea->num_hmetrics = cpu_to_be16 ((uint16_t)(font->base.num_glyphs));
@@ -728,7 +728,7 @@ cairo_truetype_font_write_hmtx_table (cairo_truetype_font_t *font,
status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
TT_TAG_hhea, 0,
(unsigned char*) &hhea, &size);
- if (status)
+ if (unlikely (status))
return _cairo_truetype_font_set_error (font, status);
num_hmetrics = be16_to_cpu(hhea.num_hmetrics);
@@ -739,7 +739,7 @@ cairo_truetype_font_write_hmtx_table (cairo_truetype_font_t *font,
status = cairo_truetype_font_allocate_write_buffer (font,
long_entry_size,
(unsigned char **) &p);
- if (status)
+ if (unlikely (status))
return _cairo_truetype_font_set_error (font, status);
if (font->glyphs[i].parent_index < num_hmetrics) {
@@ -747,7 +747,7 @@ cairo_truetype_font_write_hmtx_table (cairo_truetype_font_t *font,
TT_TAG_hmtx,
font->glyphs[i].parent_index * long_entry_size,
(unsigned char *) p, &long_entry_size);
- if (status)
+ if (unlikely (status))
return _cairo_truetype_font_set_error (font, status);
}
else
@@ -756,7 +756,7 @@ cairo_truetype_font_write_hmtx_table (cairo_truetype_font_t *font,
TT_TAG_hmtx,
(num_hmetrics - 1) * long_entry_size,
(unsigned char *) p, &short_entry_size);
- if (status)
+ if (unlikely (status))
return _cairo_truetype_font_set_error (font, status);
status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
@@ -764,7 +764,7 @@ cairo_truetype_font_write_hmtx_table (cairo_truetype_font_t *font,
num_hmetrics * long_entry_size +
(font->glyphs[i].parent_index - num_hmetrics) * short_entry_size,
(unsigned char *) (p + 1), &short_entry_size);
- if (status)
+ if (unlikely (status))
return _cairo_truetype_font_set_error (font, status);
}
font->base.widths[i] = be16_to_cpu (p[0]);
@@ -789,7 +789,7 @@ cairo_truetype_font_write_loca_table (cairo_truetype_font_t *font,
status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
TT_TAG_head, 0,
(unsigned char*) &header, &size);
- if (status)
+ if (unlikely (status))
return _cairo_truetype_font_set_error (font, status);
if (be16_to_cpu (header.index_to_loc_format) == 0)
@@ -817,12 +817,12 @@ cairo_truetype_font_write_maxp_table (cairo_truetype_font_t *font,
size = sizeof (tt_maxp_t);
status = cairo_truetype_font_allocate_write_buffer (font, size, (unsigned char **) &maxp);
- if (status)
+ if (unlikely (status))
return _cairo_truetype_font_set_error (font, status);
status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
tag, 0, (unsigned char *) maxp, &size);
- if (status)
+ if (unlikely (status))
return _cairo_truetype_font_set_error (font, status);
maxp->num_glyphs = cpu_to_be16 (font->base.num_glyphs);
@@ -862,7 +862,7 @@ cairo_truetype_font_write_offset_table (cairo_truetype_font_t *font)
table_buffer_length = font->num_tables * 16;
status = cairo_truetype_font_allocate_write_buffer (font, table_buffer_length,
&table_buffer);
- if (status)
+ if (unlikely (status))
return _cairo_truetype_font_set_error (font, status);
return CAIRO_STATUS_SUCCESS;
@@ -920,28 +920,28 @@ cairo_truetype_font_generate (cairo_truetype_font_t *font,
return font->status;
status = cairo_truetype_font_write_offset_table (font);
- if (status)
+ if (unlikely (status))
goto FAIL;
status = cairo_truetype_font_align_output (font, &start);
- if (status)
+ if (unlikely (status))
goto FAIL;
end = 0;
for (i = 0; i < font->num_tables; i++) {
status = font->truetype_tables[i].write (font, font->truetype_tables[i].tag);
- if (status)
+ if (unlikely (status))
goto FAIL;
end = _cairo_array_num_elements (&font->output);
status = cairo_truetype_font_align_output (font, &next);
- if (status)
+ if (unlikely (status))
goto FAIL;
cairo_truetype_font_update_entry (font, font->truetype_tables[i].pos,
font->truetype_tables[i].tag, start, end);
status = cairo_truetype_font_check_boundary (font, next);
- if (status)
+ if (unlikely (status))
goto FAIL;
start = next;
@@ -1081,24 +1081,24 @@ _cairo_truetype_subset_init (cairo_truetype_subset_t *truetype_subset,
unsigned long num_strings = 0;
status = _cairo_truetype_font_create (font_subset, &font);
- if (status)
+ if (unlikely (status))
return status;
for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) {
unsigned short parent_glyph = font->scaled_font_subset->glyphs[i];
status = cairo_truetype_font_use_glyph (font, parent_glyph, &parent_glyph);
- if (status)
+ if (unlikely (status))
goto fail1;
}
cairo_truetype_font_create_truetype_table_list (font);
status = cairo_truetype_font_generate (font, &data, &length,
&string_offsets, &num_strings);
- if (status)
+ if (unlikely (status))
goto fail1;
truetype_subset->base_font = strdup (font->base.base_font);
- if (truetype_subset->base_font == NULL) {
+ if (unlikely (truetype_subset->base_font == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail1;
}
@@ -1108,7 +1108,7 @@ _cairo_truetype_subset_init (cairo_truetype_subset_t *truetype_subset,
* font_subset->num_glyphs are omitted. */
truetype_subset->widths = calloc (sizeof (double),
font->scaled_font_subset->num_glyphs);
- if (truetype_subset->widths == NULL) {
+ if (unlikely (truetype_subset->widths == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail2;
}
@@ -1124,7 +1124,7 @@ _cairo_truetype_subset_init (cairo_truetype_subset_t *truetype_subset,
if (length) {
truetype_subset->data = malloc (length);
- if (truetype_subset->data == NULL) {
+ if (unlikely (truetype_subset->data == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail3;
}
@@ -1137,7 +1137,7 @@ _cairo_truetype_subset_init (cairo_truetype_subset_t *truetype_subset,
if (num_strings) {
offsets_length = num_strings * sizeof (unsigned long);
truetype_subset->string_offsets = malloc (offsets_length);
- if (truetype_subset->string_offsets == NULL) {
+ if (unlikely (truetype_subset->string_offsets == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail4;
}
@@ -1199,7 +1199,7 @@ _cairo_truetype_reverse_cmap (cairo_scaled_font_t *scaled_font,
TT_TAG_cmap, table_offset,
(unsigned char *) &buf,
&size);
- if (status)
+ if (unlikely (status))
return status;
/* All table formats have the same first two words */
@@ -1209,14 +1209,14 @@ _cairo_truetype_reverse_cmap (cairo_scaled_font_t *scaled_font,
size = be16_to_cpu (map->length);
map = malloc (size);
- if (map == NULL)
+ if (unlikely (map == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
status = backend->load_truetype_table (scaled_font,
TT_TAG_cmap, table_offset,
(unsigned char *) map,
&size);
- if (status)
+ if (unlikely (status))
goto fail;
num_segments = be16_to_cpu (map->segCountX2)/2;
@@ -1299,21 +1299,21 @@ _cairo_truetype_index_to_ucs4 (cairo_scaled_font_t *scaled_font,
TT_TAG_cmap, 0,
(unsigned char *) &buf,
&size);
- if (status)
+ if (unlikely (status))
return status;
cmap = (tt_cmap_t *) buf;
num_tables = be16_to_cpu (cmap->num_tables);
size = 4 + num_tables*sizeof(tt_cmap_index_t);
cmap = _cairo_malloc_ab_plus_c (num_tables, sizeof (tt_cmap_index_t), 4);
- if (cmap == NULL)
+ if (unlikely (cmap == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
status = backend->load_truetype_table (scaled_font,
TT_TAG_cmap, 0,
(unsigned char *) cmap,
&size);
- if (status)
+ if (unlikely (status))
goto cleanup;
/* Find a table with Unicode mapping */
diff --git a/src/cairo-type1-fallback.c b/src/cairo-type1-fallback.c
index 1f39a3f0..91c00542 100644
--- a/src/cairo-type1-fallback.c
+++ b/src/cairo-type1-fallback.c
@@ -85,12 +85,11 @@ cairo_type1_font_create (cairo_scaled_font_subset_t *scaled_font_subset,
cairo_status_t status;
font = calloc (1, sizeof (cairo_type1_font_t));
- if (font == NULL)
+ if (unlikely (font == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
- font->widths = calloc (scaled_font_subset->num_glyphs,
- sizeof (int));
- if (font->widths == NULL) {
+ font->widths = calloc (scaled_font_subset->num_glyphs, sizeof (int));
+ if (unlikely (font->widths == NULL)) {
free (font);
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
@@ -112,7 +111,7 @@ cairo_type1_font_create (cairo_scaled_font_subset_t *scaled_font_subset,
&ctm,
&font_options);
status = font->type1_scaled_font->status;
- if (status)
+ if (unlikely (status))
goto fail;
_cairo_array_init (&font->contents, sizeof (unsigned char));
@@ -227,7 +226,7 @@ _charstring_move_to (void *closure,
cairo_status_t status;
status = _cairo_array_grow_by (path_info->data, 12);
- if (status)
+ if (unlikely (status))
return status;
dx = _cairo_fixed_integer_part (point->x) - path_info->current_x;
@@ -251,7 +250,7 @@ _charstring_line_to (void *closure,
cairo_status_t status;
status = _cairo_array_grow_by (path_info->data, 12);
- if (status)
+ if (unlikely (status))
return status;
dx = _cairo_fixed_integer_part (point->x) - path_info->current_x;
@@ -277,7 +276,7 @@ _charstring_curve_to (void *closure,
cairo_status_t status;
status = _cairo_array_grow_by (path_info->data, 32);
- if (status)
+ if (unlikely (status))
return status;
dx1 = _cairo_fixed_integer_part (point1->x) - path_info->current_x;
@@ -309,7 +308,7 @@ _charstring_close_path (void *closure)
return CAIRO_STATUS_SUCCESS;
status = _cairo_array_grow_by (path_info->data, 2);
- if (status)
+ if (unlikely (status))
return status;
charstring_encode_command (path_info->data, CHARSTRING_closepath);
@@ -363,7 +362,7 @@ cairo_type1_font_create_charstring (cairo_type1_font_t *font,
CAIRO_SCALED_GLYPH_INFO_METRICS,
&scaled_glyph);
}
- if (status)
+ if (unlikely (status))
return status;
metrics = &scaled_glyph->metrics;
@@ -385,7 +384,7 @@ cairo_type1_font_create_charstring (cairo_type1_font_t *font,
font->widths[subset_index] = metrics->x_advance;
status = _cairo_array_grow_by (data, 30);
- if (status)
+ if (unlikely (status))
return status;
if (type == CAIRO_CHARSTRING_TYPE1) {
@@ -413,12 +412,12 @@ cairo_type1_font_create_charstring (cairo_type1_font_t *font,
_charstring_curve_to,
_charstring_close_path,
&path_info);
- if (status)
+ if (unlikely (status))
return status;
}
status = _cairo_array_grow_by (data, 1);
- if (status)
+ if (unlikely (status))
return status;
charstring_encode_command (path_info.data, CHARSTRING_endchar);
@@ -437,7 +436,7 @@ cairo_type1_font_write_charstrings (cairo_type1_font_t *font,
_cairo_array_init (&data, sizeof (unsigned char));
status = _cairo_array_grow_by (&data, 1024);
- if (status)
+ if (unlikely (status))
goto fail;
_cairo_output_stream_printf (encrypted_output,
@@ -449,14 +448,14 @@ cairo_type1_font_write_charstrings (cairo_type1_font_t *font,
_cairo_array_truncate (&data, 0);
/* four "random" bytes required by encryption algorithm */
status = _cairo_array_append_multiple (&data, zeros, 4);
- if (status)
+ if (unlikely (status))
goto fail;
status = cairo_type1_font_create_charstring (font, i,
font->scaled_font_subset->glyphs[i],
CAIRO_CHARSTRING_TYPE1,
&data);
- if (status)
+ if (unlikely (status))
goto fail;
charstring_encrypt (&data);
@@ -599,7 +598,7 @@ cairo_type1_font_write_private_dict (cairo_type1_font_t *font,
"/password 5839 def\n");
status = cairo_type1_font_write_charstrings (font, encrypted_output);
- if (status)
+ if (unlikely (status))
goto fail;
_cairo_output_stream_printf (encrypted_output,
@@ -651,7 +650,7 @@ cairo_type1_font_write (cairo_type1_font_t *font,
font->header_size = _cairo_output_stream_get_position (font->output);
status = cairo_type1_font_write_private_dict (font, name);
- if (status)
+ if (unlikely (status))
return status;
font->data_size = _cairo_output_stream_get_position (font->output) -
@@ -671,7 +670,7 @@ cairo_type1_font_generate (cairo_type1_font_t *font, const char *name)
cairo_int_status_t status;
status = _cairo_array_grow_by (&font->contents, 4096);
- if (status)
+ if (unlikely (status))
return status;
font->output = _cairo_output_stream_create (cairo_type1_write_stream, NULL, font);
@@ -679,7 +678,7 @@ cairo_type1_font_generate (cairo_type1_font_t *font, const char *name)
return _cairo_output_stream_destroy (font->output);
status = cairo_type1_font_write (font, name);
- if (status)
+ if (unlikely (status))
return status;
font->data = _cairo_array_index (&font->contents, 0);
@@ -714,21 +713,21 @@ _cairo_type1_fallback_init_internal (cairo_type1_subset_t *type1_subset,
unsigned int i, len;
status = cairo_type1_font_create (scaled_font_subset, &font, hex_encode);
- if (status)
+ if (unlikely (status))
return status;
status = cairo_type1_font_generate (font, name);
- if (status)
+ if (unlikely (status))
goto fail1;
type1_subset->base_font = strdup (name);
- if (type1_subset->base_font == NULL) {
+ if (unlikely (type1_subset->base_font == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail1;
}
type1_subset->widths = calloc (sizeof (int), font->scaled_font_subset->num_glyphs);
- if (type1_subset->widths == NULL) {
+ if (unlikely (type1_subset->widths == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail2;
}
@@ -745,7 +744,7 @@ _cairo_type1_fallback_init_internal (cairo_type1_subset_t *type1_subset,
length = font->header_size + font->data_size +
font->trailer_size;
type1_subset->data = malloc (length);
- if (type1_subset->data == NULL) {
+ if (unlikely (type1_subset->data == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail3;
}
@@ -816,13 +815,13 @@ _cairo_type2_charstrings_init (cairo_type2_charstrings_t *type2_subset,
cairo_array_t charstring;
status = cairo_type1_font_create (scaled_font_subset, &font, FALSE);
- if (status)
+ if (unlikely (status))
return status;
_cairo_array_init (&type2_subset->charstrings, sizeof (cairo_array_t));
type2_subset->widths = calloc (sizeof (int), font->scaled_font_subset->num_glyphs);
- if (type2_subset->widths == NULL) {
+ if (unlikely (type2_subset->widths == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail1;
}
@@ -831,18 +830,18 @@ _cairo_type2_charstrings_init (cairo_type2_charstrings_t *type2_subset,
for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) {
_cairo_array_init (&charstring, sizeof (unsigned char));
status = _cairo_array_grow_by (&charstring, 32);
- if (status)
+ if (unlikely (status))
goto fail2;
status = cairo_type1_font_create_charstring (font, i,
font->scaled_font_subset->glyphs[i],
CAIRO_CHARSTRING_TYPE2,
&charstring);
- if (status)
+ if (unlikely (status))
goto fail2;
status = _cairo_array_append (&type2_subset->charstrings, &charstring);
- if (status)
+ if (unlikely (status))
goto fail2;
}
_cairo_scaled_font_thaw_cache (font->type1_scaled_font);
diff --git a/src/cairo-type1-subset.c b/src/cairo-type1-subset.c
index e5557585..fe74dc6c 100644
--- a/src/cairo-type1-subset.c
+++ b/src/cairo-type1-subset.c
@@ -126,7 +126,7 @@ _cairo_type1_font_subset_init (cairo_type1_font_subset_t *font,
ft_unscaled_font = (cairo_ft_unscaled_font_t *) unscaled_font;
face = _cairo_ft_unscaled_font_lock_face (ft_unscaled_font);
- if (face == NULL)
+ if (unlikely (face == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
if (FT_Get_PS_Font_Info(face, &font_info) != 0) {
@@ -154,7 +154,7 @@ _cairo_type1_font_subset_init (cairo_type1_font_subset_t *font,
if (face->family_name) {
font->base.base_font = strdup (face->family_name);
- if (font->base.base_font == NULL) {
+ if (unlikely (font->base.base_font == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail2;
}
@@ -167,7 +167,7 @@ _cairo_type1_font_subset_init (cairo_type1_font_subset_t *font,
}
font->glyphs = calloc (face->num_glyphs, sizeof font->glyphs[0]);
- if (font->glyphs == NULL) {
+ if (unlikely (font->glyphs == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail3;
}
@@ -467,7 +467,7 @@ cairo_type1_font_subset_decrypt_eexec_segment (cairo_type1_font_subset_t *font)
end = (unsigned char *) in + font->eexec_segment_size;
font->cleartext = malloc (font->eexec_segment_size);
- if (font->cleartext == NULL)
+ if (unlikely (font->cleartext == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
out = font->cleartext;
@@ -573,7 +573,7 @@ cairo_type1_font_subset_get_glyph_names_and_widths (cairo_type1_font_subset_t *f
}
font->glyphs[i].name = strdup (buffer);
- if (font->glyphs[i].name == NULL)
+ if (unlikely (font->glyphs[i].name == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
@@ -838,7 +838,7 @@ cairo_type1_font_subset_look_for_seac(cairo_type1_font_subset_t *font,
int command;
charstring = malloc (encrypted_charstring_length);
- if (charstring == NULL)
+ if (unlikely (charstring == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
cairo_type1_font_subset_decrypt_charstring ((const unsigned char *)
@@ -866,11 +866,11 @@ cairo_type1_font_subset_look_for_seac(cairo_type1_font_subset_t *font,
* make sure those glyphs are present in the subset
* under their standard names. */
status = use_standard_encoding_glyph (font, stack[3]);
- if (status)
+ if (unlikely (status))
return status;
status = use_standard_encoding_glyph (font, stack[4]);
- if (status)
+ if (unlikely (status))
return status;
sp = 0;
@@ -906,18 +906,18 @@ write_used_glyphs (cairo_type1_font_subset_t *font,
"/%.*s %d %s ",
name_length, name, charstring_length, font->rd);
status = cairo_type1_font_subset_write_encrypted (font, buffer, length);
- if (status)
+ if (unlikely (status))
return status;
status = cairo_type1_font_subset_write_encrypted (font,
charstring,
charstring_length);
- if (status)
+ if (unlikely (status))
return status;
length = snprintf (buffer, sizeof buffer, "%s\n", font->nd);
status = cairo_type1_font_subset_write_encrypted (font, buffer, length);
- if (status)
+ if (unlikely (status))
return status;
return CAIRO_STATUS_SUCCESS;
@@ -983,7 +983,7 @@ cairo_type1_font_subset_for_each_glyph (cairo_type1_font_subset_t *font,
cairo_status_t status = func (font,
name, name_length,
charstring, charstring_length);
- if (status)
+ if (unlikely (status))
return status;
}
}
@@ -1040,7 +1040,7 @@ cairo_type1_font_subset_write_private_dict (cairo_type1_font_subset_t *font,
dict_start = p;
status = cairo_type1_font_subset_get_glyph_names_and_widths (font);
- if (status)
+ if (unlikely (status))
return status;
/* Now that we have the private dictionary broken down in
@@ -1052,7 +1052,7 @@ cairo_type1_font_subset_write_private_dict (cairo_type1_font_subset_t *font,
font->cleartext_end,
cairo_type1_font_subset_look_for_seac,
&p);
- if (status)
+ if (unlikely (status))
return status;
closefile_token = find_token (p, font->cleartext_end, "closefile");
@@ -1060,13 +1060,13 @@ cairo_type1_font_subset_write_private_dict (cairo_type1_font_subset_t *font,
return CAIRO_INT_STATUS_UNSUPPORTED;
status = cairo_type1_font_subset_get_glyph_names_and_widths (font);
- if (status)
+ if (unlikely (status))
return status;
/* We're ready to start outputting. First write the header,
* i.e. the public part of the font dict.*/
status = cairo_type1_font_subset_write_header (font, name);
- if (status)
+ if (unlikely (status))
return status;
font->base.header_size = _cairo_output_stream_get_position (font->output);
@@ -1076,21 +1076,21 @@ cairo_type1_font_subset_write_private_dict (cairo_type1_font_subset_t *font,
* to the /CharStrings token. */
status = cairo_type1_font_subset_write_encrypted (font, font->cleartext,
charstrings - font->cleartext);
- if (status)
+ if (unlikely (status))
return status;
/* Write out new charstring count */
length = snprintf (buffer, sizeof buffer,
"/CharStrings %d", font->num_glyphs);
status = cairo_type1_font_subset_write_encrypted (font, buffer, length);
- if (status)
+ if (unlikely (status))
return status;
/* Write out text between the charstring count and the first
* charstring definition */
status = cairo_type1_font_subset_write_encrypted (font, glyph_count_end,
dict_start - glyph_count_end);
- if (status)
+ if (unlikely (status))
return status;
/* Write out the charstring definitions for each of the glyphs in
@@ -1100,14 +1100,14 @@ cairo_type1_font_subset_write_private_dict (cairo_type1_font_subset_t *font,
font->cleartext_end,
write_used_glyphs,
&p);
- if (status)
+ if (unlikely (status))
return status;
/* Output what's left between the end of the glyph definitions and
* the end of the private dict to the output. */
status = cairo_type1_font_subset_write_encrypted (font, p,
closefile_token - p + strlen ("closefile") + 1);
- if (status)
+ if (unlikely (status))
return status;
_cairo_output_stream_write (font->output, "\n", 1);
@@ -1158,11 +1158,11 @@ cairo_type1_font_subset_write (cairo_type1_font_subset_t *font,
cairo_status_t status;
status = cairo_type1_font_subset_find_segments (font);
- if (status)
+ if (unlikely (status))
return status;
status = cairo_type1_font_subset_decrypt_eexec_segment (font);
- if (status)
+ if (unlikely (status))
return status;
/* Determine which glyph definition delimiters to use. */
@@ -1181,14 +1181,14 @@ cairo_type1_font_subset_write (cairo_type1_font_subset_t *font,
font->hex_column = 0;
status = cairo_type1_font_subset_write_private_dict (font, name);
- if (status)
+ if (unlikely (status))
return status;
font->base.data_size = _cairo_output_stream_get_position (font->output) -
font->base.header_size;
status = cairo_type1_font_subset_write_trailer (font);
- if (status)
+ if (unlikely (status))
return status;
font->base.trailer_size =
@@ -1210,12 +1210,12 @@ cairo_type1_font_subset_generate (void *abstract_font,
ft_unscaled_font = (cairo_ft_unscaled_font_t *) font->base.unscaled_font;
font->face = _cairo_ft_unscaled_font_lock_face (ft_unscaled_font);
- if (font->face == NULL)
+ if (unlikely (font->face == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
font->type1_length = font->face->stream->size;
font->type1_data = malloc (font->type1_length);
- if (font->type1_data == NULL) {
+ if (unlikely (font->type1_data == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail;
}
@@ -1239,7 +1239,7 @@ cairo_type1_font_subset_generate (void *abstract_font,
}
status = _cairo_array_grow_by (&font->contents, 4096);
- if (status)
+ if (unlikely (status))
goto fail;
font->output = _cairo_output_stream_create (type1_font_write, NULL, font);
@@ -1249,7 +1249,7 @@ cairo_type1_font_subset_generate (void *abstract_font,
}
status = cairo_type1_font_subset_write (font, name);
- if (status)
+ if (unlikely (status))
goto fail;
font->base.data = _cairo_array_index (&font->contents, 0);
@@ -1306,7 +1306,7 @@ _cairo_type1_subset_init (cairo_type1_subset_t *type1_subset,
unscaled_font = _cairo_ft_scaled_font_get_unscaled_font (scaled_font_subset->scaled_font);
status = _cairo_type1_font_subset_init (&font, unscaled_font, hex_encode);
- if (status)
+ if (unlikely (status))
return status;
for (i = 0; i < scaled_font_subset->num_glyphs; i++) {
@@ -1315,7 +1315,7 @@ _cairo_type1_subset_init (cairo_type1_subset_t *type1_subset,
}
status = cairo_type1_font_subset_generate (&font, name);
- if (status)
+ if (unlikely (status))
goto fail1;
if (font.base.base_font) {
@@ -1325,11 +1325,11 @@ _cairo_type1_subset_init (cairo_type1_subset_t *type1_subset,
scaled_font_subset->font_id, scaled_font_subset->subset_id);
type1_subset->base_font = strdup (buf);
}
- if (type1_subset->base_font == NULL)
+ if (unlikely (type1_subset->base_font == NULL))
goto fail1;
type1_subset->widths = calloc (sizeof (int), font.num_glyphs);
- if (type1_subset->widths == NULL)
+ if (unlikely (type1_subset->widths == NULL))
goto fail2;
for (i = 0; i < font.base.num_glyphs; i++) {
if (font.glyphs[i].subset_index < 0)
@@ -1349,7 +1349,7 @@ _cairo_type1_subset_init (cairo_type1_subset_t *type1_subset,
font.base.data_size +
font.base.trailer_size;
type1_subset->data = malloc (length);
- if (type1_subset->data == NULL)
+ if (unlikely (type1_subset->data == NULL))
goto fail3;
memcpy (type1_subset->data,
diff --git a/src/cairo-type3-glyph-surface.c b/src/cairo-type3-glyph-surface.c
index 6f9eb43e..b3a48313 100644
--- a/src/cairo-type3-glyph-surface.c
+++ b/src/cairo-type3-glyph-surface.c
@@ -55,7 +55,7 @@ _cairo_type3_glyph_surface_create (cairo_scaled_font_t *scaled_font,
cairo_matrix_t invert_y_axis;
surface = malloc (sizeof (cairo_type3_glyph_surface_t));
- if (surface == NULL)
+ if (unlikely (surface == NULL))
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
_cairo_surface_init (&surface->base, &cairo_type3_glyph_surface_backend,
@@ -96,7 +96,7 @@ _cairo_type3_glyph_surface_emit_image (cairo_type3_glyph_surface_t *surface,
} else {
image_mask = _cairo_image_surface_clone (image, CAIRO_FORMAT_A1);
status = cairo_surface_status (&image->base);
- if (status)
+ if (unlikely (status))
return status;
}
@@ -196,7 +196,7 @@ _cairo_type3_glyph_surface_paint (void *abstract_surface,
pattern = (const cairo_surface_pattern_t *) source;
status = _cairo_surface_acquire_source_image (pattern->surface, &image, &image_extra);
- if (status)
+ if (unlikely (status))
goto fail;
status = _cairo_type3_glyph_surface_emit_image_pattern (surface,
@@ -282,7 +282,7 @@ _cairo_type3_glyph_surface_show_glyphs (void *abstract_surface,
/* We require the matrix to be invertable. */
ctm_inverse = scaled_font->ctm;
status = cairo_matrix_invert (&ctm_inverse);
- if (status)
+ if (unlikely (status))
return CAIRO_INT_STATUS_IMAGE_FALLBACK;
cairo_matrix_multiply (&new_ctm, &scaled_font->ctm, &ctm_inverse);
@@ -315,6 +315,8 @@ static const cairo_surface_backend_t cairo_type3_glyph_surface_backend = {
NULL, /* composite */
NULL, /* fill_rectangles */
NULL, /* composite_trapezoids */
+ NULL, /* create_span_renderer */
+ NULL, /* check_span_renderer */
NULL, /* cairo_type3_glyph_surface_copy_page */
NULL, /* _cairo_type3_glyph_surface_show_page */
NULL, /* set_clip_region */
@@ -357,7 +359,7 @@ _cairo_type3_glyph_surface_emit_fallback_image (cairo_type3_glyph_surface_t *sur
CAIRO_SCALED_GLYPH_INFO_METRICS |
CAIRO_SCALED_GLYPH_INFO_SURFACE,
&scaled_glyph);
- if (status)
+ if (unlikely (status))
return status;
image = scaled_glyph->surface;
@@ -419,7 +421,7 @@ _cairo_type3_glyph_surface_analyze_glyph (void *abstract_surface,
status = _cairo_meta_surface_replay (scaled_glyph->meta_surface,
&surface->base);
- if (status)
+ if (unlikely (status))
goto cleanup;
status2 = _cairo_pdf_operators_flush (&surface->pdf_operators);
diff --git a/src/cairo-types-private.h b/src/cairo-types-private.h
index 6f1354d6..d8d5a2c0 100644
--- a/src/cairo-types-private.h
+++ b/src/cairo-types-private.h
@@ -252,6 +252,30 @@ typedef struct _cairo_box_int {
cairo_point_int_t p2;
} cairo_box_int_t;
+
+/* Rectangles that take part in a composite operation.
+ *
+ * This defines four translations that define which pixels of the
+ * source pattern, mask, clip and destination surface take part in a
+ * general composite operation. The idea is that the pixels at
+ *
+ * (i,j)+(src.x, src.y) of the source,
+ * (i,j)+(mask.x, mask.y) of the mask,
+ * (i,j)+(clip.x, clip.y) of the clip and
+ * (i,j)+(dst.x, dst.y) of the destination
+ *
+ * all combine together to form the result at (i,j)+(dst.x,dst.y),
+ * for i,j ranging in [0,width) and [0,height) respectively.
+ */
+typedef struct _cairo_composite_rectangles {
+ cairo_point_int_t src;
+ cairo_point_int_t mask;
+ cairo_point_int_t clip;
+ cairo_point_int_t dst;
+ int width;
+ int height;
+} cairo_composite_rectangles_t;
+
typedef enum _cairo_direction {
CAIRO_DIRECTION_FORWARD,
CAIRO_DIRECTION_REVERSE
diff --git a/src/cairo-user-font.c b/src/cairo-user-font.c
index c272966a..6670b536 100644
--- a/src/cairo-user-font.c
+++ b/src/cairo-user-font.c
@@ -127,7 +127,7 @@ _cairo_user_scaled_glyph_init (void *abstract_font,
cairo_destroy (cr);
- if (status) {
+ if (unlikely (status)) {
cairo_surface_destroy (meta_surface);
return status;
}
@@ -152,7 +152,7 @@ _cairo_user_scaled_glyph_init (void *abstract_font,
analysis_surface = _cairo_analysis_surface_create (null_surface, -1, -1);
cairo_surface_destroy (null_surface);
status = analysis_surface->status;
- if (status)
+ if (unlikely (status))
return status;
_cairo_analysis_surface_set_ctm (analysis_surface,
@@ -162,7 +162,7 @@ _cairo_user_scaled_glyph_init (void *abstract_font,
_cairo_analysis_surface_get_bounding_box (analysis_surface, &bbox);
cairo_surface_destroy (analysis_surface);
- if (status)
+ if (unlikely (status))
return status;
_cairo_box_to_doubles (&bbox, &x1, &y1, &x2, &y2);
@@ -215,7 +215,7 @@ _cairo_user_scaled_glyph_init (void *abstract_font,
- _cairo_fixed_integer_floor (scaled_glyph->bbox.p1.y));
status = _cairo_meta_surface_replay (meta_surface, surface);
- if (status) {
+ if (unlikely (status)) {
cairo_surface_destroy(surface);
return status;
}
@@ -232,7 +232,7 @@ _cairo_user_scaled_glyph_init (void *abstract_font,
status = _cairo_meta_surface_get_path (meta_surface, path);
- if (status) {
+ if (unlikely (status)) {
_cairo_path_fixed_destroy (path);
return status;
}
@@ -355,7 +355,7 @@ _cairo_user_scaled_font_get_implementation (cairo_toy_font_face_t *toy_face,
face,
(cairo_destroy_func_t) cairo_font_face_destroy);
- if (status) {
+ if (unlikely (status)) {
cairo_font_face_destroy (face);
return status;
}
@@ -376,7 +376,7 @@ _cairo_user_scaled_font_create_toy (cairo_toy_font_face_t *toy_face,
cairo_status_t status;
status = _cairo_user_scaled_font_get_implementation (toy_face, &face);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_user_font_face_scaled_font_create (face,
@@ -384,7 +384,7 @@ _cairo_user_scaled_font_create_toy (cairo_toy_font_face_t *toy_face,
ctm,
font_options,
font);
- if (status)
+ if (unlikely (status))
return status;
return CAIRO_STATUS_SUCCESS;
@@ -420,7 +420,7 @@ _cairo_user_font_face_scaled_font_create (void *abstract_
font_face->immutable = TRUE;
user_scaled_font = malloc (sizeof (cairo_user_scaled_font_t));
- if (user_scaled_font == NULL)
+ if (unlikely (user_scaled_font == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
status = _cairo_scaled_font_init (&user_scaled_font->base,
@@ -428,7 +428,7 @@ _cairo_user_font_face_scaled_font_create (void *abstract_
font_matrix, ctm, options,
&_cairo_user_scaled_font_backend);
- if (status) {
+ if (unlikely (status)) {
free (user_scaled_font);
return status;
}
diff --git a/src/cairo-win32-printing-surface.c b/src/cairo-win32-printing-surface.c
index 41330198..94927aeb 100644
--- a/src/cairo-win32-printing-surface.c
+++ b/src/cairo-win32-printing-surface.c
@@ -1752,6 +1752,8 @@ static const cairo_surface_backend_t cairo_win32_printing_surface_backend = {
NULL, /* composite */
NULL, /* fill_rectangles */
NULL, /* composite_trapezoids */
+ NULL, /* create_span_renderer */
+ NULL, /* check_span_renderer */
NULL, /* copy_page */
_cairo_win32_printing_surface_show_page,
NULL, /* set_clip_region */
diff --git a/src/cairo-win32-surface.c b/src/cairo-win32-surface.c
index 863f9d52..03a8f61a 100644
--- a/src/cairo-win32-surface.c
+++ b/src/cairo-win32-surface.c
@@ -872,6 +872,9 @@ _cairo_win32_surface_composite_inner (cairo_win32_surface_t *src,
return CAIRO_STATUS_SUCCESS;
}
+/* from pixman-private.h */
+#define MOD(a,b) ((a) < 0 ? ((b) - ((-(a) - 1) % (b))) - 1 : (a) % (b))
+
static cairo_int_status_t
_cairo_win32_surface_composite (cairo_operator_t op,
const cairo_pattern_t *pattern,
@@ -1153,8 +1156,8 @@ _cairo_win32_surface_composite (cairo_operator_t op,
uint32_t rendered_width = 0, rendered_height = 0;
uint32_t to_render_height, to_render_width;
int32_t piece_x, piece_y;
- int32_t src_start_x = src_r.x % src_extents.width;
- int32_t src_start_y = src_r.y % src_extents.height;
+ int32_t src_start_x = MOD(src_r.x, src_extents.width);
+ int32_t src_start_y = MOD(src_r.y, src_extents.height);
if (needs_scale)
goto UNSUPPORTED;
@@ -1979,6 +1982,8 @@ static const cairo_surface_backend_t cairo_win32_surface_backend = {
_cairo_win32_surface_composite,
_cairo_win32_surface_fill_rectangles,
NULL, /* composite_trapezoids */
+ NULL, /* create_span_renderer */
+ NULL, /* check_span_renderer */
NULL, /* copy_page */
NULL, /* show_page */
_cairo_win32_surface_set_clip_region,
diff --git a/src/cairo-xcb-surface.c b/src/cairo-xcb-surface.c
index 999f7d54..6f246f80 100644
--- a/src/cairo-xcb-surface.c
+++ b/src/cairo-xcb-surface.c
@@ -1684,6 +1684,8 @@ static const cairo_surface_backend_t cairo_xcb_surface_backend = {
_cairo_xcb_surface_composite,
_cairo_xcb_surface_fill_rectangles,
_cairo_xcb_surface_composite_trapezoids,
+ NULL, /* create_span_renderer */
+ NULL, /* check_span_renderer */
NULL, /* copy_page */
NULL, /* show_page */
_cairo_xcb_surface_set_clip_region,
diff --git a/src/cairo-xlib-display.c b/src/cairo-xlib-display.c
index 2823e5dc..e85174b7 100644
--- a/src/cairo-xlib-display.c
+++ b/src/cairo-xlib-display.c
@@ -248,7 +248,7 @@ _cairo_xlib_display_get (Display *dpy,
}
display = malloc (sizeof (cairo_xlib_display_t));
- if (display == NULL) {
+ if (unlikely (display == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto UNLOCK;
}
@@ -262,7 +262,7 @@ _cairo_xlib_display_get (Display *dpy,
XRenderQueryVersion (dpy, &render_major, &render_minor);
codes = XAddExtension (dpy);
- if (codes == NULL) {
+ if (unlikely (codes == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
free (display);
display = NULL;
diff --git a/src/cairo-xlib-screen.c b/src/cairo-xlib-screen.c
index 9dd411ed..3b1ae2e1 100644
--- a/src/cairo-xlib-screen.c
+++ b/src/cairo-xlib-screen.c
@@ -352,7 +352,7 @@ _cairo_xlib_screen_info_get (cairo_xlib_display_t *display,
info = _cairo_xlib_screen_info_reference (info);
} else {
info = malloc (sizeof (cairo_xlib_screen_info_t));
- if (info == NULL)
+ if (unlikely (info == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
CAIRO_REFERENCE_COUNT_INIT (&info->ref_count, 2); /* Add one for display cache */
@@ -485,7 +485,7 @@ _cairo_xlib_screen_get_visual_info (cairo_xlib_screen_info_t *info,
XScreenNumberOfScreen (info->screen),
visual->visualid,
&ret);
- if (status)
+ if (unlikely (status))
return status;
CAIRO_MUTEX_LOCK (info->mutex);
@@ -506,7 +506,7 @@ _cairo_xlib_screen_get_visual_info (cairo_xlib_screen_info_t *info,
status = _cairo_array_append (&info->visuals, &ret);
CAIRO_MUTEX_UNLOCK (info->mutex);
- if (status) {
+ if (unlikely (status)) {
_cairo_xlib_visual_info_destroy (dpy, ret);
return status;
}
diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c
index 136e5546..68d81922 100644
--- a/src/cairo-xlib-surface.c
+++ b/src/cairo-xlib-surface.c
@@ -147,9 +147,8 @@ _cairo_xlib_surface_create_similar_with_format (void *abstract_src,
if (! CAIRO_SURFACE_RENDER_HAS_COMPOSITE (src))
return NULL;
- xrender_format = _cairo_xlib_display_get_xrender_format (
- src->display,
- format);
+ xrender_format = _cairo_xlib_display_get_xrender_format (src->display,
+ format);
if (xrender_format == NULL)
return NULL;
@@ -672,7 +671,7 @@ _get_image_surface (cairo_xlib_surface_t *surface,
Pixmap pixmap;
status = _cairo_xlib_surface_ensure_gc (surface);
- if (status)
+ if (unlikely (status))
return status;
pixmap = XCreatePixmap (surface->dpy,
@@ -717,7 +716,7 @@ _get_image_surface (cairo_xlib_surface_t *surface,
ximage->height,
ximage->bytes_per_line);
status = image->base.status;
- if (status)
+ if (unlikely (status))
goto BAIL;
/* Let the surface take ownership of the data */
@@ -778,14 +777,14 @@ _get_image_surface (cairo_xlib_surface_t *surface,
status = _cairo_xlib_screen_get_visual_info (surface->screen_info,
surface->visual,
&visual_info);
- if (status)
+ if (unlikely (status))
goto BAIL;
}
image = (cairo_image_surface_t *) cairo_image_surface_create
(format, ximage->width, ximage->height);
status = image->base.status;
- if (status)
+ if (unlikely (status))
goto BAIL;
data = cairo_image_surface_get_data (&image->base);
@@ -822,7 +821,7 @@ _get_image_surface (cairo_xlib_surface_t *surface,
BAIL:
XDestroyImage (ximage);
- if (status) {
+ if (unlikely (status)) {
if (image) {
cairo_surface_destroy (&image->base);
image = NULL;
@@ -910,7 +909,7 @@ _cairo_xlib_surface_ensure_gc (cairo_xlib_surface_t *surface)
gcv.graphics_exposures = False;
surface->gc = XCreateGC (surface->dpy, surface->drawable,
GCGraphicsExposures, &gcv);
- if (!surface->gc)
+ if (unlikely (surface->gc == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
}
@@ -990,7 +989,7 @@ _draw_image_surface (cairo_xlib_surface_t *surface,
ximage.bits_per_pixel);
ximage.bytes_per_line = stride;
ximage.data = _cairo_malloc_ab (stride, ximage.height);
- if (ximage.data == NULL)
+ if (unlikely (ximage.data == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
own_data = TRUE;
@@ -1014,7 +1013,7 @@ _draw_image_surface (cairo_xlib_surface_t *surface,
status = _cairo_xlib_screen_get_visual_info (surface->screen_info,
surface->visual,
&visual_info);
- if (status)
+ if (unlikely (status))
goto BAIL;
}
@@ -1071,7 +1070,7 @@ _draw_image_surface (cairo_xlib_surface_t *surface,
}
status = _cairo_xlib_surface_ensure_gc (surface);
- if (status)
+ if (unlikely (status))
goto BAIL;
XPutImage(surface->dpy, surface->drawable, surface->gc,
@@ -1097,7 +1096,7 @@ _cairo_xlib_surface_acquire_source_image (void *abstract_surf
_cairo_xlib_display_notify (surface->display);
status = _get_image_surface (surface, NULL, &image, NULL);
- if (status)
+ if (unlikely (status))
return status;
*image_out = image;
@@ -1128,7 +1127,7 @@ _cairo_xlib_surface_acquire_dest_image (void *abstract_surfac
_cairo_xlib_display_notify (surface->display);
status = _get_image_surface (surface, interest_rect, &image, image_rect_out);
- if (status)
+ if (unlikely (status))
return status;
*image_out = image;
@@ -1217,7 +1216,7 @@ _cairo_xlib_surface_clone_similar (void *abstract_surface,
src_x, src_y,
width, height,
0, 0);
- if (status) {
+ if (unlikely (status)) {
cairo_surface_destroy (&clone->base);
return status;
}
@@ -1264,7 +1263,7 @@ _cairo_xlib_surface_create_solid_pattern_surface (void *abstrac
_cairo_image_surface_create_with_content (solid_pattern->content,
width, height);
status = image->base.status;
- if (status)
+ if (unlikely (status))
goto BAIL;
pixmap = XCreatePixmap (other->dpy,
@@ -1280,26 +1279,26 @@ _cairo_xlib_surface_create_solid_pattern_surface (void *abstrac
width, height,
other->depth);
status = surface->base.status;
- if (status)
+ if (unlikely (status))
goto BAIL;
status = _cairo_surface_paint (&image->base,
CAIRO_OPERATOR_SOURCE,
&solid_pattern->base, NULL);
- if (status)
+ if (unlikely (status))
goto BAIL;
status = _draw_image_surface (surface, image,
0, 0,
width, height,
0, 0);
- if (status)
+ if (unlikely (status))
goto BAIL;
BAIL:
cairo_surface_destroy (&image->base);
- if (status) {
+ if (unlikely (status)) {
if (pixmap != None)
XFreePixmap (other->dpy, pixmap);
cairo_surface_destroy (&surface->base);
@@ -1426,7 +1425,7 @@ _cairo_xlib_surface_set_attributes (cairo_xlib_surface_t *surface,
status = _cairo_xlib_surface_set_matrix (surface, &attributes->matrix,
xc, yc);
- if (status)
+ if (unlikely (status))
return status;
switch (attributes->extend) {
@@ -1443,7 +1442,7 @@ _cairo_xlib_surface_set_attributes (cairo_xlib_surface_t *surface,
}
status = _cairo_xlib_surface_set_filter (surface, attributes->filter);
- if (status)
+ if (unlikely (status))
return status;
return CAIRO_STATUS_SUCCESS;
@@ -1728,7 +1727,7 @@ _cairo_xlib_surface_composite (cairo_operator_t op,
(cairo_surface_t **) &src,
(cairo_surface_t **) &mask,
&src_attr, &mask_attr);
- if (status)
+ if (unlikely (status))
return status;
/* check for fallback surfaces that we cannot handle ... */
@@ -1757,7 +1756,7 @@ _cairo_xlib_surface_composite (cairo_operator_t op,
status = _cairo_xlib_surface_set_attributes (src, &src_attr,
dst_x + width / 2.,
dst_y + height / 2.);
- if (status)
+ if (unlikely (status))
goto BAIL;
_cairo_xlib_surface_ensure_dst_picture (dst);
@@ -1765,7 +1764,7 @@ _cairo_xlib_surface_composite (cairo_operator_t op,
status = _cairo_xlib_surface_set_attributes (mask, &mask_attr,
dst_x + width / 2.,
dst_y + height/ 2.);
- if (status)
+ if (unlikely (status))
goto BAIL;
XRenderComposite (dst->dpy,
@@ -1796,7 +1795,7 @@ _cairo_xlib_surface_composite (cairo_operator_t op,
case DO_XCOPYAREA:
status = _cairo_xlib_surface_ensure_gc (dst);
- if (status)
+ if (unlikely (status))
goto BAIL;
is_integer_translation = _cairo_matrix_is_integer_translation (&src_attr.matrix,
@@ -1824,7 +1823,7 @@ _cairo_xlib_surface_composite (cairo_operator_t op,
*/
status = _cairo_xlib_surface_ensure_gc (dst);
- if (status)
+ if (unlikely (status))
goto BAIL;
is_integer_translation = _cairo_matrix_is_integer_translation (&src_attr.matrix,
&itx, &ity);
@@ -1879,7 +1878,7 @@ _cairo_xlib_surface_solid_fill_rectangles (cairo_xlib_surface_t *surface,
_cairo_pattern_init_solid (&solid, color, CAIRO_CONTENT_COLOR);
status = _cairo_xlib_surface_ensure_gc (surface);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_pattern_acquire_surface (&solid.base, &surface->base,
@@ -1888,7 +1887,7 @@ _cairo_xlib_surface_solid_fill_rectangles (cairo_xlib_surface_t *surface,
ARRAY_LENGTH (dither_pattern),
&solid_surface,
&attrs);
- if (status)
+ if (unlikely (status))
return status;
if (! _cairo_surface_is_xlib (solid_surface)) {
@@ -1964,7 +1963,7 @@ _cairo_xlib_surface_fill_rectangles (void *abstract_surface,
if (num_rects > ARRAY_LENGTH (static_xrects)) {
xrects = _cairo_malloc_ab (num_rects, sizeof (XRectangle));
- if (xrects == NULL)
+ if (unlikely (xrects == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
@@ -2136,7 +2135,7 @@ _cairo_xlib_surface_composite_trapezoids (cairo_operator_t op,
src_x, src_y, width, height,
(cairo_surface_t **) &src,
&attributes);
- if (status)
+ if (unlikely (status))
return status;
operation = _recategorize_composite_operation (dst, op, src,
@@ -2177,7 +2176,7 @@ _cairo_xlib_surface_composite_trapezoids (cairo_operator_t op,
status = _cairo_xlib_surface_set_attributes (src, &attributes,
dst_x + width / 2.,
dst_y + height / 2.);
- if (status)
+ if (unlikely (status))
goto BAIL;
if (!_cairo_operator_bounded_by_mask (op)) {
@@ -2225,7 +2224,7 @@ _cairo_xlib_surface_composite_trapezoids (cairo_operator_t op,
if (num_traps > ARRAY_LENGTH (xtraps_stack)) {
xtraps = _cairo_malloc_ab (num_traps, sizeof (XTrapezoid));
- if (xtraps == NULL) {
+ if (unlikely (xtraps == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto BAIL;
}
@@ -2300,7 +2299,7 @@ _cairo_xlib_surface_set_clip_region (void *abstract_surface,
_cairo_region_init_rect (&bound, &rect);
_cairo_region_init (&bounded);
status = _cairo_region_intersect (&bounded, &bound, region);
- if (status) {
+ if (unlikely (status)) {
_cairo_region_fini (&bound);
_cairo_region_fini (&bounded);
return status;
@@ -2309,7 +2308,7 @@ _cairo_xlib_surface_set_clip_region (void *abstract_surface,
n_boxes = sizeof (surface->embedded_clip_rects) / sizeof (cairo_box_int_t);
boxes = (cairo_box_int_t *) surface->embedded_clip_rects;
status = _cairo_region_get_boxes (&bounded, &n_boxes, &boxes);
- if (status) {
+ if (unlikely (status)) {
_cairo_region_fini (&bound);
_cairo_region_fini (&bounded);
return status;
@@ -2317,7 +2316,7 @@ _cairo_xlib_surface_set_clip_region (void *abstract_surface,
if (n_boxes > ARRAY_LENGTH (surface->embedded_clip_rects)) {
rects = _cairo_malloc_ab (n_boxes, sizeof (XRectangle));
- if (rects == NULL) {
+ if (unlikely (rects == NULL)) {
_cairo_region_boxes_fini (&bounded, boxes);
_cairo_region_fini (&bound);
_cairo_region_fini (&bounded);
@@ -2429,7 +2428,7 @@ _cairo_xlib_surface_reset (void *abstract_surface)
cairo_status_t status;
status = _cairo_xlib_surface_set_clip_region (surface, NULL);
- if (status)
+ if (unlikely (status))
return status;
return CAIRO_STATUS_SUCCESS;
@@ -2447,6 +2446,8 @@ static const cairo_surface_backend_t cairo_xlib_surface_backend = {
_cairo_xlib_surface_composite,
_cairo_xlib_surface_fill_rectangles,
_cairo_xlib_surface_composite_trapezoids,
+ NULL, /* create_span_renderer */
+ NULL, /* check_span_renderer */
NULL, /* copy_page */
NULL, /* show_page */
_cairo_xlib_surface_set_clip_region,
@@ -2564,17 +2565,17 @@ _cairo_xlib_surface_create_internal (Display *dpy,
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_VISUAL));
status = _cairo_xlib_display_get (dpy, &display);
- if (status)
+ if (unlikely (status))
return _cairo_surface_create_in_error (status);
status = _cairo_xlib_screen_info_get (display, screen, &screen_info);
- if (status) {
+ if (unlikely (status)) {
_cairo_xlib_display_destroy (display);
return _cairo_surface_create_in_error (status);
}
surface = malloc (sizeof (cairo_xlib_surface_t));
- if (surface == NULL) {
+ if (unlikely (surface == NULL)) {
_cairo_xlib_screen_info_destroy (screen_info);
_cairo_xlib_display_destroy (display);
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
@@ -2903,7 +2904,7 @@ cairo_xlib_surface_set_drawable (cairo_surface_t *abstract_surface,
surface->display,
XRenderFreePicture,
surface->dst_picture);
- if (status) {
+ if (unlikely (status)) {
status = _cairo_surface_set_error (&surface->base, status);
return;
}
@@ -2916,7 +2917,7 @@ cairo_xlib_surface_set_drawable (cairo_surface_t *abstract_surface,
surface->display,
XRenderFreePicture,
surface->src_picture);
- if (status) {
+ if (unlikely (status)) {
status = _cairo_surface_set_error (&surface->base, status);
return;
}
@@ -3168,12 +3169,12 @@ _cairo_xlib_surface_font_init (Display *dpy,
int i;
font_private = malloc (sizeof (cairo_xlib_surface_font_private_t));
- if (font_private == NULL)
+ if (unlikely (font_private == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
font_private->scaled_font = scaled_font;
status = _cairo_xlib_display_get (dpy, &font_private->display);
- if (status) {
+ if (unlikely (status)) {
free (font_private);
return status;
}
@@ -3289,7 +3290,7 @@ _cairo_xlib_surface_scaled_glyph_fini (cairo_scaled_glyph_t *scaled_glyph,
to_free,
free);
/* XXX cannot propagate failure */
- if (status)
+ if (unlikely (status))
free (to_free);
to_free = glyphset_info->pending_free_glyphs = NULL;
@@ -3297,7 +3298,7 @@ _cairo_xlib_surface_scaled_glyph_fini (cairo_scaled_glyph_t *scaled_glyph,
if (to_free == NULL) {
to_free = malloc (sizeof (cairo_xlib_font_glyphset_free_glyphs_t));
- if (to_free == NULL) {
+ if (unlikely (to_free == NULL)) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return; /* XXX cannot propagate failure */
}
@@ -3445,7 +3446,7 @@ _cairo_xlib_surface_add_glyph (Display *dpy,
CAIRO_SCALED_GLYPH_INFO_METRICS |
CAIRO_SCALED_GLYPH_INFO_SURFACE,
pscaled_glyph);
- if (status)
+ if (unlikely (status))
return status;
scaled_glyph = *pscaled_glyph;
@@ -3457,7 +3458,7 @@ _cairo_xlib_surface_add_glyph (Display *dpy,
if (scaled_font->surface_private == NULL) {
status = _cairo_xlib_surface_font_init (dpy, scaled_font);
- if (status)
+ if (unlikely (status))
return status;
}
@@ -3484,7 +3485,7 @@ _cairo_xlib_surface_add_glyph (Display *dpy,
tmp_surface = cairo_image_surface_create (glyphset_info->format, 1, 1);
status = tmp_surface->status;
- if (status)
+ if (unlikely (status))
goto BAIL;
cr = cairo_create (tmp_surface);
@@ -3498,7 +3499,7 @@ _cairo_xlib_surface_add_glyph (Display *dpy,
glyph_surface = (cairo_image_surface_t *) tmp_surface;
- if (status)
+ if (unlikely (status))
goto BAIL;
}
@@ -3514,7 +3515,7 @@ _cairo_xlib_surface_add_glyph (Display *dpy,
glyph_surface->width,
glyph_surface->height);
status = tmp_surface->status;
- if (status)
+ if (unlikely (status))
goto BAIL;
tmp_surface->device_transform = glyph_surface->base.device_transform;
@@ -3529,7 +3530,7 @@ _cairo_xlib_surface_add_glyph (Display *dpy,
glyph_surface = (cairo_image_surface_t *) tmp_surface;
- if (status)
+ if (unlikely (status))
goto BAIL;
}
@@ -3579,7 +3580,7 @@ _cairo_xlib_surface_add_glyph (Display *dpy,
unsigned char *new, *n;
new = malloc (c);
- if (new == NULL) {
+ if (unlikely (new == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto BAIL;
}
@@ -3723,7 +3724,7 @@ _emit_glyphs_chunk (cairo_xlib_surface_t *dst,
elts = stack_elts;
} else {
elts = _cairo_malloc_ab (num_elts, sizeof (XGlyphElt8));
- if (elts == NULL)
+ if (unlikely (elts == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
@@ -3864,7 +3865,7 @@ _cairo_xlib_surface_emit_glyphs (cairo_xlib_surface_t *dst,
status = _cairo_xlib_surface_add_glyph (dst->dpy,
scaled_font,
&scaled_glyph);
- if (status) {
+ if (unlikely (status)) {
if (status == CAIRO_INT_STATUS_UNSUPPORTED)
/* Break so we flush glyphs so far and let fallback code
* handle the rest */
@@ -4055,7 +4056,7 @@ _cairo_xlib_surface_show_glyphs (void *abstract_dst,
0, 0, 1, 1,
(cairo_surface_t **) &src,
&attributes);
- if (status)
+ if (unlikely (status))
goto BAIL0;
} else {
cairo_rectangle_int_t glyph_extents;
@@ -4064,7 +4065,7 @@ _cairo_xlib_surface_show_glyphs (void *abstract_dst,
glyphs,
num_glyphs,
&glyph_extents);
- if (status)
+ if (unlikely (status))
goto BAIL0;
status = _cairo_pattern_acquire_surface (src_pattern, &dst->base,
@@ -4072,7 +4073,7 @@ _cairo_xlib_surface_show_glyphs (void *abstract_dst,
glyph_extents.width, glyph_extents.height,
(cairo_surface_t **) &src,
&attributes);
- if (status)
+ if (unlikely (status))
goto BAIL0;
}
@@ -4084,7 +4085,7 @@ _cairo_xlib_surface_show_glyphs (void *abstract_dst,
}
status = _cairo_xlib_surface_set_attributes (src, &attributes, 0, 0);
- if (status)
+ if (unlikely (status))
goto BAIL1;
_cairo_scaled_font_freeze_cache (scaled_font);
diff --git a/src/cairo-xlib-visual.c b/src/cairo-xlib-visual.c
index f6eb1ee9..7dbe86c2 100644
--- a/src/cairo-xlib-visual.c
+++ b/src/cairo-xlib-visual.c
@@ -78,7 +78,7 @@ _cairo_xlib_visual_info_create (Display *dpy,
ramp_index_to_short[i] = (0xffff * i + ((RAMP_SIZE-1)>>1)) / (RAMP_SIZE-1);
info = malloc (sizeof (cairo_xlib_visual_info_t));
- if (info == NULL)
+ if (unlikely (info == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
info->visualid = visualid;
diff --git a/src/cairo.c b/src/cairo.c
index 1fbf62dd..60988782 100644
--- a/src/cairo.c
+++ b/src/cairo.c
@@ -152,7 +152,7 @@ cairo_create (cairo_surface_t *target)
return (cairo_t *) &_cairo_nil;
cr = malloc (sizeof (cairo_t));
- if (cr == NULL) {
+ if (unlikely (cr == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
return (cairo_t *) &_cairo_nil;
}
@@ -168,7 +168,7 @@ cairo_create (cairo_surface_t *target)
cr->gstate_freelist = NULL;
status = _cairo_gstate_init (cr->gstate, target);
- if (status)
+ if (unlikely (status))
_cairo_set_error (cr, status);
return cr;
@@ -349,7 +349,7 @@ cairo_save (cairo_t *cr)
return;
status = _cairo_gstate_save (&cr->gstate, &cr->gstate_freelist);
- if (status)
+ if (unlikely (status))
_cairo_set_error (cr, status);
}
slim_hidden_def(cairo_save);
@@ -371,7 +371,7 @@ cairo_restore (cairo_t *cr)
return;
status = _cairo_gstate_restore (&cr->gstate, &cr->gstate_freelist);
- if (status)
+ if (unlikely (status))
_cairo_set_error (cr, status);
}
slim_hidden_def(cairo_restore);
@@ -458,10 +458,10 @@ cairo_push_group_with_content (cairo_t *cr, cairo_content_t content)
parent_surface = _cairo_gstate_get_target (cr->gstate);
/* Get the extents that we'll use in creating our new group surface */
status = _cairo_surface_get_extents (parent_surface, &extents);
- if (status)
+ if (unlikely (status))
goto bail;
status = _cairo_clip_intersect_to_rectangle (_cairo_gstate_get_clip (cr->gstate), &extents);
- if (status)
+ if (unlikely (status))
goto bail;
group_surface = cairo_surface_create_similar (_cairo_gstate_get_target (cr->gstate),
@@ -469,7 +469,7 @@ cairo_push_group_with_content (cairo_t *cr, cairo_content_t content)
extents.width,
extents.height);
status = cairo_surface_status (group_surface);
- if (status)
+ if (unlikely (status))
goto bail;
/* Set device offsets on the new surface so that logically it appears at
@@ -490,7 +490,7 @@ cairo_push_group_with_content (cairo_t *cr, cairo_content_t content)
bail:
cairo_surface_destroy (group_surface);
- if (status)
+ if (unlikely (status))
_cairo_set_error (cr, status);
}
slim_hidden_def(cairo_push_group_with_content);
@@ -628,7 +628,7 @@ cairo_set_operator (cairo_t *cr, cairo_operator_t op)
return;
status = _cairo_gstate_set_operator (cr->gstate, op);
- if (status)
+ if (unlikely (status))
_cairo_set_error (cr, status);
}
slim_hidden_def (cairo_set_operator);
@@ -790,7 +790,7 @@ cairo_set_source (cairo_t *cr, cairo_pattern_t *source)
}
status = _cairo_gstate_set_source (cr->gstate, source);
- if (status)
+ if (unlikely (status))
_cairo_set_error (cr, status);
}
slim_hidden_def (cairo_set_source);
@@ -838,7 +838,7 @@ cairo_set_tolerance (cairo_t *cr, double tolerance)
_cairo_restrict_value (&tolerance, CAIRO_TOLERANCE_MINIMUM, tolerance);
status = _cairo_gstate_set_tolerance (cr->gstate, tolerance);
- if (status)
+ if (unlikely (status))
_cairo_set_error (cr, status);
}
slim_hidden_def (cairo_set_tolerance);
@@ -865,7 +865,7 @@ cairo_set_antialias (cairo_t *cr, cairo_antialias_t antialias)
return;
status = _cairo_gstate_set_antialias (cr->gstate, antialias);
- if (status)
+ if (unlikely (status))
_cairo_set_error (cr, status);
}
@@ -891,7 +891,7 @@ cairo_set_fill_rule (cairo_t *cr, cairo_fill_rule_t fill_rule)
return;
status = _cairo_gstate_set_fill_rule (cr->gstate, fill_rule);
- if (status)
+ if (unlikely (status))
_cairo_set_error (cr, status);
}
@@ -932,7 +932,7 @@ cairo_set_line_width (cairo_t *cr, double width)
_cairo_restrict_value (&width, 0.0, width);
status = _cairo_gstate_set_line_width (cr->gstate, width);
- if (status)
+ if (unlikely (status))
_cairo_set_error (cr, status);
}
slim_hidden_def (cairo_set_line_width);
@@ -962,7 +962,7 @@ cairo_set_line_cap (cairo_t *cr, cairo_line_cap_t line_cap)
return;
status = _cairo_gstate_set_line_cap (cr->gstate, line_cap);
- if (status)
+ if (unlikely (status))
_cairo_set_error (cr, status);
}
slim_hidden_def (cairo_set_line_cap);
@@ -992,7 +992,7 @@ cairo_set_line_join (cairo_t *cr, cairo_line_join_t line_join)
return;
status = _cairo_gstate_set_line_join (cr->gstate, line_join);
- if (status)
+ if (unlikely (status))
_cairo_set_error (cr, status);
}
slim_hidden_def (cairo_set_line_join);
@@ -1042,7 +1042,7 @@ cairo_set_dash (cairo_t *cr,
status = _cairo_gstate_set_dash (cr->gstate,
dashes, num_dashes, offset);
- if (status)
+ if (unlikely (status))
_cairo_set_error (cr, status);
}
@@ -1132,7 +1132,7 @@ cairo_set_miter_limit (cairo_t *cr, double limit)
return;
status = _cairo_gstate_set_miter_limit (cr->gstate, limit);
- if (status)
+ if (unlikely (status))
_cairo_set_error (cr, status);
}
@@ -1157,7 +1157,7 @@ cairo_translate (cairo_t *cr, double tx, double ty)
return;
status = _cairo_gstate_translate (cr->gstate, tx, ty);
- if (status)
+ if (unlikely (status))
_cairo_set_error (cr, status);
}
@@ -1181,7 +1181,7 @@ cairo_scale (cairo_t *cr, double sx, double sy)
return;
status = _cairo_gstate_scale (cr->gstate, sx, sy);
- if (status)
+ if (unlikely (status))
_cairo_set_error (cr, status);
}
slim_hidden_def (cairo_scale);
@@ -1207,7 +1207,7 @@ cairo_rotate (cairo_t *cr, double angle)
return;
status = _cairo_gstate_rotate (cr->gstate, angle);
- if (status)
+ if (unlikely (status))
_cairo_set_error (cr, status);
}
@@ -1230,7 +1230,7 @@ cairo_transform (cairo_t *cr,
return;
status = _cairo_gstate_transform (cr->gstate, matrix);
- if (status)
+ if (unlikely (status))
_cairo_set_error (cr, status);
}
@@ -1252,7 +1252,7 @@ cairo_set_matrix (cairo_t *cr,
return;
status = _cairo_gstate_set_matrix (cr->gstate, matrix);
- if (status)
+ if (unlikely (status))
_cairo_set_error (cr, status);
}
slim_hidden_def (cairo_set_matrix);
@@ -1393,7 +1393,7 @@ cairo_move_to (cairo_t *cr, double x, double y)
y_fixed = _cairo_fixed_from_double (y);
status = _cairo_path_fixed_move_to (cr->path, x_fixed, y_fixed);
- if (status)
+ if (unlikely (status))
_cairo_set_error (cr, status);
}
slim_hidden_def(cairo_move_to);
@@ -1452,7 +1452,7 @@ cairo_line_to (cairo_t *cr, double x, double y)
y_fixed = _cairo_fixed_from_double (y);
status = _cairo_path_fixed_line_to (cr->path, x_fixed, y_fixed);
- if (status)
+ if (unlikely (status))
_cairo_set_error (cr, status);
}
slim_hidden_def (cairo_line_to);
@@ -1507,7 +1507,7 @@ cairo_curve_to (cairo_t *cr,
x1_fixed, y1_fixed,
x2_fixed, y2_fixed,
x3_fixed, y3_fixed);
- if (status)
+ if (unlikely (status))
_cairo_set_error (cr, status);
}
slim_hidden_def (cairo_curve_to);
@@ -1641,7 +1641,7 @@ cairo_arc_to (cairo_t *cr,
x1, y1,
x2, y2,
radius);
- if (status)
+ if (unlikely (status))
_cairo_set_error (cr, status);
}
*/
@@ -1677,7 +1677,7 @@ cairo_rel_move_to (cairo_t *cr, double dx, double dy)
dy_fixed = _cairo_fixed_from_double (dy);
status = _cairo_path_fixed_rel_move_to (cr->path, dx_fixed, dy_fixed);
- if (status)
+ if (unlikely (status))
_cairo_set_error (cr, status);
}
@@ -1714,7 +1714,7 @@ cairo_rel_line_to (cairo_t *cr, double dx, double dy)
dy_fixed = _cairo_fixed_from_double (dy);
status = _cairo_path_fixed_rel_line_to (cr->path, dx_fixed, dy_fixed);
- if (status)
+ if (unlikely (status))
_cairo_set_error (cr, status);
}
slim_hidden_def(cairo_rel_line_to);
@@ -1775,7 +1775,7 @@ cairo_rel_curve_to (cairo_t *cr,
dx1_fixed, dy1_fixed,
dx2_fixed, dy2_fixed,
dx3_fixed, dy3_fixed);
- if (status)
+ if (unlikely (status))
_cairo_set_error (cr, status);
}
@@ -1827,7 +1827,7 @@ cairo_stroke_to_path (cairo_t *cr)
/* The code in _cairo_meta_surface_get_path has a poorman's stroke_to_path */
status = _cairo_gstate_stroke_path (cr->gstate);
- if (status)
+ if (unlikely (status))
_cairo_set_error (cr, status);
}
#endif
@@ -1867,7 +1867,7 @@ cairo_close_path (cairo_t *cr)
return;
status = _cairo_path_fixed_close_path (cr->path);
- if (status)
+ if (unlikely (status))
_cairo_set_error (cr, status);
}
slim_hidden_def(cairo_close_path);
@@ -1941,7 +1941,7 @@ cairo_paint (cairo_t *cr)
return;
status = _cairo_gstate_paint (cr->gstate);
- if (status)
+ if (unlikely (status))
_cairo_set_error (cr, status);
}
slim_hidden_def (cairo_paint);
@@ -1980,7 +1980,7 @@ cairo_paint_with_alpha (cairo_t *cr,
_cairo_pattern_init_solid (&pattern, &color, CAIRO_CONTENT_ALPHA);
status = _cairo_gstate_mask (cr->gstate, &pattern.base);
- if (status)
+ if (unlikely (status))
_cairo_set_error (cr, status);
_cairo_pattern_fini (&pattern.base);
@@ -2016,7 +2016,7 @@ cairo_mask (cairo_t *cr,
}
status = _cairo_gstate_mask (cr->gstate, pattern);
- if (status)
+ if (unlikely (status))
_cairo_set_error (cr, status);
}
slim_hidden_def (cairo_mask);
@@ -2118,7 +2118,7 @@ cairo_stroke_preserve (cairo_t *cr)
return;
status = _cairo_gstate_stroke (cr->gstate, cr->path);
- if (status)
+ if (unlikely (status))
_cairo_set_error (cr, status);
}
slim_hidden_def(cairo_stroke_preserve);
@@ -2161,7 +2161,7 @@ cairo_fill_preserve (cairo_t *cr)
return;
status = _cairo_gstate_fill (cr->gstate, cr->path);
- if (status)
+ if (unlikely (status))
_cairo_set_error (cr, status);
}
slim_hidden_def(cairo_fill_preserve);
@@ -2187,7 +2187,7 @@ cairo_copy_page (cairo_t *cr)
return;
status = _cairo_gstate_copy_page (cr->gstate);
- if (status)
+ if (unlikely (status))
_cairo_set_error (cr, status);
}
@@ -2210,7 +2210,7 @@ cairo_show_page (cairo_t *cr)
return;
status = _cairo_gstate_show_page (cr->gstate);
- if (status)
+ if (unlikely (status))
_cairo_set_error (cr, status);
}
@@ -2244,7 +2244,7 @@ cairo_in_stroke (cairo_t *cr, double x, double y)
status = _cairo_gstate_in_stroke (cr->gstate,
cr->path,
x, y, &inside);
- if (status)
+ if (unlikely (status))
_cairo_set_error (cr, status);
return inside;
@@ -2290,8 +2290,11 @@ _cairo_rectangle_list_create_in_error (cairo_status_t status)
return (cairo_rectangle_list_t*) &_cairo_rectangles_nil;
list = malloc (sizeof (cairo_rectangle_list_t));
- if (list == NULL)
+ if (unlikely (list == NULL)) {
+ status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
return (cairo_rectangle_list_t*) &_cairo_rectangles_nil;
+ }
+
list->status = status;
list->rectangles = NULL;
list->num_rectangles = 0;
@@ -2411,7 +2414,7 @@ cairo_stroke_extents (cairo_t *cr,
status = _cairo_gstate_stroke_extents (cr->gstate,
cr->path,
x1, y1, x2, y2);
- if (status)
+ if (unlikely (status))
_cairo_set_error (cr, status);
}
@@ -2462,7 +2465,7 @@ cairo_fill_extents (cairo_t *cr,
status = _cairo_gstate_fill_extents (cr->gstate,
cr->path,
x1, y1, x2, y2);
- if (status)
+ if (unlikely (status))
_cairo_set_error (cr, status);
}
@@ -2527,7 +2530,7 @@ cairo_clip_preserve (cairo_t *cr)
return;
status = _cairo_gstate_clip (cr->gstate, cr->path);
- if (status)
+ if (unlikely (status))
_cairo_set_error (cr, status);
}
slim_hidden_def(cairo_clip_preserve);
@@ -2557,7 +2560,7 @@ cairo_reset_clip (cairo_t *cr)
return;
status = _cairo_gstate_reset_clip (cr->gstate);
- if (status)
+ if (unlikely (status))
_cairo_set_error (cr, status);
}
@@ -2595,7 +2598,7 @@ cairo_clip_extents (cairo_t *cr,
}
status = _cairo_gstate_clip_extents (cr->gstate, x1, y1, x2, y2);
- if (status)
+ if (unlikely (status))
_cairo_set_error (cr, status);
}
@@ -2681,7 +2684,7 @@ cairo_select_font_face (cairo_t *cr,
return;
status = _cairo_gstate_select_font_face (cr->gstate, family, slant, weight);
- if (status)
+ if (unlikely (status))
_cairo_set_error (cr, status);
}
@@ -2709,7 +2712,7 @@ cairo_font_extents (cairo_t *cr,
return;
status = _cairo_gstate_get_font_extents (cr->gstate, extents);
- if (status)
+ if (unlikely (status))
_cairo_set_error (cr, status);
}
@@ -2732,7 +2735,7 @@ cairo_set_font_face (cairo_t *cr,
return;
status = _cairo_gstate_set_font_face (cr->gstate, font_face);
- if (status)
+ if (unlikely (status))
_cairo_set_error (cr, status);
}
@@ -2764,7 +2767,7 @@ cairo_get_font_face (cairo_t *cr)
return (cairo_font_face_t*) &_cairo_font_face_nil;
status = _cairo_gstate_get_font_face (cr->gstate, &font_face);
- if (status) {
+ if (unlikely (status)) {
_cairo_set_error (cr, status);
return (cairo_font_face_t*) &_cairo_font_face_nil;
}
@@ -2796,7 +2799,7 @@ cairo_set_font_size (cairo_t *cr, double size)
return;
status = _cairo_gstate_set_font_size (cr->gstate, size);
- if (status)
+ if (unlikely (status))
_cairo_set_error (cr, status);
}
slim_hidden_def (cairo_set_font_size);
@@ -2824,7 +2827,7 @@ cairo_set_font_matrix (cairo_t *cr,
return;
status = _cairo_gstate_set_font_matrix (cr->gstate, matrix);
- if (status)
+ if (unlikely (status))
_cairo_set_error (cr, status);
}
@@ -2868,7 +2871,7 @@ cairo_set_font_options (cairo_t *cr,
return;
status = cairo_font_options_status ((cairo_font_options_t *) options);
- if (status) {
+ if (unlikely (status)) {
_cairo_set_error (cr, status);
return;
}
@@ -2932,15 +2935,15 @@ cairo_set_scaled_font (cairo_t *cr,
}
status = scaled_font->status;
- if (status)
+ if (unlikely (status))
goto BAIL;
status = _cairo_gstate_set_font_face (cr->gstate, scaled_font->font_face);
- if (status)
+ if (unlikely (status))
goto BAIL;
status = _cairo_gstate_set_font_matrix (cr->gstate, &scaled_font->font_matrix);
- if (status)
+ if (unlikely (status))
goto BAIL;
_cairo_gstate_set_font_options (cr->gstate, &scaled_font->options);
@@ -2981,7 +2984,7 @@ cairo_get_scaled_font (cairo_t *cr)
return _cairo_scaled_font_create_in_error (cr->status);
status = _cairo_gstate_get_scaled_font (cr->gstate, &scaled_font);
- if (status) {
+ if (unlikely (status)) {
_cairo_set_error (cr, status);
return _cairo_scaled_font_create_in_error (status);
}
@@ -3047,7 +3050,7 @@ cairo_text_extents (cairo_t *cr,
extents);
cairo_glyph_free (glyphs);
- if (status)
+ if (unlikely (status))
_cairo_set_error (cr, status);
}
@@ -3102,7 +3105,7 @@ cairo_glyph_extents (cairo_t *cr,
status = _cairo_gstate_glyph_extents (cr->gstate, glyphs, num_glyphs,
extents);
- if (status)
+ if (unlikely (status))
_cairo_set_error (cr, status);
}
@@ -3172,7 +3175,7 @@ cairo_show_text (cairo_t *cr, const char *utf8)
&glyphs, &num_glyphs,
has_show_text_glyphs ? &clusters : NULL, &num_clusters,
&cluster_flags);
- if (status)
+ if (unlikely (status))
goto BAIL;
if (num_glyphs == 0)
@@ -3183,14 +3186,14 @@ cairo_show_text (cairo_t *cr, const char *utf8)
glyphs, num_glyphs,
clusters, num_clusters,
cluster_flags);
- if (status)
+ if (unlikely (status))
goto BAIL;
last_glyph = &glyphs[num_glyphs - 1];
status = _cairo_gstate_glyph_extents (cr->gstate,
last_glyph, 1,
&extents);
- if (status)
+ if (unlikely (status))
goto BAIL;
x = last_glyph->x + extents.x_advance;
@@ -3203,7 +3206,7 @@ cairo_show_text (cairo_t *cr, const char *utf8)
if (clusters != stack_clusters)
cairo_text_cluster_free (clusters);
- if (status)
+ if (unlikely (status))
_cairo_set_error (cr, status);
}
@@ -3243,7 +3246,7 @@ cairo_show_glyphs (cairo_t *cr, const cairo_glyph_t *glyphs, int num_glyphs)
glyphs, num_glyphs,
NULL, 0,
FALSE);
- if (status)
+ if (unlikely (status))
_cairo_set_error (cr, status);
}
@@ -3346,7 +3349,7 @@ cairo_show_text_glyphs (cairo_t *cr,
utf8, utf8_len,
glyphs, num_glyphs,
clusters, num_clusters, cluster_flags);
- if (status)
+ if (unlikely (status))
_cairo_set_error (cr, status);
}
@@ -3398,7 +3401,7 @@ cairo_text_path (cairo_t *cr, const char *utf8)
NULL, NULL,
NULL);
- if (status)
+ if (unlikely (status))
goto BAIL;
if (num_glyphs == 0)
@@ -3408,7 +3411,7 @@ cairo_text_path (cairo_t *cr, const char *utf8)
glyphs, num_glyphs,
cr->path);
- if (status)
+ if (unlikely (status))
goto BAIL;
last_glyph = &glyphs[num_glyphs - 1];
@@ -3416,7 +3419,7 @@ cairo_text_path (cairo_t *cr, const char *utf8)
last_glyph, 1,
&extents);
- if (status)
+ if (unlikely (status))
goto BAIL;
x = last_glyph->x + extents.x_advance;
@@ -3426,7 +3429,7 @@ cairo_text_path (cairo_t *cr, const char *utf8)
BAIL:
cairo_glyph_free (glyphs);
- if (status)
+ if (unlikely (status))
_cairo_set_error (cr, status);
}
@@ -3464,7 +3467,7 @@ cairo_glyph_path (cairo_t *cr, const cairo_glyph_t *glyphs, int num_glyphs)
status = _cairo_gstate_glyph_path (cr->gstate,
glyphs, num_glyphs,
cr->path);
- if (status)
+ if (unlikely (status))
_cairo_set_error (cr, status);
}
@@ -3884,7 +3887,7 @@ cairo_append_path (cairo_t *cr,
}
status = _cairo_path_append_to_context (path, cr);
- if (status)
+ if (unlikely (status))
_cairo_set_error (cr, status);
}
diff --git a/src/cairoint.h b/src/cairoint.h
index 18f5a560..611f07ec 100644
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -234,6 +234,7 @@ be32_to_cpu(uint32_t v)
#include "cairo-types-private.h"
#include "cairo-cache-private.h"
#include "cairo-reference-count-private.h"
+#include "cairo-spans-private.h"
cairo_private void
_cairo_box_from_doubles (cairo_box_t *box,
@@ -263,6 +264,13 @@ _cairo_box_intersects_line_segment (cairo_box_t *box, cairo_line_t *line);
cairo_private cairo_bool_t
_cairo_box_contains_point (cairo_box_t *box, cairo_point_t *point);
+cairo_private void
+_cairo_composite_rectangles_init (cairo_composite_rectangles_t *rects,
+ int all_x,
+ int all_y,
+ int width,
+ int height);
+
/* cairo-array.c structures and functions */
cairo_private void
@@ -626,6 +634,20 @@ struct _cairo_surface_backend {
cairo_trapezoid_t *traps,
int num_traps);
+ cairo_warn cairo_span_renderer_t *
+ (*create_span_renderer) (cairo_operator_t op,
+ const cairo_pattern_t *pattern,
+ void *dst,
+ cairo_antialias_t antialias,
+ const cairo_composite_rectangles_t *rects);
+
+ cairo_warn cairo_bool_t
+ (*check_span_renderer) (cairo_operator_t op,
+ const cairo_pattern_t *pattern,
+ void *dst,
+ cairo_antialias_t antialias,
+ const cairo_composite_rectangles_t *rects);
+
cairo_warn cairo_int_status_t
(*copy_page) (void *surface);
@@ -1299,6 +1321,20 @@ _cairo_gstate_glyph_path (cairo_gstate_t *gstate,
int num_glyphs,
cairo_path_fixed_t *path);
+cairo_private cairo_status_t
+_cairo_gtate_begin_damage_tracking (cairo_gstate_t *gstate);
+
+cairo_private cairo_status_t
+_cairo_gstate_end_damage_tracking (cairo_gstate_t *gstate,
+ int *n_rectangles,
+ cairo_rectangle_t **rectangles);
+cairo_private cairo_status_t
+_cairo_gstate_set_antialias (cairo_gstate_t *gstate,
+ cairo_antialias_t antialias);
+
+cairo_private cairo_antialias_t
+_cairo_gstate_get_antialias (cairo_gstate_t *gstate);
+
cairo_private cairo_bool_t
_cairo_operator_bounded_by_mask (cairo_operator_t op) cairo_pure;
@@ -1545,6 +1581,9 @@ cairo_private cairo_bool_t
_cairo_path_fixed_is_rectangle (cairo_path_fixed_t *path,
cairo_box_t *box);
+cairo_private cairo_bool_t
+_cairo_path_fixed_is_region (cairo_path_fixed_t *path);
+
/* cairo-path-in-fill.c */
cairo_private void
_cairo_path_fixed_in_fill (cairo_path_fixed_t *path,
@@ -1861,6 +1900,22 @@ _cairo_surface_composite_trapezoids (cairo_operator_t op,
cairo_trapezoid_t *traps,
int ntraps);
+cairo_private cairo_span_renderer_t *
+_cairo_surface_create_span_renderer (
+ cairo_operator_t op,
+ const cairo_pattern_t *pattern,
+ cairo_surface_t *dst,
+ cairo_antialias_t antialias,
+ const cairo_composite_rectangles_t *rects);
+
+cairo_private cairo_bool_t
+_cairo_surface_check_span_renderer (
+ cairo_operator_t op,
+ const cairo_pattern_t *pattern,
+ cairo_surface_t *dst,
+ cairo_antialias_t antialias,
+ const cairo_composite_rectangles_t *rects);
+
cairo_private cairo_status_t
_cairo_surface_acquire_source_image (cairo_surface_t *surface,
cairo_image_surface_t **image_out,
@@ -2452,13 +2507,6 @@ _cairo_pattern_equal (const cairo_pattern_t *a,
cairo_private void
_cairo_pattern_reset_static_data (void);
-cairo_private cairo_status_t
-_cairo_gstate_set_antialias (cairo_gstate_t *gstate,
- cairo_antialias_t antialias);
-
-cairo_private cairo_antialias_t
-_cairo_gstate_get_antialias (cairo_gstate_t *gstate);
-
/* cairo-region.c */
#include "cairo-region-private.h"
diff --git a/src/check-doc-syntax.sh b/src/check-doc-syntax.sh
index abf526da..a5c84628 100755
--- a/src/check-doc-syntax.sh
+++ b/src/check-doc-syntax.sh
@@ -64,7 +64,7 @@ if echo $FILES | xargs grep . /dev/null | sed -e '/<programlisting>/,/<\/program
echo " '$func_regexp'"
fi >&2
-note_regexp='NOTE'
+note_regexp='\<NOTE\>'
if echo $FILES | xargs grep "$note_regexp" /dev/null; then
stat=1
echo Error: some source files contain the string 'NOTE'.
diff --git a/src/test-fallback-surface.c b/src/test-fallback-surface.c
index 883941df..8acd91ee 100644
--- a/src/test-fallback-surface.c
+++ b/src/test-fallback-surface.c
@@ -79,7 +79,7 @@ _cairo_test_fallback_surface_create (cairo_content_t content,
return backing;
surface = malloc (sizeof (test_fallback_surface_t));
- if (surface == NULL) {
+ if (unlikely (surface == NULL)) {
cairo_surface_destroy (backing);
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
}
@@ -214,6 +214,8 @@ static const cairo_surface_backend_t test_fallback_surface_backend = {
NULL, /* composite */
NULL, /* fill_rectangles */
NULL, /* composite_trapezoids */
+ NULL, /* create_span_renderer */
+ NULL, /* check_span_renderer */
NULL, /* copy_page */
NULL, /* show_page */
NULL, /* set_clip_region */
diff --git a/src/test-meta-surface.c b/src/test-meta-surface.c
index 71700bdd..42bf6b0c 100644
--- a/src/test-meta-surface.c
+++ b/src/test-meta-surface.c
@@ -77,7 +77,7 @@ _cairo_test_meta_surface_create (cairo_content_t content,
cairo_status_t status;
surface = malloc (sizeof (test_meta_surface_t));
- if (surface == NULL) {
+ if (unlikely (surface == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto FAIL;
}
@@ -313,6 +313,8 @@ static const cairo_surface_backend_t test_meta_surface_backend = {
NULL, /* composite */
NULL, /* fill_rectangles */
NULL, /* composite_trapezoids */
+ NULL, /* create_span_renderer */
+ NULL, /* check_span_renderer */
NULL, /* copy_page */
_test_meta_surface_show_page,
NULL, /* set_clip_region */
diff --git a/src/test-paginated-surface.c b/src/test-paginated-surface.c
index cfb87f33..4c566470 100644
--- a/src/test-paginated-surface.c
+++ b/src/test-paginated-surface.c
@@ -80,7 +80,7 @@ _cairo_test_paginated_surface_create_for_data (unsigned char *data,
return target;
surface = malloc (sizeof (test_paginated_surface_t));
- if (surface == NULL) {
+ if (unlikely (surface == NULL)) {
cairo_surface_destroy (target);
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
}
@@ -298,6 +298,8 @@ static const cairo_surface_backend_t test_paginated_surface_backend = {
NULL, /* composite */
NULL, /* fill_rectangles */
NULL, /* composite_trapezoids */
+ NULL, /* create_span_renderer */
+ NULL, /* check_span_renderer */
NULL, /* copy_page */
NULL, /* show_page */
_test_paginated_surface_set_clip_region,
diff --git a/test/Makefile.am b/test/Makefile.am
index 3afac519..de9f9c47 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -13,8 +13,10 @@ test_sources = \
big-line.c \
big-trap.c \
bilevel-image.c \
+ caps.c \
caps-joins.c \
caps-joins-alpha.c \
+ caps-joins-curve.c \
caps-sub-paths.c \
clip-all.c \
clip-empty.c \
@@ -212,7 +214,11 @@ test_sources += ft-text-vertical-layout-type3.c
test_sources += ft-text-antialias-none.c
endif
-# Need to add win32-surface-source, quartz-surface-source
+# Need to add quartz-surface-source
+if CAIRO_HAS_QUARTZ_SURFACE
+test_sources += quartz-surface-source.c
+endif
+
if CAIRO_HAS_GLITZ_SURFACE
test_sources += glitz-surface-source.c
endif
@@ -294,6 +300,10 @@ if HAVE_PTHREAD
cairo_test_suite_LDADD += -lpthread
endif
+if CAIRO_HAS_SDL_SURFACE
+cairo_test_suite_LDADD += $(sdl_LIBS)
+endif
+
BUILT_SOURCES += cairo-test-constructors.c
noinst_SCRIPTS = make-cairo-test-constructors.pl
EXTRA_DIST += $(BUILT_SOURCES) $(noinst_SCRIPTS) COPYING
@@ -318,13 +328,16 @@ REFERENCE_IMAGES = \
bilevel-image.ref.png \
bitmap-font.ref.png \
bitmap-font.rgb24.ref.png \
+ caps.ref.png \
+ caps.ps.ref.png \
caps-joins-alpha.quartz.ref.png \
caps-joins-alpha.ref.png \
caps-joins-alpha.svg12.ref.png \
caps-joins-alpha.svg11.ref.png \
+ caps-joins-curve.ref.png \
+ caps-joins-curve.ps.ref.png \
caps-joins.ref.png \
- caps-joins.ps2.ref.png \
- caps-joins.ps3.ref.png \
+ caps-joins.ps.ref.png \
caps-sub-paths.ref.png \
clip-all.ref.png \
clip-empty.ref.png \
diff --git a/test/cairo-test-runner.c b/test/cairo-test-runner.c
index 4fb0cbea..aec90ff7 100644
--- a/test/cairo-test-runner.c
+++ b/test/cairo-test-runner.c
@@ -33,6 +33,10 @@
#undef CAIRO_VERSION_MICRO
#include "../cairo-version.h"
+#if CAIRO_HAS_SDL_SURFACE
+#include <SDL_main.h>
+#endif
+
#include <pixman.h> /* for version information */
#if HAVE_FORK && HAVE_WAITPID
diff --git a/test/caps-joins-curve.c b/test/caps-joins-curve.c
new file mode 100644
index 00000000..1b2fc7f0
--- /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-curve.ps.ref.png b/test/caps-joins-curve.ps.ref.png
new file mode 100644
index 00000000..1f7e2000
--- /dev/null
+++ b/test/caps-joins-curve.ps.ref.png
Binary files differ
diff --git a/test/caps-joins-curve.ref.png b/test/caps-joins-curve.ref.png
new file mode 100644
index 00000000..9f763013
--- /dev/null
+++ b/test/caps-joins-curve.ref.png
Binary files differ
diff --git a/test/caps-joins.c b/test/caps-joins.c
index 5ec6a817..9d1c2a88 100644
--- a/test/caps-joins.c
+++ b/test/caps-joins.c
@@ -37,21 +37,15 @@ make_path (cairo_t *cr)
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);
+ 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 cairo_test_status_t
-draw (cairo_t *cr, int width, int height)
+static void
+draw_caps_joins (cairo_t *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);
-
- cairo_set_line_width (cr, LINE_WIDTH);
cairo_translate (cr, PAD, PAD);
@@ -74,6 +68,28 @@ draw (cairo_t *cr, int width, int height)
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;
}
@@ -82,6 +98,6 @@ CAIRO_TEST (caps_joins,
"stroke", /* keywords */
NULL, /* requirements */
3 * (PAD + SIZE) + PAD,
- PAD + SIZE + PAD,
+ 2 * (PAD + SIZE) + PAD,
NULL, draw)
diff --git a/test/caps-joins.ps.ref.png b/test/caps-joins.ps.ref.png
new file mode 100644
index 00000000..e61aafce
--- /dev/null
+++ b/test/caps-joins.ps.ref.png
Binary files differ
diff --git a/test/caps-joins.ps2.ref.png b/test/caps-joins.ps2.ref.png
deleted file mode 100644
index 1d473ac7..00000000
--- a/test/caps-joins.ps2.ref.png
+++ /dev/null
Binary files differ
diff --git a/test/caps-joins.ps3.ref.png b/test/caps-joins.ps3.ref.png
deleted file mode 100644
index 1d473ac7..00000000
--- a/test/caps-joins.ps3.ref.png
+++ /dev/null
Binary files differ
diff --git a/test/caps-joins.ref.png b/test/caps-joins.ref.png
index 9297ac4d..d83f9561 100644
--- a/test/caps-joins.ref.png
+++ b/test/caps-joins.ref.png
Binary files differ
diff --git a/test/caps.c b/test/caps.c
new file mode 100644
index 00000000..7f561179
--- /dev/null
+++ b/test/caps.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 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, 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 + 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;
+}
+
+CAIRO_TEST (caps,
+ "Test caps",
+ "stroke caps", /* keywords */
+ NULL, /* requirements */
+ PAD + SIZE + PAD,
+ 3 * (PAD + SIZE) + PAD,
+ NULL, draw)
+
diff --git a/test/caps.ps.ref.png b/test/caps.ps.ref.png
new file mode 100644
index 00000000..b1f4a72a
--- /dev/null
+++ b/test/caps.ps.ref.png
Binary files differ
diff --git a/test/caps.ref.png b/test/caps.ref.png
new file mode 100644
index 00000000..a46e0366
--- /dev/null
+++ b/test/caps.ref.png
Binary files differ
diff --git a/test/clip-fill-rule.pdf.argb32.ref.png b/test/clip-fill-rule.pdf.argb32.ref.png
new file mode 100644
index 00000000..0d9938e7
--- /dev/null
+++ b/test/clip-fill-rule.pdf.argb32.ref.png
Binary files differ
diff --git a/test/clip-fill-rule.rgb24.ref.png b/test/clip-fill-rule.rgb24.ref.png
index a969e367..050bd666 100644
--- a/test/clip-fill-rule.rgb24.ref.png
+++ b/test/clip-fill-rule.rgb24.ref.png
Binary files differ
diff --git a/test/clip-fill-rule.test-fallback.rgb24.ref.png b/test/clip-fill-rule.test-fallback.rgb24.ref.png
new file mode 100644
index 00000000..d21472dc
--- /dev/null
+++ b/test/clip-fill-rule.test-fallback.rgb24.ref.png
Binary files differ
diff --git a/test/clip-fill-rule.test-paginated.rgb24.ref.png b/test/clip-fill-rule.test-paginated.rgb24.ref.png
new file mode 100644
index 00000000..d21472dc
--- /dev/null
+++ b/test/clip-fill-rule.test-paginated.rgb24.ref.png
Binary files differ
diff --git a/test/clip-fill-rule.xlib.rgb24.ref.png b/test/clip-fill-rule.xlib.rgb24.ref.png
new file mode 100644
index 00000000..a969e367
--- /dev/null
+++ b/test/clip-fill-rule.xlib.rgb24.ref.png
Binary files differ
diff --git a/test/clip-nesting.pdf.argb32.ref.png b/test/clip-nesting.pdf.argb32.ref.png
new file mode 100644
index 00000000..78ae6e08
--- /dev/null
+++ b/test/clip-nesting.pdf.argb32.ref.png
Binary files differ
diff --git a/test/clip-nesting.rgb24.ref.png b/test/clip-nesting.rgb24.ref.png
index e2488f34..a014763d 100644
--- a/test/clip-nesting.rgb24.ref.png
+++ b/test/clip-nesting.rgb24.ref.png
Binary files differ
diff --git a/test/clip-nesting.test-fallback.rgb24.ref.png b/test/clip-nesting.test-fallback.rgb24.ref.png
new file mode 100644
index 00000000..d087ab6c
--- /dev/null
+++ b/test/clip-nesting.test-fallback.rgb24.ref.png
Binary files differ
diff --git a/test/clip-nesting.test-paginated.rgb24.ref.png b/test/clip-nesting.test-paginated.rgb24.ref.png
new file mode 100644
index 00000000..d087ab6c
--- /dev/null
+++ b/test/clip-nesting.test-paginated.rgb24.ref.png
Binary files differ
diff --git a/test/clip-nesting.xlib.rgb24.ref.png b/test/clip-nesting.xlib.rgb24.ref.png
new file mode 100644
index 00000000..e2488f34
--- /dev/null
+++ b/test/clip-nesting.xlib.rgb24.ref.png
Binary files differ
diff --git a/test/clip-operator.pdf.argb32.ref.png b/test/clip-operator.pdf.argb32.ref.png
index b3ee1437..e2fdc8d1 100644
--- a/test/clip-operator.pdf.argb32.ref.png
+++ b/test/clip-operator.pdf.argb32.ref.png
Binary files differ
diff --git a/test/clip-operator.pdf.rgb24.ref.png b/test/clip-operator.pdf.rgb24.ref.png
index b420f385..6590dd88 100644
--- a/test/clip-operator.pdf.rgb24.ref.png
+++ b/test/clip-operator.pdf.rgb24.ref.png
Binary files differ
diff --git a/test/clip-operator.ps2.rgb24.ref.png b/test/clip-operator.ps2.rgb24.ref.png
index 6ed9fc45..52452993 100644
--- a/test/clip-operator.ps2.rgb24.ref.png
+++ b/test/clip-operator.ps2.rgb24.ref.png
Binary files differ
diff --git a/test/clip-operator.ps3.argb32.ref.png b/test/clip-operator.ps3.argb32.ref.png
new file mode 100644
index 00000000..cd207d92
--- /dev/null
+++ b/test/clip-operator.ps3.argb32.ref.png
Binary files differ
diff --git a/test/clip-operator.ps3.rgb24.ref.png b/test/clip-operator.ps3.rgb24.ref.png
index 6ed9fc45..52452993 100644
--- a/test/clip-operator.ps3.rgb24.ref.png
+++ b/test/clip-operator.ps3.rgb24.ref.png
Binary files differ
diff --git a/test/clip-operator.ref.png b/test/clip-operator.ref.png
index 4ea1842e..3a685f5e 100644
--- a/test/clip-operator.ref.png
+++ b/test/clip-operator.ref.png
Binary files differ
diff --git a/test/clip-operator.rgb24.ref.png b/test/clip-operator.rgb24.ref.png
index 7ab964c3..0a4d4c09 100644
--- a/test/clip-operator.rgb24.ref.png
+++ b/test/clip-operator.rgb24.ref.png
Binary files differ
diff --git a/test/clip-operator.test-fallback.argb32.ref.png b/test/clip-operator.test-fallback.argb32.ref.png
new file mode 100644
index 00000000..f53e4921
--- /dev/null
+++ b/test/clip-operator.test-fallback.argb32.ref.png
Binary files differ
diff --git a/test/clip-operator.test-fallback.rgb24.ref.png b/test/clip-operator.test-fallback.rgb24.ref.png
new file mode 100644
index 00000000..7579ae69
--- /dev/null
+++ b/test/clip-operator.test-fallback.rgb24.ref.png
Binary files differ
diff --git a/test/clip-operator.test-paginated.argb32.ref.png b/test/clip-operator.test-paginated.argb32.ref.png
new file mode 100644
index 00000000..22e080a2
--- /dev/null
+++ b/test/clip-operator.test-paginated.argb32.ref.png
Binary files differ
diff --git a/test/clip-operator.xlib-fallback.rgb24.ref.png b/test/clip-operator.xlib-fallback.rgb24.ref.png
new file mode 100644
index 00000000..4a05f7ba
--- /dev/null
+++ b/test/clip-operator.xlib-fallback.rgb24.ref.png
Binary files differ
diff --git a/test/clip-operator.xlib.ref.png b/test/clip-operator.xlib.ref.png
new file mode 100644
index 00000000..4ea1842e
--- /dev/null
+++ b/test/clip-operator.xlib.ref.png
Binary files differ
diff --git a/test/clip-operator.xlib.rgb24.ref.png b/test/clip-operator.xlib.rgb24.ref.png
new file mode 100644
index 00000000..7ab964c3
--- /dev/null
+++ b/test/clip-operator.xlib.rgb24.ref.png
Binary files differ
diff --git a/test/clip-twice.pdf.argb32.ref.png b/test/clip-twice.pdf.argb32.ref.png
new file mode 100644
index 00000000..2a7541fe
--- /dev/null
+++ b/test/clip-twice.pdf.argb32.ref.png
Binary files differ
diff --git a/test/clip-twice.ref.png b/test/clip-twice.ref.png
index 8dc86f30..4aafc9ac 100644
--- a/test/clip-twice.ref.png
+++ b/test/clip-twice.ref.png
Binary files differ
diff --git a/test/clip-twice.rgb24.ref.png b/test/clip-twice.rgb24.ref.png
index 3f1c013b..25c44ef7 100644
--- a/test/clip-twice.rgb24.ref.png
+++ b/test/clip-twice.rgb24.ref.png
Binary files differ
diff --git a/test/clip-twice.test-fallback.argb32.ref.png b/test/clip-twice.test-fallback.argb32.ref.png
new file mode 100644
index 00000000..ba621807
--- /dev/null
+++ b/test/clip-twice.test-fallback.argb32.ref.png
Binary files differ
diff --git a/test/clip-twice.test-fallback.rgb24.ref.png b/test/clip-twice.test-fallback.rgb24.ref.png
new file mode 100644
index 00000000..9cbdc4d4
--- /dev/null
+++ b/test/clip-twice.test-fallback.rgb24.ref.png
Binary files differ
diff --git a/test/clip-twice.test-paginated.argb32.ref.png b/test/clip-twice.test-paginated.argb32.ref.png
new file mode 100644
index 00000000..ffd59aaf
--- /dev/null
+++ b/test/clip-twice.test-paginated.argb32.ref.png
Binary files differ
diff --git a/test/clip-twice.test-paginated.rgb24.ref.png b/test/clip-twice.test-paginated.rgb24.ref.png
new file mode 100644
index 00000000..e3d0ae49
--- /dev/null
+++ b/test/clip-twice.test-paginated.rgb24.ref.png
Binary files differ
diff --git a/test/clip-twice.xlib.ref.png b/test/clip-twice.xlib.ref.png
new file mode 100644
index 00000000..8dc86f30
--- /dev/null
+++ b/test/clip-twice.xlib.ref.png
Binary files differ
diff --git a/test/clip-twice.xlib.rgb24.ref.png b/test/clip-twice.xlib.rgb24.ref.png
new file mode 100644
index 00000000..3f1c013b
--- /dev/null
+++ b/test/clip-twice.xlib.rgb24.ref.png
Binary files differ
diff --git a/test/clipped-group.pdf.argb32.ref.png b/test/clipped-group.pdf.argb32.ref.png
new file mode 100644
index 00000000..b9975e12
--- /dev/null
+++ b/test/clipped-group.pdf.argb32.ref.png
Binary files differ
diff --git a/test/clipped-group.pdf.rgb24.ref.png b/test/clipped-group.pdf.rgb24.ref.png
new file mode 100644
index 00000000..b9975e12
--- /dev/null
+++ b/test/clipped-group.pdf.rgb24.ref.png
Binary files differ
diff --git a/test/dash-curve.ref.png b/test/dash-curve.ref.png
index 542b2d82..a590fc43 100644
--- a/test/dash-curve.ref.png
+++ b/test/dash-curve.ref.png
Binary files differ
diff --git a/test/degenerate-arc.ref.png b/test/degenerate-arc.ref.png
index 5112d7f9..1d131b22 100644
--- a/test/degenerate-arc.ref.png
+++ b/test/degenerate-arc.ref.png
Binary files differ
diff --git a/test/degenerate-arc.test-fallback.argb32.ref.png b/test/degenerate-arc.test-fallback.argb32.ref.png
new file mode 100644
index 00000000..73d41afa
--- /dev/null
+++ b/test/degenerate-arc.test-fallback.argb32.ref.png
Binary files differ
diff --git a/test/degenerate-arc.test-fallback.rgb24.ref.png b/test/degenerate-arc.test-fallback.rgb24.ref.png
new file mode 100644
index 00000000..73d41afa
--- /dev/null
+++ b/test/degenerate-arc.test-fallback.rgb24.ref.png
Binary files differ
diff --git a/test/degenerate-arc.xlib.ref.png b/test/degenerate-arc.xlib.ref.png
new file mode 100644
index 00000000..5112d7f9
--- /dev/null
+++ b/test/degenerate-arc.xlib.ref.png
Binary files differ
diff --git a/test/device-offset-fractional.pdf.argb32.ref.png b/test/device-offset-fractional.pdf.argb32.ref.png
new file mode 100644
index 00000000..c076932c
--- /dev/null
+++ b/test/device-offset-fractional.pdf.argb32.ref.png
Binary files differ
diff --git a/test/device-offset-fractional.pdf.rgb24.ref.png b/test/device-offset-fractional.pdf.rgb24.ref.png
new file mode 100644
index 00000000..c076932c
--- /dev/null
+++ b/test/device-offset-fractional.pdf.rgb24.ref.png
Binary files differ
diff --git a/test/device-offset-positive.c b/test/device-offset-positive.c
index 4ea9469d..5afe9730 100644
--- a/test/device-offset-positive.c
+++ b/test/device-offset-positive.c
@@ -67,6 +67,7 @@ draw (cairo_t *cr, int width, int height)
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);
diff --git a/test/fill-alpha-pattern.pdf.argb32.ref.png b/test/fill-alpha-pattern.pdf.argb32.ref.png
index d786c86a..d7a7ebe5 100644
--- a/test/fill-alpha-pattern.pdf.argb32.ref.png
+++ b/test/fill-alpha-pattern.pdf.argb32.ref.png
Binary files differ
diff --git a/test/fill-alpha-pattern.pdf.rgb24.ref.png b/test/fill-alpha-pattern.pdf.rgb24.ref.png
index 75e580fb..ef9049e2 100644
--- a/test/fill-alpha-pattern.pdf.rgb24.ref.png
+++ b/test/fill-alpha-pattern.pdf.rgb24.ref.png
Binary files differ
diff --git a/test/fill-alpha-pattern.ps3.argb32.ref.png b/test/fill-alpha-pattern.ps3.argb32.ref.png
new file mode 100644
index 00000000..b16731af
--- /dev/null
+++ b/test/fill-alpha-pattern.ps3.argb32.ref.png
Binary files differ
diff --git a/test/fill-alpha-pattern.ps3.rgb24.ref.png b/test/fill-alpha-pattern.ps3.rgb24.ref.png
new file mode 100644
index 00000000..d0193545
--- /dev/null
+++ b/test/fill-alpha-pattern.ps3.rgb24.ref.png
Binary files differ
diff --git a/test/fill-alpha-pattern.ref.png b/test/fill-alpha-pattern.ref.png
index 0031c04c..9ab39a7d 100644
--- a/test/fill-alpha-pattern.ref.png
+++ b/test/fill-alpha-pattern.ref.png
Binary files differ
diff --git a/test/fill-alpha-pattern.test-fallback.argb32.ref.png b/test/fill-alpha-pattern.test-fallback.argb32.ref.png
new file mode 100644
index 00000000..4dafb835
--- /dev/null
+++ b/test/fill-alpha-pattern.test-fallback.argb32.ref.png
Binary files differ
diff --git a/test/fill-alpha-pattern.test-fallback.rgb24.ref.png b/test/fill-alpha-pattern.test-fallback.rgb24.ref.png
new file mode 100644
index 00000000..4dafb835
--- /dev/null
+++ b/test/fill-alpha-pattern.test-fallback.rgb24.ref.png
Binary files differ
diff --git a/test/fill-alpha-pattern.xlib.ref.png b/test/fill-alpha-pattern.xlib.ref.png
new file mode 100644
index 00000000..0031c04c
--- /dev/null
+++ b/test/fill-alpha-pattern.xlib.ref.png
Binary files differ
diff --git a/test/fill-alpha.ref.png b/test/fill-alpha.ref.png
index 61aaac29..b50a456d 100644
--- a/test/fill-alpha.ref.png
+++ b/test/fill-alpha.ref.png
Binary files differ
diff --git a/test/fill-alpha.test-fallback.argb32.ref.png b/test/fill-alpha.test-fallback.argb32.ref.png
new file mode 100644
index 00000000..85df9198
--- /dev/null
+++ b/test/fill-alpha.test-fallback.argb32.ref.png
Binary files differ
diff --git a/test/fill-alpha.test-fallback.rgb24.ref.png b/test/fill-alpha.test-fallback.rgb24.ref.png
new file mode 100644
index 00000000..85df9198
--- /dev/null
+++ b/test/fill-alpha.test-fallback.rgb24.ref.png
Binary files differ
diff --git a/test/fill-alpha.xlib.ref.png b/test/fill-alpha.xlib.ref.png
new file mode 100644
index 00000000..61aaac29
--- /dev/null
+++ b/test/fill-alpha.xlib.ref.png
Binary files differ
diff --git a/test/fill-degenerate-sort-order.ref.png b/test/fill-degenerate-sort-order.ref.png
index 8278d76e..3a95c257 100644
--- a/test/fill-degenerate-sort-order.ref.png
+++ b/test/fill-degenerate-sort-order.ref.png
Binary files differ
diff --git a/test/fill-degenerate-sort-order.rgb24.ref.png b/test/fill-degenerate-sort-order.rgb24.ref.png
index 6c76eaf4..377c7087 100644
--- a/test/fill-degenerate-sort-order.rgb24.ref.png
+++ b/test/fill-degenerate-sort-order.rgb24.ref.png
Binary files differ
diff --git a/test/fill-degenerate-sort-order.test-fallback.argb32.ref.png b/test/fill-degenerate-sort-order.test-fallback.argb32.ref.png
new file mode 100644
index 00000000..8cf567dd
--- /dev/null
+++ b/test/fill-degenerate-sort-order.test-fallback.argb32.ref.png
Binary files differ
diff --git a/test/fill-degenerate-sort-order.test-fallback.rgb24.ref.png b/test/fill-degenerate-sort-order.test-fallback.rgb24.ref.png
new file mode 100644
index 00000000..da5aa50a
--- /dev/null
+++ b/test/fill-degenerate-sort-order.test-fallback.rgb24.ref.png
Binary files differ
diff --git a/test/fill-degenerate-sort-order.xlib.ref.png b/test/fill-degenerate-sort-order.xlib.ref.png
new file mode 100644
index 00000000..8278d76e
--- /dev/null
+++ b/test/fill-degenerate-sort-order.xlib.ref.png
Binary files differ
diff --git a/test/fill-degenerate-sort-order.xlib.rgb24.ref.png b/test/fill-degenerate-sort-order.xlib.rgb24.ref.png
new file mode 100644
index 00000000..6c76eaf4
--- /dev/null
+++ b/test/fill-degenerate-sort-order.xlib.rgb24.ref.png
Binary files differ
diff --git a/test/fill-missed-stop.pdf.argb32.ref.png b/test/fill-missed-stop.pdf.argb32.ref.png
new file mode 100644
index 00000000..7d56e3e8
--- /dev/null
+++ b/test/fill-missed-stop.pdf.argb32.ref.png
Binary files differ
diff --git a/test/fill-rule.ref.png b/test/fill-rule.ref.png
index e2e10d4a..6e19b621 100644
--- a/test/fill-rule.ref.png
+++ b/test/fill-rule.ref.png
Binary files differ
diff --git a/test/fill-rule.rgb24.ref.png b/test/fill-rule.rgb24.ref.png
index 68d2b9b8..bdfc12f4 100644
--- a/test/fill-rule.rgb24.ref.png
+++ b/test/fill-rule.rgb24.ref.png
Binary files differ
diff --git a/test/fill-rule.test-fallback.argb32.ref.png b/test/fill-rule.test-fallback.argb32.ref.png
new file mode 100644
index 00000000..e2e10d4a
--- /dev/null
+++ b/test/fill-rule.test-fallback.argb32.ref.png
Binary files differ
diff --git a/test/fill-rule.test-fallback.rgb24.ref.png b/test/fill-rule.test-fallback.rgb24.ref.png
new file mode 100644
index 00000000..49fb39c7
--- /dev/null
+++ b/test/fill-rule.test-fallback.rgb24.ref.png
Binary files differ
diff --git a/test/fill-rule.xlib.ref.png b/test/fill-rule.xlib.ref.png
new file mode 100644
index 00000000..e2e10d4a
--- /dev/null
+++ b/test/fill-rule.xlib.ref.png
Binary files differ
diff --git a/test/fill-rule.xlib.rgb24.ref.png b/test/fill-rule.xlib.rgb24.ref.png
new file mode 100644
index 00000000..68d2b9b8
--- /dev/null
+++ b/test/fill-rule.xlib.rgb24.ref.png
Binary files differ
diff --git a/test/filter-nearest-offset.pdf.argb32.ref.png b/test/filter-nearest-offset.pdf.argb32.ref.png
new file mode 100644
index 00000000..3475cb6e
--- /dev/null
+++ b/test/filter-nearest-offset.pdf.argb32.ref.png
Binary files differ
diff --git a/test/filter-nearest-offset.pdf.rgb24.ref.png b/test/filter-nearest-offset.pdf.rgb24.ref.png
new file mode 100644
index 00000000..3475cb6e
--- /dev/null
+++ b/test/filter-nearest-offset.pdf.rgb24.ref.png
Binary files differ
diff --git a/test/filter-nearest-transformed.pdf.argb32.ref.png b/test/filter-nearest-transformed.pdf.argb32.ref.png
new file mode 100644
index 00000000..40169593
--- /dev/null
+++ b/test/filter-nearest-transformed.pdf.argb32.ref.png
Binary files differ
diff --git a/test/filter-nearest-transformed.pdf.rgb24.ref.png b/test/filter-nearest-transformed.pdf.rgb24.ref.png
new file mode 100644
index 00000000..40169593
--- /dev/null
+++ b/test/filter-nearest-transformed.pdf.rgb24.ref.png
Binary files differ
diff --git a/test/finer-grained-fallbacks.ps2.argb32.ref.png b/test/finer-grained-fallbacks.ps2.argb32.ref.png
new file mode 100644
index 00000000..92cd9517
--- /dev/null
+++ b/test/finer-grained-fallbacks.ps2.argb32.ref.png
Binary files differ
diff --git a/test/finer-grained-fallbacks.ps2.rgb24.ref.png b/test/finer-grained-fallbacks.ps2.rgb24.ref.png
index de482860..688c3e06 100644
--- a/test/finer-grained-fallbacks.ps2.rgb24.ref.png
+++ b/test/finer-grained-fallbacks.ps2.rgb24.ref.png
Binary files differ
diff --git a/test/finer-grained-fallbacks.ps3.argb32.ref.png b/test/finer-grained-fallbacks.ps3.argb32.ref.png
new file mode 100644
index 00000000..92cd9517
--- /dev/null
+++ b/test/finer-grained-fallbacks.ps3.argb32.ref.png
Binary files differ
diff --git a/test/finer-grained-fallbacks.ps3.rgb24.ref.png b/test/finer-grained-fallbacks.ps3.rgb24.ref.png
index de482860..688c3e06 100644
--- a/test/finer-grained-fallbacks.ps3.rgb24.ref.png
+++ b/test/finer-grained-fallbacks.ps3.rgb24.ref.png
Binary files differ
diff --git a/test/finer-grained-fallbacks.ref.png b/test/finer-grained-fallbacks.ref.png
index c7eb113d..5b1e532b 100644
--- a/test/finer-grained-fallbacks.ref.png
+++ b/test/finer-grained-fallbacks.ref.png
Binary files differ
diff --git a/test/finer-grained-fallbacks.rgb24.ref.png b/test/finer-grained-fallbacks.rgb24.ref.png
index 3b8e9c38..d3997fe1 100644
--- a/test/finer-grained-fallbacks.rgb24.ref.png
+++ b/test/finer-grained-fallbacks.rgb24.ref.png
Binary files differ
diff --git a/test/finer-grained-fallbacks.test-fallback.argb32.ref.png b/test/finer-grained-fallbacks.test-fallback.argb32.ref.png
new file mode 100644
index 00000000..c7eb113d
--- /dev/null
+++ b/test/finer-grained-fallbacks.test-fallback.argb32.ref.png
Binary files differ
diff --git a/test/finer-grained-fallbacks.test-fallback.rgb24.ref.png b/test/finer-grained-fallbacks.test-fallback.rgb24.ref.png
new file mode 100644
index 00000000..ff75c6dd
--- /dev/null
+++ b/test/finer-grained-fallbacks.test-fallback.rgb24.ref.png
Binary files differ
diff --git a/test/finer-grained-fallbacks.xlib.ref.png b/test/finer-grained-fallbacks.xlib.ref.png
new file mode 100644
index 00000000..c7eb113d
--- /dev/null
+++ b/test/finer-grained-fallbacks.xlib.ref.png
Binary files differ
diff --git a/test/finer-grained-fallbacks.xlib.rgb24.ref.png b/test/finer-grained-fallbacks.xlib.rgb24.ref.png
new file mode 100644
index 00000000..3b8e9c38
--- /dev/null
+++ b/test/finer-grained-fallbacks.xlib.rgb24.ref.png
Binary files differ
diff --git a/test/font-matrix-translation.svg11.argb32.ref.png b/test/font-matrix-translation.svg11.argb32.ref.png
new file mode 100644
index 00000000..441f6e3b
--- /dev/null
+++ b/test/font-matrix-translation.svg11.argb32.ref.png
Binary files differ
diff --git a/test/font-matrix-translation.svg11.rgb24.ref.png b/test/font-matrix-translation.svg11.rgb24.ref.png
new file mode 100644
index 00000000..441f6e3b
--- /dev/null
+++ b/test/font-matrix-translation.svg11.rgb24.ref.png
Binary files differ
diff --git a/test/font-matrix-translation.svg12.argb32.ref.png b/test/font-matrix-translation.svg12.argb32.ref.png
new file mode 100644
index 00000000..441f6e3b
--- /dev/null
+++ b/test/font-matrix-translation.svg12.argb32.ref.png
Binary files differ
diff --git a/test/font-matrix-translation.svg12.rgb24.ref.png b/test/font-matrix-translation.svg12.rgb24.ref.png
new file mode 100644
index 00000000..441f6e3b
--- /dev/null
+++ b/test/font-matrix-translation.svg12.rgb24.ref.png
Binary files differ
diff --git a/test/ft-show-glyphs-table.svg11.argb32.ref.png b/test/ft-show-glyphs-table.svg11.argb32.ref.png
new file mode 100644
index 00000000..0c6e1c0b
--- /dev/null
+++ b/test/ft-show-glyphs-table.svg11.argb32.ref.png
Binary files differ
diff --git a/test/ft-show-glyphs-table.svg11.rgb24.ref.png b/test/ft-show-glyphs-table.svg11.rgb24.ref.png
new file mode 100644
index 00000000..0c6e1c0b
--- /dev/null
+++ b/test/ft-show-glyphs-table.svg11.rgb24.ref.png
Binary files differ
diff --git a/test/ft-show-glyphs-table.svg12.argb32.ref.png b/test/ft-show-glyphs-table.svg12.argb32.ref.png
new file mode 100644
index 00000000..0c6e1c0b
--- /dev/null
+++ b/test/ft-show-glyphs-table.svg12.argb32.ref.png
Binary files differ
diff --git a/test/ft-show-glyphs-table.svg12.rgb24.ref.png b/test/ft-show-glyphs-table.svg12.rgb24.ref.png
new file mode 100644
index 00000000..0c6e1c0b
--- /dev/null
+++ b/test/ft-show-glyphs-table.svg12.rgb24.ref.png
Binary files differ
diff --git a/test/ft-text-vertical-layout-type1.pdf.argb32.ref.png b/test/ft-text-vertical-layout-type1.pdf.argb32.ref.png
new file mode 100644
index 00000000..242c3be5
--- /dev/null
+++ b/test/ft-text-vertical-layout-type1.pdf.argb32.ref.png
Binary files differ
diff --git a/test/ft-text-vertical-layout-type1.pdf.rgb24.ref.png b/test/ft-text-vertical-layout-type1.pdf.rgb24.ref.png
new file mode 100644
index 00000000..242c3be5
--- /dev/null
+++ b/test/ft-text-vertical-layout-type1.pdf.rgb24.ref.png
Binary files differ
diff --git a/test/ft-text-vertical-layout-type1.ref.png b/test/ft-text-vertical-layout-type1.ref.png
index 2b74aa60..1accc0b3 100644
--- a/test/ft-text-vertical-layout-type1.ref.png
+++ b/test/ft-text-vertical-layout-type1.ref.png
Binary files differ
diff --git a/test/ft-text-vertical-layout-type1.svg11.argb32.ref.png b/test/ft-text-vertical-layout-type1.svg11.argb32.ref.png
new file mode 100644
index 00000000..2de3f5be
--- /dev/null
+++ b/test/ft-text-vertical-layout-type1.svg11.argb32.ref.png
Binary files differ
diff --git a/test/ft-text-vertical-layout-type1.svg11.rgb24.ref.png b/test/ft-text-vertical-layout-type1.svg11.rgb24.ref.png
new file mode 100644
index 00000000..2de3f5be
--- /dev/null
+++ b/test/ft-text-vertical-layout-type1.svg11.rgb24.ref.png
Binary files differ
diff --git a/test/ft-text-vertical-layout-type1.svg12.argb32.ref.png b/test/ft-text-vertical-layout-type1.svg12.argb32.ref.png
new file mode 100644
index 00000000..2de3f5be
--- /dev/null
+++ b/test/ft-text-vertical-layout-type1.svg12.argb32.ref.png
Binary files differ
diff --git a/test/ft-text-vertical-layout-type1.svg12.rgb24.ref.png b/test/ft-text-vertical-layout-type1.svg12.rgb24.ref.png
new file mode 100644
index 00000000..2de3f5be
--- /dev/null
+++ b/test/ft-text-vertical-layout-type1.svg12.rgb24.ref.png
Binary files differ
diff --git a/test/ft-text-vertical-layout-type1.test-fallback.argb32.ref.png b/test/ft-text-vertical-layout-type1.test-fallback.argb32.ref.png
new file mode 100644
index 00000000..9eba6bb0
--- /dev/null
+++ b/test/ft-text-vertical-layout-type1.test-fallback.argb32.ref.png
Binary files differ
diff --git a/test/ft-text-vertical-layout-type1.test-fallback.rgb24.ref.png b/test/ft-text-vertical-layout-type1.test-fallback.rgb24.ref.png
new file mode 100644
index 00000000..9eba6bb0
--- /dev/null
+++ b/test/ft-text-vertical-layout-type1.test-fallback.rgb24.ref.png
Binary files differ
diff --git a/test/ft-text-vertical-layout-type1.xlib.ref.png b/test/ft-text-vertical-layout-type1.xlib.ref.png
new file mode 100644
index 00000000..2b74aa60
--- /dev/null
+++ b/test/ft-text-vertical-layout-type1.xlib.ref.png
Binary files differ
diff --git a/test/ft-text-vertical-layout-type3.pdf.argb32.ref.png b/test/ft-text-vertical-layout-type3.pdf.argb32.ref.png
new file mode 100644
index 00000000..f232b9a5
--- /dev/null
+++ b/test/ft-text-vertical-layout-type3.pdf.argb32.ref.png
Binary files differ
diff --git a/test/ft-text-vertical-layout-type3.pdf.rgb24.ref.png b/test/ft-text-vertical-layout-type3.pdf.rgb24.ref.png
new file mode 100644
index 00000000..f232b9a5
--- /dev/null
+++ b/test/ft-text-vertical-layout-type3.pdf.rgb24.ref.png
Binary files differ
diff --git a/test/ft-text-vertical-layout-type3.ref.png b/test/ft-text-vertical-layout-type3.ref.png
index 8ec2ebec..6b59c56a 100644
--- a/test/ft-text-vertical-layout-type3.ref.png
+++ b/test/ft-text-vertical-layout-type3.ref.png
Binary files differ
diff --git a/test/ft-text-vertical-layout-type3.svg11.argb32.ref.png b/test/ft-text-vertical-layout-type3.svg11.argb32.ref.png
new file mode 100644
index 00000000..cfe92681
--- /dev/null
+++ b/test/ft-text-vertical-layout-type3.svg11.argb32.ref.png
Binary files differ
diff --git a/test/ft-text-vertical-layout-type3.svg11.rgb24.ref.png b/test/ft-text-vertical-layout-type3.svg11.rgb24.ref.png
new file mode 100644
index 00000000..cfe92681
--- /dev/null
+++ b/test/ft-text-vertical-layout-type3.svg11.rgb24.ref.png
Binary files differ
diff --git a/test/ft-text-vertical-layout-type3.svg12.argb32.ref.png b/test/ft-text-vertical-layout-type3.svg12.argb32.ref.png
new file mode 100644
index 00000000..cfe92681
--- /dev/null
+++ b/test/ft-text-vertical-layout-type3.svg12.argb32.ref.png
Binary files differ
diff --git a/test/ft-text-vertical-layout-type3.svg12.rgb24.ref.png b/test/ft-text-vertical-layout-type3.svg12.rgb24.ref.png
new file mode 100644
index 00000000..cfe92681
--- /dev/null
+++ b/test/ft-text-vertical-layout-type3.svg12.rgb24.ref.png
Binary files differ
diff --git a/test/ft-text-vertical-layout-type3.test-fallback.argb32.ref.png b/test/ft-text-vertical-layout-type3.test-fallback.argb32.ref.png
new file mode 100644
index 00000000..e57c0831
--- /dev/null
+++ b/test/ft-text-vertical-layout-type3.test-fallback.argb32.ref.png
Binary files differ
diff --git a/test/ft-text-vertical-layout-type3.test-fallback.rgb24.ref.png b/test/ft-text-vertical-layout-type3.test-fallback.rgb24.ref.png
new file mode 100644
index 00000000..e57c0831
--- /dev/null
+++ b/test/ft-text-vertical-layout-type3.test-fallback.rgb24.ref.png
Binary files differ
diff --git a/test/ft-text-vertical-layout-type3.xlib.ref.png b/test/ft-text-vertical-layout-type3.xlib.ref.png
new file mode 100644
index 00000000..8ec2ebec
--- /dev/null
+++ b/test/ft-text-vertical-layout-type3.xlib.ref.png
Binary files differ
diff --git a/test/glitz-surface-source.c b/test/glitz-surface-source.c
index 2dfa7355..89094e48 100644
--- a/test/glitz-surface-source.c
+++ b/test/glitz-surface-source.c
@@ -25,8 +25,6 @@
#include "cairo-test.h"
#include <cairo-glitz.h>
-#include <cairo-xlib.h>
-#include <cairo-xlib-xrender.h>
#define NAME "glitz"
#include "surface-source.c"
@@ -34,6 +32,8 @@
static cairo_user_data_key_t closure_key;
#if CAIRO_CAN_TEST_GLITZ_GLX_SURFACE
+#include <cairo-xlib.h>
+#include <cairo-xlib-xrender.h>
#include <glitz-glx.h>
struct closure {
@@ -198,4 +198,96 @@ create_source_surface (int size)
return surface;
}
+
+#elif CAIRO_CAN_TEST_GLITZ_AGL_SURFACE
+#include <glitz-agl.h>
+
+static void
+cleanup (void *data)
+{
+ glitz_agl_fini ();
+}
+
+static glitz_surface_t *
+_glitz_agl_create_surface (glitz_format_name_t formatname,
+ int width,
+ int height)
+{
+ glitz_drawable_format_t * dformat = NULL;
+ glitz_drawable_t * drawable = NULL;
+ glitz_format_t * format;
+ glitz_format_t templ;
+ glitz_surface_t * sr;
+ int i;
+ int alpha_size;
+
+ glitz_agl_init ();
+
+ /* Find a reasonably lame window format and use it to create a pbuffer. */
+ i = 0;
+ alpha_size = (formatname == GLITZ_STANDARD_ARGB32) ? 8 : 0;
+ while ((dformat = glitz_agl_find_window_format (0, 0, i)) != NULL
+ && !(dformat->doublebuffer == 0
+ && dformat->stencil_size == 0
+ && dformat->depth_size == 0
+ && dformat->color.fourcc == GLITZ_FOURCC_RGB
+ && dformat->color.alpha_size == alpha_size))
+ i++;
+
+ if (!dformat)
+ goto FAIL;
+
+ /* Try for a pbuffer first */
+ drawable = glitz_agl_create_pbuffer_drawable (dformat, width, height);
+ if (!drawable)
+ goto FAIL;
+
+ templ.color = dformat->color;
+ format = glitz_find_format (drawable,
+ GLITZ_FORMAT_FOURCC_MASK |
+ GLITZ_FORMAT_RED_SIZE_MASK |
+ GLITZ_FORMAT_GREEN_SIZE_MASK |
+ GLITZ_FORMAT_BLUE_SIZE_MASK |
+ GLITZ_FORMAT_ALPHA_SIZE_MASK,
+ &templ,
+ 0);
+ if (!format) {
+ fprintf (stderr, "Error: couldn't find surface format\n");
+ return NULL;
+ }
+
+ sr = glitz_surface_create (drawable, format, width, height, 0, NULL);
+ if (!sr)
+ goto DESTROY_DRAWABLE;
+
+ glitz_surface_attach (sr, drawable, GLITZ_DRAWABLE_BUFFER_FRONT_COLOR);
+ glitz_drawable_destroy (drawable);
+
+ return sr;
+ DESTROY_DRAWABLE:
+ glitz_drawable_destroy (drawable);
+ FAIL:
+ return NULL;
+}
+
+static cairo_surface_t *
+create_source_surface (int size)
+{
+ glitz_surface_t *glitz_surface;
+ cairo_surface_t *surface;
+
+ glitz_surface = _glitz_agl_create_surface (GLITZ_STANDARD_ARGB32,
+ size, size);
+
+ surface = cairo_glitz_surface_create (glitz_surface);
+ cairo_surface_set_user_data (surface, &closure_key, NULL, cleanup);
+ return surface;
+}
#endif
+
+CAIRO_TEST (glitz_surface_source,
+ "Test using a Glitz surface as the source",
+ "source", /* keywords */
+ NULL, /* requirements */
+ SIZE, SIZE,
+ preamble, draw)
diff --git a/test/glitz-surface-source.ps2.ref.png b/test/glitz-surface-source.ps2.ref.png
new file mode 100644
index 00000000..10231581
--- /dev/null
+++ b/test/glitz-surface-source.ps2.ref.png
Binary files differ
diff --git a/test/glitz-surface-source.ps3.ref.png b/test/glitz-surface-source.ps3.ref.png
new file mode 100644
index 00000000..10231581
--- /dev/null
+++ b/test/glitz-surface-source.ps3.ref.png
Binary files differ
diff --git a/test/huge-pattern.pdf.argb32.ref.png b/test/huge-pattern.pdf.argb32.ref.png
new file mode 100644
index 00000000..005d4a65
--- /dev/null
+++ b/test/huge-pattern.pdf.argb32.ref.png
Binary files differ
diff --git a/test/linear-gradient.pdf.argb32.ref.png b/test/linear-gradient.pdf.argb32.ref.png
new file mode 100644
index 00000000..f820c374
--- /dev/null
+++ b/test/linear-gradient.pdf.argb32.ref.png
Binary files differ
diff --git a/test/linear-gradient.pdf.rgb24.ref.png b/test/linear-gradient.pdf.rgb24.ref.png
new file mode 100644
index 00000000..f820c374
--- /dev/null
+++ b/test/linear-gradient.pdf.rgb24.ref.png
Binary files differ
diff --git a/test/linear-gradient.ref.png b/test/linear-gradient.ref.png
index cb8f9089..ee238e6a 100644
--- a/test/linear-gradient.ref.png
+++ b/test/linear-gradient.ref.png
Binary files differ
diff --git a/test/linear-gradient.svg11.argb32.ref.png b/test/linear-gradient.svg11.argb32.ref.png
new file mode 100644
index 00000000..ea0e7238
--- /dev/null
+++ b/test/linear-gradient.svg11.argb32.ref.png
Binary files differ
diff --git a/test/linear-gradient.svg11.rgb24.ref.png b/test/linear-gradient.svg11.rgb24.ref.png
new file mode 100644
index 00000000..ea0e7238
--- /dev/null
+++ b/test/linear-gradient.svg11.rgb24.ref.png
Binary files differ
diff --git a/test/linear-gradient.svg12.argb32.ref.png b/test/linear-gradient.svg12.argb32.ref.png
new file mode 100644
index 00000000..ea0e7238
--- /dev/null
+++ b/test/linear-gradient.svg12.argb32.ref.png
Binary files differ
diff --git a/test/linear-gradient.svg12.rgb24.ref.png b/test/linear-gradient.svg12.rgb24.ref.png
new file mode 100644
index 00000000..ea0e7238
--- /dev/null
+++ b/test/linear-gradient.svg12.rgb24.ref.png
Binary files differ
diff --git a/test/linear-gradient.test-fallback.argb32.ref.png b/test/linear-gradient.test-fallback.argb32.ref.png
new file mode 100644
index 00000000..8202880e
--- /dev/null
+++ b/test/linear-gradient.test-fallback.argb32.ref.png
Binary files differ
diff --git a/test/linear-gradient.test-fallback.rgb24.ref.png b/test/linear-gradient.test-fallback.rgb24.ref.png
new file mode 100644
index 00000000..8202880e
--- /dev/null
+++ b/test/linear-gradient.test-fallback.rgb24.ref.png
Binary files differ
diff --git a/test/linear-gradient.xlib.ref.png b/test/linear-gradient.xlib.ref.png
new file mode 100644
index 00000000..cb8f9089
--- /dev/null
+++ b/test/linear-gradient.xlib.ref.png
Binary files differ
diff --git a/test/mask-alpha.ref.png b/test/mask-alpha.ref.png
index 715a959e..d100da46 100644
--- a/test/mask-alpha.ref.png
+++ b/test/mask-alpha.ref.png
Binary files differ
diff --git a/test/mask-alpha.svg11.argb32.ref.png b/test/mask-alpha.svg11.argb32.ref.png
index 3e56aa34..fa9e82d1 100644
--- a/test/mask-alpha.svg11.argb32.ref.png
+++ b/test/mask-alpha.svg11.argb32.ref.png
Binary files differ
diff --git a/test/mask-alpha.svg11.rgb24.ref.png b/test/mask-alpha.svg11.rgb24.ref.png
new file mode 100644
index 00000000..167eab48
--- /dev/null
+++ b/test/mask-alpha.svg11.rgb24.ref.png
Binary files differ
diff --git a/test/mask-alpha.svg12.argb32.ref.png b/test/mask-alpha.svg12.argb32.ref.png
index 3e56aa34..fa9e82d1 100644
--- a/test/mask-alpha.svg12.argb32.ref.png
+++ b/test/mask-alpha.svg12.argb32.ref.png
Binary files differ
diff --git a/test/mask-alpha.svg12.rgb24.ref.png b/test/mask-alpha.svg12.rgb24.ref.png
new file mode 100644
index 00000000..167eab48
--- /dev/null
+++ b/test/mask-alpha.svg12.rgb24.ref.png
Binary files differ
diff --git a/test/mask-alpha.test-fallback.argb32.ref.png b/test/mask-alpha.test-fallback.argb32.ref.png
new file mode 100644
index 00000000..a0b9017e
--- /dev/null
+++ b/test/mask-alpha.test-fallback.argb32.ref.png
Binary files differ
diff --git a/test/mask-alpha.xlib.ref.png b/test/mask-alpha.xlib.ref.png
new file mode 100644
index 00000000..715a959e
--- /dev/null
+++ b/test/mask-alpha.xlib.ref.png
Binary files differ
diff --git a/test/mask-alpha.xlib.rgb24.ref.png b/test/mask-alpha.xlib.rgb24.ref.png
new file mode 100644
index 00000000..aa2010f3
--- /dev/null
+++ b/test/mask-alpha.xlib.rgb24.ref.png
Binary files differ
diff --git a/test/mask.pdf.argb32.ref.png b/test/mask.pdf.argb32.ref.png
index 4570bff1..8bd8f140 100644
--- a/test/mask.pdf.argb32.ref.png
+++ b/test/mask.pdf.argb32.ref.png
Binary files differ
diff --git a/test/mask.pdf.rgb24.ref.png b/test/mask.pdf.rgb24.ref.png
index 1231965d..a3d3845c 100644
--- a/test/mask.pdf.rgb24.ref.png
+++ b/test/mask.pdf.rgb24.ref.png
Binary files differ
diff --git a/test/mask.ref.png b/test/mask.ref.png
index 549c130c..2c2fa117 100644
--- a/test/mask.ref.png
+++ b/test/mask.ref.png
Binary files differ
diff --git a/test/mask.rgb24.ref.png b/test/mask.rgb24.ref.png
index 70323672..34400504 100644
--- a/test/mask.rgb24.ref.png
+++ b/test/mask.rgb24.ref.png
Binary files differ
diff --git a/test/mask.svg11.argb32.ref.png b/test/mask.svg11.argb32.ref.png
index c5828591..3ce4d53f 100644
--- a/test/mask.svg11.argb32.ref.png
+++ b/test/mask.svg11.argb32.ref.png
Binary files differ
diff --git a/test/mask.svg11.rgb24.ref.png b/test/mask.svg11.rgb24.ref.png
index 79957237..94e38009 100644
--- a/test/mask.svg11.rgb24.ref.png
+++ b/test/mask.svg11.rgb24.ref.png
Binary files differ
diff --git a/test/mask.svg12.argb32.ref.png b/test/mask.svg12.argb32.ref.png
index c5828591..3ce4d53f 100644
--- a/test/mask.svg12.argb32.ref.png
+++ b/test/mask.svg12.argb32.ref.png
Binary files differ
diff --git a/test/mask.svg12.rgb24.ref.png b/test/mask.svg12.rgb24.ref.png
index 79957237..94e38009 100644
--- a/test/mask.svg12.rgb24.ref.png
+++ b/test/mask.svg12.rgb24.ref.png
Binary files differ
diff --git a/test/mask.test-fallback.argb32.ref.png b/test/mask.test-fallback.argb32.ref.png
new file mode 100644
index 00000000..bba0f9f3
--- /dev/null
+++ b/test/mask.test-fallback.argb32.ref.png
Binary files differ
diff --git a/test/mask.test-fallback.rgb24.ref.png b/test/mask.test-fallback.rgb24.ref.png
new file mode 100644
index 00000000..49a5b364
--- /dev/null
+++ b/test/mask.test-fallback.rgb24.ref.png
Binary files differ
diff --git a/test/mask.xlib-fallback.rgb24.ref.png b/test/mask.xlib-fallback.rgb24.ref.png
new file mode 100644
index 00000000..34400504
--- /dev/null
+++ b/test/mask.xlib-fallback.rgb24.ref.png
Binary files differ
diff --git a/test/mask.xlib.ref.png b/test/mask.xlib.ref.png
new file mode 100644
index 00000000..549c130c
--- /dev/null
+++ b/test/mask.xlib.ref.png
Binary files differ
diff --git a/test/mask.xlib.rgb24.ref.png b/test/mask.xlib.rgb24.ref.png
new file mode 100644
index 00000000..70323672
--- /dev/null
+++ b/test/mask.xlib.rgb24.ref.png
Binary files differ
diff --git a/test/meta-surface-pattern.pdf.argb32.ref.png b/test/meta-surface-pattern.pdf.argb32.ref.png
new file mode 100644
index 00000000..2ee9b7da
--- /dev/null
+++ b/test/meta-surface-pattern.pdf.argb32.ref.png
Binary files differ
diff --git a/test/meta-surface-pattern.pdf.rgb24.ref.png b/test/meta-surface-pattern.pdf.rgb24.ref.png
index 680f0f50..6555a265 100644
--- a/test/meta-surface-pattern.pdf.rgb24.ref.png
+++ b/test/meta-surface-pattern.pdf.rgb24.ref.png
Binary files differ
diff --git a/test/meta-surface-pattern.svg11.argb32.ref.png b/test/meta-surface-pattern.svg11.argb32.ref.png
index 6250f26c..99695748 100644
--- a/test/meta-surface-pattern.svg11.argb32.ref.png
+++ b/test/meta-surface-pattern.svg11.argb32.ref.png
Binary files differ
diff --git a/test/meta-surface-pattern.svg11.rgb24.ref.png b/test/meta-surface-pattern.svg11.rgb24.ref.png
index feda67da..dea9b9b5 100644
--- a/test/meta-surface-pattern.svg11.rgb24.ref.png
+++ b/test/meta-surface-pattern.svg11.rgb24.ref.png
Binary files differ
diff --git a/test/meta-surface-pattern.svg12.argb32.ref.png b/test/meta-surface-pattern.svg12.argb32.ref.png
index 6250f26c..99695748 100644
--- a/test/meta-surface-pattern.svg12.argb32.ref.png
+++ b/test/meta-surface-pattern.svg12.argb32.ref.png
Binary files differ
diff --git a/test/meta-surface-pattern.svg12.rgb24.ref.png b/test/meta-surface-pattern.svg12.rgb24.ref.png
index feda67da..dea9b9b5 100644
--- a/test/meta-surface-pattern.svg12.rgb24.ref.png
+++ b/test/meta-surface-pattern.svg12.rgb24.ref.png
Binary files differ
diff --git a/test/operator-clear.pdf.argb32.ref.png b/test/operator-clear.pdf.argb32.ref.png
index 06fc51e3..258c61c9 100644
--- a/test/operator-clear.pdf.argb32.ref.png
+++ b/test/operator-clear.pdf.argb32.ref.png
Binary files differ
diff --git a/test/operator-clear.ps2.argb32.ref.png b/test/operator-clear.ps2.argb32.ref.png
new file mode 100644
index 00000000..92b41111
--- /dev/null
+++ b/test/operator-clear.ps2.argb32.ref.png
Binary files differ
diff --git a/test/operator-clear.ps3.argb32.ref.png b/test/operator-clear.ps3.argb32.ref.png
new file mode 100644
index 00000000..92b41111
--- /dev/null
+++ b/test/operator-clear.ps3.argb32.ref.png
Binary files differ
diff --git a/test/operator-source.pdf.argb32.ref.png b/test/operator-source.pdf.argb32.ref.png
index f110ff2a..f42d5af4 100644
--- a/test/operator-source.pdf.argb32.ref.png
+++ b/test/operator-source.pdf.argb32.ref.png
Binary files differ
diff --git a/test/operator-source.pdf.rgb24.ref.png b/test/operator-source.pdf.rgb24.ref.png
index c6b71705..8269bc10 100644
--- a/test/operator-source.pdf.rgb24.ref.png
+++ b/test/operator-source.pdf.rgb24.ref.png
Binary files differ
diff --git a/test/operator-source.ref.png b/test/operator-source.ref.png
index 8e2f5e61..006bf950 100644
--- a/test/operator-source.ref.png
+++ b/test/operator-source.ref.png
Binary files differ
diff --git a/test/operator-source.rgb24.ref.png b/test/operator-source.rgb24.ref.png
index a762d60a..013d8a42 100644
--- a/test/operator-source.rgb24.ref.png
+++ b/test/operator-source.rgb24.ref.png
Binary files differ
diff --git a/test/operator-source.test-fallback.argb32.ref.png b/test/operator-source.test-fallback.argb32.ref.png
new file mode 100644
index 00000000..8aac39d1
--- /dev/null
+++ b/test/operator-source.test-fallback.argb32.ref.png
Binary files differ
diff --git a/test/operator-source.test-fallback.rgb24.ref.png b/test/operator-source.test-fallback.rgb24.ref.png
new file mode 100644
index 00000000..ad37a60b
--- /dev/null
+++ b/test/operator-source.test-fallback.rgb24.ref.png
Binary files differ
diff --git a/test/operator-source.xlib-fallback.rgb24.ref.png b/test/operator-source.xlib-fallback.rgb24.ref.png
new file mode 100644
index 00000000..fe0d3c61
--- /dev/null
+++ b/test/operator-source.xlib-fallback.rgb24.ref.png
Binary files differ
diff --git a/test/operator-source.xlib.ref.png b/test/operator-source.xlib.ref.png
new file mode 100644
index 00000000..8e2f5e61
--- /dev/null
+++ b/test/operator-source.xlib.ref.png
Binary files differ
diff --git a/test/operator-source.xlib.rgb24.ref.png b/test/operator-source.xlib.rgb24.ref.png
new file mode 100644
index 00000000..a762d60a
--- /dev/null
+++ b/test/operator-source.xlib.rgb24.ref.png
Binary files differ
diff --git a/test/over-above-source.ps2.argb32.ref.png b/test/over-above-source.ps2.argb32.ref.png
index 886faad4..7c90d086 100644
--- a/test/over-above-source.ps2.argb32.ref.png
+++ b/test/over-above-source.ps2.argb32.ref.png
Binary files differ
diff --git a/test/over-above-source.ps3.argb32.ref.png b/test/over-above-source.ps3.argb32.ref.png
index 886faad4..7c90d086 100644
--- a/test/over-above-source.ps3.argb32.ref.png
+++ b/test/over-above-source.ps3.argb32.ref.png
Binary files differ
diff --git a/test/over-above-source.ref.png b/test/over-above-source.ref.png
index f3a49f61..c45fcbde 100644
--- a/test/over-above-source.ref.png
+++ b/test/over-above-source.ref.png
Binary files differ
diff --git a/test/over-above-source.rgb24.ref.png b/test/over-above-source.rgb24.ref.png
index 68c7d982..84fc880c 100644
--- a/test/over-above-source.rgb24.ref.png
+++ b/test/over-above-source.rgb24.ref.png
Binary files differ
diff --git a/test/over-above-source.test-fallback.argb32.ref.png b/test/over-above-source.test-fallback.argb32.ref.png
new file mode 100644
index 00000000..8a0183a6
--- /dev/null
+++ b/test/over-above-source.test-fallback.argb32.ref.png
Binary files differ
diff --git a/test/over-above-source.test-fallback.rgb24.ref.png b/test/over-above-source.test-fallback.rgb24.ref.png
new file mode 100644
index 00000000..85c19971
--- /dev/null
+++ b/test/over-above-source.test-fallback.rgb24.ref.png
Binary files differ
diff --git a/test/over-above-source.xlib.ref.png b/test/over-above-source.xlib.ref.png
new file mode 100644
index 00000000..f3a49f61
--- /dev/null
+++ b/test/over-above-source.xlib.ref.png
Binary files differ
diff --git a/test/over-above-source.xlib.rgb24.ref.png b/test/over-above-source.xlib.rgb24.ref.png
new file mode 100644
index 00000000..68c7d982
--- /dev/null
+++ b/test/over-above-source.xlib.rgb24.ref.png
Binary files differ
diff --git a/test/over-around-source.pdf.argb32.ref.png b/test/over-around-source.pdf.argb32.ref.png
new file mode 100644
index 00000000..02af76a9
--- /dev/null
+++ b/test/over-around-source.pdf.argb32.ref.png
Binary files differ
diff --git a/test/over-around-source.ps2.argb32.ref.png b/test/over-around-source.ps2.argb32.ref.png
index ea6de696..647420ad 100644
--- a/test/over-around-source.ps2.argb32.ref.png
+++ b/test/over-around-source.ps2.argb32.ref.png
Binary files differ
diff --git a/test/over-around-source.ps3.argb32.ref.png b/test/over-around-source.ps3.argb32.ref.png
index ea6de696..647420ad 100644
--- a/test/over-around-source.ps3.argb32.ref.png
+++ b/test/over-around-source.ps3.argb32.ref.png
Binary files differ
diff --git a/test/over-around-source.ref.png b/test/over-around-source.ref.png
index ccae9514..abaeb4e4 100644
--- a/test/over-around-source.ref.png
+++ b/test/over-around-source.ref.png
Binary files differ
diff --git a/test/over-around-source.test-fallback.argb32.ref.png b/test/over-around-source.test-fallback.argb32.ref.png
new file mode 100644
index 00000000..fca75056
--- /dev/null
+++ b/test/over-around-source.test-fallback.argb32.ref.png
Binary files differ
diff --git a/test/over-around-source.xlib.ref.png b/test/over-around-source.xlib.ref.png
new file mode 100644
index 00000000..ccae9514
--- /dev/null
+++ b/test/over-around-source.xlib.ref.png
Binary files differ
diff --git a/test/over-around-source.xlib.rgb24.ref.png b/test/over-around-source.xlib.rgb24.ref.png
new file mode 100644
index 00000000..943a28e3
--- /dev/null
+++ b/test/over-around-source.xlib.rgb24.ref.png
Binary files differ
diff --git a/test/over-below-source.pdf.argb32.ref.png b/test/over-below-source.pdf.argb32.ref.png
new file mode 100644
index 00000000..b9c4fe28
--- /dev/null
+++ b/test/over-below-source.pdf.argb32.ref.png
Binary files differ
diff --git a/test/over-between-source.ps2.argb32.ref.png b/test/over-between-source.ps2.argb32.ref.png
index 43e9424b..dd95940a 100644
--- a/test/over-between-source.ps2.argb32.ref.png
+++ b/test/over-between-source.ps2.argb32.ref.png
Binary files differ
diff --git a/test/over-between-source.ps3.argb32.ref.png b/test/over-between-source.ps3.argb32.ref.png
index 43e9424b..dd95940a 100644
--- a/test/over-between-source.ps3.argb32.ref.png
+++ b/test/over-between-source.ps3.argb32.ref.png
Binary files differ
diff --git a/test/over-between-source.ref.png b/test/over-between-source.ref.png
index 79ea75e9..0c3986fc 100644
--- a/test/over-between-source.ref.png
+++ b/test/over-between-source.ref.png
Binary files differ
diff --git a/test/over-between-source.test-fallback.argb32.ref.png b/test/over-between-source.test-fallback.argb32.ref.png
new file mode 100644
index 00000000..a8fe66a3
--- /dev/null
+++ b/test/over-between-source.test-fallback.argb32.ref.png
Binary files differ
diff --git a/test/over-between-source.xlib.ref.png b/test/over-between-source.xlib.ref.png
new file mode 100644
index 00000000..79ea75e9
--- /dev/null
+++ b/test/over-between-source.xlib.ref.png
Binary files differ
diff --git a/test/over-between-source.xlib.rgb24.ref.png b/test/over-between-source.xlib.rgb24.ref.png
new file mode 100644
index 00000000..602f2d26
--- /dev/null
+++ b/test/over-between-source.xlib.rgb24.ref.png
Binary files differ
diff --git a/test/push-group.pdf.argb32.ref.png b/test/push-group.pdf.argb32.ref.png
new file mode 100644
index 00000000..9cb59c94
--- /dev/null
+++ b/test/push-group.pdf.argb32.ref.png
Binary files differ
diff --git a/test/push-group.pdf.rgb24.ref.png b/test/push-group.pdf.rgb24.ref.png
index 7e84ec83..34d7f74e 100644
--- a/test/push-group.pdf.rgb24.ref.png
+++ b/test/push-group.pdf.rgb24.ref.png
Binary files differ
diff --git a/test/push-group.ref.png b/test/push-group.ref.png
index 84bc184d..e4ae291f 100644
--- a/test/push-group.ref.png
+++ b/test/push-group.ref.png
Binary files differ
diff --git a/test/push-group.rgb24.ref.png b/test/push-group.rgb24.ref.png
index cababd95..3a951827 100644
--- a/test/push-group.rgb24.ref.png
+++ b/test/push-group.rgb24.ref.png
Binary files differ
diff --git a/test/push-group.svg11.argb32.ref.png b/test/push-group.svg11.argb32.ref.png
index 34f06bf7..d6958798 100644
--- a/test/push-group.svg11.argb32.ref.png
+++ b/test/push-group.svg11.argb32.ref.png
Binary files differ
diff --git a/test/push-group.svg12.argb32.ref.png b/test/push-group.svg12.argb32.ref.png
index 34f06bf7..d6958798 100644
--- a/test/push-group.svg12.argb32.ref.png
+++ b/test/push-group.svg12.argb32.ref.png
Binary files differ
diff --git a/test/push-group.test-fallback.argb32.ref.png b/test/push-group.test-fallback.argb32.ref.png
new file mode 100644
index 00000000..7c5905a6
--- /dev/null
+++ b/test/push-group.test-fallback.argb32.ref.png
Binary files differ
diff --git a/test/push-group.test-fallback.rgb24.ref.png b/test/push-group.test-fallback.rgb24.ref.png
new file mode 100644
index 00000000..4586d5c5
--- /dev/null
+++ b/test/push-group.test-fallback.rgb24.ref.png
Binary files differ
diff --git a/test/push-group.xlib-fallback.rgb24.ref.png b/test/push-group.xlib-fallback.rgb24.ref.png
new file mode 100644
index 00000000..3a951827
--- /dev/null
+++ b/test/push-group.xlib-fallback.rgb24.ref.png
Binary files differ
diff --git a/test/push-group.xlib.ref.png b/test/push-group.xlib.ref.png
new file mode 100644
index 00000000..84bc184d
--- /dev/null
+++ b/test/push-group.xlib.ref.png
Binary files differ
diff --git a/test/push-group.xlib.rgb24.ref.png b/test/push-group.xlib.rgb24.ref.png
new file mode 100644
index 00000000..cababd95
--- /dev/null
+++ b/test/push-group.xlib.rgb24.ref.png
Binary files differ
diff --git a/test/quartz-surface-source.c b/test/quartz-surface-source.c
new file mode 100644
index 00000000..b0c86d0f
--- /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/quartz-surface-source.ps2.ref.png b/test/quartz-surface-source.ps2.ref.png
new file mode 100644
index 00000000..10231581
--- /dev/null
+++ b/test/quartz-surface-source.ps2.ref.png
Binary files differ
diff --git a/test/quartz-surface-source.ps3.ref.png b/test/quartz-surface-source.ps3.ref.png
new file mode 100644
index 00000000..10231581
--- /dev/null
+++ b/test/quartz-surface-source.ps3.ref.png
Binary files differ
diff --git a/test/quartz-surface-source.ref.png b/test/quartz-surface-source.ref.png
new file mode 100644
index 00000000..9fbbedd5
--- /dev/null
+++ b/test/quartz-surface-source.ref.png
Binary files differ
diff --git a/test/radial-gradient.pdf.argb32.ref.png b/test/radial-gradient.pdf.argb32.ref.png
new file mode 100644
index 00000000..6cee5d12
--- /dev/null
+++ b/test/radial-gradient.pdf.argb32.ref.png
Binary files differ
diff --git a/test/radial-gradient.pdf.rgb24.ref.png b/test/radial-gradient.pdf.rgb24.ref.png
new file mode 100644
index 00000000..6cee5d12
--- /dev/null
+++ b/test/radial-gradient.pdf.rgb24.ref.png
Binary files differ
diff --git a/test/random-intersections.ref.png b/test/random-intersections.ref.png
index 3188edef..ace75a24 100644
--- a/test/random-intersections.ref.png
+++ b/test/random-intersections.ref.png
Binary files differ
diff --git a/test/random-intersections.test-fallback.argb32.ref.png b/test/random-intersections.test-fallback.argb32.ref.png
new file mode 100644
index 00000000..a35364d8
--- /dev/null
+++ b/test/random-intersections.test-fallback.argb32.ref.png
Binary files differ
diff --git a/test/random-intersections.test-fallback.rgb24.ref.png b/test/random-intersections.test-fallback.rgb24.ref.png
new file mode 100644
index 00000000..a35364d8
--- /dev/null
+++ b/test/random-intersections.test-fallback.rgb24.ref.png
Binary files differ
diff --git a/test/random-intersections.xlib.ref.png b/test/random-intersections.xlib.ref.png
new file mode 100644
index 00000000..3188edef
--- /dev/null
+++ b/test/random-intersections.xlib.ref.png
Binary files differ
diff --git a/test/rotate-image-surface-paint.pdf.argb32.ref.png b/test/rotate-image-surface-paint.pdf.argb32.ref.png
index c12ae8fd..93fab525 100644
--- a/test/rotate-image-surface-paint.pdf.argb32.ref.png
+++ b/test/rotate-image-surface-paint.pdf.argb32.ref.png
Binary files differ
diff --git a/test/rotate-image-surface-paint.pdf.rgb24.ref.png b/test/rotate-image-surface-paint.pdf.rgb24.ref.png
index 5cd7bf61..93fab525 100644
--- a/test/rotate-image-surface-paint.pdf.rgb24.ref.png
+++ b/test/rotate-image-surface-paint.pdf.rgb24.ref.png
Binary files differ
diff --git a/test/smask-fill.pdf.argb32.ref.png b/test/smask-fill.pdf.argb32.ref.png
new file mode 100644
index 00000000..51d34d43
--- /dev/null
+++ b/test/smask-fill.pdf.argb32.ref.png
Binary files differ
diff --git a/test/smask-fill.pdf.rgb24.ref.png b/test/smask-fill.pdf.rgb24.ref.png
new file mode 100644
index 00000000..51d34d43
--- /dev/null
+++ b/test/smask-fill.pdf.rgb24.ref.png
Binary files differ
diff --git a/test/smask-fill.ref.png b/test/smask-fill.ref.png
index c778a791..28ab7338 100644
--- a/test/smask-fill.ref.png
+++ b/test/smask-fill.ref.png
Binary files differ
diff --git a/test/smask-fill.svg11.argb32.ref.png b/test/smask-fill.svg11.argb32.ref.png
new file mode 100644
index 00000000..57ae76e6
--- /dev/null
+++ b/test/smask-fill.svg11.argb32.ref.png
Binary files differ
diff --git a/test/smask-fill.svg11.rgb24.ref.png b/test/smask-fill.svg11.rgb24.ref.png
new file mode 100644
index 00000000..57ae76e6
--- /dev/null
+++ b/test/smask-fill.svg11.rgb24.ref.png
Binary files differ
diff --git a/test/smask-fill.svg12.argb32.ref.png b/test/smask-fill.svg12.argb32.ref.png
new file mode 100644
index 00000000..57ae76e6
--- /dev/null
+++ b/test/smask-fill.svg12.argb32.ref.png
Binary files differ
diff --git a/test/smask-fill.svg12.rgb24.ref.png b/test/smask-fill.svg12.rgb24.ref.png
new file mode 100644
index 00000000..57ae76e6
--- /dev/null
+++ b/test/smask-fill.svg12.rgb24.ref.png
Binary files differ
diff --git a/test/smask-fill.test-fallback.argb32.ref.png b/test/smask-fill.test-fallback.argb32.ref.png
new file mode 100644
index 00000000..3d375bba
--- /dev/null
+++ b/test/smask-fill.test-fallback.argb32.ref.png
Binary files differ
diff --git a/test/smask-fill.test-fallback.rgb24.ref.png b/test/smask-fill.test-fallback.rgb24.ref.png
new file mode 100644
index 00000000..3d375bba
--- /dev/null
+++ b/test/smask-fill.test-fallback.rgb24.ref.png
Binary files differ
diff --git a/test/smask-fill.xlib-fallback.ref.png b/test/smask-fill.xlib-fallback.ref.png
new file mode 100644
index 00000000..28ab7338
--- /dev/null
+++ b/test/smask-fill.xlib-fallback.ref.png
Binary files differ
diff --git a/test/smask-fill.xlib.ref.png b/test/smask-fill.xlib.ref.png
new file mode 100644
index 00000000..c778a791
--- /dev/null
+++ b/test/smask-fill.xlib.ref.png
Binary files differ
diff --git a/test/smask-image-mask.pdf.argb32.ref.png b/test/smask-image-mask.pdf.argb32.ref.png
new file mode 100644
index 00000000..19a20f48
--- /dev/null
+++ b/test/smask-image-mask.pdf.argb32.ref.png
Binary files differ
diff --git a/test/smask-image-mask.pdf.rgb24.ref.png b/test/smask-image-mask.pdf.rgb24.ref.png
new file mode 100644
index 00000000..19a20f48
--- /dev/null
+++ b/test/smask-image-mask.pdf.rgb24.ref.png
Binary files differ
diff --git a/test/smask-mask.pdf.argb32.ref.png b/test/smask-mask.pdf.argb32.ref.png
new file mode 100644
index 00000000..0dc2135d
--- /dev/null
+++ b/test/smask-mask.pdf.argb32.ref.png
Binary files differ
diff --git a/test/smask-mask.pdf.rgb24.ref.png b/test/smask-mask.pdf.rgb24.ref.png
new file mode 100644
index 00000000..0dc2135d
--- /dev/null
+++ b/test/smask-mask.pdf.rgb24.ref.png
Binary files differ
diff --git a/test/smask-paint.pdf.argb32.ref.png b/test/smask-paint.pdf.argb32.ref.png
new file mode 100644
index 00000000..c6b1731f
--- /dev/null
+++ b/test/smask-paint.pdf.argb32.ref.png
Binary files differ
diff --git a/test/smask-paint.pdf.rgb24.ref.png b/test/smask-paint.pdf.rgb24.ref.png
new file mode 100644
index 00000000..c6b1731f
--- /dev/null
+++ b/test/smask-paint.pdf.rgb24.ref.png
Binary files differ
diff --git a/test/smask-stroke.pdf.argb32.ref.png b/test/smask-stroke.pdf.argb32.ref.png
new file mode 100644
index 00000000..41321f23
--- /dev/null
+++ b/test/smask-stroke.pdf.argb32.ref.png
Binary files differ
diff --git a/test/smask-stroke.pdf.rgb24.ref.png b/test/smask-stroke.pdf.rgb24.ref.png
new file mode 100644
index 00000000..41321f23
--- /dev/null
+++ b/test/smask-stroke.pdf.rgb24.ref.png
Binary files differ
diff --git a/test/smask-text.svg11.argb32.ref.png b/test/smask-text.svg11.argb32.ref.png
new file mode 100644
index 00000000..5034526a
--- /dev/null
+++ b/test/smask-text.svg11.argb32.ref.png
Binary files differ
diff --git a/test/smask-text.svg11.rgb24.ref.png b/test/smask-text.svg11.rgb24.ref.png
new file mode 100644
index 00000000..5034526a
--- /dev/null
+++ b/test/smask-text.svg11.rgb24.ref.png
Binary files differ
diff --git a/test/smask-text.svg12.argb32.ref.png b/test/smask-text.svg12.argb32.ref.png
new file mode 100644
index 00000000..5034526a
--- /dev/null
+++ b/test/smask-text.svg12.argb32.ref.png
Binary files differ
diff --git a/test/smask-text.svg12.rgb24.ref.png b/test/smask-text.svg12.rgb24.ref.png
new file mode 100644
index 00000000..5034526a
--- /dev/null
+++ b/test/smask-text.svg12.rgb24.ref.png
Binary files differ
diff --git a/test/smask.pdf.argb32.ref.png b/test/smask.pdf.argb32.ref.png
new file mode 100644
index 00000000..c6b1731f
--- /dev/null
+++ b/test/smask.pdf.argb32.ref.png
Binary files differ
diff --git a/test/smask.pdf.rgb24.ref.png b/test/smask.pdf.rgb24.ref.png
new file mode 100644
index 00000000..c6b1731f
--- /dev/null
+++ b/test/smask.pdf.rgb24.ref.png
Binary files differ
diff --git a/test/surface-pattern-scale-down.pdf.argb32.ref.png b/test/surface-pattern-scale-down.pdf.argb32.ref.png
index c29d804c..dc4b3a31 100644
--- a/test/surface-pattern-scale-down.pdf.argb32.ref.png
+++ b/test/surface-pattern-scale-down.pdf.argb32.ref.png
Binary files differ
diff --git a/test/surface-pattern-scale-down.pdf.rgb24.ref.png b/test/surface-pattern-scale-down.pdf.rgb24.ref.png
index c29d804c..dc4b3a31 100644
--- a/test/surface-pattern-scale-down.pdf.rgb24.ref.png
+++ b/test/surface-pattern-scale-down.pdf.rgb24.ref.png
Binary files differ
diff --git a/test/surface-pattern-scale-up.pdf.argb32.ref.png b/test/surface-pattern-scale-up.pdf.argb32.ref.png
index 6f3a53c5..c0a2896a 100644
--- a/test/surface-pattern-scale-up.pdf.argb32.ref.png
+++ b/test/surface-pattern-scale-up.pdf.argb32.ref.png
Binary files differ
diff --git a/test/surface-pattern-scale-up.pdf.rgb24.ref.png b/test/surface-pattern-scale-up.pdf.rgb24.ref.png
index 6f3a53c5..c0a2896a 100644
--- a/test/surface-pattern-scale-up.pdf.rgb24.ref.png
+++ b/test/surface-pattern-scale-up.pdf.rgb24.ref.png
Binary files differ
diff --git a/test/surface-pattern.pdf.argb32.ref.png b/test/surface-pattern.pdf.argb32.ref.png
new file mode 100644
index 00000000..70a44767
--- /dev/null
+++ b/test/surface-pattern.pdf.argb32.ref.png
Binary files differ
diff --git a/test/surface-pattern.pdf.rgb24.ref.png b/test/surface-pattern.pdf.rgb24.ref.png
new file mode 100644
index 00000000..70a44767
--- /dev/null
+++ b/test/surface-pattern.pdf.rgb24.ref.png
Binary files differ
diff --git a/test/text-pattern.pdf.argb32.ref.png b/test/text-pattern.pdf.argb32.ref.png
index 2a70deb0..dfaed39f 100644
--- a/test/text-pattern.pdf.argb32.ref.png
+++ b/test/text-pattern.pdf.argb32.ref.png
Binary files differ
diff --git a/test/text-pattern.svg11.argb32.ref.png b/test/text-pattern.svg11.argb32.ref.png
index 97d7534c..47ee89c2 100644
--- a/test/text-pattern.svg11.argb32.ref.png
+++ b/test/text-pattern.svg11.argb32.ref.png
Binary files differ
diff --git a/test/text-pattern.svg12.argb32.ref.png b/test/text-pattern.svg12.argb32.ref.png
index 97d7534c..47ee89c2 100644
--- a/test/text-pattern.svg12.argb32.ref.png
+++ b/test/text-pattern.svg12.argb32.ref.png
Binary files differ
diff --git a/test/text-rotate.svg11.argb32.ref.png b/test/text-rotate.svg11.argb32.ref.png
new file mode 100644
index 00000000..4864046f
--- /dev/null
+++ b/test/text-rotate.svg11.argb32.ref.png
Binary files differ
diff --git a/test/text-rotate.svg11.rgb24.ref.png b/test/text-rotate.svg11.rgb24.ref.png
new file mode 100644
index 00000000..4864046f
--- /dev/null
+++ b/test/text-rotate.svg11.rgb24.ref.png
Binary files differ
diff --git a/test/text-rotate.svg12.argb32.ref.png b/test/text-rotate.svg12.argb32.ref.png
new file mode 100644
index 00000000..4864046f
--- /dev/null
+++ b/test/text-rotate.svg12.argb32.ref.png
Binary files differ
diff --git a/test/text-rotate.svg12.rgb24.ref.png b/test/text-rotate.svg12.rgb24.ref.png
new file mode 100644
index 00000000..4864046f
--- /dev/null
+++ b/test/text-rotate.svg12.rgb24.ref.png
Binary files differ
diff --git a/test/text-transform.svg11.argb32.ref.png b/test/text-transform.svg11.argb32.ref.png
new file mode 100644
index 00000000..0c4e57cc
--- /dev/null
+++ b/test/text-transform.svg11.argb32.ref.png
Binary files differ
diff --git a/test/text-transform.svg11.rgb24.ref.png b/test/text-transform.svg11.rgb24.ref.png
new file mode 100644
index 00000000..0c4e57cc
--- /dev/null
+++ b/test/text-transform.svg11.rgb24.ref.png
Binary files differ
diff --git a/test/text-transform.svg12.argb32.ref.png b/test/text-transform.svg12.argb32.ref.png
new file mode 100644
index 00000000..0c4e57cc
--- /dev/null
+++ b/test/text-transform.svg12.argb32.ref.png
Binary files differ
diff --git a/test/text-transform.svg12.rgb24.ref.png b/test/text-transform.svg12.rgb24.ref.png
new file mode 100644
index 00000000..0c4e57cc
--- /dev/null
+++ b/test/text-transform.svg12.rgb24.ref.png
Binary files differ
diff --git a/test/trap-clip.pdf.argb32.ref.png b/test/trap-clip.pdf.argb32.ref.png
index c3ee9971..15010164 100644
--- a/test/trap-clip.pdf.argb32.ref.png
+++ b/test/trap-clip.pdf.argb32.ref.png
Binary files differ
diff --git a/test/trap-clip.pdf.rgb24.ref.png b/test/trap-clip.pdf.rgb24.ref.png
index f787011c..06163675 100644
--- a/test/trap-clip.pdf.rgb24.ref.png
+++ b/test/trap-clip.pdf.rgb24.ref.png
Binary files differ
diff --git a/test/trap-clip.ps2.argb32.ref.png b/test/trap-clip.ps2.argb32.ref.png
index 37121cde..957b9382 100644
--- a/test/trap-clip.ps2.argb32.ref.png
+++ b/test/trap-clip.ps2.argb32.ref.png
Binary files differ
diff --git a/test/trap-clip.ref.png b/test/trap-clip.ref.png
index 2cbbdb76..e8c26d32 100644
--- a/test/trap-clip.ref.png
+++ b/test/trap-clip.ref.png
Binary files differ
diff --git a/test/trap-clip.rgb24.ref.png b/test/trap-clip.rgb24.ref.png
index 15068aa5..e61992ff 100644
--- a/test/trap-clip.rgb24.ref.png
+++ b/test/trap-clip.rgb24.ref.png
Binary files differ
diff --git a/test/trap-clip.test-fallback.argb32.ref.png b/test/trap-clip.test-fallback.argb32.ref.png
new file mode 100644
index 00000000..319d8356
--- /dev/null
+++ b/test/trap-clip.test-fallback.argb32.ref.png
Binary files differ
diff --git a/test/trap-clip.test-fallback.rgb24.ref.png b/test/trap-clip.test-fallback.rgb24.ref.png
new file mode 100644
index 00000000..7ac5789b
--- /dev/null
+++ b/test/trap-clip.test-fallback.rgb24.ref.png
Binary files differ
diff --git a/test/trap-clip.test-paginated.argb32.ref.png b/test/trap-clip.test-paginated.argb32.ref.png
new file mode 100644
index 00000000..dee57e7b
--- /dev/null
+++ b/test/trap-clip.test-paginated.argb32.ref.png
Binary files differ
diff --git a/test/trap-clip.xlib.ref.png b/test/trap-clip.xlib.ref.png
new file mode 100644
index 00000000..2cbbdb76
--- /dev/null
+++ b/test/trap-clip.xlib.ref.png
Binary files differ
diff --git a/test/trap-clip.xlib.rgb24.ref.png b/test/trap-clip.xlib.rgb24.ref.png
new file mode 100644
index 00000000..15068aa5
--- /dev/null
+++ b/test/trap-clip.xlib.rgb24.ref.png
Binary files differ
diff --git a/test/twin.svg11.argb32.ref.png b/test/twin.svg11.argb32.ref.png
new file mode 100644
index 00000000..0818c67c
--- /dev/null
+++ b/test/twin.svg11.argb32.ref.png
Binary files differ
diff --git a/test/twin.svg11.rgb24.ref.png b/test/twin.svg11.rgb24.ref.png
new file mode 100644
index 00000000..0818c67c
--- /dev/null
+++ b/test/twin.svg11.rgb24.ref.png
Binary files differ
diff --git a/test/twin.svg12.argb32.ref.png b/test/twin.svg12.argb32.ref.png
new file mode 100644
index 00000000..0818c67c
--- /dev/null
+++ b/test/twin.svg12.argb32.ref.png
Binary files differ
diff --git a/test/twin.svg12.rgb24.ref.png b/test/twin.svg12.rgb24.ref.png
new file mode 100644
index 00000000..0818c67c
--- /dev/null
+++ b/test/twin.svg12.rgb24.ref.png
Binary files differ
diff --git a/test/unbounded-operator.pdf.argb32.ref.png b/test/unbounded-operator.pdf.argb32.ref.png
new file mode 100644
index 00000000..4aa476de
--- /dev/null
+++ b/test/unbounded-operator.pdf.argb32.ref.png
Binary files differ
diff --git a/test/unbounded-operator.ps2.argb32.ref.png b/test/unbounded-operator.ps2.argb32.ref.png
new file mode 100644
index 00000000..4aa476de
--- /dev/null
+++ b/test/unbounded-operator.ps2.argb32.ref.png
Binary files differ
diff --git a/test/unbounded-operator.ps3.argb32.ref.png b/test/unbounded-operator.ps3.argb32.ref.png
new file mode 100644
index 00000000..4aa476de
--- /dev/null
+++ b/test/unbounded-operator.ps3.argb32.ref.png
Binary files differ
diff --git a/test/unbounded-operator.rgb24.ref.png b/test/unbounded-operator.rgb24.ref.png
index b2f1a84d..ad3225d0 100644
--- a/test/unbounded-operator.rgb24.ref.png
+++ b/test/unbounded-operator.rgb24.ref.png
Binary files differ
diff --git a/test/unbounded-operator.test-fallback.rgb24.ref.png b/test/unbounded-operator.test-fallback.rgb24.ref.png
new file mode 100644
index 00000000..07c7ecff
--- /dev/null
+++ b/test/unbounded-operator.test-fallback.rgb24.ref.png
Binary files differ
diff --git a/test/unbounded-operator.xlib.rgb24.ref.png b/test/unbounded-operator.xlib.rgb24.ref.png
new file mode 100644
index 00000000..b2f1a84d
--- /dev/null
+++ b/test/unbounded-operator.xlib.rgb24.ref.png
Binary files differ
diff --git a/test/user-font-proxy.pdf.argb32.ref.png b/test/user-font-proxy.pdf.argb32.ref.png
new file mode 100644
index 00000000..cffa9edb
--- /dev/null
+++ b/test/user-font-proxy.pdf.argb32.ref.png
Binary files differ
diff --git a/test/user-font-proxy.pdf.rgb24.ref.png b/test/user-font-proxy.pdf.rgb24.ref.png
new file mode 100644
index 00000000..cffa9edb
--- /dev/null
+++ b/test/user-font-proxy.pdf.rgb24.ref.png
Binary files differ
diff --git a/test/user-font-proxy.ref.png b/test/user-font-proxy.ref.png
index ebd97198..cffa9edb 100644
--- a/test/user-font-proxy.ref.png
+++ b/test/user-font-proxy.ref.png
Binary files differ
diff --git a/test/user-font-proxy.svg11.argb32.ref.png b/test/user-font-proxy.svg11.argb32.ref.png
new file mode 100644
index 00000000..d2a7812b
--- /dev/null
+++ b/test/user-font-proxy.svg11.argb32.ref.png
Binary files differ
diff --git a/test/user-font-proxy.svg11.rgb24.ref.png b/test/user-font-proxy.svg11.rgb24.ref.png
new file mode 100644
index 00000000..d2a7812b
--- /dev/null
+++ b/test/user-font-proxy.svg11.rgb24.ref.png
Binary files differ
diff --git a/test/user-font-proxy.svg12.argb32.ref.png b/test/user-font-proxy.svg12.argb32.ref.png
new file mode 100644
index 00000000..d2a7812b
--- /dev/null
+++ b/test/user-font-proxy.svg12.argb32.ref.png
Binary files differ
diff --git a/test/user-font-proxy.svg12.rgb24.ref.png b/test/user-font-proxy.svg12.rgb24.ref.png
new file mode 100644
index 00000000..d2a7812b
--- /dev/null
+++ b/test/user-font-proxy.svg12.rgb24.ref.png
Binary files differ
diff --git a/test/user-font-proxy.test-fallback.argb32.ref.png b/test/user-font-proxy.test-fallback.argb32.ref.png
new file mode 100644
index 00000000..9cccf312
--- /dev/null
+++ b/test/user-font-proxy.test-fallback.argb32.ref.png
Binary files differ
diff --git a/test/user-font-proxy.test-fallback.rgb24.ref.png b/test/user-font-proxy.test-fallback.rgb24.ref.png
new file mode 100644
index 00000000..9cccf312
--- /dev/null
+++ b/test/user-font-proxy.test-fallback.rgb24.ref.png
Binary files differ
diff --git a/test/user-font-proxy.xlib.ref.png b/test/user-font-proxy.xlib.ref.png
new file mode 100644
index 00000000..ebd97198
--- /dev/null
+++ b/test/user-font-proxy.xlib.ref.png
Binary files differ
diff --git a/test/user-font.ref.png b/test/user-font.ref.png
index abc31171..753fc7bc 100644
--- a/test/user-font.ref.png
+++ b/test/user-font.ref.png
Binary files differ
diff --git a/test/user-font.svg11.argb32.ref.png b/test/user-font.svg11.argb32.ref.png
new file mode 100644
index 00000000..3dc77ae4
--- /dev/null
+++ b/test/user-font.svg11.argb32.ref.png
Binary files differ
diff --git a/test/user-font.svg11.rgb24.ref.png b/test/user-font.svg11.rgb24.ref.png
new file mode 100644
index 00000000..3dc77ae4
--- /dev/null
+++ b/test/user-font.svg11.rgb24.ref.png
Binary files differ
diff --git a/test/user-font.svg12.argb32.ref.png b/test/user-font.svg12.argb32.ref.png
new file mode 100644
index 00000000..3dc77ae4
--- /dev/null
+++ b/test/user-font.svg12.argb32.ref.png
Binary files differ
diff --git a/test/user-font.svg12.rgb24.ref.png b/test/user-font.svg12.rgb24.ref.png
new file mode 100644
index 00000000..3dc77ae4
--- /dev/null
+++ b/test/user-font.svg12.rgb24.ref.png
Binary files differ
diff --git a/test/user-font.test-fallback.argb32.ref.png b/test/user-font.test-fallback.argb32.ref.png
new file mode 100644
index 00000000..3080c694
--- /dev/null
+++ b/test/user-font.test-fallback.argb32.ref.png
Binary files differ
diff --git a/test/user-font.test-fallback.rgb24.ref.png b/test/user-font.test-fallback.rgb24.ref.png
new file mode 100644
index 00000000..3080c694
--- /dev/null
+++ b/test/user-font.test-fallback.rgb24.ref.png
Binary files differ
diff --git a/test/user-font.xlib.ref.png b/test/user-font.xlib.ref.png
new file mode 100644
index 00000000..abc31171
--- /dev/null
+++ b/test/user-font.xlib.ref.png
Binary files differ
diff --git a/util/cairo-script/Makefile.am b/util/cairo-script/Makefile.am
index 4d228128..b6ab355e 100644
--- a/util/cairo-script/Makefile.am
+++ b/util/cairo-script/Makefile.am
@@ -17,10 +17,10 @@ libcairo_script_interpreter_la_SOURCES = \
$(NULL)
libcairo_script_interpreter_la_CFLAGS = $(CAIRO_CFLAGS)
libcairo_script_interpreter_la_LDFLAGS = -version-info $(CAIRO_LIBTOOL_VERSION_INFO) -no-undefined $(export_symbols)
-libcairo_script_interpreter_la_LIBADD = -lz $(CAIRO_LIBS) -L$(top_builddir)/src -lcairo
+libcairo_script_interpreter_la_LIBADD = $(top_builddir)/src/libcairo.la $(CAIRO_LIBS)
csi_replay_SOURCES = csi-replay.c
-csi_replay_LDADD = libcairo-script-interpreter.la $(top_builddir)/src/libcairo.la
+csi_replay_LDADD = libcairo-script-interpreter.la $(top_builddir)/src/libcairo.la $(CAIRO_LIBS)
EXTRA_DIST = \
COPYING
diff --git a/util/cairo-script/cairo-script-file.c b/util/cairo-script/cairo-script-file.c
index c21ef630..fcdccf14 100644
--- a/util/cairo-script/cairo-script-file.c
+++ b/util/cairo-script/cairo-script-file.c
@@ -36,7 +36,6 @@
#include <stdio.h>
#include <string.h>
-#include <zlib.h>
#define CHUNK_SIZE 32768
@@ -372,6 +371,9 @@ csi_file_new_ascii85_decode (csi_t *ctx,
return _csi_file_new_filter (ctx, obj, src, &funcs, data);
}
+#if HAVE_ZLIB
+#include <zlib.h>
+
typedef struct _deflate_decode_data {
z_stream zlib_stream;
@@ -503,6 +505,7 @@ csi_file_new_deflate_decode (csi_t *ctx,
return _csi_file_new_filter (ctx, obj, src, &funcs, data);
}
+#endif
#if 0
static int
diff --git a/util/cairo-script/cairo-script-operators.c b/util/cairo-script/cairo-script-operators.c
index a70b55d5..13d6f766 100644
--- a/util/cairo-script/cairo-script-operators.c
+++ b/util/cairo-script/cairo-script-operators.c
@@ -1317,7 +1317,9 @@ _filter (csi_t *ctx)
csi_object_t *);
} filters[] = {
{ "ascii85", csi_file_new_ascii85_decode },
+#if HAVE_ZLIB
{ "deflate", csi_file_new_deflate_decode },
+#endif
#if 0
{ "lzw", csi_file_new_lzw_decode },
#endif
diff --git a/util/cairo-script/csi-replay.c b/util/cairo-script/csi-replay.c
index 5ca035f2..e5a847e4 100644
--- a/util/cairo-script/csi-replay.c
+++ b/util/cairo-script/csi-replay.c
@@ -68,6 +68,14 @@ _surface_create (void *closure,
return surface;
}
+#else
+/* fallback: just use an image surface */
+static cairo_surface_t *
+_surface_create (void *closure,
+ double width, double height)
+{
+ return cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
+}
#endif
int